diff --git a/firmware/include/config.h b/firmware/include/config.h index 1215ac3..e1b7871 100644 --- a/firmware/include/config.h +++ b/firmware/include/config.h @@ -54,10 +54,11 @@ // RGB LEDs // #ifdef JB_MOD_RGBLEDS - #define JB_RGBLEDS_REFRESH_INTERVAL 250 - #define JB_RGBLEDS_REFRESH_OFFSET 100 + #define JB_RGBLEDS_REFRESH_INTERVAL 100 + #define JB_RGBLEDS_REFRESH_OFFSET 0 #define JB_RGBLEDS_PIN 2 + #define JB_RGBLEDS_NUM 12 #define JB_RGBLEDS_FREQ 800000.f // #define JB_RGBLEDS_IS_RGBW // #endif diff --git a/firmware/include/rgb.h b/firmware/include/rgb.h index e0e100a..e7b6eec 100644 --- a/firmware/include/rgb.h +++ b/firmware/include/rgb.h @@ -5,7 +5,13 @@ #define JUKEBOX_WS2812_RGB_H void rgb_init(void); -void rgb_put_pixel(uint32_t pixel_grb); + +uint32_t rgb_to_grbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w); +uint32_t hsv_to_grbw(uint16_t hue, uint8_t sat, uint8_t val); + +void rgb_put(uint8_t idx, uint32_t pixel_grb); +void rgb_clear(void); +void rgb_present(void); void rgb_task(void); #endif // JUKEBOX_WS2812_RGB_H diff --git a/firmware/src/rgb.c b/firmware/src/rgb.c index 457bd2d..9beaf7e 100644 --- a/firmware/src/rgb.c +++ b/firmware/src/rgb.c @@ -14,35 +14,90 @@ PIO rgb_pio = pio1; int rgb_sm = 1; uint rgb_offset = 0; +uint32_t pixel_buf[JB_RGBLEDS_NUM] = {0}; + void rgb_init(void) { rgb_offset = pio_add_program(rgb_pio, &ws2812_program); ws2812_program_init(rgb_pio, rgb_sm, rgb_offset, JB_RGBLEDS_PIN, JB_RGBLEDS_FREQ, is_rgbw); } -void rgb_put_pixel(uint32_t pixel_grb) { - pio_sm_put_blocking(rgb_pio, rgb_sm, pixel_grb << 8u); +uint32_t rgb_to_grbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { + return ((uint32_t) (r) << 16) | ((uint32_t) (g) << 24) | ((uint32_t) (b) << 8)| ((uint32_t) (w)); +} + +uint32_t hsv_to_grbw(uint16_t hue, uint8_t sat, uint8_t val) { + uint8_t r, g, b; + hue = (hue * 1530L + 32768) / 65536; + if (hue < 510) { + b = 0; + if (hue < 255) { + r = 255; + g = hue; + } else { + r = 510 - hue; + g = 255; + } + } else if (hue < 1020) { + r = 0; + if (hue < 765) { + g = 255; + b = hue - 510; + } else { + g = 1020 - hue; + b = 255; + } + } else if (hue < 1530) { + g = 0; + if (hue < 1275) { + r = hue - 1020; + b = 255; + } else { + r = 255; + b = 1530 - hue; + } + } else { + r = 255; + g = b = 0; + } + + uint32_t v1 = 1 + val; + uint16_t s1 = 1 + sat; + uint8_t s2 = 255 - sat; + + return rgb_to_grbw( + ((((r * s1) >> 8) + s2) * v1) >> 8, + ((((g * s1) >> 8) + s2) * v1) >> 8, + ((((b * s1) >> 8) + s2) * v1) >> 8, + 0 + ); +} + +void rgb_put(uint8_t idx, uint32_t pixel_grbw) { + if (idx >= JB_RGBLEDS_NUM) { + return; + } + pixel_buf[idx] = pixel_grbw; +} + +void rgb_clear(void) { + for (uint8_t i = 0; i < JB_RGBLEDS_NUM; i++) { + rgb_put(i, 0); + } +} + +void rgb_present(void) { + for (uint8_t i = 0; i < JB_RGBLEDS_NUM; i++) { + pio_sm_put_blocking(rgb_pio, rgb_sm, pixel_buf[i]); + } } void rgb_task(void) { REFRESH_CHECK(JB_RGBLEDS_REFRESH_INTERVAL, JB_RGBLEDS_REFRESH_OFFSET); + rgb_clear(); + + for (uint8_t i = 0; i < JB_RGBLEDS_NUM; i++) { + rgb_put(i, hsv_to_grbw((time_us_32()>>8) - 512*i, 255, 4)); + } - rgb_put_pixel(0x000000); - rgb_put_pixel(0x020000); - rgb_put_pixel(0x000200); - rgb_put_pixel(0x000002); - - rgb_put_pixel(0x000000); - rgb_put_pixel(0x020200); - rgb_put_pixel(0x000202); - rgb_put_pixel(0x020002); - - rgb_put_pixel(0x000000); - rgb_put_pixel(0x020000); - rgb_put_pixel(0x000200); - rgb_put_pixel(0x000002); - - rgb_put_pixel(0x000000); - rgb_put_pixel(0x020202); - rgb_put_pixel(0x020202); - rgb_put_pixel(0x020202); + rgb_present(); }