diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8bfa84ffb..c9bc3cdda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,6 +85,8 @@ jobs: echo "$HOME/gcc-riscv64-unknown-elf-8.3.0-ubuntu/bin" >> $GITHUB_PATH popd - name: ci-build - run: pushd examples; RISCV=1 ./build_all.sh || exit; popd + run: | + pushd ./examples/lora; CC=`which arm-none-eabi-gcc` CXX=`which arm-none-eabi-g++` ./build-RadioLib.sh; popd + pushd examples; RISCV=1 ./build_all.sh || exit; popd - name: ci-debug-build run: pushd examples/blink; make debug RAM_START=0x20004000 FLASH_INIT=0x30051 || exit; popd diff --git a/.gitmodules b/.gitmodules index 6c3a1dc31..487bd98cf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lvgl/lvgl"] path = lvgl/lvgl url = https://github.com/littlevgl/lvgl.git +[submodule "examples/lora/RadioLib"] + path = examples/lora/RadioLib + url = https://github.com/jgromes/RadioLib.git diff --git a/examples/lora/README.md b/examples/lora/README.md new file mode 100644 index 000000000..f77d6f0c0 --- /dev/null +++ b/examples/lora/README.md @@ -0,0 +1,25 @@ +LoRa +==== + +LoRa (Long Range) is a radio communication technique that uses +spread spectrum modulation technique derived from chirp spread +spectrum (CSS) technology. + +LoRa provides a number of properties including: + + * long range, can cover tens of kilometres + * low power, devices can run for years + * reasonably secure + * standardised + * relativity cheap + +This directory contains a range of examples using +[RadioLib](https://github.com/jgromes/RadioLib) to +support LoRa on Tock. + +Before the examples will work you first need to build +RadioLib. + +Note that the Makefiles will do this automatically when +you run `make` in a subdirectory, but if you want to do +it manually you can run the `build-RadioLib.sh` script. diff --git a/examples/lora/RadioLib b/examples/lora/RadioLib new file mode 160000 index 000000000..ada400630 --- /dev/null +++ b/examples/lora/RadioLib @@ -0,0 +1 @@ +Subproject commit ada400630d9bf95a310a575e93cb88c8dcfd681c diff --git a/examples/lora/build-RadioLib.sh b/examples/lora/build-RadioLib.sh new file mode 100755 index 000000000..381c06762 --- /dev/null +++ b/examples/lora/build-RadioLib.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +pushd RadioLib/examples/NonArduino/Tock/ + +rm -rf build + +# Change the source to point to the current libtock-c directory +# Note, x-platform `sed -i` has odd, but particular syntax +# https://stackoverflow.com/questions/5694228/sed-in-place-flag-that-works-both-on-mac-bsd-and-linux +sed -i._SED_HACK 's|${CMAKE_CURRENT_SOURCE_DIR}/libtock-c|../../../../../../../|g' CMakeLists.txt +sed -i._SED_HACK 's|target_include_directories(${PROJECT_NAME} PUBLIC|target_include_directories(\${PROJECT_NAME}\n PUBLIC ../../../../../../|g' CMakeLists.txt + +find . -name '*._SED_HACK' -delete + +mkdir -p build +cd build + +cmake -G "CodeBlocks - Unix Makefiles" .. + +# Build the Tock example application +# This will fail to link, as it can't find the libtock-c libraries +# That's fine for us though, as we just need to build the RadioLib +# library, not the entire example application +make -j4 2> /dev/null + +popd diff --git a/examples/lora/sensor-receive/Makefile b/examples/lora/sensor-receive/Makefile new file mode 100644 index 000000000..1afd96989 --- /dev/null +++ b/examples/lora/sensor-receive/Makefile @@ -0,0 +1,33 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../ + +# We only compile this for Cortex-M platforms because we only have +# libraries for Cortex-M. +TOCK_TARGETS := cortex-m0 cortex-m3 cortex-m4 cortex-m7 + +# Which files to compile. +CXX_SRCS := $(wildcard *.cc) + +# Include the core RadioLib headers +override CPPFLAGS += -I../RadioLib/src + +# Include the Tock specific headers +override CPPFLAGS += -I../RadioLib/examples/NonArduino/Tock + +# Include the base of libtock-c to fix the libtock/ includes from RadioLib +override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR)/ + +override LEGACY_LIBS_cortex-m += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m0 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m3 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m4 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m7 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk + +../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a: + cd ../ && ./build-RadioLib.sh diff --git a/examples/lora/sensor-receive/README.md b/examples/lora/sensor-receive/README.md new file mode 100644 index 000000000..f76c80b59 --- /dev/null +++ b/examples/lora/sensor-receive/README.md @@ -0,0 +1,4 @@ +Sensor Receive +============== + +This example builds an application to receiver sensor data. diff --git a/examples/lora/sensor-receive/main.cc b/examples/lora/sensor-receive/main.cc new file mode 100644 index 000000000..b08ab86d2 --- /dev/null +++ b/examples/lora/sensor-receive/main.cc @@ -0,0 +1,71 @@ +/* + RadioLib Non-Arduino Tock Library test application + + Licensed under the MIT or Apache License + + Copyright (c) 2023 Alistair Francis + */ + +// include the library +#include + +// include the hardware abstraction layer +#include "libtockHal.h" + +// Include some libtock-c helpers +#include +#include + +#define BUFFER_LEN 64 + +// the entry point for the program +int main(void) { + char buffer[BUFFER_LEN]; + + printf("[SX1261] Initialising Radio ... \n"); + + // create a new instance of the HAL class + TockHal* hal = new TockHal(); + + // now we can create the radio module + // pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE + // NSS pin: 0 + // DIO1 pin: 2 + // NRST pin: 4 + // BUSY pin: 1 + Module* tock_module = new Module(hal, RADIO_NSS, RADIO_DIO_1, RADIO_RESET, RADIO_BUSY); + SX1262* radio = new SX1262(tock_module); + + // Setup the radio + // The settings here work for the SparkFun LoRa Thing Plus - expLoRaBLE + radio->XTAL = true; + int state = radio->begin(915.0); + + if (state != RADIOLIB_ERR_NONE) { + printf("failed, code %d\r\n", state); + return 1; + } + printf("success!\r\n"); + + printf("[SX1261] Receiving...\r\n"); + + // loop forever + for ( ;;) { + // Ensure there are no pending callbacks + yield_no_wait(); + + state = radio->receive((uint8_t*)buffer, BUFFER_LEN); + + if (state == RADIOLIB_ERR_NONE) { + // the packet was successfully transmitted + printf("success!: %s\r\n", buffer); + + // wait for a second before transmitting again + hal->delay(1000); + } else { + printf("failed, code %d\r\n", state); + } + } + + return 0; +} diff --git a/examples/lora/sensor-transmit/Makefile b/examples/lora/sensor-transmit/Makefile new file mode 100644 index 000000000..1afd96989 --- /dev/null +++ b/examples/lora/sensor-transmit/Makefile @@ -0,0 +1,33 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../ + +# We only compile this for Cortex-M platforms because we only have +# libraries for Cortex-M. +TOCK_TARGETS := cortex-m0 cortex-m3 cortex-m4 cortex-m7 + +# Which files to compile. +CXX_SRCS := $(wildcard *.cc) + +# Include the core RadioLib headers +override CPPFLAGS += -I../RadioLib/src + +# Include the Tock specific headers +override CPPFLAGS += -I../RadioLib/examples/NonArduino/Tock + +# Include the base of libtock-c to fix the libtock/ includes from RadioLib +override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR)/ + +override LEGACY_LIBS_cortex-m += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m0 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m3 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m4 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a +override LEGACY_LIBS_cortex-m7 += ../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk + +../RadioLib/examples/NonArduino/Tock/build/RadioLib/libRadioLib.a: + cd ../ && ./build-RadioLib.sh diff --git a/examples/lora/sensor-transmit/README.md b/examples/lora/sensor-transmit/README.md new file mode 100644 index 000000000..cad1c16ee --- /dev/null +++ b/examples/lora/sensor-transmit/README.md @@ -0,0 +1,4 @@ +Sensor Transmitter +================== + +This example builds an application to transmit sensor data. diff --git a/examples/lora/sensor-transmit/main.cc b/examples/lora/sensor-transmit/main.cc new file mode 100644 index 000000000..1a1995d71 --- /dev/null +++ b/examples/lora/sensor-transmit/main.cc @@ -0,0 +1,81 @@ +/* + RadioLib Non-Arduino Tock Library test application + + Licensed under the MIT or Apache License + + Copyright (c) 2023 Alistair Francis + */ + +// include the library +#include + +// include the hardware abstraction layer +#include "libtockHal.h" + +// Include some libtock-c helpers +#include +#include + +#define BUFFER_LEN 64 + +// the entry point for the program +int main(void) { + char buffer[BUFFER_LEN]; + + printf("[SX1261] Initialising Radio ... \n"); + + // create a new instance of the HAL class + TockHal* hal = new TockHal(); + + // now we can create the radio module + // pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE + // NSS pin: 0 + // DIO1 pin: 2 + // NRST pin: 4 + // BUSY pin: 1 + Module* tock_module = new Module(hal, RADIO_NSS, RADIO_DIO_1, RADIO_RESET, RADIO_BUSY); + SX1262* radio = new SX1262(tock_module); + + // Setup the radio + // The settings here work for the SparkFun LoRa Thing Plus - expLoRaBLE + radio->XTAL = true; + int state = radio->begin(915.0); + + if (state != RADIOLIB_ERR_NONE) { + printf("failed, code %d\r\n", state); + return 1; + } + printf("success!\r\n"); + + int temp = 0; + unsigned humi = 0; + + // loop forever + for ( ;;) { + // Ensure there are no pending callbacks + yield_no_wait(); + + // Read some sensor data from the board + temperature_read_sync(&temp); + humidity_read_sync(&humi); + + snprintf(buffer, BUFFER_LEN, "Temp: %d, Hum: %u", temp, humi); + + // send a packet + printf("[SX1261] Transmitting '%s' \r\n", buffer); + + state = radio->transmit(buffer); + + if (state == RADIOLIB_ERR_NONE) { + // the packet was successfully transmitted + printf("success!\r\n"); + + // wait for a second before transmitting again + hal->delay(1000); + } else { + printf("failed, code %d\r\n", state); + } + } + + return 0; +}