Browse Source

Merge branch 'dev' into tracker_l1_environment_sensors

Florent 10 tháng trước cách đây
mục cha
commit
c9b060aefb

+ 33 - 0
boards/tiny_relay.json

@@ -0,0 +1,33 @@
+{
+  "build": {
+    "arduino": {
+      "variant_h": "variant_RAK3172_MODULE.h"
+    },
+    "core": "stm32",
+    "cpu": "cortex-m4",
+    "extra_flags": "-DSTM32WL -DSTM32WLxx -DSTM32WLE5xx",
+    "framework_extra_flags": {
+      "arduino": "-DUSE_CM4_STARTUP_FILE -DARDUINO_RAK3172_MODULE"
+    },
+    "f_cpu": "48000000L",
+    "mcu": "stm32wle5ccu",
+    "product_line": "STM32WLE5xx",
+    "variant": "STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U"
+  },
+  "debug": {
+    "default_tools": ["stlink"],
+    "jlink_device": "STM32WLE5CC",
+    "openocd_target": "stm32wlx",
+    "svd_path": "STM32WLE5_CM4.svd"
+  },
+  "frameworks": ["arduino"],
+  "name": "BB-STM32WL",
+  "upload": {
+    "maximum_ram_size": 65536,
+    "maximum_size": 262144,
+    "protocol": "stlink",
+    "protocols": ["stlink", "jlink"]
+  },
+  "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wle5cc.html",
+  "vendor": "YAOYAO"
+}

+ 15 - 2
examples/companion_radio/DataStore.cpp

@@ -42,12 +42,17 @@ static File openWrite(FILESYSTEM* fs, const char* filename) {
 #endif
 }
 
+#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
+  static uint32_t _ContactsChannelsTotalBlocks = 0;
+#endif
+
 void DataStore::begin() {
 #if defined(RP2040_PLATFORM)
   identity_store.begin();
 #endif
 
 #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
+  _ContactsChannelsTotalBlocks = _getContactsChannelsFS()->_getFS()->cfg->block_count;
   checkAdvBlobFile();
   #if defined(EXTRAFS) || defined(QSPIFLASH)
   migrateToSecondaryFS();
@@ -74,14 +79,22 @@ void DataStore::begin() {
 
 #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
 int _countLfsBlock(void *p, lfs_block_t block){
+      if (block > _ContactsChannelsTotalBlocks) {
+        MESH_DEBUG_PRINTLN("ERROR: Block %d exceeds filesystem bounds - CORRUPTION DETECTED!", block);
+        return LFS_ERR_CORRUPT;  // return error to abort lfs_traverse() gracefully
+    }
   lfs_size_t *size = (lfs_size_t*) p;
   *size += 1;
-  return 0;
+    return 0;
 }
 
 lfs_ssize_t _getLfsUsedBlockCount(FILESYSTEM* fs) {
   lfs_size_t size = 0;
-  lfs_traverse(fs->_getFS(), _countLfsBlock, &size);
+  int err = lfs_traverse(fs->_getFS(), _countLfsBlock, &size);
+  if (err) {
+    MESH_DEBUG_PRINTLN("ERROR: lfs_traverse() error: %d", err);
+    return 0;
+  }
   return size;
 }
 #endif

+ 20 - 1
examples/companion_radio/MyMesh.cpp

@@ -175,15 +175,34 @@ void MyMesh::updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, co
   }
 }
 
