diff --git a/variants/rak3401/platformio.ini b/variants/rak3401/platformio.ini index 48e7192266..56883e752d 100644 --- a/variants/rak3401/platformio.ini +++ b/variants/rak3401/platformio.ini @@ -134,3 +134,128 @@ build_src_filter = ${rak3401.build_src_filter} extends = rak3401 build_src_filter = ${rak3401.build_src_filter} +<../examples/kiss_modem/> + +; ------------------------- RAK4631 core + RAK13302 ------------------------- +; Same RF hardware as the RAK3401 1W kit, but the RAK4631 core carries a second, +; unused SX1262 that would otherwise idle in standby forever. These envs match +; the RAK_3401_* ones and additionally cold-sleep that radio at boot. +; Do not flash them to a genuine RAK3401 -- there is no onboard radio to sleep. + +[rak4631_13302] +extends = rak3401 +board = rak4631 +build_flags = ${rak3401.build_flags} + -D RAK4631_ONBOARD_SX1262_SLEEP +build_src_filter = ${rak3401.build_src_filter} +lib_deps = ${rak3401.lib_deps} + +[env:RAK_4631_13302_repeater] +extends = rak4631_13302 +build_flags = + ${rak4631_13302.build_flags} + -D DISPLAY_CLASS=SSD1306Display + -D ADVERT_NAME='"RAK4631 1W Repeater"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 + ;-D MESH_PACKET_LOGGING=1 + ;-D MESH_DEBUG=1 +build_src_filter = ${rak4631_13302.build_src_filter} + + + +<../examples/simple_repeater> + +[env:RAK_4631_13302_room_server] +extends = rak4631_13302 +build_flags = + ${rak4631_13302.build_flags} + -D DISPLAY_CLASS=SSD1306Display + -D ADVERT_NAME='"Test Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' + ;-D MESH_PACKET_LOGGING=1 + ;-D MESH_DEBUG=1 +build_src_filter = ${rak4631_13302.build_src_filter} + + + +<../examples/simple_room_server> + +[env:RAK_4631_13302_companion_radio_usb] +extends = rak4631_13302 +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_flags = + ${rak4631_13302.build_flags} + -I examples/companion_radio/ui-new + -D PIN_USER_BTN_ANA=31 + -D DISPLAY_CLASS=SSD1306Display + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D ENABLE_USB_INTERFACE +; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1 +; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1 +build_src_filter = ${rak4631_13302.build_src_filter} + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${rak4631_13302.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:RAK_4631_13302_companion_radio_ble] +extends = rak4631_13302 +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_flags = + ${rak4631_13302.build_flags} + -I examples/companion_radio/ui-new + -D PIN_USER_BTN_ANA=31 + -D DISPLAY_CLASS=SSD1306Display + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D BLE_PIN_CODE=123456 + -D BLE_DEBUG_LOGGING=1 + -D OFFLINE_QUEUE_SIZE=256 + ;-D MESH_PACKET_LOGGING=1 + ;-D MESH_DEBUG=1 +build_src_filter = ${rak4631_13302.build_src_filter} + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${rak4631_13302.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:RAK_4631_13302_terminal_chat] +extends = rak4631_13302 +build_flags = + ${rak4631_13302.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=1 + ;-D MESH_PACKET_LOGGING=1 + ;-D MESH_DEBUG=1 +build_src_filter = ${rak4631_13302.build_src_filter} + +<../examples/simple_secure_chat/main.cpp> +lib_deps = + ${rak4631_13302.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:RAK_4631_13302_sensor] +extends = rak4631_13302 +build_flags = + ${rak4631_13302.build_flags} + -D DISPLAY_CLASS=SSD1306Display + -D ADVERT_NAME='"RAK4631 Sensor"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + ;-D MESH_PACKET_LOGGING=1 + ;-D MESH_DEBUG=1 +build_src_filter = ${rak4631_13302.build_src_filter} + + + +<../examples/simple_sensor> + +[env:RAK_4631_13302_kiss_modem] +extends = rak4631_13302 +build_src_filter = ${rak4631_13302.build_src_filter} + +<../examples/kiss_modem/> diff --git a/variants/rak3401/target.cpp b/variants/rak3401/target.cpp index 5309e6b22b..dac12ede70 100644 --- a/variants/rak3401/target.cpp +++ b/variants/rak3401/target.cpp @@ -32,8 +32,49 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); EnvironmentSensorManager sensors; #endif +#ifdef RAK4631_ONBOARD_SX1262_SLEEP +// With a RAK13302 fitted the RAK4631's own SX1262 never gets initialized, so it +// sits in STDBY_RC drawing standby current for the life of the board. Firmware +// cannot cut its supply -- P1.05 is the RF switch rail, not the radio's -- so +// bring it up on its own pins just long enough to put it into cold sleep. +static void sleep_onboard_radio() { + pinMode(ONBOARD_LORA_ANT_SW, OUTPUT); + digitalWrite(ONBOARD_LORA_ANT_SW, LOW); // nothing downstream needs the RF switch + + SPI.setPins(ONBOARD_LORA_MISO, ONBOARD_LORA_SCLK, ONBOARD_LORA_MOSI); + SPI.begin(); + + Module mod(ONBOARD_LORA_NSS, ONBOARD_LORA_DIO_1, ONBOARD_LORA_RESET, ONBOARD_LORA_BUSY, SPI); + SX1262 onboard(&mod); + + // BUSY is driven low in STDBY_RC and high while asleep, so it doubles as a + // non-invasive readback of what state we found the chip in and left it in. + pinMode(ONBOARD_LORA_BUSY, INPUT); + int busy_before = digitalRead(ONBOARD_LORA_BUSY); + + // begin() resets the chip and leaves it in standby. A TCXO calibration failure + // still leaves SPI usable, so issue the sleep regardless of what it returns. + int status = onboard.begin(434.0f, 125.0f, 9, 7, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, + 0, 8, ONBOARD_LORA_TCXO_VOLTAGE, false); + int slept = onboard.sleep(false); // cold sleep: config discarded, RTC off + delay(2); + int busy_after = digitalRead(ONBOARD_LORA_BUSY); + MESH_DEBUG_PRINTLN("onboard SX1262: begin=%d sleep=%d busy %d->%d", + status, slept, busy_before, busy_after); + + SPI.end(); // release SPIM3 so std_init() can repin it onto the RAK13302 + + // The SX1262 wakes on an NSS falling edge, so keep NSS driven high from here on. + digitalWrite(ONBOARD_LORA_NSS, HIGH); + pinMode(ONBOARD_LORA_NSS, OUTPUT); +} +#endif + bool radio_init() { rtc_clock.begin(Wire); +#ifdef RAK4631_ONBOARD_SX1262_SLEEP + sleep_onboard_radio(); +#endif return radio.std_init(&SPI); } diff --git a/variants/rak3401/variant.h b/variants/rak3401/variant.h index 9882788608..0576dadb8c 100644 --- a/variants/rak3401/variant.h +++ b/variants/rak3401/variant.h @@ -175,6 +175,21 @@ static const uint8_t AREF = PIN_AREF; #define P_LORA_BUSY SX126X_BUSY #define P_LORA_RESET SX126X_RESET +// The RAK4631 core carries its own SX1262, which is unused when a RAK13302 +// supplies the RF path. RAK4631_ONBOARD_SX1262_SLEEP builds put it into cold +// sleep at boot; on a genuine RAK3401 these pins are unconnected. +#ifdef RAK4631_ONBOARD_SX1262_SLEEP +#define ONBOARD_LORA_NSS (42) // P1.10 +#define ONBOARD_LORA_SCLK (43) // P1.11 +#define ONBOARD_LORA_MOSI (44) // P1.12 +#define ONBOARD_LORA_MISO (45) // P1.13 +#define ONBOARD_LORA_BUSY (46) // P1.14 +#define ONBOARD_LORA_DIO_1 (47) // P1.15 +#define ONBOARD_LORA_RESET (38) // P1.06 +#define ONBOARD_LORA_ANT_SW (37) // P1.05, powers the onboard RF switch +#define ONBOARD_LORA_TCXO_VOLTAGE 1.8 +#endif + // enables 3.3V periphery like GPS or IO Module // Do not toggle this for GPS power savings #define PIN_3V3_EN (34)