From e2712b478d0f4e6056fe83ac7d161d01d0784365 Mon Sep 17 00:00:00 2001 From: Junhuang Date: Thu, 15 Aug 2024 11:49:54 +0800 Subject: [PATCH 1/8] support M5 corebasic2.7+Module-LoRa433_V1.1+GNSS Module --- platformio.ini | 2 +- src/ButtonThread.cpp | 16 ++++- src/graphics/Screen.cpp | 81 +++++++++++++++++++++-- src/graphics/TFTDisplay.cpp | 18 +++-- src/main.cpp | 13 +++- src/main.h | 12 +++- src/mesh/RadioInterface.cpp | 17 ++++- src/mesh/generated/meshtastic/mesh.pb.h | 2 + src/platform/esp32/architecture.h | 2 + variants/m5stack_corebasic/pins_arduino.h | 13 ++++ variants/m5stack_corebasic/platformio.ini | 25 +++++++ variants/m5stack_corebasic/variant.h | 50 ++++++++++++++ 12 files changed, 230 insertions(+), 21 deletions(-) create mode 100644 variants/m5stack_corebasic/pins_arduino.h create mode 100644 variants/m5stack_corebasic/platformio.ini create mode 100644 variants/m5stack_corebasic/variant.h diff --git a/platformio.ini b/platformio.ini index e60f0d7b93..172fb24183 100644 --- a/platformio.ini +++ b/platformio.ini @@ -39,7 +39,7 @@ default_envs = tbeam ;default_envs = heltec_vision_master_e213 ;default_envs = heltec_vision_master_e290 ;default_envs = heltec_mesh_node_t114 - +;default_envs = m5stack-corebasic extra_configs = arch/*/*.ini variants/*/platformio.ini diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index 1b101044fd..e4b248ce4e 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -13,7 +13,9 @@ #ifdef ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif - +#if defined(M5STACK_COREBASIC) +#include +#endif #define DEBUG_BUTTONS 0 #if DEBUG_BUTTONS #define LOG_BUTTON(...) LOG_DEBUG(__VA_ARGS__) @@ -124,6 +126,9 @@ int32_t ButtonThread::runOnce() switch (btnEvent) { case BUTTON_EVENT_PRESSED: { LOG_BUTTON("press!\n"); +#if defined(M5STACK_COREBASIC) + M5.Speaker.tone(1000, 100); +#endif #ifdef BUTTON_PIN if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) != moduleConfig.canned_message.inputbroker_pin_press) || @@ -144,6 +149,9 @@ int32_t ButtonThread::runOnce() case BUTTON_EVENT_DOUBLE_PRESSED: { LOG_BUTTON("Double press!\n"); +#if defined(M5STACK_COREBASIC) + M5.Speaker.tone(2000, 100); +#endif service->refreshLocalMeshNode(); auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true); if (screen) { @@ -185,6 +193,9 @@ int32_t ButtonThread::runOnce() case BUTTON_EVENT_LONG_PRESSED: { LOG_BUTTON("Long press!\n"); +#if defined(M5STACK_COREBASIC) + M5.Speaker.tone(3000, 300); +#endif powerFSM.trigger(EVENT_PRESS); if (screen) { screen->startAlert("Shutting down..."); @@ -197,6 +208,9 @@ int32_t ButtonThread::runOnce() // may wake the board immediatedly. case BUTTON_EVENT_LONG_RELEASED: { LOG_INFO("Shutdown from long press\n"); +#if defined(M5STACK_COREBASIC) + M5.Speaker.tone(4000, 300); +#endif playShutdownMelody(); delay(3000); power->shutdown(); diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 3a4db6ee00..8955527463 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -62,7 +62,10 @@ along with this program. If not, see . #if ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif - +#if defined(M5STACK_COREBASIC) +#include "M5Unified.h" +extern DataInfo DataRegion; +#endif using namespace meshtastic; /** @todo remove */ namespace graphics @@ -949,7 +952,26 @@ bool deltaToTimestamp(uint32_t secondsAgo, uint8_t *hours, uint8_t *minutes, int validCached = true; return validCached; } - +#if defined(M5STACK_COREBASIC) +static void drawLoraMessage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y){ + display->clear(); + display->drawString(x + 0, y + 0, myRegion->name); + display->setFont(FONT_MEDIUM); + display->drawString(x + 10, y + 30,"channel: "+String(DataRegion.lora_channel_num+1)); + display->drawString(x + 10, y + 60,"bw: "+ String(DataRegion.lora_bw)); + display->drawString(x + SCREEN_WIDTH/2+10, y+30,"freq: "+String(DataRegion.lora_freq)); + display->drawString(x + SCREEN_WIDTH/2+10, y+60,"power: "+ String(DataRegion.lora_power_output)); + display->drawString(x + 10, y + 90,"sf: "+String(DataRegion.lora_sf)); + display->drawString(x + SCREEN_WIDTH/2+10, y+90,"cr: 4/:"+ String(DataRegion.lora_cr)); + display->setTextAlignment(TEXT_ALIGN_LEFT); + const char *title = "LoRa"; + display->drawString(x + SCREEN_WIDTH/2-20, y +0, title); + display->setFont(FONT_SMALL); + display->setTextAlignment(TEXT_ALIGN_RIGHT); + display->drawString(x + SCREEN_WIDTH, y,String(DataRegion.lora_channel_name)); + display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code +} +#endif /// Draw the last text message we received static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { @@ -968,7 +990,11 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state 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); +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::BLACK); +#else + display->setColor(BLACK); +#endif } // For time delta @@ -1002,7 +1028,11 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state } } +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::WHITE); +#else display->setColor(WHITE); +#endif #ifndef EXCLUDE_EMOJI if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, @@ -1075,10 +1105,15 @@ void Screen::drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char int xo = x, yo = y; while (*f) { display->drawString(xo, yo, *f); +#if defined(M5STACK_COREBASIC) + if ((display->getColor() == OLEDDISPLAY_COLOR::BLACK) && config.display.heading_bold) + display->drawString(xo + 1, yo, *f); + display->setColor(OLEDDISPLAY_COLOR::WHITE); +#else if ((display->getColor() == BLACK) && config.display.heading_bold) display->drawString(xo + 1, yo, *f); - display->setColor(WHITE); +#endif yo += FONT_HEIGHT_SMALL; if (yo > SCREEN_HEIGHT - FONT_HEIGHT_SMALL) { xo += SCREEN_WIDTH / 2; @@ -1487,7 +1522,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ display->drawCircle(compassX, compassY, compassDiam / 2); if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::BLACK); +#else display->setColor(BLACK); +#endif } // Must be after distStr is populated screen->drawColumns(display, x, y, fields); @@ -2103,7 +2142,13 @@ void Screen::setFrames(FrameFocus focus) fsi.positions.textMessage = numframes; if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) { normalFrames[numframes++] = drawTextMessageFrame; +#if defined(M5STACK_COREBASIC) + M5.Speaker.tone(3000, 400); +#endif } +#if defined(M5STACK_COREBASIC) + normalFrames[numframes++] = drawLoraMessage; +#endif // then all the nodes // We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens @@ -2365,7 +2410,11 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::BLACK); +#else display->setColor(BLACK); +#endif } char channelStr[20]; @@ -2406,7 +2455,11 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 } } #endif - display->setColor(WHITE); +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::WHITE); +#else + display->setColor(WHITE); +#endif // Draw the channel name display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr); // Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo @@ -2477,7 +2530,11 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::BLACK); +#else display->setColor(BLACK); +#endif } if (WiFi.status() != WL_CONNECTED) { @@ -2497,7 +2554,11 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i } } - display->setColor(WHITE); +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::WHITE); +#else + display->setColor(WHITE); +#endif /* - WL_CONNECTED: assigned when connected to a WiFi network; @@ -2557,7 +2618,11 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::BLACK); +#else display->setColor(BLACK); +#endif } char batStr[20]; @@ -2596,7 +2661,11 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat // minutes %= 60; // hours %= 24; +#if defined(M5STACK_COREBASIC) + display->setColor(OLEDDISPLAY_COLOR::WHITE); +#else display->setColor(WHITE); +#endif // Show uptime as days, hours, minutes OR seconds std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds); diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 8ea90c5232..dc43e900a1 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -311,7 +311,11 @@ class LGFX : public lgfx::LGFX_Device cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read cfg.readable = true; // Set to true if data can be read +#if defined(M5STACK_COREBASIC) + cfg.invert = true; // Set to true if the light/darkness of the panel is reversed +#else cfg.invert = false; // Set to true if the light/darkness of the panel is reversed +#endif cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped cfg.dlen_16bit = false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI @@ -586,7 +590,7 @@ void TFTDisplay::sendCommand(uint8_t com) #elif defined(ST7735_BL_V05) pinMode(ST7735_BL_V05, OUTPUT); digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON); -#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) +#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(M5STACK_COREBASIC) tft->wakeup(); tft->powerSaveOff(); #elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON) @@ -604,7 +608,7 @@ void TFTDisplay::sendCommand(uint8_t com) unphone.backlight(true); // using unPhone library #endif #ifdef RAK14014 -#elif !defined(M5STACK) && !defined(ST7789_CS) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function +#elif !defined(M5STACK) && !defined(ST7789_CS) && !defined(M5STACK_COREBASIC)// T-Deck gets brightness set in Screen.cpp in the handleSetOn function tft->setBrightness(172); #endif break; @@ -619,7 +623,7 @@ void TFTDisplay::sendCommand(uint8_t com) #elif defined(ST7735_BL_V05) pinMode(ST7735_BL_V05, OUTPUT); digitalWrite(ST7735_BL_V05, !TFT_BACKLIGHT_ON); -#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) +#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(M5STACK_COREBASIC) tft->sleep(); tft->powerSaveOn(); #elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON) @@ -636,7 +640,7 @@ void TFTDisplay::sendCommand(uint8_t com) unphone.backlight(false); // using unPhone library #endif #ifdef RAK14014 -#elif !defined(M5STACK) +#elif !defined(M5STACK) || !defined(M5STACK_COREBASIC) tft->setBrightness(0); #endif break; @@ -670,7 +674,7 @@ bool TFTDisplay::hasTouch(void) { #ifdef RAK14014 return true; -#elif !defined(M5STACK) +#elif !defined(M5STACK) || !defined(M5STACK_COREBASIC) return tft->touch() != nullptr; #else return false; @@ -689,7 +693,7 @@ bool TFTDisplay::getTouch(int16_t *x, int16_t *y) } else { return false; } -#elif !defined(M5STACK) +#elif !defined(M5STACK) || !defined(M5STACK_COREBASIC) return tft->getTouch(x, y); #else return false; @@ -733,7 +737,7 @@ bool TFTDisplay::connect() tft->init(); -#if defined(M5STACK) +#if defined(M5STACK) || defined(M5STACK_COREBASIC) tft->setRotation(0); #elif defined(RAK14014) tft->setRotation(1); diff --git a/src/main.cpp b/src/main.cpp index 7f45905d15..1142fd9660 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -111,7 +111,9 @@ AccelerometerThread *accelerometerThread = nullptr; #include "AudioThread.h" AudioThread *audioThread = nullptr; #endif - +#if defined(M5STACK_COREBASIC) +#include +#endif using namespace concurrency; // We always create a screen object, but we only init it if we find the hardware @@ -757,7 +759,14 @@ void setup() if (!pmu_found) RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware #endif - +#if defined(M5STACK_COREBASIC) + M5.begin(); + M5.Speaker.tone(2000, 600); + M5.Display.init(); + M5.Display.clearDisplay(); + M5.Display.display(); + M5.Display.fillScreen(TFT_BLACK); +#endif #if !MESHTASTIC_EXCLUDE_I2C // Don't call screen setup until after nodedb is setup (because we need // the current region name) diff --git a/src/main.h b/src/main.h index 52a3fff1f8..99983acf8f 100644 --- a/src/main.h +++ b/src/main.h @@ -42,7 +42,17 @@ extern bool isUSBPowered; #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) extern ATECCX08A atecc; #endif - +#if defined(M5STACK_COREBASIC) +struct DataInfo { + int lora_channel_num; + double lora_freq; + const char* lora_channel_name; + int lora_power_output; + float lora_bw; + int lora_sf; + int lora_cr; +}; +#endif #ifdef T_WATCH_S3 #include extern Adafruit_DRV2605 drv; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 262d2d6a99..689901dd2d 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -11,7 +11,9 @@ #include #include #include - +#if defined(M5STACK_COREBASIC) +DataInfo DataRegion; +#endif #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \ { \ meshtastic_Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ @@ -199,7 +201,10 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl) float tPacket = tPreamble + tPayload; uint32_t msecs = tPacket * 1000; - +#if defined(M5STACK_COREBASIC) + DataRegion.lora_sf=sf; + DataRegion.lora_cr=cr; +#endif LOG_DEBUG("(bw=%d, sf=%d, cr=4/%d) packet symLen=%d ms, payloadSize=%u, time %d ms\n", (int)bw, sf, cr, (int)(tSym * 1000), pl, msecs); return msecs; @@ -514,7 +519,13 @@ void RadioInterface::applyModemConfig() preambleTimeMsec = getPacketTime((uint32_t)0); maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader)); - +#if defined(M5STACK_COREBASIC) + DataRegion.lora_channel_num=channel_num; + DataRegion.lora_freq=getFreq(); + DataRegion.lora_channel_name=channelName; + DataRegion.lora_power_output=power; + DataRegion.lora_bw=bw; +#endif LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, loraConfig.frequency_offset); LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power); diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 955484cb09..a0b9d4edea 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -187,6 +187,8 @@ typedef enum _meshtastic_HardwareModel { /* RadioMaster 900 Bandit, https://www.radiomasterrc.com/products/bandit-expresslrs-rf-module SSD1306 OLED and No GPS */ meshtastic_HardwareModel_RADIOMASTER_900_BANDIT = 74, + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ + meshtastic_HardwareModel_M5STACK_COREBASIC=75, /* ------------------------------------------------------------------------------------------------------------------------------------------ Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. ------------------------------------------------------------------------------------------------------------------------------------------ */ diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index fd3f92a9c3..187cf4e46d 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -159,6 +159,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_VISION_MASTER_E290 #elif defined(HELTEC_MESH_NODE_T114) #define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114 +#elif defined(M5STACK_COREBASIC) +#define HW_VENDOR meshtastic_HardwareModel_M5STACK_COREBASIC #endif // ----------------------------------------------------------------------------- diff --git a/variants/m5stack_corebasic/pins_arduino.h b/variants/m5stack_corebasic/pins_arduino.h new file mode 100644 index 0000000000..7e25669b74 --- /dev/null +++ b/variants/m5stack_corebasic/pins_arduino.h @@ -0,0 +1,13 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +static const uint8_t SDA = 21; +static const uint8_t SCL = 22; + +static const uint8_t SS = 5; +static const uint8_t MOSI = 23; +static const uint8_t MISO = 19; +static const uint8_t SCK = 18; +#endif /* Pins_Arduino_h */ \ No newline at end of file diff --git a/variants/m5stack_corebasic/platformio.ini b/variants/m5stack_corebasic/platformio.ini new file mode 100644 index 0000000000..aa92ea6dbf --- /dev/null +++ b/variants/m5stack_corebasic/platformio.ini @@ -0,0 +1,25 @@ +[env:m5stack-corebasic] +extends = esp32_base +board = m5stack-core-esp32 +monitor_filters = esp32_exception_decoder +build_src_filter = + ${esp32_base.build_src_filter} +build_flags = + ${esp32_base.build_flags} -I variants/m5stack_corebasic + + -DILI9341_DRIVER + -DM5STACK_COREBASIC + -DTFT_DRIVER=0x9341 + -DTFT_MISO=19 + -DTFT_MOSI=23 + -DTFT_SCLK=18 + -DTFT_CS=14 + -DTFT_DC=27 + -DTFT_RST=33 + -DTFT_BL=32 + -DSPI_FREQUENCY=40000000 + -DSPI_READ_FREQUENCY=16000000 +lib_deps = + ${esp32_base.lib_deps} + lovyan03/LovyanGFX@^1.1.8 + m5stack/M5Unified@^0.1.14 \ No newline at end of file diff --git a/variants/m5stack_corebasic/variant.h b/variants/m5stack_corebasic/variant.h new file mode 100644 index 0000000000..92dc58a65f --- /dev/null +++ b/variants/m5stack_corebasic/variant.h @@ -0,0 +1,50 @@ +// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep + +#define I2C_SDA 21 +#define I2C_SCL 22 + +#define BUTTON_NEED_PULLUP +// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin. +// Select Use the middle button, you can also use 39, 37 +#define BUTTON_PIN 38 + +#define PIN_BUZZER 25 +// The Module used here is module-LORa433_V1.1. You can also use module-LORa868_V1.1 +// https://docs.m5stack.com/en/module/Module-LoRa433_V1.1 +// https://docs.m5stack.com/en/module/Module-LoRa868_V1.1 +#undef LORA_SCK +#undef LORA_MISO +#undef LORA_MOSI +#undef LORA_CS + +#define LORA_SCK 18 +#define LORA_MISO 19 +#define LORA_MOSI 23 +#define LORA_CS 5 //NSS + +#define USE_RF95 +#define LORA_DIO0 35 // IRQ +#define LORA_RESET 13 // RST +#define LORA_DIO1 RADIOLIB_NC // Not really used +#define LORA_DIO2 RADIOLIB_NC // Not really used + +// The gnss module is used here https://docs.m5stack.com/en/module/GNSS%20Module +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#define GPS_RX_PIN 16 +#define GPS_TX_PIN 17 + + +//Note: If you use corebasic version 2.7 or later, +//you need to go to the src>graphics>TFTDisplay.cpp file to change the value of cfg.invert, +//this one is to set the color inversion +#define TFT_HEIGHT 240 +#define TFT_WIDTH 320 +#define TFT_OFFSET_X 0 +#define TFT_OFFSET_Y 0 +#define TFT_BUSY -1 + +// LCD screens are slow, so slowdown the wipe so it looks better +#define SCREEN_TRANSITION_FRAMERATE 1 // fps + +#define ILI9341_SPI_HOST VSPI_HOST // VSPI_HOST or HSPI_HOST From b21551ac54b91b312bc95ff2bbae270982cdcf1c Mon Sep 17 00:00:00 2001 From: Junhuang Date: Thu, 15 Aug 2024 14:54:14 +0800 Subject: [PATCH 2/8] Increase sleep wake screen backlight --- src/graphics/Screen.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 8955527463..d292f4b191 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1639,6 +1639,10 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) pinMode(VTFT_LEDA, OUTPUT); digitalWrite(VTFT_LEDA, TFT_BACKLIGHT_ON); #endif +#endif +#if defined(M5STACK_COREBASIC) + pinMode(TFT_BL, OUTPUT); + digitalWrite(TFT_BL, HIGH); #endif enabled = true; setInterval(0); // Draw ASAP @@ -1651,6 +1655,10 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) #endif LOG_INFO("Turning off screen\n"); dispdev->displayOff(); +#if defined(M5STACK_COREBASIC) + pinMode(TFT_BL, OUTPUT); + digitalWrite(TFT_BL, LOW); +#endif #ifdef USE_ST7789 SPI1.end(); #if defined(ARCH_ESP32) From c1a05465754ab2155fc7f6ef7da97fe9acbae7a4 Mon Sep 17 00:00:00 2001 From: Junhuang Date: Thu, 22 Aug 2024 17:28:05 +0800 Subject: [PATCH 3/8] Modification conflict --- src/main.cpp | 4 ++++ src/mesh/generated/meshtastic/mesh.pb.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 1142fd9660..31ca80f7b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -111,6 +111,10 @@ AccelerometerThread *accelerometerThread = nullptr; #include "AudioThread.h" AudioThread *audioThread = nullptr; #endif + + + + #if defined(M5STACK_COREBASIC) #include #endif diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index a0b9d4edea..324bbff61e 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -187,8 +187,10 @@ typedef enum _meshtastic_HardwareModel { /* RadioMaster 900 Bandit, https://www.radiomasterrc.com/products/bandit-expresslrs-rf-module SSD1306 OLED and No GPS */ meshtastic_HardwareModel_RADIOMASTER_900_BANDIT = 74, + + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ - meshtastic_HardwareModel_M5STACK_COREBASIC=75, + meshtastic_HardwareModel_M5STACK_COREBASIC=76, /* ------------------------------------------------------------------------------------------------------------------------------------------ Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. ------------------------------------------------------------------------------------------------------------------------------------------ */ From c651c60b980b945be1d3a1e1ca2770f44f89a3b5 Mon Sep 17 00:00:00 2001 From: Junhuang Date: Mon, 26 Aug 2024 18:24:34 +0800 Subject: [PATCH 4/8] Support M5 core2 +Module-LoRa433_V1.1+GNSS Module --- platformio.ini | 1 + src/ButtonThread.cpp | 86 ++++++++++++++++++++++++- src/ButtonThread.h | 3 + src/graphics/Screen.cpp | 34 ++++++---- src/graphics/TFTDisplay.cpp | 13 ++-- src/main.cpp | 10 +-- src/main.h | 2 +- src/mesh/RadioInterface.cpp | 6 +- src/mesh/generated/meshtastic/mesh.pb.h | 2 + src/platform/esp32/architecture.h | 2 + variants/m5stack_core2/pins_arduino.h | 47 ++++++++++++++ variants/m5stack_core2/platformio.ini | 26 ++++++++ variants/m5stack_core2/variant.h | 44 +++++++++++++ 13 files changed, 246 insertions(+), 30 deletions(-) create mode 100644 variants/m5stack_core2/pins_arduino.h create mode 100644 variants/m5stack_core2/platformio.ini create mode 100644 variants/m5stack_core2/variant.h diff --git a/platformio.ini b/platformio.ini index ef8f9d8c07..35358215df 100644 --- a/platformio.ini +++ b/platformio.ini @@ -41,6 +41,7 @@ default_envs = tbeam ;default_envs = heltec_vision_master_e290 ;default_envs = heltec_mesh_node_t114 ;default_envs = m5stack-corebasic +;default_envs = m5stack-core2 extra_configs = arch/*/*.ini variants/*/platformio.ini diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index b0271a76d2..4e17e7549c 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -13,7 +13,7 @@ #ifdef ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) #include #endif #define DEBUG_BUTTONS 0 @@ -341,4 +341,86 @@ void ButtonThread::userButtonPressedLongStop() if (millis() > c_holdOffTime) { btnEvent = BUTTON_EVENT_LONG_RELEASED; } -} \ No newline at end of file +} +#if defined(M5STACK_CORE2) +// Define a constant +const unsigned long LONG_PRESS_THRESHOLD = 5000; // Hold the threshold +const unsigned long DOUBLE_CLICK_THRESHOLD = 1000; // Double-click the threshold +const int MAX_CLICKS = 2; // Maximum hits +// Global variable +unsigned long lastClickTime = 0; // The time of the last click +int clickCount = 0; // Click count +unsigned long touch_start_time; // Touch start time +bool is_touching = false; // Mark whether you are currently touching +void ScreenTouch(){ + M5.update(); + auto count = M5.Touch.getCount(); + if (count == 0) return; + for (std::size_t i = 0; i < count; ++i) { + auto t = M5.Touch.getDetail(i); + + // If touch starts + if (t.wasPressed()) { + touch_start_time = millis(); // Record the time when the touch began + is_touching = true; // Set to touch + } + + //Check the current touch status + if (is_touching) { + unsigned long duration = millis() - touch_start_time; + if (duration >= LONG_PRESS_THRESHOLD) { + LOG_INFO("Long Press Detected\n"); + powerFSM.trigger(EVENT_PRESS); + screen->startAlert("Shutting down..."); + screen->forceDisplay(true); + // Executive logic, such as shutdown, display menu, etc + // To avoid duplicate detection, set is_touching to false here + is_touching = false; + M5.Speaker.tone(3000, 300); + delay(1000); + M5.Power.powerOff(); + } + } + // Check if the touch just ended + if (t.wasReleased()) { + if (is_touching) { + unsigned long duration = millis() - touch_start_time; + if (duration < LONG_PRESS_THRESHOLD) { + unsigned long currentTime = millis(); + // Check whether it is a double click + if (currentTime - lastClickTime <= DOUBLE_CLICK_THRESHOLD) { + clickCount++; + if (clickCount == MAX_CLICKS) { + LOG_INFO("Double Click Detected\n"); + M5.Speaker.tone(2000, 100); + service->refreshLocalMeshNode(); + auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true); + if (screen) { + if (sentPosition) + screen->print("Sent ad-hoc position\n"); + else + screen->print("Sent ad-hoc nodeinfo\n"); + screen->forceDisplay(true); // Force a new UI frame, then force an EInk update + } + clickCount = 0; + } + } else { + clickCount = 1; + } + + lastClickTime = currentTime; // Update last click time + } + } + // Reset the touch status + is_touching = false; + } + // You can add more status checks, such as sliding and dragging + if (t.wasFlickStart()) { + LOG_INFO("Flick Start Detected\n"); + M5.Speaker.tone(1000, 100); + powerFSM.trigger(EVENT_PRESS); + + } + } +} +#endif \ No newline at end of file diff --git a/src/ButtonThread.h b/src/ButtonThread.h index 9cd7b3dac3..d787ddbc1b 100644 --- a/src/ButtonThread.h +++ b/src/ButtonThread.h @@ -66,3 +66,6 @@ class ButtonThread : public concurrency::OSThread }; extern ButtonThread *buttonThread; +#if defined(M5STACK_CORE2) +void ScreenTouch(); +#endif \ No newline at end of file diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index d292f4b191..97ffe6173d 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -62,7 +62,7 @@ along with this program. If not, see . #if ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) #include "M5Unified.h" extern DataInfo DataRegion; #endif @@ -952,7 +952,7 @@ bool deltaToTimestamp(uint32_t secondsAgo, uint8_t *hours, uint8_t *minutes, int validCached = true; return validCached; } -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) static void drawLoraMessage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y){ display->clear(); display->drawString(x + 0, y + 0, myRegion->name); @@ -990,7 +990,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state 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); -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::BLACK); #else display->setColor(BLACK); @@ -1028,7 +1028,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state } } -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::WHITE); #else display->setColor(WHITE); @@ -1105,7 +1105,7 @@ void Screen::drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char int xo = x, yo = y; while (*f) { display->drawString(xo, yo, *f); -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) if ((display->getColor() == OLEDDISPLAY_COLOR::BLACK) && config.display.heading_bold) display->drawString(xo + 1, yo, *f); display->setColor(OLEDDISPLAY_COLOR::WHITE); @@ -1522,7 +1522,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ display->drawCircle(compassX, compassY, compassDiam / 2); if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::BLACK); #else display->setColor(BLACK); @@ -1643,6 +1643,10 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) #if defined(M5STACK_COREBASIC) pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, HIGH); +#endif +#if defined(M5STACK_CORE2) + M5.Power.Axp192.setDCDC3(1000); + M5.Display.setBrightness(130); #endif enabled = true; setInterval(0); // Draw ASAP @@ -1658,6 +1662,8 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) #if defined(M5STACK_COREBASIC) pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, LOW); +#elif defined(M5STACK_CORE2) + M5.Power.Axp192.setDCDC3(0); #endif #ifdef USE_ST7789 SPI1.end(); @@ -2150,11 +2156,11 @@ void Screen::setFrames(FrameFocus focus) fsi.positions.textMessage = numframes; if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) { normalFrames[numframes++] = drawTextMessageFrame; -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) M5.Speaker.tone(3000, 400); #endif } -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) normalFrames[numframes++] = drawLoraMessage; #endif @@ -2418,7 +2424,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::BLACK); #else display->setColor(BLACK); @@ -2463,7 +2469,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 } } #endif -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::WHITE); #else display->setColor(WHITE); @@ -2538,7 +2544,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::BLACK); #else display->setColor(BLACK); @@ -2562,7 +2568,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i } } -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::WHITE); #else display->setColor(WHITE); @@ -2626,7 +2632,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::BLACK); #else display->setColor(BLACK); @@ -2669,7 +2675,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat // minutes %= 60; // hours %= 24; -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) display->setColor(OLEDDISPLAY_COLOR::WHITE); #else display->setColor(WHITE); diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index dc43e900a1..20a3b2dd46 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -332,7 +332,9 @@ class LGFX : public lgfx::LGFX_Device { auto cfg = _light_instance.config(); // Gets a structure for backlight settings. +#if !defined(M5STACK_CORE2) cfg.pin_bl = TFT_BL; // Pin number to which the backlight is connected +#endif cfg.invert = false; // true to invert the brightness of the backlight // cfg.freq = 44100; // PWM frequency of backlight // cfg.pwm_channel = 1; // PWM channel number to use @@ -590,7 +592,7 @@ void TFTDisplay::sendCommand(uint8_t com) #elif defined(ST7735_BL_V05) pinMode(ST7735_BL_V05, OUTPUT); digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON); -#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(M5STACK_COREBASIC) +#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(M5STACK_COREBASIC) && !defined(M5STACK_CORE2) tft->wakeup(); tft->powerSaveOff(); #elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON) @@ -608,7 +610,7 @@ void TFTDisplay::sendCommand(uint8_t com) unphone.backlight(true); // using unPhone library #endif #ifdef RAK14014 -#elif !defined(M5STACK) && !defined(ST7789_CS) && !defined(M5STACK_COREBASIC)// T-Deck gets brightness set in Screen.cpp in the handleSetOn function +#elif !defined(M5STACK) && !defined(ST7789_CS) && !defined(M5STACK_COREBASIC) && !defined(M5STACK_CORE2)// T-Deck gets brightness set in Screen.cpp in the handleSetOn function tft->setBrightness(172); #endif break; @@ -623,7 +625,7 @@ void TFTDisplay::sendCommand(uint8_t com) #elif defined(ST7735_BL_V05) pinMode(ST7735_BL_V05, OUTPUT); digitalWrite(ST7735_BL_V05, !TFT_BACKLIGHT_ON); -#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(M5STACK_COREBASIC) +#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(M5STACK_COREBASIC) && !defined(M5STACK_CORE2) tft->sleep(); tft->powerSaveOn(); #elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON) @@ -734,10 +736,11 @@ bool TFTDisplay::connect() unphone.backlight(true); // using unPhone library LOG_INFO("Power to TFT Backlight\n"); #endif - +#if !defined(M5STACK_CORE2) tft->init(); +#endif -#if defined(M5STACK) || defined(M5STACK_COREBASIC) +#if defined(M5STACK) || defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) tft->setRotation(0); #elif defined(RAK14014) tft->setRotation(1); diff --git a/src/main.cpp b/src/main.cpp index 562f282178..0a2f2f401b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,7 +115,7 @@ AudioThread *audioThread = nullptr; #if defined(TCXO_OPTIONAL) float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if TCXO is optional, put this here so it can be changed further down. #endif -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) #include #endif @@ -667,7 +667,6 @@ void setup() // I2C trigger by sending 'go' command drv.setMode(DRV2605_MODE_INTTRIG); #endif - // Init our SPI controller (must be before screen and lora) initSPI(); #ifdef ARCH_RP2040 @@ -754,12 +753,10 @@ void setup() if (!pmu_found) RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware #endif -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) M5.begin(); M5.Speaker.tone(2000, 600); M5.Display.init(); - M5.Display.clearDisplay(); - M5.Display.display(); M5.Display.fillScreen(TFT_BLACK); #endif #if !MESHTASTIC_EXCLUDE_I2C @@ -1158,5 +1155,8 @@ void loop() mainDelay.delay(delayMsec); } // if (didWake) LOG_DEBUG("wake!\n"); +#if defined(M5STACK_CORE2) + ScreenTouch(); +#endif } #endif diff --git a/src/main.h b/src/main.h index 99983acf8f..5cb54c4d47 100644 --- a/src/main.h +++ b/src/main.h @@ -42,7 +42,7 @@ extern bool isUSBPowered; #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) extern ATECCX08A atecc; #endif -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) struct DataInfo { int lora_channel_num; double lora_freq; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index cd7fc74025..71654b40a5 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -11,7 +11,7 @@ #include #include #include -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) DataInfo DataRegion; #endif #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \ @@ -203,7 +203,7 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl) float tPacket = tPreamble + tPayload; uint32_t msecs = tPacket * 1000; -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) DataRegion.lora_sf=sf; DataRegion.lora_cr=cr; #endif @@ -551,7 +551,7 @@ void RadioInterface::applyModemConfig() slotTimeMsec = computeSlotTimeMsec(bw, sf); preambleTimeMsec = getPacketTime((uint32_t)0); maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader)); -#if defined(M5STACK_COREBASIC) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) DataRegion.lora_channel_num=channel_num; DataRegion.lora_freq=getFreq(); DataRegion.lora_channel_name=channelName; diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index d671d66257..c60fd1139a 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -200,6 +200,8 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_RP2040_FEATHER_RFM95 = 76, /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ meshtastic_HardwareModel_M5STACK_COREBASIC=77, + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ + meshtastic_HardwareModel_M5STACK_CORE2=78, /* ------------------------------------------------------------------------------------------------------------------------------------------ Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. ------------------------------------------------------------------------------------------------------------------------------------------ */ diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 760eb4f8c1..d17c3ad5c0 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -166,6 +166,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114 #elif defined(M5STACK_COREBASIC) #define HW_VENDOR meshtastic_HardwareModel_M5STACK_COREBASIC +#elif defined(M5STACK_CORE2) +#define HW_VENDOR meshtastic_HardwareModel_M5STACK_CORE2 #endif // ----------------------------------------------------------------------------- diff --git a/variants/m5stack_core2/pins_arduino.h b/variants/m5stack_core2/pins_arduino.h new file mode 100644 index 0000000000..86c6b812ab --- /dev/null +++ b/variants/m5stack_core2/pins_arduino.h @@ -0,0 +1,47 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +static const uint8_t TX = 1; +static const uint8_t RX = 3; + +static const uint8_t TXD2 = 17; +static const uint8_t RXD2 = 16; + +static const uint8_t SDA = 21; +static const uint8_t SCL = 22; + +static const uint8_t SS = 33; +static const uint8_t MOSI = 23; +static const uint8_t MISO = 38; +static const uint8_t SCK = 18; + +static const uint8_t G23 = 23; +static const uint8_t G19 = 19; +static const uint8_t G18 = 18; +static const uint8_t G3 = 3; +static const uint8_t G16 = 16; +static const uint8_t G21 = 21; +static const uint8_t G2 = 2; +static const uint8_t G12 = 12; +static const uint8_t G15 = 15; +static const uint8_t G35 = 35; +static const uint8_t G36 = 36; +static const uint8_t G25 = 25; +static const uint8_t G26 = 26; +static const uint8_t G1 = 1; +static const uint8_t G17 = 17; +static const uint8_t G22 = 22; +static const uint8_t G5 = 5; +static const uint8_t G13 = 13; +static const uint8_t G0 = 0; +static const uint8_t G34 = 34; + +static const uint8_t DAC1 = 25; +static const uint8_t DAC2 = 26; + +static const uint8_t ADC1 = 35; +static const uint8_t ADC2 = 36; + +#endif /* Pins_Arduino_h */ diff --git a/variants/m5stack_core2/platformio.ini b/variants/m5stack_core2/platformio.ini new file mode 100644 index 0000000000..cae516ad26 --- /dev/null +++ b/variants/m5stack_core2/platformio.ini @@ -0,0 +1,26 @@ +[env:m5stack-core2] +extends = esp32_base +board = m5stack-core-esp32 +monitor_filters = esp32_exception_decoder +build_src_filter = + ${esp32_base.build_src_filter} +build_flags = + ${esp32_base.build_flags} -I variants/m5stack_core2 + -DILI9341_DRIVER + -DM5STACK_CORE2 + -DUSER_SETUP_LOADED + -DTFT_SDA_READ + -DTFT_DRIVER=0x9341 + -DTFT_MISO=38 + -DTFT_MOSI=23 + -DTFT_SCLK=18 + -DTFT_CS=5 + -DTFT_DC=15 + -DTFT_RST=-1 + -DSPI_FREQUENCY=40000000 + -DSPI_READ_FREQUENCY=16000000 + -DDISABLE_ALL_LIBRARY_WARNINGS +lib_deps = + ${esp32_base.lib_deps} + lovyan03/LovyanGFX@^1.1.8 + m5stack/M5Unified@^0.1.14 \ No newline at end of file diff --git a/variants/m5stack_core2/variant.h b/variants/m5stack_core2/variant.h new file mode 100644 index 0000000000..cdd10dc763 --- /dev/null +++ b/variants/m5stack_core2/variant.h @@ -0,0 +1,44 @@ +// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep + + +// #define BUTTON_PIN 39 // 38, 37 +// #define BUTTON_PIN 0 +#define BUTTON_NEED_PULLUP +// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin. + +//#define BUTTON_PIN + +//#define PIN_BUZZER 25 +#undef LORA_SCK +#undef LORA_MISO +#undef LORA_MOSI +#undef LORA_CS + +#define LORA_SCK 18 +#define LORA_MISO 38 +#define LORA_MOSI 23 +#define LORA_CS 33 //NSS + +#define USE_RF95 +#define LORA_DIO0 35 // IRQ +#define LORA_RESET 19 +#define LORA_DIO1 RADIOLIB_NC // Not really used +#define LORA_DIO2 RADIOLIB_NC // Not really used + +// This board has different GPS pins than all other boards +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#define GPS_RX_PIN 13 +#define GPS_TX_PIN 14 + +#define TFT_HEIGHT 240 +#define TFT_WIDTH 320 +#define TFT_OFFSET_X 0 +#define TFT_OFFSET_Y 0 +#define TFT_BUSY -1 +#define TFT_OFFSET_ROTATION 0 +// LCD screens are slow, so slowdown the wipe so it looks better +#define SCREEN_TRANSITION_FRAMERATE 30 // fps +// Picomputer gets a white on black display +#define TFT_MESH COLOR565 (0xA0, 0xFF, 0x00)//(0x94, 0xEA, 0x67) +#define ILI9341_SPI_HOST VSPI_HOST // VSPI_HOST or HSPI_HOST \ No newline at end of file From 194580532a275d0b1be77373ba4a7f083a526b19 Mon Sep 17 00:00:00 2001 From: Junhuang Date: Fri, 30 Aug 2024 12:10:07 +0800 Subject: [PATCH 5/8] Modify macro definition, remove and open some features --- src/ButtonThread.cpp | 14 +----- src/graphics/Screen.cpp | 90 ++++++++++--------------------------- src/main.cpp | 3 -- src/main.h | 2 - src/mesh/RadioInterface.cpp | 7 +-- 5 files changed, 25 insertions(+), 91 deletions(-) diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index 4e17e7549c..17e9bdaf5d 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -13,7 +13,7 @@ #ifdef ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) +#if defined(M5STACK_CORE2) #include #endif #define DEBUG_BUTTONS 0 @@ -126,9 +126,6 @@ int32_t ButtonThread::runOnce() switch (btnEvent) { case BUTTON_EVENT_PRESSED: { LOG_BUTTON("press!\n"); -#if defined(M5STACK_COREBASIC) - M5.Speaker.tone(1000, 100); -#endif #ifdef BUTTON_PIN if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) != moduleConfig.canned_message.inputbroker_pin_press) || @@ -149,9 +146,6 @@ int32_t ButtonThread::runOnce() case BUTTON_EVENT_DOUBLE_PRESSED: { LOG_BUTTON("Double press!\n"); -#if defined(M5STACK_COREBASIC) - M5.Speaker.tone(2000, 100); -#endif service->refreshLocalMeshNode(); auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true); if (screen) { @@ -193,9 +187,6 @@ int32_t ButtonThread::runOnce() case BUTTON_EVENT_LONG_PRESSED: { LOG_BUTTON("Long press!\n"); -#if defined(M5STACK_COREBASIC) - M5.Speaker.tone(3000, 300); -#endif powerFSM.trigger(EVENT_PRESS); if (screen) { screen->startAlert("Shutting down..."); @@ -208,9 +199,6 @@ int32_t ButtonThread::runOnce() // may wake the board immediatedly. case BUTTON_EVENT_LONG_RELEASED: { LOG_INFO("Shutdown from long press\n"); -#if defined(M5STACK_COREBASIC) - M5.Speaker.tone(4000, 300); -#endif playShutdownMelody(); delay(3000); power->shutdown(); diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 6504202168..fe7fba2fac 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -62,10 +62,15 @@ along with this program. If not, see . #if ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) +#if defined(M5STACK_CORE2) #include "M5Unified.h" -extern DataInfo DataRegion; +#define OLED_BLACK OLEDDISPLAY_COLOR::BLACK +#define OLED_WHITE OLEDDISPLAY_COLOR::WHITE +#else + #define OLED_BLACK BLACK + #define OLED_WHITE WHITE #endif +extern DataInfo DataRegion; using namespace meshtastic; /** @todo remove */ namespace graphics @@ -952,9 +957,7 @@ bool deltaToTimestamp(uint32_t secondsAgo, uint8_t *hours, uint8_t *minutes, int validCached = true; return validCached; } -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) static void drawLoraMessage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y){ - display->clear(); display->drawString(x + 0, y + 0, myRegion->name); display->setFont(FONT_MEDIUM); display->drawString(x + 10, y + 30,"channel: "+String(DataRegion.lora_channel_num+1)); @@ -971,7 +974,6 @@ static void drawLoraMessage(OLEDDisplay *display, OLEDDisplayUiState *state, int display->drawString(x + SCREEN_WIDTH, y,String(DataRegion.lora_channel_name)); display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code } -#endif /// Draw the last text message we received static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { @@ -990,11 +992,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state 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); -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::BLACK); -#else - display->setColor(BLACK); -#endif + display->setColor(OLED_BLACK); } // For time delta @@ -1028,11 +1026,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state } } -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::WHITE); -#else - display->setColor(WHITE); -#endif + display->setColor(OLED_WHITE); #ifndef EXCLUDE_EMOJI if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, @@ -1105,15 +1099,10 @@ void Screen::drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char int xo = x, yo = y; while (*f) { display->drawString(xo, yo, *f); -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - if ((display->getColor() == OLEDDISPLAY_COLOR::BLACK) && config.display.heading_bold) - display->drawString(xo + 1, yo, *f); - display->setColor(OLEDDISPLAY_COLOR::WHITE); -#else - if ((display->getColor() == BLACK) && config.display.heading_bold) + + if ((display->getColor() == OLED_BLACK) && config.display.heading_bold) display->drawString(xo + 1, yo, *f); - display->setColor(WHITE); -#endif + display->setColor(OLED_WHITE); yo += FONT_HEIGHT_SMALL; if (yo > SCREEN_HEIGHT - FONT_HEIGHT_SMALL) { xo += SCREEN_WIDTH / 2; @@ -1523,11 +1512,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ display->drawCircle(compassX, compassY, compassDiam / 2); if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::BLACK); -#else - display->setColor(BLACK); -#endif + display->setColor(OLED_BLACK); } // Must be after distStr is populated screen->drawColumns(display, x, y, fields); @@ -1641,7 +1626,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) digitalWrite(VTFT_LEDA, TFT_BACKLIGHT_ON); #endif #endif -#if defined(M5STACK_COREBASIC) +#ifdef TFT_BL pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, HIGH); #endif @@ -1660,10 +1645,11 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) #endif LOG_INFO("Turning off screen\n"); dispdev->displayOff(); -#if defined(M5STACK_COREBASIC) +#ifdef TFT_BL pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, LOW); -#elif defined(M5STACK_CORE2) +#endif +#if defined(M5STACK_CORE2) M5.Power.Axp192.setDCDC3(0); #endif #ifdef USE_ST7789 @@ -2157,14 +2143,8 @@ void Screen::setFrames(FrameFocus focus) fsi.positions.textMessage = numframes; if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) { normalFrames[numframes++] = drawTextMessageFrame; -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - M5.Speaker.tone(3000, 400); -#endif } -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) normalFrames[numframes++] = drawLoraMessage; -#endif - // then all the nodes // We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens size_t numToShow = min(numMeshNodes, 4U); @@ -2425,11 +2405,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::BLACK); -#else - display->setColor(BLACK); -#endif + display->setColor(OLED_BLACK); } char channelStr[20]; @@ -2470,11 +2446,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 } } #endif -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::WHITE); -#else - display->setColor(WHITE); -#endif + display->setColor(OLED_WHITE); // Draw the channel name display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr); // Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo @@ -2547,11 +2519,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::BLACK); -#else - display->setColor(BLACK); -#endif + display->setColor(OLED_BLACK); } if (WiFi.status() != WL_CONNECTED) { @@ -2571,11 +2539,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i } } -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::WHITE); -#else - display->setColor(WHITE); -#endif + display->setColor(OLED_WHITE); /* - WL_CONNECTED: assigned when connected to a WiFi network; @@ -2635,11 +2599,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::BLACK); -#else - display->setColor(BLACK); -#endif + display->setColor(OLED_BLACK); } char batStr[20]; @@ -2678,11 +2638,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat // minutes %= 60; // hours %= 24; -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) - display->setColor(OLEDDISPLAY_COLOR::WHITE); -#else - display->setColor(WHITE); -#endif + display->setColor(OLED_WHITE); // Show uptime as days, hours, minutes OR seconds std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds); diff --git a/src/main.cpp b/src/main.cpp index 461cbf0e08..351c16edbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -761,9 +761,6 @@ void setup() #endif #if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) M5.begin(); - M5.Speaker.tone(2000, 600); - M5.Display.init(); - M5.Display.fillScreen(TFT_BLACK); #endif #if !MESHTASTIC_EXCLUDE_I2C // Don't call screen setup until after nodedb is setup (because we need diff --git a/src/main.h b/src/main.h index 5cb54c4d47..9e6a5d5305 100644 --- a/src/main.h +++ b/src/main.h @@ -42,7 +42,6 @@ extern bool isUSBPowered; #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) extern ATECCX08A atecc; #endif -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) struct DataInfo { int lora_channel_num; double lora_freq; @@ -52,7 +51,6 @@ struct DataInfo { int lora_sf; int lora_cr; }; -#endif #ifdef T_WATCH_S3 #include extern Adafruit_DRV2605 drv; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 71654b40a5..847c7c21bc 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -11,9 +11,8 @@ #include #include #include -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) + DataInfo DataRegion; -#endif #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \ { \ meshtastic_Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ @@ -203,10 +202,8 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl) float tPacket = tPreamble + tPayload; uint32_t msecs = tPacket * 1000; -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) DataRegion.lora_sf=sf; DataRegion.lora_cr=cr; -#endif LOG_DEBUG("(bw=%d, sf=%d, cr=4/%d) packet symLen=%d ms, payloadSize=%u, time %d ms\n", (int)bw, sf, cr, (int)(tSym * 1000), pl, msecs); return msecs; @@ -551,13 +548,11 @@ void RadioInterface::applyModemConfig() slotTimeMsec = computeSlotTimeMsec(bw, sf); preambleTimeMsec = getPacketTime((uint32_t)0); maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader)); -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) DataRegion.lora_channel_num=channel_num; DataRegion.lora_freq=getFreq(); DataRegion.lora_channel_name=channelName; DataRegion.lora_power_output=power; DataRegion.lora_bw=bw; -#endif LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, loraConfig.frequency_offset); LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power); From d9d821f1fcdaa3eefb5ac6cca589d9e8224aac7a Mon Sep 17 00:00:00 2001 From: Junhuang Date: Tue, 18 Feb 2025 09:02:10 +0800 Subject: [PATCH 6/8] Added RF95 power upper limit macro definition --- src/main.h | 3 --- variants/m5stack_core2/platformio.ini | 4 ++-- variants/m5stack_core2/variant.h | 1 + variants/m5stack_corebasic/platformio.ini | 4 ++-- variants/m5stack_corebasic/variant.h | 1 + 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main.h b/src/main.h index b1ff550fe1..056ed9452c 100644 --- a/src/main.h +++ b/src/main.h @@ -40,9 +40,6 @@ extern bool isCharging; extern bool isUSBPowered; -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) -extern ATECCX08A atecc; -#endif struct DataInfo { int lora_channel_num; double lora_freq; diff --git a/variants/m5stack_core2/platformio.ini b/variants/m5stack_core2/platformio.ini index cae516ad26..3c7c32c998 100644 --- a/variants/m5stack_core2/platformio.ini +++ b/variants/m5stack_core2/platformio.ini @@ -22,5 +22,5 @@ build_flags = -DDISABLE_ALL_LIBRARY_WARNINGS lib_deps = ${esp32_base.lib_deps} - lovyan03/LovyanGFX@^1.1.8 - m5stack/M5Unified@^0.1.14 \ No newline at end of file + lovyan03/LovyanGFX@^1.2.0 + m5stack/M5Unified@^0.2.3 \ No newline at end of file diff --git a/variants/m5stack_core2/variant.h b/variants/m5stack_core2/variant.h index cdd10dc763..605a6be6a2 100644 --- a/variants/m5stack_core2/variant.h +++ b/variants/m5stack_core2/variant.h @@ -20,6 +20,7 @@ #define LORA_CS 33 //NSS #define USE_RF95 +#define RF95_MAX_POWER 17 #define LORA_DIO0 35 // IRQ #define LORA_RESET 19 #define LORA_DIO1 RADIOLIB_NC // Not really used diff --git a/variants/m5stack_corebasic/platformio.ini b/variants/m5stack_corebasic/platformio.ini index aa92ea6dbf..0d60a848d2 100644 --- a/variants/m5stack_corebasic/platformio.ini +++ b/variants/m5stack_corebasic/platformio.ini @@ -21,5 +21,5 @@ build_flags = -DSPI_READ_FREQUENCY=16000000 lib_deps = ${esp32_base.lib_deps} - lovyan03/LovyanGFX@^1.1.8 - m5stack/M5Unified@^0.1.14 \ No newline at end of file + lovyan03/LovyanGFX@^1.2.0 + m5stack/M5Unified@^0.2.3 \ No newline at end of file diff --git a/variants/m5stack_corebasic/variant.h b/variants/m5stack_corebasic/variant.h index 92dc58a65f..3d4233ce54 100644 --- a/variants/m5stack_corebasic/variant.h +++ b/variants/m5stack_corebasic/variant.h @@ -23,6 +23,7 @@ #define LORA_CS 5 //NSS #define USE_RF95 +#define RF95_MAX_POWER 17 #define LORA_DIO0 35 // IRQ #define LORA_RESET 13 // RST #define LORA_DIO1 RADIOLIB_NC // Not really used From 3729635ef5f6ccb660228199c72ba0f58e2af517 Mon Sep 17 00:00:00 2001 From: imliubo Date: Thu, 27 Feb 2025 16:19:43 +0800 Subject: [PATCH 7/8] fix the code format by use trunk Signed-off-by: imliubo --- src/ButtonThread.cpp | 43 ++++++++++++++-------------- src/graphics/Screen.cpp | 39 +++++++++++++------------ src/graphics/TFTDisplay.cpp | 13 +++++---- src/main.cpp | 4 +-- src/main.h | 7 ++--- src/mesh/RadioInterface.cpp | 16 +++++------ variants/m5stack_core2/variant.h | 13 ++++----- variants/m5stack_corebasic/variant.h | 13 ++++----- 8 files changed, 73 insertions(+), 75 deletions(-) diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index d82898d0ee..fcb61dfe62 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -14,7 +14,7 @@ #ifdef ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif -#if defined(M5STACK_CORE2) +#if defined(M5STACK_CORE2) #include #endif #define DEBUG_BUTTONS 0 @@ -372,38 +372,40 @@ void ButtonThread::userButtonPressedLongStop() } #if defined(M5STACK_CORE2) // Define a constant -const unsigned long LONG_PRESS_THRESHOLD = 5000; // Hold the threshold +const unsigned long LONG_PRESS_THRESHOLD = 5000; // Hold the threshold const unsigned long DOUBLE_CLICK_THRESHOLD = 1000; // Double-click the threshold -const int MAX_CLICKS = 2; // Maximum hits +const int MAX_CLICKS = 2; // Maximum hits // Global variable unsigned long lastClickTime = 0; // The time of the last click -int clickCount = 0; // Click count -unsigned long touch_start_time; // Touch start time -bool is_touching = false; // Mark whether you are currently touching -void ScreenTouch(){ +int clickCount = 0; // Click count +unsigned long touch_start_time; // Touch start time +bool is_touching = false; // Mark whether you are currently touching +void ScreenTouch() +{ M5.update(); auto count = M5.Touch.getCount(); - if (count == 0) return; + if (count == 0) + return; for (std::size_t i = 0; i < count; ++i) { auto t = M5.Touch.getDetail(i); // If touch starts if (t.wasPressed()) { touch_start_time = millis(); // Record the time when the touch began - is_touching = true; // Set to touch + is_touching = true; // Set to touch } - //Check the current touch status + // Check the current touch status if (is_touching) { unsigned long duration = millis() - touch_start_time; - if (duration >= LONG_PRESS_THRESHOLD) { - LOG_INFO("Long Press Detected\n"); + if (duration >= LONG_PRESS_THRESHOLD) { + LOG_INFO("Long Press Detected\n"); powerFSM.trigger(EVENT_PRESS); screen->startAlert("Shutting down..."); screen->forceDisplay(true); // Executive logic, such as shutdown, display menu, etc // To avoid duplicate detection, set is_touching to false here - is_touching = false; + is_touching = false; M5.Speaker.tone(3000, 300); delay(1000); M5.Power.powerOff(); @@ -413,13 +415,13 @@ void ScreenTouch(){ if (t.wasReleased()) { if (is_touching) { unsigned long duration = millis() - touch_start_time; - if (duration < LONG_PRESS_THRESHOLD) { - unsigned long currentTime = millis(); + if (duration < LONG_PRESS_THRESHOLD) { + unsigned long currentTime = millis(); // Check whether it is a double click if (currentTime - lastClickTime <= DOUBLE_CLICK_THRESHOLD) { clickCount++; if (clickCount == MAX_CLICKS) { - LOG_INFO("Double Click Detected\n"); + LOG_INFO("Double Click Detected\n"); M5.Speaker.tone(2000, 100); service->refreshLocalMeshNode(); auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true); @@ -430,24 +432,23 @@ void ScreenTouch(){ screen->print("Sent ad-hoc nodeinfo\n"); screen->forceDisplay(true); // Force a new UI frame, then force an EInk update } - clickCount = 0; + clickCount = 0; } } else { - clickCount = 1; + clickCount = 1; } - + lastClickTime = currentTime; // Update last click time } } // Reset the touch status - is_touching = false; + is_touching = false; } // You can add more status checks, such as sliding and dragging if (t.wasFlickStart()) { LOG_INFO("Flick Start Detected\n"); M5.Speaker.tone(1000, 100); powerFSM.trigger(EVENT_PRESS); - } } } diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index e88e0b646f..de04735286 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -64,15 +64,15 @@ along with this program. If not, see . #include "modules/StoreForwardModule.h" #include "platform/portduino/PortduinoGlue.h" #endif -#if defined(M5STACK_CORE2) +#if defined(M5STACK_CORE2) #include "M5Unified.h" #define OLED_BLACK OLEDDISPLAY_COLOR::BLACK #define OLED_WHITE OLEDDISPLAY_COLOR::WHITE #else - #define OLED_BLACK BLACK - #define OLED_WHITE WHITE +#define OLED_BLACK BLACK +#define OLED_WHITE WHITE #endif -extern DataInfo DataRegion; +extern DataInfo DataRegion; using namespace meshtastic; /** @todo remove */ namespace graphics @@ -956,21 +956,22 @@ bool deltaToTimestamp(uint32_t secondsAgo, uint8_t *hours, uint8_t *minutes, int validCached = true; return validCached; } -static void drawLoraMessage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y){ +static void drawLoraMessage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ display->drawString(x + 0, y + 0, myRegion->name); display->setFont(FONT_MEDIUM); - display->drawString(x + 10, y + 30,"channel: "+String(DataRegion.lora_channel_num+1)); - display->drawString(x + 10, y + 60,"bw: "+ String(DataRegion.lora_bw)); - display->drawString(x + SCREEN_WIDTH/2+10, y+30,"freq: "+String(DataRegion.lora_freq)); - display->drawString(x + SCREEN_WIDTH/2+10, y+60,"power: "+ String(DataRegion.lora_power_output)); - display->drawString(x + 10, y + 90,"sf: "+String(DataRegion.lora_sf)); - display->drawString(x + SCREEN_WIDTH/2+10, y+90,"cr: 4/:"+ String(DataRegion.lora_cr)); + display->drawString(x + 10, y + 30, "channel: " + String(DataRegion.lora_channel_num + 1)); + display->drawString(x + 10, y + 60, "bw: " + String(DataRegion.lora_bw)); + display->drawString(x + SCREEN_WIDTH / 2 + 10, y + 30, "freq: " + String(DataRegion.lora_freq)); + display->drawString(x + SCREEN_WIDTH / 2 + 10, y + 60, "power: " + String(DataRegion.lora_power_output)); + display->drawString(x + 10, y + 90, "sf: " + String(DataRegion.lora_sf)); + display->drawString(x + SCREEN_WIDTH / 2 + 10, y + 90, "cr: 4/:" + String(DataRegion.lora_cr)); display->setTextAlignment(TEXT_ALIGN_LEFT); const char *title = "LoRa"; - display->drawString(x + SCREEN_WIDTH/2-20, y +0, title); + display->drawString(x + SCREEN_WIDTH / 2 - 20, y + 0, title); display->setFont(FONT_SMALL); display->setTextAlignment(TEXT_ALIGN_RIGHT); - display->drawString(x + SCREEN_WIDTH, y,String(DataRegion.lora_channel_name)); + display->drawString(x + SCREEN_WIDTH, y, String(DataRegion.lora_channel_name)); display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code } /// Draw the last text message we received @@ -991,7 +992,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state 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(OLED_BLACK); + display->setColor(OLED_BLACK); } // For time delta @@ -1659,9 +1660,9 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, HIGH); #endif -#if defined(M5STACK_CORE2) +#if defined(M5STACK_CORE2) M5.Power.Axp192.setDCDC3(1000); - M5.Display.setBrightness(130); + M5.Display.setBrightness(130); #endif enabled = true; setInterval(0); // Draw ASAP @@ -1678,7 +1679,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, LOW); #endif -#if defined(M5STACK_CORE2) +#if defined(M5STACK_CORE2) M5.Power.Axp192.setDCDC3(0); #endif #ifdef USE_ST7789 @@ -2512,7 +2513,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 } } #endif - display->setColor(OLED_WHITE); + display->setColor(OLED_WHITE); // Draw the channel name display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr); // Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo @@ -2605,7 +2606,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i } } - display->setColor(OLED_WHITE); + display->setColor(OLED_WHITE); /* - WL_CONNECTED: assigned when connected to a WiFi network; diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 9a60d2e3d0..3386cfc0e1 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -310,9 +310,9 @@ class LGFX : public lgfx::LGFX_Device cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read cfg.readable = true; // Set to true if data can be read #if defined(M5STACK_COREBASIC) - cfg.invert = true; // Set to true if the light/darkness of the panel is reversed + cfg.invert = true; // Set to true if the light/darkness of the panel is reversed #else - cfg.invert = false; // Set to true if the light/darkness of the panel is reversed + cfg.invert = false; // Set to true if the light/darkness of the panel is reversed #endif cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped cfg.dlen_16bit = @@ -332,9 +332,9 @@ class LGFX : public lgfx::LGFX_Device auto cfg = _light_instance.config(); // Gets a structure for backlight settings. #if !defined(M5STACK_CORE2) - cfg.pin_bl = TFT_BL; // Pin number to which the backlight is connected + cfg.pin_bl = TFT_BL; // Pin number to which the backlight is connected #endif - cfg.invert = false; // true to invert the brightness of the backlight + cfg.invert = false; // true to invert the brightness of the backlight // cfg.freq = 44100; // PWM frequency of backlight // cfg.pwm_channel = 1; // PWM channel number to use @@ -747,7 +747,8 @@ void TFTDisplay::sendCommand(uint8_t com) unphone.backlight(true); // using unPhone library #endif #ifdef RAK14014 -#elif !defined(M5STACK) && !defined(ST7789_CS) && !defined(M5STACK_COREBASIC) && !defined(M5STACK_CORE2)// T-Deck gets brightness set in Screen.cpp in the handleSetOn function +#elif !defined(M5STACK) && !defined(ST7789_CS) && !defined(M5STACK_COREBASIC) && \ + !defined(M5STACK_CORE2) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function tft->setBrightness(172); #endif break; @@ -857,7 +858,7 @@ bool TFTDisplay::connect() tft->init(); #endif -#if defined(M5STACK) || defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) +#if defined(M5STACK) || defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) tft->setRotation(0); #elif defined(RAK14014) tft->setRotation(1); diff --git a/src/main.cpp b/src/main.cpp index 373d6f2584..db404e3fb1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,11 +115,10 @@ AccelerometerThread *accelerometerThread = nullptr; AudioThread *audioThread = nullptr; #endif - #if defined(TCXO_OPTIONAL) float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if TCXO is optional, put this here so it can be changed further down. #endif -#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) +#if defined(M5STACK_COREBASIC) || defined(M5STACK_CORE2) #include #endif @@ -1234,6 +1233,5 @@ void loop() #if defined(M5STACK_CORE2) ScreenTouch(); #endif - } #endif diff --git a/src/main.h b/src/main.h index 056ed9452c..5a5b12c524 100644 --- a/src/main.h +++ b/src/main.h @@ -39,14 +39,13 @@ extern bool pmu_found; extern bool isCharging; extern bool isUSBPowered; - struct DataInfo { int lora_channel_num; double lora_freq; - const char* lora_channel_name; - int lora_power_output; + const char *lora_channel_name; + int lora_power_output; float lora_bw; - int lora_sf; + int lora_sf; int lora_cr; }; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 218e4f37de..46d707fa4b 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -12,7 +12,7 @@ #include #include -DataInfo DataRegion; +DataInfo DataRegion; #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \ { \ meshtastic_Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ @@ -213,8 +213,8 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl) float tPacket = tPreamble + tPayload; uint32_t msecs = tPacket * 1000; - DataRegion.lora_sf=sf; - DataRegion.lora_cr=cr; + DataRegion.lora_sf = sf; + DataRegion.lora_cr = cr; LOG_DEBUG("(bw=%d, sf=%d, cr=4/%d) packet symLen=%d ms, payloadSize=%u, time %d ms\n", (int)bw, sf, cr, (int)(tSym * 1000), pl, msecs); return msecs; @@ -574,11 +574,11 @@ void RadioInterface::applyModemConfig() preambleTimeMsec = getPacketTime((uint32_t)0); maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader)); - DataRegion.lora_channel_num=channel_num; - DataRegion.lora_freq=getFreq(); - DataRegion.lora_channel_name=channelName; - DataRegion.lora_power_output=power; - DataRegion.lora_bw=bw; + DataRegion.lora_channel_num = channel_num; + DataRegion.lora_freq = getFreq(); + DataRegion.lora_channel_name = channelName; + DataRegion.lora_power_output = power; + DataRegion.lora_bw = bw; LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, loraConfig.frequency_offset); LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power); diff --git a/variants/m5stack_core2/variant.h b/variants/m5stack_core2/variant.h index 605a6be6a2..38c82fb34c 100644 --- a/variants/m5stack_core2/variant.h +++ b/variants/m5stack_core2/variant.h @@ -1,14 +1,13 @@ // #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep - // #define BUTTON_PIN 39 // 38, 37 // #define BUTTON_PIN 0 #define BUTTON_NEED_PULLUP // #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin. -//#define BUTTON_PIN +// #define BUTTON_PIN -//#define PIN_BUZZER 25 +// #define PIN_BUZZER 25 #undef LORA_SCK #undef LORA_MISO #undef LORA_MOSI @@ -17,11 +16,11 @@ #define LORA_SCK 18 #define LORA_MISO 38 #define LORA_MOSI 23 -#define LORA_CS 33 //NSS +#define LORA_CS 33 // NSS #define USE_RF95 #define RF95_MAX_POWER 17 -#define LORA_DIO0 35 // IRQ +#define LORA_DIO0 35 // IRQ #define LORA_RESET 19 #define LORA_DIO1 RADIOLIB_NC // Not really used #define LORA_DIO2 RADIOLIB_NC // Not really used @@ -41,5 +40,5 @@ // LCD screens are slow, so slowdown the wipe so it looks better #define SCREEN_TRANSITION_FRAMERATE 30 // fps // Picomputer gets a white on black display -#define TFT_MESH COLOR565 (0xA0, 0xFF, 0x00)//(0x94, 0xEA, 0x67) -#define ILI9341_SPI_HOST VSPI_HOST // VSPI_HOST or HSPI_HOST \ No newline at end of file +#define TFT_MESH COLOR565(0xA0, 0xFF, 0x00) //(0x94, 0xEA, 0x67) +#define ILI9341_SPI_HOST VSPI_HOST // VSPI_HOST or HSPI_HOST \ No newline at end of file diff --git a/variants/m5stack_corebasic/variant.h b/variants/m5stack_corebasic/variant.h index 3d4233ce54..1da4fbe5d1 100644 --- a/variants/m5stack_corebasic/variant.h +++ b/variants/m5stack_corebasic/variant.h @@ -20,12 +20,12 @@ #define LORA_SCK 18 #define LORA_MISO 19 #define LORA_MOSI 23 -#define LORA_CS 5 //NSS +#define LORA_CS 5 // NSS #define USE_RF95 #define RF95_MAX_POWER 17 -#define LORA_DIO0 35 // IRQ -#define LORA_RESET 13 // RST +#define LORA_DIO0 35 // IRQ +#define LORA_RESET 13 // RST #define LORA_DIO1 RADIOLIB_NC // Not really used #define LORA_DIO2 RADIOLIB_NC // Not really used @@ -35,10 +35,9 @@ #define GPS_RX_PIN 16 #define GPS_TX_PIN 17 - -//Note: If you use corebasic version 2.7 or later, -//you need to go to the src>graphics>TFTDisplay.cpp file to change the value of cfg.invert, -//this one is to set the color inversion +// Note: If you use corebasic version 2.7 or later, +// you need to go to the src>graphics>TFTDisplay.cpp file to change the value of cfg.invert, +// this one is to set the color inversion #define TFT_HEIGHT 240 #define TFT_WIDTH 320 #define TFT_OFFSET_X 0 From cda742eb19d7a1ff3498e109a1bddca0bcbb276f Mon Sep 17 00:00:00 2001 From: Junhuang Date: Wed, 14 May 2025 12:29:30 +0800 Subject: [PATCH 8/8] Correct the color definition error --- src/graphics/Screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 423eb0ee71..9da82d2617 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -2722,7 +2722,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat if (config.display.heading_bold) display->drawString(x - 1 + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str()); - display->setColor(WHITE); + display->setColor(OLED_WHITE); // Setup string to assemble analogClock string std::string analogClock = "";