The SDVX Controller firmware runs on an STM32F401CEU6 “BlackPill” v3.0 board. Every peripheral — buttons, rotary encoders, the WS2812B LED strip, and the DFU bootloader-control line — is assigned to a specific GPIO pin. This page is the authoritative reference for those assignments, drawn directly fromDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/MrJefter/sdvx-controller/llms.txt
Use this file to discover all available pages before exploring further.
main.h and the peripheral initialisation code in main.c.
All button inputs are configured with the STM32’s internal PULLUP resistor enabled. This means each GPIO pin sits at 3.3 V when the button is open, and is pulled to GND when the button is pressed — active-low logic. Do not add an external pull-down resistor to any of these pins.
Full pin assignment table
| Pin | Port | Firmware symbol | Function | Notes |
|---|---|---|---|---|
| PA1 | GPIOA | BTN4_Pin | BT-D button | GPIO_PULLUP, EXTI1, active-low |
| PA2 | GPIOA | BTN3_Pin | BT-C button | GPIO_PULLUP, EXTI2, active-low |
| PA3 | GPIOA | BTN2_Pin | BT-B button | GPIO_PULLUP, EXTI3, active-low |
| PA4 | GPIOA | FXL_Pin | FX-L button | GPIO_PULLUP, EXTI4, active-low |
| PA5 | GPIOA | BTN1_Pin | BT-A button | GPIO_PULLUP, EXTI9_5, active-low |
| PA6 | GPIOA | KNOBLA_Pin | VOL-L encoder — channel A | TIM3_CH1, quadrature input |
| PA7 | GPIOA | KNOBLB_Pin | VOL-L encoder — channel B | TIM3_CH2, quadrature input |
| PA9 | GPIOA | FXR_Pin | FX-R button | GPIO_PULLUP, EXTI9_5, active-low |
| PA10 | GPIOA | START_Pin | START button / DFU trigger | GPIO_PULLUP, EXTI15_10, active-low; hold 5 s to enter bootloader |
| PA15 | GPIOA | BOOT0_PIN | BOOT0 control output | Push-pull output; driven HIGH before system reset to select DFU mode |
| PB0 | GPIOB | (ws2812b.h) | WS2812B LED strip data out | 12 LEDs, DMA-driven PWM via TIM1 |
| PB6 | GPIOB | KNOBRA_Pin | VOL-R encoder — channel A | TIM4_CH1, quadrature input |
| PB7 | GPIOB | KNOBRB_Pin | VOL-R encoder — channel B | TIM4_CH2, quadrature input |
Timer configuration
Both rotary encoders are read in hardware using the STM32’s dedicated timer encoder interface. The firmware configures them identically.TIM3 — VOL-L (Left knob)
| Parameter | Value |
|---|---|
| Pins | PA6 (CH1 / A), PA7 (CH2 / B) |
| Encoder mode | TIM_ENCODERMODE_TI12 |
| Period (ARR) | 0xFFFF (65 535) |
| Prescaler | 0 (no division) |
| IC polarity | Rising on both channels |
| IC filter | 5 |
TIM4 — VOL-R (Right knob)
| Parameter | Value |
|---|---|
| Pins | PB6 (CH1 / A), PB7 (CH2 / B) |
| Encoder mode | TIM_ENCODERMODE_TI12 |
| Period (ARR) | 0xFFFF (65 535) |
| Prescaler | 0 (no division) |
| IC polarity | Rising on both channels |
| IC filter | 5 |
TIM_ENCODERMODE_TI12, which counts edges on both quadrature channels, giving four counts per physical detent on a standard encoder.
EXTI interrupt configuration
All button EXTI lines share the same priority settings, set duringMX_GPIO_Init():
| EXTI line | IRQ handler | Priority (preempt, sub) |
|---|---|---|
| EXTI1 | EXTI1_IRQn | (0, 0) |
| EXTI2 | EXTI2_IRQn | (0, 0) |
| EXTI3 | EXTI3_IRQn | (0, 0) |
| EXTI4 | EXTI4_IRQn | (0, 0) |
| EXTI9_5 | EXTI9_5_IRQn | (0, 0) |
| EXTI15_10 | EXTI15_10_IRQn | (0, 0) |
GPIO_MODE_IT_RISING_FALLING so the callback fires on both press and release edges. Software debouncing (3 ms lockout window) is applied inside HAL_GPIO_EXTI_Callback().
DFU bootloader entry
PA15 is a push-pull output that controls the BlackPill’s BOOT0 signal. When the START button (PA10) is held for 5 000 ms,GoToBootloader() drives PA15 HIGH and calls NVIC_SystemReset(). The MCU boots into the built-in USB DFU bootloader on the next power cycle.
This mechanism requires a 150 nF ceramic capacitor modification on the BlackPill board (see the hardware README). Without the capacitor, PA15 cannot reach BOOT0 in time before the reset cycle completes. If the modification has not been made, use the physical BOOT0 button on the BlackPill instead.