ws2812.c (1075B)
1#include "ws2812.h" 2#include "ws2812.pio.h" 3#include "util.h" 4 5#include "hardware/pio.h" 6#include "hardware/clocks.h" 7 8#define CYCLES_PER_BIT (ws2812_T1 + ws2812_T2 + ws2812_T3) 9 10void 11ws2812_init(struct ws2812 *pix, PIO pio, uint pin) 12{ 13 pio_sm_config config; 14 uint offset; 15 16 pix->pio = pio; 17 pix->pin = pin; 18 19 pix->sm = claim_unused_sm(pio); 20 21 pio_gpio_init(pio, pin); 22 pio_sm_set_consecutive_pindirs(pio, pix->sm, pin, 1, true); 23 24 offset = pio_add_program(pix->pio, &ws2812_program); 25 config = ws2812_program_get_default_config(offset); 26 sm_config_set_sideset_pins(&config, pin); 27 sm_config_set_out_shift(&config, false, true, 24); 28 sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_TX); 29 sm_config_set_clkdiv(&config, 30 (float) clock_get_hz(clk_sys) / (800000 * CYCLES_PER_BIT)); 31 32 pio_sm_init(pio, pix->sm, offset, &config); 33 pio_sm_set_enabled(pio, pix->sm, true); 34 35 pix->init = true; 36} 37 38void 39ws2812_put(struct ws2812 *pix, uint32_t rgb) { 40 rgb = ((rgb & 0xFF0000) >> 8) | ((rgb & 0x00FF00) << 8) 41 | (rgb & 0x0000FF); 42 pio_sm_put_blocking(pix->pio, pix->sm, rgb << 8u); 43}