Clean up RFP ESP32-S3 target and tooling
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,8 +5,11 @@
|
|||||||
.gitignore
|
.gitignore
|
||||||
.idea
|
.idea
|
||||||
.pio
|
.pio
|
||||||
|
.piohome
|
||||||
.pioenvs
|
.pioenvs
|
||||||
.piolibdeps
|
.piolibdeps
|
||||||
|
.tools
|
||||||
|
.venv
|
||||||
.vscode
|
.vscode
|
||||||
.vscode/extensions.json
|
.vscode/extensions.json
|
||||||
|
|
||||||
|
|||||||
64
docs/rfp-esp32s3-wroom1-n16r8-3x106.md
Normal file
64
docs/rfp-esp32s3-wroom1-n16r8-3x106.md
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# RFP ESP32-S3 WROOM-1 N16R8 (3 x 106)
|
||||||
|
|
||||||
|
This repository includes a tracked PlatformIO target for the RFP ESP32-S3 WROOM-1 N16R8 nodes with three LED outputs and 106 pixels per output.
|
||||||
|
|
||||||
|
Build target:
|
||||||
|
|
||||||
|
- `rfp_esp32s3_wroom1_n16r8_3x106`
|
||||||
|
|
||||||
|
Default output pins:
|
||||||
|
|
||||||
|
- Output 1: `GPIO4`
|
||||||
|
- Output 2: `GPIO5`
|
||||||
|
- Output 3: `GPIO6`
|
||||||
|
|
||||||
|
Pins intentionally avoided:
|
||||||
|
|
||||||
|
- `GPIO0`, `GPIO3`, `GPIO45`, `GPIO46` for boot / strapping
|
||||||
|
- `GPIO19`, `GPIO20` for USB
|
||||||
|
- `GPIO33` to `GPIO37` because they are reserved by octal PSRAM / flash on `N16R8`
|
||||||
|
- `GPIO48` because it is used as the onboard status pixel
|
||||||
|
|
||||||
|
Build:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python -m platformio run -e rfp_esp32s3_wroom1_n16r8_3x106
|
||||||
|
```
|
||||||
|
|
||||||
|
Build and upload:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\tools\flash_rfp_s3.ps1 -ComPort COM7
|
||||||
|
```
|
||||||
|
|
||||||
|
Build only with the helper script:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\tools\flash_rfp_s3.ps1 -BuildOnly
|
||||||
|
```
|
||||||
|
|
||||||
|
Local Wi-Fi defaults:
|
||||||
|
|
||||||
|
- Keep SSID and password in the ignored file `wled00/my_config.h`.
|
||||||
|
- If the file does not exist yet, create it with your local values:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CLIENT_SSID "your-ssid"
|
||||||
|
#define CLIENT_PASS "your-password"
|
||||||
|
```
|
||||||
|
|
||||||
|
Important:
|
||||||
|
|
||||||
|
- The `3 x 106` bus layout is used as the default when the device has no saved `cfg.json`.
|
||||||
|
- If a board already has a saved WLED config, do a factory reset or erase settings once so the default bus layout is recreated.
|
||||||
|
|
||||||
|
Onboard status pixel on `GPIO48`:
|
||||||
|
|
||||||
|
- `green blinking`: DDP realtime active
|
||||||
|
- `green solid`: network connected
|
||||||
|
- `blue blinking`: AP / setup mode active
|
||||||
|
- `red fast blinking`: Wi-Fi configured but currently disconnected
|
||||||
|
- `amber fast blinking`: network connected, MQTT configured, but MQTT not connected
|
||||||
|
- `off`: idle / no status to show
|
||||||
@@ -107,6 +107,7 @@ default_envs =
|
|||||||
;; === esp32-S3 === with 16MB flash
|
;; === esp32-S3 === with 16MB flash
|
||||||
esp32S3_16MB_PSRAM_M_HUB75 ;; for S3 with 16MB flash, HUB75 supported (MOONHUB HUB75 adapter board)
|
esp32S3_16MB_PSRAM_M_HUB75 ;; for S3 with 16MB flash, HUB75 supported (MOONHUB HUB75 adapter board)
|
||||||
esp32S3_WROOM-2_M ;; for S3 WROOM-2; HUB75 supported
|
esp32S3_WROOM-2_M ;; for S3 WROOM-2; HUB75 supported
|
||||||
|
; rfp_esp32s3_wroom1_n16r8_3x106 ;; RFP ESP32-S3 WROOM-1 N16R8, 3x106 pixels on GPIO 4/5/6
|
||||||
;;
|
;;
|
||||||
;; === esp32-S2 boards ===
|
;; === esp32-S2 boards ===
|
||||||
esp32s2_PSRAM_S ;; OTA-compatible with upstream
|
esp32s2_PSRAM_S ;; OTA-compatible with upstream
|
||||||
@@ -2438,6 +2439,32 @@ build_flags = ${env:esp32S3_8MB_PSRAM_M_opi.build_flags}
|
|||||||
[env:esp32S3_8MB_PSRAM_M] ;; legacy alias
|
[env:esp32S3_8MB_PSRAM_M] ;; legacy alias
|
||||||
extends = env:esp32S3_8MB_PSRAM_M_opi
|
extends = env:esp32S3_8MB_PSRAM_M_opi
|
||||||
|
|
||||||
|
[env:rfp_esp32s3_wroom1_n16r8_3x106]
|
||||||
|
;; RFP ESP32-S3 WROOM-1 N16R8, 16MB flash / 8MB OPI PSRAM, 3 outputs x 106 pixels
|
||||||
|
extends = env:esp32S3_8MB_PSRAM_M_opi
|
||||||
|
board_upload.flash_size = 16MB
|
||||||
|
board_upload.maximum_size = 16777216
|
||||||
|
board_build.partitions = tools/WLED_ESP32_16MB.csv
|
||||||
|
build_unflags = ${env:esp32S3_8MB_PSRAM_M_opi.build_unflags}
|
||||||
|
-D WLED_RELEASE_NAME=esp32S3_8MB_PSRAM_M_opi
|
||||||
|
-D LEDPIN=21
|
||||||
|
-D BTNPIN=0
|
||||||
|
-D RLYPIN=1
|
||||||
|
-D IRPIN=-1
|
||||||
|
-D AUDIOPIN=-1
|
||||||
|
build_flags = ${env:esp32S3_8MB_PSRAM_M_opi.build_flags}
|
||||||
|
-D WLED_RELEASE_NAME=RFP_ESP32S3_N16R8_3x106
|
||||||
|
-D LEDPIN=4
|
||||||
|
-D DATA_PINS=4,5,6
|
||||||
|
-D PIXEL_COUNTS=106,106,106
|
||||||
|
-D DEFAULT_LED_COUNT=106
|
||||||
|
-D STATUSPIXELPIN=48
|
||||||
|
-D STATUSPIXELCOLORORDER=COL_ORDER_GRB
|
||||||
|
-D BTNPIN=-1
|
||||||
|
-D RLYPIN=-1
|
||||||
|
-D IRPIN=-1
|
||||||
|
-D AUDIOPIN=-1
|
||||||
|
|
||||||
[env:esp32S3_8MB_S]
|
[env:esp32S3_8MB_S]
|
||||||
;; MM for ESP32-S3 boards - FASTPATH + optimize for speed; ; HUB75 support included (may still have pin conflicts)
|
;; MM for ESP32-S3 boards - FASTPATH + optimize for speed; ; HUB75 support included (may still have pin conflicts)
|
||||||
extends = esp32_4MB_V4_M_base
|
extends = esp32_4MB_V4_M_base
|
||||||
|
|||||||
44
tools/flash_rfp_s3.ps1
Normal file
44
tools/flash_rfp_s3.ps1
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
param(
|
||||||
|
[string]$ComPort,
|
||||||
|
|
||||||
|
[switch]$BuildOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
$repoRoot = Split-Path -Parent $scriptDir
|
||||||
|
$envName = "rfp_esp32s3_wroom1_n16r8_3x106"
|
||||||
|
$venvPython = Join-Path $repoRoot ".venv\Scripts\python.exe"
|
||||||
|
|
||||||
|
if (-not $BuildOnly -and [string]::IsNullOrWhiteSpace($ComPort)) {
|
||||||
|
throw "ComPort is required unless -BuildOnly is used."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path $venvPython) {
|
||||||
|
$pythonCommand = $venvPython
|
||||||
|
$pythonArgs = @()
|
||||||
|
} elseif (Get-Command py -ErrorAction SilentlyContinue) {
|
||||||
|
$pythonCommand = "py"
|
||||||
|
$pythonArgs = @("-3")
|
||||||
|
} elseif (Get-Command python -ErrorAction SilentlyContinue) {
|
||||||
|
$pythonCommand = "python"
|
||||||
|
$pythonArgs = @()
|
||||||
|
} else {
|
||||||
|
throw "No Python runtime found. Install Python or create .venv first."
|
||||||
|
}
|
||||||
|
|
||||||
|
$pioHome = Join-Path $repoRoot ".piohome"
|
||||||
|
$env:PLATFORMIO_CORE_DIR = $pioHome
|
||||||
|
$env:PLATFORMIO_PACKAGES_DIR = Join-Path $pioHome "packages"
|
||||||
|
$env:PLATFORMIO_PLATFORMS_DIR = Join-Path $pioHome "platforms"
|
||||||
|
$env:PLATFORMIO_CACHE_DIR = Join-Path $pioHome ".cache"
|
||||||
|
$env:PLATFORMIO_BUILD_CACHE_DIR = Join-Path $pioHome "buildcache"
|
||||||
|
|
||||||
|
$args = @("-m", "platformio", "run", "-e", $envName)
|
||||||
|
if (-not $BuildOnly) {
|
||||||
|
$args += @("-t", "upload", "--upload-port", $ComPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
& $pythonCommand @pythonArgs @args
|
||||||
|
exit $LASTEXITCODE
|
||||||
@@ -168,6 +168,9 @@ String PinManagerClass::getPinSpecialText(int gpio) { // special purpose PIN in
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(STATUSPIXELPIN)
|
||||||
|
if (gpio == STATUSPIXELPIN) return(F("WLED Status Pixel"));
|
||||||
|
#endif
|
||||||
#if defined(STATUSLED)
|
#if defined(STATUSLED)
|
||||||
if (gpio == STATUSLED) return(F("WLED Status LED"));
|
if (gpio == STATUSLED) return(F("WLED Status LED"));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
171
wled00/wled.cpp
171
wled00/wled.cpp
@@ -71,6 +71,73 @@
|
|||||||
#endif
|
#endif
|
||||||
// WLEDMM end
|
// WLEDMM end
|
||||||
|
|
||||||
|
#if defined(STATUSLED) || defined(STATUSPIXELPIN)
|
||||||
|
static inline void writeStatusIndicator(uint32_t color) {
|
||||||
|
#if defined(STATUSPIXELPIN)
|
||||||
|
if (statusPixelBus != nullptr) {
|
||||||
|
if (statusPixelBus->canShow()) {
|
||||||
|
statusPixelBus->setPixelColor(0, color);
|
||||||
|
statusPixelBus->show();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STATUSLED)
|
||||||
|
#if STATUSLED >= 0
|
||||||
|
#ifdef STATUSLEDINVERTED
|
||||||
|
digitalWrite(STATUSLED, color ? LOW : HIGH);
|
||||||
|
#else
|
||||||
|
digitalWrite(STATUSLED, color ? HIGH : LOW);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
busses.setStatusPixel(color);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STATUSPIXELPIN)
|
||||||
|
#ifndef STATUSPIXELCOLORORDER
|
||||||
|
#define STATUSPIXELCOLORORDER COL_ORDER_GRB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void initStatusPixelBus() {
|
||||||
|
if (statusPixelBus != nullptr) return;
|
||||||
|
if (pinManager.isPinAllocated(STATUSPIXELPIN)) {
|
||||||
|
USER_PRINTF("Skipping status pixel on GPIO %u because the pin is already in use.\n", STATUSPIXELPIN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
|
constexpr uint8_t maxStatusPixelBusses = 4;
|
||||||
|
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
|
constexpr uint8_t maxStatusPixelBusses = 2;
|
||||||
|
#else
|
||||||
|
constexpr uint8_t maxStatusPixelBusses = 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t busIndex = busses.getNumBusses();
|
||||||
|
if (busIndex >= maxStatusPixelBusses) {
|
||||||
|
USER_PRINTLN(F("Skipping status pixel because no free hardware LED channel is left."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t pins[] = {STATUSPIXELPIN};
|
||||||
|
BusConfig statusCfg(TYPE_WS2812_RGB, pins, 0, 1, STATUSPIXELCOLORORDER, false, 0, RGBW_MODE_MANUAL_ONLY);
|
||||||
|
statusPixelBus = new BusDigital(statusCfg, busIndex, busses.getColorOrderMap());
|
||||||
|
if (statusPixelBus == nullptr || !statusPixelBus->isOk()) {
|
||||||
|
delete statusPixelBus;
|
||||||
|
statusPixelBus = nullptr;
|
||||||
|
USER_PRINTLN(F("Failed to initialize onboard status pixel."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusPixelBus->setBrightness(255, true);
|
||||||
|
writeStatusIndicator(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if INCLUDE_xTaskGetHandle && defined(ARDUINO_ARCH_ESP32) && (defined(WLED_DEBUG) || defined(WLED_DEBUG_HEAP))
|
#if INCLUDE_xTaskGetHandle && defined(ARDUINO_ARCH_ESP32) && (defined(WLED_DEBUG) || defined(WLED_DEBUG_HEAP))
|
||||||
// WLEDMM stack debug tool - find async_tcp task, and queries it's free stack
|
// WLEDMM stack debug tool - find async_tcp task, and queries it's free stack
|
||||||
@@ -883,6 +950,9 @@ void WLED::setup()
|
|||||||
|
|
||||||
DEBUG_PRINTLN(F("Initializing strip"));
|
DEBUG_PRINTLN(F("Initializing strip"));
|
||||||
beginStrip();
|
beginStrip();
|
||||||
|
#if defined(STATUSPIXELPIN)
|
||||||
|
initStatusPixelBus();
|
||||||
|
#endif
|
||||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(getFreeHeapSize());
|
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(getFreeHeapSize());
|
||||||
|
|
||||||
USER_PRINTLN(F("\nUsermods setup ..."));
|
USER_PRINTLN(F("\nUsermods setup ..."));
|
||||||
@@ -1568,58 +1638,79 @@ void WLED::handleConnection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If status LED pin is allocated for other uses, does nothing
|
// If status LED pin is allocated for other uses, does nothing
|
||||||
// else blink at 1Hz when WLED_CONNECTED is false (no WiFi, ?? no Ethernet ??)
|
// green blink = DDP realtime active
|
||||||
// else blink at 2Hz when MQTT is enabled but not connected
|
// blue blink = AP active
|
||||||
// else turn the status LED off
|
// green solid = network connected
|
||||||
|
// amber fast blink = MQTT configured but disconnected
|
||||||
|
// red fast blink = WiFi configured but currently disconnected
|
||||||
|
// off = idle / no status to show
|
||||||
void WLED::handleStatusLED()
|
void WLED::handleStatusLED()
|
||||||
{
|
{
|
||||||
#if defined(STATUSLED)
|
#if defined(STATUSLED) || defined(STATUSPIXELPIN)
|
||||||
[[maybe_unused]] uint32_t c = 0;
|
uint32_t c = 0;
|
||||||
|
uint8_t nextType = 0;
|
||||||
|
uint16_t blinkIntervalMs = 0;
|
||||||
|
|
||||||
#if STATUSLED>=0
|
#if defined(STATUSLED) && STATUSLED>=0
|
||||||
if (pinManager.isPinAllocated(STATUSLED)) {
|
if (pinManager.isPinAllocated(STATUSLED)) {
|
||||||
return; //lower priority if something else uses the same pin
|
return; //lower priority if something else uses the same pin
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (WLED_CONNECTED) {
|
if (realtimeMode == REALTIME_MODE_DDP) {
|
||||||
c = RGBW32(0,255,0,0);
|
c = RGBW32(0,255,0,0);
|
||||||
ledStatusType = 2;
|
nextType = 2;
|
||||||
} else if (WLED_MQTT_CONNECTED) {
|
blinkIntervalMs = 250;
|
||||||
c = RGBW32(0,128,0,0);
|
|
||||||
ledStatusType = 4;
|
|
||||||
} else if (apActive) {
|
} else if (apActive) {
|
||||||
c = RGBW32(0,0,255,0);
|
c = RGBW32(0,0,255,0);
|
||||||
ledStatusType = 1;
|
nextType = 2;
|
||||||
}
|
blinkIntervalMs = 500;
|
||||||
if (ledStatusType) {
|
} else if (WLED_CONNECTED) {
|
||||||
if (millis() - ledStatusLastMillis >= (1000/ledStatusType)) {
|
#ifndef WLED_DISABLE_MQTT
|
||||||
ledStatusLastMillis = millis();
|
if (mqttEnabled && mqttServer[0] != 0 && !WLED_MQTT_CONNECTED) {
|
||||||
#if 1
|
c = RGBW32(255,96,0,0);
|
||||||
// WLEDMM un-comment this to stop the blinking
|
nextType = 3;
|
||||||
if ((ledStatusType != 2) && (ledStatusType != 4))
|
blinkIntervalMs = 250;
|
||||||
ledStatusState = !ledStatusState;
|
} else
|
||||||
else
|
|
||||||
ledStatusState = HIGH;
|
|
||||||
#else
|
|
||||||
ledStatusState = !ledStatusState;
|
|
||||||
#endif
|
|
||||||
#if STATUSLED>=0
|
|
||||||
digitalWrite(STATUSLED, ledStatusState);
|
|
||||||
#else
|
|
||||||
busses.setStatusPixel(ledStatusState ? c : 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#if STATUSLED>=0
|
|
||||||
#ifdef STATUSLEDINVERTED
|
|
||||||
digitalWrite(STATUSLED, HIGH);
|
|
||||||
#else
|
|
||||||
digitalWrite(STATUSLED, LOW);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
busses.setStatusPixel(0);
|
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
c = RGBW32(0,255,0,0);
|
||||||
|
nextType = 1;
|
||||||
|
}
|
||||||
|
} else if (WLED_WIFI_CONFIGURED) {
|
||||||
|
c = RGBW32(255,0,0,0);
|
||||||
|
nextType = 3;
|
||||||
|
blinkIntervalMs = 250;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextType != ledStatusType) {
|
||||||
|
ledStatusType = nextType;
|
||||||
|
ledStatusLastMillis = millis();
|
||||||
|
ledStatusState = (nextType == 1);
|
||||||
|
writeStatusIndicator(ledStatusState ? c : 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextType == 0) {
|
||||||
|
if (ledStatusState) {
|
||||||
|
ledStatusState = false;
|
||||||
|
writeStatusIndicator(0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextType == 1) {
|
||||||
|
if (!ledStatusState) {
|
||||||
|
ledStatusState = true;
|
||||||
|
writeStatusIndicator(c);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (millis() - ledStatusLastMillis >= blinkIntervalMs) {
|
||||||
|
ledStatusLastMillis = millis();
|
||||||
|
ledStatusState = !ledStatusState;
|
||||||
|
writeStatusIndicator(ledStatusState ? c : 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -751,12 +751,15 @@ WLED_GLOBAL bool doSerializeConfig _INIT(false); // flag to initiate savi
|
|||||||
WLED_GLOBAL bool doReboot _INIT(false); // flag to initiate reboot from async handlers
|
WLED_GLOBAL bool doReboot _INIT(false); // flag to initiate reboot from async handlers
|
||||||
WLED_GLOBAL bool doPublishMqtt _INIT(false);
|
WLED_GLOBAL bool doPublishMqtt _INIT(false);
|
||||||
|
|
||||||
// status led
|
// status led / status pixel
|
||||||
#if defined(STATUSLED)
|
#if defined(STATUSLED) || defined(STATUSPIXELPIN)
|
||||||
WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0);
|
WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0);
|
||||||
WLED_GLOBAL uint8_t ledStatusType _INIT(0); // current status type - corresponds to number of blinks per second
|
WLED_GLOBAL uint8_t ledStatusType _INIT(0); // 0=off, 1=solid, 2=slow blink, 3=fast blink
|
||||||
WLED_GLOBAL bool ledStatusState _INIT(false); // the current LED state
|
WLED_GLOBAL bool ledStatusState _INIT(false); // the current LED state
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(STATUSPIXELPIN)
|
||||||
|
WLED_GLOBAL BusDigital* statusPixelBus _INIT(nullptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
// server library objects
|
// server library objects
|
||||||
WLED_GLOBAL AsyncWebServer server _INIT_N(((80)));
|
WLED_GLOBAL AsyncWebServer server _INIT_N(((80)));
|
||||||
|
|||||||
Reference in New Issue
Block a user