qmk-firmwares/docs/ws2812_driver.md
Joshua Diamond 18e561b82c
Fix incorrect delay when setting WS2812 (and similar) leds (#9302)
* Fix incorrect delay when setting WS2812 (and similar) leds

* Add documentation for WS2812_DELAY_MICROSECONDS

* Remove improper cast to uint8_t

Co-authored-by: Sergey Vlasov <sigprof@gmail.com>

* Remove unneeded cast to uint8_t and correct math

Co-authored-by: Sergey Vlasov <sigprof@gmail.com>

* microseconds -> µs

Co-authored-by: Ryan <fauxpark@gmail.com>

* Make documentation better match the spec sheet.

Co-authored-by: Ryan <fauxpark@gmail.com>

* Rename macro to match spec sheet

* Further correction to the delay maths for the SPI case.

Co-authored-by: Joel Challis <git@zvecr.com>

* Move ws2812_common.h to the drivers directory

* Revert "Further correction to the delay maths for the SPI case."

This reverts commit e61b56a2cfc7dfec9992a7a3af92afa50e5b8ec0.

* Remove ws2812_setleds_pin(); consolidate ws2812.h

Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Joel Challis <git@zvecr.com>
2020-06-20 12:59:28 +10:00

121 lines
4.7 KiB
Markdown

# WS2812 Driver
This driver powers the [RGB Lighting](feature_rgblight.md) and [RGB Matrix](feature_rgb_matrix.md) features.
Currently QMK supports the following addressable LEDs (however, the white LED in RGBW variants is not supported):
WS2811, WS2812, WS2812B, WS2812C, etc.
SK6812, SK6812MINI, SK6805
These LEDs are called "addressable" because instead of using a wire per color, each LED contains a small microchip that understands a special protocol sent over a single wire. The chip passes on the remaining data to the next LED, allowing them to be chained together. In this way, you can easily control the color of the individual LEDs.
## Supported Driver Types
| | AVR | ARM |
|----------|--------------------|--------------------|
| bit bang | :heavy_check_mark: | :heavy_check_mark: |
| I2C | :heavy_check_mark: | |
| SPI | | :heavy_check_mark: |
| PWM | | :heavy_check_mark: |
## Driver configuration
### All drivers
Different versions of the addressable LEDs have differing requirements for the T<sub>RST</sub> period between frames.
The default setting is 280 µs, which should work for most cases, but this can be overridden in your config.h. e.g.:
```c
#define WS2812_TRST_US 80
```
### Bitbang
Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk:
```make
WS2812_DRIVER = bitbang
```
!> This driver is not hardware accelerated and may not be performant on heavily loaded systems.
### I2C
Targeting boards where WS2812 support is offloaded to a 2nd MCU. Currently the driver is limited to AVR given the known consumers are ps2avrGB/BMC. To configure it, add this to your rules.mk:
```make
WS2812_DRIVER = i2c
```
Configure the hardware via your config.h:
```c
#define WS2812_ADDRESS 0xb0 // default: 0xb0
#define WS2812_TIMEOUT 100 // default: 100
```
### SPI
Targeting STM32 boards where WS2812 support is offloaded to an SPI hardware device. The advantage is that the use of DMA offloads processing of the WS2812 protocol from the MCU. `RGB_DI_PIN` for this driver is the configured SPI MOSI pin. Due to the nature of repurposing SPI to drive the LEDs, the other SPI pins, MISO and SCK, **must** remain unused. To configure it, add this to your rules.mk:
```make
WS2812_DRIVER = spi
```
Configure the hardware via your config.h:
```c
#define WS2812_SPI SPID1 // default: SPID1
#define WS2812_SPI_MOSI_PAL_MODE 5 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5
```
You must also turn on the SPI feature in your halconf.h and mcuconf.h
#### Testing Notes
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
| | SPI1 | SPI2 | SPI3 |
|-|-|-|-|
| f072 | ? | B15 :heavy_check_mark: | N/A |
| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A |
| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: |
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*
### PWM
Targeting STM32 boards where WS2812 support is offloaded to an PWM timer and DMA stream. The advantage is that the use of DMA offloads processing of the WS2812 protocol from the MCU. To configure it, add this to your rules.mk:
```make
WS2812_DRIVER = pwm
```
Configure the hardware via your config.h:
```c
#define WS2812_PWM_DRIVER PWMD2 // default: PWMD2
#define WS2812_PWM_CHANNEL 2 // default: 2
#define WS2812_PWM_PAL_MODE 2 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2
#define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
#define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
```
You must also turn on the PWM feature in your halconf.h and mcuconf.h
#### Testing Notes
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
| | Status |
|-|-|
| f072 | ? |
| f103 | :heavy_check_mark: |
| f303 | :heavy_check_mark: |
| f401/f411 | :heavy_check_mark: |
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*
### Push Pull and Open Drain Configuration
The default configuration is a push pull on the defined pin.
This can be configured for bitbang, PWM and SPI.
Note: This only applies to STM32 boards.
To configure the `RGB_DI_PIN` to open drain configuration add this to your config.h file:
```c
#define WS2812_EXTERNAL_PULLUP
```