From a4d40ef10555e9fc0bb73d5ad633deb82bfbd475 Mon Sep 17 00:00:00 2001 From: Nathann Morand Date: Wed, 31 Jul 2024 13:55:24 +0200 Subject: [PATCH 1/9] Added a few info in CONTRIBUTING.md Tried to improve the documentation for futur contributor. Notably added instruction to also update the Makefile, ad an entry to Utilities.h which I had to discover by trial and error --- Documentation/CONTRIBUTING.md | 97 +++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/Documentation/CONTRIBUTING.md b/Documentation/CONTRIBUTING.md index 3a8d1ac..9290699 100644 --- a/Documentation/CONTRIBUTING.md +++ b/Documentation/CONTRIBUTING.md @@ -1,7 +1,8 @@ # Board support -If you wish to add support for a specific board to the project, all you have to do (if it's ESP32 or nRF52), is write an additional entry for `Boards.h`. +If you wish to add support for a specific board to the project, all you have to do (if it's ESP32 or nRF52), is write an additional entry for `Boards.h` and `Utilities.h` and the `Makefile` . -This entry should include, at a minimum, the following: +### Boards.h +This entry in `Boards.h` should include, at a minimum, the following: * whether the device has bluetooth / BLE * whether the device has a PMU * whether the device has an EEPROM (false in all cases for nRF52, true for ESP32) @@ -10,7 +11,47 @@ This entry should include, at a minimum, the following: * whether the modem has a busy pin * RX and TX leds (preferably LEDs of different colours) -# Check this area... +here is an example : +the new entry to add whoses number should not be used aldready +``` +#define BOARD_GENERIC_ESP32_C3 0x3B +``` +and the board definition +``` +#elif BOARD_MODEL == BOARD_GENERIC_ESP32_C3 + #define HAS_BLUETOOTH false + #define HAS_CONSOLE true + #define HAS_EEPROM true + #define INTERFACE_COUNT 1 + const int pin_led_rx = 9; + const int pin_led_tx = 8; + const uint8_t interfaces[INTERFACE_COUNT] = {SX127X}; + const bool interface_cfg[INTERFACE_COUNT][3] = { + // SX127X + { + true, // DEFAULT_SPI + false, // HAS_TCXO + false // DIO2_AS_RF_SWITCH + }, + }; + const int8_t interface_pins[INTERFACE_COUNT][10] = { + // SX127X + { + 7, // pin_ss + 4, // pin_sclk + 6, // pin_mosi + 5, // pin_miso + -1, // pin_busy + 2, // pin_dio + 3, // pin_reset + -1, // pin_txen + -1, // pin_rxen + -1 // pin_tcxo_enable + } + }; + +``` + see https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.h#L39 Effectively, there are multiple SPI buses we can map to pins on these devices (including the hardware SPI bus) @@ -98,6 +139,56 @@ An example of an entry using the SX1280 modem can be seen below: const int pin_led_tx = 6; ``` + +### Utilities.h +you should add something like this to drive the led : + +``` +#elif BOARD_MODEL == BOARD_GENERIC_ESP32_C3 + void led_rx_on() { digitalWrite(pin_led_rx, HIGH); } + void led_rx_off() { digitalWrite(pin_led_rx, LOW); } + void led_tx_on() { digitalWrite(pin_led_tx, HIGH); } + void led_tx_off() { digitalWrite(pin_led_tx, LOW); } +``` + +### Makefile + +one entry to build the firmware +``` +firmware-genericesp32c3: + arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\"" +``` +pay attention the the DBOARD_MODEL= value as you must choose an unsigned one for your board. + +one entry to upload the firmware to the board + +``` +upload-genericesp32c3: + arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32c3 + @sleep 1 + rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bin) + @sleep 3 + python ./Release/esptool/esptool.py --chip esp32c3 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin +``` + +and finally one entry to make a realease for the firmware + +``` +release-genericesp32c3: + arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\"" + cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_esp32_generic-c3.boot_app0 + cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bin build/rnode_firmware_esp32c3_generic.bin + cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_esp32c3_generic.bootloader + cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_esp32c3_generic.partitions + zip --junk-paths ./Release/rnode_firmware_esp32c3_generic.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_esp32c3_generic.boot_app0 build/rnode_firmware_esp32c3_generic.bin build/rnode_firmware_esp32c3_generic.bootloader build/rnode_firmware_esp32c3_generic.partitions + rm -r build +``` +dont forget to add this entry to the `release-all` action. + +``` +release-all: console-site spiffs-image release-tbeam release-tbeam_sx1262 release-lora32_v10 release-lora32_v20 release-lora32_v21 release-lora32_v10_extled release-lora32_v20_extled release-lora32_v21_extled release-lora32_v21_tcxo release-featheresp32 release-genericesp32 release-genericesp32c3 release-heltec32_v2 release-heltec32_v3 release-heltec32_v2_extled release-rnode_ng_20 release-rnode_ng_21 release-t3s3 release-hashe +``` + Please submit this, and any other support in different areas of the project your board may require, as a PR for my consideration. # Feature request From e5eea88aa5c3f3dcddaacd2bbde0b7bc1b63987e Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Wed, 31 Jul 2024 22:11:34 +0100 Subject: [PATCH 2/9] Update guide and fix spelling / grammar errors --- Documentation/CONTRIBUTING.md | 205 ++++++++++++++++++++-------------- 1 file changed, 124 insertions(+), 81 deletions(-) diff --git a/Documentation/CONTRIBUTING.md b/Documentation/CONTRIBUTING.md index 9290699..09cb729 100644 --- a/Documentation/CONTRIBUTING.md +++ b/Documentation/CONTRIBUTING.md @@ -7,18 +7,20 @@ This entry in `Boards.h` should include, at a minimum, the following: * whether the device has a PMU * whether the device has an EEPROM (false in all cases for nRF52, true for ESP32) * pin mappings for SPI NSS, SCLK, MOSI, MISO, modem reset and dio0 -* the type of modem on the board (if undefined it defaults to SX127x) +* the type of modem on the board +* the number of interfaces (modems) * whether the modem has a busy pin * RX and TX leds (preferably LEDs of different colours) -here is an example : -the new entry to add whoses number should not be used aldready +You should also define a unique name for your board (with a unique value), for +example: ``` -#define BOARD_GENERIC_ESP32_C3 0x3B +#define BOARD_MY_WICKED_BOARD 0x3B ``` -and the board definition +**Check your chosen value is not in use** in `Boards.h` first! +The board definition should look as follows: ``` -#elif BOARD_MODEL == BOARD_GENERIC_ESP32_C3 +#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD #define HAS_BLUETOOTH false #define HAS_CONSOLE true #define HAS_EEPROM true @@ -51,38 +53,25 @@ and the board definition }; ``` +Note, this will have to be pasted in the section according to the MCU variant, +e.g. nRF52 or ESP32. Find the section by searching for the comparison where +`MCU_VARIANT` is checked for your MCU variant. **Do not change the order of the +pins or options in any of the interface_cfg or interface_pins arrays.** You +have been warned. -see https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.h#L39 -Effectively, there are multiple SPI buses we can map to pins on these -devices (including the hardware SPI bus) +[There are multiple SPI +buses](https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.h#L39) +we can map to pins on these devices (including the hardware SPI bus). -An example of a minimal entry can be seen below: -``` -#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD - #define HAS_BLUETOOTH true - #define HAS_PMU true - #define HAS_EEPROM true - #define EEPROM_SIZE 296 // minimum EEPROM size - #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED - const int pin_cs = 20; - const int pin_reset = 19; - // const int pin_cs = 1; not needed here - // const int pin_sclk = 2; not needed here - // const int pin_mosi = 3; not needed here - // const int pin_miso = 4; not needed here - const int pin_dio = 18; - // const int pin_busy = 0; not present - const int pin_led_rx = 5; - const int pin_led_tx = 6; -``` In some cases the SPI pins will not be required, as they will be the default pins for the SPI library supporting the board anyway, and therefore do not need overriding in the config. If the SX1262 is being used the following should also be considered: +* the modem busy pin * whether DIO2 should be used as the RF switch (DIO2_AS_RF_SWITCH) -* whether an rf on/off switch also has to be operated (through the pin pin_rxen) -* whether a TCXO is connected to the modem (HAS_TCXO) -* the enable pin for the TCXO (if present) +* whether an RF on/off switch also has to be operated (through the pin pin_rxen) +* whether a TCXO is connected to the modem (HAS_TCXO and pin_tcxo_enable to enable the TCXO if present) +* whether the SPI pins are the default used by the SPI library An example of an entry using the SX1262 modem can be seen below: ``` @@ -92,22 +81,34 @@ An example of an entry using the SX1262 modem can be seen below: #define HAS_EEPROM true #define EEPROM_SIZE 296 // minimum EEPROM size #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED - #define MODEM SX1262 - #define DIO2_AS_RF_SWITCH true - #define HAS_TCXO true - #define HAS_BUSY true - const int pin_cs = 20; - const int pin_reset = 19; - const int pin_rxen = 10; - // const int pin_cs = 1; not needed here - // const int pin_sclk = 2; not needed here - // const int pin_mosi = 3; not needed here - // const int pin_miso = 4; not needed here - const int pin_dio = 18; - const int pin_busy = 7; - const int pin_tcxo_enable = -1; const int pin_led_rx = 5; const int pin_led_tx = 6; + #define INTERFACE_COUNT 1 + const uint8_t interfaces[INTERFACE_COUNT] = {SX126X}; + const bool interface_cfg[INTERFACE_COUNT][3] = { + // SX1262 + { + false, // DEFAULT_SPI + true, // HAS_TCXO + true // DIO2_AS_RF_SWITCH + } + }; + const int8_t interface_pins[INTERFACE_COUNT][10] = { + // SX1262 + { + 42, // pin_ss + 43, // pin_sclk + 44, // pin_mosi + 45, // pin_miso + 46, // pin_busy + 47, // pin_dio + 38, // pin_reset + -1, // pin_txen + 37, // pin_rxen + -1 // pin_tcxo_enable + } + }; + ``` If the SX1280 is being used, the following should also be added: @@ -121,73 +122,115 @@ An example of an entry using the SX1280 modem can be seen below: #define HAS_EEPROM true #define EEPROM_SIZE 296 // minimum EEPROM size #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED - #define MODEM SX1280 - #define HAS_BUSY true - #define HAS_RF_SWITCH_RX_TX true - const int pin_cs = 20; - const int pin_reset = 19; - const int pin_rxen = 10; - const int pin_txen = 11; - // const int pin_cs = 1; not needed here - // const int pin_sclk = 2; not needed here - // const int pin_mosi = 3; not needed here - // const int pin_miso = 4; not needed here - const int pin_dio = 18; - const int pin_busy = 7; - const int pin_tcxo_enable = -1; const int pin_led_rx = 5; const int pin_led_tx = 6; + #define INTERFACE_COUNT 1 + const uint8_t interfaces[INTERFACE_COUNT] = {SX128X}; + const bool interface_cfg[INTERFACE_COUNT][3] = { + // SX1280 + { + true, // DEFAULT_SPI + false,// HAS_TCXO + false // DIO2_AS_RF_SWITCH + } + }; + const int8_t interface_pins[INTERFACE_COUNT][10] = { + // SX1280 + { + 24, // pin_ss + 3, // pin_sclk + 30, // pin_mosi + 29, // pin_miso + 25, // pin_busy + 15, // pin_dio + 16, // pin_reset + 20, // pin_txen + 19, // pin_rxen + -1 // pin_tcxo_enable + } + }; ``` +#### INTERFACE_SPI (nRF52 only) +If you are using non-default SPI pins on an nRF52 MCU variant, you **must** ensure that you add this section to the bottom of your board config: +``` + // Required because on nRF52, non-default SPI pins must be initialised when class is declared. + const SPIClass interface_spi[1] = { + // SX1262 + SPIClass( + NRF_SPIM2, + interface_pins[0][3], + interface_pins[0][1], + interface_pins[0][2] + ) + }; +``` +This will ensure the pins are set correctly in the SPI class. ### Utilities.h -you should add something like this to drive the led : - +You should add something similar to the following to drive the LEDs depending on your configuration: ``` -#elif BOARD_MODEL == BOARD_GENERIC_ESP32_C3 +#elif BOARD_MODEL == BOARD_MY_WICKED_BOARD void led_rx_on() { digitalWrite(pin_led_rx, HIGH); } void led_rx_off() { digitalWrite(pin_led_rx, LOW); } void led_tx_on() { digitalWrite(pin_led_tx, HIGH); } void led_tx_off() { digitalWrite(pin_led_tx, LOW); } ``` +Note: this will again have to be pasted in the correct section according to +your MCU variant. Please search for the other definitions of `led_rx_on()` to +find the correct section, then find the final section by searching for the +comparison where `MCU_VARIANT` is checked for your MCU variant. ### Makefile - -one entry to build the firmware +You can add the example target below to the makefile for your board, but **you must replace the FQBN** in the arduino-cli command with the correct one for your board. ``` -firmware-genericesp32c3: +firmware-wicked_esp32: arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\"" ``` -pay attention the the DBOARD_MODEL= value as you must choose an unsigned one for your board. - -one entry to upload the firmware to the board +Pay attention the the DBOARD_MODEL= value as you must insert the one you chose earlier here. +Another entry to upload to the board. Again substitute your FQBN, and you may have to experiment with the commands to get it to flash: +#### ESP32 ``` -upload-genericesp32c3: +upload-wicked_esp32: arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32c3 @sleep 1 rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bin) @sleep 3 python ./Release/esptool/esptool.py --chip esp32c3 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin ``` - -and finally one entry to make a realease for the firmware - +#### nRF52 ``` -release-genericesp32c3: +upload-wicked_nrf52: + arduino-cli upload -p /dev/ttyACM0 --fqbn rakwireless:nrf52:WisCoreRAK4631Board + unzip -o build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.zip -d build/rakwireless.nrf52.WisCoreRAK4631Board + rnodeconf /dev/ttyACM0 --firmware-hash $$(sha256sum ./build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.bin | grep -o '^\S*') +``` + +And one final entry to make a release for the firmware: +#### ESP32 +``` +release-wicked_esp32: arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\"" - cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_esp32_generic-c3.boot_app0 - cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bin build/rnode_firmware_esp32c3_generic.bin - cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_esp32c3_generic.bootloader - cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_esp32c3_generic.partitions - zip --junk-paths ./Release/rnode_firmware_esp32c3_generic.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_esp32c3_generic.boot_app0 build/rnode_firmware_esp32c3_generic.bin build/rnode_firmware_esp32c3_generic.bootloader build/rnode_firmware_esp32c3_generic.partitions + cp ~/.arduino15/packages/esp32/hardware/esp32/$(ESP_IDF_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_wicked_esp32.boot_app0 + cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bin build/rnode_firmware_wicked_esp32.bin + cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_wicked_esp32.bootloader + cp build/esp32.esp32.esp32c3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_wicked_esp32.partitions + zip --junk-paths ./Release/rnode_firmware_wicked_esp32.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_wicked_esp32.boot_app0 build/rnode_firmware_wicked_esp32.bin build/rnode_firmware_wicked_esp32.bootloader build/rnode_firmware_wicked_esp32.partitions rm -r build ``` -dont forget to add this entry to the `release-all` action. - +#### nRF52 ``` -release-all: console-site spiffs-image release-tbeam release-tbeam_sx1262 release-lora32_v10 release-lora32_v20 release-lora32_v21 release-lora32_v10_extled release-lora32_v20_extled release-lora32_v21_extled release-lora32_v21_tcxo release-featheresp32 release-genericesp32 release-genericesp32c3 release-heltec32_v2 release-heltec32_v3 release-heltec32_v2_extled release-rnode_ng_20 release-rnode_ng_21 release-t3s3 release-hashe +release-wicked_nrf52: + arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\"" + cp build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.hex build/rnode_firmware_wicked_nrf52.hex + adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_wicked_nrf52.hex Release/rnode_firmware_wicked_nrf52.zip ``` +Don't forget to add this entry to the `release-all` target! +``` +release-all: console-site spiffs-image release-tbeam release-tbeam_sx1262 release-lora32_v10 release-lora32_v20 release-lora32_v21 release-lora32_v10_extled release-lora32_v20_extled release-lora32_v21_extled release-lora32_v21_tcxo release-featheresp32 release-genericesp32 ***release-wicked_esp32*** release-heltec32_v2 release-heltec32_v3 release-heltec32_v2_extled release-rnode_ng_20 release-rnode_ng_21 release-t3s3 release-hashes +``` +You can of course replace the ESP32 target with the nRF52 target, if you are building for that MCU variant, as seen in previous instructions. Please submit this, and any other support in different areas of the project your board may require, as a PR for my consideration. From fe7d7450523cbede6b0971961caddd12b49a80dc Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Thu, 1 Aug 2024 17:53:22 +0100 Subject: [PATCH 3/9] Remove last remaining AVR stuff --- Makefile | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/Makefile b/Makefile index fa92457..d802724 100644 --- a/Makefile +++ b/Makefile @@ -21,12 +21,7 @@ clean: -rm -r ./build -rm ./Release/rnode_firmware* -prep: prep-avr prep-esp32 prep-samd - -prep-avr: - arduino-cli core update-index --config-file arduino-cli.yaml - arduino-cli core install arduino:avr --config-file arduino-cli.yaml - arduino-cli core install unsignedio:avr --config-file arduino-cli.yaml +prep: prep-esp32 prep-samd prep-esp32: arduino-cli core update-index --config-file arduino-cli.yaml @@ -59,12 +54,6 @@ upload-spiffs: @echo Deploying SPIFFS image... python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin -firmware: - arduino-cli compile --fqbn unsignedio:avr:rnode - -firmware-mega2560: - arduino-cli compile --fqbn arduino:avr:mega - firmware-tbeam: arduino-cli compile --fqbn esp32:esp32:t-beam -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\"" @@ -125,12 +114,6 @@ firmware-rak4631_sx1280: firmware-freenode: arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\" \"-DBOARD_VARIANT=0x21\"" -upload: - arduino-cli upload -p /dev/ttyUSB0 --fqbn unsignedio:avr:rnode - -upload-mega2560: - arduino-cli upload -p /dev/ttyACM0 --fqbn arduino:avr:mega - upload-tbeam: arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:t-beam @sleep 1 @@ -372,11 +355,6 @@ release-genericesp32: zip --junk-paths ./Release/rnode_firmware_esp32_generic.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_esp32_generic.boot_app0 build/rnode_firmware_esp32_generic.bin build/rnode_firmware_esp32_generic.bootloader build/rnode_firmware_esp32_generic.partitions rm -r build -release-mega2560: - arduino-cli compile --fqbn arduino:avr:mega -e --build-property "compiler.cpp.extra_flags=\"-DMODEM=0x01\"" - cp build/arduino.avr.mega/RNode_Firmware_CE.ino.hex Release/rnode_firmware_m2560.hex - rm -r build - release-rak4631: arduino-cli compile --fqbn rakwireless:nrf52:WisCoreRAK4631Board -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x51\" \"-DBOARD_VARIANT=0x12\"" cp build/rakwireless.nrf52.WisCoreRAK4631Board/RNode_Firmware_CE.ino.hex build/rnode_firmware_rak4631.hex From 761923e210d0127dde80bbb770474a2fe4f26dbb Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Thu, 1 Aug 2024 18:04:31 +0100 Subject: [PATCH 4/9] Update dependencies --- Documentation/BUILDING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/BUILDING.md b/Documentation/BUILDING.md index e1381b7..6e90f8e 100644 --- a/Documentation/BUILDING.md +++ b/Documentation/BUILDING.md @@ -1,6 +1,6 @@ # Building ## Prerequisites -The build system of this repository is based on Make. The `Makefile` is in the base of the repository. Please ensure you have `arduino-cli` installed before proceeding. +The build system of this repository is based on GNU Make. The `Makefile` is in the base of the repository. Please ensure you have `arduino-cli`, `python3` and `make` installed before proceeding. Firstly, figure out which MCU platform your supported board is based on. The table below can help you. From 152e7f17b35bcddd9508df9bbb90593666e64dae Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Thu, 1 Aug 2024 18:04:39 +0100 Subject: [PATCH 5/9] Auto install needed packages, and bypass external management error --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d802724..751d45d 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ prep-esp32: arduino-cli lib install "Adafruit SSD1306" arduino-cli lib install "XPowersLib" arduino-cli lib install "Crypto" + pip install pyserial rns --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error. prep-samd: arduino-cli core update-index --config-file arduino-cli.yaml @@ -40,7 +41,8 @@ prep-nrf: arduino-cli lib install "Crypto" arduino-cli lib install "Adafruit GFX Library" arduino-cli lib install "GxEPD2" - pip install adafruit-nrfutil --upgrade + pip install pyserial rns --upgrade --user --break-system-packages + pip install adafruit-nrfutil --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error. console-site: make -C Console clean site From a4fe2baf7802d7404a1efcda87a8e666dd34fb8a Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Sat, 3 Aug 2024 13:24:27 +0100 Subject: [PATCH 6/9] Clarify pin requirements --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9935a0e..e5016ba 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ The RNode Firmware supports all transceiver modules based on the following chips * Semtech SX1278 * Semtech SX1280 -These also must have an **SPI interface** and **DIO_0** pin connected to the MCU directly. +These also must have an **SPI interface** and **DIO_0 (sometimes called DIO_1)** pin connected to the MCU directly. ## One Tool, Many Uses From 721cee3603a9c59bd62d2907cd3b57c1b59fb086 Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Tue, 6 Aug 2024 17:37:47 +0100 Subject: [PATCH 7/9] Fix SPI semaphore lockup issue on ESP32 --- Boards.h | 17 ----- RNode_Firmware_CE.ino | 35 ++++++--- Radio.cpp | 160 +++++++++++++++++++++--------------------- Radio.h => Radio.hpp | 12 ++-- Utilities.h | 2 +- 5 files changed, 112 insertions(+), 114 deletions(-) rename Radio.h => Radio.hpp (97%) diff --git a/Boards.h b/Boards.h index c8c4d94..75f5284 100644 --- a/Boards.h +++ b/Boards.h @@ -726,17 +726,6 @@ }; #endif - #define INTERFACE_SPI - // Required because on RAK4631, non-default SPI pins must be initialised when class is declared. - const SPIClass interface_spi[1] = { - // SX1262 - SPIClass( - NRF_SPIM2, - interface_pins[0][3], - interface_pins[0][1], - interface_pins[0][2] - ) - }; const int pin_disp_cs = SS; const int pin_disp_dc = WB_IO1; @@ -752,10 +741,4 @@ #endif #endif - #ifndef INTERFACE_SPI - // INTERFACE_SPI is only required on NRF52 platforms, as the SPI pins are set in the class constructor and not by a setter method. - // Even if custom SPI interfaces are not needed, the array must exist to prevent compilation errors. - #define INTERFACE_SPI - const SPIClass interface_spi[1]; - #endif #endif diff --git a/RNode_Firmware_CE.ino b/RNode_Firmware_CE.ino index c91ac31..dabe7c9 100644 --- a/RNode_Firmware_CE.ino +++ b/RNode_Firmware_CE.ino @@ -17,10 +17,25 @@ #include #include "Utilities.h" -#if BOARD_MODEL == BOARD_HELTEC32_V3 -// Default stack size for loop function on Heltec32 V3 is not large enough, -// must be increased to 11kb to prevent crashes. -SET_LOOP_TASK_STACK_SIZE(11 * 1024); // 11KB +#if MCU_VARIANT == MCU_NRF52 + #define INTERFACE_SPI + // Required because on RAK4631, non-default SPI pins must be initialised when class is declared. + SPIClass interface_spi[1] = { + // SX1262 + SPIClass( + NRF_SPIM2, + interface_pins[0][3], + interface_pins[0][1], + interface_pins[0][2] + ) + }; +#endif + +#ifndef INTERFACE_SPI +// INTERFACE_SPI is only required on NRF52 platforms, as the SPI pins are set in the class constructor and not by a setter method. +// Even if custom SPI interfaces are not needed, the array must exist to prevent compilation errors. +#define INTERFACE_SPI +SPIClass interface_spi[1]; #endif FIFOBuffer serialFIFO; @@ -134,13 +149,13 @@ void setup() { sx126x* obj; // if default spi enabled if (interface_cfg[i][0]) { - obj = new sx126x(i, SPI, interface_cfg[i][1], + obj = new sx126x(i, &SPI, interface_cfg[i][1], interface_cfg[i][2], interface_pins[i][0], interface_pins[i][1], interface_pins[i][2], interface_pins[i][3], interface_pins[i][6], interface_pins[i][5], interface_pins[i][4], interface_pins[i][8]); } else { - obj = new sx126x(i, interface_spi[i], interface_cfg[i][1], + obj = new sx126x(i, &interface_spi[i], interface_cfg[i][1], interface_cfg[i][2], interface_pins[i][0], interface_pins[i][1], interface_pins[i][2], interface_pins[i][3], interface_pins[i][6], interface_pins[i][5], interface_pins[i][4], interface_pins[i][8]); @@ -157,12 +172,12 @@ void setup() { sx127x* obj; // if default spi enabled if (interface_cfg[i][0]) { - obj = new sx127x(i, SPI, interface_pins[i][0], + obj = new sx127x(i, &SPI, interface_pins[i][0], interface_pins[i][1], interface_pins[i][2], interface_pins[i][3], interface_pins[i][6], interface_pins[i][5], interface_pins[i][4]); } else { - obj = new sx127x(i, interface_spi[i], interface_pins[i][0], + obj = new sx127x(i, &interface_spi[i], interface_pins[i][0], interface_pins[i][1], interface_pins[i][2], interface_pins[i][3], interface_pins[i][6], interface_pins[i][5], interface_pins[i][4]); } @@ -177,13 +192,13 @@ void setup() { sx128x* obj; // if default spi enabled if (interface_cfg[i][0]) { - obj = new sx128x(i, SPI, interface_cfg[i][1], + obj = new sx128x(i, &SPI, interface_cfg[i][1], interface_pins[i][0], interface_pins[i][1], interface_pins[i][2], interface_pins[i][3], interface_pins[i][6], interface_pins[i][5], interface_pins[i][4], interface_pins[i][8], interface_pins[i][7]); } else { - obj = new sx128x(i, interface_spi[i], interface_cfg[i][1], + obj = new sx128x(i, &interface_spi[i], interface_cfg[i][1], interface_pins[i][0], interface_pins[i][1], interface_pins[i][2], interface_pins[i][3], interface_pins[i][6], interface_pins[i][5], interface_pins[i][4], interface_pins[i][8], interface_pins[i][7]); diff --git a/Radio.cpp b/Radio.cpp index 585cceb..cb949c2 100644 --- a/Radio.cpp +++ b/Radio.cpp @@ -4,7 +4,7 @@ // Modifications and additions copyright 2024 by Mark Qvist & Jacob Eva // Obviously still under the MIT license. -#include "Radio.h" +#include "Radio.hpp" #if PLATFORM == PLATFORM_ESP32 #if defined(ESP32) and !defined(CONFIG_IDF_TARGET_ESP32S3) @@ -106,7 +106,7 @@ void ISR_VECT onDio0Rise() { } } -sx126x::sx126x(uint8_t index, SPIClass spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen) : +sx126x::sx126x(uint8_t index, SPIClass* spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen) : RadioInterface(index), _spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), _ss(ss), _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0), @@ -130,12 +130,12 @@ bool sx126x::preInit() { // todo: check if this change causes issues on any platforms #if MCU_VARIANT == MCU_ESP32 if (_sclk != -1 && _miso != -1 && _mosi != -1 && _ss != -1) { - _spiModem.begin(_sclk, _miso, _mosi, _ss); + _spiModem->begin(_sclk, _miso, _mosi, _ss); } else { - _spiModem.begin(); + _spiModem->begin(); } #else - _spiModem.begin(); + _spiModem->begin(); #endif // check version (retry for up to 2 seconds) @@ -177,15 +177,15 @@ uint8_t ISR_VECT sx126x::singleTransfer(uint8_t opcode, uint16_t address, uint8_ digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(opcode); - _spiModem.transfer((address & 0xFF00) >> 8); - _spiModem.transfer(address & 0x00FF); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(opcode); + _spiModem->transfer((address & 0xFF00) >> 8); + _spiModem->transfer(address & 0x00FF); if (opcode == OP_READ_REGISTER_6X) { - _spiModem.transfer(0x00); + _spiModem->transfer(0x00); } - response = _spiModem.transfer(value); - _spiModem.endTransaction(); + response = _spiModem->transfer(value); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); @@ -222,15 +222,15 @@ void sx126x::executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(opcode); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(opcode); for (int i = 0; i < size; i++) { - _spiModem.transfer(buffer[i]); + _spiModem->transfer(buffer[i]); } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -241,16 +241,16 @@ void sx126x::executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(opcode); - _spiModem.transfer(0x00); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(opcode); + _spiModem->transfer(0x00); for (int i = 0; i < size; i++) { - buffer[i] = _spiModem.transfer(0x00); + buffer[i] = _spiModem->transfer(0x00); } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -261,17 +261,17 @@ void sx126x::writeBuffer(const uint8_t* buffer, size_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(OP_FIFO_WRITE_6X); - _spiModem.transfer(_fifo_tx_addr_ptr); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(OP_FIFO_WRITE_6X); + _spiModem->transfer(_fifo_tx_addr_ptr); for (int i = 0; i < size; i++) { - _spiModem.transfer(buffer[i]); + _spiModem->transfer(buffer[i]); _fifo_tx_addr_ptr++; } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -282,17 +282,17 @@ void sx126x::readBuffer(uint8_t* buffer, size_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(OP_FIFO_READ_6X); - _spiModem.transfer(_fifo_rx_addr_ptr); - _spiModem.transfer(0x00); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(OP_FIFO_READ_6X); + _spiModem->transfer(_fifo_rx_addr_ptr); + _spiModem->transfer(0x00); for (int i = 0; i < size; i++) { - buffer[i] = _spiModem.transfer(0x00); + buffer[i] = _spiModem->transfer(0x00); } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -451,7 +451,7 @@ void sx126x::end() sleep(); // stop SPI - _spiModem.end(); + _spiModem->end(); _bitrate = 0; @@ -676,7 +676,7 @@ void sx126x::onReceive(void(*callback)(uint8_t, int)) executeOpcode(OP_SET_IRQ_FLAGS_6X, buf, 8); #ifdef SPI_HAS_NOTUSINGINTERRUPT - _spiModem.usingInterrupt(digitalPinToInterrupt(_dio0)); + _spiModem->usingInterrupt(digitalPinToInterrupt(_dio0)); #endif // make function available extern void onDio0Rise(); @@ -685,7 +685,7 @@ void sx126x::onReceive(void(*callback)(uint8_t, int)) } else { detachInterrupt(digitalPinToInterrupt(_dio0)); #ifdef SPI_HAS_NOTUSINGINTERRUPT - _spiModem.notUsingInterrupt(digitalPinToInterrupt(_dio0)); + _spiModem->notUsingInterrupt(digitalPinToInterrupt(_dio0)); #endif } } @@ -1081,7 +1081,7 @@ void sx126x::clearIRQStatus() { #define SYNC_WORD_7X 0x12 -sx127x::sx127x(uint8_t index, SPIClass spi, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy) : +sx127x::sx127x(uint8_t index, SPIClass* spi, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy) : RadioInterface(index), _spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), @@ -1116,12 +1116,12 @@ bool sx127x::preInit() { // todo: check if this change causes issues on any platforms #if MCU_VARIANT == MCU_ESP32 if (_sclk != -1 && _miso != -1 && _mosi != -1 && _ss != -1) { - _spiModem.begin(_sclk, _miso, _mosi, _ss); + _spiModem->begin(_sclk, _miso, _mosi, _ss); } else { - _spiModem.begin(); + _spiModem->begin(); } #else - _spiModem.begin(); + _spiModem->begin(); #endif // Check modem version @@ -1143,10 +1143,10 @@ uint8_t ISR_VECT sx127x::singleTransfer(uint8_t address, uint8_t value) { uint8_t response; digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(address); - response = _spiModem.transfer(value); - _spiModem.endTransaction(); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(address); + response = _spiModem->transfer(value); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); return response; @@ -1193,7 +1193,7 @@ int sx127x::begin() { void sx127x::end() { sleep(); - _spiModem.end(); + _spiModem->end(); _bitrate = 0; _radio_online = false; _preinit_done = false; @@ -1331,7 +1331,7 @@ void sx127x::onReceive(void(*callback)(uint8_t, int)) { writeRegister(REG_DIO_MAPPING_1_7X, 0x00); #ifdef SPI_HAS_NOTUSINGINTERRUPT - _spiModem.usingInterrupt(digitalPinToInterrupt(_dio0)); + _spiModem->usingInterrupt(digitalPinToInterrupt(_dio0)); #endif // make function available @@ -1343,7 +1343,7 @@ void sx127x::onReceive(void(*callback)(uint8_t, int)) { detachInterrupt(digitalPinToInterrupt(_dio0)); #ifdef SPI_HAS_NOTUSINGINTERRUPT - _spiModem.notUsingInterrupt(digitalPinToInterrupt(_dio0)); + _spiModem->notUsingInterrupt(digitalPinToInterrupt(_dio0)); #endif } } @@ -1599,7 +1599,7 @@ void sx127x::clearIRQStatus() { #define FREQ_DIV_8X (double)pow(2.0, 18.0) #define FREQ_STEP_8X (double)(XTAL_FREQ_8X / FREQ_DIV_8X) -sx128x::sx128x(uint8_t index, SPIClass spi, bool tcxo, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen, int txen) : +sx128x::sx128x(uint8_t index, SPIClass* spi, bool tcxo, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen, int txen) : RadioInterface(index), _spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), @@ -1626,12 +1626,12 @@ bool sx128x::preInit() { // todo: check if this change causes issues on any platforms #if MCU_VARIANT == MCU_ESP32 if (_sclk != -1 && _miso != -1 && _mosi != -1 && _ss != -1) { - _spiModem.begin(_sclk, _miso, _mosi, _ss); + _spiModem->begin(_sclk, _miso, _mosi, _ss); } else { - _spiModem.begin(); + _spiModem->begin(); } #else - _spiModem.begin(); + _spiModem->begin(); #endif // check version (retry for up to 2 seconds) @@ -1676,15 +1676,15 @@ uint8_t ISR_VECT sx128x::singleTransfer(uint8_t opcode, uint16_t address, uint8_ digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(opcode); - _spiModem.transfer((address & 0xFF00) >> 8); - _spiModem.transfer(address & 0x00FF); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(opcode); + _spiModem->transfer((address & 0xFF00) >> 8); + _spiModem->transfer(address & 0x00FF); if (opcode == OP_READ_REGISTER_8X) { - _spiModem.transfer(0x00); + _spiModem->transfer(0x00); } - response = _spiModem.transfer(value); - _spiModem.endTransaction(); + response = _spiModem->transfer(value); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); @@ -1734,15 +1734,15 @@ void sx128x::executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(opcode); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(opcode); for (int i = 0; i < size; i++) { - _spiModem.transfer(buffer[i]); + _spiModem->transfer(buffer[i]); } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -1753,16 +1753,16 @@ void sx128x::executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(opcode); - _spiModem.transfer(0x00); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(opcode); + _spiModem->transfer(0x00); for (int i = 0; i < size; i++) { - buffer[i] = _spiModem.transfer(0x00); + buffer[i] = _spiModem->transfer(0x00); } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -1773,17 +1773,17 @@ void sx128x::writeBuffer(const uint8_t* buffer, size_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(OP_FIFO_WRITE_8X); - _spiModem.transfer(_fifo_tx_addr_ptr); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(OP_FIFO_WRITE_8X); + _spiModem->transfer(_fifo_tx_addr_ptr); for (int i = 0; i < size; i++) { - _spiModem.transfer(buffer[i]); + _spiModem->transfer(buffer[i]); _fifo_tx_addr_ptr++; } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -1794,17 +1794,17 @@ void sx128x::readBuffer(uint8_t* buffer, size_t size) digitalWrite(_ss, LOW); - _spiModem.beginTransaction(_spiSettings); - _spiModem.transfer(OP_FIFO_READ_8X); - _spiModem.transfer(_fifo_rx_addr_ptr); - _spiModem.transfer(0x00); + _spiModem->beginTransaction(_spiSettings); + _spiModem->transfer(OP_FIFO_READ_8X); + _spiModem->transfer(_fifo_rx_addr_ptr); + _spiModem->transfer(0x00); for (int i = 0; i < size; i++) { - buffer[i] = _spiModem.transfer(0x00); + buffer[i] = _spiModem->transfer(0x00); } - _spiModem.endTransaction(); + _spiModem->endTransaction(); digitalWrite(_ss, HIGH); } @@ -1921,7 +1921,7 @@ void sx128x::end() sleep(); // stop SPI - _spiModem.end(); + _spiModem->end(); _bitrate = 0; @@ -2130,7 +2130,7 @@ void sx128x::onReceive(void(*callback)(uint8_t, int)) executeOpcode(OP_SET_IRQ_FLAGS_8X, buf, 8); //#ifdef SPI_HAS_NOTUSINGINTERRUPT -// _spiModem.usingInterrupt(digitalPinToInterrupt(_dio0)); +// _spiModem->usingInterrupt(digitalPinToInterrupt(_dio0)); //#endif // make function available @@ -2140,7 +2140,7 @@ void sx128x::onReceive(void(*callback)(uint8_t, int)) } else { detachInterrupt(digitalPinToInterrupt(_dio0)); //#ifdef SPI_HAS_NOTUSINGINTERRUPT -// _spiModem.notUsingInterrupt(digitalPinToInterrupt(_dio0)); +// _spiModem->notUsingInterrupt(digitalPinToInterrupt(_dio0)); //#endif } } diff --git a/Radio.h b/Radio.hpp similarity index 97% rename from Radio.h rename to Radio.hpp index 13bb0da..fa42abd 100644 --- a/Radio.h +++ b/Radio.hpp @@ -333,7 +333,7 @@ protected: class sx126x : public RadioInterface { public: - sx126x(uint8_t index, SPIClass spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int + sx126x(uint8_t index, SPIClass* spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen); int begin(); @@ -425,7 +425,7 @@ private: private: SPISettings _spiSettings; - SPIClass _spiModem; + SPIClass* _spiModem; int _ss; int _sclk; int _mosi; @@ -454,7 +454,7 @@ private: class sx127x : public RadioInterface { public: - sx127x(uint8_t index, SPIClass spi, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy); + sx127x(uint8_t index, SPIClass* spi, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy); int begin(); void end(); @@ -529,7 +529,7 @@ private: private: SPISettings _spiSettings; - SPIClass _spiModem; + SPIClass* _spiModem; int _ss; int _sclk; int _mosi; @@ -548,7 +548,7 @@ private: class sx128x : public RadioInterface { public: - sx128x(uint8_t index, SPIClass spi, bool tcxo, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen, int txen); + sx128x(uint8_t index, SPIClass* spi, bool tcxo, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen, int txen); int begin(); void end(); @@ -636,7 +636,7 @@ private: private: SPISettings _spiSettings; - SPIClass _spiModem; + SPIClass* _spiModem; int _ss; int _sclk; int _mosi; diff --git a/Utilities.h b/Utilities.h index 3f0a8b8..2d82b15 100644 --- a/Utilities.h +++ b/Utilities.h @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "Radio.h" +#include "Radio.hpp" #include "Config.h" // Included for sorting From d7f2de07c03d134dbf577b72644c044d935895fc Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Wed, 21 Aug 2024 11:01:38 +0100 Subject: [PATCH 8/9] Fix BLE pairing behaviour and disable just works pairing --- Bluetooth.h | 54 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/Bluetooth.h b/Bluetooth.h index fb0abe4..18b3051 100644 --- a/Bluetooth.h +++ b/Bluetooth.h @@ -259,9 +259,34 @@ void bt_disable_pairing() { void bt_pairing_complete(uint16_t conn_handle, uint8_t auth_status) { if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) { - bt_state = BT_STATE_CONNECTED; - cable_state = CABLE_STATE_DISCONNECTED; - bt_disable_pairing(); + BLEConnection* connection = Bluefruit.Connection(conn_handle); + + ble_gap_conn_sec_mode_t security = connection->getSecureMode(); + + // On the NRF52 it is not possible with the Arduino library to reject + // requests from devices with no IO capabilities, which would allow + // bypassing pin entry through pairing using the "just works" mode. + // Therefore, we must check the security level of the connection after + // pairing to ensure "just works" has not been used. If it has, we need + // to disconnect, unpair and delete any bonding information immediately. + // Settings on the SerialBT service should prevent unauthorised access to + // the serial port anyway, but this is still wise to do regardless. + // + // Note: It may be nice to have this done in the BLESecurity class in the + // future, but as it stands right now I'd have to fork the BSP to do + // that, which I don't fancy doing. Impact on security is likely minimal. + // Requires investigation. + + if (security.sm == 1 && security.lv >= 3) { + bt_state = BT_STATE_CONNECTED; + cable_state = CABLE_STATE_DISCONNECTED; + bt_disable_pairing(); + } else { + if (connection->bonded()) { + connection->removeBondKey(); + } + connection->disconnect(); + } } else { bt_ssp_pin = 0; } @@ -273,21 +298,21 @@ bool bt_passkey_callback(uint16_t conn_handle, uint8_t const passkey[6], bool ma bt_ssp_pin += ((int)passkey[i] - 48) * pow(10, 5-i); } kiss_indicate_btpin(); - if (match_request) { - if (bt_allow_pairing) { - return true; - } + if (bt_allow_pairing) { + return true; } return false; } void bt_connect_callback(uint16_t conn_handle) { - bt_state = BT_STATE_CONNECTED; - cable_state = CABLE_STATE_DISCONNECTED; + bt_state = BT_STATE_CONNECTED; + cable_state = CABLE_STATE_DISCONNECTED; } void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) { - bt_state = BT_STATE_ON; + if (reason != BLE_GAP_SEC_STATUS_SUCCESS) { + bt_state = BT_STATE_ON; + } } bool bt_setup_hw() { @@ -305,7 +330,14 @@ bool bt_setup_hw() { Bluefruit.autoConnLed(false); if (Bluefruit.begin()) { Bluefruit.setTxPower(8); // Check bluefruit.h for supported values - Bluefruit.Security.setIOCaps(true, true, false); + Bluefruit.Security.setIOCaps(true, false, false); // display, yes; yes / no, no; keyboard, no + // This device is indeed capable of yes / no through the pairing mode + // being set, but I have chosen to set it thus to force the input of the + // pin on the device initiating the pairing. This prevents it from being + // paired with automatically by a hypothetical malicious device nearby + // without physical access to the RNode. + + Bluefruit.Security.setMITM(true); Bluefruit.Security.setPairPasskeyCallback(bt_passkey_callback); Bluefruit.Periph.setConnectCallback(bt_connect_callback); Bluefruit.Periph.setDisconnectCallback(bt_disconnect_callback); From 7f05a4fd9f27ce057a4f710466a61f852c26b9eb Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Wed, 21 Aug 2024 17:54:38 +0100 Subject: [PATCH 9/9] Fix weird behaviour with queue sizing --- RNode_Firmware_CE.ino | 6 +++--- Utilities.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RNode_Firmware_CE.ino b/RNode_Firmware_CE.ino index dabe7c9..639afda 100644 --- a/RNode_Firmware_CE.ino +++ b/RNode_Firmware_CE.ino @@ -137,7 +137,7 @@ void setup() { for (int i = 0; i < INTERFACE_COUNT; i++) { fifo16_init(&packet_starts[i], packet_starts_buf, CONFIG_QUEUE_MAX_LENGTH); fifo16_init(&packet_lengths[i], packet_lengths_buf, CONFIG_QUEUE_MAX_LENGTH); - packet_queue[i] = (uint8_t*)malloc(getQueueSize(i)); + packet_queue[i] = (uint8_t*)malloc(getQueueSize(i)+1); } // Create and configure interface objects @@ -585,9 +585,9 @@ void serialCallback(uint8_t sbyte) { if (getInterfaceIndex(command) < INTERFACE_COUNT) { uint8_t index = getInterfaceIndex(command); - if (!fifo16_isfull(&packet_starts[index]) && queued_bytes[index] < (getQueueSize(index))) { + if (!fifo16_isfull(&packet_starts[index]) && (queued_bytes[index] < (getQueueSize(index)))) { uint16_t s = current_packet_start[index]; - int16_t e = queue_cursor[index]-1; if (e == -1) e = (getQueueSize(index))-1; + uint16_t e = queue_cursor[index]-1; if (e == -1) e = (getQueueSize(index))-1; uint16_t l; if (s != e) { diff --git a/Utilities.h b/Utilities.h index 2d82b15..95def2f 100644 --- a/Utilities.h +++ b/Utilities.h @@ -1100,7 +1100,7 @@ uint8_t getInterfaceCommandByte(uint8_t index) { } } -uint32_t getQueueSize(uint8_t index) { +uint16_t getQueueSize(uint8_t index) { switch (index) { case 0: return CONFIG_QUEUE_0_SIZE;