Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions devtool.toml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ needs_boot_mode = true
port_changes_on_reset = true
group = "OLED Display"

[boards.waveshare-s3-lcd183]
name = "Waveshare ESP32-S3-Touch-LCD-1.83"
env = "waveshare-s3-lcd183"
chip = "esp32s3"
description = "ESP32-S3 with 1.83\" ST7789P 240x284, AXP2101 PMU, CST816D touch"
needs_boot_mode = true
port_changes_on_reset = true
group = "ESP32-S3 Display"

[boards.wireless-paper]
name = "Heltec Wireless Paper"
env = "wireless-paper"
Expand Down
48 changes: 48 additions & 0 deletions include/board_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,54 @@

// SHA Implementation: Defined in platformio.ini (USE_HARDWARE_SHA=1)

// ============================================================
// Waveshare ESP32-S3-Touch-LCD-1.83
// 240x284 ST7789P, CST816D touch, AXP2101 PMU
// ============================================================
#elif defined(WAVESHARE_S3_LCD183)
#define BOARD_NAME "Waveshare-S3-LCD-1.83"

#ifndef USE_DISPLAY
#define USE_DISPLAY 1
#endif
#define DISPLAY_TYPE_TFT 1

#ifdef TFT_WIDTH
#undef TFT_WIDTH
#endif
#define TFT_WIDTH 240

#ifdef TFT_HEIGHT
#undef TFT_HEIGHT
#endif
#define TFT_HEIGHT 284

// Backlight
#ifndef TFT_BL_PIN
#define TFT_BL_PIN 40
#endif

// No physical button on this board
#ifndef BUTTON_PIN
#define BUTTON_PIN -1
#endif
#define BUTTON_ACTIVE_LOW 1

// AXP2101 PMU
#define HAS_AXP2101 1
#define AXP2101_I2C_ADDR 0x34
#define AXP2101_SDA_PIN 15
#define AXP2101_SCL_PIN 14

// Touch (CST816D on same I2C bus)
#define TOUCH_SDA_PIN 15
#define TOUCH_SCL_PIN 14
#define TOUCH_RST_PIN 39
#define TOUCH_INT_PIN 13
#define TOUCH_I2C_ADDR 0x15

// SHA Implementation: Defined in platformio.ini (USE_HARDWARE_SHA=1)

// ============================================================
// ESP32-S3 DevKit - Hardware SHA (headless)
// ============================================================
Expand Down
74 changes: 73 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
; Monitor: pio device monitor

[platformio]
default_envs = esp32-2432s028
default_envs = waveshare-s3-lcd183

[env]
platform = espressif32@6.6.0
Expand Down Expand Up @@ -681,6 +681,78 @@ lib_ignore =
SD_MMC
FastLED

; ============================================================
; Waveshare ESP32-S3-Touch-LCD-1.83
; 240x284 ST7789P SPI, CST816D touch, AXP2101 PMU
; ESP32-S3R8 (8MB PSRAM, 16MB Flash)
; ============================================================
[env:waveshare-s3-lcd183]
board = esp32-s3-devkitc-1
board_build.partitions = default_16MB.csv
board_build.mcu = esp32s3
board_build.f_cpu = 240000000L
board_build.arduino.memory_type = qio_opi
board_build.flash_mode = qio
board_upload.flash_size = 16MB
upload_speed = 921600

build_unflags = -Os

build_flags =
-D AUTO_VERSION=\"v2.9.5\"
-D WAVESHARE_S3_LCD183=1
-D USE_HARDWARE_SHA=1
-D BOARD_HAS_PSRAM
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1
-D USE_DISPLAY=1
; Optimization
-O3
-funroll-loops
; ===== TFT_eSPI Configuration (SPI) =====
-D USER_SETUP_LOADED=1
-D ST7789_DRIVER=1
-D TFT_WIDTH=240
-D TFT_HEIGHT=284
-D TFT_INVERSION_ON=1
-D TFT_RGB_ORDER=TFT_RGB
; SPI Pins (Waveshare BSP pinout)
-D TFT_MOSI=7
-D TFT_SCLK=6
-D TFT_CS=5
-D TFT_DC=4
-D TFT_RST=38
-D TFT_MISO=-1
-D TFT_BL=40
-D TFT_BACKLIGHT_ON=HIGH
; SPI speed (match BSP 24MHz for reliability)
-D SPI_FREQUENCY=24000000
-D SPI_READ_FREQUENCY=6000000
; Fonts
-D LOAD_GLCD=1
-D LOAD_FONT2=1
-D LOAD_FONT4=1
-D LOAD_GFXFF=1
-D SMOOTH_FONT=1
; No physical button - use touch or serial
-D BUTTON_PIN=-1
; AXP2101 PMU
-D HAS_AXP2101=1
-D AXP2101_SDA=15
-D AXP2101_SCL=14
;-D DEBUG_MINING=1

lib_deps =
${env.lib_deps}
https://github.com/takkaO/OpenFontRender#v1.2
bodmer/TFT_eSPI@^2.5.43

lib_ignore =
SD
SD_MMC
XPT2046_Touchscreen
FastLED

; ============================================================
; ESP32-S3 Headless - No display, serial only
; Dual-core with monochrome display and LoRa
Expand Down
10 changes: 10 additions & 0 deletions src/display/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
#define LCD_BL_PIN 4
#endif

// Waveshare ESP32-S3-Touch-LCD-1.83 (240x284, SPI)
#if defined(WAVESHARE_S3_LCD183)
#define LCD_BL_PIN 40
#endif

// PWM settings for backlight
#define LEDC_CHANNEL 0
#define LEDC_FREQ 5000
Expand Down Expand Up @@ -75,6 +80,11 @@
#define LINE_HEIGHT 18
#define HEADER_HEIGHT 30
#define SMALL_DISPLAY 1
#elif defined(WAVESHARE_S3_LCD183)
#define MARGIN 6
#define LINE_HEIGHT 18
#define HEADER_HEIGHT 30
#define SMALL_DISPLAY 1
#else
#define MARGIN 10
#define LINE_HEIGHT 22
Expand Down
53 changes: 46 additions & 7 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,40 @@ extern "C" {
#include "stats/monitor.h"
#include "display/display.h"

// AXP2101 PMU support for Waveshare board
#if defined(HAS_AXP2101)
#include <Wire.h>
#define AXP2101_ADDR 0x34

static void axp2101_write(uint8_t reg, uint8_t val) {
Wire1.beginTransmission(AXP2101_ADDR);
Wire1.write(reg);
Wire1.write(val);
Wire1.endTransmission();
}

static uint8_t axp2101_read(uint8_t reg) {
Wire1.beginTransmission(AXP2101_ADDR);
Wire1.write(reg);
Wire1.endTransmission(false);
Wire1.requestFrom((uint8_t)AXP2101_ADDR, (uint8_t)1);
return Wire1.available() ? Wire1.read() : 0;
}

static void axp2101_init() {
Wire1.begin(AXP2101_SDA, AXP2101_SCL, 400000);
delay(10);

// Enable fuel gauge (battery percentage register 0xA4)
uint8_t fuel_cfg = axp2101_read(0xA2);
axp2101_write(0xA2, fuel_cfg | 0x40);

// Read battery percentage to verify
uint8_t batt = axp2101_read(0xA4);
Serial.printf("[AXP2101] PMU initialized, battery: %d%%\n", batt);
}
#endif

// Task handles
TaskHandle_t miner0Task = NULL;
TaskHandle_t miner1Task = NULL;
Expand All @@ -46,7 +80,7 @@ TaskHandle_t buttonTask = NULL;
volatile bool systemReady = false;

// Button handling (OneButton)
#if defined(BUTTON_PIN) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
#if defined(BUTTON_PIN) && (BUTTON_PIN >= 0) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
OneButton button(BUTTON_PIN, true, true); // active low, enable pullup

// Single click: wake screen if off, otherwise cycle screens
Expand Down Expand Up @@ -139,7 +173,7 @@ void onButtonLongPressStart() {
}
#endif

#if defined(BUTTON_PIN) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
#if defined(BUTTON_PIN) && (BUTTON_PIN >= 0) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
/**
* Dedicated button handling task (with display)
* Runs at higher priority than mining to ensure responsive UI
Expand All @@ -152,7 +186,7 @@ void button_task(void *param) {
}
}

#elif defined(BUTTON_PIN)
#elif defined(BUTTON_PIN) && (BUTTON_PIN >= 0)
/**
* Headless button handling task
* Simple long-press detection for factory reset (no OneButton/display dependencies)
Expand Down Expand Up @@ -277,7 +311,7 @@ uint32_t tryOverclock() {
* Hold BOOT button for 5+ seconds to wipe NVS and restart
*/
void checkFactoryReset() {
#ifdef BUTTON_PIN
#if defined(BUTTON_PIN) && (BUTTON_PIN >= 0)
pinMode(BUTTON_PIN, INPUT_PULLUP);

// Check if button is pressed at boot
Expand Down Expand Up @@ -381,14 +415,19 @@ void setup() {
stratum_set_backup_pool(config->backupPoolUrl, config->backupPoolPort,
config->backupWallet, config->backupPoolPassword, config->workerName);

// Initialize AXP2101 PMU (Waveshare board - must be before display)
#if defined(HAS_AXP2101)
axp2101_init();
#endif

// Initialize display early (needed for WiFi setup screen)
#if (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
display_init(config->rotation, config->brightness);
display_set_inverted(config->invertColors);
#endif

// Setup button handlers (OneButton)
#if defined(BUTTON_PIN) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
#if defined(BUTTON_PIN) && (BUTTON_PIN >= 0) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
button.setClickMs(400); // Time window for single click (ms)
button.setPressMs(1500); // Time for long press to start (1.5s)
button.setDebounceMs(50); // Debounce time (ms)
Expand Down Expand Up @@ -511,7 +550,7 @@ void setupTasks() {

// Button task (responsive UI during mining)
// Needs 4KB+ stack for NVS writes (rotation save) and display updates
#if defined(BUTTON_PIN) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
#if defined(BUTTON_PIN) && (BUTTON_PIN >= 0) && (USE_DISPLAY || USE_OLED_DISPLAY || USE_EINK_DISPLAY)
xTaskCreatePinnedToCore(
button_task,
"Button",
Expand All @@ -521,7 +560,7 @@ void setupTasks() {
&buttonTask,
0 // Core 0 with other UI tasks
);
#elif defined(BUTTON_PIN)
#elif defined(BUTTON_PIN) && (BUTTON_PIN >= 0)
// Headless button task for factory reset (Issue #15 fix)
xTaskCreatePinnedToCore(
button_task,
Expand Down