7.7 KiB
AGENTS.md
Hardware
- Board: STM32H7S78-DK evaluation board
- MCU: STM32H7S78 (Cortex-M7 @ 480MHz)
- Flash: 2 MB external OSPI Flash (for Boot)
- RAM: 1 MB internal + external PSRAM (for Audio/Framebuffers)
Project Architecture
Dual-Boot Structure
This project uses a dual-project architecture:
| Project | Directory | Purpose |
|---|---|---|
| Boot | /Boot/ |
Bootloader - initializes hardware, loads application from external flash |
| Appli | /Appli/ |
Main application - TouchGFX UI + audio processing |
Flashing order: Boot must be flashed first (without loader), then Appli (with external loader). After flashing Appli, press NRST button to start.
Note: The Appli uses external memory (0x70000000) for TouchGFX assets and requires the external FlashLoader MX66UW1G45G_STM32H7S78-DK.stldr to program the external flash.
Project Setup
- IDE: STM32CubeIDE with STM32CubeMX plugin
- RTOS: FreeRTOS V10.5.1 (CMSIS-RTOS V2)
- GUI: TouchGFX 4.26.1 with NemaGFX GPU acceleration
- Language: C/C++
- Build System: GCC Makefile (not CMake)
Key Constraints
- Dual-boot flashing sequence: Flash Boot first, then Appli. Press NRST after Appli flash.
- External FlashLoader required: Use
gcc/MX66UW1G45G_STM32H7S78-DK.stldrfor programming external flash (0x70000000) - Never edit
Core/Src/andCore/Inc/directly - regenerate via STM32CubeMX instead - High-speed audio acquisition (48kHz) - uses DMA for ADF1 (microphone) and audio codec
- External memory usage: Audio buffers (>900KB) stored in external PSRAM (section
AudioLooperBuffer) - TouchGFX architecture: Two-stage debug - debug Boot first, then Appli
- FreeRTOS heap size: Configured to 50KB in
FreeRTOSConfig.h(heap_4) - Interrupt priorities: Audio interrupts at priority 2 (high priority), touch/SD at 14-15
Build & Flash
Prerequisites
- STM32CubeIDE (for CubeMX GUI, code generation)
- gcc-arm-embedded (
arm-none-eabi-gcc) - STM32CubeProgrammer (for flashing with external loader)
- TouchGFX 4.26.1 (for GUI generation)
Build Commands
From /gcc/ directory:
make # Build both Boot and Appli
make clean # Clean all build artifacts
Individual projects:
# Build only Boot
make -f makefile_boot all
# Build only Appli
make -f makefile_appli all
Flashing Commands
Important: Flashing requires external FlashLoader for external memory access.
Flash Boot (internal flash only):
STM32_Programmer_CLI -c port=SWD \
-d Boot/TouchGFX/build/bin/target.hex \
-hardRst
Flash Appli (requires external FlashLoader for 0x70000000):
STM32_Programmer_CLI -c port=SWD \
-d Appli/TouchGFX/build/bin/target.hex \
-el gcc/MX66UW1G45G_STM32H7S78-DK.stldr \
-hardRst
Or using STM32CubeIDE GUI:
- Open STM32CubeIDE
- Connect ST-Link
- Right-click on project → Run As → 1 STM32CubeProgrammer
- Select the appropriate loader for external memory
Debugging
Two-stage debugging process:
- Debug Boot project first:
# In STM32CubeIDE:
# 1. Open Boot project
# 2. Launch debug session
# 3. Wait for compilation/flash complete
# 4. Terminate session (Ctrl+F2)
- Debug Appli project:
# In STM32CubeIDE:
# 1. Open Appli project
# 2. Launch debug session
# 3. Wait for compilation/flash complete
# 4. Click Resume (F8)
# 5. Press the black NRST button on the board
# 6. Application breaks at first line of main() in Appli
Command line (if needed):
# Start GDB server
openocd -f interface/jlink.cfg -f target/sth7rs.cfg
# In another terminal
arm-none-eabi-gdb gcc/target.elf
(gdb) target remote :3333
(gdb) load
(gdb) break main
(gdb) continue
Sensors/Peripherals
Audio (Primary Function)
- ADF1 - Digital microphone (PDM interface, 48kHz sample rate)
- I2C1 - Audio codec (STM32 Audio BSP)
- DMA2D/GPDMA1/HPDMA1 - Audio DMA channels
Display
- LTDC - LCD-TFT controller
- GPU2D (NemaGFX) - 2D acceleration
- Display: ST7789 (240x240 RGB)
Storage & Communication
- XSPI1 - External PSRAM (for audio buffers)
- XSPI2 - External Flash (for TouchGFX assets)
- I2C1 - Touch controller (FT5336), sensors
Touch Control
- FT5336 - Capacitive touch controller
- SPI - Touch interface
- GPIO - Touch interrupt (TP_IRQ)
Audio Processing
Effects Chain (in order)
- Octaver - Dual-grain pitch shifting (-2, -1, +1, +2 octaves)
- Equalizer - 5-band graphic EQ
- Overdrive - Distortion effect
- Saturation - Audio saturation
- Echo - Delay-based echo
- Reverb - Room reverb
Analysis
- FFT: 2048-point real FFT (CMSIS-DSP)
- Sample rate: 48kHz
- Bins: 1024 (0-24kHz spectrum)
- Peak detection: Frequency with maximum magnitude
Looping
- Duration: Up to 5 seconds at 48kHz
- Playback: 2x speed (raises pitch by octave)
- Storage: External PSRAM (937.5KB buffer)
TouchGFX Architecture
Project Structure
Appli/
├── TouchGFX/
│ ├── App/ # Application code (user created)
│ ├── assets/ # Images, fonts, videos
│ ├── build/ # Generated build files
│ ├── config/ # Build configuration
│ ├── generated/ # Auto-generated code (DO NOT EDIT)
│ ├── gui/ # Custom GUI code (views, presenters)
│ ├── simulator/ # Simulator files
│ └── target/ # Target-specific code
GUI Screens
- InitScreen - Initial splash screen
- Overview - Main screen with audio on/off, volume, looper button
- Oscillo - Spectrum analyzer display
- Octaver, Equalizer, Overdrive, Saturation, Echo, Reverb - Effect tuning screens
Memory Map
Key Sections
- AudioLooperBuffer - External PSRAM (audio loop recording)
- TouchGFX framebuffers - External PSRAM (LCD display)
- Heap - Internal RAM (50KB FreeRTOS heap)
- Stack - Internal RAM (task stacks)
External Memory
- PSRAM: 8MB (XSPI1) - Audio buffers + framebuffers
- Flash: 128MB (XSPI2) - TouchGFX assets (compressed images/fonts)
- External FlashLoader:
gcc/MX66UW1G45G_STM32H7S78-DK.stldr(required for programming external flash via STM32CubeProgrammer)
Data Logging
- Format: CSV (to be implemented)
- Storage: SD card via SPI (not currently implemented in main code)
- FATFS: File system (available via Middlewares/ST)
Last updated: October 2026 Project: STM32H7S78-DK Audio Effects Processor with TouchGFX
Last fixed: October 18, 2026 (Flashing method updated with external FlashLoader)
Flashing Troubleshooting
Common Issues
-
"Upload size is bigger than flash memory size"
- Cause: Trying to read too much memory (e.g., 1MB from 0x08000000)
- Solution: Use smaller read size (64KB max for internal flash)
-
"Error: The read command you trying to perform (-u) is missing some arguments"
- Cause: Incorrect STM32CubeProgrammer syntax for external loader
- Solution: Use
-el <loader.stldr>flag with correct loader path
-
External memory (0x70000000) not accessible
- Cause: External FlashLoader not loaded
- Solution: Flash Appli with
-el gcc/MX66UW1G45G_STM32H7S78-DK.stldr
-
Application runs but display is blank
- Cause: Appli not flashed in external memory correctly
- Solution: Re-flash Appli with external loader, verify with
-u 0x70000000read
Verification Commands
# Verify internal flash (Boot)
STM32_Programmer_CLI -c port=SWD -u 0x08000000 0x1000 /tmp/read_int.bin
# Verify external flash (Appli)
STM32_Programmer_CLI -c port=SWD -u 0x70000000 0x1000 /tmp/read_ext.bin