Browse Source

Support for Elecrow Thinknode M2

Tomas P 9 months ago
parent
commit
31b8f7252a

+ 39 - 0
boards/ESP32-S3-WROOM-1-N4.json

@@ -0,0 +1,39 @@
+{
+  "build": {
+    "arduino": {
+      "ldscript": "esp32s3_out.ld"
+    },
+    "core": "esp32",
+    "extra_flags": [
+      "-D ARDUINO_USB_CDC_ON_BOOT=0",
+      "-D ARDUINO_USB_MSC_ON_BOOT=0",
+      "-D ARDUINO_USB_DFU_ON_BOOT=0",
+      "-D ARDUINO_USB_MODE=0",
+      "-D ARDUINO_RUNNING_CORE=1",
+      "-D ARDUINO_EVENT_RUNNING_CORE=1"
+    ],
+    "f_cpu": "240000000L",
+    "f_flash": "80000000L",
+    "flash_mode": "qio",
+    "hwids": [["0x303A", "0x1001"]],
+    "mcu": "esp32s3",
+    "variant": "ESP32-S3-WROOM-1-N4"
+  },
+  "connectivity": ["wifi", "bluetooth"],
+  "debug": {
+    "default_tool": "esp-builtin",
+    "onboard_tools": ["esp-builtin"],
+    "openocd_target": "esp32s3.cfg"
+  },
+  "frameworks": ["arduino", "espidf"],
+  "name": "ESP32-S3-WROOM-1-N4 (4 MB Flash, No PSRAM)",
+  "upload": {
+    "flash_size": "4MB",
+    "maximum_ram_size": 524288,
+    "maximum_size": 4194304,
+    "require_upload_port": true,
+    "speed": 921600
+  },
+  "url": "https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf",
+  "vendor": "Espressif"
+}

+ 32 - 0
variants/thinknode_m2/ThinknodeM2Board.cpp

@@ -0,0 +1,32 @@
+#include "ThinknodeM2Board.h"
+
+
+
+void ThinknodeM2Board::begin() {
+    ESP32Board::begin();
+    pinMode(PIN_VEXT_EN, OUTPUT); // init display
+    digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE); // pin needs to be high
+    delay(10); 
+    digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE); // need to do this twice. do not know why..
+    pinMode(PIN_STATUS_LED, OUTPUT); // init power led    
+  }
+
+  void ThinknodeM2Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
+    esp_deep_sleep_start();
+  }
+
+  void ThinknodeM2Board::powerOff()  {
+    enterDeepSleep(0);
+  }
+
+  uint16_t ThinknodeM2Board::getBattMilliVolts()  {
+    analogReadResolution(12);
+    delay(10);
+    float volts = (analogRead(PIN_VBAT_READ) * ADC_MULTIPLIER * AREF_VOLTAGE) / 4096;
+    analogReadResolution(10);
+    return volts * 1000;
+  }
+
+  const char* ThinknodeM2Board::getManufacturerName() const {
+    return "Elecrow ThinkNode M2";
+  }

+ 18 - 0
variants/thinknode_m2/ThinknodeM2Board.h

@@ -0,0 +1,18 @@
+#pragma once
+
+#include <Arduino.h>
+#include <helpers/RefCountedDigitalPin.h>
+#include <helpers/ESP32Board.h>
+#include <driver/rtc_io.h>
+
+class ThinknodeM2Board : public ESP32Board {
+
+public:
+
+  void begin();
+  void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);
+  void powerOff() override;
+  uint16_t getBattMilliVolts() override;
+  const char* getManufacturerName() const override ;
+
+};

+ 28 - 0
variants/thinknode_m2/pins_arduino.h

@@ -0,0 +1,28 @@
+// Need this file for ESP32-S3
+// No need to modify this file, changes to pins imported from variant.h
+// Most is similar to https://github.com/espressif/arduino-esp32/blob/master/variants/esp32s3/pins_arduino.h
+
+#ifndef Pins_Arduino_h
+#define Pins_Arduino_h
+
+#include <stdint.h>
+#include <variant.h>
+
+#define USB_VID 0x303a
+#define USB_PID 0x1001
+
+// Serial
+static const uint8_t TX = GPS_TX;
+static const uint8_t RX = GPS_RX;
+
+// Default SPI will be mapped to Radio
+static const uint8_t SS = P_LORA_NSS;
+static const uint8_t SCK = P_LORA_SCLK;
+static const uint8_t MOSI = P_LORA_MISO;
+static const uint8_t MISO = P_LORA_MOSI;
+
+// The default Wire will be mapped to PMU and RTC
+static const uint8_t SCL = PIN_BOARD_SCL;
+static const uint8_t SDA = PIN_BOARD_SDA;
+
+#endif /* Pins_Arduino_h */

+ 171 - 0
variants/thinknode_m2/platformio.ini

