diff --git a/platformio.ini b/platformio.ini index ef8f9d8c0..35358215d 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 b0271a76d..4e17e7549 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 9cd7b3dac..d787ddbc1 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 d292f4b19..97ffe6173 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 dc43e900a..20a3b2dd4 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 562f28217..0a2f2f401 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 99983acf8..5cb54c4d4 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 cd7fc7402..71654b40a 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 d671d6625..c60fd1139 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 760eb4f8c..d17c3ad5c 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 000000000..86c6b812a --- /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 000000000..cae516ad2 --- /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 000000000..cdd10dc76 --- /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