+bool MyMesh::Frame::isChannelMsg() const {
+  return buf[0] == RESP_CODE_CHANNEL_MSG_RECV || buf[0] == RESP_CODE_CHANNEL_MSG_RECV_V3;
+}
+
 void MyMesh::addToOfflineQueue(const uint8_t frame[], int len) {
   if (offline_queue_len >= OFFLINE_QUEUE_SIZE) {
-    MESH_DEBUG_PRINTLN("ERROR: offline_queue is full!");
+    MESH_DEBUG_PRINTLN("WARN: offline_queue is full!");
+    int pos = 0;
+    while (pos < offline_queue_len) {
+      if (offline_queue[pos].isChannelMsg()) {
+        for (int i = pos; i < offline_queue_len - 1; i++) { // delete oldest channel msg from queue
+          offline_queue[i] = offline_queue[i + 1];
+        }
+        MESH_DEBUG_PRINTLN("INFO: removed oldest channel message from queue.");
+        offline_queue[offline_queue_len - 1].len = len;
+        memcpy(offline_queue[offline_queue_len - 1].buf, frame, len);
+        return;
+      }
+      pos++;
+    }
+    MESH_DEBUG_PRINTLN("INFO: no channel messages to remove from queue.");
   } else {
     offline_queue[offline_queue_len].len = len;
     memcpy(offline_queue[offline_queue_len].buf, frame, len);
     offline_queue_len++;
   }
 }