@@ -0,0 +1,171 @@
+[ThinkNode_M2]
+extends = esp32_base
+board = ESP32-S3-WROOM-1-N4
+build_flags = ${esp32_base.build_flags}
+  -I variants/thinknode_m2
+  -D THINKNODE_M2
+  -D GPS_RX=44
+  -D GPS_TX=43
+  -D PIN_VEXT_EN=46
+  -D PIN_BUZZER=5
+  -D PIN_VEXT_EN_ACTIVE=HIGH
+  -D PIN_BOARD_SCL=15
+  -D PIN_BOARD_SDA=16
+  -D P_LORA_DIO_1=3
+  -D P_LORA_NSS=10
+  -D P_LORA_RESET=21   ; RADIOLIB_NC
+  -D P_LORA_BUSY=14   ;  DIO2 = 38
+  -D P_LORA_SCLK=12
+  -D P_LORA_MISO=13
+  -D P_LORA_MOSI=11
+  -D PIN_USER_BTN=47
+  -D PIN_STATUS_LED=6
+  -D PIN_LED=6
+  -D SX126X_DIO2_AS_RF_SWITCH=true
+  -D SX126X_DIO3_TCXO_VOLTAGE=3.3
+  -D SX126X_CURRENT_LIMIT=140
+  -D DISPLAY_CLASS=SH1106Display
+  -D RADIO_CLASS=CustomSX1262
+  -D WRAPPER_CLASS=CustomSX1262Wrapper
+  -D LORA_TX_POWER=22
+  -D SX126X_RX_BOOSTED_GAIN=1
+  -D MESH_DEBUG=1
+build_src_filter = ${esp32_base.build_src_filter}
+  +<helpers/ui/SH1106Display.cpp>
+  +<helpers/ui/MomentaryButton.cpp>
+  +<helpers/ui/buzzer.cpp>
+  +<../variants/thinknode_m2>
+lib_deps = ${esp32_base.lib_deps}
+  adafruit/Adafruit SH110X @ ~2.1.13
+  adafruit/Adafruit GFX Library @ ^1.12.1
+
+[env:ThinkNode_M2_Repeater]
+extends = ThinkNode_M2
+build_src_filter = ${ThinkNode_M2.build_src_filter}
+  +<../examples/simple_repeater/*.cpp>
+build_flags =
+  ${ThinkNode_M2.build_flags}
+  -D ADVERT_NAME='"Thinknode M2 Repeater"'
+  -D ADVERT_LAT=0.0
+  -D ADVERT_LON=0.0
+  -D ADMIN_PASSWORD='"password"'
+  -D MAX_NEIGHBOURS=8
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+lib_deps =
+  ${ThinkNode_M2.lib_deps}
+  ${esp32_ota.lib_deps}
+
+; [env:ThinkNode_M2_Repeater_bridge_rs232]
+; extends = ThinkNode_M2
+; build_src_filter = ${ThinkNode_M2.build_src_filter}
+;   +<helpers/bridges/RS232Bridge.cpp>
+;   +<../examples/simple_repeater/*.cpp>
+; build_flags =
+;   ${ThinkNode_M2.build_flags}
+;   -D ADVERT_NAME='"RS232 Bridge"'
+;   -D ADVERT_LAT=0.0
+;   -D ADVERT_LON=0.0
+;   -D ADMIN_PASSWORD='"password"'
+;   -D MAX_NEIGHBOURS=8
+;   -D WITH_RS232_BRIDGE=Serial2
+;   -D WITH_RS232_BRIDGE_RX=5
+;   -D WITH_RS232_BRIDGE_TX=6
+; ;  -D MESH_PACKET_LOGGING=1
+; ;  -D MESH_DEBUG=1
+; lib_deps =
+;   ${ThinkNode_M2.lib_deps}
+;   ${esp32_ota.lib_deps}
+
+[env:ThinkNode_M2_Repeater_bridge_espnow]
+extends = ThinkNode_M2
+build_src_filter = ${ThinkNode_M2.build_src_filter}
+  +<helpers/bridges/ESPNowBridge.cpp>
+  +<../examples/simple_repeater/*.cpp>
+build_flags =
+  ${ThinkNode_M2.build_flags}
+  -D ADVERT_NAME='"ESPNow Bridge"'
+  -D ADVERT_LAT=0.0
+  -D ADVERT_LON=0.0
+  -D ADMIN_PASSWORD='"password"'
+  -D MAX_NEIGHBOURS=8
+  -D WITH_ESPNOW_BRIDGE=1
+  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+lib_deps =
+  ${ThinkNode_M2.lib_deps}
+  ${esp32_ota.lib_deps}
+
+[env:ThinkNode_M2_room_server]
+extends = ThinkNode_M2
+build_src_filter = ${ThinkNode_M2.build_src_filter}
+  +<../examples/simple_room_server>
+build_flags =
+  ${ThinkNode_M2.build_flags}
+  -D ADVERT_NAME='"Thinknode M2 Room Server"'
+  -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
+lib_deps =
+  ${ThinkNode_M2.lib_deps}
+  ${esp32_ota.lib_deps}
+
+[env:ThinkNode_M2_terminal_chat]
+extends = ThinkNode_M2
+build_flags =
+  ${ThinkNode_M2.build_flags}
+  -D MAX_CONTACTS=300
+  -D MAX_GROUP_CHANNELS=8
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${ThinkNode_M2.build_src_filter}
+  +<../examples/simple_secure_chat/main.cpp>
+lib_deps =
+  ${ThinkNode_M2.lib_deps}
+  densaugeo/base64 @ ~1.4.0
+
+[env:ThinkNode_M2_companion_radio_ble]
+extends = ThinkNode_M2
+build_flags =
+  ${ThinkNode_M2.build_flags}
+  -I examples/companion_radio/ui-new
+  -D MAX_CONTACTS=300
+  -D MAX_GROUP_CHANNELS=8
+  -D BLE_PIN_CODE=123456
+  -D OFFLINE_QUEUE_SIZE=256
+;  -D BLE_DEBUG_LOGGING=1
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${ThinkNode_M2.build_src_filter}
+  +<helpers/esp32/*.cpp>
+  +<helpers/ui/MomentaryButton.cpp>
+  +<../examples/companion_radio/*.cpp>
+  +<../examples/companion_radio/ui-new/*.cpp>
+
+lib_deps =
+  ${ThinkNode_M2.lib_deps}
+  densaugeo/base64 @ ~1.4.0
+
+[env:ThinkNode_M2_companion_radio_serial]
+extends = ThinkNode_M2
+build_flags =
+  ${ThinkNode_M2.build_flags}
+  -I examples/companion_radio/ui-new
+  -D MAX_CONTACTS=300
+  -D MAX_GROUP_CHANNELS=8
+  -D SERIAL_TX=D6
+  -D SERIAL_RX=D7
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${ThinkNode_M2.build_src_filter}
+  +<helpers/esp32/*.cpp>
+  +<helpers/ui/MomentaryButton.cpp>
+  +<../examples/companion_radio/*.cpp>
+  +<../examples/companion_radio/ui-new/*.cpp>
+lib_deps =
+  ${ThinkNode_M2.lib_deps}
+  densaugeo/base64 @ ~1.4.0

+ 57 - 0
variants/thinknode_m2/target.cpp

@@ -0,0 +1,57 @@
+#include <Arduino.h>
+#include "target.h"
+
+ThinknodeM2Board board;
+
+#if defined(P_LORA_SCLK)
+  static SPIClass spi;
+  RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
+#else
+  RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
+#endif
+
+WRAPPER_CLASS radio_driver(radio, board);
+
+ESP32RTCClock fallback_clock;
+AutoDiscoverRTCClock rtc_clock(fallback_clock);
+SensorManager sensors;
+
+#ifdef DISPLAY_CLASS
+  DISPLAY_CLASS display;
+  MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
+#endif
+
+bool radio_init() {
+  fallback_clock.begin();
+  rtc_clock.begin(Wire);
+  pinMode(21, INPUT);
+  pinMode(48, OUTPUT);
+  #if defined(P_LORA_SCLK)
+  spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
+  return radio.std_init(&spi);
+#else
+  return radio.std_init();
+#endif
+}
+
+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
+}
+

+ 32 - 0
variants/thinknode_m2/target.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#define RADIOLIB_STATIC_ONLY 1
+#include <RadioLib.h>
+#include <helpers/radiolib/RadioLibWrappers.h>
+//#include <helpers/ESP32Board.h>
+#include <ThinknodeM2Board.h>
+#include <helpers/radiolib/CustomSX1262Wrapper.h>
+#include <helpers/AutoDiscoverRTCClock.h>
+#include <helpers/SensorManager.h>
+#ifdef DISPLAY_CLASS
+  #include <helpers/ui/SH1106Display.h>
+  #include <helpers/ui/MomentaryButton.h>
+#endif
+
+extern ThinknodeM2Board board;
+extern WRAPPER_CLASS radio_driver;
+extern AutoDiscoverRTCClock rtc_clock;
+extern SensorManager sensors;
+
+#ifdef DISPLAY_CLASS
+  extern DISPLAY_CLASS display;
+  extern MomentaryButton user_btn;
+#endif
+
+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();
+
+ 

+ 15 - 0
variants/thinknode_m2/variant.h

@@ -0,0 +1,15 @@
+#define I2C_SCL 15
+#define I2C_SDA 16
+#define  PIN_VBAT_READ    17
+#define AREF_VOLTAGE            (3.0)
+#define ADC_MULTIPLIER (1.548F)
+#define PIN_BUZZER 5
+#define PIN_VEXT_EN_ACTIVE HIGH
+#define PIN_VEXT_EN 46
+#define PIN_USER_BTN 47
+#define PIN_LED 6
+#define PIN_STATUS_LED 6
+#define PIN_PWRBTN 4
+
+
+