This commit is contained in:
thomas committed 2026-10-18 21:55:09 +02:00
1 parent 4b54d587fe
commit 2b9e574ba9
1 file changed
+880
+880
View File
@@ -0,0 +1,880 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>STM32H7S78-DK Audio Effects Processor - Documentation</title>
<style>
:root {
--primary-color: #2c3e50;
--secondary-color: #34495e;
--accent-color: #3498db;
--light-bg: #ecf0f1;
--dark-text: #2c3e50;
--code-bg: #f4f4f4;
--border-color: #bdc3c7;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: var(--dark-text);
background-color: var(--light-bg);
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* Header */
header {
background-color: var(--primary-color);
color: white;
padding: 40px 0;
text-align: center;
}
header h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
header .subtitle {
font-size: 1.2em;
opacity: 0.9;
}
/* Navigation */
nav {
background-color: var(--secondary-color);
padding: 10px 0;
position: sticky;
top: 0;
z-index: 100;
}
nav ul {
display: flex;
justify-content: center;
list-style: none;
gap: 30px;
}
nav a {
color: white;
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
}
nav a:hover {
color: var(--accent-color);
}
/* Main Content */
main {
padding: 40px 0;
}
section {
margin-bottom: 60px;
background: white;
border-radius: 8px;
padding: 40px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
section h2 {
color: var(--primary-color);
margin-bottom: 30px;
padding-bottom: 15px;
border-bottom: 2px solid var(--accent-color);
font-size: 2em;
}
section h3 {
color: var(--secondary-color);
margin: 25px 0 15px;
font-size: 1.3em;
}
section p {
margin-bottom: 15px;
}
/* Tables */
table {
width: 100%;
border-collapse: collapse;
margin: 25px 0;
}
table th, table td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid var(--border-color);
}
table th {
background-color: var(--accent-color);
color: white;
font-weight: 600;
}
table tr:hover {
background-color: var(--light-bg);
}
/* Code Blocks */
pre {
background-color: var(--code-bg);
padding: 20px;
border-radius: 5px;
overflow-x: auto;
border-left: 4px solid var(--accent-color);
margin: 20px 0;
}
code {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.9em;
background-color: var(--code-bg);
padding: 2px 6px;
border-radius: 3px;
}
.bash {
color: #27ae60;
}
.c {
color: #2980b9;
}
/* Steps */
.steps {
counter-reset: step-counter;
}
.step {
position: relative;
padding-left: 50px;
margin-bottom: 20px;
}
.step::before {
content: counter(step-counter);
counter-increment: step-counter;
position: absolute;
left: 0;
top: 0;
width: 35px;
height: 35px;
background-color: var(--accent-color);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
/* Hardware */
.hardware-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin: 25px 0;
}
.hardware-card {
background: var(--light-bg);
padding: 20px;
border-radius: 8px;
border: 1px solid var(--border-color);
}
.hardware-card h4 {
color: var(--primary-color);
margin-bottom: 10px;
font-size: 1.1em;
}
/* Colors */
.color-blue { color: var(--accent-color); }
.color-green { color: #27ae60; }
.color-orange { color: #e67e22; }
/* Footer */
footer {
background-color: var(--primary-color);
color: white;
text-align: center;
padding: 30px 0;
margin-top: 60px;
}
/* Responsive */
@media (max-width: 768px) {
header h1 { font-size: 2em; }
nav ul { flex-direction: column; align-items: center; gap: 15px; }
section { padding: 25px; }
}
</style>
</head>
<body>
<header>
<div class="container">
<h1>STM32H7S78-DK Audio Effects Processor</h1>
<div class="subtitle">Dual-Boot Audio Processing System with TouchGFX</div>
</div>
</header>
<nav>
<div class="container">
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#architecture">Architecture</a></li>
<li><a href="#hardware">Hardware</a></li>
<li><a href="#build">Build & Flash</a></li>
<li><a href="#debugging">Debugging</a></li>
<li><a href="#audio">Audio Processing</a></li>
<li><a href="#touchgfx">TouchGFX</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
</ul>
</div>
</nav>
<main class="container">
<!-- Overview Section -->
<section id="overview">
<h2>Project Overview</h2>
<p>This dual-boot project consists of two components working together to create a professional audio effects processor:</p>
<table>
<thead>
<tr>
<th>Project</th>
<th>Directory</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Boot</strong></td>
<td><code>/Boot/</code></td>
<td>Bootloader - initializes hardware, loads application from external flash</td>
</tr>
<tr>
<td><strong>Appli</strong></td>
<td><code>/Appli/</code></td>
<td>Main application - TouchGFX UI + audio processing</td>
</tr>
</tbody>
</table>
<h3>Key Features</h3>
<ul>
<li>Real-time audio effects processing at 48kHz sample rate</li>
<li>6 audio effects: Octaver, Equalizer, Overdrive, Saturation, Echo, Reverb</li>
<li>2048-point FFT spectrum analyzer with 1024 frequency bins</li>
<li>Audio looper with up to 5 seconds recording (2x playback speed)</li>
<li>TouchGFX graphical interface with NemaGFX GPU acceleration</li>
<li>Dual-boot architecture for reliable firmware updates</li>
</ul>
</section>
<!-- Architecture Section -->
<section id="architecture">
<h2>System Architecture</h2>
<h3>Dual-Boot Structure</h3>
<p>This project uses a <strong> dual-project architecture</strong>:</p>
<div class="hardware-grid">
<div class="hardware-card">
<h4>Boot Project</h4>
<p>Initializes the hardware platform</p>
<p>Loads Appli from external flash (0x70000000)</p>
<p>First stage of the boot process</p>
</div>
<div class="hardware-card">
<h4>Appli Project</h4>
<p>Main application execution</p>
<p>TouchGFX UI + audio processing</p>
<p>Uses external memory for assets</p>
</div>
</div>
<h3>Flashing Sequence</h3>
<div class="steps">
<div class="step">
<p>Flash <strong>Boot</strong> first (internal flash only)</p>
</div>
<div class="step">
<p>Flash <strong>Appli</strong> with external FlashLoader</p>
</div>
<div class="step">
<p>Press NRST button to start application</p>
</div>
</div>
<p><strong>Important:</strong> The Appli uses external memory (0x70000000) for TouchGFX assets and requires the external FlashLoader <code>MX66UW1G45G_STM32H7S78-DK.stldr</code> to program the external flash.</p>
<h3>Build System</h3>
<p><strong>Build System:</strong> GCC Makefile (not CMake)</p>
<p><strong>Toolchain:</strong> gcc-arm-embedded (arm-none-eabi-gcc)</p>
<p><strong>IDE:</strong> STM32CubeIDE with STM32CubeMX plugin</p>
<h3>Real-Time Operating System</h3>
<p><strong>RTOS:</strong> FreeRTOS V10.5.1 (CMSIS-RTOS V2)</p>
<p><strong>Heap Size:</strong> 50KB (heap_4)</p>
<p><strong>Task priorities:</strong> Audio interrupts at priority 2 (high), touch/SD at 14-15</p>
</section>
<!-- Hardware Section -->
<section id="hardware">
<h2>Hardware Specifications</h2>
<h3>Core Hardware</h3>
<table>
<thead>
<tr>
<th>Component</th>
<th>Specification</th>
</tr>
</thead>
<tbody>
<tr>
<td>Board</td>
<td>STM32H7S78-DK evaluation board</td>
</tr>
<tr>
<td>MCU</td>
<td>STM32H7S78 (Cortex-M7 @ 480MHz)</td>
</tr>
<tr>
<td>Internal Flash</td>
<td>2 MB</td>
</tr>
<tr>
<td>Internal RAM</td>
<td>1 MB</td>
</tr>
<tr>
<td>External PSRAM</td>
<td>8 MB (on XSPI1)</td>
</tr>
<tr>
<td>External Flash</td>
<td>128 MB (on XSPI2, MX66UW1G45G)</td>
</tr>
</tbody>
</table>
<h3>Audio Peripherals</h3>
<table>
<thead>
<tr>
<th>Peripheral</th>
<th>Interface</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td>ADF1</td>
<td>PDM (Digital)</td>
<td>Microphone input (48kHz sample rate)</td>
</tr>
<tr>
<td>Audio Codec</td>
<td>I2C1</td>
<td>Analog audio processing</td>
</tr>
<tr>
<td>DMA Channels</td>
<td>DMA2D/GPDMA1/HPDMA1</td>
<td>Audio data transfer</td>
</tr>
</tbody>
</table>
<h3>Display & Touch</h3>
<table>
<thead>
<tr>
<th>Peripheral</th>
<th>Specification</th>
</tr>
</thead>
<tbody>
<tr>
<td>Display Controller</td>
<td>LTDC (LCD-TFT)</td>
</tr>
<tr>
<td>GPU Acceleration</td>
<td>NemaGFX 2D</td>
</tr>
<tr>
<td>Display</td>
<td>ST7789 (240x240 RGB)</td>
</tr>
<tr>
<td>Touch Controller</td>
<td>FT5336 (Capacitive)</td>
</tr>
<tr>
<td>Touch Interface</td>
<td>SPI + GPIO (TP_IRQ)</td>
</tr>
</tbody>
</table>
<h3>Storage & Communication</h3>
<table>
<thead>
<tr>
<th>Interface</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td>XSPI1</td>
<td>External PSRAM (audio buffers + framebuffers)</td>
</tr>
<tr>
<td>XSPI2</td>
<td>External Flash (TouchGFX assets)</td>
</tr>
<tr>
<td>I2C1</td>
<td>Touch controller + sensors</td>
</tr>
<tr>
<td>SPI</td>
<td>Touch interrupt + SD card (optional)</td>
</tr>
</tbody>
</table>
</section>
<!-- Build & Flash Section -->
<section id="build">
<h2>Build & Flash Guide</h2>
<h3>Prerequisites</h3>
<ul>
<li>STM32CubeIDE (for CubeMX GUI, code generation)</li>
<li>gcc-arm-embedded (<code>arm-none-eabi-gcc</code>)</li>
<li><strong>STM32CubeProgrammer</strong> (for flashing with external loader)</li>
<li>TouchGFX 4.26.1 (for GUI generation)</li>
</ul>
<h3>Build Commands</h3>
<p><strong>From the project root directory:</strong></p>
<pre><code class="bash"># 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</code></pre>
<h3>Flashing Commands</h3>
<p><strong>Important:</strong> Flashing requires external FlashLoader for external memory access.</p>
<h4>Flash Boot (internal flash only)</h4>
<pre><code class="bash">STM32_Programmer_CLI -c port=SWD \
-d Boot/TouchGFX/build/bin/target.hex \
-hardRst</code></pre>
<h4>Flash Appli (requires external FlashLoader)</h4>
<pre><code class="bash">STM32_Programmer_CLI -c port=SWD \
-d Appli/TouchGFX/build/bin/target.hex \
-el gcc/MX66UW1G45G_STM32H7S78-DK.stldr \
-hardRst</code></pre>
<h3>VS Code Tasks</h3>
<p>Two VS Code tasks are available in <code>.vscode/tasks.json</code>:</p>
<ul>
<li><strong>Build + Flash Boot</strong> - Builds and flashes the Bootloader</li>
<li><strong>Build + Flash Appli</strong> - Builds and flashes the Application with external loader</li>
</ul>
<p><strong>Note:</strong> The Flash Loader for external memory is located at: <code>gcc/MX66UW1G45G_STM32H7S78-DK.stldr</code></p>
</section>
<!-- Debugging Section -->
<section id="debugging">
<h2>Debugging Guide</h2>
<p>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:</p>
<div class="steps">
<div class="step">
<p>Generate code in TouchGFX Designer</p>
</div>
<div class="step">
<p>Open the project in STM32CubeIDE</p>
</div>
<div class="step">
<p>Launch a debug session for the <strong>Boot</strong> project</p>
</div>
<div class="step">
<p>Wait for the compilation and flashing to complete</p>
</div>
<div class="step">
<p>Terminate the debug session (<code>Ctrl + F2</code>)</p>
</div>
<div class="step">
<p>Launch a debug session for the <strong>Appli</strong> project</p>
</div>
<div class="step">
<p>Wait for the compilation and flashing to complete</p>
</div>
<div class="step">
<p>Click <strong>Resume</strong> (<code>F8</code>)</p>
</div>
<div class="step">
<p>Press the black <strong>NRST</strong> button on the STM32H7S78-DK board</p>
</div>
<div class="step">
<p>The application is now at a break point at the first line of <code>main()</code> in the Appli project. If not, click Resume (<code>F8</code>) once more</p>
</div>
<div class="step">
<p>Proceed by clicking Resume (<code>F8</code>) or Step Over (<code>F6</code>)</p>
</div>
</div>
<h3>Command Line Debugging</h3>
<pre><code class="bash"># 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</code></pre>
</section>
<!-- Audio Processing Section -->
<section id="audio">
<h2>Audio Processing</h2>
<h3>Effects Chain</h3>
<p>The audio effects are processed in the following order:</p>
<div class="hardware-grid">
<div class="hardware-card">
<h4><span class="color-blue">1.</span> Octaver</h4>
<p>Dual-grain pitch shifting</p>
<p>Octaves: -2, -1, +1, +2</p>
</div>
<div class="hardware-card">
<h4><span class="color-blue">2.</span> Equalizer</h4>
<p>5-band graphic EQ</p>
<p>Frequency bands: 60Hz, 170Hz, 350Hz, 1kHz, 3kHz</p>
</div>
<div class="hardware-card">
<h4><span class="color-blue">3.</span> Overdrive</h4>
<p>Distortion effect</p>
<p>Adjustable drive and output gain</p>
</div>
<div class="hardware-card">
<h4><span class="color-blue">4.</span> Saturation</h4>
<p>Audio saturation</p>
<p>Warm tone enhancement</p>
</div>
<div class="hardware-card">
<h4><span class="color-blue">5.</span> Echo</h4>
<p>Delay-based echo</p>
<p>Adjustable delay time and feedback</p>
</div>
<div class="hardware-card">
<h4><span class="color-blue">6.</span> Reverb</h4>
<p>Room reverb</p>
<p>Simulates different acoustic environments</p>
</div>
</div>
<h3>Spectrum Analyzer</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>FFT Size</td>
<td>2048 points (real FFT)</td>
</tr>
<tr>
<td>Sample Rate</td>
<td>48 kHz</td>
</tr>
<tr>
<td>Frequency Bins</td>
<td>1024 (0 to 24 kHz spectrum)</td>
</tr>
<tr>
<td>Display</td>
<td>GUI Graph widget (1024 pixels)</td>
</tr>
<tr>
<td>Peak Detection</td>
<td>Frequency with maximum magnitude</td>
</tr>
</tbody>
</table>
<h3>AudioLooper</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sample Rate</td>
<td>48,000 Hz</td>
</tr>
<tr>
<td>Max Duration</td>
<td>5 seconds</td>
</tr>
<tr>
<td>Max Samples</td>
<td>240,000 samples</td>
</tr>
<tr>
<td>Playback Speed</td>
<td>2.0x (raises pitch by octave)</td>
</tr>
<tr>
<td>Buffer Size</td>
<td>937.5 KB</td>
</tr>
<tr>
<td>Storage Location</td>
<td>External PSRAM (0x70000000)</td>
</tr>
</tbody>
</table>
<h3>Memory Map</h3>
<table>
<thead>
<tr>
<th>Section</th>
<th>Location</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>AudioLooperBuffer</code></td>
<td>External PSRAM</td>
<td>Audio loop recording</td>
</tr>
<tr>
<td>TouchGFX framebuffers</td>
<td>External PSRAM</td>
<td>LCD display buffers</td>
</tr>
<tr>
<td>Heap</td>
<td>Internal RAM</td>
<td>FreeRTOS heap (50KB)</td>
</tr>
<tr>
<td>Stack</td>
<td>Internal RAM</td>
<td>Task stacks</td>
</tr>
</tbody>
</table>
</section>
<!-- TouchGFX Section -->
<section id="touchgfx">
<h2>TouchGFX Architecture</h2>
<h3>Project Structure</h3>
<pre><code class="bash">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</code></pre>
<h3>GUI Screens</h3>
<table>
<thead>
<tr>
<th>Screen</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>InitScreen</code></td>
<td>Initial splash screen with logo</td>
</tr>
<tr>
<td><code>Overview</code></td>
<td>Main screen with audio on/off, volume, looper button</td>
</tr>
<tr>
<td><code>Oscillo</code></td>
<td>Spectrum analyzer display (1024 frequency bins)</td>
</tr>
<tr>
<td><code>Octaver</code></td>
<td>Octaver effect tuning (levels for -2, -1, +1, +2 octaves)</td>
</tr>
<tr>
<td><code>Equalizer</code></td>
<td>5-band graphic EQ (60Hz, 170Hz, 350Hz, 1kHz, 3kHz)</td>
</tr>
<tr>
<td><code>Overdrive</code></td>
<td>Distortion effect (drive, output gain)</td>
</tr>
<tr>
<td><code>Saturation</code></td>
<td>Audio saturation (drive, output gain)</td>
</tr>
<tr>
<td><code>Echo</code></td>
<td>Delay-based echo (delay time, feedback)</td>
</tr>
<tr>
<td><code>Reverb</code></td>
<td>Room reverb (mix level, decay time)</td>
</tr>
</tbody>
</table>
<h3>TouchGFX Architecture</h3>
<ul>
<li><strong>Views:</strong> UI screen implementations</li>
<li><strong>Presenters:</strong> Business logic between views and model</li>
<li><strong>Model:</strong> Data storage and state management</li>
<li><strong>Assets:</strong> Images, fonts, videos stored in external flash</li>
</ul>
<h3>GPU Acceleration</h3>
<p>The application uses NemaGFX (GPU2D) for accelerated 2D rendering:</p>
<ul>
<li>Alpha blending</li>
<li>Image scaling</li>
<li>Color format conversion</li>
<li>Windowed rendering</li>
</ul>
</section>
<!-- Troubleshooting Section -->
<section id="troubleshooting">
<h2>Troubleshooting</h2>
<h3>Common Build Issues</h3>
<table>
<thead>
<tr>
<th>Error</th>
<th>Cause</th>
<th>Solution</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>"Upload size is bigger than flash memory size"</code></td>
<td>Trying to read too much memory (e.g., 1MB from 0x08000000)</td>
<td>Use smaller read size (64KB max for internal flash)</td>
</tr>
<tr>
<td><code>"Error: The read command you trying to perform (-u) is missing some arguments"</code></td>
<td>Incorrect STM32CubeProgrammer syntax for external loader</td>
<td>Use <code>-el &lt;loader.stldr&gt;</code> flag with correct loader path</td>
</tr>
<tr>
<td><code>External memory (0x70000000) not accessible</code></td>
<td>External FlashLoader not loaded</td>
<td>Flash Appli with <code>-el gcc/MX66UW1G45G_STM32H7S78-DK.stldr</code></td>
</tr>
<tr>
<td><code>Application runs but display is blank</code></td>
<td>Appli not flashed in external memory correctly</td>
<td>Re-flash Appli with external loader, verify with <code>-u 0x70000000</code> read</td>
</tr>
</tbody>
</table>
<h3>Verification Commands</h3>
<pre><code class="bash"># 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</code></pre>
<h3>Flashing Checklist</h3>
<div class="steps">
<div class="step">
<p>Ensure Boot is flashed first (without external loader)</p>
</div>
<div class="step">
<p>Use correct FlashLoader: <code>MX66UW1G45G_STM32H7S78-DK.stldr</code></p>
</div>
<div class="step">
<p>Verify HEX file exists: <code>Appli/TouchGFX/build/bin/target.hex</code></p>
</div>
<div class="step">
<p>Press NRST button after flashing Appli</p>
</div>
<div class="step">
<p>Check UART console for boot messages (if enabled)</p>
</div>
</div>
</section>
</main>
<footer>
<div class="container">
<p><strong>STM32H7S78-DK Audio Effects Processor</strong></p>
<p>Project built with STM32CubeIDE, TouchGFX 4.26.1, and FreeRTOS</p>
<p>Last updated: October 2026</p>
</div>
</footer>
</body>
</html>