diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..fcde50484 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,44 @@ +{ + "name": "MeshCore", + "image": "mcr.microsoft.com/devcontainers/python:3-bookworm", + "features": { + "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": { + "packages": [ + "sudo" + ] + } + }, + "runArgs": [ + "--privileged", + // arch tty* is owned by uucp (986) + // debian tty* is owned by uucp (20) - no change needed + "--group-add=986", + "--network=host", + "--volume=/dev/bus/usb:/dev/bus/usb:ro" + ], + "postCreateCommand": { + "platformio": "pipx install platformio" + }, + "customizations": { + "vscode": { + "settings": { + "platformio-ide.disablePIOHomeStartup": true, + "editor.formatOnSave": false, + "workbench.colorCustomizations": { + "titleBar.activeBackground": "#0d1a2b", + "titleBar.activeForeground": "#ffffff", + "titleBar.inactiveBackground": "#0d1a2b99", + "titleBar.inactiveForeground": "#ffffff99" + } + }, + "extensions": [ + "platformio.platformio-ide", + "github.vscode-github-actions", + "GitHub.vscode-pull-request-github" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] + } + } +} \ No newline at end of file diff --git a/boards/thinknode_m3.json b/boards/thinknode_m3.json new file mode 100644 index 000000000..617740b61 --- /dev/null +++ b/boards/thinknode_m3.json @@ -0,0 +1,72 @@ +{ + "build": { + "arduino": { + "ldscript": "nrf52840_s140_v6.ld" + }, + "core": "nRF5", + "cpu": "cortex-m4", + "extra_flags": "-DNRF52840_XXAA", + "f_cpu": "64000000L", + "hwids": [ + [ + "0x239A", + "0x4405" + ], + [ + "0x239A", + "0x0029" + ], + [ + "0x239A", + "0x002A" + ] + ], + "usb_product": "elecrow_eink", + "mcu": "nrf52840", + "variant": "ELECROW-ThinkNode-M3", + "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", + "onboard_tools": [ + "jlink" + ], + "svd_path": "nrf52840.svd", + "openocd_target": "nrf52.cfg" + }, + "frameworks": [ + "arduino" + ], + "name": "elecrow nrf", + "upload": { + "maximum_ram_size": 248832, + "maximum_size": 815104, + "speed": 115200, + "use_1200bps_touch": true, + "require_upload_port": true, + "wait_for_upload_port": true, + "protocol": "nrfutil", + "protocols": [ + "jlink", + "nrfjprog", + "nrfutil", + "stlink" + ] + }, + "url": "https://github.com/Elecrow-RD", + "vendor": "ELECROW" +} \ No newline at end of file diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 5fb1a729f..6ae6ac0a8 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -173,6 +173,12 @@ int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t telemetry.reset(); telemetry.addVoltage(TELEM_CHANNEL_SELF, (float)board.getBattMilliVolts() / 1000.0f); + + float temperature = board.getMCUTemperature(); + if(!isnan(temperature)) { // Supported boards with built-in temperature sensor. ESP32-C3 may return NAN + telemetry.addTemperature(TELEM_CHANNEL_SELF, temperature); // Built-in MCU Temperature + } + // query other sensors -- target specific if ((sender->permissions & PERM_ACL_ROLE_MASK) == PERM_ACL_GUEST) { perm_mask = 0x00; // just base telemetry allowed diff --git a/src/MeshCore.h b/src/MeshCore.h index 11a6a5b41..eb7940589 100644 --- a/src/MeshCore.h +++ b/src/MeshCore.h @@ -1,6 +1,7 @@ #pragma once #include +#include #define MAX_HASH_SIZE 8 #define PUB_KEY_SIZE 32 @@ -42,6 +43,7 @@ namespace mesh { class MainBoard { public: virtual uint16_t getBattMilliVolts() = 0; + virtual float getMCUTemperature() { return NAN; } virtual bool setAdcMultiplier(float multiplier) { return false; }; virtual float getAdcMultiplier() const { return 0.0f; } virtual const char* getManufacturerName() const = 0; diff --git a/src/helpers/ESP32Board.h b/src/helpers/ESP32Board.h index e566f9293..64c92c43d 100644 --- a/src/helpers/ESP32Board.h +++ b/src/helpers/ESP32Board.h @@ -42,6 +42,11 @@ class ESP32Board : public mesh::MainBoard { #endif } + // Temperature from ESP32 MCU + float getMCUTemperature() override { + return temperatureRead(); + } + uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) diff --git a/src/helpers/NRF52Board.cpp b/src/helpers/NRF52Board.cpp new file mode 100644 index 000000000..c0d58314e --- /dev/null +++ b/src/helpers/NRF52Board.cpp @@ -0,0 +1,104 @@ +#if defined(NRF52_PLATFORM) +#include "NRF52Board.h" + +#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"); +} + +void NRF52Board::begin() { + startup_reason = BD_STARTUP_NORMAL; +} + +void NRF52BoardDCDC::begin() { + NRF52Board::begin(); + + // Enable DC/DC converter for improved power efficiency + uint8_t sd_enabled = 0; + sd_softdevice_is_enabled(&sd_enabled); + if (sd_enabled) { + sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); + } else { + NRF_POWER->DCDCEN = 1; + } +} + +// Temperature from NRF52 MCU +float NRF52Board::getMCUTemperature() { + NRF_TEMP->TASKS_START = 1; // Start temperature measurement + + long startTime = millis(); + while (NRF_TEMP->EVENTS_DATARDY == 0) { // Wait for completion. Should complete in 50us + if(millis() - startTime > 5) { // To wait 5ms just in case + NRF_TEMP->TASKS_STOP = 1; + return NAN; + } + } + + NRF_TEMP->EVENTS_DATARDY = 0; // Clear event flag + + int32_t temp = NRF_TEMP->TEMP; // In 0.25 *C units + NRF_TEMP->TASKS_STOP = 1; + + return temp * 0.25f; // Convert to *C +} + +bool NRF52BoardOTA::startOTAUpdate(const char *id, char reply[]) { + // 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(ota_name); + + 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 + + uint8_t mac_addr[6]; + memset(mac_addr, 0, sizeof(mac_addr)); + Bluefruit.getAddr(mac_addr); + sprintf(reply, "OK - mac: %02X:%02X:%02X:%02X:%02X:%02X", mac_addr[5], mac_addr[4], mac_addr[3], + mac_addr[2], mac_addr[1], mac_addr[0]); + + return true; +} +#endif diff --git a/src/helpers/NRF52Board.h b/src/helpers/NRF52Board.h new file mode 100644 index 000000000..0d6c0a431 --- /dev/null +++ b/src/helpers/NRF52Board.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +#if defined(NRF52_PLATFORM) + +class NRF52Board : public mesh::MainBoard { +protected: + uint8_t startup_reason; + +public: + virtual void begin(); + virtual uint8_t getStartupReason() const override { return startup_reason; } + virtual float getMCUTemperature() override; + virtual void reboot() override { NVIC_SystemReset(); } +}; + +/* + * The NRF52 has an internal DC/DC regulator that allows increased efficiency + * compared to the LDO regulator. For being able to use it, the module/board + * needs to have the required inductors and and capacitors populated. If the + * hardware requirements are met, this subclass can be used to enable the DC/DC + * regulator. + */ +class NRF52BoardDCDC : virtual public NRF52Board { +public: + virtual void begin() override; +}; + +class NRF52BoardOTA : virtual public NRF52Board { +private: + char *ota_name; + +public: + NRF52BoardOTA(char *name) : ota_name(name) {} + virtual bool startOTAUpdate(const char *id, char reply[]) override; +}; +#endif \ No newline at end of file diff --git a/src/helpers/nrf52/SerialBLEInterface.cpp b/src/helpers/nrf52/SerialBLEInterface.cpp index b4811a207..eb1e90bb7 100644 --- a/src/helpers/nrf52/SerialBLEInterface.cpp +++ b/src/helpers/nrf52/SerialBLEInterface.cpp @@ -4,7 +4,23 @@ #include "ble_gap.h" #include "ble_hci.h" +// Magic numbers came from actual testing #define BLE_HEALTH_CHECK_INTERVAL 10000 // Advertising watchdog check every 10 seconds +#define BLE_RETRY_THROTTLE_MS 250 // Throttle retries to 250ms when queue buildup detected + +// Connection parameters (units: interval=1.25ms, timeout=10ms) +#define BLE_MIN_CONN_INTERVAL 12 // 15ms +#define BLE_MAX_CONN_INTERVAL 24 // 30ms +#define BLE_SLAVE_LATENCY 4 +#define BLE_CONN_SUP_TIMEOUT 200 // 2000ms + +// Advertising parameters +#define BLE_ADV_INTERVAL_MIN 32 // 20ms (units: 0.625ms) +#define BLE_ADV_INTERVAL_MAX 244 // 152.5ms (units: 0.625ms) +#define BLE_ADV_FAST_TIMEOUT 30 // seconds + +// RX drain buffer size for overflow protection +#define BLE_RX_DRAIN_BUF_SIZE 32 static SerialBLEInterface* instance = nullptr; @@ -38,14 +54,18 @@ void SerialBLEInterface::onSecured(uint16_t connection_handle) { // Apple: "The product will not read or use the parameters in the Peripheral Preferred Connection Parameters characteristic." // So we explicitly set it here to make Android & Apple match ble_gap_conn_params_t conn_params; - conn_params.min_conn_interval = 12; // 15ms - conn_params.max_conn_interval = 24; // 30ms - conn_params.slave_latency = 0; - conn_params.conn_sup_timeout = 200; // 2000ms + conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL; + conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL; + conn_params.slave_latency = BLE_SLAVE_LATENCY; + conn_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT; uint32_t err_code = sd_ble_gap_conn_param_update(connection_handle, &conn_params); if (err_code == NRF_SUCCESS) { - BLE_DEBUG_PRINTLN("Connection parameter update requested: 15-30ms interval, 2s timeout"); + BLE_DEBUG_PRINTLN("Connection parameter update requested: %u-%ums interval, latency=%u, %ums timeout", + conn_params.min_conn_interval * 5 / 4, // convert to ms (1.25ms units) + conn_params.max_conn_interval * 5 / 4, + conn_params.slave_latency, + conn_params.conn_sup_timeout * 10); // convert to ms (10ms units) } else { BLE_DEBUG_PRINTLN("Failed to request connection parameter update: %lu", err_code); } @@ -116,14 +136,18 @@ void SerialBLEInterface::begin(const char* device_name, uint32_t pin_code) { // Connection interval units: 1.25ms, supervision timeout units: 10ms ble_gap_conn_params_t ppcp_params; - ppcp_params.min_conn_interval = 12; // 15ms - ppcp_params.max_conn_interval = 24; // 30ms - ppcp_params.slave_latency = 0; - ppcp_params.conn_sup_timeout = 200; // 2000ms + ppcp_params.min_conn_interval = BLE_MIN_CONN_INTERVAL; + ppcp_params.max_conn_interval = BLE_MAX_CONN_INTERVAL; + ppcp_params.slave_latency = BLE_SLAVE_LATENCY; + ppcp_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT; uint32_t err_code = sd_ble_gap_ppcp_set(&ppcp_params); if (err_code == NRF_SUCCESS) { - BLE_DEBUG_PRINTLN("PPCP set: 15-30ms interval, 2s timeout"); + BLE_DEBUG_PRINTLN("PPCP set: %u-%ums interval, latency=%u, %ums timeout", + ppcp_params.min_conn_interval * 5 / 4, // convert to ms (1.25ms units) + ppcp_params.max_conn_interval * 5 / 4, + ppcp_params.slave_latency, + ppcp_params.conn_sup_timeout * 10); // convert to ms (10ms units) } else { BLE_DEBUG_PRINTLN("Failed to set PPCP: %lu", err_code); } @@ -153,8 +177,8 @@ void SerialBLEInterface::begin(const char* device_name, uint32_t pin_code) { Bluefruit.ScanResponse.addName(); - Bluefruit.Advertising.setInterval(32, 244); - Bluefruit.Advertising.setFastTimeout(30); + Bluefruit.Advertising.setInterval(BLE_ADV_INTERVAL_MIN, BLE_ADV_INTERVAL_MAX); + Bluefruit.Advertising.setFastTimeout(BLE_ADV_FAST_TIMEOUT); Bluefruit.Advertising.restartOnDisconnect(true); @@ -163,6 +187,7 @@ void SerialBLEInterface::begin(const char* device_name, uint32_t pin_code) { void SerialBLEInterface::clearBuffers() { send_queue_len = 0; recv_queue_len = 0; + _last_retry_attempt = 0; bleuart.flush(); } @@ -257,21 +282,30 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) { BLE_DEBUG_PRINTLN("writeBytes: connection invalid, clearing send queue"); send_queue_len = 0; } else { - Frame frame_to_send = send_queue[0]; - - size_t written = bleuart.write(frame_to_send.buf, frame_to_send.len); - if (written == frame_to_send.len) { - BLE_DEBUG_PRINTLN("writeBytes: sz=%u, hdr=%u", (unsigned)frame_to_send.len, (unsigned)frame_to_send.buf[0]); - shiftSendQueueLeft(); - } else if (written > 0) { - BLE_DEBUG_PRINTLN("writeBytes: partial write, sent=%u of %u, dropping corrupted frame", (unsigned)written, (unsigned)frame_to_send.len); - shiftSendQueueLeft(); - } else { - if (!isConnected()) { - BLE_DEBUG_PRINTLN("writeBytes failed: connection lost, dropping frame"); + unsigned long now = millis(); + bool throttle_active = (_last_retry_attempt > 0 && (now - _last_retry_attempt) < BLE_RETRY_THROTTLE_MS); + + if (!throttle_active) { + Frame frame_to_send = send_queue[0]; + + size_t written = bleuart.write(frame_to_send.buf, frame_to_send.len); + if (written == frame_to_send.len) { + BLE_DEBUG_PRINTLN("writeBytes: sz=%u, hdr=%u", (unsigned)frame_to_send.len, (unsigned)frame_to_send.buf[0]); + _last_retry_attempt = 0; + shiftSendQueueLeft(); + } else if (written > 0) { + BLE_DEBUG_PRINTLN("writeBytes: partial write, sent=%u of %u, dropping corrupted frame", (unsigned)written, (unsigned)frame_to_send.len); + _last_retry_attempt = 0; shiftSendQueueLeft(); } else { - BLE_DEBUG_PRINTLN("writeBytes failed (buffer full), keeping frame for retry"); + if (!isConnected()) { + BLE_DEBUG_PRINTLN("writeBytes failed: connection lost, dropping frame"); + _last_retry_attempt = 0; + shiftSendQueueLeft(); + } else { + BLE_DEBUG_PRINTLN("writeBytes failed (buffer full), keeping frame for retry"); + _last_retry_attempt = now; + } } } } @@ -329,9 +363,9 @@ void SerialBLEInterface::onBleUartRX(uint16_t conn_handle) { if (avail > MAX_FRAME_SIZE) { BLE_DEBUG_PRINTLN("onBleUartRX: WARN: BLE RX overflow, avail=%d, draining all", avail); - uint8_t drain_buf[32]; + uint8_t drain_buf[BLE_RX_DRAIN_BUF_SIZE]; while (instance->bleuart.available() > 0) { - int chunk = instance->bleuart.available() > 32 ? 32 : instance->bleuart.available(); + int chunk = instance->bleuart.available() > BLE_RX_DRAIN_BUF_SIZE ? BLE_RX_DRAIN_BUF_SIZE : instance->bleuart.available(); instance->bleuart.readBytes(drain_buf, chunk); } continue; @@ -349,5 +383,5 @@ bool SerialBLEInterface::isConnected() const { } bool SerialBLEInterface::isWriteBusy() const { - return send_queue_len >= (FRAME_QUEUE_SIZE - 1); + return send_queue_len >= (FRAME_QUEUE_SIZE * 2 / 3); } diff --git a/src/helpers/nrf52/SerialBLEInterface.h b/src/helpers/nrf52/SerialBLEInterface.h index 557b86c5e..25968d78f 100644 --- a/src/helpers/nrf52/SerialBLEInterface.h +++ b/src/helpers/nrf52/SerialBLEInterface.h @@ -13,6 +13,7 @@ class SerialBLEInterface : public BaseSerialInterface { bool _isDeviceConnected; uint16_t _conn_handle; unsigned long _last_health_check; + unsigned long _last_retry_attempt; struct Frame { uint8_t len; @@ -46,6 +47,7 @@ class SerialBLEInterface : public BaseSerialInterface { _isDeviceConnected = false; _conn_handle = BLE_CONN_HANDLE_INVALID; _last_health_check = 0; + _last_retry_attempt = 0; send_queue_len = 0; recv_queue_len = 0; } diff --git a/variants/heltec_mesh_solar/MeshSolarBoard.cpp b/variants/heltec_mesh_solar/MeshSolarBoard.cpp index 54929cd1e..bc955fb53 100644 --- a/variants/heltec_mesh_solar/MeshSolarBoard.cpp +++ b/variants/heltec_mesh_solar/MeshSolarBoard.cpp @@ -1,28 +1,10 @@ #include -#include "MeshSolarBoard.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"); -} +#include "MeshSolarBoard.h" void MeshSolarBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); meshSolarStart(); @@ -32,46 +14,3 @@ void MeshSolarBoard::begin() { Wire.begin(); } - -bool MeshSolarBoard::startOTAUpdate(const char* id, char reply[]) { - // 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("MESH_SOLAR_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 - - strcpy(reply, "OK - started"); - return true; -} diff --git a/variants/heltec_mesh_solar/MeshSolarBoard.h b/variants/heltec_mesh_solar/MeshSolarBoard.h index 3bec144f7..69437c877 100644 --- a/variants/heltec_mesh_solar/MeshSolarBoard.h +++ b/variants/heltec_mesh_solar/MeshSolarBoard.h @@ -2,6 +2,7 @@ #include #include +#include #ifdef HELTEC_MESH_SOLAR #include "meshSolarApp.h" @@ -19,14 +20,10 @@ #define SX126X_DIO2_AS_RF_SWITCH true #define SX126X_DIO3_TCXO_VOLTAGE 1.8 - -class MeshSolarBoard : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class MeshSolarBoard : public NRF52BoardOTA { public: + MeshSolarBoard() : NRF52BoardOTA("MESH_SOLAR_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } uint16_t getBattMilliVolts() override { return meshSolarGetBattVoltage(); @@ -35,10 +32,4 @@ class MeshSolarBoard : public mesh::MainBoard { const char* getManufacturerName() const override { return "Heltec Mesh Solar"; } - - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/heltec_t114/T114Board.cpp b/variants/heltec_t114/T114Board.cpp index f46a1a84b..4995e7de1 100644 --- a/variants/heltec_t114/T114Board.cpp +++ b/variants/heltec_t114/T114Board.cpp @@ -2,25 +2,9 @@ #include #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"); -} void T114Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); NRF_POWER->DCDCEN = 1; pinMode(PIN_VBAT_READ, INPUT); @@ -39,47 +23,4 @@ void T114Board::begin() { pinMode(SX126X_POWER_EN, OUTPUT); digitalWrite(SX126X_POWER_EN, HIGH); delay(10); // give sx1262 some time to power up -} - -bool T114Board::startOTAUpdate(const char *id, char reply[]) { - // 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("T114_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 - - strcpy(reply, "OK - started"); - return true; -} +} \ No newline at end of file diff --git a/variants/heltec_t114/T114Board.h b/variants/heltec_t114/T114Board.h index 0f7fc47fa..74e26455c 100644 --- a/variants/heltec_t114/T114Board.h +++ b/variants/heltec_t114/T114Board.h @@ -2,19 +2,17 @@ #include #include +#include // built-ins #define PIN_VBAT_READ 4 #define PIN_BAT_CTL 6 #define MV_LSB (3000.0F / 4096.0F) // 12-bit ADC with 3.0V input range -class T114Board : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class T114Board : public NRF52BoardOTA { public: + T114Board() : NRF52BoardOTA("T114_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -43,10 +41,6 @@ class T114Board : public mesh::MainBoard { return "Heltec T114"; } - void reboot() override { - NVIC_SystemReset(); - } - void powerOff() override { #ifdef LED_PIN digitalWrite(LED_PIN, HIGH); @@ -57,6 +51,4 @@ class T114Board : public mesh::MainBoard { #endif sd_power_system_off(); } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/heltec_t114/platformio.ini b/variants/heltec_t114/platformio.ini index 7b6f5ceef..377fbae29 100644 --- a/variants/heltec_t114/platformio.ini +++ b/variants/heltec_t114/platformio.ini @@ -6,6 +6,7 @@ extends = nrf52_base board = heltec_t114 board_build.ldscript = boards/nrf52840_s140_v6.ld build_flags = ${nrf52_base.build_flags} + ${sensor_base.build_flags} -I lib/nrf52/s140_nrf52_6.1.1_API/include -I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52 -I variants/heltec_t114 @@ -36,10 +37,11 @@ build_flags = ${nrf52_base.build_flags} -D PIN_GPS_RESET_ACTIVE=LOW build_src_filter = ${nrf52_base.build_src_filter} + + + +<../variants/heltec_t114> lib_deps = ${nrf52_base.lib_deps} - stevemarple/MicroNMEA @ ^2.0.6 + ${sensor_base.lib_deps} adafruit/Adafruit GFX Library @ ^1.12.1 debug_tool = jlink upload_protocol = nrfutil @@ -56,6 +58,8 @@ build_flags = -D ADVERT_LON=0.0 -D ADMIN_PASSWORD='"password"' -D MAX_NEIGHBOURS=50 + -D ENV_PIN_SDA=PIN_WIRE1_SDA + -D ENV_PIN_SCL=PIN_WIRE1_SCL ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 @@ -167,6 +171,8 @@ build_flags = -D ADVERT_LON=0.0 -D ADMIN_PASSWORD='"password"' -D MAX_NEIGHBOURS=50 + -D ENV_PIN_SDA=PIN_WIRE1_SDA + -D ENV_PIN_SCL=PIN_WIRE1_SCL ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 diff --git a/variants/heltec_t114/target.cpp b/variants/heltec_t114/target.cpp index c3341103a..6202b4599 100644 --- a/variants/heltec_t114/target.cpp +++ b/variants/heltec_t114/target.cpp @@ -1,7 +1,6 @@ #include #include "target.h" #include -#include T114Board board; @@ -11,8 +10,15 @@ WRAPPER_CLASS radio_driver(radio, board); VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); -T114SensorManager sensors = T114SensorManager(nmea); + +#if ENV_INCLUDE_GPS + #include + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); + EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else + EnvironmentSensorManager sensors; +#endif + #ifdef DISPLAY_CLASS DISPLAY_CLASS display; @@ -43,91 +49,4 @@ void radio_set_tx_power(uint8_t dbm) { mesh::LocalIdentity radio_new_identity() { RadioNoiseListener rng(radio); return mesh::LocalIdentity(&rng); // create new random identity -} - -void T114SensorManager::start_gps() { - if (!gps_active) { - gps_active = true; - _location->begin(); - } -} - -void T114SensorManager::stop_gps() { - if (gps_active) { - gps_active = false; - _location->stop(); - } -} - -bool T114SensorManager::begin() { - Serial1.begin(9600); - - // Try to detect if GPS is physically connected to determine if we should expose the setting - pinMode(GPS_EN, OUTPUT); - digitalWrite(GPS_EN, HIGH); // Power on GPS - - // Give GPS a moment to power up and send data - delay(1500); - - // We'll consider GPS detected if we see any data on Serial1 - gps_detected = (Serial1.available() > 0); - - if (gps_detected) { - MESH_DEBUG_PRINTLN("GPS detected"); - } else { - MESH_DEBUG_PRINTLN("No GPS detected"); - } - digitalWrite(GPS_EN, LOW); // Power off GPS until the setting is changed - - return true; -} - -bool T114SensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) { - if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission? - telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude); - } - return true; -} - -void T114SensorManager::loop() { - static long next_gps_update = 0; - - _location->loop(); - - if (millis() > next_gps_update) { - if (_location->isValid()) { - node_lat = ((double)_location->getLatitude())/1000000.; - node_lon = ((double)_location->getLongitude())/1000000.; - node_altitude = ((double)_location->getAltitude()) / 1000.0; - MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon); - } - next_gps_update = millis() + 1000; - } -} - -int T114SensorManager::getNumSettings() const { - return gps_detected ? 1 : 0; // only show GPS setting if GPS is detected -} - -const char* T114SensorManager::getSettingName(int i) const { - return (gps_detected && i == 0) ? "gps" : NULL; -} - -const char* T114SensorManager::getSettingValue(int i) const { - if (gps_detected && i == 0) { - return gps_active ? "1" : "0"; - } - return NULL; -} - -bool T114SensorManager::setSettingValue(const char* name, const char* value) { - if (gps_detected && strcmp(name, "gps") == 0) { - if (strcmp(value, "0") == 0) { - stop_gps(); - } else { - start_gps(); - } - return true; - } - return false; // not supported -} +} \ No newline at end of file diff --git a/variants/heltec_t114/target.h b/variants/heltec_t114/target.h index 6306cd699..d2cd76669 100644 --- a/variants/heltec_t114/target.h +++ b/variants/heltec_t114/target.h @@ -6,8 +6,6 @@ #include #include #include -#include -#include #ifdef DISPLAY_CLASS #include @@ -18,29 +16,12 @@ #endif #endif -class T114SensorManager : public SensorManager { - bool gps_active = false; - bool gps_detected = false; - LocationProvider* _location; - - void start_gps(); - void stop_gps(); -public: - T114SensorManager(LocationProvider &location): _location(&location) { } - bool begin() override; - bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override; - void loop() override; - LocationProvider* getLocationProvider() override { return gps_detected ? _location : NULL; } - int getNumSettings() const override; - const char* getSettingName(int i) const override; - const char* getSettingValue(int i) const override; - bool setSettingValue(const char* name, const char* value) override; -}; +#include extern T114Board board; extern WRAPPER_CLASS radio_driver; extern AutoDiscoverRTCClock rtc_clock; -extern T114SensorManager sensors; +extern EnvironmentSensorManager sensors; #ifdef DISPLAY_CLASS extern DISPLAY_CLASS display; diff --git a/variants/heltec_t114/variant.h b/variants/heltec_t114/variant.h index b3f760bbb..d635b2e1b 100644 --- a/variants/heltec_t114/variant.h +++ b/variants/heltec_t114/variant.h @@ -50,9 +50,15 @@ //////////////////////////////////////////////////////////////////////////////// // I2C pin definition +#define WIRE_INTERFACES_COUNT 2 + #define PIN_WIRE_SDA (26) // P0.26 #define PIN_WIRE_SCL (27) // P0.27 +#define PIN_WIRE1_SDA (16) // P0.16 +#define PIN_WIRE1_SCL (13) // P0.13 + + //////////////////////////////////////////////////////////////////////////////// // SPI pin definition diff --git a/variants/ikoka_handheld_nrf/IkokaNrf52Board.cpp b/variants/ikoka_handheld_nrf/IkokaNrf52Board.cpp index 44940b8ff..f1d9f17d3 100644 --- a/variants/ikoka_handheld_nrf/IkokaNrf52Board.cpp +++ b/variants/ikoka_handheld_nrf/IkokaNrf52Board.cpp @@ -2,27 +2,11 @@ #include #include -#include #include "IkokaNrf52Board.h" -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"); -} - void IkokaNrf52Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); // ensure we have pull ups on the screen i2c, this isn't always available // in hardware and it should only be 20k ohms. Disable the pullups if we @@ -53,48 +37,4 @@ void IkokaNrf52Board::begin() { delay(10); // give sx1262 some time to power up } -bool IkokaNrf52Board::startOTAUpdate(const char *id, char reply[]) { - // 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("XIAO_NRF52_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 - - strcpy(reply, "OK - started"); - - return true; -} - #endif diff --git a/variants/ikoka_handheld_nrf/IkokaNrf52Board.h b/variants/ikoka_handheld_nrf/IkokaNrf52Board.h index 9dfc3833e..acb58b3ce 100644 --- a/variants/ikoka_handheld_nrf/IkokaNrf52Board.h +++ b/variants/ikoka_handheld_nrf/IkokaNrf52Board.h @@ -1,17 +1,15 @@ #pragma once -#include #include +#include +#include #ifdef IKOKA_NRF52 -class IkokaNrf52Board : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class IkokaNrf52Board : public NRF52BoardOTA { public: + IkokaNrf52Board() : NRF52BoardOTA("XIAO_NRF52_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -41,12 +39,6 @@ class IkokaNrf52Board : public mesh::MainBoard { const char* getManufacturerName() const override { return "Ikoka Handheld E22 30dBm (Xiao_nrf52)"; } - - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char* id, char reply[]) override; }; #endif diff --git a/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.cpp b/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.cpp index ee7996921..b963b2f4b 100644 --- a/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.cpp +++ b/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.cpp @@ -1,28 +1,12 @@ #ifdef XIAO_NRF52 #include -#include "IkokaNanoNRFBoard.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"); -} +#include "IkokaNanoNRFBoard.h" void IkokaNanoNRFBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); pinMode(PIN_VBAT, INPUT); pinMode(VBAT_ENABLE, OUTPUT); @@ -48,47 +32,4 @@ void IkokaNanoNRFBoard::begin() { delay(10); // give sx1262 some time to power up } -bool IkokaNanoNRFBoard::startOTAUpdate(const char *id, char reply[]) { - // 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("XIAO_NRF52_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 - - strcpy(reply, "OK - started"); - return true; -} - #endif diff --git a/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.h b/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.h index 8484085b0..c7e96921e 100644 --- a/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.h +++ b/variants/ikoka_nano_nrf/IkokaNanoNRFBoard.h @@ -2,16 +2,14 @@ #include #include +#include #ifdef XIAO_NRF52 -class IkokaNanoNRFBoard : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class IkokaNanoNRFBoard : public NRF52BoardOTA { public: + IkokaNanoNRFBoard() : NRF52BoardOTA("XIAO_NRF52_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -49,12 +47,6 @@ class IkokaNanoNRFBoard : public mesh::MainBoard { const char *getManufacturerName() const override { return MANUFACTURER_STRING; } - - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char *id, char reply[]) override; }; #endif diff --git a/variants/ikoka_stick_nrf/IkokaStickNRFBoard.cpp b/variants/ikoka_stick_nrf/IkokaStickNRFBoard.cpp index 6b660383a..1c416039d 100644 --- a/variants/ikoka_stick_nrf/IkokaStickNRFBoard.cpp +++ b/variants/ikoka_stick_nrf/IkokaStickNRFBoard.cpp @@ -1,28 +1,12 @@ #ifdef XIAO_NRF52 #include -#include "IkokaStickNRFBoard.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"); -} +#include "IkokaStickNRFBoard.h" void IkokaStickNRFBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); pinMode(PIN_VBAT, INPUT); pinMode(VBAT_ENABLE, OUTPUT); @@ -48,47 +32,4 @@ void IkokaStickNRFBoard::begin() { delay(10); // give sx1262 some time to power up } -bool IkokaStickNRFBoard::startOTAUpdate(const char *id, char reply[]) { - // 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("XIAO_NRF52_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 - - strcpy(reply, "OK - started"); - return true; -} - #endif diff --git a/variants/ikoka_stick_nrf/IkokaStickNRFBoard.h b/variants/ikoka_stick_nrf/IkokaStickNRFBoard.h index 4a061d42f..00a26029c 100644 --- a/variants/ikoka_stick_nrf/IkokaStickNRFBoard.h +++ b/variants/ikoka_stick_nrf/IkokaStickNRFBoard.h @@ -2,16 +2,14 @@ #include #include +#include #ifdef XIAO_NRF52 -class IkokaStickNRFBoard : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class IkokaStickNRFBoard : public NRF52BoardOTA { public: + IkokaStickNRFBoard() : NRF52BoardOTA("XIAO_NRF52_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -49,12 +47,6 @@ class IkokaStickNRFBoard : public mesh::MainBoard { const char *getManufacturerName() const override { return MANUFACTURER_STRING; } - - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char *id, char reply[]) override; }; #endif diff --git a/variants/keepteen_lt1/KeepteenLT1Board.cpp b/variants/keepteen_lt1/KeepteenLT1Board.cpp index 46bff1fc2..2f1fa5f9a 100644 --- a/variants/keepteen_lt1/KeepteenLT1Board.cpp +++ b/variants/keepteen_lt1/KeepteenLT1Board.cpp @@ -1,14 +1,10 @@ #include -#include "KeepteenLT1Board.h" - -#include #include -static BLEDfu bledfu; +#include "KeepteenLT1Board.h" void KeepteenLT1Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); btn_prev_state = HIGH; pinMode(PIN_VBAT_READ, INPUT); @@ -18,58 +14,4 @@ void KeepteenLT1Board::begin() { #endif Wire.begin(); -} - -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 KeepteenLT1Board::startOTAUpdate(const char* id, char reply[]) { - // 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("KeepteenLT1_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 - - strcpy(reply, "OK - started"); - return true; -} +} \ No newline at end of file diff --git a/variants/keepteen_lt1/KeepteenLT1Board.h b/variants/keepteen_lt1/KeepteenLT1Board.h index 9892638b2..a9844c90b 100644 --- a/variants/keepteen_lt1/KeepteenLT1Board.h +++ b/variants/keepteen_lt1/KeepteenLT1Board.h @@ -2,17 +2,16 @@ #include #include +#include -class KeepteenLT1Board : public mesh::MainBoard { +class KeepteenLT1Board : public NRF52BoardOTA { protected: - uint8_t startup_reason; uint8_t btn_prev_state; public: + KeepteenLT1Board() : NRF52BoardOTA("KeepteenLT1_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } - #define BATTERY_SAMPLES 8 uint16_t getBattMilliVolts() override { @@ -39,13 +38,7 @@ class KeepteenLT1Board : public mesh::MainBoard { } #endif - void reboot() override { - NVIC_SystemReset(); - } - void powerOff() override { sd_power_system_off(); } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/lilygo_techo/TechoBoard.cpp b/variants/lilygo_techo/TechoBoard.cpp index dee146880..81d3d0c9a 100644 --- a/variants/lilygo_techo/TechoBoard.cpp +++ b/variants/lilygo_techo/TechoBoard.cpp @@ -1,28 +1,12 @@ #include -#include "TechoBoard.h" - -#ifdef LILYGO_TECHO - -#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; +#include "TechoBoard.h" - MESH_DEBUG_PRINTLN("BLE client disconnected"); -} +#ifdef LILYGO_TECHO void TechoBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); Wire.begin(); @@ -44,47 +28,4 @@ uint16_t TechoBoard::getBattMilliVolts() { // divider into account (providing the actual LIPO voltage) return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB); } - -bool TechoBoard::startOTAUpdate(const char* id, char reply[]) { - // 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("TECHO_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 - - strcpy(reply, "OK - started"); - return true; -} #endif diff --git a/variants/lilygo_techo/TechoBoard.h b/variants/lilygo_techo/TechoBoard.h index 080387976..c9bdc229b 100644 --- a/variants/lilygo_techo/TechoBoard.h +++ b/variants/lilygo_techo/TechoBoard.h @@ -2,6 +2,7 @@ #include #include +#include // built-ins #define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 @@ -12,19 +13,11 @@ #define PIN_VBAT_READ (4) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) -class TechoBoard : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class TechoBoard : public NRF52BoardOTA { public: - + TechoBoard() : NRF52BoardOTA("TECHO_OTA") {} void begin(); uint16_t getBattMilliVolts() override; - bool startOTAUpdate(const char* id, char reply[]) override; - - uint8_t getStartupReason() const override { - return startup_reason; - } const char* getManufacturerName() const override { return "LilyGo T-Echo"; @@ -48,8 +41,4 @@ class TechoBoard : public mesh::MainBoard { #endif sd_power_system_off(); } - - void reboot() override { - NVIC_SystemReset(); - } }; diff --git a/variants/lilygo_techo_lite/TechoBoard.cpp b/variants/lilygo_techo_lite/TechoBoard.cpp index dee146880..81d3d0c9a 100644 --- a/variants/lilygo_techo_lite/TechoBoard.cpp +++ b/variants/lilygo_techo_lite/TechoBoard.cpp @@ -1,28 +1,12 @@ #include -#include "TechoBoard.h" - -#ifdef LILYGO_TECHO - -#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; +#include "TechoBoard.h" - MESH_DEBUG_PRINTLN("BLE client disconnected"); -} +#ifdef LILYGO_TECHO void TechoBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); Wire.begin(); @@ -44,47 +28,4 @@ uint16_t TechoBoard::getBattMilliVolts() { // divider into account (providing the actual LIPO voltage) return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB); } - -bool TechoBoard::startOTAUpdate(const char* id, char reply[]) { - // 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("TECHO_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 - - strcpy(reply, "OK - started"); - return true; -} #endif diff --git a/variants/lilygo_techo_lite/TechoBoard.h b/variants/lilygo_techo_lite/TechoBoard.h index 4792153a9..8e6974bd3 100644 --- a/variants/lilygo_techo_lite/TechoBoard.h +++ b/variants/lilygo_techo_lite/TechoBoard.h @@ -2,6 +2,7 @@ #include #include +#include // built-ins #define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 @@ -12,19 +13,11 @@ #define PIN_VBAT_READ (4) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) -class TechoBoard : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class TechoBoard : public NRF52BoardOTA { public: - + TechoBoard() : NRF52BoardOTA("TECHO_OTA") {} void begin(); uint16_t getBattMilliVolts() override; - bool startOTAUpdate(const char* id, char reply[]) override; - - uint8_t getStartupReason() const override { - return startup_reason; - } const char* getManufacturerName() const override { return "LilyGo T-Echo"; @@ -48,8 +41,4 @@ class TechoBoard : public mesh::MainBoard { #endif sd_power_system_off(); } - - void reboot() override { - NVIC_SystemReset(); - } }; diff --git a/variants/mesh_pocket/MeshPocket.cpp b/variants/mesh_pocket/MeshPocket.cpp index 0d0e8993c..0c53121f2 100644 --- a/variants/mesh_pocket/MeshPocket.cpp +++ b/variants/mesh_pocket/MeshPocket.cpp @@ -1,72 +1,12 @@ #include -#include "MeshPocket.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"); -} +#include "MeshPocket.h" void HeltecMeshPocket::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); Serial.begin(115200); pinMode(PIN_VBAT_READ, INPUT); pinMode(PIN_USER_BTN, INPUT); } - -bool HeltecMeshPocket::startOTAUpdate(const char* id, char reply[]) { - // 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("MESH_POCKET_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 - - strcpy(reply, "OK - started"); - return true; -} diff --git a/variants/mesh_pocket/MeshPocket.h b/variants/mesh_pocket/MeshPocket.h index 8f5b09c9f..db65c99b1 100644 --- a/variants/mesh_pocket/MeshPocket.h +++ b/variants/mesh_pocket/MeshPocket.h @@ -2,21 +2,17 @@ #include #include +#include // built-ins #define PIN_VBAT_READ 29 #define PIN_BAT_CTL 34 #define MV_LSB (3000.0F / 4096.0F) // 12-bit ADC with 3.0V input range -class HeltecMeshPocket : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class HeltecMeshPocket : public NRF52BoardOTA { public: + HeltecMeshPocket() : NRF52BoardOTA("MESH_POCKET_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } - - uint16_t getBattMilliVolts() override { int adcvalue = 0; @@ -37,13 +33,7 @@ class HeltecMeshPocket : public mesh::MainBoard { return "Heltec MeshPocket"; } - void reboot() override { - NVIC_SystemReset(); - } - void powerOff() override { sd_power_system_off(); } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.cpp b/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.cpp index 561ed5049..0267185c9 100644 --- a/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.cpp +++ b/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.cpp @@ -1,12 +1,10 @@ #include -#include "MinewsemiME25LS01Board.h" #include -#include +#include "MinewsemiME25LS01Board.h" void MinewsemiME25LS01Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); btn_prev_state = HIGH; pinMode(PIN_VBAT_READ, INPUT); @@ -28,62 +26,4 @@ void MinewsemiME25LS01Board::begin() { #endif delay(10); // give sx1262 some time to power up -} - -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 MinewsemiME25LS01Board::startOTAUpdate(const char* id, char reply[]) { - // 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("Minewsemi_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 - - strcpy(reply, "OK - started"); - return true; } \ No newline at end of file diff --git a/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h b/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h index 777606a6d..805f9dfa8 100644 --- a/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h +++ b/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h @@ -2,6 +2,7 @@ #include #include +#include // LoRa and SPI pins @@ -19,13 +20,12 @@ #define PIN_VBAT_READ BATTERY_PIN #define ADC_MULTIPLIER (1.815f) // dependent on voltage divider resistors. TODO: more accurate battery tracking - -class MinewsemiME25LS01Board : public mesh::MainBoard { +class MinewsemiME25LS01Board : public NRF52BoardOTA { protected: - uint8_t startup_reason; uint8_t btn_prev_state; public: + MinewsemiME25LS01Board() : NRF52BoardOTA("Minewsemi_OTA") {} void begin(); #define BATTERY_SAMPLES 8 @@ -41,8 +41,6 @@ class MinewsemiME25LS01Board : public mesh::MainBoard { return (ADC_MULTIPLIER * raw); } - uint8_t getStartupReason() const override { return startup_reason; } - const char* getManufacturerName() const override { return "Minewsemi"; } @@ -78,11 +76,4 @@ class MinewsemiME25LS01Board : public mesh::MainBoard { digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off } #endif - - - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char* id, char reply[]) override; }; \ No newline at end of file diff --git a/variants/nano_g2_ultra/nano-g2.cpp b/variants/nano_g2_ultra/nano-g2.cpp index 9a2782871..6a749aab6 100644 --- a/variants/nano_g2_ultra/nano-g2.cpp +++ b/variants/nano_g2_ultra/nano-g2.cpp @@ -24,8 +24,7 @@ static void disconnect_callback(uint16_t conn_handle, uint8_t reason) void NanoG2Ultra::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); // set user button pinMode(PIN_BUTTON1, INPUT); diff --git a/variants/nano_g2_ultra/nano-g2.h b/variants/nano_g2_ultra/nano-g2.h index 5cedb0f99..6961fc86d 100644 --- a/variants/nano_g2_ultra/nano-g2.h +++ b/variants/nano_g2_ultra/nano-g2.h @@ -4,6 +4,7 @@ #include #include +#include // LoRa radio module pins #define P_LORA_DIO_1 (32 + 10) @@ -34,21 +35,14 @@ #define PIN_VBAT_READ (0 + 2) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) -class NanoG2Ultra : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class NanoG2Ultra : public NRF52Board { public: void begin(); uint16_t getBattMilliVolts() override; bool startOTAUpdate(const char *id, char reply[]) override; - uint8_t getStartupReason() const override { return startup_reason; } - const char *getManufacturerName() const override { return "Nano G2 Ultra"; } - void reboot() override { NVIC_SystemReset(); } - void powerOff() override { // put GPS chip to sleep digitalWrite(PIN_GPS_STANDBY, LOW); diff --git a/variants/promicro/PromicroBoard.cpp b/variants/promicro/PromicroBoard.cpp index b923e16e5..7011521b8 100644 --- a/variants/promicro/PromicroBoard.cpp +++ b/variants/promicro/PromicroBoard.cpp @@ -1,14 +1,10 @@ #include -#include "PromicroBoard.h" - -#include #include -static BLEDfu bledfu; +#include "PromicroBoard.h" void PromicroBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); btn_prev_state = HIGH; pinMode(PIN_VBAT_READ, INPUT); @@ -26,58 +22,4 @@ void PromicroBoard::begin() { pinMode(SX126X_POWER_EN, OUTPUT); digitalWrite(SX126X_POWER_EN, HIGH); delay(10); // give sx1262 some time to power up -} - -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 PromicroBoard::startOTAUpdate(const char* id, char reply[]) { - // 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("ProMicro_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 - - strcpy(reply, "OK - started"); - return true; -} +} \ No newline at end of file diff --git a/variants/promicro/PromicroBoard.h b/variants/promicro/PromicroBoard.h index dc20e5500..c23ed1c99 100644 --- a/variants/promicro/PromicroBoard.h +++ b/variants/promicro/PromicroBoard.h @@ -2,6 +2,7 @@ #include #include +#include #define P_LORA_NSS 13 //P1.13 45 #define P_LORA_DIO_1 11 //P0.10 10 @@ -19,17 +20,15 @@ #define PIN_VBAT_READ 17 #define ADC_MULTIPLIER (1.815f) // dependent on voltage divider resistors. TODO: more accurate battery tracking -class PromicroBoard : public mesh::MainBoard { +class PromicroBoard : public NRF52BoardOTA { protected: - uint8_t startup_reason; uint8_t btn_prev_state; float adc_mult = ADC_MULTIPLIER; public: + PromicroBoard() : NRF52BoardOTA("ProMicro_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } - #define BATTERY_SAMPLES 8 uint16_t getBattMilliVolts() override { @@ -74,13 +73,7 @@ class PromicroBoard : public mesh::MainBoard { return 0; } - void reboot() override { - NVIC_SystemReset(); - } - void powerOff() override { sd_power_system_off(); } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/rak4631/RAK4631Board.cpp b/variants/rak4631/RAK4631Board.cpp index 97a966022..65c54711d 100644 --- a/variants/rak4631/RAK4631Board.cpp +++ b/variants/rak4631/RAK4631Board.cpp @@ -1,26 +1,10 @@ #include -#include "RAK4631Board.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"); -} +#include "RAK4631Board.h" void RAK4631Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52BoardDCDC::begin(); pinMode(PIN_VBAT_READ, INPUT); #ifdef PIN_USER_BTN pinMode(PIN_USER_BTN, INPUT_PULLUP); @@ -39,52 +23,4 @@ void RAK4631Board::begin() { pinMode(SX126X_POWER_EN, OUTPUT); digitalWrite(SX126X_POWER_EN, HIGH); delay(10); // give sx1262 some time to power up -} - -bool RAK4631Board::startOTAUpdate(const char* id, char reply[]) { - // 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("RAK4631_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 - - uint8_t mac_addr[6]; - memset(mac_addr, 0, sizeof(mac_addr)); - Bluefruit.getAddr(mac_addr); - sprintf(reply, "OK - mac: %02X:%02X:%02X:%02X:%02X:%02X", - mac_addr[5], mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]); - - return true; -} +} \ No newline at end of file diff --git a/variants/rak4631/RAK4631Board.h b/variants/rak4631/RAK4631Board.h index 7f3a8fea9..a181256b0 100644 --- a/variants/rak4631/RAK4631Board.h +++ b/variants/rak4631/RAK4631Board.h @@ -2,6 +2,7 @@ #include #include +#include // LoRa radio module pins for RAK4631 #define P_LORA_DIO_1 47 @@ -28,13 +29,10 @@ #define PIN_VBAT_READ 5 #define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000) -class RAK4631Board : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class RAK4631Board : public NRF52BoardDCDC, public NRF52BoardOTA { public: + RAK4631Board() : NRF52BoardOTA("RAK4631_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #define BATTERY_SAMPLES 8 @@ -53,10 +51,4 @@ class RAK4631Board : public mesh::MainBoard { const char* getManufacturerName() const override { return "RAK 4631"; } - - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/rak_wismesh_tag/RAKWismeshTagBoard.cpp b/variants/rak_wismesh_tag/RAKWismeshTagBoard.cpp index 68638f0dd..7eab4bc9e 100644 --- a/variants/rak_wismesh_tag/RAKWismeshTagBoard.cpp +++ b/variants/rak_wismesh_tag/RAKWismeshTagBoard.cpp @@ -1,35 +1,10 @@ #include -#include "RAKWismeshTagBoard.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"); -} +#include "RAKWismeshTagBoard.h" void RAKWismeshTagBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; - - // Enable DC/DC converter for improved power efficiency - uint8_t sd_enabled = 0; - sd_softdevice_is_enabled(&sd_enabled); - if (sd_enabled) { - sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); - } else { - NRF_POWER->DCDCEN = 1; - } + NRF52BoardDCDC::begin(); pinMode(PIN_VBAT_READ, INPUT); pinMode(PIN_USER_BTN, INPUT_PULLUP); @@ -40,52 +15,4 @@ void RAKWismeshTagBoard::begin() { pinMode(SX126X_POWER_EN, OUTPUT); digitalWrite(SX126X_POWER_EN, HIGH); delay(10); // give sx1262 some time to power up -} - -bool RAKWismeshTagBoard::startOTAUpdate(const char* id, char reply[]) { - // 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("WISMESHTAG_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 - - uint8_t mac_addr[6]; - memset(mac_addr, 0, sizeof(mac_addr)); - Bluefruit.getAddr(mac_addr); - sprintf(reply, "OK - mac: %02X:%02X:%02X:%02X:%02X:%02X", - mac_addr[5], mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]); - - return true; -} +} \ No newline at end of file diff --git a/variants/rak_wismesh_tag/RAKWismeshTagBoard.h b/variants/rak_wismesh_tag/RAKWismeshTagBoard.h index e5104a58d..9aa457d24 100644 --- a/variants/rak_wismesh_tag/RAKWismeshTagBoard.h +++ b/variants/rak_wismesh_tag/RAKWismeshTagBoard.h @@ -2,18 +2,16 @@ #include #include +#include // built-ins #define PIN_VBAT_READ 5 #define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000) -class RAKWismeshTagBoard : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class RAKWismeshTagBoard : public NRF52BoardDCDC, public NRF52BoardOTA { public: + RAKWismeshTagBoard() : NRF52BoardOTA("WISMESHTAG_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) && defined(LED_STATE_ON) void onBeforeTransmit() override { @@ -42,12 +40,6 @@ class RAKWismeshTagBoard : public mesh::MainBoard { return "RAK WisMesh Tag"; } - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char* id, char reply[]) override; - void powerOff() override { #ifdef BUZZER_EN digitalWrite(BUZZER_EN, LOW); diff --git a/variants/sensecap_solar/SenseCapSolarBoard.cpp b/variants/sensecap_solar/SenseCapSolarBoard.cpp index d6c044d1d..c08830359 100644 --- a/variants/sensecap_solar/SenseCapSolarBoard.cpp +++ b/variants/sensecap_solar/SenseCapSolarBoard.cpp @@ -1,26 +1,10 @@ #include -#include "SenseCapSolarBoard.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"); -} +#include "SenseCapSolarBoard.h" void SenseCapSolarBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); #if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL) Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL); @@ -34,48 +18,4 @@ void SenseCapSolarBoard::begin() { #endif delay(10); // give sx1262 some time to power up -} - -bool SenseCapSolarBoard::startOTAUpdate(const char* id, char reply[]) { - // 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("SENSECAP_SOLAR_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 - - strcpy(reply, "OK - started"); - - return true; -} +} \ No newline at end of file diff --git a/variants/sensecap_solar/SenseCapSolarBoard.h b/variants/sensecap_solar/SenseCapSolarBoard.h index b1e5f8f17..dfe007bf7 100644 --- a/variants/sensecap_solar/SenseCapSolarBoard.h +++ b/variants/sensecap_solar/SenseCapSolarBoard.h @@ -2,14 +2,12 @@ #include #include +#include -class SenseCapSolarBoard : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class SenseCapSolarBoard : public NRF52BoardOTA { public: + SenseCapSolarBoard() : NRF52BoardOTA("SENSECAP_SOLAR_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -33,10 +31,4 @@ class SenseCapSolarBoard : public mesh::MainBoard { const char* getManufacturerName() const override { return "Seeed SenseCap Solar"; } - - void reboot() override { - NVIC_SystemReset(); - } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/t1000-e/T1000eBoard.cpp b/variants/t1000-e/T1000eBoard.cpp index a41abd92e..0d390f798 100644 --- a/variants/t1000-e/T1000eBoard.cpp +++ b/variants/t1000-e/T1000eBoard.cpp @@ -1,23 +1,12 @@ #include -#include "T1000eBoard.h" #include -#include +#include "T1000eBoard.h" void T1000eBoard::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52BoardDCDC::begin(); btn_prev_state = HIGH; - // Enable DC/DC converter for improved power efficiency - uint8_t sd_enabled = 0; - sd_softdevice_is_enabled(&sd_enabled); - if (sd_enabled) { - sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); - } else { - NRF_POWER->DCDCEN = 1; - } - #ifdef BUTTON_PIN pinMode(BATTERY_PIN, INPUT); pinMode(BUTTON_PIN, INPUT); @@ -31,64 +20,4 @@ void T1000eBoard::begin() { Wire.begin(); delay(10); // give sx1262 some time to power up -} - -#if 0 -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 TrackerT1000eBoard::startOTAUpdate(const char* id, char reply[]) { - // 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("T1000E_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 - - strcpy(reply, "OK - started"); - return true; -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/variants/t1000-e/T1000eBoard.h b/variants/t1000-e/T1000eBoard.h index 359e5e9a1..32f54bb38 100644 --- a/variants/t1000-e/T1000eBoard.h +++ b/variants/t1000-e/T1000eBoard.h @@ -2,10 +2,10 @@ #include #include +#include -class T1000eBoard : public mesh::MainBoard { +class T1000eBoard : public NRF52BoardDCDC { protected: - uint8_t startup_reason; uint8_t btn_prev_state; public: @@ -33,8 +33,6 @@ class T1000eBoard : public mesh::MainBoard { #endif } - uint8_t getStartupReason() const override { return startup_reason; } - const char* getManufacturerName() const override { return "Seeed Tracker T1000-e"; } @@ -92,9 +90,5 @@ class T1000eBoard : public mesh::MainBoard { sd_power_system_off(); } - void reboot() override { - NVIC_SystemReset(); - } - // bool startOTAUpdate(const char* id, char reply[]) override; }; \ No newline at end of file diff --git a/variants/thinknode_m1/ThinkNodeM1Board.cpp b/variants/thinknode_m1/ThinkNodeM1Board.cpp index 12dd73624..45449bafc 100644 --- a/variants/thinknode_m1/ThinkNodeM1Board.cpp +++ b/variants/thinknode_m1/ThinkNodeM1Board.cpp @@ -1,28 +1,12 @@ -#include "ThinkNodeM1Board.h" #include - -#ifdef THINKNODE_M1 - #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; +#include "ThinkNodeM1Board.h" - MESH_DEBUG_PRINTLN("BLE client disconnected"); -} +#ifdef THINKNODE_M1 void ThinkNodeM1Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52Board::begin(); Wire.begin(); @@ -49,47 +33,4 @@ uint16_t ThinkNodeM1Board::getBattMilliVolts() { // divider into account (providing the actual LIPO voltage) return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB); } - -bool ThinkNodeM1Board::startOTAUpdate(const char *id, char reply[]) { - // 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("THINKNODE_M1_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 - - strcpy(reply, "OK - started"); - return true; -} #endif diff --git a/variants/thinknode_m1/ThinkNodeM1Board.h b/variants/thinknode_m1/ThinkNodeM1Board.h index cffa0aaaf..500a02658 100644 --- a/variants/thinknode_m1/ThinkNodeM1Board.h +++ b/variants/thinknode_m1/ThinkNodeM1Board.h @@ -2,6 +2,7 @@ #include #include +#include // built-ins #define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 @@ -12,19 +13,11 @@ #define PIN_VBAT_READ (4) #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) -class ThinkNodeM1Board : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class ThinkNodeM1Board : public NRF52BoardOTA { public: - + ThinkNodeM1Board() : NRF52BoardOTA("THINKNODE_M1_OTA") {} void begin(); uint16_t getBattMilliVolts() override; - bool startOTAUpdate(const char* id, char reply[]) override; - - uint8_t getStartupReason() const override { - return startup_reason; - } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -39,10 +32,6 @@ class ThinkNodeM1Board : public mesh::MainBoard { return "Elecrow ThinkNode-M1"; } - void reboot() override { - NVIC_SystemReset(); - } - void powerOff() override { // turn off all leds, sd_power_system_off will not do this for us diff --git a/variants/thinknode_m3/ThinknodeM3Board.cpp b/variants/thinknode_m3/ThinknodeM3Board.cpp new file mode 100644 index 000000000..74019fcbb --- /dev/null +++ b/variants/thinknode_m3/ThinknodeM3Board.cpp @@ -0,0 +1,80 @@ +#include +#include "ThinknodeM3Board.h" +#include + +#include + +void ThinknodeM3Board::begin() { + // for future use, sub-classes SHOULD call this from their begin() + startup_reason = BD_STARTUP_NORMAL; + btn_prev_state = HIGH; + + sd_power_mode_set(NRF_POWER_MODE_LOWPWR); + + // Enable DC/DC converter for improved power efficiency + NRF_POWER->DCDCEN = 1; + + Wire.begin(); + + delay(10); // give sx1262 some time to power up +} + +#if 0 +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 TrackerThinknodeM3Board::startOTAUpdate(const char* id, char reply[]) { + // 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("T1000E_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 + + strcpy(reply, "OK - started"); + return true; +} +#endif \ No newline at end of file diff --git a/variants/thinknode_m3/ThinknodeM3Board.h b/variants/thinknode_m3/ThinknodeM3Board.h new file mode 100644 index 000000000..c9b962737 --- /dev/null +++ b/variants/thinknode_m3/ThinknodeM3Board.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include + +#define ADC_FACTOR ((1000.0*ADC_MULTIPLIER*AREF_VOLTAGE)/ADC_MAX) + +class ThinknodeM3Board : public mesh::MainBoard { +protected: + uint8_t startup_reason; + uint8_t btn_prev_state; + +public: + void begin(); + + uint16_t getBattMilliVolts() override { + int adcvalue = 0; + + analogReference(AR_INTERNAL_2_4); + analogReadResolution(ADC_RESOLUTION); + delay(10); + + // ADC range is 0..2400mV and resolution is 12-bit (0..4095) + adcvalue = analogRead(PIN_VBAT_READ); + // Convert the raw value to compensated mv, taking the resistor- + // divider into account (providing the actual LIPO voltage) + return (uint16_t)((float)adcvalue * ADC_FACTOR); + } + + uint8_t getStartupReason() const override { return startup_reason; } + + #if defined(P_LORA_TX_LED) + #if !defined(P_LORA_TX_LED_ON) + #define P_LORA_TX_LED_ON HIGH + #endif + void onBeforeTransmit() override { + digitalWrite(P_LORA_TX_LED, P_LORA_TX_LED_ON); // turn TX LED on + } + void onAfterTransmit() override { + digitalWrite(P_LORA_TX_LED, !P_LORA_TX_LED_ON); // turn TX LED off + } + #endif + + const char* getManufacturerName() const override { + return "Elecrow ThinkNode M3"; + } + + int buttonStateChanged() { + #ifdef BUTTON_PIN + uint8_t v = digitalRead(BUTTON_PIN); + if (v != btn_prev_state) { + btn_prev_state = v; + return (v == LOW) ? 1 : -1; + } + #endif + return 0; + } + + void powerOff() override { + sd_power_system_off(); + } + + void reboot() override { + NVIC_SystemReset(); + } + +// bool startOTAUpdate(const char* id, char reply[]) override; +}; \ No newline at end of file diff --git a/variants/thinknode_m3/platformio.ini b/variants/thinknode_m3/platformio.ini new file mode 100644 index 000000000..8ef2ba54a --- /dev/null +++ b/variants/thinknode_m3/platformio.ini @@ -0,0 +1,122 @@ +[ThinkNode_M3] +extends = nrf52_base +board = thinknode_m3 +board_build.ldscript = boards/nrf52840_s140_v6.ld +build_flags = ${nrf52_base.build_flags} + -I src/helpers/nrf52 + -I lib/nrf52/s140_nrf52_6.1.1_API/include + -I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52 + -I variants/thinknode_m3 + -I src/helpers/ui + -D THINKNODE_M3 + -D PIN_USER_BTN=12 + -D USER_BTN_PRESSED=LOW + -D PIN_STATUS_LED=35 + -D RADIO_CLASS=CustomLR1110 + -D WRAPPER_CLASS=CustomLR1110Wrapper + -D LORA_TX_POWER=22 + -D RF_SWITCH_TABLE + -D RX_BOOSTED_GAIN=true + -D P_LORA_BUSY=43 + -D P_LORA_SCLK=45 + -D P_LORA_NSS=44 + -D P_LORA_DIO_1=40 + -D P_LORA_MISO=47 + -D P_LORA_MOSI=46 + -D P_LORA_RESET=42 + -D P_LORA_TX_LED=PIN_LED_BLUE + -D P_LORA_TX_LED_ON=LOW + -D LR11X0_DIO_AS_RF_SWITCH=true + -D LR11X0_DIO3_TCXO_VOLTAGE=3.3 + -D MESH_DEBUG=1 + -D ENV_INCLUDE_GPS=1 +build_src_filter = ${nrf52_base.build_src_filter} + + + +<../variants/thinknode_m3> + + +debug_tool = stlink +upload_protocol = nrfutil +lib_deps= ${nrf52_base.lib_deps} + +[env:ThinkNode_M3_repeater] +extends = ThinkNode_M3 +build_flags = ${ThinkNode_M3.build_flags} + -I examples/companion_radio/ui-orig + -D ADVERT_NAME='"ThinkNode_M3 Repeater"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${ThinkNode_M3.build_src_filter} + +<../examples/simple_repeater> +lib_deps = ${ThinkNode_M3.lib_deps} + stevemarple/MicroNMEA @ ^2.0.6 + +[env:ThinkNode_M3_room_server] +extends = ThinkNode_M3 +build_flags = ${ThinkNode_M3.build_flags} + -I examples/companion_radio/ui-orig + -D ADVERT_NAME='"ThinkNode_M3 Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 + -D RF_SWITCH_TABLE +build_src_filter = ${ThinkNode_M3.build_src_filter} + +<../examples/simple_room_server> +lib_deps = ${ThinkNode_M3.lib_deps} + stevemarple/MicroNMEA @ ^2.0.6 + +[env:ThinkNode_M3_companion_radio_usb] +extends = ThinkNode_M3 +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 708608 +build_flags = ${ThinkNode_M3.build_flags} + -I examples/companion_radio/ui-orig + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 + -D OFFLINE_QUEUE_SIZE=256 + -D DISPLAY_CLASS=NullDisplayDriver + -D PIN_BUZZER=23 + -D PIN_BUZZER_EN=36 +build_src_filter = ${ThinkNode_M3.build_src_filter} + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-orig/*.cpp> +lib_deps = ${ThinkNode_M3.lib_deps} + densaugeo/base64 @ ~1.4.0 + stevemarple/MicroNMEA @ ^2.0.6 + end2endzone/NonBlockingRTTTL@^1.3.0 + +[env:ThinkNode_M3_companion_radio_ble] +extends = ThinkNode_M3 +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 708608 +build_flags = ${ThinkNode_M3.build_flags} + -I examples/companion_radio/ui-orig + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D BLE_PIN_CODE=123456 + -D BLE_TX_POWER=0 +; -D BLE_DEBUG_LOGGING=1 +; -D MESH_PACKET_LOGGING=1 + -D GPS_NMEA_DEBUG + -D OFFLINE_QUEUE_SIZE=256 + -D DISPLAY_CLASS=NullDisplayDriver + -D PIN_BUZZER=23 + -D PIN_BUZZER_EN=36 +build_src_filter = ${ThinkNode_M3.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-orig/*.cpp> +lib_deps = ${ThinkNode_M3.lib_deps} + densaugeo/base64 @ ~1.4.0 + stevemarple/MicroNMEA @ ^2.0.6 + end2endzone/NonBlockingRTTTL@^1.3.0 diff --git a/variants/thinknode_m3/target.cpp b/variants/thinknode_m3/target.cpp new file mode 100644 index 000000000..c6708e4d1 --- /dev/null +++ b/variants/thinknode_m3/target.cpp @@ -0,0 +1,99 @@ +#include +#include "target.h" +#include + +ThinknodeM3Board board; + +RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); + +WRAPPER_CLASS radio_driver(radio, board); + +VolatileRTCClock fallback_clock; +AutoDiscoverRTCClock rtc_clock(fallback_clock); +#ifdef ENV_INCLUDE_GPS +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else +EnvironmentSensorManager sensors = EnvironmentSensorManager(); +#endif + +#ifdef DISPLAY_CLASS + NullDisplayDriver display; +#endif + +#ifndef LORA_CR + #define LORA_CR 5 +#endif + +#ifdef RF_SWITCH_TABLE +static const uint32_t rfswitch_dios[Module::RFSWITCH_MAX_PINS] = { + RADIOLIB_LR11X0_DIO5, + RADIOLIB_LR11X0_DIO6, + RADIOLIB_NC, + RADIOLIB_NC, + RADIOLIB_NC +}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + { LR11x0::MODE_STBY, {LOW , LOW }}, + { LR11x0::MODE_RX, {HIGH, LOW }}, + { LR11x0::MODE_TX, {HIGH, HIGH }}, + { LR11x0::MODE_TX_HP, {LOW , HIGH }}, + { LR11x0::MODE_TX_HF, {LOW , LOW }}, + { LR11x0::MODE_GNSS, {LOW , LOW }}, + { LR11x0::MODE_WIFI, {LOW , LOW }}, + END_OF_MODE_TABLE, +}; +#endif + +bool radio_init() { + rtc_clock.begin(Wire); + +#ifdef LR11X0_DIO3_TCXO_VOLTAGE + float tcxo = LR11X0_DIO3_TCXO_VOLTAGE; +#else + float tcxo = 1.6f; +#endif + + SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); + SPI.begin(); + int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_LR11X0_LORA_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo); + if (status != RADIOLIB_ERR_NONE) { + Serial.print("ERROR: radio init failed: "); + Serial.println(status); + return false; // fail + } + + radio.setCRC(2); + radio.explicitHeader(); + +#ifdef RF_SWITCH_TABLE + radio.setRfSwitchTable(rfswitch_dios, rfswitch_table); +#endif +#ifdef RX_BOOSTED_GAIN + radio.setRxBoostedGainMode(RX_BOOSTED_GAIN); +#endif + + return true; // success +} + +uint32_t radio_get_rng_seed() { + return radio.random(0x7FFFFFFF); +} + +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { + radio.setFrequency(freq); + radio.setSpreadingFactor(sf); + radio.setBandwidth(bw); + radio.setCodingRate(cr); +} + +void radio_set_tx_power(uint8_t dbm) { + radio.setOutputPower(dbm); +} + +mesh::LocalIdentity radio_new_identity() { + RadioNoiseListener rng(radio); + return mesh::LocalIdentity(&rng); // create new random identity +} \ No newline at end of file diff --git a/variants/thinknode_m3/target.h b/variants/thinknode_m3/target.h new file mode 100644 index 000000000..f60a85b03 --- /dev/null +++ b/variants/thinknode_m3/target.h @@ -0,0 +1,29 @@ +#pragma once + +#define RADIOLIB_STATIC_ONLY 1 +#include +#include +#include "ThinknodeM3Board.h" +#include +#include +#include +#include +#include +#ifdef DISPLAY_CLASS + #include "NullDisplayDriver.h" +#endif + +#ifdef DISPLAY_CLASS + extern NullDisplayDriver display; +#endif + +extern ThinknodeM3Board board; +extern WRAPPER_CLASS radio_driver; +extern AutoDiscoverRTCClock rtc_clock; +extern EnvironmentSensorManager sensors; + +bool radio_init(); +uint32_t radio_get_rng_seed(); +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); +void radio_set_tx_power(uint8_t dbm); +mesh::LocalIdentity radio_new_identity(); diff --git a/variants/thinknode_m3/variant.cpp b/variants/thinknode_m3/variant.cpp new file mode 100644 index 000000000..dad0f3f55 --- /dev/null +++ b/variants/thinknode_m3/variant.cpp @@ -0,0 +1,95 @@ +/* + * variant.cpp + * Copyright (C) 2023 Seeed K.K. + * MIT License + */ + +#include "variant.h" +#include "wiring_constants.h" +#include "wiring_digital.h" + +const uint32_t g_ADigitalPinMap[] = +{ + 0, // P0.00 + 1, // P0.01 + 2, // P0.02 + 3, // P0.03 + 4, // P0.04 + 5, // P0.05 + 6, // P0.06 + 7, // P0.07 + 8, // P0.08 + 9, // P0.09 + 10, // P0.10 + 11, // P0.11 + 12, // P0.12 + 13, // P0.13 + 14, // P0.14 + 15, // P0.15 + 16, // P0.16 + 17, // P0.17 + 18, // P0.18 + 19, // P0.19 + 20, // P0.20 + 21, // P0.21 + 22, // P0.22 + 23, // P0.23 + 24, // P0.24 + 25, // P0.25 + 26, // P0.26 + 27, // P0.27 + 28, // P0.28 + 29, // P0.29 + 30, // P0.30 + 31, // P0.31 + 32, // P1.00 + 33, // P1.01 + 34, // P1.02 + 35, // P1.03 + 36, // P1.04 + 37, // P1.05 + 38, // P1.06 + 39, // P1.07 + 40, // P1.08 + 41, // P1.09 + 42, // P1.10 + 43, // P1.11 + 44, // P1.12 + 45, // P1.13 + 46, // P1.14 + 47, // P1.15 +}; + +void initVariant() +{ +/* TODO */ + pinMode(PIN_PWR_EN, OUTPUT); + digitalWrite(PIN_PWR_EN, HIGH); + + pinMode(BAT_POWER, OUTPUT); + digitalWrite(BAT_POWER, HIGH); + pinMode(EEPROM_POWER, OUTPUT); + digitalWrite(EEPROM_POWER, HIGH); + + pinMode(36, OUTPUT); + digitalWrite(36, HIGH); + pinMode(34, OUTPUT); + digitalWrite(34, HIGH); + + pinMode(LED_POWER, OUTPUT); + digitalWrite(LED_POWER, HIGH); + + pinMode(PIN_LED_BLUE, OUTPUT); + pinMode(PIN_LED_GREEN, OUTPUT); + pinMode(PIN_LED_RED, OUTPUT); + + pinMode(BUTTON_PIN, INPUT_PULLUP); + + pinMode(PIN_GPS_POWER, OUTPUT); + pinMode(PIN_GPS_EN, OUTPUT); + pinMode(PIN_GPS_RESET, OUTPUT); + + // Power on gps but in standby + digitalWrite(PIN_GPS_EN, LOW); + digitalWrite(PIN_GPS_POWER, HIGH); +} diff --git a/variants/thinknode_m3/variant.h b/variants/thinknode_m3/variant.h new file mode 100644 index 000000000..02ed78a84 --- /dev/null +++ b/variants/thinknode_m3/variant.h @@ -0,0 +1,109 @@ +/* + * variant.h + * Copyright (C) 2023 Seeed K.K. + * MIT License + */ + +#pragma once + +#include "WVariant.h" + +//////////////////////////////////////////////////////////////////////////////// +// Low frequency clock source + +#define USE_LFXO // 32.768 kHz crystal oscillator +#define VARIANT_MCK (64000000ul) +// #define USE_LFRC // 32.768 kHz RC oscillator + +//////////////////////////////////////////////////////////////////////////////// +// Number of pins + +#define PINS_COUNT (48) +#define NUM_DIGITAL_PINS (48) +#define NUM_ANALOG_INPUTS (1) +#define NUM_ANALOG_OUTPUTS (0) + +//////////////////////////////////////////////////////////////////////////////// +// Power + +#define NRF_APM // detect usb power + + +#define EXT_CHRG_DETECT (32) // P1.3 +#define EXT_PWR_DETECT (31) // P0.5 + +#define PIN_VBAT_READ (5) +#define AREF_VOLTAGE (2.4f) +#define ADC_MULTIPLIER (2.0) //(1.75f) +// 2.0 gives more coherent value, 4.2V when charged, needs tweaking +#define ADC_RESOLUTION (12) +#define ADC_MAX (4096) + +#define EEPROM_POWER (7) +#define BAT_POWER (17) +#define PIN_PWR_EN (16) + + +//////////////////////////////////////////////////////////////////////////////// +// UART pin definition + +#define PIN_SERIAL1_RX PIN_GPS_TX +#define PIN_SERIAL1_TX PIN_GPS_RX + +//////////////////////////////////////////////////////////////////////////////// +// I2C pin definition + +#define HAS_WIRE (1) +#define WIRE_INTERFACES_COUNT (1) + +#define PIN_WIRE_SDA (26) // P0.26 +#define PIN_WIRE_SCL (27) // P0.27 +#define I2C_NO_RESCAN + +//////////////////////////////////////////////////////////////////////////////// +// SPI pin definition + +#define SPI_INTERFACES_COUNT (1) + +#define PIN_SPI_MISO (47) // P1.15 +#define PIN_SPI_MOSI (46) // P1.14 +#define PIN_SPI_SCK (45) // P1.13 +#define PIN_SPI_NSS (44) // P1.12 + +//////////////////////////////////////////////////////////////////////////////// +// Builtin LEDs + +#define LED_POWER (29) +#define LED_BLUE (-1) // No blue led +#define PIN_LED_BLUE (37) +#define PIN_LED_GREEN (35) // P0.24 +#define PIN_LED_RED (33) +#define LED_PIN PIN_LED_GREEN +#define LED_BUILTIN PIN_LED_BLUE +#define LED_STATE_ON LOW + +//////////////////////////////////////////////////////////////////////////////// +// Builtin buttons + +#define PIN_BUTTON1 (12) // P0.12 +#define BUTTON_PIN PIN_BUTTON1 + +//////////////////////////////////////////////////////////////////////////////// +// GPS + +#define HAS_GPS 1 +#define PIN_GPS_RX (22) +#define PIN_GPS_TX (20) + +#define PIN_GPS_POWER (14) +#define PIN_GPS_EN (21) // STANDBY +#define PIN_GPS_RESET (25) // REINIT +#define GPS_RESET_ACTIVE LOW +#define GPS_EN_ACTIVE HIGH +#define GPS_BAUDRATE 9600 + +//////////////////////////////////////////////////////////////////////////////// +// Buzzer + +#define BUZZER_EN (37) // P1.5 +#define BUZZER_PIN (25) // P0.25 \ No newline at end of file diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.cpp b/variants/wio-tracker-l1/WioTrackerL1Board.cpp index 34d9a8745..4153714e9 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.cpp +++ b/variants/wio-tracker-l1/WioTrackerL1Board.cpp @@ -1,37 +1,12 @@ #include -#include "WioTrackerL1Board.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"); -} +#include "WioTrackerL1Board.h" void WioTrackerL1Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; + NRF52BoardDCDC::begin(); btn_prev_state = HIGH; - // Enable DC/DC converter for improved power efficiency - uint8_t sd_enabled = 0; - sd_softdevice_is_enabled(&sd_enabled); - if (sd_enabled) { - sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); - } else { - NRF_POWER->DCDCEN = 1; - } - pinMode(PIN_VBAT_READ, INPUT); // VBAT ADC input // Set all button pins to INPUT_PULLUP pinMode(PIN_BUTTON1, INPUT_PULLUP); @@ -55,51 +30,3 @@ void WioTrackerL1Board::begin() { delay(10); // give sx1262 some time to power up } - -bool WioTrackerL1Board::startOTAUpdate(const char* id, char reply[]) { - // 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("WioTrackerL1 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 - - uint8_t mac_addr[6]; - memset(mac_addr, 0, sizeof(mac_addr)); - Bluefruit.getAddr(mac_addr); - sprintf(reply, "OK - mac: %02X:%02X:%02X:%02X:%02X:%02X", - mac_addr[5], mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0]); - - return true; -} diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.h b/variants/wio-tracker-l1/WioTrackerL1Board.h index f04b673f8..bfd87d396 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.h +++ b/variants/wio-tracker-l1/WioTrackerL1Board.h @@ -2,15 +2,15 @@ #include #include +#include -class WioTrackerL1Board : public mesh::MainBoard { +class WioTrackerL1Board : public NRF52BoardDCDC, public NRF52BoardOTA { protected: - uint8_t startup_reason; uint8_t btn_prev_state; public: + WioTrackerL1Board() : NRF52BoardOTA("WioTrackerL1 OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -34,13 +34,7 @@ class WioTrackerL1Board : public mesh::MainBoard { return "Seeed Wio Tracker L1"; } - void reboot() override { - NVIC_SystemReset(); - } - void powerOff() override { sd_power_system_off(); } - - bool startOTAUpdate(const char* id, char reply[]) override; }; diff --git a/variants/wio_wm1110/WioWM1110Board.cpp b/variants/wio_wm1110/WioWM1110Board.cpp index 153d476c4..d0ab97858 100644 --- a/variants/wio_wm1110/WioWM1110Board.cpp +++ b/variants/wio_wm1110/WioWM1110Board.cpp @@ -21,16 +21,7 @@ static void disconnect_callback(uint16_t conn_handle, uint8_t reason) { } void WioWM1110Board::begin() { - startup_reason = BD_STARTUP_NORMAL; - - // Enable DC/DC converter for improved power efficiency - uint8_t sd_enabled = 0; - sd_softdevice_is_enabled(&sd_enabled); - if (sd_enabled) { - sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); - } else { - NRF_POWER->DCDCEN = 1; - } + NRF52BoardDCDC::begin(); pinMode(BATTERY_PIN, INPUT); pinMode(LED_GREEN, OUTPUT); diff --git a/variants/wio_wm1110/WioWM1110Board.h b/variants/wio_wm1110/WioWM1110Board.h index 823acbc7d..697028b06 100644 --- a/variants/wio_wm1110/WioWM1110Board.h +++ b/variants/wio_wm1110/WioWM1110Board.h @@ -2,6 +2,7 @@ #include #include +#include #ifdef WIO_WM1110 @@ -10,13 +11,9 @@ #endif #define Serial Serial1 -class WioWM1110Board : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class WioWM1110Board : public NRF52BoardDCDC { public: void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(LED_GREEN) void onBeforeTransmit() override { @@ -40,10 +37,6 @@ class WioWM1110Board : public mesh::MainBoard { return "Seeed Wio WM1110"; } - void reboot() override { - NVIC_SystemReset(); - } - bool startOTAUpdate(const char* id, char reply[]) override; void enableSensorPower(bool enable) { diff --git a/variants/xiao_nrf52/XiaoNrf52Board.cpp b/variants/xiao_nrf52/XiaoNrf52Board.cpp index f847c6543..b7b60dc63 100644 --- a/variants/xiao_nrf52/XiaoNrf52Board.cpp +++ b/variants/xiao_nrf52/XiaoNrf52Board.cpp @@ -2,36 +2,11 @@ #include #include -#include #include "XiaoNrf52Board.h" -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"); -} - void XiaoNrf52Board::begin() { - // for future use, sub-classes SHOULD call this from their begin() - startup_reason = BD_STARTUP_NORMAL; - - // Enable DC/DC converter for improved power efficiency - uint8_t sd_enabled = 0; - sd_softdevice_is_enabled(&sd_enabled); - if (sd_enabled) { - sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); - } else { - NRF_POWER->DCDCEN = 1; - } + NRF52BoardDCDC::begin(); pinMode(PIN_VBAT, INPUT); pinMode(VBAT_ENABLE, OUTPUT); @@ -57,48 +32,4 @@ void XiaoNrf52Board::begin() { delay(10); // give sx1262 some time to power up } -bool XiaoNrf52Board::startOTAUpdate(const char *id, char reply[]) { - // 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("XIAO_NRF52_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 - - strcpy(reply, "OK - started"); - - return true; -} - #endif \ No newline at end of file diff --git a/variants/xiao_nrf52/XiaoNrf52Board.h b/variants/xiao_nrf52/XiaoNrf52Board.h index f37660123..1c46dfeee 100644 --- a/variants/xiao_nrf52/XiaoNrf52Board.h +++ b/variants/xiao_nrf52/XiaoNrf52Board.h @@ -2,16 +2,14 @@ #include #include +#include #ifdef XIAO_NRF52 -class XiaoNrf52Board : public mesh::MainBoard { -protected: - uint8_t startup_reason; - +class XiaoNrf52Board : public NRF52BoardDCDC, public NRF52BoardOTA { public: + XiaoNrf52Board() : NRF52BoardOTA("XIAO_NRF52_OTA") {} void begin(); - uint8_t getStartupReason() const override { return startup_reason; } #if defined(P_LORA_TX_LED) void onBeforeTransmit() override { @@ -42,10 +40,6 @@ class XiaoNrf52Board : public mesh::MainBoard { return "Seeed Xiao-nrf52"; } - void reboot() override { - NVIC_SystemReset(); - } - void powerOff() override { // set led on and wait for button release before poweroff digitalWrite(PIN_LED, LOW); @@ -63,8 +57,6 @@ class XiaoNrf52Board : public mesh::MainBoard { sd_power_system_off(); } - - bool startOTAUpdate(const char* id, char reply[]) override; }; #endif \ No newline at end of file