• Stars
    star
    197
  • Rank 197,722 (Top 4 %)
  • Language
    C
  • Created over 6 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

WS2811, WS2812, WS2812B or compatible leds driver with STM32, TIM, PWM and DMA with minimum RAM required

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, or 1.25us pulse length for each bit
  • Transfer length is 24 pulses for each led, that's 30us for one LED
  • Each logical bit (1 or 0) consists of high and low part, with different length
  • Reset pulse is needed prior updating led strip, to synchronize sequence

WS2811 & WS2812 & WS2812B LED protocol

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.

STM32 DMA circular mode

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

Memory requirement

Memory requirement for one LED strip is split to:

  • 3 * leds_count to store read, green & blue colors for each led
  • 1 working buffer with size of 2 leds (48 elements), each element of 16/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

More Repositories

1

stm32f429

Keil projects and libraries for STM32F4xx devices
C
2,108
star
2

stm32-usart-uart-dma-rx-tx

STM32 examples for USART using DMA for efficient RX and TX transmission
C
1,247
star
3

c-code-style

Recommended C code style and coding rules for standard C99 or later
Python
994
star
4

lwrb

Lightweight generic ring buffer manager library
C
845
star
5

stm32fxxx-hal-libraries

Libraries for STM32F4xx and STM32F7xx built on HAL drivers from ST
C
755
star
6

stm32-cube-cmake-vscode

STM32, VSCode and CMake detailed tutorial
C
543
star
7

lwesp

Lightweight and versatile AT parser library for ESP8266 and ESP32 devices.
C
437
star
8

lwcell

Lightweight cellular modem host AT library
C
396
star
9

lwgps

Lightweight GPS NMEA parser for embedded systems
C
384
star
10

lwmem

Lightweight dynamic memory manager library for embedded systems with memory constraints. It implements malloc, calloc, realloc and free functions
C
285
star
11

lwow

Lightweight onewire protocol library optimized for UART hardware on embedded systems
C
183
star
12

lwprintf

Lightweight printf library optimized for embedded systems
C
183
star
13

EasyGUI

Easy GUI for microcontrollers
C
172
star
14

GSM_AT_commands_parser

Platform independent, ANSI C AT commands parser for SIMcom GSM modules
C
171
star
15

lwjson

Lightweight JSON parser for embedded systems
C
139
star
16

lwshell

Lightweight shell implementation for embedded systems
C
125
star
17

lwpkt

Lightweight packet protocol structure for multi-device communication focused on RS-485
C
113
star
18

doxygen-dark-theme

Dark theme for doxygen documentation generator
CSS
89
star
19

stm32h7-dual-core-inter-cpu-async-communication

Inter-CPU asynchronous communication between Cortex-M7 and Cortex-M4 cores on STM32H7 dual core devices
C
79
star
20

lwevt

Lightweight event management system for embedded systems
C
58
star
21

lwutil

Versatile and easy to use C language utility library with functions and macros commonly used in various applications
C
56
star
22

embedded-libs

Libraries for embedded software
C
54
star
23

lwbtn

Lightweight button handler for embedded systems
C
47
star
24

RegExp

Regular expressions library for embedded systems
C
35
star
25

lwdtc

Lightweight date, time & cron utilities for embedded systems
C
33
star
26

lwwdg

Lightweight watchdog for RTOS and embedded systems
C
24
star
27

touchgfx-cmake-vscode-stm32-simulator

TouchGFX simulator development in Visual Studio Code with CMake
C++
8
star
28

docs-majerle

Documentation parent project for docs.majerle.eu
7
star
29

iclocker

Official repository for IC Locker storage
JavaScript
6
star
30

learncpp

Learn C++ random repository
C++
2
star
31

mbedtls_playground

Playground for various mbedTLS test and learning scripts
C
1
star