From 8e793dc55e0287de8506413bace968c5e84cd629 Mon Sep 17 00:00:00 2001 From: taco Date: Thu, 20 Feb 2025 22:24:46 +1100 Subject: [PATCH] Faketec board support, including build targets --- boards/supermini_nrf52840.json | 78 +++++++++++ examples/companion_radio/main.cpp | 6 + examples/simple_repeater/main.cpp | 4 + examples/simple_room_server/main.cpp | 4 + examples/simple_secure_chat/main.cpp | 4 + platformio.ini | 88 ++++++++++++ src/helpers/nrf52/faketecBoard.cpp | 63 +++++++++ src/helpers/nrf52/faketecBoard.h | 61 ++++++++ variants/supermini_nrf52840/variant.cpp | 52 +++++++ variants/supermini_nrf52840/variant.h | 176 ++++++++++++++++++++++++ 10 files changed, 536 insertions(+) create mode 100644 boards/supermini_nrf52840.json create mode 100644 src/helpers/nrf52/faketecBoard.cpp create mode 100644 src/helpers/nrf52/faketecBoard.h create mode 100644 variants/supermini_nrf52840/variant.cpp create mode 100644 variants/supermini_nrf52840/variant.h diff --git a/boards/supermini_nrf52840.json b/boards/supermini_nrf52840.json new file mode 100644 index 00000000..328c0c9d --- /dev/null +++ b/boards/supermini_nrf52840.json @@ -0,0 +1,78 @@ +{ + "build": { + "arduino":{ + "ldscript": "nrf52840_s140_v6.ld" + }, + "core": "nRF5", + "cpu": "cortex-m4", + "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA", + "f_cpu": "64000000L", + "hwids": [ + [ + "0x239A", + "0x00B3" + ], + [ + "0x239A", + "0x8029" + ], + [ + "0x239A", + "0x0029" + ], + [ + "0x239A", + "0x002A" + ], + [ + "0x239A", + "0x802A" + ] + ], + "usb_product": "SuperMini nRF52840", + "mcu": "nrf52840", + "variant": "supermini_nrf52840", + "variants_dir": "variants", + "bsp": { + "name": "adafruit" + }, + "softdevice": { + "sd_flags": "-DS140", + "sd_name": "s140", + "sd_version": "6.1.1", + "sd_fwid": "0x00B6" + }, + "bootloader": { + "settings_addr": "0xFF000" + } + }, + "connectivity": [ + "bluetooth" + ], + "debug": { + "jlink_device": "nRF52840_xxAA", + "svd_path": "nrf52840.svd" + }, + "frameworks": [ + "arduino", + "zephyr" + ], + "name": "Nologo SuperMini nRF52840", + "upload": { + "maximum_ram_size": 248832, + "maximum_size": 815104, + "speed": 115200, + "protocol": "nrfutil", + "protocols": [ + "jlink", + "nrfjprog", + "nrfutil", + "stlink" + ], + "use_1200bps_touch": true, + "require_upload_port": true, + "wait_for_upload_port": true + }, + "url": "https://www.nologo.tech/en/product/otherboard/NRF52840.html", + "vendor": "Nologo" + } \ No newline at end of file diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 833e41d8..75dbfba1 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -92,6 +92,10 @@ #include #include static TechoBoard board; +#elif defined(FAKETEC) + #include + #include + static faketecBoard board; #else #error "need to provide a 'board' object" #endif @@ -1290,7 +1294,9 @@ void setup() { sprintf(dev_name, "MeshCore-%s", the_mesh.getNodeName()); serial_interface.begin(dev_name, the_mesh.getBLEPin()); #else +#ifdef RAK_4631 pinMode(WB_IO2, OUTPUT); +#endif serial_interface.begin(Serial); #endif the_mesh.startInterface(serial_interface); diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index 5743647b..3f57e814 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -96,6 +96,10 @@ #include #include static TechoBoard board; +#elif defined(FAKETEC) + #include + #include + static faketecBoard board; #else #error "need to provide a 'board' object" #endif diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index 285d59c6..76412d90 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -100,6 +100,10 @@ #include #include static TechoBoard board; +#elif defined(FAKETEC) + #include + #include + static faketecBoard board; #else #error "need to provide a 'board' object" #endif diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index 951d51dc..64e5c321 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -78,6 +78,10 @@ #include #include static T1000eBoard board; +#elif defined(FAKETEC) + #include + #include + static faketecBoard board; #else #error "need to provide a 'board' object" #endif diff --git a/platformio.ini b/platformio.ini index 02ce189c..a1e154ce 100644 --- a/platformio.ini +++ b/platformio.ini @@ -947,3 +947,91 @@ build_src_filter = ${LilyGo_Techo.build_src_filter} lib_deps = ${LilyGo_Techo.lib_deps} densaugeo/base64 @ ~1.4.0 + + +[faketec] +extends = nrf52840_base +board = supermini_nrf52840 +#board_check = true +build_src_filter = ${nrf52840_base.build_src_filter} + +build_flags = ${nrf52840_base.build_flags} + -D FAKETEC + -D RADIO_CLASS=CustomSX1262 + -D WRAPPER_CLASS=CustomSX1262Wrapper + -D LORA_TX_POWER=22 + -D SX126X_CURRENT_LIMIT=130 + +[env:Faketec_Repeater] +extends = faketec +build_src_filter = ${faketec.build_src_filter} +<../examples/simple_repeater/main.cpp> +build_flags = + ${faketec.build_flags} + -D ADVERT_NAME="\"Faketec Repeater\"" + -D ADVERT_LAT=-37.0 + -D ADVERT_LON=145.0 + -D ADMIN_PASSWORD="\"password\"" +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +lib_deps = + ${faketec.lib_deps} + adafruit/RTClib @ ^2.1.3 + +[env:Faketec_room_server] +extends = faketec +build_src_filter = ${faketec.build_src_filter} +<../examples/simple_room_server/main.cpp> +build_flags = + ${faketec.build_flags} + -D ADVERT_NAME="\"Test Room\"" + -D ADVERT_LAT=-37.0 + -D ADVERT_LON=145.0 + -D ADMIN_PASSWORD="\"password\"" + -D ROOM_PASSWORD="\"hello\"" +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +lib_deps = + ${faketec.lib_deps} + adafruit/RTClib @ ^2.1.3 + +[env:Faketec_terminal_chat] +extends = faketec +build_flags = + ${faketec.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${faketec.build_src_filter} +<../examples/simple_secure_chat/main.cpp> +lib_deps = + ${faketec.lib_deps} + densaugeo/base64 @ ~1.4.0 + adafruit/RTClib @ ^2.1.3 + +[env:Faketec_companion_radio_usb] +extends = faketec +build_flags = + ${faketec.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=1 +; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1 +; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1 +build_src_filter = ${faketec.build_src_filter} +<../examples/companion_radio/main.cpp> +lib_deps = + ${faketec.lib_deps} + adafruit/RTClib @ ^2.1.3 + densaugeo/base64 @ ~1.4.0 + +[env:Faketec_companion_radio_ble] +extends = faketec +build_flags = + ${faketec.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=1 + -D BLE_PIN_CODE=123456 + -D BLE_DEBUG_LOGGING=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${faketec.build_src_filter} + +<../examples/companion_radio/main.cpp> +lib_deps = + ${faketec.lib_deps} + adafruit/RTClib @ ^2.1.3 + densaugeo/base64 @ ~1.4.0 \ No newline at end of file diff --git a/src/helpers/nrf52/faketecBoard.cpp b/src/helpers/nrf52/faketecBoard.cpp new file mode 100644 index 00000000..6ef294bc --- /dev/null +++ b/src/helpers/nrf52/faketecBoard.cpp @@ -0,0 +1,63 @@ +#include +#include "faketecBoard.h" + +#include +#include + +static BLEDfu bledfu; + +static void connect_callback(uint16_t conn_handle) +{ + (void)conn_handle; + MESH_DEBUG_PRINTLN("BLE client connected"); +} + +static void disconnect_callback(uint16_t conn_handle, uint8_t reason) +{ + (void)conn_handle; + (void)reason; + + MESH_DEBUG_PRINTLN("BLE client disconnected"); +} + +bool faketecBoard::startOTAUpdate() { + // Config the peripheral connection with maximum bandwidth + // more SRAM required by SoftDevice + // Note: All config***() function must be called before begin() + Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); + Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16); + + Bluefruit.begin(1, 0); + // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 + Bluefruit.setTxPower(4); + // Set the BLE device name + Bluefruit.setName("Faketec_OTA"); + + Bluefruit.Periph.setConnectCallback(connect_callback); + Bluefruit.Periph.setDisconnectCallback(disconnect_callback); + + // To be consistent OTA DFU should be added first if it exists + bledfu.begin(); + + // Set up and start advertising + // Advertising packet + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + Bluefruit.Advertising.addName(); + + /* Start Advertising + - Enable auto advertising if disconnected + - Interval: fast mode = 20 ms, slow mode = 152.5 ms + - Timeout for fast mode is 30 seconds + - Start(timeout) with timeout = 0 will advertise forever (until connected) + + For recommended advertising interval + https://developer.apple.com/library/content/qa/qa1931/_index.html + */ + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds + + return true; +} diff --git a/src/helpers/nrf52/faketecBoard.h b/src/helpers/nrf52/faketecBoard.h new file mode 100644 index 00000000..42ea37dc --- /dev/null +++ b/src/helpers/nrf52/faketecBoard.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#define P_LORA_NSS D13 +#define P_LORA_DIO_1 D11 +#define P_LORA_RESET D10 +#define P_LORA_BUSY D16 +#define P_LORA_MISO D15 +#define P_LORA_SCLK D12 +#define P_LORA_MOSI D14 +#define SX126X_POWER_EN EXT_VCC + +#define SX126X_DIO2_AS_RF_SWITCH true +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 + +#define PIN_VBAT_READ PIN_A2 +#define ADC_MULTIPLIER (1.815) // dependent on voltage divider resistors. TODO: more accurate battery tracking + +class faketecBoard : public mesh::MainBoard { +protected: + uint8_t startup_reason; + +public: + void begin() { + // for future use, sub-classes SHOULD call this from their begin() + startup_reason = BD_STARTUP_NORMAL; + + pinMode(PIN_VBAT_READ, INPUT); + + pinMode(SX126X_POWER_EN, OUTPUT); + digitalWrite(SX126X_POWER_EN, HIGH); + delay(10); // give sx1262 some time to power up + } + + uint8_t getStartupReason() const override { return startup_reason; } + + #define BATTERY_SAMPLES 8 + + uint16_t getBattMilliVolts() override { + analogReadResolution(12); + + uint32_t raw = 0; + for (int i = 0; i < BATTERY_SAMPLES; i++) { + raw += analogRead(PIN_VBAT_READ); + } + raw = raw / BATTERY_SAMPLES; + return (ADC_MULTIPLIER * raw); + } + + const char* getManufacturerName() const override { + return "Faketec DIY"; + } + + void reboot() override { + NVIC_SystemReset(); + } + + bool startOTAUpdate() override; +}; diff --git a/variants/supermini_nrf52840/variant.cpp b/variants/supermini_nrf52840/variant.cpp new file mode 100644 index 00000000..2e832f31 --- /dev/null +++ b/variants/supermini_nrf52840/variant.cpp @@ -0,0 +1,52 @@ +#include "variant.h" +#include "wiring_constants.h" +#include "wiring_digital.h" +#include "nrf.h" + +const uint32_t g_ADigitalPinMap[] = +{ + // D0 - D9 (left side, top to bottom) + 6, // D0 is P0.06 (D0, TX) + 8, // D1 is P0.08 (D1, RX) + 17, // D2 is P0.17 (D2, SCK) + 20, // D3 is P0.20 (D3, MISO) + 22, // D4 is P0.22 (D4, MOSI) + 24, // D5 is P0.24 (D5, CS) + 32, // D6 is P1.00 (D6, SDA) + 11, // D7 is P0.11 (D7, SCL) + 36, // D8 is P1.04 (D8) + 38, // D9 is P1.06 (D9) + + // D10 - D17 (right side, bottom to top) + 9, // D10 is P0.09 (D10, NFC1) + 10, // D11 is P0.10 (D11, NFC2) + 43, // D12 is P1.11 (D12) + 45, // D13 is P1.13 (D13, SDA1) + 47, // D14 is P1.15 (D14, SCL1) + 2, // D15 is P0.02 (D15, A0) + 29, // D16 is P0.29 (D16, A1) + 31, // D17 is P0.31 (D17, A2) + + // D18 - D20 (extra center pins, left to right) + 33, // D18 is P1.01 (D18, SCK1) + 34, // D19 is P1.02 (D19, MISO1) + 39, // D20 is P1.07 (D20, MOSI1) + + // EXT_VCC + 13, // 'D21' is P0.13 (EXT_VCC) [active high] + + // LED + 15, // 'D22' is P0.15 (LED) +}; + +void initVariant() +{ + // enable EXT_VCC by default + pinMode(EXT_VCC, OUTPUT); + digitalWrite(EXT_VCC, HIGH); + + // enable LED by default + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); +} + diff --git a/variants/supermini_nrf52840/variant.h b/variants/supermini_nrf52840/variant.h new file mode 100644 index 00000000..b7b59c8e --- /dev/null +++ b/variants/supermini_nrf52840/variant.h @@ -0,0 +1,176 @@ +#ifndef _SUPERMINI_NRF52840_H_ +#define _SUPERMINI_NRF52840_H_ + +#define TARGET_SUPERMINI_NRF52840 + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +//#define USE_LFXO // Board uses 32khz crystal for LF +#define USE_LFRC // Board uses RC for LF + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +#define PINS_COUNT (23) +#define NUM_DIGITAL_PINS (23) +#define NUM_ANALOG_INPUTS (3) +#define NUM_ANALOG_OUTPUTS (0) + +// NOTE: +// +// BATTERY VOLTAGE IS READ VIA VDDH/5 BY CALLING +// +// analogReadVDDHDIV5() // returns uint32_t + +// 3V3 Regulator Disable +#define PIN_EXT_VCC (21) // EXT_VCC is P0.13 (set low to disable 3v3) +#define EXT_VCC (PIN_EXT_VCC) + +// LEDs +#define PIN_LED (22) // USR LED is P0.15 +#define LED_PWR (PINS_COUNT) // no LED_PWR +#define PIN_NEOPIXEL (PINS_COUNT) // no neopixel +#define NEOPIXEL_NUM 0 +#define LED_BLUE PIN_LED // required by bluefruit library + +#define LED_BUILTIN PIN_LED + +#define LED_STATE_ON 1 // State when LED is on + +/* + * Buttons + */ +#define PIN_BUTTON1 (PINS_COUNT) // no button + +// Digital PINs +// NOTE: THIS IS A RENUMBERING OF THE PINS +// AND DOES NOT CORRESPOND TO THE NICENANO DIAGRAM + +// left side (top to bottom) +#define D0 (0ul) // P0.06 (TX) +#define D1 (1ul) // P0.08 (RX) +#define D2 (2ul) // P0.17 (SCK) +#define D3 (3ul) // P0.20 (MISO) +#define D4 (4ul) // P0.22 (MOSI) +#define D5 (5ul) // P0.24 (CS) +#define D6 (6ul) // P1.00 (SDA) +#define D7 (7ul) // P0.11 (SCL) +#define D8 (8ul) // P1.04 +#define D9 (9ul) // P1.06 + +// right side (bottom to top) +#define D10 (10ul) // P0.09 (NFC1) +#define D11 (11ul) // P0.10 (NFC2) +#define D12 (12ul) // P1.11 +#define D13 (13ul) // P1.13 (SDA1) +#define D14 (14ul) // P1.15 (SCL1) +#define D15 (15ul) // P0.02/AIN0 (A0) +#define D16 (16ul) // P0.29/AIN6 (A1) +#define D17 (17ul) // P0.31/AIN7 (A2) + +// extra center pins (left to right) +#define D18 (18ul) // P1.01 (SCK1) +#define D19 (19ul) // P1.02 (MISO1) +#define D20 (20ul) // P1.07 (MOSI1) + +/* + * Macros for nRF pin numbers for compatibility + */ +#define P0_06 (D0) +#define P0_08 (D1) +#define P0_17 (D2) +#define P0_20 (D3) +#define P0_22 (D4) +#define P0_24 (D5) +#define P1_00 (D6) +#define P0_11 (D7) +#define P1_04 (D8) +#define P1_06 (D9) +#define P0_09 (D10) +#define P0_10 (D11) +#define P1_11 (D12) +#define P1_13 (D13) +#define P1_15 (D14) +#define P0_02 (D15) +#define P0_29 (D16) +#define P0_31 (D17) +#define P1_01 (D18) +#define P1_02 (D19) +#define P1_07 (D20) +#define P0_13 (EXT_VCC) +#define P0_15 (PIN_LED) + +/* + * Analog pins + */ +#define PIN_A0 (15) // P0.02 (D15) +#define PIN_A1 (16) // P0.29 (D16) +#define PIN_A2 (17) // P0.31 (D17) + +static const uint8_t A0 = PIN_A0 ; +static const uint8_t A1 = PIN_A1 ; +static const uint8_t A2 = PIN_A2 ; +#define ADC_RESOLUTION 12 + +/* + * Other pins + */ +#define PIN_NFC1 (10) // P0.09 - also D10 +#define PIN_NFC2 (11) // P0.10 - also D11 + +/* + * Serial interfaces + */ +#define PIN_SERIAL1_TX (0) // P0.06 - also D0 +#define PIN_SERIAL1_RX (1) // P0.08 - also D1 + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_SCK (2) // P0.17 - D2 +#define PIN_SPI_MISO (3) // P0.20 - D3 +#define PIN_SPI_MOSI (4) // P0.22 - D4 + +static const uint8_t SS = (5); // P0.24 - D5 +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +#define PIN_SPI1_SCK (18) // P1.01 - D18 +#define PIN_SPI1_MISO (19) // P1.02 - D19 +#define PIN_SPI1_MOSI (20) // P1.07 - D20 + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 2 + +#define PIN_WIRE_SDA (6) // P1.00 - D6 +#define PIN_WIRE_SCL (7) // P0.11 - D7 + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +#define PIN_WIRE1_SDA (13) // P1.13 - D13 +#define PIN_WIRE1_SCL (14) // P1.15 - D14 + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif