From f3351d95903d0beb31435e15d15c21abb87e06a4 Mon Sep 17 00:00:00 2001 From: Milo Winningham Date: Sat, 27 Jan 2024 16:13:24 -0800 Subject: [PATCH] Add T-Display S3 support --- .github/workflows/main.yml | 5 +- .gitignore | 5 +- flash.bat | 2 +- flash.sh | 2 +- platformio.ini | 35 ++++++++++++ setup/firmware/knobby/manifest.json | 2 +- setup/firmware/tdisplay-s3/manifest.json | 15 ++++++ setup/firmware/twatch/manifest.json | 2 +- setup/index.html | 1 + src/main.cpp | 68 ++++++++++++++---------- src/main.h | 2 + 11 files changed, 103 insertions(+), 36 deletions(-) create mode 100644 setup/firmware/tdisplay-s3/manifest.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a5dddf6..b0cc120 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,7 @@ jobs: build: strategy: matrix: - target: [knobby, twatch] + target: [knobby, tdisplay-s3, twatch] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -56,6 +56,7 @@ jobs: cd upload mv ~/artifacts/*/* . unzip -p knobby-firmware.zip firmware.bin > knobby.bin + unzip -p tdisplay-s3-firmware.zip firmware.bin > tdisplay-s3.bin unzip -p twatch-firmware.zip firmware.bin > twatch.bin - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 @@ -75,6 +76,7 @@ jobs: if: github.ref_type == 'tag' run: mv upload/knobby-firmware.zip upload/knobby-firmware-${{ github.ref_name }}.zip; + mv upload/tdisplay-s3-firmware.zip upload/tdisplay-s3-firmware-${{ github.ref_name }}.zip; mv upload/twatch-firmware.zip upload/twatch-firmware-${{ github.ref_name }}.zip; aws s3 cp --metadata "{\"git-version\":\"$(git describe --match="" --dirty --always)\"}" @@ -82,6 +84,7 @@ jobs: upload s3://knobby/firmware/; unzip -d setup/firmware/knobby upload/knobby-firmware-${{ github.ref_name }}.zip; + unzip -d setup/firmware/tdisplay-s3 upload/tdisplay-s3-firmware-${{ github.ref_name }}.zip; unzip -d setup/firmware/twatch upload/twatch-firmware-${{ github.ref_name }}.zip; aws s3 cp --metadata "{\"git-version\":\"$(git describe --match="" --dirty --always)\"}" diff --git a/.gitignore b/.gitignore index 213a586..6801c95 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .piolibdeps .vscode/.browse.c_cpp.db* .vscode/*.json +build/ setup/firmware/*/*.bin -sdkconfig.knobby -sdkconfig.twatch +!sdkconfig.defaults +sdkconfig.* diff --git a/flash.bat b/flash.bat index 1074805..873667d 100755 --- a/flash.bat +++ b/flash.bat @@ -1 +1 @@ -esptool.py --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 ota_data_initial.bin 0x10000 firmware.bin 0x3b0000 spiffs.bin +esptool.py --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 ota_data_initial.bin 0x10000 firmware.bin 0x3b0000 spiffs.bin diff --git a/flash.sh b/flash.sh index f76f8e7..58465d1 100755 --- a/flash.sh +++ b/flash.sh @@ -1,2 +1,2 @@ #!/bin/sh -esptool.py --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 ota_data_initial.bin 0x10000 firmware.bin 0x3b0000 spiffs.bin +esptool.py --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 ota_data_initial.bin 0x10000 firmware.bin 0x3b0000 spiffs.bin diff --git a/platformio.ini b/platformio.ini index 31898f2..549cdac 100644 --- a/platformio.ini +++ b/platformio.ini @@ -72,6 +72,41 @@ build_flags = lib_deps = ${common.lib_deps} +[env:tdisplay-s3] +board = lilygo-t-display-s3 +build_flags = + ${common.build_flags} + -DADC_EN=15 + -DADC_PIN=4 + -DBOARD_HAS_PSRAM=1 + -DCONFIG_IDF_TARGET_ESP32S3=1 + -DROTARY_ENCODER_A_PIN=2 + -DROTARY_ENCODER_B_PIN=3 + -DROTARY_ENCODER_BUTTON_PIN=1 + -DROTARY_ENCODER_PULSE_COUNT=4 + -DUSER_SETUP_LOADED=1 + -DST7789_DRIVER=1 + -DTFT_INVERSION_ON=1 + -DTFT_PARALLEL_8_BIT=1 + -DTFT_WIDTH=170 + -DTFT_HEIGHT=320 + -DTFT_D0=39 + -DTFT_D1=40 + -DTFT_D2=41 + -DTFT_D3=42 + -DTFT_D4=45 + -DTFT_D5=46 + -DTFT_D6=47 + -DTFT_D7=48 + -DTFT_WR=8 + -DTFT_RD=9 + -DTFT_CS=6 + -DTFT_DC=7 + -DTFT_RST=5 + -DTFT_BL=38 +lib_deps = + ${common.lib_deps} + [env:twatch] build_flags = ${common.build_flags} diff --git a/setup/firmware/knobby/manifest.json b/setup/firmware/knobby/manifest.json index 6784a86..a7c913d 100644 --- a/setup/firmware/knobby/manifest.json +++ b/setup/firmware/knobby/manifest.json @@ -1,6 +1,6 @@ { "name": "knobby", - "version": "2024.01.01", + "version": "2024.01.27", "builds": [ { "chipFamily": "ESP32", diff --git a/setup/firmware/tdisplay-s3/manifest.json b/setup/firmware/tdisplay-s3/manifest.json new file mode 100644 index 0000000..6e250c7 --- /dev/null +++ b/setup/firmware/tdisplay-s3/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "knobby", + "version": "2024.01.27", + "builds": [ + { + "chipFamily": "ESP32-S3", + "parts": [ + { "path": "bootloader.bin", "offset": 4096 }, + { "path": "partitions.bin", "offset": 32768 }, + { "path": "ota_data_initial.bin", "offset": 57344 }, + { "path": "firmware.bin", "offset": 65536 } + ] + } + ] +} diff --git a/setup/firmware/twatch/manifest.json b/setup/firmware/twatch/manifest.json index 6784a86..a7c913d 100644 --- a/setup/firmware/twatch/manifest.json +++ b/setup/firmware/twatch/manifest.json @@ -1,6 +1,6 @@ { "name": "knobby", - "version": "2024.01.01", + "version": "2024.01.27", "builds": [ { "chipFamily": "ESP32", diff --git a/setup/index.html b/setup/index.html index 1d97195..eaa9044 100644 --- a/setup/index.html +++ b/setup/index.html @@ -63,6 +63,7 @@

knobby setup

diff --git a/src/main.cpp b/src/main.cpp index 83f739d..873df9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,12 +30,7 @@ void setup() { knobby.setup(); rtc_gpio_hold_dis((gpio_num_t)ROTARY_ENCODER_BUTTON_PIN); - esp_pm_config_esp32_t pm_config_ls_enable = { - .max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, - .min_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, - .light_sleep_enable = true - }; - ESP_ERROR_CHECK(esp_pm_configure(&pm_config_ls_enable)); + setLightSleepEnabled(true); ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MAX_MODEM)); #ifdef LILYGO_WATCH_2019_WITH_TOUCH @@ -56,9 +51,9 @@ void setup() { ttgo->power->setPowerOutPut(AXP202_LDO3, AXP202_OFF); ttgo->power->setPowerOutPut(AXP202_LDO4, AXP202_OFF); #else - ledcSetup(TFT_BL, 12000, 8); - ledcAttachPin(TFT_BL, TFT_BL); - ledcWrite(TFT_BL, 255); + ledcSetup(backlightChannel, 12000, 8); + ledcAttachPin(TFT_BL, backlightChannel); + ledcWrite(backlightChannel, 255); tft.init(); tft.fillScreen(TFT_BLACK); #endif @@ -366,6 +361,23 @@ void setup() { if (knobby.powerStatus() == PowerStatusPowered) knobby.printHeader(); } +void setLightSleepEnabled(bool enabled) { +#ifdef CONFIG_IDF_TARGET_ESP32S3 + esp_pm_config_esp32s3_t pm_config_ls_enable = { + .max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ, + .min_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ, + .light_sleep_enable = enabled + }; +#else + esp_pm_config_esp32_t pm_config_ls_enable = { + .max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, + .min_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, + .light_sleep_enable = enabled + }; +#endif + ESP_ERROR_CHECK(esp_pm_configure(&pm_config_ls_enable)); +} + void setupKnob() { ESP32Encoder::useInternalWeakPullResistors = UP; knob = ESP32Encoder(); @@ -434,12 +446,7 @@ void loop() { #else ledcDetachPin(TFT_BL); digitalWrite(TFT_BL, HIGH); - esp_pm_config_esp32_t pm_config_ls_enable = { - .max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, - .min_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, - .light_sleep_enable = true - }; - ESP_ERROR_CHECK(esp_pm_configure(&pm_config_ls_enable)); + setLightSleepEnabled(true); #endif } else if (inputDelta > inactivityMillis + 2 * inactivityFadeOutMillis) { startDeepSleep(); @@ -452,18 +459,13 @@ void loop() { #endif uint32_t duty = min(max((int)round(fadeProgress * 255.0), minimumDuty), 255); if (duty >= 250) { - esp_pm_config_esp32_t pm_config_ls_enable = { - .max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, - .min_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, - .light_sleep_enable = false - }; - ESP_ERROR_CHECK(esp_pm_configure(&pm_config_ls_enable)); + setLightSleepEnabled(false); } #ifdef LILYGO_WATCH_2019_WITH_TOUCH ttgo->setBrightness(duty); #else - if (duty >= 250) ledcAttachPin(TFT_BL, TFT_BL); - ledcWrite(TFT_BL, duty); + if (duty >= 250) ledcAttachPin(TFT_BL, backlightChannel); + ledcWrite(backlightChannel, duty); #endif } else if (menuMode == VolumeControl && inputDelta > menuTimeoutMillis) { setMenuMode(NowPlaying, VolumeButton); @@ -1407,13 +1409,19 @@ void drawDeviceMenu() { } void drawVolumeControl() { - const uint8_t x = 10; - const uint8_t y = 30; - const uint8_t width = 220; - img.createSprite(width, 40); + const auto x = 10; + const auto y = 30; + const auto padding = 4; + const auto outerRadius = 5; + const auto outerWidth = screenWidth - x * 2; + const auto outerHeight = 32; + const auto innerRadius = 3; + const auto innerWidth = outerWidth - padding * 2; + const auto innerHeight = outerHeight - padding * 2; + img.createSprite(outerWidth, 40); img.fillSprite(TFT_BLACK); - img.drawRoundRect(0, 0, width, 32, 5, TFT_WHITE); - img.fillRoundRect(4, 4, round(2.12 * menuIndex), 24, 3, TFT_DARKGREY); + img.drawRoundRect(0, 0, outerWidth, outerHeight, outerRadius, TFT_WHITE); + img.fillRoundRect(padding, padding, round(0.01 * menuIndex * innerWidth), innerHeight, innerRadius, TFT_DARKGREY); img.pushSprite(x, y); img.deleteSprite(); @@ -2122,9 +2130,11 @@ void startDeepSleep() { struct timeval tod; gettimeofday(&tod, NULL); lastSleepSeconds = tod.tv_sec; +#ifndef CONFIG_IDF_TARGET_ESP32S3 rtc_gpio_isolate(GPIO_NUM_0); // button 1 rtc_gpio_isolate(GPIO_NUM_35); // button 2 rtc_gpio_isolate(GPIO_NUM_39); +#endif esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); esp_sleep_enable_ext0_wakeup((gpio_num_t)ROTARY_ENCODER_BUTTON_PIN, LOW); #if CORE_DEBUG_LEVEL < ARDUHAL_LOG_LEVEL_DEBUG diff --git a/src/main.h b/src/main.h index 7f1cc21..06a56a2 100644 --- a/src/main.h +++ b/src/main.h @@ -235,6 +235,7 @@ bool contains(C&& c, T e) { const char *hostname = "knobby"; const char *rootMenuItems[] = {"settings", "countries", "genres", "explore", "playlists", "now playing", "users", "devices"}; const char *settingsMenuItems[] = {"about", "update", "orientation", "add user", "log out", "reset settings"}; +const uint8_t backlightChannel = 4; const int screenWidth = TFT_HEIGHT; const int screenHeight = TFT_WIDTH; const int centerX = screenWidth / 2; @@ -458,6 +459,7 @@ void playMenuPlaylist(MenuModes mode, uint16_t index); void playUri(const char *uri, const char *name); void setActiveDevice(SpotifyDevice_t *device); void setActiveUser(SpotifyUser_t *user); +void setLightSleepEnabled(bool enabled); void setMenuIndex(uint16_t newMenuIndex); void setMenuMode(MenuModes newMode, uint16_t newMenuIndex); void setStatusMessage(const char *message, unsigned long durationMs = statusMessageMillis);