WS2811 and WS2812B driver for STM32 with TIM, PWM and DMA
This application note aims to explain architecture and understanding how to develop driver for addressable LEDs, such as WS2811, WS2812, WS2812B or any other matching protocol specifications.
Table of Contents
Github supports ToC by default. It is available in the top-left corner of this document.
Abbreviations
- DMA: Direct Memory Access controller in STM32
- TIM: Timer peripheral, general or advanced, w/ or w/o external channel (output compare or input capture)
- PWM: Pulse-Width-Modulation generated by TIM peripheral
- HT: Half-Transfer Complete DMA event/flag
- TC: Transfer Complete DMA event/flag
- IRQ: Interrupt
Understanding LED protocol
WS2811 and WS2812 protocol is specific one and has defined values:
- Transfer rate is
800 kHz
, or1.25us
pulse length for each bit - Transfer length is
24
pulses for each led, that's30us
for one LED - Each logical bit (
1
or0
) consists of high and low part, with different length - Reset pulse is needed prior updating led strip, to synchronize sequence
Minimum reset pulse length depends on WS281x device. Check datasheet for your particular unit. WS2812B says
> 50us
, while WS2811 says> 280us
.
STM32 TIM and PWM
Several STM32 timers (TIM) have support for Capture/Compare channels, connect to output pins, and being able to generate PWM pulses.
According to protocol (also explained above), timer should be able to generate 3
type of pulses:
- All-time zero to emulate reset pulse
- Logical bit
1
with~3/4
of time being high and low for the rest of the time - Logical bit
0
with~1/4
of time being high and low for the rest of the time
Furthemore, timer should be configured to generate update event for 800 kHz
, with auto-reload register (TIMx->ARR
) set to TIMx->ARR = timer_kernel_clock / 800000 - 1
and prescaler = 0
for maximum resolution.
Timer does not support a look-up table to know if logical bit 1
or 0
is next, hence we will utilize DMA feature to implement this task.
Timer channel allows DMA requests to load next value to channel compare register, and effectively implement look-up table with data transfer from memory to timer peripheral.
STM32 Timer Cookbook is a great starting point to understand how timers work in STM32s.
STM32 DMA
DMA controllers in STM32s support various operations, one of them being super handy for our WS LED driver, called circular operation mode. Circular mode will continuously transmit data from memory to peripheral (or, in general, can also go opposite direction) and periodically send transfer-complete or half-transfer-complete interrupts to the application.
We will use HT and TC events extensively, as they will be use to prepare data for next operations to transfer all bits for all leds. More explained in the later sections.
List of some useful STM32 DMA application notes
- AN4031 - Using the STM32F2, STM32F4 and STM32F7 Series DMA controller
- AN2548 - Using the STM32F0/F1/F3/Gx/Lx Series DMA controller
- AN5593 - How to use the GPDMA for STM32U575/585 microcontrollers
- AN5224 - STM32 DMAMUX: the DMA request router
- STM32H7 DMA
Memory requirement
Memory requirement for one LED strip is split to:
3 * leds_count
to store read, green & blue colors for each led1
working buffer with size of2
leds (48
elements), each element of16/32
bits, depending on used TIM peripheral
Putting it all together
To put all together, application developer must:
- Decide to use one timer with PWM generation support with one channel
- Select one DMA channel/stream/dmamux (depends on STM32) for selected timer and channel
- Put DMA in circular mode and enable HT and TC interrupts
- Use HT and TC events to prepare data for next operation
- HT event is used to prepare data at the beginning of memory (part of memory just completed with transmision)
- TC event is used to prepare data for second part of memory
Examples are extensively commented and should provide necessary understanding for application development
Examples
Examples can be used as reference code to implement your own LED driver with your own STM32.
- Developed in STM32CubeIDE for easier evaluation on STM32 boards
- Supports CMake and VSCode development
- Uses LL or HAL drivers
- Demos for various STM32
STM32 family | Board name | TIM & CH | GPIO | DMA settings |
---|---|---|---|---|
STM32G0xx | NUCLEO-G0B1RE |
TIM2 CH4 |
PA3 |
DMA2 , Channel 5 |