Compare commits

...

9 Commits

Author SHA1 Message Date
c5233cf15c added support fo guition board 2026-03-13 16:39:27 +00:00
philippe44
0203682200 Lyrat 1.2 and ES8311 2026-02-16 12:51:39 +01:00
philippe44
0fee152cce 0.602 2026-02-16 12:32:15 +01:00
philippe44
7ca2e931eb Merge pull request #538 from michaelherger/master-v4.3
Fix missing colon
2026-02-16 12:25:42 +01:00
philippe44
b15263b961 Merge pull request #546 from irgendwer92/patch-1
README.md: Put touch button note back into button section
2026-02-16 12:24:07 +01:00
irgendwer92
967f448994 Put touch button note back into button section
The note about touch buttons is currently in the ethernet section, i put it back to the buttons.
2026-02-01 13:43:37 +01:00
Michael Herger
689a9fb057 Fix missing colon 2026-01-07 14:28:53 +01:00
philippe44
a71aff6882 Add files via upload 2025-12-30 13:02:24 +01:00
github-actions
e46df63090 Update prebuilt objects [skip actions] 2025-12-26 20:57:08 +00:00
40 changed files with 3107 additions and 122 deletions

189
GUITION_SETUP.md Normal file
View File

@@ -0,0 +1,189 @@
# Guition JC4827W543C Board Setup Guide
This guide explains how to configure and build squeezelite-esp32 for the Guition JC4827W543C development board.
## Board Features
- **Processor**: ESP32-S3-WROOM-1 (dual-core, 240MHz)
- **Display**: 4.3" ILI9488 LCD (480x272 pixels)
- **Touch**: GT911 capacitive touch controller
- **Interface**: QSPI display interface
- **Memory**: 4MB Flash, 4MB PSRAM
- **Connectivity**: WiFi, Bluetooth
## Hardware Configuration
### Display Connections (QSPI)
- **CLK**: GPIO47
- **DATA0**: GPIO21
- **DATA1**: GPIO48
- **DATA2**: GPIO40
- **DATA3**: GPIO39
- **CS**: GPIO45
- **DC**: Not used with QSPI
- **RST**: GPIO38 (if available)
### I2C Connections (Touch)
- **SDA**: GPIO8
- **SCL**: GPIO4
- **Touch INT**: GPIO3
- **Touch RST**: GPIO38
### Audio I2S (External DAC Required)
- **BCK**: GPIO15
- **WS**: GPIO16
- **DO**: GPIO17
- **DI**: (not used for output only)
### Other GPIO
- **Backlight**: GPIO1 (PWM controlled)
## Software Configuration
### 1. Build Configuration
Use the provided build script:
```bash
# Make the script executable
chmod +x build-guition.sh
# Configure and build
./build-guition.sh
```
Or manually:
```bash
# Set ESP32-S3 target
export IDF_TARGET=esp32s3
# Copy Guition configuration
cp squeezelite-esp32-Guition-sdkconfig.defaults sdkconfig.defaults
# Configure project
idf.py menuconfig
# Build
idf.py build
```
### 2. Menuconfig Settings
In `idf.py menuconfig`, select:
**Target Configuration**:
- `Squeezelite-ESP32``Guition JC4827W543C`
**Audio Settings**:
- Configure I2S GPIO pins for your external DAC
- Default: BCK=15, WS=16, DO=17
**Display Settings**:
- Should be automatically configured as:
- Type: QSPI
- Driver: ILI9488
- Width: 480
- Height: 272
- CS: 45
- Speed: 20MHz
**I2C Settings**:
- SDA: 8
- SCL: 4
- Speed: 400kHz
- Port: 0
### 3. External Audio DAC
The Guition board does not have a built-in audio DAC. You must connect an external I2S DAC such as:
- PCM5102
- TAS575x series
- ES8388
- AC101
Connect the DAC to the I2S pins and configure it in the NVS settings or through the web UI.
## Flashing the Firmware
```bash
# Flash to the board
idf.py -p /dev/ttyUSB0 flash
# Monitor output (optional)
idf.py -p /dev/ttyUSB0 monitor
```
## First Boot Configuration
1. Connect to the WiFi AP created by the device (SSID: SqueezeESP32-XXXXXX)
2. Open the web configuration interface
3. Configure your WiFi network
4. Set up your audio DAC if needed
5. Configure LMS server connection
## Display Features
The ILI9488 driver supports:
- 16-bit RGB565 color
- Hardware acceleration
- Shadow buffering for performance
- Automatic dirty region tracking
- Rotation and flip options
## Touch Support
Touch functionality is planned but not yet implemented. The GT911 touch controller is connected via I2C.
## Troubleshooting
### Display Not Working
- Check QSPI GPIO connections
- Verify CS pin is correctly set to GPIO45
- Ensure proper power supply (3.3V for display logic)
### Audio Not Working
- Verify external DAC is properly connected
- Check I2S GPIO assignments
- Configure DAC model in web UI if using a supported DAC
### Build Issues
- Ensure ESP-IDF supports ESP32-S3
- Check that all required components are included
- Verify GPIO pin assignments don't conflict
## Performance Notes
- The 480x272 display requires significant memory bandwidth
- PSRAM is used for display framebuffer (≈260KB)
- Audio performance may be affected at high display refresh rates
- Consider reducing display update rate if audio issues occur
## GPIO Map Summary
| GPIO | Function | Direction |
|------|----------|-----------|
| 1 | Backlight PWM | Out |
| 3 | Touch INT | In |
| 4 | I2C SCL | Out |
| 8 | I2C SDA | I/O |
| 15 | I2S BCK | Out |
| 16 | I2S WS | Out |
| 17 | I2S DO | Out |
| 21 | QSPI DATA0 | Out |
| 39 | QSPI DATA3 | Out |
| 40 | QSPI DATA2 | Out |
| 45 | QSPI CS | Out |
| 47 | QSPI CLK | Out |
| 48 | QSPI DATA1 | Out |
| 38 | Touch RST | Out |
## Support
For issues specific to the Guition board implementation:
1. Check this README first
2. Review the squeezelite-esp32 documentation
3. Open an issue on the GitHub repository
For general squeezelite-esp32 questions, refer to the main project documentation and forums.

View File

