Skip to content

Commit 31b8f72

Browse files
committed
Support for Elecrow Thinknode M2
1 parent 99e44f4 commit 31b8f72

File tree

8 files changed

+392
-0
lines changed

8 files changed

+392
-0
lines changed

boards/ESP32-S3-WROOM-1-N4.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"build": {
3+
"arduino": {
4+
"ldscript": "esp32s3_out.ld"
5+
},
6+
"core": "esp32",
7+
"extra_flags": [
8+
"-D ARDUINO_USB_CDC_ON_BOOT=0",
9+
"-D ARDUINO_USB_MSC_ON_BOOT=0",
10+
"-D ARDUINO_USB_DFU_ON_BOOT=0",
11+
"-D ARDUINO_USB_MODE=0",
12+
"-D ARDUINO_RUNNING_CORE=1",
13+
"-D ARDUINO_EVENT_RUNNING_CORE=1"
14+
],
15+
"f_cpu": "240000000L",
16+
"f_flash": "80000000L",
17+
"flash_mode": "qio",
18+
"hwids": [["0x303A", "0x1001"]],
19+
"mcu": "esp32s3",
20+
"variant": "ESP32-S3-WROOM-1-N4"
21+
},
22+
"connectivity": ["wifi", "bluetooth"],
23+
"debug": {
24+
"default_tool": "esp-builtin",
25+
"onboard_tools": ["esp-builtin"],
26+
"openocd_target": "esp32s3.cfg"
27+
},
28+
"frameworks": ["arduino", "espidf"],
29+
"name": "ESP32-S3-WROOM-1-N4 (4 MB Flash, No PSRAM)",
30+
"upload": {
31+
"flash_size": "4MB",
32+
"maximum_ram_size": 524288,
33+
"maximum_size": 4194304,
34+
"require_upload_port": true,
35+
"speed": 921600
36+
},
37+
"url": "https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf",
38+
"vendor": "Espressif"
39+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "ThinknodeM2Board.h"
2+
3+
4+
5+
void ThinknodeM2Board::begin() {
6+
ESP32Board::begin();
7+
pinMode(PIN_VEXT_EN, OUTPUT); // init display
8+
digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE); // pin needs to be high
9+
delay(10);
10+
digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE); // need to do this twice. do not know why..
11+
pinMode(PIN_STATUS_LED, OUTPUT); // init power led
12+
}
13+
14+
void ThinknodeM2Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
15+
esp_deep_sleep_start();
16+
}
17+
18+
void ThinknodeM2Board::powerOff() {
19+
enterDeepSleep(0);
20+
}
21+
22+
uint16_t ThinknodeM2Board::getBattMilliVolts() {
23+
analogReadResolution(12);
24+
delay(10);
25+
float volts = (analogRead(PIN_VBAT_READ) * ADC_MULTIPLIER * AREF_VOLTAGE) / 4096;
26+
analogReadResolution(10);
27+
return volts * 1000;
28+
}
29+
30+
const char* ThinknodeM2Board::getManufacturerName() const {
31+
return "Elecrow ThinkNode M2";
32+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
3+
#include <Arduino.h>
4+
#include <helpers/RefCountedDigitalPin.h>
5+
#include <helpers/ESP32Board.h>
6+
#include <driver/rtc_io.h>
7+
8+
class ThinknodeM2Board : public ESP32Board {
9+
10+
public:
11+
12+
void begin();
13+
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);
14+
void powerOff() override;
15+
uint16_t getBattMilliVolts() override;
16+
const char* getManufacturerName() const override ;
17+
18+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Need this file for ESP32-S3
2+
// No need to modify this file, changes to pins imported from variant.h
3+
// Most is similar to https://github.com/espressif/arduino-esp32/blob/master/variants/esp32s3/pins_arduino.h
4+
5+
#ifndef Pins_Arduino_h
6+
#define Pins_Arduino_h
7+
8+
#include <stdint.h>
9+
#include <variant.h>
10+
11+
#define USB_VID 0x303a
12+
#define USB_PID 0x1001
13+
14+
// Serial
15+
static const uint8_t TX = GPS_TX;
16+
static const uint8_t RX = GPS_RX;
17+
18+
// Default SPI will be mapped to Radio
19+
static const uint8_t SS = P_LORA_NSS;
20+
static const uint8_t SCK = P_LORA_SCLK;
21+
static const uint8_t MOSI = P_LORA_MISO;
22+
static const uint8_t MISO = P_LORA_MOSI;
23+
24+
// The default Wire will be mapped to PMU and RTC
25+
static const uint8_t SCL = PIN_BOARD_SCL;
26+
static const uint8_t SDA = PIN_BOARD_SDA;
27+
28+
#endif /* Pins_Arduino_h */
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
[ThinkNode_M2]
2+
extends = esp32_base
3+
board = ESP32-S3-WROOM-1-N4
4+
build_flags = ${esp32_base.build_flags}
5+
-I variants/thinknode_m2
6+
-D THINKNODE_M2
7+
-D GPS_RX=44
8+
-D GPS_TX=43
9+
-D PIN_VEXT_EN=46
10+
-D PIN_BUZZER=5
11+
-D PIN_VEXT_EN_ACTIVE=HIGH
12+
-D PIN_BOARD_SCL=15
13+
-D PIN_BOARD_SDA=16
14+
-D P_LORA_DIO_1=3
15+
-D P_LORA_NSS=10
16+
-D P_LORA_RESET=21 ; RADIOLIB_NC
17+
-D P_LORA_BUSY=14 ; DIO2 = 38
18+
-D P_LORA_SCLK=12
19+
-D P_LORA_MISO=13
20+
-D P_LORA_MOSI=11
21+
-D PIN_USER_BTN=47
22+
-D PIN_STATUS_LED=6
23+
-D PIN_LED=6
24+
-D SX126X_DIO2_AS_RF_SWITCH=true
25+
-D SX126X_DIO3_TCXO_VOLTAGE=3.3
26+
-D SX126X_CURRENT_LIMIT=140
27+
-D DISPLAY_CLASS=SH1106Display
28+
-D RADIO_CLASS=CustomSX1262
29+
-D WRAPPER_CLASS=CustomSX1262Wrapper
30+
-D LORA_TX_POWER=22
31+
-D SX126X_RX_BOOSTED_GAIN=1
32+
-D MESH_DEBUG=1
33+
build_src_filter = ${esp32_base.build_src_filter}
34+
+<helpers/ui/SH1106Display.cpp>
35+
+<helpers/ui/MomentaryButton.cpp>
36+
+<helpers/ui/buzzer.cpp>
37+
+<../variants/thinknode_m2>
38+
lib_deps = ${esp32_base.lib_deps}
39+
adafruit/Adafruit SH110X @ ~2.1.13
40+
adafruit/Adafruit GFX Library @ ^1.12.1
41+
42+
[env:ThinkNode_M2_Repeater]
43+
extends = ThinkNode_M2
44+
build_src_filter = ${ThinkNode_M2.build_src_filter}
45+
+<../examples/simple_repeater/*.cpp>
46+
build_flags =
47+
${ThinkNode_M2.build_flags}
48+
-D ADVERT_NAME='"Thinknode M2 Repeater"'
49+
-D ADVERT_LAT=0.0
50+
-D ADVERT_LON=0.0
51+
-D ADMIN_PASSWORD='"password"'
52+
-D MAX_NEIGHBOURS=8
53+
; -D MESH_PACKET_LOGGING=1
54+
; -D MESH_DEBUG=1
55+
lib_deps =
56+
${ThinkNode_M2.lib_deps}
57+
${esp32_ota.lib_deps}
58+
59+
; [env:ThinkNode_M2_Repeater_bridge_rs232]
60+
; extends = ThinkNode_M2
61+
; build_src_filter = ${ThinkNode_M2.build_src_filter}
62+
; +<helpers/bridges/RS232Bridge.cpp>
63+
; +<../examples/simple_repeater/*.cpp>
64+
; build_flags =
65+
; ${ThinkNode_M2.build_flags}
66+
; -D ADVERT_NAME='"RS232 Bridge"'
67+
; -D ADVERT_LAT=0.0
68+
; -D ADVERT_LON=0.0
69+
; -D ADMIN_PASSWORD='"password"'
70+
; -D MAX_NEIGHBOURS=8
71+
; -D WITH_RS232_BRIDGE=Serial2
72+
; -D WITH_RS232_BRIDGE_RX=5
73+
; -D WITH_RS232_BRIDGE_TX=6
74+
; ; -D MESH_PACKET_LOGGING=1
75+
; ; -D MESH_DEBUG=1
76+
; lib_deps =
77+
; ${ThinkNode_M2.lib_deps}
78+
; ${esp32_ota.lib_deps}
79+
80+
[env:ThinkNode_M2_Repeater_bridge_espnow]
81+
extends = ThinkNode_M2
82+
build_src_filter = ${ThinkNode_M2.build_src_filter}
83+
+<helpers/bridges/ESPNowBridge.cpp>
84+
+<../examples/simple_repeater/*.cpp>
85+
build_flags =
86+
${ThinkNode_M2.build_flags}
87+
-D ADVERT_NAME='"ESPNow Bridge"'
88+
-D ADVERT_LAT=0.0
89+
-D ADVERT_LON=0.0
90+
-D ADMIN_PASSWORD='"password"'
91+
-D MAX_NEIGHBOURS=8
92+
-D WITH_ESPNOW_BRIDGE=1
93+
-D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
94+
; -D MESH_PACKET_LOGGING=1
95+
; -D MESH_DEBUG=1
96+
lib_deps =
97+
${ThinkNode_M2.lib_deps}
98+
${esp32_ota.lib_deps}
99+
100+
[env:ThinkNode_M2_room_server]
101+
extends = ThinkNode_M2
102+
build_src_filter = ${ThinkNode_M2.build_src_filter}
103+
+<../examples/simple_room_server>
104+
build_flags =
105+
${ThinkNode_M2.build_flags}
106+
-D ADVERT_NAME='"Thinknode M2 Room Server"'
107+
-D ADVERT_LAT=0.0
108+
-D ADVERT_LON=0.0
109+
-D ADMIN_PASSWORD='"password"'
110+
-D ROOM_PASSWORD='"hello"'
111+
; -D MESH_PACKET_LOGGING=1
112+
; -D MESH_DEBUG=1
113+
lib_deps =
114+
${ThinkNode_M2.lib_deps}
115+
${esp32_ota.lib_deps}
116+
117+
[env:ThinkNode_M2_terminal_chat]
118+
extends = ThinkNode_M2
119+
build_flags =
120+
${ThinkNode_M2.build_flags}
121+
-D MAX_CONTACTS=300
122+
-D MAX_GROUP_CHANNELS=8
123+
; -D MESH_PACKET_LOGGING=1
124+
; -D MESH_DEBUG=1
125+
build_src_filter = ${ThinkNode_M2.build_src_filter}
126+
+<../examples/simple_secure_chat/main.cpp>
127+
lib_deps =
128+
${ThinkNode_M2.lib_deps}
129+
densaugeo/base64 @ ~1.4.0
130+
131+
[env:ThinkNode_M2_companion_radio_ble]
132+
extends = ThinkNode_M2
133+
build_flags =
134+
${ThinkNode_M2.build_flags}
135+
-I examples/companion_radio/ui-new
136+
-D MAX_CONTACTS=300
137+
-D MAX_GROUP_CHANNELS=8
138+
-D BLE_PIN_CODE=123456
139+
-D OFFLINE_QUEUE_SIZE=256
140+
; -D BLE_DEBUG_LOGGING=1
141+
; -D MESH_PACKET_LOGGING=1
142+
; -D MESH_DEBUG=1
143+
build_src_filter = ${ThinkNode_M2.build_src_filter}
144+
+<helpers/esp32/*.cpp>
145+
+<helpers/ui/MomentaryButton.cpp>
146+
+<../examples/companion_radio/*.cpp>
147+
+<../examples/companion_radio/ui-new/*.cpp>
148+
149+
lib_deps =
150+
${ThinkNode_M2.lib_deps}
151+
densaugeo/base64 @ ~1.4.0
152+
153+
[env:ThinkNode_M2_companion_radio_serial]
154+
extends = ThinkNode_M2
155+
build_flags =
156+
${ThinkNode_M2.build_flags}
157+
-I examples/companion_radio/ui-new
158+
-D MAX_CONTACTS=300
159+
-D MAX_GROUP_CHANNELS=8
160+
-D SERIAL_TX=D6
161+
-D SERIAL_RX=D7
162+
; -D MESH_PACKET_LOGGING=1
163+
; -D MESH_DEBUG=1
164+
build_src_filter = ${ThinkNode_M2.build_src_filter}
165+
+<helpers/esp32/*.cpp>
166+
+<helpers/ui/MomentaryButton.cpp>
167+
+<../examples/companion_radio/*.cpp>
168+
+<../examples/companion_radio/ui-new/*.cpp>
169+
lib_deps =
170+
${ThinkNode_M2.lib_deps}
171+
densaugeo/base64 @ ~1.4.0

variants/thinknode_m2/target.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <Arduino.h>
2+
#include "target.h"
3+
4+
ThinknodeM2Board board;
5+
6+
#if defined(P_LORA_SCLK)
7+
static SPIClass spi;
8+
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
9+
#else
10+
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
11+
#endif
12+
13+
WRAPPER_CLASS radio_driver(radio, board);
14+
15+
ESP32RTCClock fallback_clock;
16+
AutoDiscoverRTCClock rtc_clock(fallback_clock);
17+
SensorManager sensors;
18+
19+
#ifdef DISPLAY_CLASS
20+
DISPLAY_CLASS display;
21+
MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
22+
#endif
23+
24+
bool radio_init() {
25+
fallback_clock.begin();
26+
rtc_clock.begin(Wire);
27+
pinMode(21, INPUT);
28+
pinMode(48, OUTPUT);
29+
#if defined(P_LORA_SCLK)
30+
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
31+
return radio.std_init(&spi);
32+
#else
33+
return radio.std_init();
34+
#endif
35+
}
36+
37+
uint32_t radio_get_rng_seed() {
38+
return radio.random(0x7FFFFFFF);
39+
}
40+
41+
42+
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
43+
radio.setFrequency(freq);
44+
radio.setSpreadingFactor(sf);
45+
radio.setBandwidth(bw);
46+
radio.setCodingRate(cr);
47+
}
48+
49+
void radio_set_tx_power(uint8_t dbm) {
50+
radio.setOutputPower(dbm);
51+
}
52+
53+
mesh::LocalIdentity radio_new_identity() {
54+
RadioNoiseListener rng(radio);
55+
return mesh::LocalIdentity(&rng); // create new random identity
56+
}
57+

variants/thinknode_m2/target.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
3+
#define RADIOLIB_STATIC_ONLY 1
4+
#include <RadioLib.h>
5+
#include <helpers/radiolib/RadioLibWrappers.h>
6+
//#include <helpers/ESP32Board.h>
7+
#include <ThinknodeM2Board.h>
8+
#include <helpers/radiolib/CustomSX1262Wrapper.h>
9+
#include <helpers/AutoDiscoverRTCClock.h>
10+
#include <helpers/SensorManager.h>
11+
#ifdef DISPLAY_CLASS
12+
#include <helpers/ui/SH1106Display.h>
13+
#include <helpers/ui/MomentaryButton.h>
14+
#endif
15+
16+
extern ThinknodeM2Board board;
17+
extern WRAPPER_CLASS radio_driver;
18+
extern AutoDiscoverRTCClock rtc_clock;
19+
extern SensorManager sensors;
20+
21+
#ifdef DISPLAY_CLASS
22+
extern DISPLAY_CLASS display;
23+
extern MomentaryButton user_btn;
24+
#endif
25+
26+
bool radio_init();
27+
uint32_t radio_get_rng_seed();
28+
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
29+
void radio_set_tx_power(uint8_t dbm);
30+
mesh::LocalIdentity radio_new_identity();
31+
32+

0 commit comments

Comments
 (0)