Clean up RFP ESP32-S3 target and tooling
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,8 +5,11 @@
|
||||
.gitignore
|
||||
.idea
|
||||
.pio
|
||||
.piohome
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.tools
|
||||
.venv
|
||||
.vscode
|
||||
.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
|
||||
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
|
||||
; rfp_esp32s3_wroom1_n16r8_3x106 ;; RFP ESP32-S3 WROOM-1 N16R8, 3x106 pixels on GPIO 4/5/6
|
||||
;;
|
||||
;; === esp32-S2 boards ===
|
||||
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
|
||||
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]
|
||||
;; MM for ESP32-S3 boards - FASTPATH + optimize for speed; ; HUB75 support included (may still have pin conflicts)
|
||||
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
|
||||
|
||||
#if defined(STATUSPIXELPIN)
|
||||
if (gpio == STATUSPIXELPIN) return(F("WLED Status Pixel"));
|
||||
#endif
|
||||
#if defined(STATUSLED)
|
||||
if (gpio == STATUSLED) return(F("WLED Status LED"));
|
||||
#endif
|
||||
|
||||
167
wled00/wled.cpp
167
wled00/wled.cpp
@@ -71,6 +71,73 @@
|
||||
#endif
|
||||
// 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))
|
||||
// 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"));
|
||||
beginStrip();
|
||||
#if defined(STATUSPIXELPIN)
|
||||
initStatusPixelBus();
|
||||
#endif
|
||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(getFreeHeapSize());
|
||||
|
||||
USER_PRINTLN(F("\nUsermods setup ..."));
|
||||
@@ -1568,58 +1638,79 @@ void WLED::handleConnection()
|
||||
}
|
||||
|
||||
// If status LED pin is allocated for other uses, does nothing
|
||||
// else blink at 1Hz when WLED_CONNECTED is false (no WiFi, ?? no Ethernet ??)
|
||||
// else blink at 2Hz when MQTT is enabled but not connected
|
||||
// else turn the status LED off
|
||||
// green blink = DDP realtime active
|
||||
// blue blink = AP active
|
||||
// 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()
|
||||
{
|
||||
#if defined(STATUSLED)
|
||||
[[maybe_unused]] uint32_t c = 0;
|
||||
#if defined(STATUSLED) || defined(STATUSPIXELPIN)
|
||||
uint32_t c = 0;
|
||||
uint8_t nextType = 0;
|
||||
uint16_t blinkIntervalMs = 0;
|
||||
|
||||
#if STATUSLED>=0
|
||||
#if defined(STATUSLED) && STATUSLED>=0
|
||||
if (pinManager.isPinAllocated(STATUSLED)) {
|
||||
return; //lower priority if something else uses the same pin
|
||||
}
|
||||
#endif
|
||||
|
||||
if (WLED_CONNECTED) {
|
||||
if (realtimeMode == REALTIME_MODE_DDP) {
|
||||
c = RGBW32(0,255,0,0);
|
||||
ledStatusType = 2;
|
||||
} else if (WLED_MQTT_CONNECTED) {
|
||||
c = RGBW32(0,128,0,0);
|
||||
ledStatusType = 4;
|
||||
nextType = 2;
|
||||
blinkIntervalMs = 250;
|
||||
} else if (apActive) {
|
||||
c = RGBW32(0,0,255,0);
|
||||
ledStatusType = 1;
|
||||
nextType = 2;
|
||||
blinkIntervalMs = 500;
|
||||
} else if (WLED_CONNECTED) {
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
if (mqttEnabled && mqttServer[0] != 0 && !WLED_MQTT_CONNECTED) {
|
||||
c = RGBW32(255,96,0,0);
|
||||
nextType = 3;
|
||||
blinkIntervalMs = 250;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
c = RGBW32(0,255,0,0);
|
||||
nextType = 1;
|
||||
}
|
||||
if (ledStatusType) {
|
||||
if (millis() - ledStatusLastMillis >= (1000/ledStatusType)) {
|
||||
} 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();
|
||||
#if 1
|
||||
// WLEDMM un-comment this to stop the blinking
|
||||
if ((ledStatusType != 2) && (ledStatusType != 4))
|
||||
ledStatusState = !ledStatusState;
|
||||
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
|
||||
writeStatusIndicator(ledStatusState ? c : 0);
|
||||
}
|
||||
#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 doPublishMqtt _INIT(false);
|
||||
|
||||
// status led
|
||||
#if defined(STATUSLED)
|
||||
// status led / status pixel
|
||||
#if defined(STATUSLED) || defined(STATUSPIXELPIN)
|
||||
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
|
||||
#endif
|
||||
#if defined(STATUSPIXELPIN)
|
||||
WLED_GLOBAL BusDigital* statusPixelBus _INIT(nullptr);
|
||||
#endif
|
||||
|
||||
// server library objects
|
||||
WLED_GLOBAL AsyncWebServer server _INIT_N(((80)));
|
||||
|
||||
Reference in New Issue
Block a user