+
 int MyMesh::getFromOfflineQueue(uint8_t frame[]) {
   if (offline_queue_len > 0) {         // check offline queue
     size_t len = offline_queue[0].len; // take from top of queue

+ 2 - 0
examples/companion_radio/MyMesh.h

@@ -198,6 +198,8 @@ private:
   struct Frame {
     uint8_t len;
     uint8_t buf[MAX_FRAME_SIZE];
+
+    bool isChannelMsg() const;
   };
   int offline_queue_len;
   Frame offline_queue[OFFLINE_QUEUE_SIZE];

+ 44 - 0
variants/tiny_relay/platformio.ini

@@ -0,0 +1,44 @@
+[Tiny_Relay]
+extends = stm32_base
+board = tiny_relay
+board_upload.maximum_size = 229376 ; 32kb for FS
+build_flags = ${stm32_base.build_flags}
+  -D RADIO_CLASS=CustomSTM32WLx
+  -D WRAPPER_CLASS=CustomSTM32WLxWrapper
+  -D SPI_INTERFACES_COUNT=0
+  -D RX_BOOSTED_GAIN=true
+;  -D STM32WL_TCXO_VOLTAGE=1.6 ; defaults to 0 if undef
+;  -D LORA_TX_POWER=14 ; Defaults to 22 for HP, 14 is for LP version
+  -D LORA_TX_POWER=22 ; Enable 22dBm transmission
+  -D MAX_LORA_TX_POWER=22 ; Allow setting up to 22dBm in companion radio
+  -I variants/tiny_relay
+build_src_filter = ${stm32_base.build_src_filter}
+  +<../variants/tiny_relay>
+
+[env:Tiny_Relay-repeater]
+extends = Tiny_Relay
+build_flags = ${Tiny_Relay.build_flags}
+  -D ADVERT_NAME='"tiny_relay Repeater"'
+  -D ADMIN_PASSWORD='"password"'
+build_src_filter = ${Tiny_Relay.build_src_filter}
+  +<../examples/simple_repeater/main.cpp>
+
+[env:Tiny_Relay-sensor]
+extends = Tiny_Relay
+build_flags = ${Tiny_Relay.build_flags}
+  -D ADVERT_NAME='"tiny_relay Sensor"'
+  -D ADMIN_PASSWORD='"password"'
+build_src_filter = ${Tiny_Relay.build_src_filter}
+  +<../examples/simple_sensor>
+
+[env:Tiny_Relay_companion_radio_usb]
+extends = Tiny_Relay
+build_flags = ${Tiny_Relay.build_flags}
+;  -D FORMAT_FS=true
+  -D MAX_CONTACTS=100
+  -D MAX_GROUP_CHANNELS=8
+  -D MAX_LORA_TX_POWER=22
+build_src_filter = ${Tiny_Relay.build_src_filter}
+  +<../examples/companion_radio/*.cpp>
+lib_deps = ${Tiny_Relay.lib_deps}
+  densaugeo/base64 @ ~1.4.0

+ 82 - 0
variants/tiny_relay/target.cpp

@@ -0,0 +1,82 @@
+#include "target.h"
+#include <Arduino.h>
+#include <helpers/ArduinoHelpers.h>
+
+TinyRelayBoard board;
+
+RADIO_CLASS radio = new STM32WLx_Module();
+
+WRAPPER_CLASS radio_driver(radio, board);
+
+static const uint32_t rfswitch_pins[] = {LORAWAN_RFSWITCH_PINS, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+    {STM32WLx::MODE_IDLE, {LOW, LOW}},
+    {STM32WLx::MODE_RX, {HIGH, LOW}},
+    {STM32WLx::MODE_TX_LP, {LOW, HIGH}},
+    {STM32WLx::MODE_TX_HP, {LOW, HIGH}},
+    END_OF_MODE_TABLE,
+};
+
+VolatileRTCClock rtc_clock;
+SensorManager sensors;
+
+#ifndef LORA_CR
+#define LORA_CR 5
+#endif
+
+#ifndef STM32WL_TCXO_VOLTAGE
+// TCXO set to 0 for RAK3172
+#define STM32WL_TCXO_VOLTAGE 0
+#endif
+
+#ifndef LORA_TX_POWER
+#define LORA_TX_POWER 22
+#endif
+
+bool radio_init()
+{
+    //  rtc_clock.begin(Wire);
+
+    radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+    int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16,
+                             STM32WL_TCXO_VOLTAGE, 0);
+
+    if (status != RADIOLIB_ERR_NONE) {
+        Serial.print("ERROR: radio init failed: ");
+        Serial.println(status);
+        return false; // fail
+    }
+
+#ifdef RX_BOOSTED_GAIN
+    radio.setRxBoostedGainMode(RX_BOOSTED_GAIN);
+#endif
+
+    radio.setCRC(1);
+
+    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
+}

+ 59 - 0
variants/tiny_relay/target.h

@@ -0,0 +1,59 @@
+#pragma once
+
+#define RADIOLIB_STATIC_ONLY 1
+#include <RadioLib.h>
+#include <helpers/ArduinoHelpers.h>
+#include <helpers/SensorManager.h>
+#include <helpers/radiolib/CustomSTM32WLxWrapper.h>
+#include <helpers/radiolib/RadioLibWrappers.h>
+#include <helpers/stm32/STM32Board.h>
+
+#define PIN_VBAT_READ A0
+#define ADC_MULTIPLIER (5 * 1.73 * 1000)
+
+class TinyRelayBoard : public STM32Board
+{
+  public:
+    void begin() override
+    {
+        STM32Board::begin();
+        pinMode(PA0, OUTPUT);
+        pinMode(PA1, OUTPUT);
+    }
+
+    const char *getManufacturerName() const override { return "Tiny Relay"; }
+
+    uint16_t getBattMilliVolts() override
+    {
+        analogReadResolution(12);
+        uint32_t raw = 0;
+        for (int i = 0; i < 8; i++) {
+            raw += analogRead(PIN_VBAT_READ);
+        }
+        return ((double)raw) * ADC_MULTIPLIER / 8 / 4096;
+    }
+
+    void setGpio(uint32_t values) override
+    {
+        // set led values
+        digitalWrite(PA0, values & 1);
+        digitalWrite(PA1, (values & 2) >> 1);
+    }
+
+    uint32_t getGpio() override
+    {
+        // get led value
+        return (digitalRead(PA1) << 1) | digitalRead(PA0);
+    }
+};
+
+extern TinyRelayBoard board;
+extern WRAPPER_CLASS radio_driver;
+extern VolatileRTCClock rtc_clock;
+extern SensorManager 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();

+ 5 - 0
variants/tiny_relay/variant.h

@@ -0,0 +1,5 @@
+#pragma once
+
+#include <variant_RAK3172_MODULE.h>
+
+#undef RNG