From 9a0d41aaedd87763ce57622b711da8b78b9ef2da Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Fri, 9 Feb 2024 11:48:44 +1300 Subject: [PATCH] feat: initial support for Heltec Wireless Paper v1.0 E-ink panel is DEPG0213BNS800. Otherwise, identical to v1.1 (?) Partial refresh supported, but not implemented in this commit. --- src/graphics/EInkDisplay2.cpp | 57 +++++++++++++- src/graphics/EInkDisplay2.h | 5 ++ src/platform/esp32/architecture.h | 2 + .../heltec_wireless_paper_v1/pins_arduino.h | 78 +++++++++++++++++++ .../heltec_wireless_paper_v1/platformio.ini | 13 ++++ variants/heltec_wireless_paper_v1/variant.h | 54 +++++++++++++ 6 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 variants/heltec_wireless_paper_v1/pins_arduino.h create mode 100644 variants/heltec_wireless_paper_v1/platformio.ini create mode 100644 variants/heltec_wireless_paper_v1/variant.h diff --git a/src/graphics/EInkDisplay2.cpp b/src/graphics/EInkDisplay2.cpp index 787b47e1f7..09ea343e1b 100644 --- a/src/graphics/EInkDisplay2.cpp +++ b/src/graphics/EInkDisplay2.cpp @@ -7,7 +7,7 @@ #include "main.h" #include -#ifdef HELTEC_WIRELESS_PAPER +#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0) SPIClass *hspi = NULL; #endif @@ -48,6 +48,11 @@ SPIClass *hspi = NULL; #elif defined(HELTEC_WIRELESS_PAPER) // #define TECHO_DISPLAY_MODEL GxEPD2_213_T5D #define TECHO_DISPLAY_MODEL GxEPD2_213_FC1 + +#elif defined(HELTEC_WIRELESS_PAPER_V1_0) +// 2.13" 122x250 - DEPG0213BNS800 +#define TECHO_DISPLAY_MODEL GxEPD2_213_BN + #endif GxEPD2_BW *adafruitDisplay; @@ -70,6 +75,17 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY // GxEPD2_154_M09 // setGeometry(GEOMETRY_RAWMODE, 200, 200); +#elif defined(HELTEC_WIRELESS_PAPER_V1_0) + + // The display's memory is actually 128px x 250px + // Setting the buffersize manually prevents 122/8 truncating to a 15 byte width + // (Or something like that..) + + this->geometry = GEOMETRY_RAWMODE; + this->displayWidth = 250; + this->displayHeight = 122; + this->displayBufferSize = 250 * (128 / 8); + #elif defined(HELTEC_WIRELESS_PAPER) // GxEPD2_213_BN - 2.13 inch b/w 250x122 setGeometry(GEOMETRY_RAWMODE, 250, 122); @@ -146,6 +162,8 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit) #elif defined(PCA10059) || defined(M5_COREINK) adafruitDisplay->nextPage(); +#elif defined(HELTEC_WIRELESS_PAPER_V1_0) + adafruitDisplay->nextPage(); #elif defined(HELTEC_WIRELESS_PAPER) adafruitDisplay->nextPage(); #elif defined(PRIVATE_HW) || defined(my) @@ -229,6 +247,43 @@ bool EInkDisplay::connect() (void)adafruitDisplay; } } + +#elif defined(HELTEC_WIRELESS_PAPER_V1_0) + { + // Is this a normal boot, or a wake from deep sleep? + esp_sleep_wakeup_cause_t wakeReason = esp_sleep_get_wakeup_cause(); + + // If waking from sleep, need to reverse rtc_gpio_isolate(), called in cpuDeepSleep() + // Otherwise, SPI won't work + if (wakeReason != ESP_SLEEP_WAKEUP_UNDEFINED) { + // HSPI + other display pins + rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_SCLK); + rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_DC); + rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_RES); + rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_BUSY); + rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_CS); + rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_MOSI); + } + + // Start HSPI + hspi = new SPIClass(HSPI); + hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS + + // Enable VExt (ACTIVE LOW) + // Unsure if called elsewhere first? + delay(100); + pinMode(Vext, OUTPUT); + digitalWrite(Vext, LOW); + delay(100); + + // Create GxEPD2 objects + auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, *hspi); + adafruitDisplay = new GxEPD2_BW(*lowLevel); + + // Init GxEPD2 + adafruitDisplay->init(); + adafruitDisplay->setRotation(3); + } #elif defined(HELTEC_WIRELESS_PAPER) { hspi = new SPIClass(HSPI); diff --git a/src/graphics/EInkDisplay2.h b/src/graphics/EInkDisplay2.h index 2529b1f0e3..7bbf07069a 100644 --- a/src/graphics/EInkDisplay2.h +++ b/src/graphics/EInkDisplay2.h @@ -2,6 +2,11 @@ #include +#if defined(HELTEC_WIRELESS_PAPER_V1_0) +// Re-enable SPI after deep sleep: rtc_gpio_hold_dis() +#include "driver/rtc_io.h" +#endif + /** * An adapter class that allows using the GxEPD2 library as if it was an OLEDDisplay implementation. * diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index e2c5fefbe5..9fa4a5dd7e 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -107,6 +107,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_WSL_V3 #elif defined(HELTEC_WIRELESS_TRACKER) #define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER +#elif defined(HELTEC_WIRELESS_PAPER_V1_0) +#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_PAPER_V1_0 #elif defined(HELTEC_WIRELESS_PAPER) #define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_PAPER #elif defined(TLORA_T3S3_V1) diff --git a/variants/heltec_wireless_paper_v1/pins_arduino.h b/variants/heltec_wireless_paper_v1/pins_arduino.h new file mode 100644 index 0000000000..66d0916914 --- /dev/null +++ b/variants/heltec_wireless_paper_v1/pins_arduino.h @@ -0,0 +1,78 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define WIFI_Kit_32 true +#define DISPLAY_HEIGHT 64 +#define DISPLAY_WIDTH 128 + +#define EXTERNAL_NUM_INTERRUPTS 16 +#define NUM_DIGITAL_PINS 40 +#define NUM_ANALOG_INPUTS 16 + +#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1) +#define digitalPinToInterrupt(p) (((p) < 40) ? (p) : -1) +#define digitalPinHasPWM(p) (p < 34) + +static const uint8_t LED_BUILTIN = 35; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN + +static const uint8_t KEY_BUILTIN = 0; + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +static const uint8_t SDA = 41; +static const uint8_t SCL = 42; + +static const uint8_t SS = 8; +static const uint8_t MOSI = 10; +static const uint8_t MISO = 11; +static const uint8_t SCK = 9; + +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 5; +static const uint8_t A5 = 6; +static const uint8_t A6 = 7; +static const uint8_t A7 = 8; +static const uint8_t A8 = 9; +static const uint8_t A9 = 10; +static const uint8_t A10 = 11; +static const uint8_t A11 = 12; +static const uint8_t A12 = 13; +static const uint8_t A13 = 14; +static const uint8_t A14 = 15; +static const uint8_t A15 = 16; +static const uint8_t A16 = 17; +static const uint8_t A17 = 18; +static const uint8_t A18 = 19; +static const uint8_t A19 = 20; + +static const uint8_t T1 = 1; +static const uint8_t T2 = 2; +static const uint8_t T3 = 3; +static const uint8_t T4 = 4; +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; +static const uint8_t T7 = 7; +static const uint8_t T8 = 8; +static const uint8_t T9 = 9; +static const uint8_t T10 = 10; +static const uint8_t T11 = 11; +static const uint8_t T12 = 12; +static const uint8_t T13 = 13; +static const uint8_t T14 = 14; + +static const uint8_t Vext = 45; +static const uint8_t LED = 18; + +static const uint8_t RST_LoRa = 12; +static const uint8_t BUSY_LoRa = 13; +static const uint8_t DIO0 = 14; + +#endif /* Pins_Arduino_h */ diff --git a/variants/heltec_wireless_paper_v1/platformio.ini b/variants/heltec_wireless_paper_v1/platformio.ini new file mode 100644 index 0000000000..7d7f4eb14f --- /dev/null +++ b/variants/heltec_wireless_paper_v1/platformio.ini @@ -0,0 +1,13 @@ +[env:heltec-wireless-paper-v1_0] +extends = esp32s3_base +board = heltec_wifi_lora_32_V3 +build_flags = + ${esp32s3_base.build_flags} + -I variants/heltec_wireless_paper_v1 + -D HELTEC_WIRELESS_PAPER_V1_0 +lib_deps = + ${esp32s3_base.lib_deps} + https://github.com/meshtastic/GxEPD2/ + adafruit/Adafruit BusIO@^1.13.2 + lewisxhe/PCF8563_Library@^1.0.1 +upload_speed = 115200 \ No newline at end of file diff --git a/variants/heltec_wireless_paper_v1/variant.h b/variants/heltec_wireless_paper_v1/variant.h new file mode 100644 index 0000000000..4daf9a655f --- /dev/null +++ b/variants/heltec_wireless_paper_v1/variant.h @@ -0,0 +1,54 @@ +#define LED_PIN 18 + +// Enable bus for external periherals +#define I2C_SDA SDA +#define I2C_SCL SCL + +#define USE_EINK +/* + * eink display pins + */ +#define PIN_EINK_CS 4 +#define PIN_EINK_BUSY 7 +#define PIN_EINK_DC 5 +#define PIN_EINK_RES 6 +#define PIN_EINK_SCLK 3 +#define PIN_EINK_MOSI 2 + +/* + * SPI interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO 10 // MISO P0.17 +#define PIN_SPI_MOSI 11 // MOSI P0.15 +#define PIN_SPI_SCK 9 // SCK P0.13 + +#define VEXT_ENABLE 45 // active low, powers the oled display and the lora antenna boost +#define BUTTON_PIN 0 + +#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +#define ADC_CHANNEL ADC1_GPIO1_CHANNEL +#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider +#define ADC_MULTIPLIER 4.9 + +#define USE_SX1262 + +#define LORA_DIO0 -1 // a No connect on the SX1262 module +#define LORA_RESET 12 +#define LORA_DIO1 14 // SX1262 IRQ +#define LORA_DIO2 13 // SX1262 BUSY +#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled + +#define LORA_SCK 9 +#define LORA_MISO 11 +#define LORA_MOSI 10 +#define LORA_CS 8 + +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_DIO2 +#define SX126X_RESET LORA_RESET + +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8