39 #define WS2811_BITS_PER_LED 24
41 #define WS2811_DELAY_BUFFER_LENGTH 42
43 #define WS2811_TIMER_HZ 24000000
44 #define WS2811_TIMER_PERIOD 29 // 800KHz
46 #define BIT_COMPARE_1 17
48 #define BIT_COMPARE_0 9
50 #define PIOS_WS2811_MAGIC 0x00281100
80 memset(ws2811_dev, 0,
sizeof(*ws2811_dev) + buffer_size);
83 ws2811_dev->
config = ws2811_cfg;
87 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
88 TIM_OCInitTypeDef TIM_OCInitStructure;
89 DMA_InitTypeDef DMA_InitStructure;
91 GPIO_InitTypeDef gpio_cfg = {
93 .GPIO_Mode = GPIO_Mode_AF,
97 .GPIO_Speed = GPIO_Speed_50MHz,
98 .GPIO_OType = GPIO_OType_PP,
99 .GPIO_PuPd = GPIO_PuPd_NOPULL,
102 GPIO_Init(ws2811_cfg->
led_gpio, &gpio_cfg);
104 GPIO_PinAFConfig(ws2811_cfg->
led_gpio,
111 TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
113 TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
114 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
115 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
116 TIM_TimeBaseInit(ws2811_cfg->
timer, &TIM_TimeBaseStructure);
119 TIM_OCStructInit(&TIM_OCInitStructure);
120 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
121 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
122 TIM_OCInitStructure.TIM_Pulse = 5;
123 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
127 TIM_OC1Init(ws2811_cfg->
timer, &TIM_OCInitStructure);
128 TIM_OC1PreloadConfig(ws2811_cfg->
timer, TIM_OCPreload_Enable);
131 TIM_OC2Init(ws2811_cfg->
timer, &TIM_OCInitStructure);
132 TIM_OC2PreloadConfig(ws2811_cfg->
timer, TIM_OCPreload_Enable);
135 TIM_OC3Init(ws2811_cfg->
timer, &TIM_OCInitStructure);
136 TIM_OC3PreloadConfig(ws2811_cfg->
timer, TIM_OCPreload_Enable);
139 TIM_OC4Init(ws2811_cfg->
timer, &TIM_OCInitStructure);
140 TIM_OC4PreloadConfig(ws2811_cfg->
timer, TIM_OCPreload_Enable);
144 TIM_CtrlPWMOutputs(ws2811_cfg->
timer, ENABLE);
148 DMA_StructInit(&DMA_InitStructure);
149 DMA_InitStructure.DMA_PeripheralBaseAddr =
151 DMA_InitStructure.DMA_MemoryBaseAddr =
153 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
154 DMA_InitStructure.DMA_BufferSize = ws2811_dev->
buffer_size;
155 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
156 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
157 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
158 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
159 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
160 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
161 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
163 DMA_Init(ws2811_cfg->
dma_chan, &DMA_InitStructure);
167 TIM_Cmd(ws2811_cfg->
timer, ENABLE);
171 *dev_out = ws2811_dev;
177 uint8_t r, uint8_t g, uint8_t b)
189 uint32_t grb = (g << 16) | (r << 8) | b;
191 for (
int bit = (WS2811_BITS_PER_LED - 1); bit >= 0; --bit) {
const struct pios_ws2811_cfg * config
int PIOS_WS2811_get_num_leds(ws2811_dev_t dev)
Find out how many LEDs are configured on an interface.
Main PiOS header to include all the compiled in PiOS options.
void * PIOS_malloc(size_t size)
int PIOS_WS2811_init(ws2811_dev_t *dev_out, const struct pios_ws2811_cfg *cfg, int max_leds)
Allocate and initialise WS2811 device.
void PIOS_WS2811_set_all(ws2811_dev_t dev, uint8_t r, uint8_t g, uint8_t b)
Sets all LEDs to a color value.
#define PIOS_WS2811_MAGIC
#define WS2811_BITS_PER_LED
#define WS2811_DELAY_BUFFER_LENGTH
uint16_t timer_dma_source
void PIOS_WS2811_set(ws2811_dev_t dev, int idx, uint8_t r, uint8_t g, uint8_t b)
Set a given LED to a color value.
DMA_Channel_TypeDef * dma_chan
void PIOS_WS2811_trigger_update(ws2811_dev_t dev)
Trigger an update of the LED strand.
#define WS2811_TIMER_PERIOD