diff --git a/pio/ws2812/ws2812.c b/pio/ws2812/ws2812.c index fff4792d5..aa8eb4fc8 100644 --- a/pio/ws2812/ws2812.c +++ b/pio/ws2812/ws2812.c @@ -17,15 +17,19 @@ * Take into consideration if your WS2812 is a RGB or RGBW variant. * * If it is RGBW, you need to set IS_RGBW to true and provide 4 bytes per - * pixel (Red, Green, Blue, White) and use urgbw_u32(). + * pixel (Red, Green, Blue, White) and use urgb_u32() or urgbw_u32(). * * If it is RGB, set IS_RGBW to false and provide 3 bytes per pixel (Red, * Green, Blue) and use urgb_u32(). * * When RGBW is used with urgb_u32(), the White channel will be ignored (off). * + * Some strips only support 400Khz. + * + * Set IS_800KHz to false if your strip is like that. */ #define IS_RGBW false +#define IS_800KHz true #define NUM_PIXELS 150 #ifdef PICO_DEFAULT_WS2812_PIN @@ -40,6 +44,7 @@ #error Attempting to use a pin>=32 on a platform that does not support it #endif +#ifndef IS_RGBW static inline void put_pixel(PIO pio, uint sm, uint32_t pixel_grb) { pio_sm_put_blocking(pio, sm, pixel_grb << 8u); } @@ -50,14 +55,32 @@ static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) { ((uint32_t) (g) << 16) | (uint32_t) (b); } +#else +static inline void put_pixel(PIO pio, uint sm, uint32_t pixel_grb) { + pio_sm_put_blocking(pio, sm, pixel_grb); +} -static inline uint32_t urgbw_u32(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { +static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) { + return + ((uint32_t) (r) << 8) | + ((uint32_t) (g) << 16) | + (uint32_t) (b); +} + +/* + * NOTE: + * This code here is unused in this example, however can be useful if you want to set the white brightness too. + * Keeping it here for later reference. + * You may remove __attribute__((unused)) in case you use it. + */ +static inline uint32_t __attribute__((unused)) urgbw_u32(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { return ((uint32_t) (r) << 8) | ((uint32_t) (g) << 16) | ((uint32_t) (w) << 24) | (uint32_t) (b); } +#endif void pattern_snakes(PIO pio, uint sm, uint len, uint t) { for (uint i = 0; i < len; ++i) { @@ -91,7 +114,7 @@ void pattern_greys(PIO pio, uint sm, uint len, uint t) { uint max = 100; // let's not draw too much current! t %= max; for (uint i = 0; i < len; ++i) { - put_pixel(pio, sm, t * 0x10101); + put_pixel(pio, sm, t * 0x1010101); if (++t >= max) t = 0; } } @@ -108,11 +131,9 @@ const struct { }; int main() { - //set_sys_clock_48(); stdio_init_all(); printf("WS2812 Smoke Test, using pin %d\n", WS2812_PIN); - // todo get free sm PIO pio; uint sm; uint offset; @@ -123,7 +144,11 @@ int main() { bool success = pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_program, &pio, &sm, &offset, WS2812_PIN, 1, true); hard_assert(success); +#if IS_800KHz ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW); +#else + ws2812_program_init(pio, sm, offset, WS2812_PIN, 400000, IS_RGBW); +#endif int t = 0; while (1) {