Compare commits

..

43 Commits

Author SHA1 Message Date
Marcel
5fee5d7eec E22 can now reach 33dBm of output power 2025-04-04 11:37:09 +02:00
Marcel
21e298820f Credits added in HOWTO 2025-03-31 10:55:51 +02:00
Marcel
90969627bc E22 module is now working. 2025-03-30 10:46:25 +02:00
Marcel
6800a4da8e E22 module is now working. 2025-03-30 10:43:36 +02:00
Marcel
3ba0d52ca7 Start implementing support for SX1268, not working yet. 2025-03-10 18:29:35 +01:00
Marcel
cd4ab151e6 Made HOWTO a tiny bit better. 2025-03-04 20:59:09 +01:00
Marcel
4ac7d32bb9 Made HOWTO a tiny bit better. 2025-03-04 20:43:22 +01:00
Marcel
5f3a760bb5 Made HOWTO a tiny bit better. 2025-03-04 20:41:34 +01:00
Marcel
8732ae9f6b Made HOWTO a tiny bit better. 2025-03-04 20:35:24 +01:00
Marcel
9cb1d51311 Made HOWTO a tiny bit better. 2025-03-04 20:32:22 +01:00
Marcel
d3d39b929d Made HOWTO a tiny bit better. 2025-03-04 20:26:23 +01:00
Marcel
ddb4cd12b2 Made HOWTO a tiny bit better. 2025-03-04 20:16:24 +01:00
Marcel
a70e20cd50 Made HOWTO a tiny bit better. 2025-03-04 16:51:10 +01:00
Marcel
0c425e8a04 Made HOWTO a tiny bit better. 2025-03-04 16:40:50 +01:00
Marcel
e0e23a1a19 Made HOWTO a tiny bit better. 2025-03-04 16:16:28 +01:00
Marcel
6e86659c62 Made HOWTO a tiny bit better. 2025-03-04 16:06:29 +01:00
Marcel
7dc3e59be2 Made HOWTO a tiny bit better. 2025-03-04 15:40:26 +01:00
Marcel
27230c0985 Made HOWTO a tiny bit better. 2025-03-04 15:39:28 +01:00
Marcel
113f546a21 Made HOWTO a tiny bit better. 2025-03-04 15:36:46 +01:00
Marcel
289b015296 Made HOWTO a tiny bit better. 2025-03-04 15:31:29 +01:00
Marcel
f12c5a04c6 Made HOWTO a tiny bit better. 2025-03-04 15:23:56 +01:00
Marcel
ac4443a8ee Made HOWTO a tiny bit better. 2025-03-04 15:14:26 +01:00
Marcel
6843b3debf Made HOWTO a tiny bit better. 2025-03-04 15:13:07 +01:00
Marcel
5604c0c71a Firmware works for SX1278 in combination with all ESP32 S3 boards if corrects GPIOs are exposed. 2025-03-03 16:12:49 +01:00
Marcel
089b168a92 Waveshare ESP32 S3 Pico with SX1278 now works. 2025-02-28 15:09:06 +01:00
Marcel
b4526aba3b Waveshare ESP32 S3 Pico with SX1278 now works. 2025-02-28 14:56:41 +01:00
Marcel
cc70ff95bc Waveshare ESP32 S3 Pico with SX1278 now works. 2025-02-28 14:55:09 +01:00
Marcel
e6277be9e6 Release section Makefile cleaned up, HOWTO updated. 2025-02-25 11:29:29 +01:00
Marcel
a8e5ed5067 HOWTO updated 2025-02-24 12:10:14 +01:00
Marcel
08fc86d214 Waveshare ESP32 board compiles and uploads, but does not work with Reticulum yet 2025-02-24 12:06:35 +01:00
Marcel
2daa9e09e5 Added new board, which is a copy of lora32_v21. Can compile and flash it. 2025-02-18 11:26:29 +01:00
Marcel
ee34635afa CHANGELOG.ms added 2025-02-17 21:16:36 +01:00
Marcel
7b21597da8 Changed README.md to explain purpose of this copy of the firmware 2025-02-17 21:10:01 +01:00
jacob.eva
0f29d1b65e Fix builds 2025-02-12 17:05:19 +00:00
jacob.eva
283d2176bd Update interfaces 2025-02-12 17:05:03 +00:00
jacob.eva
fc8dd54848 Fix display compilation 2025-02-12 17:04:46 +00:00
jacob.eva
49fb916fd3 Fix board configs for CE 2025-02-12 17:04:25 +00:00
jacob.eva
eaf5f0682f Update clarification 2025-02-12 17:03:43 +00:00
jacob.eva
06aa6721f8 Ensure interfaces are actually set up 2025-02-12 14:25:02 +00:00
jacob.eva
a39357d332 Fix potential bugs 2025-02-12 14:24:50 +00:00
jacob.eva
1d62fdd52e Cleanup 2025-02-11 18:26:26 +00:00
jacob.eva
accb5d907c Use new modem TX IRQ functions 2025-02-11 18:25:37 +00:00
jacob.eva
e9660ae595 Add new modem TX IRQ handling 2025-02-11 18:24:13 +00:00
15 changed files with 2528 additions and 373 deletions

497
Boards.h
View File

