Project Overview
This dual-boot project consists of two components working together to create a professional audio effects processor:
| Project | Directory | Purpose |
|---|---|---|
| Boot | /Boot/ |
Bootloader - initializes hardware, loads application from external flash |
| Appli | /Appli/ |
Main application - TouchGFX UI + audio processing |
Key Features
- Real-time audio effects processing at 48kHz sample rate
- 6 audio effects: Octaver, Equalizer, Overdrive, Saturation, Echo, Reverb
- 2048-point FFT spectrum analyzer with 1024 frequency bins
- Audio looper with up to 5 seconds recording (2x playback speed)
- TouchGFX graphical interface with NemaGFX GPU acceleration
- Dual-boot architecture for reliable firmware updates
System Architecture
Dual-Boot Structure
This project uses a dual-project architecture:
Boot Project
Initializes the hardware platform
Loads Appli from external flash (0x70000000)
First stage of the boot process
Appli Project
Main application execution
TouchGFX UI + audio processing
Uses external memory for assets
Flashing Sequence
Flash Boot first (internal flash only)
Flash Appli with external FlashLoader
Press NRST button to start application
Important: The Appli uses external memory (0x70000000) for TouchGFX assets and requires the external FlashLoader MX66UW1G45G_STM32H7S78-DK.stldr to program the external flash.
Build System
Build System: GCC Makefile (not CMake)
Toolchain: gcc-arm-embedded (arm-none-eabi-gcc)
IDE: STM32CubeIDE with STM32CubeMX plugin
Real-Time Operating System
RTOS: FreeRTOS V10.5.1 (CMSIS-RTOS V2)
Heap Size: 50KB (heap_4)
Task priorities: Audio interrupts at priority 2 (high), touch/SD at 14-15
Hardware Specifications
Core Hardware
| Component | Specification |
|---|---|
| Board | STM32H7S78-DK evaluation board |
| MCU | STM32H7S78 (Cortex-M7 @ 480MHz) |
| Internal Flash | 2 MB |
| Internal RAM | 1 MB |
| External PSRAM | 8 MB (on XSPI1) |
| External Flash | 128 MB (on XSPI2, MX66UW1G45G) |
Audio Peripherals
| Peripheral | Interface | Purpose |
|---|---|---|
| ADF1 | PDM (Digital) | Microphone input (48kHz sample rate) |
| Audio Codec | I2C1 | Analog audio processing |
| DMA Channels | DMA2D/GPDMA1/HPDMA1 | Audio data transfer |
Display & Touch
| Peripheral | Specification |
|---|---|
| Display Controller | LTDC (LCD-TFT) |
| GPU Acceleration | NemaGFX 2D |
| Display | ST7789 (240x240 RGB) |
| Touch Controller | FT5336 (Capacitive) |
| Touch Interface | SPI + GPIO (TP_IRQ) |
Storage & Communication
| Interface | Purpose |
|---|---|
| XSPI1 | External PSRAM (audio buffers + framebuffers) |
| XSPI2 | External Flash (TouchGFX assets) |
| I2C1 | Touch controller + sensors |
| SPI | Touch interrupt + SD card (optional) |
Build & Flash Guide
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 the project root directory:
# Build both Boot and Appli
make
# Clean all build artifacts
make clean
# Build only Boot
make -f gcc/makefile_boot all
# Build only Appli
make -f gcc/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)
STM32_Programmer_CLI -c port=SWD \
-d Appli/TouchGFX/build/bin/target.hex \
-el gcc/MX66UW1G45G_STM32H7S78-DK.stldr \
-hardRst
VS Code Tasks
Two VS Code tasks are available in .vscode/tasks.json:
- Build + Flash Boot - Builds and flashes the Bootloader
- Build + Flash Appli - Builds and flashes the Application with external loader
Note: The Flash Loader for external memory is located at: gcc/MX66UW1G45G_STM32H7S78-DK.stldr
Debugging Guide
Debugging the code in an IDE can be complex because of the Bootloader and Application structure. To step through the code of the TouchGFX application in STM32CubeIDE, follow these steps:
Generate code in TouchGFX Designer
Open the project in STM32CubeIDE
Launch a debug session for the Boot project
Wait for the compilation and flashing to complete
Terminate the debug session (Ctrl + F2)
Launch a debug session for the Appli project
Wait for the compilation and flashing to complete
Click Resume (F8)
Press the black NRST button on the STM32H7S78-DK board
The application is now at a break point at the first line of main() in the Appli project. If not, click Resume (F8) once more
Proceed by clicking Resume (F8) or Step Over (F6)
Command Line Debugging
# Terminal 1: Start GDB server
openocd -f interface/jlink.cfg -f target/sth7rs.cfg
# Terminal 2: Connect with GDB
arm-none-eabi-gdb gcc/target.elf
(gdb) target remote :3333
(gdb) load
(gdb) break main
(gdb) continue
Audio Processing
Effects Chain
The audio effects are processed in the following order:
1. Octaver
Dual-grain pitch shifting
Octaves: -2, -1, +1, +2
2. Equalizer
5-band graphic EQ
Frequency bands: 60Hz, 170Hz, 350Hz, 1kHz, 3kHz
3. Overdrive
Distortion effect
Adjustable drive and output gain
4. Saturation
Audio saturation
Warm tone enhancement
5. Echo
Delay-based echo
Adjustable delay time and feedback
6. Reverb
Room reverb
Simulates different acoustic environments
Spectrum Analyzer
| Parameter | Value |
|---|---|
| FFT Size | 2048 points (real FFT) |
| Sample Rate | 48 kHz |
| Frequency Bins | 1024 (0 to 24 kHz spectrum) |
| Display | GUI Graph widget (1024 pixels) |
| Peak Detection | Frequency with maximum magnitude |
AudioLooper
| Parameter | Value |
|---|---|
| Sample Rate | 48,000 Hz |
| Max Duration | 5 seconds |
| Max Samples | 240,000 samples |
| Playback Speed | 2.0x (raises pitch by octave) |
| Buffer Size | 937.5 KB |
| Storage Location | External PSRAM (0x70000000) |
Memory Map
| Section | Location | Purpose |
|---|---|---|
AudioLooperBuffer |
External PSRAM | Audio loop recording |
| TouchGFX framebuffers | External PSRAM | LCD display buffers |
| Heap | Internal RAM | FreeRTOS heap (50KB) |
| Stack | Internal RAM | Task stacks |
TouchGFX Architecture
Project Structure
Appli/
└── TouchGFX/
├── App/ # Application code (user created)
├── assets/ # Images, fonts, videos
├── build/ # Generated build files
│ └── bin/
│ ├── target.hex # Flash image (INTERNAL)
│ └── target.bin # Binary image (EXTERNAL)
├── config/ # Build configuration
├── generated/ # Auto-generated code (DO NOT EDIT)
├── gui/ # Custom GUI code (views, presenters)
│ ├── views/ # Screen views
│ ├── presenters/ # Presenter logic
│ └── model/ # Model data
├── simulator/ # Simulator files
└── target/ # Target-specific code
GUI Screens
| Screen | Description |
|---|---|
InitScreen |
Initial splash screen with logo |
Overview |
Main screen with audio on/off, volume, looper button |
Oscillo |
Spectrum analyzer display (1024 frequency bins) |
Octaver |
Octaver effect tuning (levels for -2, -1, +1, +2 octaves) |
Equalizer |
5-band graphic EQ (60Hz, 170Hz, 350Hz, 1kHz, 3kHz) |
Overdrive |
Distortion effect (drive, output gain) |
Saturation |
Audio saturation (drive, output gain) |
Echo |
Delay-based echo (delay time, feedback) |
Reverb |
Room reverb (mix level, decay time) |
TouchGFX Architecture
- Views: UI screen implementations
- Presenters: Business logic between views and model
- Model: Data storage and state management
- Assets: Images, fonts, videos stored in external flash
GPU Acceleration
The application uses NemaGFX (GPU2D) for accelerated 2D rendering:
- Alpha blending
- Image scaling
- Color format conversion
- Windowed rendering
Troubleshooting
Common Build Issues
| Error | Cause | Solution |
|---|---|---|
"Upload size is bigger than flash memory size" |
Trying to read too much memory (e.g., 1MB from 0x08000000) | Use smaller read size (64KB max for internal flash) |
"Error: The read command you trying to perform (-u) is missing some arguments" |
Incorrect STM32CubeProgrammer syntax for external loader | Use -el <loader.stldr> flag with correct loader path |
External memory (0x70000000) not accessible |
External FlashLoader not loaded | Flash Appli with -el gcc/MX66UW1G45G_STM32H7S78-DK.stldr |
Application runs but display is blank |
Appli not flashed in external memory correctly | Re-flash Appli with external loader, verify with -u 0x70000000 read |
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
Flashing Checklist
Ensure Boot is flashed first (without external loader)
Use correct FlashLoader: MX66UW1G45G_STM32H7S78-DK.stldr
Verify HEX file exists: Appli/TouchGFX/build/bin/target.hex
Press NRST button after flashing Appli
Check UART console for boot messages (if enabled)