@@ -157,6 +157,21 @@ XMT - 3.3V
Use the `squeezelite-esp32-I2S-4MFlash-sdkconfig.defaults` configuration file.
### ESP32 LyraT Mini v1.2
This board is one of the [audio developpement board](https://docs.espressif.com/projects/esp-adf/en/latest/design-guide/dev-boards/get-started-esp32-lyrat-mini.html) designed by espressif for their ESP-ADF (Espressif Audio Development Framework). It uses ESP32-WROVER-E as it core and ES8311 as DAC.
A jack connector can be used or an HP output.
It also contains 2 LEDS (one green, one blue) and 8 Buttons. Those buttons are not supported for now.
An ADC is also present on the board, but not used in squeezelite use case.
As for now, audio playback and LEDs are working.
Use the `squeezelite-esp32-I2S-4MFlash-sdkconfig.defaults` configuration file.
- i2c_config: `scl=25,sda=18,speed=400000,port=1`
- dac_config: `model=es8311,bck=5,ws=25,do=26,sda=18,scl=23,i2c=24`
- set_GPIO: `22=green,27=red,19=jack`
### SqueezeAmpToo !
And the super cool project https://github.com/rochuck/squeeze-amp-too
@@ -184,11 +199,11 @@ Default and only "host" is 1 as others are used already by flash and spiram. The
### DAC/I2S
The NVS parameter "dac_config" set the gpio used for i2s communication with your DAC. You can define the defaults at compile time but nvs parameter takes precedence except for named configurations
```
bck=<gpio>,ws=<gpio>,do=<gpio>[,mck=0|1|2][,mute=<gpio>[:0|1][,model=TAS57xx|TAS5713|AC101|WM8978|ES8388|I2S][,sda=<gpio>,scl=<gpio>[,i2c=<addr>]]
bck=<gpio>,ws=<gpio>,do=<gpio>[,mck=0|1|2][,mute=<gpio>[:0|1][,model=TAS57xx|TAS5713|AC101|WM8978|ES8388|ES8311|I2S][,sda=<gpio>,scl=<gpio>[,i2c=<addr>]]
```
if "model" is not set or is not recognized, then default "I2S" is used. The option "mck" is used for some codecs that require a master clock (although they should not). By default GPIO0 is used as MCLK and only recent builds (post mid-2023) can use 1 or 2. Also be aware that this cannot coexit with RMII Ethernet (see ethernet section below). I2C parameters are optional and only needed if your DAC requires an I2C control (See 'dac_controlset' below). Note that "i2c" parameters are decimal, hex notation is not allowed.
So far, TAS57xx, TAS5713, AC101, WM8978 and ES8388 are recognized models where the proper init sequence/volume/power controls are sent. For other codecs that might require an I2C commands, please use the parameter "dac_controlset" that allows definition of simple commands to be sent over i2c for init, power, speaker and headset on and off using a JSON syntax:
So far, TAS57xx, TAS5713, AC101, WM8978, ES8388 and ES8311 are recognized models where the proper init sequence/volume/power controls are sent. For other codecs that might require an I2C commands, please use the parameter "dac_controlset" that allows definition of simple commands to be sent over i2c for init, power, speaker and headset on and off using a JSON syntax:
```json
{ <command>: [ <item1>, <item2>, ... <item3> ],
<command>: [ <item1>, <item2>, ... <item3> ],
@@ -478,11 +493,12 @@ The benefit of the "raw" mode is that you can build a player which is as close a
There is no good or bad option, it's your choice. Use the NVS parameter "lms_ctrls_raw" to change that option
**Note that gpio 36 and 39 are input only and cannot use interrupt. When using them for a button, a 100ms polling is started which is expensive. Long press is also likely to not work very well**
**Note:** Touch buttons that can be found on some board like the LyraT V4.3 are not supported currently.
### Ethernet
Wired ethernet is supported by esp32 with various options but squeezeESP32 is only supporting a Microchip LAN8720 with a RMII interface like [this](https://www.aliexpress.com/item/32858432526.html) or SPI-ethernet bridges like Davicom DM9051 [that](https://www.amazon.com/dp/B08JLFWX9Z) or W5500 like [this](https://www.aliexpress.com/item/32312441357.html).
**Note:** Touch buttons that can be find on some board like the LyraT V4.3 are not supported currently.
#### RMII (LAN8720)
- RMII PHY wiring is fixed and can not be changed

216
WINDOWS_BUILD_GUIDE.md Normal file
View File

@@ -0,0 +1,216 @@
# Windows Build Guide for Guition JC4827W543C
This guide explains how to build squeezelite-esp32 for the Guition board on Windows.
## Prerequisites
1. **ESP-IDF for Windows**
- Download and install ESP-IDF from: https://dl.espressif.com/dl/esp-idf/
- Run the installer and follow the setup instructions
- Make sure to install the required tools (Git, Python, CMake)
2. **Visual Studio Build Tools** (if not already installed by ESP-IDF)
- Install from Visual Studio Installer
- Select "C++ build tools"
3. **Hardware**
- Guition JC4827W543C board
- USB cable for power and programming
- External I2S audio DAC (required)
## Setup Instructions
### 1. Install ESP-IDF
```cmd
# Run the ESP-IDF installer
# Launch ESP-IDF Command Prompt from Start Menu
```
### 2. Initialize ESP-IDF Environment
```cmd
# In ESP-IDF Command Prompt
cd C:\Espressif\esp-idf
export.bat
```
### 3. Clone and Setup Project
```cmd
# Navigate to your workspace
cd C:\Users\YourName\Projects
# Clone the repository (if not already done)
git clone <repository-url> squeezelite-esp32-gronod
cd squeezelite-esp32-gronod
```
### 4. Set Environment for Project
```cmd
# Set ESP-IDF environment for this project
C:\Espressif\esp-idf\export.bat
```
## Build Methods
### Method 1: PowerShell Script (Recommended)
```powershell
# Open PowerShell as Administrator
# Navigate to project directory
cd C:\Users\YourName\Projects\squeezelite-esp32-gronod
# Run the build script
.\build-guition.ps1
# For clean build
.\build-guition.ps1 -Clean
```
**Note:** If you get execution policy errors, run:
```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
### Method 2: Batch File (Simple)
```cmd
# Open Command Prompt
# Navigate to project directory
cd C:\Users\YourName\Projects\squeezelite-esp32-gronod
# Run the build script
build-guition.bat
# For clean build
build-guition.bat clean
```
### Method 3: Manual Commands
```cmd
# Set ESP-IDF environment
C:\Espressif\esp-idf\export.bat
# Set target
set IDF_TARGET=esp32s3
# Copy Guition config
copy /Y squeezelite-esp32-Guition-sdkconfig.defaults sdkconfig.defaults
# Configure (opens menu interface)
idf.py menuconfig
# Build
idf.py build
```
## Menuconfig Configuration
When `idf.py menuconfig` runs:
1. **Select Target Hardware**:
- Navigate to: `Squeezelite-ESP32``Guition JC4827W543C`
2. **Configure Audio** (if needed):
- Navigate to: `Audio settings``DAC settings`
- Set I2S GPIO pins for your external DAC
- Default: BCK=15, WS=16, DO=17
3. **Save and Exit**:
- Press `S` to save
- Press `Q` to exit
## Flashing the Firmware
### Find Your COM Port
```cmd
# List all COM ports
mode
# Or check Device Manager under "Ports (COM & LPT)"
```
### Flash and Monitor
```cmd
# Flash firmware
idf.py -p COM3 flash
# Flash and monitor (recommended)
idf.py -p COM3 flash monitor
# Just monitor (if already flashed)
idf.py -p COM3 monitor
```
### Using the Scripts
Both PowerShell and batch scripts will ask if you want to flash after building.
## Troubleshooting
### Common Issues
1. **"ESP-IDF environment not found"**
- Make sure you're running from ESP-IDF Command Prompt
- Or run `C:\Espressif\esp-idf\export.bat` first
2. **"Python not found"**
- ESP-IDF installer should include Python
- Check that Python is in your PATH
3. **"Build tools not found"**
- Install Visual Studio Build Tools
- Make sure C++ tools are selected
4. **"Permission denied" (PowerShell)**
- Run PowerShell as Administrator
- Or set execution policy: `Set-ExecutionPolicy RemoteSigned`
5. **"COM port not found"**
- Check device connections
- Install USB drivers if needed (CH340/CP210x)
- Check Device Manager
### Clean Build
If you encounter build issues:
```cmd
# Using batch file
build-guition.bat clean
# Or manually
idf.py fullclean
idf.py build
```
### Verifying Installation
```cmd
# Check ESP-IDF version
idf.py --version
# Check target
echo %IDF_TARGET%
# List available targets
idf.py --help | findstr target
```
## Development Workflow
1. **Initial Setup**: Run the build script once to configure
2. **Code Changes**: Make your modifications
3. **Build**: Run `.\build-guition.ps1` or `build-guition.bat`
4. **Flash**: Let the script flash automatically, or use `idf.py -p COMX flash`
5. **Monitor**: Use `idf.py -p COMX monitor` to view logs
## Performance Tips
- **SSD Storage**: Build on SSD for much faster compilation
- **RAM**: 8GB+ recommended for large projects
- **CPU**: Multi-core CPU helps with parallel compilation
- **Antivirus**: Exclude project directory from real-time scanning
## Next Steps
After successful build and flash:
1. Connect to WiFi AP created by device
2. Configure your network settings
3. Set up audio DAC configuration
4. Connect to your Logitech Media Server
For more detailed configuration, see `GUITION_SETUP.md`.

80
build-guition.bat Normal file
View File

@@ -0,0 +1,80 @@
@echo off
REM Build script for Guition JC4827W543C board - Batch file version
REM Usage: build-guition.bat [clean]
echo Building Squeezelite-ESP32 for Guition JC4827W543C
REM Check if ESP-IDF environment is set up
if "%IDF_PATH%"=="" (
echo Error: ESP-IDF environment not found!
echo Please run esp-idf\export.bat first
pause
exit /b 1
)
REM Set target to ESP32-S3
set IDF_TARGET=esp32s3
echo Target set to: %IDF_TARGET%
REM Copy Guition-specific configuration
if exist "squeezelite-esp32-Guition-sdkconfig.defaults" (
echo Using Guition configuration...
copy /Y "squeezelite-esp32-Guition-sdkconfig.defaults" "sdkconfig.defaults"
) else (
echo Warning: Guition configuration file not found
)
REM Clean if requested
if /i "%1"=="clean" (
echo Cleaning build...
idf.py fullclean
if errorlevel 1 (
echo Clean failed!
pause
exit /b 1
)
)
REM Configure the project
echo Configuring project...
echo Running: idf.py menuconfig
echo Select: Squeezelite-ESP32 -^> Guition JC4827W543C
echo.
echo Press any key to continue to menuconfig...
pause > nul
idf.py menuconfig
if errorlevel 1 (
echo Configuration failed!
pause
exit /b 1
)
REM Build the project
echo Building firmware...
idf.py build
if errorlevel 1 (
echo Build failed!
pause
exit /b 1
)
echo Build complete!
echo Firmware location: build\squeezelite.bin
echo.
echo To flash the firmware:
echo idf.py -p ^<PORT^> flash
echo.
echo To monitor output:
echo idf.py -p ^<PORT^> monitor
REM Ask if user wants to flash
echo.
set /p flash="Do you want to flash the firmware now? (y/n) "
if /i "%flash%"=="y" (
set /p port="Enter COM port (e.g., COM3): "
echo Flashing to %port%...
idf.py -p %port% flash monitor
)
pause

76
build-guition.ps1 Normal file
View File

@@ -0,0 +1,76 @@
# Build script for Guition JC4827W543C board - PowerShell version
# Usage: .\build-guition.ps1 [-Clean]
param(
[switch]$Clean
)
Write-Host "Building Squeezelite-ESP32 for Guition JC4827W543C" -ForegroundColor Green
# Check if ESP-IDF environment is set up
if (-not $env:IDF_PATH) {
Write-Host "Error: ESP-IDF environment not found!" -ForegroundColor Red
Write-Host "Please run esp-idf/export.bat first" -ForegroundColor Yellow
exit 1
}
# Set target to ESP32-S3
$env:IDF_TARGET = "esp32s3"
Write-Host "Target set to: $env:IDF_TARGET" -ForegroundColor Cyan
# Copy Guition-specific configuration
if (Test-Path "squeezelite-esp32-Guition-sdkconfig.defaults") {
Write-Host "Using Guition configuration..." -ForegroundColor Cyan
Copy-Item "squeezelite-esp32-Guition-sdkconfig.defaults" "sdkconfig.defaults" -Force
} else {
Write-Host "Warning: Guition configuration file not found" -ForegroundColor Yellow
}
# Clean if requested
if ($Clean) {
Write-Host "Cleaning build..." -ForegroundColor Cyan
idf.py fullclean
if ($LASTEXITCODE -ne 0) {
Write-Host "Clean failed!" -ForegroundColor Red
exit 1
}
}
# Configure the project
Write-Host "Configuring project..." -ForegroundColor Cyan
Write-Host "Running: idf.py menuconfig" -ForegroundColor White
Write-Host "Select: Squeezelite-ESP32 -> Guition JC4827W543C" -ForegroundColor Yellow
Write-Host "Press Enter to continue to menuconfig..." -ForegroundColor White
Read-Host
idf.py menuconfig
if ($LASTEXITCODE -ne 0) {
Write-Host "Configuration failed!" -ForegroundColor Red
exit 1
}
# Build the project
Write-Host "Building firmware..." -ForegroundColor Cyan
idf.py build
if ($LASTEXITCODE -ne 0) {
Write-Host "Build failed!" -ForegroundColor Red
exit 1
}
Write-Host "Build complete!" -ForegroundColor Green
Write-Host "Firmware location: build\squeezelite.bin" -ForegroundColor Cyan
Write-Host ""
Write-Host "To flash the firmware:" -ForegroundColor White
Write-Host "idf.py -p <PORT> flash" -ForegroundColor Yellow
Write-Host ""
Write-Host "To monitor output:" -ForegroundColor White
Write-Host "idf.py -p <PORT> monitor" -ForegroundColor Yellow
# Ask if user wants to flash
Write-Host ""
$flash = Read-Host "Do you want to flash the firmware now? (y/n)"
if ($flash -eq 'y' -or $flash -eq 'Y') {
$port = Read-Host "Enter COM port (e.g., COM3)"
Write-Host "Flashing to $port..." -ForegroundColor Cyan
idf.py -p $port flash monitor
}

40
build-guition.sh Normal file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
# Build script for Guition JC4827W543C board
# Usage: ./build-guition.sh [clean]
set -e
echo "Building Squeezelite-ESP32 for Guition JC4827W543C"
# Set target to ESP32-S3
export IDF_TARGET=esp32s3
# Copy Guition-specific configuration
if [ -f "squeezelite-esp32-Guition-sdkconfig.defaults" ]; then
echo "Using Guition configuration..."
cp squeezelite-esp32-Guition-sdkconfig.defaults sdkconfig.defaults
fi
# Clean if requested
if [ "$1" == "clean" ]; then
echo "Cleaning build..."
idf.py fullclean
fi
# Configure with Guition target
echo "Configuring project..."
idf.py menuconfig
# Build the project
echo "Building firmware..."
idf.py build
echo "Build complete!"
echo "Firmware location: build/squeezelite.bin"
echo ""
echo "To flash the firmware:"
echo "idf.py -p <PORT> flash"
echo ""
echo "To monitor output:"
echo "idf.py -p <PORT> monitor"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,297 @@
/**
* ILI9488 Display Driver for Guition JC4827W543C
* Supports QSPI interface for 480x272 resolution
* Based on ILI9341 driver adapted for ILI9488
*
* (c) Guition Support 2026
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <esp_heap_caps.h>
#include <esp_log.h>
#include "gds.h"
#include "gds_private.h"
#define SHADOW_BUFFER
#define USE_IRAM
#define PAGE_BLOCK 4096
#define ENABLE_WRITE 0x2c
#define min(a,b) (((a) < (b)) ? (a) : (b))
static char TAG[] = "ILI9488";
struct PrivateSpace {
uint8_t *iRAM, *Shadowbuffer;
struct {
uint16_t Height, Width;
} Offset;
uint8_t MADCtl, PageSize;
uint8_t Model;
};
// ILI9488 Commands
static const uint8_t ILI9488_INIT_SEQUENCE[] = {
// Software reset
0x01, 0x80, 150, // SWRESET, delay 150ms
// Power control
0xD0, 3, 0x07, 0x42, 0x18, // Power Control
0xD1, 3, 0x00, 0x07, 0x10, // VCOM Control
0xD2, 1, 0x01, // Power Control for Normal Mode
0xC0, 2, 0x10, 0x3B, // Panel Driving Setting
0xC1, 1, 0x10, // Frame Rate Control
0xC5, 5, 0x0A, 0x3A, 0x28, 0x28, 0x02, // MCU Control
0xC6, 1, 0x00, // Frame Rate Control
0xB1, 2, 0x00, 0x1B, // Display Function Control
0xB4, 1, 0x02, // Inversion Control
0xB6, 3, 0x02, 0x02, 0x3B, // Display Function Control
0xB7, 1, 0xC6, // Entry Mode Set
0xE0, 16, 0x00, 0x07, 0x10, 0x0E, 0x09, 0x16, 0x06, 0x0A,
0x0E, 0x09, 0x15, 0x0D, 0x0E, 0x11, 0x0F, 0x12, // Positive Gamma Control
0xE1, 16, 0x00, 0x17, 0x1A, 0x04, 0x0E, 0x06, 0x2F, 0x24,
0x1B, 0x1B, 0x22, 0x1F, 0x1E, 0x37, 0x3F, 0x00, // Negative Gamma Control
0x36, 1, 0xE8, // Memory Access Control (MX, MY, RGB mode)
0x3A, 1, 0x55, // Interface Pixel Format (16bpp)
0x11, 0x80, 150, // Sleep Out, delay 150ms
0x29, 0x80, 50, // Display On, delay 50ms
0xFF, 0x00 // End of sequence
};
static void WriteByte( struct GDS_Device* Device, uint8_t Data ) {
Device->WriteData( Device, &Data, 1 );
}
static void SetColumnAddress( struct GDS_Device* Device, uint16_t Start, uint16_t End ) {
uint32_t Addr = __builtin_bswap16(Start) | (__builtin_bswap16(End) << 16);
Device->WriteCommand( Device, 0x2A );
Device->WriteData( Device, (uint8_t*) &Addr, 4 );
}
static void SetRowAddress( struct GDS_Device* Device, uint16_t Start, uint16_t End ) {
uint32_t Addr = __builtin_bswap16(Start) | (__builtin_bswap16(End) << 16);
Device->WriteCommand( Device, 0x2B );
Device->WriteData( Device, (uint8_t*) &Addr, 4 );
}
static void Update16( struct GDS_Device* Device ) {
struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
#ifdef SHADOW_BUFFER
uint32_t *optr = (uint32_t*) Private->Shadowbuffer, *iptr = (uint32_t*) Device->Framebuffer;
int FirstCol = Device->Width / 2, LastCol = 0, FirstRow = -1, LastRow = 0;
for (int r = 0; r < Device->Height; r++) {
// look for change and update shadow (cheap optimization = width is always a multiple of 2)
for (int c = 0; c < Device->Width / 2; c++, iptr++, optr++) {
if (*optr != *iptr) {
*optr = *iptr;
if (c < FirstCol) FirstCol = c;
if (c > LastCol) LastCol = c;
if (FirstRow < 0) FirstRow = r;
LastRow = r;
}
}
// wait for a large enough window - careful that window size might increase by more than a line at once !
if (FirstRow < 0 || ((LastCol - FirstCol + 1) * (r - FirstRow + 1) * 4 < PAGE_BLOCK && r != Device->Height - 1)) continue;
FirstCol *= 2;
LastCol = LastCol * 2 + 1;
SetRowAddress( Device, FirstRow + Private->Offset.Height, LastRow + Private->Offset.Height);
SetColumnAddress( Device, FirstCol + Private->Offset.Width, LastCol + Private->Offset.Width );
Device->WriteCommand( Device, ENABLE_WRITE );
int ChunkSize = (LastCol - FirstCol + 1) * 2;
// own use of IRAM has not proven to be much better than letting SPI do its copy
if (Private->iRAM) {
uint8_t *optr = Private->iRAM;
for (int i = FirstRow; i <= LastRow; i++) {
memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 2, ChunkSize);
optr += ChunkSize;
if (optr - Private->iRAM <= (PAGE_BLOCK - ChunkSize) && i < LastRow) continue;
Device->WriteData(Device, Private->iRAM, optr - Private->iRAM);
optr = Private->iRAM;
}
} else for (int i = FirstRow; i <= LastRow; i++) {
Device->WriteData( Device, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 2, ChunkSize );
}
FirstCol = Device->Width / 2;
LastCol = 0;
FirstRow = -1;
}
#endif
}
static void Clear( struct GDS_Device* Device ) {
memset( Device->Framebuffer, 0, Device->Width * Device->Height * 2 );
Device->Update( Device);
}
static void SetPixel( struct GDS_Device* Device, int X, int Y, uint32_t Color ) {
if( X < 0 || X >= Device->Width || Y < 0 || Y >= Device->Height) return;
*((uint16_t*) Device->Framebuffer + (Y * Device->Width) + X) = (uint16_t) Color;
}
static uint32_t GetPixel( struct GDS_Device* Device, int X, int Y ) {
if( X < 0 || X >= Device->Width || Y < 0 || Y >= Device->Height) return 0;
return *((uint16_t*) Device->Framebuffer + (Y * Device->Width) + X);
}
static void DrawPixel( struct GDS_Device* Device, int X, int Y, uint32_t Color ) {
SetPixel( Device, X, Y, Color );
}
static void DrawPixelFast( struct GDS_Device* Device, int X, int Y, uint32_t Color ) {
*((uint16_t*) Device->Framebuffer + (Y * Device->Width) + X) = (uint16_t) Color;
}
static void DrawCBR( struct GDS_Device* Device, int X, int Y, int Width, int Height, uint32_t Color ) {
uint16_t *fb = (uint16_t*) Device->Framebuffer + Y * Device->Width + X;
for( int y = 0; y < Height; y++) {
for( int x = 0; x < Width; x++) {
fb[x] = (uint16_t) Color;
}
fb += Device->Width;
}
}
static void DrawHLine( struct GDS_Device* Device, int X0, int X1, int Y, uint32_t Color ) {
if( Y < 0 || Y >= Device->Height) return;
if( X0 > X1) {
int Temp = X0;
X0 = X1;
X1 = Temp;
}
if( X0 < 0) X0 = 0;
if( X1 >= Device->Width) X1 = Device->Width - 1;
uint16_t *fb = (uint16_t*) Device->Framebuffer + Y * Device->Width + X0;
for( int x = X0; x <= X1; x++) {
*fb++ = (uint16_t) Color;
}
}
static void DrawVLine( struct GDS_Device* Device, int X, int Y0, int Y1, uint32_t Color ) {
if( X < 0 || X >= Device->Width) return;
if( Y0 > Y1) {
int Temp = Y0;
Y0 = Y1;
Y1 = Temp;
}
if( Y0 < 0) Y0 = 0;
if( Y1 >= Device->Height) Y1 = Device->Height - 1;
uint16_t *fb = (uint16_t*) Device->Framebuffer + Y0 * Device->Width + X;
for( int y = Y0; y <= Y1; y++) {
*fb = (uint16_t) Color;
fb += Device->Width;
}
}
static bool Init( struct GDS_Device* Device ) {
struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
const uint8_t *p = ILI9488_INIT_SEQUENCE;
ESP_LOGI(TAG, "Initializing ILI9488 display %dx%d", Device->Width, Device->Height);
// Allocate IRAM buffer if available
Private->iRAM = (uint8_t*) heap_caps_malloc(PAGE_BLOCK, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
if (!Private->iRAM) {
ESP_LOGW(TAG, "Could not allocate IRAM buffer, using direct write");
}
#ifdef SHADOW_BUFFER
Private->Shadowbuffer = (uint8_t*) heap_caps_malloc(Device->Width * Device->Height * 2, MALLOC_CAP_DMA);
if (!Private->Shadowbuffer) {
ESP_LOGE(TAG, "Could not allocate shadow buffer");
if (Private->iRAM) free(Private->iRAM);
return false;
}
memset(Private->Shadowbuffer, 0, Device->Width * Device->Height * 2);
#endif
// Send initialization sequence
while(*p != 0xFF) {
uint8_t cmd = *p++;
uint8_t len = (*p & 0x7F);
bool delay = (*p++ & 0x80);
Device->WriteCommand(Device, cmd);
if(len) Device->WriteData(Device, (uint8_t*)p, len);
p += len;
if(delay) {
uint8_t ms = *p++;
vTaskDelay(ms / portTICK_PERIOD_MS);
}
}
// Set orientation and layout
Private->MADCtl = 0xE8; // MX=1, MY=1, RGB=1, BGR=0
Device->WriteCommand(Device, 0x36);
Device->WriteData(Device, &Private->MADCtl, 1);
// Set pixel format to 16-bit
uint8_t fmt = 0x55;
Device->WriteCommand(Device, 0x3A);
Device->WriteData(Device, &fmt, 1);
// Turn on display
Device->WriteCommand(Device, 0x29);
ESP_LOGI(TAG, "ILI9488 initialization complete");
return true;
}
static void Deinit( struct GDS_Device* Device ) {
struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
if (Private->iRAM) free(Private->iRAM);
#ifdef SHADOW_BUFFER
if (Private->Shadowbuffer) free(Private->Shadowbuffer);
#endif
}
struct GDS_Device* ILI9488_Detect( char *Driver, struct GDS_Device *Device ) {
if(strcasecmp(Driver, "ILI9488") != 0) return NULL;
Device->Private = calloc(1, sizeof(struct PrivateSpace));
if(!Device->Private) {
ESP_LOGE(TAG, "Cannot allocate private data");
return NULL;
}
Device->Mode = GDS_RGB565;
Device->Depth = 16;
Device->Update = Update16;
Device->Clear = Clear;
Device->SetPixel = SetPixel;
Device->GetPixel = GetPixel;
Device->DrawPixel = DrawPixel;
Device->DrawPixelFast = DrawPixelFast;
Device->DrawCBR = DrawCBR;
Device->DrawHLine = DrawHLine;
Device->DrawVLine = DrawVLine;
Device->Init = Init;
Device->Deinit = Deinit;
ESP_LOGI(TAG, "ILI9488 driver loaded");
return Device;
}

View File

@@ -13,6 +13,10 @@ bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int
bool GDS_SPIInit( int SPI, int DC );
bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed, int BacklightPin, int Mode );
bool GDS_QSPIInit( int QSPI, int DC );
bool GDS_QSPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed, int BacklightPin, int Mode );
bool GDS_QSPIBusInit( int MOSIPin, int MISOPin, int CLKPin, int Host );
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,161 @@
/**
* QSPI Interface for Guition JC4827W543C ILI9488 Display
* Supports ESP32-S3 QSPI peripheral
*
* (c) Guition Support 2026
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <driver/spi_master.h>
#include <driver/gpio.h>
#include <freertos/task.h>
#include "gds.h"
#include "gds_err.h"
#include "gds_private.h"
#include "gds_default_if.h"
static const int GDS_QSPI_Command_Mode = 0;
static const int GDS_QSPI_Data_Mode = 1;
static spi_host_device_t QSPIHost;
static int DCPin;
static bool QSPIDefaultWriteBytes( spi_device_handle_t QSPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength );
static bool QSPIDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command );
static bool QSPIDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength );
bool GDS_QSPIInit( int QSPI, int DC ) {
QSPIHost = QSPI;
DCPin = DC;
return true;
}
bool GDS_QSPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int BackLightPin, int Speed, int Mode ) {
spi_device_interface_config_t QSPIDeviceConfig = { };
spi_device_handle_t QSPIDevice;
NullCheck( Device, return false );
if (CSPin >= 0) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( CSPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( CSPin, 0 ), return false );
}
QSPIDeviceConfig.clock_speed_hz = Speed > 0 ? Speed : SPI_MASTER_FREQ_20M;
QSPIDeviceConfig.spics_io_num = CSPin;
QSPIDeviceConfig.queue_size = 4;
QSPIDeviceConfig.mode = Mode;
QSPIDeviceConfig.flags = SPI_DEVICE_HALFDUPLEX;
QSPIDeviceConfig.duty_cycle_pos = 128; // 50% duty cycle
// QSPI specific configuration for ESP32-S3
QSPIDeviceConfig.command_bits = 8;
QSPIDeviceConfig.address_bits = 24;
QSPIDeviceConfig.address_len = 3;
if( spi_bus_add_device( QSPIHost, &QSPIDeviceConfig, &QSPIDevice ) != ESP_OK ) {
GDS_LOG_ERROR( "Failed to add QSPI device to host" );
return false;
}
if( DCPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( DCPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DCPin, 1 ), return false );
}
if( RSTPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 1 ), return false );
}
if( BackLightPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( BackLightPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( BackLightPin, 1 ), return false );
}
Device->WriteCommand = QSPIDefaultWriteCommand;
Device->WriteData = QSPIDefaultWriteData;
Device->DeviceHandle = QSPIDevice;
// Hardware reset if pin is available
if( RSTPin >= 0 ) {
gpio_set_level( RSTPin, 0 );
vTaskDelay( pdMS_TO_TICKS( 10 ) );
gpio_set_level( RSTPin, 1 );
vTaskDelay( pdMS_TO_TICKS( 120 ) );
}
return true;
}
static bool QSPIDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command ) {
return QSPIDefaultWriteBytes( Device->DeviceHandle, GDS_QSPI_Command_Mode, &Command, 1 );
}
static bool QSPIDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength ) {
if( DCPin >= 0 ) {
gpio_set_level( DCPin, 1 );
}
bool Result = QSPIDefaultWriteBytes( Device->DeviceHandle, GDS_QSPI_Data_Mode, Data, DataLength );
if( DCPin >= 0 ) {
gpio_set_level( DCPin, 0 );
}
return Result;
}
static bool QSPIDefaultWriteBytes( spi_device_handle_t QSPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength ) {
spi_transaction_ext_t SPITransaction = { };
SPITransaction.base.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY;
SPITransaction.base.cmd = 0;
SPITransaction.base.addr = 0;
SPITransaction.base.length = DataLength * 8;
SPITransaction.base.tx_buffer = Data;
SPITransaction.base.rx_buffer = NULL;
SPITransaction.command_bits = 8;
SPITransaction.address_bits = 0;
SPITransaction.dummy_bits = 0;
if( WriteMode == GDS_QSPI_Command_Mode ) {
SPITransaction.command_bits = 8;
SPITransaction.base.cmd = Data[0];
SPITransaction.base.length = 0;
SPITransaction.base.tx_buffer = NULL;
}
if( spi_device_transmit( QSPIHandle, (spi_transaction_t*) &SPITransaction ) != ESP_OK ) {
GDS_LOG_ERROR( "QSPI transaction failed" );
return false;
}
return true;
}
bool GDS_QSPIBusInit( int MOSIPin, int MISOPin, int CLKPin, int Host ) {
spi_bus_config_t BusConfig = { };
NullCheck( Host >= SPI2_HOST && Host <= SPI3_HOST, return false );
// QSPI pin configuration for ESP32-S3
BusConfig.mosi_io_num = MOSIPin;
BusConfig.miso_io_num = MISOPin;
BusConfig.sclk_io_num = CLKPin;
BusConfig.quadwp_io_num = -1; // Not used for ILI9488
BusConfig.quadhd_io_num = -1; // Not used for ILI9488
BusConfig.max_transfer_sz = 65536;
BusConfig.flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_NATIVE_PINS;
if( spi_bus_initialize( Host, &BusConfig, DMA_CH_AUTO ) != ESP_OK ) {
GDS_LOG_ERROR( "Failed to initialize QSPI bus" );
return false;
}
return true;
}

View File

@@ -73,6 +73,7 @@ static const char *known_drivers[] = {"SH1106",
"ST7735",
"ST7789",
"ILI9341",
"ILI9488",
NULL
};
@@ -80,8 +81,8 @@ static void displayer_task(void *args);
static void display_sleep(void);
struct GDS_Device *display;
extern GDS_DetectFunc SSD1306_Detect, SSD132x_Detect, SH1106_Detect, SH1122_Detect, SSD1675_Detect, SSD1322_Detect, SSD1351_Detect, ST77xx_Detect, ILI9341_Detect;
GDS_DetectFunc *drivers[] = { SH1106_Detect, SH1122_Detect, SSD1306_Detect, SSD132x_Detect, SSD1675_Detect, SSD1322_Detect, SSD1351_Detect, ST77xx_Detect, ILI9341_Detect, NULL };
extern GDS_DetectFunc SSD1306_Detect, SSD132x_Detect, SH1106_Detect, SH1122_Detect, SSD1675_Detect, SSD1322_Detect, SSD1351_Detect, ST77xx_Detect, ILI9341_Detect, ILI9488_Detect;
GDS_DetectFunc *drivers[] = { SH1106_Detect, SH1122_Detect, SSD1306_Detect, SSD132x_Detect, SSD1675_Detect, SSD1322_Detect, SSD1351_Detect, ST77xx_Detect, ILI9341_Detect, ILI9488_Detect, NULL };
/****************************************************************************************
*
@@ -134,6 +135,31 @@ void display_init(char *welcome) {
GDS_SPIAttachDevice( display, width, height, CS_pin, RST_pin, backlight_pin, speed, mode );
ESP_LOGI(TAG, "Display is SPI host %u with cs:%d", spi_system_host, CS_pin);
} else if (strcasestr(config, "QSPI") && spi_system_host != -1) {
int CS_pin = -1, speed = 0, mode = 0;
PARSE_PARAM(config, "cs", '=', CS_pin);
PARSE_PARAM(config, "speed", '=', speed);
PARSE_PARAM(config, "mode", '=', mode);
// Parse QSPI data pins
int data_pins[4] = {-1, -1, -1, -1};
char *data_str = strstr(config, "data=");
if (data_str) {
sscanf(data_str + 5, "%d,%d,%d,%d", &data_pins[0], &data_pins[1], &data_pins[2], &data_pins[3]);
}
init = true;
// Initialize QSPI bus with data pins
if (data_pins[0] != -1 && data_pins[1] != -1 && data_pins[2] != -1 && data_pins[3] != -1) {
GDS_QSPIBusInit( data_pins[0], data_pins[1], spi_system_clk_gpio, spi_system_host );
}
GDS_QSPIInit( spi_system_host, spi_system_dc_gpio );
GDS_QSPIAttachDevice( display, width, height, CS_pin, RST_pin, backlight_pin, speed, mode );
ESP_LOGI(TAG, "Display is QSPI host %u with cs:%d", spi_system_host, CS_pin);
} else {
display = NULL;
ESP_LOGI(TAG, "Unsupported display interface or serial link not configured");

View File

@@ -51,6 +51,19 @@ static const struct {
{\"reg\":26,\"val\":0}, {\"reg\":27,\"val\":0}, {\"reg\":25,\"val\":50}, {\"reg\":38,\"val\":0}, \
{\"reg\":39,\"val\":184}, {\"reg\":42,\"val\":184}, {\"reg\":46,\"val\":30}, {\"reg\":47,\"val\":30}, \
{\"reg\":48,\"val\":30}, {\"reg\":49,\"val\":30}, {\"reg\":2,\"val\":170}]}" },
{ "es8311", true,
"{\"init\":[ \
{\"reg\":1,\"val\":48}, {\"reg\":2,\"val\":0}, {\"reg\":3,\"val\":16}, {\"reg\":22,\"val\":36}, \
{\"reg\":4,\"val\":16}, {\"reg\":5,\"val\":0}, {\"reg\":11,\"val\":0}, {\"reg\":12,\"val\":0}, \
{\"reg\":16,\"val\":31}, {\"reg\":17,\"val\":127}, {\"reg\":0,\"val\":128}, {\"reg\":0,\"val\":128}, \
{\"reg\":1,\"val\":63}, {\"reg\":1,\"val\":63}, {\"reg\":2,\"val\":0}, {\"reg\":5,\"val\":0}, \
{\"reg\":3,\"val\":16}, {\"reg\":4,\"val\":16}, {\"reg\":7,\"val\":0}, {\"reg\":8,\"val\":255}, \
{\"reg\":6,\"val\":3}, {\"reg\":1,\"val\":63}, {\"reg\":6,\"val\":3}, {\"reg\":19,\"val\":16}, \
{\"reg\":27,\"val\":10}, {\"reg\":28,\"val\":106}, {\"reg\":9,\"val\":12}, {\"reg\":10,\"val\":12}, \
{\"reg\":9,\"val\":12}, {\"reg\":10,\"val\":12}, {\"reg\":50,\"val\":178}, {\"reg\":9,\"val\":12}, \
{\"reg\":10,\"val\":12}, {\"reg\":23,\"val\":191}, {\"reg\":14,\"val\":2} ,{\"reg\":18,\"val\":0}, \
{\"reg\":20,\"val\":26}, {\"reg\":20,\"val\":26}, {\"reg\":13,\"val\":1}, {\"reg\":21,\"val\":64}, \
{\"reg\":55,\"val\":72}, {\"reg\":69,\"val\":0}, {\"reg\":50,\"val\":200}]}" },
{ NULL, false, NULL }
};

View File

@@ -1,4 +1,4 @@
idf_component_register( SRC_DIRS . muse
idf_component_register( SRC_DIRS . muse guition
INCLUDE_DIRS .
PRIV_REQUIRES services
)

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "guition.c"
INCLUDE_DIRS "."
REQUIRES driver esp_common
)

View File

@@ -0,0 +1,43 @@
/*
* Guition JC4827W543C board support for squeezelite-esp32
*
* (c) Guition Board Support 2026
* Based on squeezelite-esp32 architecture
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include <string.h>
#include <esp_log.h>
#include <esp_types.h>
#include <esp_system.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "globdefs.h"
#include "monitor.h"
#include "targets.h"
static const char TAG[] = "guition";
static bool init(void);
const struct target_s target_guition = {
.model = "guition",
.init = init
};
static bool init(void) {
ESP_LOGI(TAG, "Initializing Guition JC4827W543C board");
ESP_LOGI(TAG, "Board features:");
ESP_LOGI(TAG, " - ESP32-S3-WROOM-1 processor");
ESP_LOGI(TAG, " - 4.3\" ILI9488 display (480x272)");
ESP_LOGI(TAG, " - GT911 capacitive touch");
ESP_LOGI(TAG, " - QSPI display interface");
ESP_LOGI(TAG, " - I2C touch interface (GPIO8/4)");
// No board-specific hardware initialization required
// All configuration is handled through NVS parameters
return true;
}

View File

@@ -1,7 +1,7 @@
#include "string.h"
#include "targets.h"
const struct target_s *target_set[] = { &target_muse, NULL };
const struct target_s *target_set[] = { &target_muse, &target_guition, NULL };
void target_init(char *target) {
for (int i = 0; *target && target_set[i]; i++) if (strcasestr(target_set[i]->model, target)) {

View File

@@ -20,3 +20,4 @@ struct target_s {
};
extern const struct target_s target_muse;
extern const struct target_s target_guition;

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -80,6 +80,8 @@ declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
@@ -244,6 +246,7 @@ declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare let sd: {};
declare let rf: boolean;
declare function refreshStatus(): void;

View File

@@ -1,5 +1,5 @@
target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.3b0bbfde52d921a84f9b.css.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.3fded7.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.3fded7.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.d35fda.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.d35fda.bundle.js.gz BINARY)

View File

@@ -6,29 +6,29 @@ extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_s
extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end");
extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start");
extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end");
extern const uint8_t _index_3fded7_bundle_js_gz_start[] asm("_binary_index_3fded7_bundle_js_gz_start");
extern const uint8_t _index_3fded7_bundle_js_gz_end[] asm("_binary_index_3fded7_bundle_js_gz_end");
extern const uint8_t _node_vendors_3fded7_bundle_js_gz_start[] asm("_binary_node_vendors_3fded7_bundle_js_gz_start");
extern const uint8_t _node_vendors_3fded7_bundle_js_gz_end[] asm("_binary_node_vendors_3fded7_bundle_js_gz_end");
extern const uint8_t _index_d35fda_bundle_js_gz_start[] asm("_binary_index_d35fda_bundle_js_gz_start");
extern const uint8_t _index_d35fda_bundle_js_gz_end[] asm("_binary_index_d35fda_bundle_js_gz_end");
extern const uint8_t _node_vendors_d35fda_bundle_js_gz_start[] asm("_binary_node_vendors_d35fda_bundle_js_gz_start");
extern const uint8_t _node_vendors_d35fda_bundle_js_gz_end[] asm("_binary_node_vendors_d35fda_bundle_js_gz_end");
const char * resource_lookups[] = {
"/css/index.3b0bbfde52d921a84f9b.css.gz",
"/favicon-32x32.png",
"/index.html.gz",
"/js/index.3fded7.bundle.js.gz",
"/js/node_vendors.3fded7.bundle.js.gz",
"/js/index.d35fda.bundle.js.gz",
"/js/node_vendors.d35fda.bundle.js.gz",
""
};
const uint8_t * resource_map_start[] = {
_index_3b0bbfde52d921a84f9b_css_gz_start,
_favicon_32x32_png_start,
_index_html_gz_start,
_index_3fded7_bundle_js_gz_start,
_node_vendors_3fded7_bundle_js_gz_start
_index_d35fda_bundle_js_gz_start,
_node_vendors_d35fda_bundle_js_gz_start
};
const uint8_t * resource_map_end[] = {
_index_3b0bbfde52d921a84f9b_css_gz_end,
_favicon_32x32_png_end,
_index_html_gz_end,
_index_3fded7_bundle_js_gz_end,
_node_vendors_3fded7_bundle_js_gz_end
_index_d35fda_bundle_js_gz_end,
_node_vendors_d35fda_bundle_js_gz_end
};

View File

@@ -1,6 +1,6 @@
/***********************************
webpack_headers
dist/css/index.3b0bbfde52d921a84f9b.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.3fded7.bundle.js.gz,dist/js/node_vendors.3fded7.bundle.js.gz
dist/css/index.3b0bbfde52d921a84f9b.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.d35fda.bundle.js.gz,dist/js/node_vendors.d35fda.bundle.js.gz
***********************************/
#pragma once
#include <inttypes.h>

View File

@@ -73,6 +73,10 @@ menu "Squeezelite-ESP32"
bool "T-WATCH2020 by LilyGo"
select I2C_LOCKED
select TARGET_LOCKED
config GUITION
bool "Guition JC4827W543C"
select I2C_LOCKED
select TARGET_LOCKED
endchoice
config RELEASE_API
string "Software update URL"
@@ -91,12 +95,14 @@ menu "Squeezelite-ESP32"
default "SqueezeAMP" if SQUEEZEAMP
default "Squeezelite-TWATCH" if TWATCH2020
default "Muse" if MUSE
default "Squeezelite-Guition" if GUITION
default "Squeezelite-ESP32"
config FW_PLATFORM_NAME
string
default "SqueezeAmp" if SQUEEZEAMP
default "TWATCH" if TWATCH2020
default "Muse" if MUSE
default "Guition" if GUITION
default "ESP32"
# AGGREGATES - begin
# these parameters are "aggregates" that take precedence. They must have a default value
@@ -105,6 +111,7 @@ menu "Squeezelite-ESP32"
default "model=TAS57xx,bck=33,ws=25,do=32,sda=27,scl=26,mute=14:0" if SQUEEZEAMP
default "model=I2S,bck=26,ws=25,do=33,i2c=53,sda=21,scl=22" if TWATCH2020
default "model=I2S,bck=5,ws=25,do=26,di=35,i2c=16,sda=18,scl=23,mck" if MUSE
default "model=I2S,bck=15,ws=16,do=17" if GUITION
default ""
config SPDIF_CONFIG
string
@@ -117,10 +124,12 @@ menu "Squeezelite-ESP32"
string
default "dc=27,data=19,clk=18" if TWATCH2020
default "mosi=15,miso=2,clk=14" if MUSE
default "clk=47,data=21,48,40,39,cs=45,host=2" if GUITION
default ""
config DISPLAY_CONFIG
string
default "SPI,driver=ST7789,width=240,height=240,cs=5,back=12,speed=16000000,HFlip,VFlip" if TWATCH2020
default "QSPI,driver=ILI9488,width=480,height=272,cs=45,speed=20000000,invert,rotate" if GUITION
default ""
config ETH_CONFIG
string
@@ -143,6 +152,7 @@ menu "Squeezelite-ESP32"
config TARGET
string
default "muse" if MUSE
default "guition" if GUITION
default ""
config AMP_GPIO
int
@@ -176,6 +186,7 @@ menu "Squeezelite-ESP32"
string
default "0=ir" if SQUEEZEAMP
default "" if TWATCH2020
default "1=backlight" if GUITION
endmenu
menu "Audio settings"
@@ -344,6 +355,7 @@ menu "Squeezelite-ESP32"
visible if !TWATCH2020
config I2C_CONFIG
string "I2C system configuration"
default "sda=8,scl=4,speed=400000,port=0" if GUITION
default ""
help
Set parameters of shared I2C interface

Binary file not shown.

View File

@@ -15,7 +15,7 @@ use Slim::Utils::Strings qw(string cstring);
use Slim::Utils::Log;
use Slim::Utils::Prefs;
use Plugins::SqueezeESP32::Player
use Plugins::SqueezeESP32::Player;
my $log = logger('player.RgbLed');
@@ -72,10 +72,10 @@ sub updateLED {
my $client = shift;
my $on = shift || 1;
my $cprefs = $prefs->client($client);
my $visu = $cprefs->get('led_visualizer') || 0;
my $bright = $cprefs->get('led_brightness') || 20;
$visu = 0 if ($visu < 0 || $visu > ledVisualizerNModes || !(Slim::Player::Source::playmode($client) eq 'play') || !$on);
my $modes = ledVisualizerModes;
my $params = $modes->[$visu]{'params'};
@@ -87,9 +87,9 @@ sub updateLED {
sub ledVisualParams {
my $client = shift;
my $visu = $prefs->client($client)->get('led_visualizer') || 0;
return $ledvisualizers[$visu]{params};
}
@@ -100,8 +100,8 @@ sub ledVisualModeOptions {
'-1' => ' '
};
my $modes = ledVisualizerModes;
my $nmodes = ledVisualizerNModes;
my $modes = ledVisualizerModes;
my $nmodes = ledVisualizerNModes;
for (my $i = 0; $i <= $nmodes; $i++) {
@@ -128,7 +128,7 @@ sub sendDMX {
# get our parameters
my $client = $request->client();
my $count = 0;
my $outData;
my @values = split(',', $request->getParam('_data') || '');
@@ -139,7 +139,7 @@ sub sendDMX {
$count /= 3;
my $data = pack('nn', $request->getParam('_xoff') || 0, $count ) . $outData;
# changed from dmxt to ledd (matches 'ledc' for tricolor led in receiver player)
$client->sendFrame( ledd => \$data );
}
@@ -155,28 +155,28 @@ sub setLEDVisu {
my $client = $request->client();
return if (!$client->hasLED);
my $cprefs = $prefs->client($client);
my $visu = $cprefs->get('led_visualizer') || 0;
my $mode = $request->getParam('_mode') || -1;
if ($mode == -1) {
$visu+=1;
} else {
$visu = $mode;
}
}
$visu = 0 if ($visu < 0 || $visu > ledVisualizerNModes);
$cprefs->set('led_visualizer', $visu);
my $bright = $request->getParam('_bright') || -1;
if ($bright >= 0 && $bright < 256) {
$cprefs->set('led_brightness', $bright);
}
updateLED($client);
# display name
my $modes = ledVisualizerModes;
my $modes = ledVisualizerModes;
my $desc = $modes->[$visu]{'desc'};
my $name = '';
for (my $j = 0; $j < scalar @$desc; $j++) {
@@ -193,7 +193,7 @@ sub setLEDVisu {
sub onNotification {
my $request = shift;
my $client = $request->client || return;
foreach my $player ($client->syncGroupActiveMembers) {
next unless $player->isa('Plugins::SqueezeESP32::Player');
updateLED($player) if $player->hasLED;
@@ -208,9 +208,9 @@ sub setMainMode {
$client->update();
return;
}
Slim::Buttons::Common::pushModeLeft($client, 'INPUT.Choice', {
'listRef' => [
'listRef' => [
{
name => string('PLUGIN_SQUEEZEESP32_LED_VISUALIZER'),
onPlay => sub { Slim::Control::Request::executeRequest($client, ['led_visual']); },
@@ -247,7 +247,7 @@ sub setLedvuBrightMode {
'increment' => 1,
'onChange' => sub {
my ($client, $value) = @_;
$bright = $bright + $value;
if ($bright > 0 && $bright <= 255) {
$prefs->client($client)->set('led_brightness', $bright);

View File

@@ -10,6 +10,6 @@
<name>PLUGIN_SQUEEZEESP32</name>
<description>PLUGIN_SQUEEZEESP32_DESC</description>
<module>Plugins::SqueezeESP32::Plugin</module>
<version>0.601</version>
<version>0.602</version>
<creator>Philippe</creator>
</extensions>

View File

@@ -1,10 +1,10 @@
<?xml version='1.0' standalone='yes'?>
<extensions>
<plugins>
<plugin version="0.601" name="SqueezeESP32" minTarget="7.9" maxTarget="*">
<plugin version="0.602" name="SqueezeESP32" minTarget="7.9" maxTarget="*">
<link>https://github.com/sle118/squeezelite-esp32</link>
<creator>Philippe</creator>
<sha>439637e01db7410157a333446cd284509f877849</sha>
<sha>590aaf4311716815585ebd9770c656cba54e4134</sha>
<email>philippe_44@outlook.com</email>
<desc lang="EN">SqueezeESP32 additional player id (100/101)</desc>
<url>http://raw.githubusercontent.com/sle118/squeezelite-esp32/master-v4.3/plugin/SqueezeESP32.zip</url>

View File

@@ -175,48 +175,48 @@ gWhuDSQPcaeDGHcy7NxRZHmlpHz+/Ot067VuxjGqm9veKNGZMUdroS+ocxAJBXv3
Z1NCCowvpZazNxKccQg7izYwd6HL70WMxCWFU0e70uw9KZqteG7SVcQ=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIIOzCCByOgAwIBAgIQCHNhNIH5XVH5G3SANwHecTANBgkqhkiG9w0BAQsFADA8
MIIIPDCCBySgAwIBAgIQBsMDe40cFre0eD3AUSN7oTANBgkqhkiG9w0BAQsFADA8
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
UlNBIDIwNDggTTAxMB4XDTI1MDkxOTAwMDAwMFoXDTI2MDgyMzIzNTk1OVowGzEZ
UlNBIDIwNDggTTAxMB4XDTI1MDUyMDAwMDAwMFoXDTI2MDUxNTIzNTk1OVowGzEZ
MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMdxOeavAJSP5sHcShN1qqDR2LF9RtWaXtp5bdgNNKlgt4buDh3f
EGe60xX+RNSANTeyWtUZ8fhtQ7ugj7OoMZi+a2KczPFj3Q34OgM/8+290Z9joZ0p
wkKNwY03qEO6vlr9E/qA0Y9A6xZBD6QNUmD7jR4Etqq7jtBFgocdjZ6bgMqGQ8Uh
Ss5qapqokrKQrbKZLBHKRCqYGoKwgD1ciXiV6iXuJj+GXDmwte7MZAfFyg5OJngh
GKNCMdU38AYRGrfTWoVH5RC67JlfZMenQBK9sB/XnrB3kOkRbBR/spRYsZg+mbaR
Q7uyPL0hTHyDu1KAe8BpmxYoDrvkmkLPr58CAwEAAaOCBVgwggVUMB8GA1UdIwQY
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBSLsv8vDlH1xvXIpmJ3
htLYjcrMszCCAokGA1UdEQSCAoAwggJ8ghBzMy5hbWF6b25hd3MuY29tghIqLnMz
LmFtYXpvbmF3cy5jb22CKCouczMtYWNjZXNzcG9pbnQudXMtZWFzdC0xLmFtYXpv
bmF3cy5jb22CJCouczMtY29udHJvbC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIk
czMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgicqLnMzLWRlcHJl
Y2F0ZWQudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVhbHN0
YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgh0qLnMzLWV4dGVybmFsLTIuYW1h
em9uYXdzLmNvbYIaczMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CMiouczMtYWNj
ZXNzcG9pbnQuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tghwqLnMz
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgh0qLnMzLWV4dGVybmFsLTEuYW1hem9u
YXdzLmNvbYImKi5zMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22C
G3MzLWV4dGVybmFsLTIuYW1hem9uYXdzLmNvbYIiczMtY29udHJvbC51cy1lYXN0
LTEuYW1hem9uYXdzLmNvbYIbczMtZXh0ZXJuYWwtMS5hbWF6b25hd3MuY29tgiVz
My1kZXByZWNhdGVkLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgi4qLnMzLWNvbnRy
b2wuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tMBMGA1UdIAQMMAow
ADCCAQoCggEBAMkF0zlDqMKf/RCOFH1yRIsuCK3ZLbpIlhBL36oSgpkV6KWTLfxX
E+wJjmsREQiiQ59B06QHYYRXOnuvks4h52IpnUiQ9Q4rlZblZM+llDeOJ4KPT+xf
3WhbXND0o0+7dvjHRPQeA0b0LGvS0wVnESI+fHtPES2e7zLSVTyc9Cd8py5U1RYJ
zE5oG601rrEUEUBVOMa/BUTF5sYNioJpuPK6E803VJUwpQj6MFIG7gAHtm6smDPq
4L4eRAlKkgQL2mqaRMI1h9K6SpW/hJrKf2V9D8jk4dHwGFBYJICR4hyl16EK2pSH
2uTaXBO3ykOmYJdIeXMRgfPvMKvY7PqErO0CAwEAAaOCBVkwggVVMB8GA1UdIwQY
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBQwNmD3HxPbjUExpM5y
rBUNT2tQKzCCAokGA1UdEQSCAoAwggJ8ghBzMy5hbWF6b25hd3MuY29tghIqLnMz
LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou
czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h
d3MuY29tgiQqLnMzLWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CInMz
LWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLiouczMtY29udHJvbC5k
dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh
bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz
dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYInKi5zMy1kZXByZWNhdGVkLnVz
LWVhc3QtMS5hbWF6b25hd3MuY29tgiVzMy1kZXByZWNhdGVkLnVzLWVhc3QtMS5h
bWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0xLmFtYXpvbmF3cy5jb22CHSouczMt
ZXh0ZXJuYWwtMS5hbWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0yLmFtYXpvbmF3
cy5jb22CHSouczMtZXh0ZXJuYWwtMi5hbWF6b25hd3MuY29tMBMGA1UdIAQMMAow
CAYGZ4EMAQIBMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
KwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0wMS5hbWF6
b250cnVzdC5jb20vcjJtMDEuY3JsMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw
AYYhaHR0cDovL29jc3AucjJtMDEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC
hipodHRwOi8vY3J0LnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5jZXIwDAYD
VR0TAQH/BAIwADCCAX0GCisGAQQB1nkCBAIEggFtBIIBaQFnAHYA2AlVO5RPev/I
FhlvlE+Fq7D4/F6HVSYPFdEucrtFSxQAAAGZY2zFywAABAMARzBFAiEA52TfXblf
xGMn7zs62yXq7rXB/ccKutSfyoReVaLtluACIFL9G5g8WzioAe/Tmx0cJjYXBzof
9go+a5TjVIY4bpnnAHYAwjF+V0UZo0XufzjespBB68fCIVoiv3/Vta12mtkOUs0A
AAGZY2zFywAABAMARzBFAiAdPbpyBei1fmph20ZWi1ZN7nl9b6EDX0s/gYxduL7k
CQIhAMeQp4B56jeit+b3akK3MHyTQoZBgR2CZMBZI6QVk5DUAHUAlE5Dh/rswe+B
8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGZY2zF4AAABAMARjBEAiBpEesssZJD
0SnUOe2Alz/5nGHs/Usxgzgz/xrMmEAXwAIgI90hHJajlzg30MZC3RKkXV8wezmC
pK+h+FLlSvMOUVowDQYJKoZIhvcNAQELBQADggEBAMMItDbq4GvNzuM8t2iBx90Z
F0hcsivxMOHbbxvBRrLtEYjY5wyvmGdWF2t24YFaYzyEMb0qX0YLxLGpoJCf5vIJ
olRHHgdDdkxg354SVQ4+SB1SvpJlAjyzqAGD4XQHAU3t0+jK+9OfJp8Zh57Z3jzI
zhA5ILi5hT3mW3hbHaNfvDpiauB6Sm9T0jc7853Msuh17LvABsIYlt2gVx48ivJc
oLmsInswJM2kWvD8WGTc0sG0wQfT6GNxEGG9anP3odTgdPUNnm8OKqW8nabzmhfu
sMKmxp3ShPpT0KiO5gBlGsMkDKu0+xKB0QjGaRoRbFC/9f0if9jQX5Hiz/xxpS4=
VR0TAQH/BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYADleUvPOuqT4z
GyyZB7P3kN+bwj1xMiXdIaklrGHFTiEAAAGW7u9atgAABAMARzBFAiA4KMndf6lu
8C+yaJ7up6OP9YBciHo9bM7OJZHEAfOqEgIhAIjeizxsehNRGTnNWdJuAeiY6/KH
fc0KJYhNi1SQeB4oAHYAZBHEbKQS7KeJHKICLgC8q08oB9QeNSer6v7VA8l9zfAA
AAGW7u9aawAABAMARzBFAiEAnLSyDZ1Iqy98eeZkxpjcWgLwdBBiEIX/reb2o913
UY4CIGFo/sopJL65RQAm4Li2y2ZOUXjxrceVHQJa7Vc0tZzmAHYASZybad4dfOz8
Nt7Nh2SmuFuvCoeAGdFVUvvp6ynd+MMAAAGW7u9afAAABAMARzBFAiA6UQ2zTUdW
ppxjrPv7r/JDZxM+C/jwL5xz0/aAcvr6OQIhAJQHGasiXNHE8KA715WY2hH2ylqH
xFz3o/m9fsdQaMTgMA0GCSqGSIb3DQEBCwUAA4IBAQB5mp7XHwC3cdInFeJJmg2z
YNYJiK6tnUy84V+NjlPl8UAdmPQb2oPdoHmngbrSzurqOUjI8LUtRLrOHCu872Tb
tvivDVGTm+aL5sXwfximkRV4je6ivj23hHF/8q29MVjqCE2k8SGgPd9PR2htPivg
GIlja7c3nxZ3HML3xlqMwpqIhmeHjQKbP494c63H5cShg+ORm5OCjUbuEXpCN0tl
BGQ0BnYQk0N0pOV2lNHdSK+DTdApUASGia1MlDmXSZfdSTeefVrjGck6lEXZlCI0
iqqNCx8PLJ8saAB97rif7iiP1z1HWj4CQTzojxyaFkPvfUa3kJC5HCnE7OQjVIxh
-----END CERTIFICATE-----

BIN
server_certs/r2m01.cer.56 Normal file

Binary file not shown.

View File

@@ -1,46 +1,46 @@
-----BEGIN CERTIFICATE-----
MIIIOzCCByOgAwIBAgIQCHNhNIH5XVH5G3SANwHecTANBgkqhkiG9w0BAQsFADA8
MIIIPDCCBySgAwIBAgIQBsMDe40cFre0eD3AUSN7oTANBgkqhkiG9w0BAQsFADA8
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
UlNBIDIwNDggTTAxMB4XDTI1MDkxOTAwMDAwMFoXDTI2MDgyMzIzNTk1OVowGzEZ
UlNBIDIwNDggTTAxMB4XDTI1MDUyMDAwMDAwMFoXDTI2MDUxNTIzNTk1OVowGzEZ
MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMdxOeavAJSP5sHcShN1qqDR2LF9RtWaXtp5bdgNNKlgt4buDh3f
EGe60xX+RNSANTeyWtUZ8fhtQ7ugj7OoMZi+a2KczPFj3Q34OgM/8+290Z9joZ0p
wkKNwY03qEO6vlr9E/qA0Y9A6xZBD6QNUmD7jR4Etqq7jtBFgocdjZ6bgMqGQ8Uh
Ss5qapqokrKQrbKZLBHKRCqYGoKwgD1ciXiV6iXuJj+GXDmwte7MZAfFyg5OJngh
GKNCMdU38AYRGrfTWoVH5RC67JlfZMenQBK9sB/XnrB3kOkRbBR/spRYsZg+mbaR
Q7uyPL0hTHyDu1KAe8BpmxYoDrvkmkLPr58CAwEAAaOCBVgwggVUMB8GA1UdIwQY
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBSLsv8vDlH1xvXIpmJ3
htLYjcrMszCCAokGA1UdEQSCAoAwggJ8ghBzMy5hbWF6b25hd3MuY29tghIqLnMz
LmFtYXpvbmF3cy5jb22CKCouczMtYWNjZXNzcG9pbnQudXMtZWFzdC0xLmFtYXpv
bmF3cy5jb22CJCouczMtY29udHJvbC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIk
czMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgicqLnMzLWRlcHJl
Y2F0ZWQudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVhbHN0
YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgh0qLnMzLWV4dGVybmFsLTIuYW1h
em9uYXdzLmNvbYIaczMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CMiouczMtYWNj
ZXNzcG9pbnQuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tghwqLnMz
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgh0qLnMzLWV4dGVybmFsLTEuYW1hem9u
YXdzLmNvbYImKi5zMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22C
G3MzLWV4dGVybmFsLTIuYW1hem9uYXdzLmNvbYIiczMtY29udHJvbC51cy1lYXN0
LTEuYW1hem9uYXdzLmNvbYIbczMtZXh0ZXJuYWwtMS5hbWF6b25hd3MuY29tgiVz
My1kZXByZWNhdGVkLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgi4qLnMzLWNvbnRy
b2wuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tMBMGA1UdIAQMMAow
ADCCAQoCggEBAMkF0zlDqMKf/RCOFH1yRIsuCK3ZLbpIlhBL36oSgpkV6KWTLfxX
E+wJjmsREQiiQ59B06QHYYRXOnuvks4h52IpnUiQ9Q4rlZblZM+llDeOJ4KPT+xf
3WhbXND0o0+7dvjHRPQeA0b0LGvS0wVnESI+fHtPES2e7zLSVTyc9Cd8py5U1RYJ
zE5oG601rrEUEUBVOMa/BUTF5sYNioJpuPK6E803VJUwpQj6MFIG7gAHtm6smDPq
4L4eRAlKkgQL2mqaRMI1h9K6SpW/hJrKf2V9D8jk4dHwGFBYJICR4hyl16EK2pSH
2uTaXBO3ykOmYJdIeXMRgfPvMKvY7PqErO0CAwEAAaOCBVkwggVVMB8GA1UdIwQY
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBQwNmD3HxPbjUExpM5y
rBUNT2tQKzCCAokGA1UdEQSCAoAwggJ8ghBzMy5hbWF6b25hd3MuY29tghIqLnMz
LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou
czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h
d3MuY29tgiQqLnMzLWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CInMz
LWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLiouczMtY29udHJvbC5k
dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh
bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz
dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYInKi5zMy1kZXByZWNhdGVkLnVz
LWVhc3QtMS5hbWF6b25hd3MuY29tgiVzMy1kZXByZWNhdGVkLnVzLWVhc3QtMS5h
bWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0xLmFtYXpvbmF3cy5jb22CHSouczMt
ZXh0ZXJuYWwtMS5hbWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0yLmFtYXpvbmF3
cy5jb22CHSouczMtZXh0ZXJuYWwtMi5hbWF6b25hd3MuY29tMBMGA1UdIAQMMAow
CAYGZ4EMAQIBMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
KwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0wMS5hbWF6
b250cnVzdC5jb20vcjJtMDEuY3JsMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw
AYYhaHR0cDovL29jc3AucjJtMDEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC
hipodHRwOi8vY3J0LnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5jZXIwDAYD
VR0TAQH/BAIwADCCAX0GCisGAQQB1nkCBAIEggFtBIIBaQFnAHYA2AlVO5RPev/I
FhlvlE+Fq7D4/F6HVSYPFdEucrtFSxQAAAGZY2zFywAABAMARzBFAiEA52TfXblf
xGMn7zs62yXq7rXB/ccKutSfyoReVaLtluACIFL9G5g8WzioAe/Tmx0cJjYXBzof
9go+a5TjVIY4bpnnAHYAwjF+V0UZo0XufzjespBB68fCIVoiv3/Vta12mtkOUs0A
AAGZY2zFywAABAMARzBFAiAdPbpyBei1fmph20ZWi1ZN7nl9b6EDX0s/gYxduL7k
CQIhAMeQp4B56jeit+b3akK3MHyTQoZBgR2CZMBZI6QVk5DUAHUAlE5Dh/rswe+B
8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGZY2zF4AAABAMARjBEAiBpEesssZJD
0SnUOe2Alz/5nGHs/Usxgzgz/xrMmEAXwAIgI90hHJajlzg30MZC3RKkXV8wezmC
pK+h+FLlSvMOUVowDQYJKoZIhvcNAQELBQADggEBAMMItDbq4GvNzuM8t2iBx90Z
F0hcsivxMOHbbxvBRrLtEYjY5wyvmGdWF2t24YFaYzyEMb0qX0YLxLGpoJCf5vIJ
olRHHgdDdkxg354SVQ4+SB1SvpJlAjyzqAGD4XQHAU3t0+jK+9OfJp8Zh57Z3jzI
zhA5ILi5hT3mW3hbHaNfvDpiauB6Sm9T0jc7853Msuh17LvABsIYlt2gVx48ivJc
oLmsInswJM2kWvD8WGTc0sG0wQfT6GNxEGG9anP3odTgdPUNnm8OKqW8nabzmhfu
sMKmxp3ShPpT0KiO5gBlGsMkDKu0+xKB0QjGaRoRbFC/9f0if9jQX5Hiz/xxpS4=
VR0TAQH/BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYADleUvPOuqT4z
GyyZB7P3kN+bwj1xMiXdIaklrGHFTiEAAAGW7u9atgAABAMARzBFAiA4KMndf6lu
8C+yaJ7up6OP9YBciHo9bM7OJZHEAfOqEgIhAIjeizxsehNRGTnNWdJuAeiY6/KH
fc0KJYhNi1SQeB4oAHYAZBHEbKQS7KeJHKICLgC8q08oB9QeNSer6v7VA8l9zfAA
AAGW7u9aawAABAMARzBFAiEAnLSyDZ1Iqy98eeZkxpjcWgLwdBBiEIX/reb2o913
UY4CIGFo/sopJL65RQAm4Li2y2ZOUXjxrceVHQJa7Vc0tZzmAHYASZybad4dfOz8
Nt7Nh2SmuFuvCoeAGdFVUvvp6ynd+MMAAAGW7u9afAAABAMARzBFAiA6UQ2zTUdW
ppxjrPv7r/JDZxM+C/jwL5xz0/aAcvr6OQIhAJQHGasiXNHE8KA715WY2hH2ylqH
xFz3o/m9fsdQaMTgMA0GCSqGSIb3DQEBCwUAA4IBAQB5mp7XHwC3cdInFeJJmg2z
YNYJiK6tnUy84V+NjlPl8UAdmPQb2oPdoHmngbrSzurqOUjI8LUtRLrOHCu872Tb
tvivDVGTm+aL5sXwfximkRV4je6ivj23hHF/8q29MVjqCE2k8SGgPd9PR2htPivg
GIlja7c3nxZ3HML3xlqMwpqIhmeHjQKbP494c63H5cShg+ORm5OCjUbuEXpCN0tl
BGQ0BnYQk0N0pOV2lNHdSK+DTdApUASGia1MlDmXSZfdSTeefVrjGck6lEXZlCI0
iqqNCx8PLJ8saAB97rif7iiP1z1HWj4CQTzojxyaFkPvfUa3kJC5HCnE7OQjVIxh
-----END CERTIFICATE-----

View File

@@ -0,0 +1,139 @@
#
# Guition JC4827W543C ESP32-S3 configuration
# Based on I2S-S3-sdkconfig with Guition-specific settings
#
# ESP32-S3 Target Configuration
CONFIG_IDF_TARGET="esp32s3"
CONFIG_IDF_TARGET_ESP32S3=y
CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009
# ESP32-S3 specific settings
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_SPEED_80M=y
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_TYPE_AUTO=y
CONFIG_SPIRAM_SIZE_AUTO=y
CONFIG_SPIRAM_USE_MALLOC=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
CONFIG_SPIRAM_USE_HEAP=y
CONFIG_SPIRAM_CACHE_WR=y
CONFIG_SPIRAM_CACHE_WR=y
# PSRAM Configuration
CONFIG_SPIRAM_BOOT_INIT=y
CONFIG_SPIRAM_IGNORE_NOTFOUND=n
CONFIG_SPIRAM_USE_MEMMAP=y
CONFIG_SPIRAM_USE_NOINIT=n
CONFIG_SPIRAM_USE_EMBEDDED_MEM=n
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
CONFIG_SPIRAM_USE_MALLOC=y
CONFIG_SPIRAM_USE_HEAP=y
CONFIG_SPIRAM_MEMTEST=y
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=n
# Performance Settings
CONFIG_ESP32S3_RTOS_INT_NUM=0
CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0
# Flash Configuration
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
# Partition Table
CONFIG_PARTITION_TABLE_SINGLE_APP=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_single_app.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_single_app.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000
# UART Configuration
CONFIG_ESP_CONSOLE_UART_DEFAULT=y
CONFIG_ESP_CONSOLE_UART_NUM=0
CONFIG_ESP_CONSOLE_UART_TX_GPIO=43
CONFIG_ESP_CONSOLE_UART_RX_GPIO=44
# GPIO Configuration
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
# FreeRTOS Configuration
CONFIG_FREERTOS_HZ=1000
# Log Configuration
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_LOG_MAXIMUM_LEVEL=3
# Component Configuration
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
CONFIG_LWIP_UDP_RECVMBOX_SIZE=6
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072
# WiFi Configuration
CONFIG_ESP32_WIFI_ENABLED=y
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
# Bluetooth Configuration (ESP32-S3 doesn't have Bluetooth Audio)
CONFIG_BT_ENABLED=y
CONFIG_BT_BLUEDROID_ENABLED=y
CONFIG_BT_CLASSIC_ENABLED=y
CONFIG_BT_SCO_ENABLED=y
CONFIG_BT_A2DP_ENABLE=y
CONFIG_BT_BLE_ENABLED=y
# ADC Configuration
CONFIG_ADC_CAL_EFUSE_TP_ENABLE=n
CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=n
CONFIG_ADC_CAL_LUT_ENABLE=n
# I2C Configuration
CONFIG_I2C_ENABLE_DEBUG_LOG=n
# SPI Configuration
CONFIG_SPI_MASTER_IN_IRAM=y
CONFIG_SPI_SLAVE_IN_IRAM=y
# Touch Configuration
CONFIG_TOUCH_PAD_SLEEP_CYCLE=2000
# FAT Filesystem
CONFIG_FATFS_LAZY_LOCK=y
CONFIG_FATFS_API_IN_IRAM=y
# Event Loop Library
CONFIG_EVENT_LOOP_PROFILING=n
# Ethernet
CONFIG_ETH_USE_ESP32_EMAC=n
# HTTP Server
CONFIG_HTTPD_WS_SUPPORT=y
# JSON Parser
CONFIG_JSON_ENABLE_DEBUG=n
# MDNS
CONFIG_MDNS_ENABLE_DEBUG=n
# MQTT
CONFIG_MQTT_PROTOCOL_311=y
CONFIG_MQTT_TRANSPORT_SSL=y
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
# OpenSSL
CONFIG_OPENSSL_DEBUG=n
# Protobuf-c
CONFIG_PROTOBUF_C_ENABLE_DEBUG=n
# WebSockets
CONFIG_WS_BUFFER_SIZE=1024
# NVS
CONFIG_NVS_ENCRYPTION=n
CONFIG_NVS_ASSERT_ERROR_CHECK=n