@@ -111,6 +111,7 @@
#define BOARD_HELTEC_T114 0x3C
#define MODEL_C6 0xC6 // Heltec Mesh Node T114, 470-510 MHz
#define MODEL_C7 0xC7 // Heltec Mesh Node T114, 863-928 MHz
#define MODEL_CB 0xCB // Heltec Mesh Node T114, 863-928 MHz + GPS
#define PRODUCT_TECHO 0x15 // LilyGO T-Echo devices
#define BOARD_TECHO 0x44
@@ -125,13 +126,17 @@
#define MODEL_FE 0xFE // Homebrew board, max 17dBm output power
#define MODEL_FF 0xFF // Homebrew board, max 14dBm output power
// Board added by Mees Electronics
#define BOARD_MEES_ESP32_S3 0x61 // Mees Electronics ESP32 S3 board
#define MODEL_F1 0xF1 // SX1278
#define MODEL_F2 0xF2 // SX1268
// Displays
#define OLED 0x01
#define EINK_BW 0x02
#define EINK_3C 0x03
#define MONO_OLED 0x04
#define TFT 0x05
#define ADAFRUIT_TFT 0x06
#if defined(ESP32)
#define PLATFORM PLATFORM_ESP32
@@ -161,11 +166,9 @@
#endif
#if MCU_VARIANT == MCU_ESP32
// Board models for ESP32 based builds are
// defined by the build target in the makefile.
// If you are not using make to compile this
// firmware, you can manually define model here.
// Board models for ESP32 based builds are defined by the build target in
// the makefile. If you are not using make to compile this firmware, you
// can manually define the model here.
//
// #define BOARD_MODEL BOARD_GENERIC_ESP32
#define CONFIG_UART_BUFFER_SIZE 6144
@@ -186,7 +189,7 @@
#define INTERFACE_COUNT 1
const int pin_led_rx = 14;
const int pin_led_tx = 32;
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX127X
{
@@ -229,7 +232,7 @@
const int pin_led_tx = 4;
#if BOARD_VARIANT == MODEL_E4 || BOARD_VARIANT == MODEL_E9
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX127X
{
@@ -290,7 +293,7 @@
const int pin_led_rx = 14;
const int pin_led_tx = 32;
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX127X
{
@@ -300,7 +303,7 @@
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
// SX127X
{
4, // pin_ss
-1, // pin_sclk
@@ -377,7 +380,7 @@
#endif
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX127X
{
@@ -494,7 +497,7 @@
const int pin_led_tx = 25;
#endif
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX127X
{
@@ -707,7 +710,7 @@
#endif
#endif
const uint8_t interfaces[INTERFACE_COUNT] = {SX127X};
const uint8_t interfaces[INTERFACE_COUNT] = {SX1276};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX127X
{
@@ -732,8 +735,6 @@
}
};
// todo ce-ise all boards below here
#elif BOARD_MODEL == BOARD_T3S3
#define IS_ESP32S3 true
#define HAS_DISPLAY true
@@ -754,7 +755,7 @@
#define INTERFACE_COUNT 1
const int pin_btn_usr1 = 0;
#if BOARD_VARIANT == MODEL_A1
#if BOARD_VARIANT == MODEL_A1 || BOARD_VARIANT == MODEL_A6
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
@@ -779,6 +780,31 @@
-1 // pin_tcxo_enable
}
};
#elif BOARD_VARIANT == MODEL_A5 || BOARD_VARIANT == MODEL_AA
const uint8_t interfaces[INTERFACE_COUNT] = {SX1278};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1278
{
false, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const uint8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1278
{
7, // pin_ss
5, // pin_sclk
6, // pin_mosi
3, // pin_miso
34, // pin_busy
33, // pin_dio
8, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
#elif BOARD_VARIANT == MODEL_AC // SX1280 with PA
#define CONFIG_QUEUE_0_SIZE 6144
const uint8_t interfaces[INTERFACE_COUNT] = {SX1280};
@@ -828,25 +854,24 @@
#elif BOARD_MODEL == BOARD_TDECK
#define IS_ESP32S3 true
#define MODEM SX1262
#define DIO2_AS_RF_SWITCH true
#define HAS_BUSY true
#define HAS_TCXO true
#define HAS_DISPLAY false
#define DISPLAY TFT // to be tested...
#define HAS_CONSOLE false
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_PMU true
#define HAS_NP false
#define HAS_SD false
#define HAS_EEPROM true
#define HAS_INPUT true
#define HAS_SLEEP true
#define PIN_WAKEUP GPIO_NUM_0
#define WAKEUP_LEVEL 0
const int pin_poweron = 10;
const int pin_btn_usr1 = 0;
const int pin_cs = 9;
const int pin_reset = 17;
const int pin_sclk = 40;
const int pin_mosi = 41;
const int pin_miso = 38;
const int pin_tcxo_enable = -1;
const int pin_dio = 45;
const int pin_busy = 13;
const int SD_MISO = 38;
const int SD_MOSI = 41;
const int SD_CLK = 40;
@@ -859,6 +884,33 @@
const int DISPLAY_CLK = 40;
const int DISPLAY_BL_PIN = 42;
#define INTERFACE_COUNT 1
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
{
false, // DEFAULT_SPI
true, // HAS_TCXO
true // DIO2_AS_RF_SWITCH
},
};
const uint8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
{
9, // pin_ss
40, // pin_sclk
41, // pin_mosi
38, // pin_miso
13, // pin_busy
45, // pin_dio
17, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
#if HAS_NP == false
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 43;
@@ -871,13 +923,10 @@
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
#define IS_ESP32S3 true
#define MODEM SX1262
#define DIO2_AS_RF_SWITCH true
#define HAS_BUSY true
#define HAS_TCXO true
#define OCP_TUNED 0x38
#define HAS_DISPLAY true
#define DISPLAY MONO_OLED
#define HAS_CONSOLE true
#define HAS_BLUETOOTH false
#define HAS_BLE true
@@ -895,15 +944,6 @@
const int pin_btn_usr1 = 0;
const int pin_cs = 10;
const int pin_reset = 5;
const int pin_sclk = 12;
const int pin_mosi = 11;
const int pin_miso = 13;
const int pin_tcxo_enable = -1;
const int pin_dio = 1;
const int pin_busy = 4;
const int SD_MISO = 37;
const int SD_MOSI = 35;
const int SD_CLK = 36;
@@ -911,17 +951,8 @@
const int IMU_CS = 34;
#if HAS_NP == false
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 43;
const int pin_led_tx = 43;
#else
const int pin_led_rx = 43;
const int pin_led_tx = 43;
#endif
#endif
#define INTERFACE_COUNT 1
#if BOARD_VARIANT == MODEL_A1
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
@@ -934,52 +965,36 @@
const uint8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
{
7, // pin_ss
5, // pin_sclk
6, // pin_mosi
3, // pin_miso
34, // pin_busy
33, // pin_dio
8, // pin_reset
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
4, // pin_busy
1, // pin_dio
5, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
#elif BOARD_VARIANT == MODEL_AC // SX1280 with PA
#define CONFIG_UART_BUFFER_SIZE 40000
#define CONFIG_QUEUE_0_SIZE 40000
const uint8_t interfaces[INTERFACE_COUNT] = {SX1280};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1280
{
false, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const uint8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1280
{
7, // pin_ss
5, // pin_sclk
6, // pin_mosi
3, // pin_miso
36, // pin_busy
9, // pin_dio
8, // pin_reset
10, // pin_txen
21, // pin_rxen
-1 // pin_tcxo_enable
}
};
#if HAS_NP == false
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 43;
const int pin_led_tx = 43;
#else
const int pin_led_rx = 43;
const int pin_led_tx = 43;
#endif
#endif
#elif BOARD_MODEL == BOARD_E22_ESP32
#define HAS_DISPLAY true
#define DISPLAY OLED
// currently there is only support for using one Bluetooth type,
// Bluetooth has been chosen over BLE as it is less experimental
#define HAS_BLUETOOTH true
#define HAS_BLE true
//#define HAS_BLE true
#define HAS_CONSOLE true
#define HAS_SD false
#define HAS_EEPROM true
@@ -1014,115 +1029,90 @@
}
};
#elif BOARD_MODEL == BOARD_TDECK
// Board definition added by Mees Electronics
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
#define IS_ESP32S3 true
#define MODEM SX1262
#define DIO2_AS_RF_SWITCH true
#define HAS_BUSY true
#define HAS_TCXO true
#define HAS_DISPLAY false
#define HAS_CONSOLE false
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_PMU true
#define HAS_NP false
#define HAS_SD false
#define HAS_EEPROM true
#define HAS_INPUT true
#define HAS_SLEEP true
#define PIN_WAKEUP GPIO_NUM_0
#define WAKEUP_LEVEL 0
const int pin_poweron = 10;
const int pin_btn_usr1 = 0;
const int pin_cs = 9;
const int pin_reset = 17;
const int pin_sclk = 40;
const int pin_mosi = 41;
const int pin_miso = 38;
const int pin_tcxo_enable = -1;
const int pin_dio = 45;
const int pin_busy = 13;
const int SD_MISO = 38;
const int SD_MOSI = 41;
const int SD_CLK = 40;
const int SD_CS = 39;
const int DISPLAY_DC = 11;
const int DISPLAY_CS = 12;
const int DISPLAY_MISO = 38;
const int DISPLAY_MOSI = 41;
const int DISPLAY_CLK = 40;
const int DISPLAY_BL_PIN = 42;
#if HAS_NP == false
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 43;
const int pin_led_tx = 43;
#else
const int pin_led_rx = 43;
const int pin_led_tx = 43;
#endif
#endif
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
#define IS_ESP32S3 true
#define MODEM SX1262
#define DIO2_AS_RF_SWITCH true
#define HAS_BUSY true
#define HAS_TCXO true
#define HAS_DISPLAY true
#define HAS_CONSOLE true
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_PMU true
#define HAS_NP false
#define HAS_SD false
#define HAS_EEPROM true
#define INTERFACE_COUNT 1
#define HAS_INPUT true
#define HAS_SLEEP false
#define PMU_IRQ 40
#define I2C_SCL 41
#define I2C_SDA 42
const int pin_btn_usr1 = 0;
const int pin_cs = 10;
const int pin_reset = 5;
const int pin_sclk = 12;
const int pin_mosi = 11;
const int pin_miso = 13;
const int pin_tcxo_enable = -1;
const int pin_dio = 1;
const int pin_busy = 4;
const int SD_MISO = 37;
const int SD_MOSI = 35;
const int SD_CLK = 36;
const int SD_CS = 47;
const int IMU_CS = 34;
#define HAS_NP true
const int pin_np = 21;// 21 on Waveshare ESP32 S3 Pico, 48 on ESP32-S3-DevKitC-1
#if HAS_NP == false
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 43;
const int pin_led_tx = 43;
const int pin_led_rx = 18;
const int pin_led_tx = 33;
#else
const int pin_led_rx = 43;
const int pin_led_tx = 43;
#endif
const int pin_led_rx = 21;
const int pin_led_tx = 21;
#endif
#endif
#if BOARD_VARIANT == MODEL_F1
const uint8_t interfaces[INTERFACE_COUNT] = {SX1278};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1278
{
false, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1278
{
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
-1, // pin_busy
15, // pin_dio
14, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
#elif BOARD_VARIANT == MODEL_F2
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
{
false, // DEFAULT_SPI
true, // HAS_TCXO
true // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
{
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
16, // pin_busy
15, // pin_dio
14, // pin_reset
-1, // pin_txen
17, // pin_rxen
-1 // pin_tcxo_enable
}
};
#endif
#else
#error An unsupported ESP32 board was selected. Cannot compile RNode firmware.
#endif
#elif MCU_VARIANT == MCU_NRF52
#define CONFIG_UART_BUFFER_SIZE 6144
#define CONFIG_QUEUE_0_SIZE 6144
#define CONFIG_QUEUE_MAX_LENGTH 200
#if BOARD_MODEL == BOARD_TECHO
#define _PINNUM(port, pin) ((port) * 32 + (pin))
#define HAS_INPUT true
@@ -1315,71 +1305,12 @@
const int pin_led_rx = LED_BLUE;
const int pin_led_tx = LED_GREEN;
#elif BOARD_MODEL == BOARD_TECHO
#define _PINNUM(port, pin) ((port) * 32 + (pin))
#define MODEM SX1262
#define HAS_EEPROM false
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_CONSOLE false
#define HAS_PMU true
#define HAS_NP false
#define HAS_SD false
#define HAS_TCXO true
#define HAS_BUSY true
#define HAS_INPUT true
#define HAS_SLEEP true
#define BLE_MANUFACTURER "LilyGO"
#define BLE_MODEL "T-Echo"
#define HAS_INPUT true
#define EEPROM_SIZE 296
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
#define CONFIG_UART_BUFFER_SIZE 32768
#define CONFIG_QUEUE_SIZE 6144
#define CONFIG_QUEUE_MAX_LENGTH 200
#define HAS_DISPLAY true
#define DISPLAY EINK_BW
#define HAS_BACKLIGHT true
#define DISPLAY_SCALE 1
#define LED_ON LOW
#define LED_OFF HIGH
#define PIN_LED_GREEN _PINNUM(1, 1)
#define PIN_LED_RED _PINNUM(1, 3)
#define PIN_LED_BLUE _PINNUM(0, 14)
#define PIN_VEXT_EN _PINNUM(0, 12)
const int pin_disp_cs = 30;
const int pin_disp_dc = 28;
const int pin_disp_reset = 2;
const int pin_disp_busy = 3;
const int pin_disp_en = -1;
const int pin_disp_sck = 31;
const int pin_disp_mosi = 29;
const int pin_disp_miso = -1;
const int pin_backlight = 43;
const int pin_btn_usr1 = _PINNUM(1, 10);
const int pin_btn_touch = _PINNUM(0, 11);
const int pin_reset = 25;
const int pin_cs = 24;
const int pin_sclk = 19;
const int pin_mosi = 22;
const int pin_miso = 23;
const int pin_busy = 17;
const int pin_dio = 20;
const int pin_tcxo_enable = 21;
const int pin_led_rx = PIN_LED_BLUE;
const int pin_led_tx = PIN_LED_RED;
#elif BOARD_MODEL == BOARD_HELTEC_T114
#define MODEM SX1262
#define HAS_EEPROM false
#define HAS_DISPLAY true
#define DISPLAY TFT
#define DISPLAY_SCALE_OVERRIDE true
#define DISPLAY_SCALE 2
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_CONSOLE false
@@ -1390,7 +1321,6 @@
#define HAS_BUSY true
#define HAS_INPUT true
#define HAS_SLEEP true
#define DIO2_AS_RF_SWITCH true
#define CONFIG_UART_BUFFER_SIZE 6144
#define CONFIG_QUEUE_SIZE 6144
#define CONFIG_QUEUE_MAX_LENGTH 200
@@ -1408,53 +1338,58 @@
#define NP_M 1
const int pin_np = PIN_T114_LED;
// SPI
#define PIN_T114_MOSI 22
#define PIN_T114_MISO 23
#define PIN_T114_SCK 19
#define PIN_T114_SS 24
// SX1262
#define PIN_T114_RST 25
#define PIN_T114_DIO1 20
#define PIN_T114_BUSY 17
// TFT
#define DISPLAY_SCALE_OVERRIDE true
#define DISPLAY_SCALE 2
#define PIN_T114_TFT_MOSI 9
#define PIN_T114_TFT_MISO 11 // not connected
#define PIN_T114_TFT_SCK 8
#define PIN_T114_TFT_SS 11
#define PIN_T114_TFT_DC 12
#define PIN_T114_TFT_RST 2
#define PIN_T114_TFT_EN 3
#define PIN_T114_TFT_BLGT 15
// pins for buttons on Heltec T114
const int pin_btn_usr1 = 42;
// pins for sx1262 on Heltec T114
const int pin_reset = PIN_T114_RST;
const int pin_cs = PIN_T114_SS;
const int pin_sclk = PIN_T114_SCK;
const int pin_mosi = PIN_T114_MOSI;
const int pin_miso = PIN_T114_MISO;
const int pin_busy = PIN_T114_BUSY;
const int pin_dio = PIN_T114_DIO1;
const int pin_led_rx = 35;
const int pin_led_tx = 35;
const int pin_tcxo_enable = -1;
#define PIN_T114_TFT_BLGT 15
#define PIN_T114_TFT_EN 3
// pins for ST7789 display on Heltec T114
const int DISPLAY_DC = PIN_T114_TFT_DC;
const int DISPLAY_CS = PIN_T114_TFT_SS;
const int DISPLAY_MISO = PIN_T114_TFT_MISO;
const int DISPLAY_MOSI = PIN_T114_TFT_MOSI;
const int DISPLAY_CLK = PIN_T114_TFT_SCK;
const int DISPLAY_DC = 12;
const int DISPLAY_CS = 11;
const int DISPLAY_MISO = 11; // not connected
const int DISPLAY_MOSI = 9;
const int DISPLAY_CLK = 8;
const int DISPLAY_BL_PIN = PIN_T114_TFT_BLGT;
const int DISPLAY_RST = PIN_T114_TFT_RST;
const int DISPLAY_RST = 2;
#define INTERFACE_COUNT 1
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
{
false, // DEFAULT_SPI
true, // HAS_TCXO
true // DIO2_AS_RF_SWITCH
}
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
{
24, // pin_ss
19, // pin_sclk
22, // pin_mosi
23, // pin_miso
17, // pin_busy
20, // pin_dio
25, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
#if BOARD_VARIANT == MODEL_CB
#define HAS_GPS true
#define GPS_BAUD_RATE 9600
#define PIN_GPS_RX 37
#define PIN_GPS_TX 39
#endif
#else
#error An unsupported nRF board was selected. Cannot compile RNode firmware.
#endif

1418
Boards.h_old Normal file

File diff suppressed because it is too large Load Diff

105
CHANGELOG.md Normal file
View File

@@ -0,0 +1,105 @@
# Changelog
For the changed made by Mees Electronics.
All notable changes to this project will be documented in this file.
Added : for new features.
Changed : for changes in existing functionality.
Deprecated: for soon-to-be removed features.
Removed : for now removed features.
Fixed : for any bug fixes.
Security : in case of vulnerabilities.
### 2025-04-04
#### Fixed
RXEN switches to low before transmitting, and now the E22 module can output 33 dBm. The maximum power is reached when SX1268 is set to 22 dBm.
### 2025-03-30
#### Fixed
Both SX1278 and SX1268 modules are now working.
#### Changed
Pinout changed to make room for RXEN pin of E22 module.
|pin|GPIO|
|---|----|
|NSS|10|
|MOSI|11|
|SCK|12|
|MISO|13|
|RST|14|
|DIO|15|
|BUSY|16|
|RXEN|17|
|RX LED|18|
|TX LED|33|
### 2025-03-10
#### Changed
Renamed BOARD_WAVESHARE_ESP32_S3_PICO to MEES_ESP32_S3 in source code. Also renamed firmware-waveshare-esp32-s3-pico to firmware-mees-esp32-s3, upload-waveshare-esp32-s3-pico to upload-mees-esp32-s3 and release-waveshare-esp32-s3-pico to release-mees-esp32-s3. This way it is obvious the firmware works for all generic ESP32 S3 boards.
#### Added
Two BOARD_VARIANTs: 0xF1 for SX1278 and 0xF2 for SX1268. Can be chosen during compile time.
### 2025-03-03
Final pinout of LoRa module defined. Should work on most ESP32-S3 development boards.
|pin|GPIO|
|---|----|
|NSS|10|
|MOSI|11|
|SCK|12|
|MISO|13|
|RST|14|
|DIO|15|
|BUSY|16|
|RX LED|17|
|TX LED|18|
### 2025-02-28
Started all over again. This time I succeeded! The Waveshare ESP32 S3 Pico and the Ra-02 SX1278 LoRa transceiver are working as a proper rnode. It took me some time, but now I am happy. See Documentation/HOWTO-change-firmware-and-compile-it_MeesElectronics.md for more information about adding a new board to the code.
Pinout Ra-02:
|pin|GPIO|
|---|----|
|NSS|39|
|MOSI|37|
|MISO|36|
|SCK|38|
|RST|40|
|DIO|35|
But pinout can easily be mapped to other pins.
## 2025-02-24
Added new board (Waveshare ESP32-S3 Pico) to source code.
Pinout Ra-02 LoRa transceiver:
|pin|GPIO|
|---|----|
|NSS|10|
|MOSI|11|
|MISO|13|
|SCK|12|
|RST|14|
|DIO|15|
Can compile the source (with "make firmware-waveshare-esp32-s3-pico") and upload the program to ESP32 (with "make upload-waveshare-esp32-s3-pico"). According to the oscilloscope the SPI bus works. Reticulum still gives errors: "TX power mismatch" and "Radio state mismatch". RGB LED works, so Reticulum seems to communicate with the rnode.
## [1.74] - 2025-02-17
Version from https://github.com/liberatedsystems/RNode_Firmware_CE

View File

@@ -15,13 +15,14 @@
#include <Adafruit_GFX.h>
#define DISP_W 128
#define DISP_H 64
#if DISPLAY == OLED
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define DISPLAY_BLACK SSD1306_BLACK
#define DISPLAY_WHITE SSD1306_WHITE
#define DISP_W 128
#define DISP_H 64
#elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
void (*display_callback)();
@@ -33,15 +34,21 @@ void busyCallback(const void* p) { display_callback(); }
#elif DISPLAY == ADAFRUIT_TFT
// t-deck
#include <Adafruit_ST7789.h>
#define DISPLAY_WHITE ST77XX_WHITE
#define DISPLAY_BLACK ST77XX_BLACK
#elif DISPLAY == TFT
// t114
#include "ST7789.h"
//#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
#include "src/display/ST7789.h"
#define DISPLAY_WHITE ST77XX_WHITE
#define DISPLAY_BLACK ST77XX_BLACK
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
#elif DISPLAY == MONO_OLED
// tbeam_s
#include <Adafruit_SH110X.h>
#define DISPLAY_WHITE SH110X_WHITE
#define DISPLAY_BLACK SH110X_BLACK
#endif
#if DISPLAY == EINK_BW
@@ -295,7 +302,7 @@ uint8_t display_contrast = 0x00;
}
level = value;
}
#elif BOARD_MODEL == BOARD_OPENCOM_XL || BOARD_MODEL == BOARD_H_W_PAPER
#elif BOARD_MODEL == BOARD_OPENCOM_XL || BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_H_W_PAPER
// no backlight on these displays
void set_contrast (void* display, uint8_t contrast) {};
#else
@@ -475,6 +482,10 @@ bool display_init() {
#elif BOARD_MODEL == BOARD_TDECK
disp_mode = DISP_MODE_PORTRAIT;
display.setRotation(3);
// Added by Mees Electronics
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
disp_mode = DISP_MODE_LANDSCAPE;
display.setRotation(0);
#else
disp_mode = DISP_MODE_PORTRAIT;
display.setRotation(3);
@@ -858,7 +869,7 @@ void update_stat_area() {
drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), DISPLAY_WHITE, DISPLAY_BLACK);
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
drawBitmap(p_as_x+2, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), DISPLAY_WHITE, DISPLAY_BLACK);
if (device_init_done && !disp_ext_fb) display.drawLine(p_as_x, 0, p_as_x, DISP_W/2, DISPLAY_WHITE);
if (device_init_done && !disp_ext_fb) drawLine(p_as_x, 0, p_as_x, DISP_W/2, DISPLAY_WHITE);
}
} else {
@@ -1047,7 +1058,6 @@ void update_disp_area() {
drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), DISPLAY_WHITE, DISPLAY_BLACK);
if (disp_mode == DISP_MODE_LANDSCAPE) {
if (device_init_done && !firmware_update_mode && !disp_ext_fb) {
//display.drawLine(0, 0, 0, 63, DISPLAY_WHITE);
drawLine(0, 0, 0, 63, DISPLAY_WHITE);
}
}

View File

@@ -0,0 +1,469 @@
# How to compile the RNode firmware yourself
This document describes my efforts to add a new board to the Reticulum RNode firmware. It is published in the hope that it is useful to other makers who want to make their own RNodes.
## Required knowledge
To follow this manual, some basic programming knowledge like using text editors to edit source code and using basic commands like `make` is required. Plus some basic Linux knowledge. But you don't have to be an expert.
## Dependencies
Make sure *git*, *make*, *python* and *pip* are installed. Most likely these are already available on your system. Otherwise do:
$ sudo apt install git
$ sudo apt install make
$ sudo apt install pip
$ sudo apt install python
Install Reticulum:
$ pip install rns --break-system-packages
Add new directories to path:
$ nano ~/.bashrc
Add `export PATH=~/.local/bin:~/bin:$PATH` to the end of the file. Exit with `CTRL-x` and type `y` to save the changes.
Now reload the shell so the changes to the path will take effect: `exec $SHELL`. You can also logout and login again.
Download arduino-cli:
$ cd
$ curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
## Clone git repo
$ cd
$ git clone https://github.com/liberatedsystems/RNode_Firmware_CE.git
## Prepare
Install the required BSP and libraries for the ESP32 system.
$ cd RNode_Firmware_CE/
$ make prep-esp32
Sometimes this command stalls. If this happens, stop the command by hiting `CTRL-c` and restarted it.
## Test
To test if you can compile the firmware try it:
$ make firmware-heltec32_v3
Be patient, this can take up to 15 minutes to complete. Wait for the command prompt to return. You should not see any errors.
## Define a new board
Go to the directory `~/RNode_Firmware_CE`. This is the source code of the RNode firmware. Here you will find all the files needed to compile the firmware. You can edit these files with any text editor you like.
Let's say we want to add support for our homebrew ESP32-S3 with an SX1278 LoRa transceiver. First we have to define a BOARD_MODEL. This is an 8 bit value that is used in the source code to select the right code for the hardware. Let's choose 0x61 as the BOARD_MODEL as this number is not used yet. Optional we can also define a BOARD_VARIANT. This defines the variant of the board. A board could come with different LoRa transceivers, for example. It is also a unique 8 bit number. For now, we ignore this BOARD_VARIANT and only use the BOARD_MODEL.
### Makefile
The source code is compiled using `make` and the file called *Makefile*.
Every target board has a section `firmware-<board_name>`, `upload-<board-name>` and `release-<board-name>`. In the Makefile, three new sections for our new board have to be added. The exact place is not critical. But it is good practice to put them alongside the already present sections for firmware, upload and release.
```
# Added board from Mees Electronics
firmware-mees-esp32-s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\""
```
```
# Added board from Mees Electronics
upload-mees-esp32-s3:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:esp32s3
@sleep 1
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin)
@sleep 3
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) --chip esp32-s3 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
```
```
release-mees-esp32-s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_mees-esp32-s3.boot_app0
cp build/esp32.esp32.mees-esp32-s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_mees-esp32-s3.bin
cp build/esp32.esp32.mees-esp32-s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_mees-esp32-s3.bootloader
cp build/esp32.esp32.mees-esp32-s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_mees-esp32-s3.partitions
zip --junk-paths ./Release/rnode_firmware_mees-esp32-s3.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_mees-esp32-s3.boot_app0 build/rnode_firmware_mees-esp32-s3.bin build/rnode_firmware_mees-esp32-s3.bootloader build/rnode_firmware_mees-esp32-s3.partitions
rm -r build
```
The `upload-mees-esp32-s3` section assumes the ESP32 S3 is connected to serial port /dev/ttyACM0. On your system, this could be another port. Manual change all the `/dev/ttyACM0` to the port on your system.
### Boards.h
The file `Board.h` is the most important file to edit. This is the place where the supported boards are defined. For our new board, a new section has to be added. This section defines the pinout of the SPI port and if it has certain peripherals such as a screen or BLE.
First, the new board has to be defined at the beginning of the file. Search for the line `#define MODEL_FF 0xFF // Homebrew board, max 14dBm output power` and add the new definition below that line:
// Board added by Mees Electronics
#define BOARD_MEES_ESP32_S3 0x61 // Mees electronics ESP32 S3
Next, search for the line `#if MCU_VARIANT == MCU_ESP32`. This is the part where all the ESP32 variant are defined. This section stops at the line `#elif MCU_VARIANT == MCU_NRF52`. From here the definitions for the NRF52 board begin.
Somewhere between these to lines we have to add our board definition. It is good practice to add it at the end, just before the following code:
#else
#error An unsupported ESP32 board was selected. Cannot compile RNode firmware.
#endif
The new code:
// Board definition added by Mees Electronics
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
#define IS_ESP32S3 true
#define HAS_DISPLAY false
#define HAS_BLUETOOTH false
#define HAS_BLE true
#define HAS_PMU true
#define HAS_CONSOLE true
#define HAS_EEPROM true
#define INTERFACE_COUNT 1
#define HAS_NP true
const int pin_np = 21;
#if HAS_NP == false
#if defined(EXTERNAL_LEDS)
const int pin_led_rx = 16;
const int pin_led_tx = 17;
#else
const int pin_led_rx = 21;
const int pin_led_tx = 21;
#endif
#endif
const uint8_t interfaces[INTERFACE_COUNT] = {SX1278};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1278
{
false, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1278
{
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
-1, // pin_busy
15, // pin_dio
14, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
A lot of the abilities of the board is defined here. Most of it is self explanatory. The above values should be good enough to get you started.
|Name|What does it do|
|----|-------|
|IS_ESP32S3|Is the board an ESP32 S3|
|HAS_DISPLAY| Has the board a display|
|HAS_BLUETOOTH| Has the board Bluetooth|
|HAS_BLE|Has the board Bluetooth LE|
|HAS_PMU|Unknown yet|
|HAS_CONSOLE|RNode Bootstrap Console|
|HAS_EEPROM|All ESP32 have EEPROM|
|INTERFACE_COUNT|Unknown, set to 1|
|HAS_NP|Has the board a NeoPixel|
|EXTERNAL_LEDS|Has the board external LEDs|
The SPI bus is defined in the structs `interfaces`, `interface_cfg` and `interface_pins`. The comments in the code explain it well enough, I think. When the value of `interface_cfg[0]` is set to *false*, we can define all the IO pins in the struct `interface_pins`. The numbers are the GPIO numbers of the ESP32 S3. So 10 means GPIO10. If the value is set to -1 the pin is not used. For example, the SX1278 transceiver doesn't have a busy pin, so it is set to -1.
### Utilities.h
In this file, the routines for the optional external LEDs are defined. If the new board has a NeoPixel, you don't have to change these. But keep reading, because there are some other functions you have to change even if your board has a NeoPixel!
Search for the line `#if MCU_VARIANT == MCU_ESP32`. Because there are several of these lines, make sure you have the right one: the next line should be `#if HAS_NP == true`. Here you will find a bunch of `#elif BOARD_MODEL ==` lines. Find the last one of this if block, which ends with `#endif`. Add the new section for our board just before the `#endif`:
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
void led_id_on() { }
void led_id_off() { }
Search for the code `bool eeprom_model_valid() {`. This code checks if the BOARD_MODEL, which is stored in the EEPROM corresponds with the running firmware version. If these are not the same, the firmware will not boot.
After adding our new board section, the code looks something like this:
```
#if BOARD_MODEL == BOARD_RNODE
if (model == MODEL_A4 || model == MODEL_A9 || model == MODEL_FF || model == MODEL_FE) {
#elif BOARD_MODEL == BOARD_RNODE_NG_20
if (model == MODEL_A3 || model == MODEL_A8) {
#elif BOARD_MODEL == BOARD_RNODE_NG_21
if (model == MODEL_A2 || model == MODEL_A7) {
#elif BOARD_MODEL == BOARD_T3S3
if (model == MODEL_A1 || model == MODEL_A6 || model == MODEL_A5 || model == MODEL_AA || model == MODEL_AC) {
#elif BOARD_MODEL == BOARD_HMBRW
if (model == MODEL_FF || model == MODEL_FE) {
#elif BOARD_MODEL == BOARD_TBEAM
if (model == MODEL_E4 || model == MODEL_E9 || model == MODEL_E3 || model == MODEL_E8) {
#elif BOARD_MODEL == BOARD_TDECK
if (model == MODEL_D4 || model == MODEL_D9) {
#elif BOARD_MODEL == BOARD_TECHO
if (model == MODEL_16 || model == MODEL_17) {
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
if (model == MODEL_DB || model == MODEL_DC) {
#elif BOARD_MODEL == BOARD_LORA32_V1_0
if (model == MODEL_BA || model == MODEL_BB) {
#elif BOARD_MODEL == BOARD_LORA32_V2_0
if (model == MODEL_B3 || model == MODEL_B8) {
#elif BOARD_MODEL == BOARD_LORA32_V2_1
if (model == MODEL_B4 || model == MODEL_B9) {
#elif BOARD_MODEL == BOARD_HELTEC32_V2
if (model == MODEL_C4 || model == MODEL_C9) {
#elif BOARD_MODEL == BOARD_HELTEC32_V3
if (model == MODEL_C5 || model == MODEL_CA) {
#elif BOARD_MODEL == BOARD_H_W_PAPER
if (model == MODEL_C8) {
#elif BOARD_MODEL == BOARD_HELTEC_T114
if (model == MODEL_C6 || model == MODEL_C7) {
#elif BOARD_MODEL == BOARD_RAK4631
if (model == MODEL_11 || model == MODEL_12 || model == MODEL_13 || model == MODEL_14) {
#elif BOARD_MODEL == BOARD_OPENCOM_XL
if (model == MODEL_21) {
#elif BOARD_MODEL == BOARD_HUZZAH32
if (model == MODEL_FF) {
#elif BOARD_MODEL == BOARD_HMBRW
if (model == MODEL_FF || model == MODEL_FE) {
#elif BOARD_MODEL == BOARD_GENERIC_ESP32
if (model == MODEL_FF || model == MODEL_FE) {
// Added by Mees Electronics
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
if (model == MODEL_A4) {
#else
```
Last, find the line `void setTXPower(RadioInterface* radio, int txp) {`. This is the code that handles the RF power settings of the LoRa transceiver. Here you have to add the proper code for the LoRa module you use. After adding the code for the SX1278 module we use in this example the code should look something like this:
```
if (model == MODEL_A1) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_A2) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_A3) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
if (model == MODEL_A4) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
if (model == MODEL_A5) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
if (model == MODEL_A6) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_A7) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_A8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_A9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_AA) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_AC) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_B3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_B4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_B8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_B9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_BA) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_BB) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_C4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_C9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_C5) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_C6) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
if (model == MODEL_C7) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
if (model == MODEL_CA) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_D4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_D9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_DB) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_DC) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_E4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_E9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_E3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_E8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_FE) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_FF) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
// Added by Mees Electronics
if (model == MODEL_A4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
```
The `MODEL_A4` is an 8 bit value read from the EEPROM. This is the value we will write to the EEPROM later in this document with the command `rnodeconf /dev/ttyACM0 -r --platform ESP32 --model a4 --product f0 --hwrev 3`. The model number a4 is chosen from a list published in the file [https://git.meezenest.nl/marcel/RNode_Firmware_CE/src/branch/master/Documentation/BUILDING.md](https://git.meezenest.nl/marcel/RNode_Firmware_CE/src/branch/master/Documentation/BUILDING.md). It is shared with another board and it is probably better to choose a unique value. But `rnodeconf` uses this value and choosing a new number breaks Reticulum. Further research is needed. But for now let's use a4, because it works.
### Display.h
The file **display.h** also has a board specific definition section. If the new board has a display, make sure there is a proper entry for it. Our example board doesn't have a display, so we don't have to change this file. If your board has a display, make sure you make the proper changes.
### Power.h
The file **Power.h** must also have a board definition. And also proper definitions in **void measure_battery()** and **bool init_pmu()**. These are more elaborate and not yet fully understood, but only used when the board has a battery installed. Our example board doesn't have a battery, so we don't have to change this file. If your board has a display, make sure you make the proper changes.
### Compiling the code and flashing the board
Make sure you are in the dialout group. If not:
$ sudo usermod -aG dialout <username>
If you are flashing a custom board, you will need to generate a signing key in rnodeconf prior to flashing if you do not already have one by running:
$ rnodeconf -k
Compile the code:
$ make firmware-mees-esp32-s3
Than flash the firmware:
$ make upload-mees-esp32-s3
This first time you flash a new board, this command will end with the error `This device has not been provisioned yet, cannot set firmware hash`. That is because the EEPROM is not programmes yet You will need to provision the EEPROM before use:
$ rnodeconf /dev/ttyACM0 -r --platform ESP32 --model a4 --product f0 --hwrev 3
### Migrating to another system
When the rnode is flashed, it is signed with a key. If you connect the RNode to another system, this key cannot be validated. It is possible to write a new key to the RNode by erasing the eeprom and writing the local key to it.
$ rnodeconf /dev/ttyACM0 --eeprom-wipe
$ rnodeconf /dev/ttyACM0 -r --platform ESP32 --model a4 --product f0 --hwrev 3
## Adding support for SX1268 module
### Boards.h
Change the following section:
````
const uint8_t interfaces[INTERFACE_COUNT] = {SX1278};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1278
{
false, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1278
{
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
-1, // pin_busy
15, // pin_dio
14, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
````
with this:
````
#if BOARD_VARIANT == MODEL_F1
const uint8_t interfaces[INTERFACE_COUNT] = {SX1278};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1278
{
false, // DEFAULT_SPI
false, // HAS_TCXO
false // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1278
{
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
-1, // pin_busy
15, // pin_dio
14, // pin_reset
-1, // pin_txen
-1, // pin_rxen
-1 // pin_tcxo_enable
}
};
#elif BOARD_VARIANT == MODEL_F2
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
const bool interface_cfg[INTERFACE_COUNT][3] = {
// SX1262
{
false, // DEFAULT_SPI
true, // HAS_TCXO
true // DIO2_AS_RF_SWITCH
},
};
const int8_t interface_pins[INTERFACE_COUNT][10] = {
// SX1262
{
10, // pin_ss
12, // pin_sclk
11, // pin_mosi
13, // pin_miso
16, // pin_busy
15, // pin_dio
14, // pin_reset
-1, // pin_txen
17, // pin_rxen
-1 // pin_tcxo_enable
}
};
#endif
````
### Radio.cpp
Add the following statement to the function **sx126x::enableTCXO()**:
// Board added by Mees Electronics
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF};
Add the following statement to the function **int sx126x::endPacket()** just after `setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);`:
// Added by Mees Electronics: RXEN on E22 module back to low
#if BOARD_MODEL == BOARD_MEES_ESP32_S3 && BOARD_VARIANT == MODEL_F2
if (_rxen != -1) {
digitalWrite(_rxen, LOW);
}
#endif
The E22 module has an RXEN and a TXEN input. Both must be used and both cannot be logic 1 at the same time. RXEN must be controlled by the firmware while TXEN can be controlled by either the firmware or the DIO2 pin, by using the DIO2_AS_RF_SWITCH function in the firmware. My current solution is to control TXEN by the DIO2 pin. If you forget to control the TXEN line, the maximum output will be 22 dBm instead of 33 dBm. It would be better to alter the code to make it more universal (like with the *sx128x* code), but for now it works.
### Makefile
Change the following section:
````
# Added board from Mees Electronics
firmware-mees-esp32-s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\""
````
with this:
````
# Added board from Mees Electronics
firmware-mees-esp32-s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\" \"-DBOARD_VARIANT=0xF2\""
````
If you want to compile the board for the SX1278 just change **BOARD_VARIANT** to *0xF1*.
# License
(C) 2025 M.T. Konstapel https://meezenest.nl/mees
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Many thanks to Tom ON3DHC for proofreading this document.

View File

@@ -106,6 +106,11 @@
#define ERROR_MEMORY_LOW 0x05
#define ERROR_MODEM_TIMEOUT 0x06
#define CMD_GPS 0xA0
#define GPS_CMD_LAT 0x00
#define GPS_CMD_LNG 0x01
// Serial logging
#define LOG_MSG 0x2F

View File

@@ -1,4 +1,6 @@
#define SX1276 0x00
#define SX1278 0x01
#define SX1262 0x10
#define SX1261 0x10
#define SX1262 0x11
#define SX1268 0x12
#define SX1280 0x20

101
Makefile
View File

@@ -54,6 +54,7 @@ prep-nrf:
arduino-cli lib install "Crypto"
arduino-cli lib install "Adafruit GFX Library"
arduino-cli lib install "GxEPD2"
arduino-cli lib install "TinyGPSPlus"
arduino-cli config set library.enable_unsafe_install true
arduino-cli lib install --git-url https://github.com/liamcottle/esp8266-oled-ssd1306#e16cee124fe26490cb14880c679321ad8ac89c95
pip install pyserial rns --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error.
@@ -151,6 +152,14 @@ firmware-opencom-xl:
firmware-heltec_t114:
arduino-cli compile --log --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\""
firmware-heltec_t114_gps:
arduino-cli compile --log --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\" \"-DBOARD_VARIANT=0xCB\""
# Added board from Mees Electronics
firmware-mees-esp32-s3:
#arduino-cli compile --fqbn esp32:esp32:ttgo-lora32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\""
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\" \"-DBOARD_VARIANT=0xF2\""
upload-tbeam:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:t-beam
@sleep 1
@@ -264,6 +273,20 @@ upload-techo:
@sleep 6
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes from_device /dev/ttyACM0)
# Added board from Mees Electronics
upload-mees-esp32-s3:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:esp32s3
@sleep 1
python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) --chip esp32-s3 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
@sleep 3
rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin)
#arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:ttgo-lora32
#@sleep 1
#rnodeconf $(or $(port), /dev/ttyACM0) --firmware-hash $$(./partition_hashes ./build/esp32.esp32.ttgo-lora32/RNode_Firmware_CE.ino.bin)
#@sleep 3
#python3 ./Release/esptool/esptool.py --port $(or $(port), /dev/ttyACM0) $(COMMON_ESP_UPLOAD_FLAGS) ./Release/console_image.bin
release: console-site spiffs-image $(shell grep ^release- Makefile | cut -d: -f1)
release-hashes:
@@ -279,7 +302,7 @@ release-tbeam: check_bt_buffers
rm -r build
release-tbeam_sx1262: check_bt_buffers
arduino-cli compile --fqbn esp32:esp32:t-beam $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DBOARD_MODEL=E8\""
arduino-cli compile --fqbn esp32:esp32:t-beam $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x33\" \"-DBOARD_VARIANT=0xE8\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tbeam_sx1262.boot_app0
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bin build/rnode_firmware_tbeam_sx1262.bin
cp build/esp32.esp32.t-beam/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_tbeam_sx1262.bootloader
@@ -409,25 +432,7 @@ release-techo:
rm -r build
release-t3s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_MODEL=0xAB\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3.boot_app0 build/rnode_firmware_t3s3.bin build/rnode_firmware_t3s3.bootloader build/rnode_firmware_t3s3.partitions
rm -r build
release-e22_esp32:
arduino-cli compile --fqbn esp32:esp32:esp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x44\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_esp32_e22.boot_app0
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bin build/rnode_firmware_esp32_e22.bin
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_esp32_e22.bootloader
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_esp32_e22.partitions
zip --junk-paths ./Release/rnode_firmware_esp32_e22.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_esp32_e22.boot_app0 build/rnode_firmware_esp32_e22.bin build/rnode_firmware_esp32_e22.bootloader build/rnode_firmware_esp32_e22.partitions
rm -r build
release-t3s3_sx126x:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_MODEL=0xA1\""
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xA1\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx126x.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx126x.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx126x.bootloader
@@ -435,6 +440,33 @@ release-t3s3_sx126x:
zip --junk-paths ./Release/rnode_firmware_t3s3_sx126x.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx126x.boot_app0 build/rnode_firmware_t3s3_sx126x.bin build/rnode_firmware_t3s3_sx126x.bootloader build/rnode_firmware_t3s3_sx126x.partitions
rm -r build
release-t3s3_sx127x:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xA5\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx127x.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx127x.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx127x.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3_sx127x.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3_sx127x.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx127x.boot_app0 build/rnode_firmware_t3s3_sx127x.bin build/rnode_firmware_t3s3_sx127x.bootloader build/rnode_firmware_t3s3_sx127x.partitions
rm -r build
release-t3s3_sx1280_pa:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xAC\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx1280_pa.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx1280_pa.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx1280_pa.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3_sx1280_pa.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3_sx1280_pa.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx1280_pa.boot_app0 build/rnode_firmware_t3s3_sx1280_pa.bin build/rnode_firmware_t3s3_sx1280_pa.bootloader build/rnode_firmware_t3s3_sx1280_pa.partitions
rm -r build
release-e22_esp32:
arduino-cli compile --fqbn esp32:esp32:esp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x45\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_esp32_e22.boot_app0
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bin build/rnode_firmware_esp32_e22.bin
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_esp32_e22.bootloader
cp build/esp32.esp32.esp32/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_esp32_e22.partitions
zip --junk-paths ./Release/rnode_firmware_esp32_e22.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_esp32_e22.boot_app0 build/rnode_firmware_esp32_e22.bin build/rnode_firmware_esp32_e22.bootloader build/rnode_firmware_esp32_e22.partitions
rm -r build
release-tdeck:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3B\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_tdeck.boot_app0
@@ -444,24 +476,6 @@ release-tdeck:
zip --junk-paths ./Release/rnode_firmware_tdeck.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_tdeck.boot_app0 build/rnode_firmware_tdeck.bin build/rnode_firmware_tdeck.bootloader build/rnode_firmware_tdeck.partitions
rm -r build
release-t3s3_sx1280_pa:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DMODEM=0x04\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx1280_pa.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx1280_pa.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx1280_pa.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3_sx1280_pa.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3_sx1280_pa.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx1280_pa.boot_app0 build/rnode_firmware_t3s3_sx1280_pa.bin build/rnode_firmware_t3s3_sx1280_pa.bootloader build/rnode_firmware_t3s3_sx1280_pa.partitions
rm -r build
release-t3s3_sx127x:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DMODEM=0x01\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_t3s3_sx127x.boot_app0
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_t3s3_sx127x.bin
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_t3s3_sx127x.bootloader
cp build/esp32.esp32.esp32s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_t3s3_sx127x.partitions
zip --junk-paths ./Release/rnode_firmware_t3s3_sx127x.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx127x.boot_app0 build/rnode_firmware_t3s3_sx127x.bin build/rnode_firmware_t3s3_sx127x.bootloader build/rnode_firmware_t3s3_sx127x.partitions
rm -r build
release-tbeam_supreme:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3D\""
@@ -512,3 +526,14 @@ release-heltec_t114:
arduino-cli compile --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\""
cp build/Heltec_nRF52.Heltec_nRF52.HT-n5262/RNode_Firmware_CE.ino.hex build/rnode_firmware_heltec_t114.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/rnode_firmware_heltec_t114.hex Release/rnode_firmware_heltec_t114.zip
rm -r build
# Added by Mees Electronics
release-mees-esp32-s3:
arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x61\" \"-DBOARD_VARIANT=0x31\""
cp ~/.arduino15/packages/esp32/hardware/esp32/$(ARDUINO_ESP_CORE_VER)/tools/partitions/boot_app0.bin build/rnode_firmware_mees-esp32-s3.boot_app0
cp build/esp32.esp32.mees-esp32-s3/RNode_Firmware_CE.ino.bin build/rnode_firmware_mees-esp32-s3.bin
cp build/esp32.esp32.mees-esp32-s3/RNode_Firmware_CE.ino.bootloader.bin build/rnode_firmware_mees-esp32-s3.bootloader
cp build/esp32.esp32.mees-esp32-s3/RNode_Firmware_CE.ino.partitions.bin build/rnode_firmware_mees-esp32-s3.partitions
zip --junk-paths ./Release/rnode_firmware_mees-esp32-s3.zip ./Release/esptool/esptool.py ./Release/console_image.bin build/rnode_firmware_t3s3_sx126xrnode_firmware_mees-esp32-s3.boot_app0 build/rnode_firmware_mees-esp32-s3.bin build/rnode_firmware_mees-esp32-s3.bootloader build/rnode_firmware_mees-esp32-s3.partitions
rm -r build

16
Power.h
View File

@@ -164,6 +164,22 @@
bool bat_voltage_dropping = false;
float bat_delay_v = 0;
float bat_state_change_v = 0;
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.3
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 5
const uint8_t pin_vbat = 35;
float bat_p_samples[BAT_SAMPLES];
float bat_v_samples[BAT_SAMPLES];
uint8_t bat_samples_count = 0;
int bat_discharging_samples = 0;
int bat_charging_samples = 0;
int bat_charged_samples = 0;
bool bat_voltage_dropping = false;
float bat_delay_v = 0;
float bat_state_change_v = 0;
#endif
uint32_t last_pmu_update = 0;

View File

@@ -1,6 +1,31 @@
# RNode Firmware - Community Edition
# RNode Firmware - Mees Electronics Edition
This is the community maintained fork of the open firmware which powers RNode devices. It has been created to continue to expand development and support for more hardware devices, as the upstream repository is no longer accepting PRs for new hardware support. The original repository by Mark Qvist can be found [here](https://github.com/markqvist/RNode_Firmware).
This version of the RNode firmware is made to add support for the E22-400M33S LoRa module. With an output power of 33 dBm this module is suitable for ham radio applications.
This is a copy of the community maintained fork of the open firmware which powers RNode devices found on [https://github.com/liberatedsystems/RNode_Firmware_CE](https://github.com/liberatedsystems/RNode_Firmware_CE). The copy has been created to add support for hardware designed by [Mees Electronics](https://meezenest.nl/mees). The original repository by Mark Qvist can be found [here](https://github.com/markqvist/RNode_Firmware).
Support is added for **ESP32 S3** boards with either an **SX1278** or an **SX1268** LoRa module. It is tested with a **Waveshare ESP32 S3 Pico** and a **LilyGO T7-S3 ESP32-S3 Development Board**. But it is expected to work with all ESP32 S3 boards which expose the proper GPIO pins. LoRa modules that are tested are the **Ra-02 SX1278** transceiver and the **E22-400M33S SX1268** transceiver. See [./Documentation/HOWTO-change-firmware-and-compile-it_MeesElectronics.md](https://git.meezenest.nl/marcel/RNode_Firmware_CE/src/branch/master/Documentation/HOWTO-change-firmware-and-compile-it_MeesElectronics.md) for more information about adding a new board to the code.
More information about this project can be found on: [https://www.meezenest.nl/mees-elektronica/projects/reticulum_design_my_own_rnode/index.html](https://www.meezenest.nl/mees-elektronica/projects/reticulum_design_my_own_rnode/index.html)
Pinout between ESP and LoRa module:
|LoRa|ESP32 GPIO|
|---|----|
|NSS|10|
|MOSI|11|
|SCK|12|
|MISO|13|
|RST|14|
|DIO|15|
|BUSY|16|
|RXEN|17|
|RX LED|18|
|TX LED|33|
Note: **BUSY** and **RXEN** are only necessary when using the SX1268 module.
# What it is
An RNode is an open, free and unrestricted digital radio transceiver. It enables anyone to send and receive any kind of data over both short and very long distances. RNodes can be used with many different kinds of programs and systems, but they are especially well suited for use with [Reticulum](https://reticulum.network).

View File

@@ -18,8 +18,8 @@
#include "Utilities.h"
#if MCU_VARIANT == MCU_NRF52
#define INTERFACE_SPI
#if BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
#define INTERFACE_SPI
// Required because on RAK4631, non-default SPI pins must be initialised when class is declared.
SPIClass interface_spi[1] = {
// SX1262
@@ -31,6 +31,7 @@
)
};
#elif BOARD_MODEL == BOARD_TECHO
#define INTERFACE_SPI
SPIClass interface_spi[1] = {
// SX1262
SPIClass(
@@ -40,6 +41,17 @@
interface_pins[0][2]
)
};
#elif BOARD_MODEL == BOARD_HELTEC_T114
#define INTERFACE_SPI
SPIClass interface_spi[1] = {
// SX1262
SPIClass(
NRF_SPIM1,
interface_pins[0][3],
interface_pins[0][1],
interface_pins[0][2]
)
};
#endif
#endif
@@ -66,6 +78,9 @@ volatile uint16_t queued_bytes[INTERFACE_COUNT] = {0};
volatile uint16_t queue_cursor[INTERFACE_COUNT] = {0};
volatile uint16_t current_packet_start[INTERFACE_COUNT] = {0};
volatile bool serial_buffering = false;
extern void setup_interfaces(); // from /src/misc/ModemISR.h
#if HAS_BLUETOOTH || HAS_BLE == true
bool bt_init_ran = false;
#endif
@@ -117,8 +132,14 @@ void setup() {
pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_LED_BLUE, OUTPUT);
delay(200);
#elif BOARD_MODEL == BOARD_HELTEC_T114
delay(200);
pinMode(PIN_VEXT_EN, OUTPUT);
digitalWrite(PIN_VEXT_EN, HIGH);
delay(100);
#endif
if (!eeprom_begin()) { Serial.write("EEPROM initialisation failed.\r\n"); }
#endif
@@ -179,6 +200,8 @@ void setup() {
memset(seq, 0xFF, sizeof(seq));
memset(read_len, 0, sizeof(read_len));
setup_interfaces();
modem_packet_queue = xQueueCreate(MODEM_QUEUE_SIZE, sizeof(modem_packet_t*));
for (int i = 0; i < INTERFACE_COUNT; i++) {
@@ -191,6 +214,11 @@ void setup() {
fifo_init(&packet_rdy_interfaces, packet_rdy_interfaces_buf, MAX_INTERFACES);
#if HAS_GPS
// init GPS
gps_s.begin(GPS_BAUD_RATE);
#endif
// add call to init_channel_stats here? \todo
// Create and configure interface objects
@@ -381,6 +409,7 @@ void setup() {
// Validate board health, EEPROM and config
validate_status();
}
void lora_receive(RadioInterface* radio) {
@@ -656,10 +685,10 @@ void flush_queue(RadioInterface* radio) {
}
queue_flushing = false;
queue_height[index] = 0;
queued_bytes[index] = 0;
selected_radio->updateAirtime();
queue_flushing = false;
radio->updateAirtime();
#if HAS_DISPLAY
display_tx[radio->getIndex()] = true;
@@ -672,11 +701,7 @@ void pop_queue(RadioInterface* radio) {
queue_flushing = true;
led_tx_on(); uint16_t processed = 0;
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
if (!fifo16_isempty(&packet_starts[index])) {
#else
if (!fifo16_isempty_locked(&packet_starts[index])) {
#endif
uint16_t start = fifo16_pop(&packet_starts[index]);
uint16_t length = fifo16_pop(&packet_lengths[index]);
@@ -688,6 +713,7 @@ void pop_queue(RadioInterface* radio) {
transmit(radio, length); processed++;
}
queue_height[index] -= processed;
queued_bytes[index] -= length;
}
@@ -702,6 +728,7 @@ void pop_queue(RadioInterface* radio) {
#if HAS_DISPLAY
display_tx[radio->getIndex()] = true;
#endif
}
void transmit(RadioInterface* radio, uint16_t size) {
@@ -725,8 +752,15 @@ void transmit(RadioInterface* radio, uint16_t size) {
// Only start a new packet if this is a split packet and it has
// exceeded the length of a single packet
if (written == 255 && header & 0x0F) {
radio->endPacket(); radio->addAirtime();
if (written == 255 && isSplitPacket(header)) {
if (!radio->endPacket()) {
kiss_indicate_error(ERROR_MODEM_TIMEOUT);
kiss_indicate_error(ERROR_TXFAILED);
led_indicate_error(5);
hard_reset();
}
radio->addAirtime();
radio->beginPacket();
radio->write(header);
written = 1;
@@ -873,6 +907,7 @@ void serial_callback(uint8_t sbyte) {
if (frame_len < CMD_L) cmdbuf[frame_len++] = sbyte;
}
if (frame_len == 4) {
selected_radio = interface_obj[interface];
uint32_t bw = (uint32_t)cmdbuf[0] << 24 | (uint32_t)cmdbuf[1] << 16 | (uint32_t)cmdbuf[2] << 8 | (uint32_t)cmdbuf[3];
@@ -1522,7 +1557,7 @@ void loop() {
process_serial();
#if HAS_DISPLAY
#if DISPLAY == OLED
#if DISPLAY == OLED || DISPLAY == TFT || DISPLAY == ADAFRUIT_TFT
if (disp_ready) update_display();
#elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
// Display refreshes take so long on e-paper displays that they can disrupt
@@ -1554,6 +1589,20 @@ void loop() {
input_read();
#endif
#if HAS_GPS
while (gps_s.available() > 0) {
if (gps.encode(gps_s.read()) && millis() - last_gps >= GPS_INTERVAL) {
kiss_indicate_location();
last_gps = millis();
}
}
if (millis() > 5000 && gps.charsProcessed() < 10) {
while (true) {
Serial.println(F("No GPS detected: check wiring."));
}
}
#endif
if (memory_low) {
#if PLATFORM == PLATFORM_ESP32
if (esp_get_free_heap_size() < 8192) {

View File

@@ -5,6 +5,7 @@
// Obviously still under the MIT license.
#include "Radio.hpp"
#include "src/misc/ModemISR.h"
#if PLATFORM == PLATFORM_ESP32
#if defined(ESP32) and !defined(CONFIG_IDF_TARGET_ESP32S3)
@@ -91,31 +92,6 @@
extern FIFOBuffer packet_rdy_interfaces;
extern RadioInterface* interface_obj[];
// ISRs cannot provide parameters to the functions they call. Since we have
// multiple interfaces, we have to read each dio0 pin for each one and see
// which one is high. We can then use the index of this pin in the 2D array to
// signal the correct interface to the main loop
void ISR_VECT onDio0Rise() {
BaseType_t int_status = taskENTER_CRITICAL_FROM_ISR();
for (int i = 0; i < INTERFACE_COUNT; i++) {
if (digitalRead(interface_pins[i][5]) == HIGH) {
if (interface_obj[i]->getPacketValidity()) {
interface_obj[i]->handleDio0Rise();
}
if (interfaces[i] == SX1280) {
// On the SX1280, there is a bug which can cause the busy line
// to remain high if a high amount of packets are received when
// in continuous RX mode. This is documented as Errata 16.1 in
// the SX1280 datasheet v3.2 (page 149)
// Therefore, the modem is set into receive mode each time a packet is received.
interface_obj[i]->receive();
}
break;
}
}
taskEXIT_CRITICAL_FROM_ISR(int_status);
}
sx126x::sx126x(uint8_t index, SPIClass* spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen) :
RadioInterface(index),
_spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), _ss(ss),
@@ -463,6 +439,13 @@ int sx126x::endPacket()
{
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
// Added by Mees Electronics: RXEN on E22 module back to low
#if BOARD_MODEL == BOARD_MEES_ESP32_S3 && BOARD_VARIANT == MODEL_F2
if (_rxen != -1) {
digitalWrite(_rxen, LOW);
}
#endif
// put in single TX mode
uint8_t timeout[3] = {0};
executeOpcode(OP_TX_6X, timeout, 3);
@@ -669,9 +652,9 @@ void sx126x::onReceive(void(*callback)(uint8_t, int))
_spiModem->usingInterrupt(digitalPinToInterrupt(_dio0));
#endif
// make function available
extern void onDio0Rise();
extern void (*onIntRise[INTERFACE_COUNT])(void);
attachInterrupt(digitalPinToInterrupt(_dio0), onDio0Rise, RISING);
attachInterrupt(digitalPinToInterrupt(_dio0), onIntRise[_index], RISING);
} else {
detachInterrupt(digitalPinToInterrupt(_dio0));
#ifdef SPI_HAS_NOTUSINGINTERRUPT
@@ -735,6 +718,9 @@ void sx126x::enableTCXO() {
uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF};
#elif BOARD_MODEL == BOARD_HELTEC_T114
uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF};
// Board added by Mees Electronics
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF};
#else
uint8_t buf[4] = {0};
#endif
@@ -766,6 +752,11 @@ void sx126x::setTxPower(int level, int outputPin) {
_txp = level;
// Added by Mees Electronics: E22 transceiver can go to +33dBm, but only needs 9dBm drive. Set any higher and it might blow the finals!
//#if BOARD_MODEL == BOARD_MEES_ESP32_S3 && BOARD_VARIANT == MODEL_F2
//if (level > 9) { level = 9; }
//#endif
writeRegister(REG_OCP_6X, OCP_TUNED); // 160mA limit, overcurrent protection
uint8_t tx_buf[2];
@@ -1321,10 +1312,9 @@ void sx127x::onReceive(void(*callback)(uint8_t, int)) {
#endif
// make function available
extern void onDio0Rise();
attachInterrupt(digitalPinToInterrupt(_dio0), onDio0Rise, RISING);
extern void (*onIntRise[INTERFACE_COUNT])(void);
attachInterrupt(digitalPinToInterrupt(_dio0), onIntRise[_index], RISING);
} else {
detachInterrupt(digitalPinToInterrupt(_dio0));
@@ -2106,9 +2096,9 @@ void sx128x::onReceive(void(*callback)(uint8_t, int))
#endif
// make function available
extern void onDio0Rise();
extern void (*onIntRise[INTERFACE_COUNT])(void);
attachInterrupt(digitalPinToInterrupt(_dio0), onDio0Rise, RISING);
attachInterrupt(digitalPinToInterrupt(_dio0), onIntRise[_index], RISING);
} else {
detachInterrupt(digitalPinToInterrupt(_dio0));
#ifdef SPI_HAS_NOTUSINGINTERRUPT

View File

@@ -61,6 +61,10 @@ uint8_t eeprom_read(uint32_t mapped_addr);
#include "Input.h"
#endif
#if HAS_GPS
#include "src/misc/gps.h"
#endif
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
#include "Device.h"
#endif
@@ -289,6 +293,13 @@ uint8_t boot_vector = 0x00;
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
void led_id_on() { }
void led_id_off() { }
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
void led_id_on() { }
void led_id_off() { }
#endif
#elif MCU_VARIANT == MCU_NRF52
#if HAS_NP == true
@@ -1246,6 +1257,16 @@ void setTXPower(RadioInterface* radio, int txp) {
if (model == MODEL_FE) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
if (model == MODEL_FF) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
// Added by Mees Electronics
if (model == MODEL_A4) {
if (interfaces[radio->getIndex()] == SX1278) {
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
} else {
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
}
}
}
uint8_t getRandom(RadioInterface* radio) {
@@ -1528,6 +1549,9 @@ bool eeprom_model_valid() {
if (model == MODEL_FF || model == MODEL_FE) {
#elif BOARD_MODEL == BOARD_GENERIC_ESP32
if (model == MODEL_FF || model == MODEL_FE) {
// Added by Mees Electronics
#elif BOARD_MODEL == BOARD_MEES_ESP32_S3
if (model == MODEL_A4) {
#else
if (false) {
#endif
@@ -1712,6 +1736,35 @@ void unlock_rom() {
eeprom_erase();
}
void kiss_indicate_location() {
#if HAS_GPS
char location[10];
int len;
int32_t val;
if (gps.location.isValid()) {
serial_write(FEND);
serial_write(CMD_GPS);
serial_write(GPS_CMD_LAT);
val = gps.location.lat() * 1000000;
escaped_serial_write(val>>24);
escaped_serial_write(val>>16);
escaped_serial_write(val>>8);
escaped_serial_write(val);
serial_write(FEND);
serial_write(FEND);
serial_write(CMD_GPS);
serial_write(GPS_CMD_LNG);
val = gps.location.lng() * 1000000;
escaped_serial_write(val>>24);
escaped_serial_write(val>>16);
escaped_serial_write(val>>8);
escaped_serial_write(val);
serial_write(FEND);
}
#endif
}
void log_debug(const char* msg) {
serial_write(FEND);
serial_write(LOG_MSG);

45
src/misc/ModemISR.h Normal file
View File

@@ -0,0 +1,45 @@
extern RadioInterface* interface_obj[INTERFACE_COUNT];
void (*onIntRise[INTERFACE_COUNT]) (void);
#if INTERFACE_COUNT == 1
void onInt0Rise() {
if (interfaces[0] == SX1280) {
// On the SX1280, there is a bug which can cause the busy line
// to remain high if a high amount of packets are received when
// in continuous RX mode. This is documented as Errata 16.1 in
// the SX1280 datasheet v3.2 (page 149)
// Therefore, the modem is set into receive mode each time a packet is received.
interface_obj[0]->receive();
}
if (interface_obj[0]->getPacketValidity()) {
interface_obj[0]->handleDio0Rise();
}
}
void setup_interfaces() {
onIntRise[0] = onInt0Rise;
}
#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL
void onInt0Rise() {
if (interface_obj[0]->getPacketValidity()) {
interface_obj[0]->handleDio0Rise();
}
}
void onInt1Rise() {
// On the SX1280, there is a bug which can cause the busy line
// to remain high if a high amount of packets are received when
// in continuous RX mode. This is documented as Errata 16.1 in
// the SX1280 datasheet v3.2 (page 149)
// Therefore, the modem is set into receive mode each time a packet is received.
interface_obj[1]->receive();
if (interface_obj[1]->getPacketValidity()) {
interface_obj[1]->handleDio0Rise();
}
}
void setup_interfaces() {
onIntRise[0] = onInt0Rise;
onIntRise[1] = onInt1Rise;
}
#endif

8
src/misc/gps.h Normal file
View File

@@ -0,0 +1,8 @@
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#define GPS_INTERVAL 5000 // ms
unsigned long last_gps = 0;
TinyGPSPlus gps;
SoftwareSerial gps_s(PIN_GPS_RX, PIN_GPS_TX);