From a27d35436485f6fcdfe270d97100511d7e4e5696 Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Mon, 1 May 2023 14:12:00 +0200 Subject: [PATCH 01/20] Add board - BPI PicoW ESP32-S3 SX1262 (#2450) * Add files via upload * Add files via upload --- bpi_picow_esp32_s3.json | 38 +++++++++++ variants/bpi_picow_esp32_s3/pins_arduino.h | 37 +++++++++++ variants/bpi_picow_esp32_s3/platformio.ini | 14 +++++ variants/bpi_picow_esp32_s3/variant.h | 73 ++++++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 bpi_picow_esp32_s3.json create mode 100644 variants/bpi_picow_esp32_s3/pins_arduino.h create mode 100644 variants/bpi_picow_esp32_s3/platformio.ini create mode 100644 variants/bpi_picow_esp32_s3/variant.h diff --git a/bpi_picow_esp32_s3.json b/bpi_picow_esp32_s3.json new file mode 100644 index 000000000..75983d845 --- /dev/null +++ b/bpi_picow_esp32_s3.json @@ -0,0 +1,38 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=0", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "hwids": [["0x303A", "0x1001"]], + "mcu": "esp32s3", + "variant": "bpi_picow_esp32_s3" + }, + "connectivity": ["wifi"], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino", "espidf"], + "name": "BPI-PicoW-S3 (8 MB FLASH, 2 MB PSRAM)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://wiki.banana-pi.org/BPI-PicoW-S3", + "vendor": "BPI" +} diff --git a/variants/bpi_picow_esp32_s3/pins_arduino.h b/variants/bpi_picow_esp32_s3/pins_arduino.h new file mode 100644 index 000000000..ee0e34ebf --- /dev/null +++ b/variants/bpi_picow_esp32_s3/pins_arduino.h @@ -0,0 +1,37 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +#define EXTERNAL_NUM_INTERRUPTS 46 +#define NUM_DIGITAL_PINS 48 +#define NUM_ANALOG_INPUTS 20 + +#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1) +#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1) +#define digitalPinHasPWM(p) (p < 46) + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +// The default Wire will be mapped to PMU and RTC +static const uint8_t SDA = 12; +static const uint8_t SCL = 14; + +// Default SPI will be mapped to Radio +static const uint8_t MISO = 39; +static const uint8_t SCK = 21; +static const uint8_t MOSI = 38; +static const uint8_t SS = 17; + +//#define SPI_MOSI (11) +//#define SPI_SCK (14) +//#define SPI_MISO (2) +//#define SPI_CS (13) + +//#define SDCARD_CS SPI_CS + +#endif /* Pins_Arduino_h */ \ No newline at end of file diff --git a/variants/bpi_picow_esp32_s3/platformio.ini b/variants/bpi_picow_esp32_s3/platformio.ini new file mode 100644 index 000000000..27c420df5 --- /dev/null +++ b/variants/bpi_picow_esp32_s3/platformio.ini @@ -0,0 +1,14 @@ +[env:bpi_picow_esp32_s3] +extends = esp32s3_base +board = bpi_picow_esp32_s3 +board_level = extra +;OpenOCD flash method +;upload_protocol = esp-builtin +;Normal method +upload_protocol = esptool +upload_port = /dev/ttyACM2 +lib_deps = + ${esp32_base.lib_deps} + caveman99/ESP32 Codec2@^1.0.1 +build_flags = + ${esp32_base.build_flags} -D PRIVATE_HW -I variants/bpi_picow_esp32_s3 \ No newline at end of file diff --git a/variants/bpi_picow_esp32_s3/variant.h b/variants/bpi_picow_esp32_s3/variant.h new file mode 100644 index 000000000..78eae1dad --- /dev/null +++ b/variants/bpi_picow_esp32_s3/variant.h @@ -0,0 +1,73 @@ +#define HAS_GPS 0 +#undef GPS_RX_PIN +#undef GPS_TX_PIN + +//#define HAS_SCREEN 0 + +//#define HAS_SDCARD +//#define SDCARD_USE_SPI1 + +#define USE_SSD1306 +#define I2C_SDA 12 +#define I2C_SCL 14 + +#define LED_PIN 46 +#define LED_STATE_ON 0 // State when LED is litted + +//#define BUTTON_PIN 15 // Pico OLED 1.3 User key 0 - removed User key 1 (17) + +#define BUTTON_PIN 40 +//#define BUTTON_PIN 0 // This is the BOOT button pad at the moment +//#define BUTTON_NEED_PULLUP + +//#define USE_RF95 // RFM95/SX127x + +#undef RF95_SCK +#undef RF95_MISO +#undef RF95_MOSI +#undef RF95_NSS + +// WaveShare Core1262-868M OK +// https://www.waveshare.com/wiki/Core1262-868M +#define USE_SX1262 + +#ifdef USE_SX1262 +#define RF95_MISO 39 +#define RF95_SCK 21 +#define RF95_MOSI 38 +#define RF95_NSS 17 +#define LORA_RESET 42 +#define LORA_DIO1 5 +#define LORA_BUSY 47 +#define SX126X_CS RF95_NSS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_BUSY +#define SX126X_RESET LORA_RESET +#define SX126X_E22 +#endif + +//#define USE_SX1280 +#ifdef USE_SX1280 +#define RF95_MISO 1 +#define RF95_SCK 3 +#define RF95_MOSI 4 +#define RF95_NSS 2 +#define LORA_RESET 17 +#define LORA_DIO1 12 +#define LORA_BUSY 47 +#define SX128X_CS RF95_NSS +#define SX128X_DIO1 LORA_DIO1 +#define SX128X_BUSY LORA_BUSY +#define SX128X_RESET LORA_RESET +#endif + +//#define USE_EINK +/* + * eink display pins + */ +//#define PIN_EINK_CS +//#define PIN_EINK_BUSY +//#define PIN_EINK_DC +//#define PIN_EINK_RES (-1) +//#define PIN_EINK_SCLK 3 +//#define PIN_EINK_MOSI 4 \ No newline at end of file From 7ef12c77a8878685fa9a6f84d63369c6d575900a Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 1 May 2023 16:10:27 -0500 Subject: [PATCH 02/20] Add initial screen for receiving waypoints (#2452) --- protobufs | 2 +- src/PowerFSM.cpp | 8 ++-- src/PowerFSM.h | 2 +- src/graphics/Screen.cpp | 41 +++++++++++++++++++ src/mesh/generated/meshtastic/deviceonly.pb.h | 16 ++++++-- src/modules/AdminModule.cpp | 4 +- src/modules/TextMessageModule.cpp | 2 +- src/modules/WaypointModule.cpp | 6 +++ 8 files changed, 68 insertions(+), 13 deletions(-) diff --git a/protobufs b/protobufs index ef2bc66bb..e84f0cc7c 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit ef2bc66bba41e8ef98ea893e46eb36a2da40cb5e +Subproject commit e84f0cc7cab2879b00085000589b9fd6527d0d68 diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 7babc2067..6804242c2 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -295,10 +295,10 @@ void PowerFSM_setup() powerFSM.add_transition(&stateON, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update"); // Show the received text message - powerFSM.add_transition(&stateLS, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); - powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); - powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); - powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); // restarts the sleep timer + powerFSM.add_transition(&stateLS, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text"); + powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text"); + powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text"); + powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text"); // restarts the sleep timer } // If we are not in statePOWER but get a serial connection, suppress sleep (and keep the screen on) while connected diff --git a/src/PowerFSM.h b/src/PowerFSM.h index 116468121..752a9f7dd 100644 --- a/src/PowerFSM.h +++ b/src/PowerFSM.h @@ -8,7 +8,7 @@ #define EVENT_WAKE_TIMER 2 // #define EVENT_RECEIVED_PACKET 3 #define EVENT_PACKET_FOR_PHONE 4 -#define EVENT_RECEIVED_TEXT_MSG 5 +#define EVENT_RECEIVED_MSG 5 // #define EVENT_BOOT 6 // now done with a timed transition #define EVENT_BLUETOOTH_PAIR 7 #define EVENT_NODEDB_UPDATED 8 // NodeDB has a big enough change that we think you should turn on the screen diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 482e76450..219214091 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -404,6 +404,43 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf); } +/// Draw the last waypoint we received +static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + static char tempBuf[237]; + + meshtastic_MeshPacket &mp = devicestate.rx_waypoint; + meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp)); + + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(FONT_SMALL); + if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { + display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); + display->setColor(BLACK); + } + + uint32_t seconds = sinceReceived(&mp); + uint32_t minutes = seconds / 60; + uint32_t hours = minutes / 60; + uint32_t days = hours / 24; + + if (config.display.heading_bold) { + display->drawStringf(1 + x, 0 + y, tempBuf, "%s ago from %s", + screen->drawTimeDelta(days, hours, minutes, seconds).c_str(), + (node && node->has_user) ? node->user.short_name : "???"); + } + display->drawStringf(0 + x, 0 + y, tempBuf, "%s ago from %s", screen->drawTimeDelta(days, hours, minutes, seconds).c_str(), + (node && node->has_user) ? node->user.short_name : "???"); + + display->setColor(WHITE); + meshtastic_Waypoint scratch; + memset(&scratch, 0, sizeof(scratch)); + if (pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) { + snprintf(tempBuf, sizeof(tempBuf), "Received waypoint: %s", scratch.name); + display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf); + } +} + /// Draw a series of fields in a column, wrapping to multiple colums if needed static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields) { @@ -1232,6 +1269,10 @@ void Screen::setFrames() if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) { normalFrames[numframes++] = drawTextMessageFrame; } + // If we have a waypoint - show it next, unless it's a phone message and we aren't using any special modules + if (devicestate.has_rx_waypoint && shouldDrawMessage(&devicestate.rx_waypoint)) { + normalFrames[numframes++] = drawWaypointFrame; + } // then all the nodes // We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index 56beee95e..d08c18ba9 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -56,6 +56,11 @@ typedef struct _meshtastic_DeviceState { bool no_save; /* Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. */ bool did_gps_reset; + /* We keep the last received waypoint stored in the device flash, + so we can show it on the screen. + Might be null */ + bool has_rx_waypoint; + meshtastic_MeshPacket rx_waypoint; } meshtastic_DeviceState; /* The on-disk saved channels */ @@ -110,10 +115,10 @@ extern "C" { /* Initializer values for message structs */ -#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0} +#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default} #define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0} #define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default} -#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0} +#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero} #define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0} #define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero} @@ -126,6 +131,7 @@ extern "C" { #define meshtastic_DeviceState_version_tag 8 #define meshtastic_DeviceState_no_save_tag 9 #define meshtastic_DeviceState_did_gps_reset_tag 11 +#define meshtastic_DeviceState_rx_waypoint_tag 12 #define meshtastic_ChannelFile_channels_tag 1 #define meshtastic_ChannelFile_version_tag 2 #define meshtastic_OEMStore_oem_icon_width_tag 1 @@ -146,7 +152,8 @@ X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \ X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \ X(a, STATIC, SINGULAR, UINT32, version, 8) \ X(a, STATIC, SINGULAR, BOOL, no_save, 9) \ -X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) +X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \ +X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12) #define meshtastic_DeviceState_CALLBACK NULL #define meshtastic_DeviceState_DEFAULT NULL #define meshtastic_DeviceState_my_node_MSGTYPE meshtastic_MyNodeInfo @@ -154,6 +161,7 @@ X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) #define meshtastic_DeviceState_node_db_MSGTYPE meshtastic_NodeInfo #define meshtastic_DeviceState_receive_queue_MSGTYPE meshtastic_MeshPacket #define meshtastic_DeviceState_rx_text_message_MSGTYPE meshtastic_MeshPacket +#define meshtastic_DeviceState_rx_waypoint_MSGTYPE meshtastic_MeshPacket #define meshtastic_ChannelFile_FIELDLIST(X, a) \ X(a, STATIC, REPEATED, MESSAGE, channels, 1) \ @@ -187,7 +195,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg; /* Maximum encoded size of messages (where known) */ #define meshtastic_ChannelFile_size 638 -#define meshtastic_DeviceState_size 22040 +#define meshtastic_DeviceState_size 22364 #define meshtastic_OEMStore_size 3041 #ifdef __cplusplus diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 106aaeafc..d5f887734 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -39,9 +39,9 @@ static void writeSecret(char *buf, size_t bufsz, const char *currentVal) } /** - * @brief Handle recieved protobuf message + * @brief Handle received protobuf message * - * @param mp Recieved MeshPacket + * @param mp Received MeshPacket * @param r Decoded AdminMessage * @return bool */ diff --git a/src/modules/TextMessageModule.cpp b/src/modules/TextMessageModule.cpp index bab5decda..0fa175a14 100644 --- a/src/modules/TextMessageModule.cpp +++ b/src/modules/TextMessageModule.cpp @@ -15,7 +15,7 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp devicestate.rx_text_message = mp; devicestate.has_rx_text_message = true; - powerFSM.trigger(EVENT_RECEIVED_TEXT_MSG); + powerFSM.trigger(EVENT_RECEIVED_MSG); notifyObservers(&mp); return ProcessMessage::CONTINUE; // Let others look at this message also if they want diff --git a/src/modules/WaypointModule.cpp b/src/modules/WaypointModule.cpp index 079be604e..f95bdec34 100644 --- a/src/modules/WaypointModule.cpp +++ b/src/modules/WaypointModule.cpp @@ -10,6 +10,12 @@ ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp) auto &p = mp.decoded; LOG_INFO("Received waypoint msg from=0x%0x, id=0x%x, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes); + // We only store/display messages destined for us. + // Keep a copy of the most recent text message. + devicestate.rx_waypoint = mp; + devicestate.has_rx_waypoint = true; + + powerFSM.trigger(EVENT_RECEIVED_MSG); notifyObservers(&mp); return ProcessMessage::CONTINUE; // Let others look at this message also if they want From b6ff80f0b7e56d9f197f2ed121982f9c50702ed6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 17:36:38 -0500 Subject: [PATCH 03/20] [create-pull-request] automated change (#2453) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 253a4d545..3c943e966 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 1 -build = 10 +build = 11 From a6385a522d9f6e6545daf3f7756de95019e4d936 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 3 May 2023 06:24:09 -0500 Subject: [PATCH 04/20] Disable TX/RX EN in favor of power EN over TX_EN (#2456) * Disable TX/RX EN in favor of power EN over TX_EN * Oops --- variants/diy/v1/variant.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/variants/diy/v1/variant.h b/variants/diy/v1/variant.h index 541edfa91..da9e41553 100644 --- a/variants/diy/v1/variant.h +++ b/variants/diy/v1/variant.h @@ -38,8 +38,9 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_RXEN 14 -#define SX126X_TXEN 13 +//#define SX126X_RXEN 14 +//#define SX126X_TXEN 13 +#define SX126X_POWER_EN (13) // RX/TX for RFM95/SX127x #define RF95_RXEN 14 From 973b30fc0be1960d412b031359bd8a839ed91ee2 Mon Sep 17 00:00:00 2001 From: IhorNehrutsa <70886343+IhorNehrutsa@users.noreply.github.com> Date: Wed, 3 May 2023 14:25:03 +0300 Subject: [PATCH 05/20] Update RemoteHardwareModule.cpp (#2454) --- src/modules/RemoteHardwareModule.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp index fb455af44..2a90c2b66 100644 --- a/src/modules/RemoteHardwareModule.cpp +++ b/src/modules/RemoteHardwareModule.cpp @@ -18,7 +18,7 @@ static void pinModes(uint64_t mask, uint8_t mode) { for (uint64_t i = 0; i < NUM_GPIOS; i++) { - if (mask & (1 << i)) { + if (mask & (1ULL << i)) { pinMode(i, mode); } } @@ -35,7 +35,7 @@ static uint64_t digitalReads(uint64_t mask) // pinModes(mask, INPUT_PULLUP); for (uint64_t i = 0; i < NUM_GPIOS; i++) { - uint64_t m = 1 << i; + uint64_t m = 1ULL << i; if (mask & m) { if (digitalRead(i)) { res |= m; @@ -64,7 +64,7 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r screen->print("Write GPIOs\n"); for (uint8_t i = 0; i < NUM_GPIOS; i++) { - uint64_t mask = 1 << i; + uint64_t mask = 1ULL << i; if (p.gpio_mask & mask) { digitalWrite(i, (p.gpio_value & mask) ? 1 : 0); } From e360c6248000cf84d666e76f8eb6baf55293ac30 Mon Sep 17 00:00:00 2001 From: IhorNehrutsa <70886343+IhorNehrutsa@users.noreply.github.com> Date: Thu, 4 May 2023 05:09:18 +0300 Subject: [PATCH 06/20] RemoteHardwareModule.cpp: Hot Fix digitalReads() pinModes(mask, INPUT_PULLUP) (#2459) --- src/modules/RemoteHardwareModule.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp index 2a90c2b66..c3232d266 100644 --- a/src/modules/RemoteHardwareModule.cpp +++ b/src/modules/RemoteHardwareModule.cpp @@ -29,10 +29,7 @@ static uint64_t digitalReads(uint64_t mask) { uint64_t res = 0; - // The Arduino docs show to run pinMode(). But, when testing, found it is best not to. - // If the line below is uncommented, read will flip the pin to the default of the second - // argument in pinModes(), which will make the read turn the PIN "on". - // pinModes(mask, INPUT_PULLUP); + pinModes(mask, INPUT_PULLUP); for (uint64_t i = 0; i < NUM_GPIOS; i++) { uint64_t m = 1ULL << i; From 313860c8a4aff50f7d89a279c8477c23f87cb7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 4 May 2023 09:55:12 +0200 Subject: [PATCH 07/20] fix #2460 - we only really need the router object after nodedb init, so lets move it there. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7af41116c..e42c190df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -234,8 +234,6 @@ void setup() fsInit(); - router = new ReliableRouter(); - #ifdef I2C_SDA1 Wire1.begin(I2C_SDA1, I2C_SCL1); #endif @@ -413,6 +411,8 @@ void setup() // If we're taking on the repeater role, use flood router if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) router = new FloodingRouter(); + else + router = new ReliableRouter(); #if HAS_BUTTON // Buttons. Moved here cause we need NodeDB to be initialized From 7c9d0a022a5a03f53d479cd1a7d770e86541a55b Mon Sep 17 00:00:00 2001 From: Manuel Verch Date: Thu, 4 May 2023 20:27:31 +0200 Subject: [PATCH 08/20] fix AI C3 DevKit-M configuration --- src/sleep.cpp | 5 +++++ variants/ai-c3/platformio.ini | 10 ++++++++-- variants/ai-c3/variant.h | 33 ++++++++++++++++++++------------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/sleep.cpp b/src/sleep.cpp index c25e3473e..e612b0032 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -309,8 +309,13 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r // assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK); #endif #ifdef BUTTON_PIN +#if SOC_PM_SUPPORT_EXT_WAKEUP esp_sleep_enable_ext0_wakeup((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN), LOW); // when user presses, this button goes low +#else + esp_sleep_enable_gpio_wakeup(); + gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); +#endif #endif #if defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC) gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL); // SX126x/SX128x interrupt, active high diff --git a/variants/ai-c3/platformio.ini b/variants/ai-c3/platformio.ini index 76ecd9f0f..fbc6b51fa 100644 --- a/variants/ai-c3/platformio.ini +++ b/variants/ai-c3/platformio.ini @@ -2,7 +2,13 @@ extends = esp32c3_base board = esp32-c3-devkitm-1 board_level = extra -build_flags = - ${esp32_base.build_flags} +build_flags = ${esp32c3_base.build_flags} -D PRIVATE_HW -I variants/ai-c3 +; as long as BSEC2 Software Library is not supported remove Sensors from build +build_src_filter = ${esp32c3_base.build_src_filter} + - + - + - +lib_ignore = ${esp32c3_base.lib_ignore} + BSEC Software Library diff --git a/variants/ai-c3/variant.h b/variants/ai-c3/variant.h index 05f0abb51..2db91ccab 100644 --- a/variants/ai-c3/variant.h +++ b/variants/ai-c3/variant.h @@ -1,26 +1,33 @@ -// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep +#define HAS_TELEMETRY 0 // as long as BSEC2 is not supported +#define HAS_SENSOR 0 // as long as BSEC2 is not supported -#define I2C_SDA 8 -#define I2C_SCL 9 +#define SDA 0 +#define SCL 1 +#define I2C_SDA SDA +#define I2C_SCL SCL -#define BUTTON_PIN 0 +#define BUTTON_PIN 9 // BOOT button +#define LED_PIN 30 // RGB LED #define USE_RF95 -#undef RF95_SCK #define RF95_SCK 4 -#undef RF95_MISO #define RF95_MISO 5 -#undef RF95_MOSI #define RF95_MOSI 6 -#undef RF95_NSS #define RF95_NSS 7 -#define LORA_DIO0 10 // a No connect on the SX1262 module -#define LORA_DIO1 3 // a No connect on the SX1262 module +#define LORA_DIO0 10 +#define LORA_DIO1 3 #define LORA_RESET 2 +// WaveShare Core1262-868M +// https://www.waveshare.com/wiki/Core1262-868M +#define USE_SX1262 +#define SX126X_CS RF95_NSS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY 10 +#define SX126X_RESET LORA_RESET +#define SX126X_E22 // use DIO2 as RF switch + +#define HAS_GPS 0 #undef GPS_RX_PIN #undef GPS_TX_PIN - -#define HAS_SCREEN 0 -#define HAS_GPS 0 From 17e25babb1d6d4028bbffa1960563de963449e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 4 May 2023 11:04:43 +0200 Subject: [PATCH 09/20] probably fixes #2451 - please test --- src/gps/NMEAWPL.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 6ab2c85bf..41ebab72c 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,5 +1,6 @@ #include "NMEAWPL.h" #include "GeoCoord.h" +#include /* ------------------------------------------- * 1 2 3 4 5 6 @@ -56,12 +57,14 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); - uint32_t len = - snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000, - pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, - geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), - (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, - pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); + tm *t = localtime((time_t *)&pos.timestamp); + + uint32_t len = snprintf( + buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, + t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, geoCoord.getDMSLatDeg(), + (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), + (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, + pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); uint32_t chk = 0; for (uint32_t i = 1; i < len; i++) { From 39aa756100f8126c9d22fc4d846fc144ddca7e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 5 May 2023 09:44:18 +0200 Subject: [PATCH 10/20] wrong datapoint --- src/gps/NMEAWPL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 41ebab72c..70d3d22cb 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -63,7 +63,7 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), - (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, + (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_quality, pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); uint32_t chk = 0; From 09d48f659ebe535c71a17f37ca6e1125496fbd1d Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 6 May 2023 07:17:40 -0500 Subject: [PATCH 11/20] RAK14001 RGB LED support (#2464) * WIP * WIP * Moved it * More random strobey behavior * Guard to RAK4630 devices for now * Oops * Ship it --- src/configuration.h | 5 +++ src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 1 + src/main.cpp | 4 ++ src/main.h | 1 + src/modules/ExternalNotificationModule.cpp | 42 ++++++++++++++++++- variants/rak4631/platformio.ini | 1 + variants/rak4631_epaper/platformio.ini | 1 + variants/rak4631_epaper_onrxtx/platformio.ini | 1 + 9 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/configuration.h b/src/configuration.h index 58e41877d..e1420c8db 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -124,6 +124,11 @@ along with this program. If not, see . #define MPU6050_ADDR 0x68 #define LIS3DH_ADR 0x18 +// ----------------------------------------------------------------------------- +// LED +// ----------------------------------------------------------------------------- +#define NCP5623_ADDR 0x38 + // ----------------------------------------------------------------------------- // Security // ----------------------------------------------------------------------------- diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 01b300c10..a56ce86fe 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -33,6 +33,7 @@ class ScanI2C PMSA0031, MPU6050, LIS3DH, + NCP5623, } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index fb568b552..b7f16734f 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port) break; SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n") + SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n"); #ifdef HAS_PMU SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n") diff --git a/src/main.cpp b/src/main.cpp index e42c190df..b1a21e942 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -100,6 +100,8 @@ uint8_t kb_model; ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE; // The I2C address of the Accelerometer (if found) ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE; +// The I2C address of the RGB LED (if found) +ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE); #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) ATECCX08A atecc; @@ -344,6 +346,8 @@ void setup() * nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field * "found". */ + // Only one supported RGB LED currently + rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623); #if !defined(ARCH_PORTDUINO) auto acc_info = i2cScanner->firstAccelerometer(); diff --git a/src/main.h b/src/main.h index 645ba2ee2..5707e3bc5 100644 --- a/src/main.h +++ b/src/main.h @@ -26,6 +26,7 @@ extern ScanI2C::DeviceAddress cardkb_found; extern uint8_t kb_model; extern ScanI2C::DeviceAddress rtc_found; extern ScanI2C::DeviceAddress accelerometer_found; +extern ScanI2C::FoundDevice rgb_found; extern bool eink_found; extern bool pmu_found; diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index 3c931f3e2..7dbf78a08 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -8,6 +8,17 @@ #include "mesh/generated/meshtastic/rtttl.pb.h" #include +#include "main.h" + +#ifdef RAK4630 +#include +NCP5623 rgb; + +uint8_t red = 0; +uint8_t green = 0; +uint8_t blue = 0; +#endif + #ifndef PIN_BUZZER #define PIN_BUZZER false #endif @@ -73,6 +84,15 @@ int32_t ExternalNotificationModule::runOnce() millis()) { getExternal(2) ? setExternalOff(2) : setExternalOn(2); } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + green = (green + 50) % 255; + red = abs(red - green) % 255; + blue = abs(blue / red) % 255; + + rgb.setColor(red, green, blue); + } +#endif } // now let the PWM buzzer play @@ -84,6 +104,7 @@ int32_t ExternalNotificationModule::runOnce() rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone); } } + return 25; } } @@ -106,6 +127,11 @@ void ExternalNotificationModule::setExternalOn(uint8_t index) digitalWrite(output, (moduleConfig.external_notification.active ? true : false)); break; } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + rgb.setColor(red, green, blue); + } +#endif } void ExternalNotificationModule::setExternalOff(uint8_t index) @@ -126,6 +152,15 @@ void ExternalNotificationModule::setExternalOff(uint8_t index) digitalWrite(output, (moduleConfig.external_notification.active ? false : true)); break; } + +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + red = 0; + green = 0; + blue = 0; + rgb.setColor(red, green, blue); + } +#endif } bool ExternalNotificationModule::getExternal(uint8_t index) @@ -200,6 +235,12 @@ ExternalNotificationModule::ExternalNotificationModule() LOG_INFO("Using Pin %i in PWM mode\n", config.device.buzzer_gpio); } } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + rgb.begin(); + rgb.setCurrent(10); + } +#endif } else { LOG_INFO("External Notification Module Disabled\n"); disable(); @@ -300,7 +341,6 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms; } } - setIntervalFromNow(0); // run once so we know if we should do something } diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index a0928605f..0d1f17d91 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -9,6 +9,7 @@ lib_deps = ${networking_base.lib_deps} melopero/Melopero RV3028@^1.1.0 https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper/platformio.ini b/variants/rak4631_epaper/platformio.ini index fd266c07f..e9c3e8723 100644 --- a/variants/rak4631_epaper/platformio.ini +++ b/variants/rak4631_epaper/platformio.ini @@ -8,6 +8,7 @@ lib_deps = ${nrf52840_base.lib_deps} zinggjm/GxEPD2@^1.4.9 melopero/Melopero RV3028@^1.1.0 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper_onrxtx/platformio.ini b/variants/rak4631_epaper_onrxtx/platformio.ini index 920380011..6e922b841 100644 --- a/variants/rak4631_epaper_onrxtx/platformio.ini +++ b/variants/rak4631_epaper_onrxtx/platformio.ini @@ -10,6 +10,7 @@ lib_deps = ${nrf52840_base.lib_deps} zinggjm/GxEPD2@^1.5.1 melopero/Melopero RV3028@^1.1.0 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink From cdc8bf44e997dd344bdc01728cfd7bbc1e8489ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 6 May 2023 18:10:00 +0200 Subject: [PATCH 12/20] use the device time, only use gps timestamp as a fallback. --- src/gps/NMEAWPL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 70d3d22cb..902ba4c95 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,6 +1,7 @@ #include "NMEAWPL.h" #include "GeoCoord.h" #include +#include "RTC.h" /* ------------------------------------------- * 1 2 3 4 5 6 @@ -58,6 +59,9 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); tm *t = localtime((time_t *)&pos.timestamp); + if (getRTCQuality() > 0) // use the device clock if we got time from somewhere. If not, use the GPS timestamp. + t = localtime((time_t *)getValidTime(RTCQuality::RTCQualityDevice)); + uint32_t len = snprintf( buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, From 694fd04367c0fc0aa4c8f67669047d8d8b361d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 4 May 2023 11:04:43 +0200 Subject: [PATCH 13/20] probably fixes #2451 - please test --- src/gps/NMEAWPL.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 6ab2c85bf..41ebab72c 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,5 +1,6 @@ #include "NMEAWPL.h" #include "GeoCoord.h" +#include /* ------------------------------------------- * 1 2 3 4 5 6 @@ -56,12 +57,14 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); - uint32_t len = - snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000, - pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, - geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), - (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, - pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); + tm *t = localtime((time_t *)&pos.timestamp); + + uint32_t len = snprintf( + buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, + t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, geoCoord.getDMSLatDeg(), + (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), + (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, + pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); uint32_t chk = 0; for (uint32_t i = 1; i < len; i++) { From e1c4968c58e60cdf20d4023972b0f0bb16e3c68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 5 May 2023 09:44:18 +0200 Subject: [PATCH 14/20] wrong datapoint --- src/gps/NMEAWPL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 41ebab72c..70d3d22cb 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -63,7 +63,7 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), - (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, + (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_quality, pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); uint32_t chk = 0; From 9b6ac98ae0d41023e1d8ccb517098d0fa601cdaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 6 May 2023 18:10:00 +0200 Subject: [PATCH 15/20] use the device time, only use gps timestamp as a fallback. --- src/gps/NMEAWPL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 70d3d22cb..902ba4c95 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,6 +1,7 @@ #include "NMEAWPL.h" #include "GeoCoord.h" #include +#include "RTC.h" /* ------------------------------------------- * 1 2 3 4 5 6 @@ -58,6 +59,9 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); tm *t = localtime((time_t *)&pos.timestamp); + if (getRTCQuality() > 0) // use the device clock if we got time from somewhere. If not, use the GPS timestamp. + t = localtime((time_t *)getValidTime(RTCQuality::RTCQualityDevice)); + uint32_t len = snprintf( buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, From 81bfd69a41542a22707066b0214aca81d98e8f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 6 May 2023 18:13:52 +0200 Subject: [PATCH 16/20] fmt --- src/gps/NMEAWPL.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 902ba4c95..cf158d993 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,7 +1,7 @@ #include "NMEAWPL.h" #include "GeoCoord.h" -#include #include "RTC.h" +#include /* ------------------------------------------- * 1 2 3 4 5 6 @@ -61,7 +61,6 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) tm *t = localtime((time_t *)&pos.timestamp); if (getRTCQuality() > 0) // use the device clock if we got time from somewhere. If not, use the GPS timestamp. t = localtime((time_t *)getValidTime(RTCQuality::RTCQualityDevice)); - uint32_t len = snprintf( buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, From b4ff37104a58792f8a5c3519d061880af3f9d791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 6 May 2023 23:16:39 +0200 Subject: [PATCH 17/20] fix NMEA Timestamp for good --- src/gps/NMEAWPL.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index cf158d993..ac11d78f8 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -59,8 +59,10 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); tm *t = localtime((time_t *)&pos.timestamp); - if (getRTCQuality() > 0) // use the device clock if we got time from somewhere. If not, use the GPS timestamp. - t = localtime((time_t *)getValidTime(RTCQuality::RTCQualityDevice)); + if (getRTCQuality() > 0) { // use the device clock if we got time from somewhere. If not, use the GPS timestamp. + uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice); + t = localtime((time_t *)&rtc_sec); + } uint32_t len = snprintf( buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, From 19a310e196ca396eca0f17ab13396788c7a59494 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 6 May 2023 19:37:01 -0500 Subject: [PATCH 18/20] [create-pull-request] automated change (#2469) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 3c943e966..0e33ac38b 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 1 -build = 11 +build = 12 From e761631d5e00adc77d0508d8292b4bb17ac6c32c Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Mon, 8 May 2023 10:08:47 +0200 Subject: [PATCH 19/20] Add files via upload --- boards/bpi_picow_esp32_s3.json | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 boards/bpi_picow_esp32_s3.json diff --git a/boards/bpi_picow_esp32_s3.json b/boards/bpi_picow_esp32_s3.json new file mode 100644 index 000000000..75983d845 --- /dev/null +++ b/boards/bpi_picow_esp32_s3.json @@ -0,0 +1,38 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=0", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "hwids": [["0x303A", "0x1001"]], + "mcu": "esp32s3", + "variant": "bpi_picow_esp32_s3" + }, + "connectivity": ["wifi"], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino", "espidf"], + "name": "BPI-PicoW-S3 (8 MB FLASH, 2 MB PSRAM)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://wiki.banana-pi.org/BPI-PicoW-S3", + "vendor": "BPI" +} From 2e915e782b00429e488e8b7d35a59ccc24b46421 Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Mon, 8 May 2023 10:09:01 +0200 Subject: [PATCH 20/20] Delete bpi_picow_esp32_s3.json --- bpi_picow_esp32_s3.json | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 bpi_picow_esp32_s3.json diff --git a/bpi_picow_esp32_s3.json b/bpi_picow_esp32_s3.json deleted file mode 100644 index 75983d845..000000000 --- a/bpi_picow_esp32_s3.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "build": { - "arduino": { - "ldscript": "esp32s3_out.ld" - }, - "core": "esp32", - "extra_flags": [ - "-DARDUINO_USB_CDC_ON_BOOT=1", - "-DARDUINO_USB_MODE=0", - "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=1", - "-DBOARD_HAS_PSRAM" - ], - "f_cpu": "240000000L", - "f_flash": "80000000L", - "flash_mode": "dio", - "hwids": [["0x303A", "0x1001"]], - "mcu": "esp32s3", - "variant": "bpi_picow_esp32_s3" - }, - "connectivity": ["wifi"], - "debug": { - "openocd_target": "esp32s3.cfg" - }, - "frameworks": ["arduino", "espidf"], - "name": "BPI-PicoW-S3 (8 MB FLASH, 2 MB PSRAM)", - "upload": { - "flash_size": "8MB", - "maximum_ram_size": 327680, - "maximum_size": 8388608, - "use_1200bps_touch": true, - "wait_for_upload_port": true, - "require_upload_port": true, - "speed": 921600 - }, - "url": "https://wiki.banana-pi.org/BPI-PicoW-S3", - "vendor": "BPI" -}