From 1402dad8c392e65feccf22d9c87c05bd863f9d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sun, 23 Oct 2022 17:27:18 +0200 Subject: [PATCH] First completed version --- animation.c | 7 ++-- include/animation.h | 5 +-- main.c | 80 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/animation.c b/animation.c index f89efa5..72156c2 100644 --- a/animation.c +++ b/animation.c @@ -17,6 +17,7 @@ static void reset_rainbow_to_start(struct animation *ani) ani->rb_start_color.red = RAINBOW_MAX_COL; ani->rb_start_color.blue = 0u; ani->rb_start_color.green = 0u; + ani->rb_start_color.white = 0u; } void animation_reset(struct animation *ani) @@ -68,7 +69,7 @@ static enum animation_state next_col_state(enum animation_state current) * @param[in,out] current_state Current rainbow state * @param[in, out] col Current color */ -static void rainbow_color_advance(enum rainbow_state *current_state, struct rgb_color *col) +static void rainbow_color_advance(enum rainbow_state *current_state, struct rgbw_color *col) { enum rainbow_state state; @@ -134,7 +135,7 @@ static bool animation_rainbow(struct animation *ani, uint8_t *dmx_universe) { bool ret = false; enum rainbow_state led_state; - struct rgb_color color; + struct rgbw_color color; uint32_t idx; /* Get the start state of first led */ @@ -146,7 +147,7 @@ static bool animation_rainbow(struct animation *ani, uint8_t *dmx_universe) dmx_universe[idx * 4 + 0] = color.red; dmx_universe[idx * 4 + 1] = color.green; dmx_universe[idx * 4 + 2] = color.blue; - dmx_universe[idx * 4 + 3] = 0u; + dmx_universe[idx * 4 + 3] = color.white; /* Sdvance rainbow color */ rainbow_color_advance(&led_state, &color); diff --git a/include/animation.h b/include/animation.h index 85aab2b..6f2e733 100644 --- a/include/animation.h +++ b/include/animation.h @@ -11,10 +11,11 @@ enum animation_state { ANI_FLASH_WHITE, }; -struct rgb_color { +struct rgbw_color { uint8_t red; uint8_t green; uint8_t blue; + uint8_t white; }; enum rainbow_state { @@ -29,7 +30,7 @@ enum rainbow_state { struct animation { enum animation_state state; enum rainbow_state rb_start_state; - struct rgb_color rb_start_color; + struct rgbw_color rb_start_color; uint32_t step; uint32_t last_tick; uint32_t next_interval; diff --git a/main.c b/main.c index 6210312..1fda20c 100644 --- a/main.c +++ b/main.c @@ -19,9 +19,9 @@ enum color_mode { MODE_BLUE, MODE_RGB, MODE_WHITE_DISCRETE, - MODE_WHITE_ANGLE, - MODE_RED_BLUE_RING, MODE_ANIMATION, + MODE_GREEN_BLUE_ANGLE, + MODE_WHITE_ANGLE, MODE_DMX_SHUTDOWN, }; @@ -66,12 +66,61 @@ static void setup_pins(void) GPIOB->PUPDR = PULLUP(1); } +static uint32_t map_index_to_range(int32_t index, uint32_t len) +{ + int32_t mapped; + + if (index < 0) { + mapped = len - (-index) % len; + } else { + mapped = index % len; + } + + return (uint32_t)mapped; +} + +static void dmx_universe_set_rgbw(uint32_t led_idx, const struct rgbw_color *col) +{ + dmx_universe[led_idx * 4 + 0] = col->red; + dmx_universe[led_idx * 4 + 1] = col->green; + dmx_universe[led_idx * 4 + 2] = col->blue; + dmx_universe[led_idx * 4 + 3] = col->white; +} + +static void set_angle(uint32_t led_count, uint32_t pos, uint32_t width, const struct rgbw_color *col, const struct rgbw_color *rest) +{ + int32_t lower_end; + int32_t upper_end; + int32_t idx; + int32_t mapped_idx; + + if (width > led_count) + return; + + upper_end = pos + width / 2u; + lower_end = pos - width / 2u; + + /* Set leds to color */ + for (idx = lower_end; idx <= upper_end; idx++) { + mapped_idx = map_index_to_range(idx, led_count); + dmx_universe_set_rgbw(mapped_idx, col); + } + + /* Set the rest ring to rest color */ + for (idx = upper_end + 1; idx < (upper_end + 1 + (led_count - width)); idx++) { + mapped_idx = map_index_to_range(idx, led_count); + dmx_universe_set_rgbw(mapped_idx, rest); + } +} + static void process_mode(enum color_mode mode, const struct poti_values *poti_vals) { uint32_t odr; static bool last_blink_state = false; bool blink_state; int i; + struct rgbw_color col1 = {0, 0, 0, 0}; + struct rgbw_color col2 = {0, 0, 0, 0}; odr = GPIOA->ODR; odr &= ~((1<<5) | (1<<6) | (1<<7)); @@ -92,7 +141,7 @@ static void process_mode(enum color_mode mode, const struct poti_values *poti_va case MODE_RGB: odr |= (1<<5) | (1<<6) | (1<<7); for (i = 0; i < 32; i++) { - dmx_universe[i * 4 + 0] =poti_vals->pot_vals_filtered[0]; + dmx_universe[i * 4 + 0] = poti_vals->pot_vals_filtered[0]; dmx_universe[i * 4 + 1] = poti_vals->pot_vals_filtered[1]; dmx_universe[i * 4 + 2] = poti_vals->pot_vals_filtered[2]; dmx_universe[i * 4 + 3] = 0x0; @@ -119,8 +168,25 @@ static void process_mode(enum color_mode mode, const struct poti_values *poti_va } last_blink_state = blink_state; break; + case MODE_GREEN_BLUE_ANGLE: + dmx_universe[128] = 0u; + odr |= (1<<5) | (1<<6) | (1<<7); + col1.blue = poti_vals->pot_vals_filtered[0]; + col2.green = poti_vals->pot_vals_filtered[0]; + set_angle(32u, (int32_t)poti_vals->pot_vals_filtered[1] * 32u / 255u, + (int32_t)poti_vals->pot_vals_filtered[2] * 32u / 255u, &col1, &col2); + break; + case MODE_WHITE_ANGLE: + dmx_universe[128] = 0u; + odr |= (1<<5) | (1<<6) | (1<<7); + col1.white = poti_vals->pot_vals_filtered[0]; + col1.red = poti_vals->pot_vals_filtered[0]; + col1.green = poti_vals->pot_vals_filtered[0]; + col1.blue = poti_vals->pot_vals_filtered[0]; + set_angle(32u, (int32_t)poti_vals->pot_vals_filtered[1] * 32u / 255u, + (int32_t)poti_vals->pot_vals_filtered[2] * 32u / 255u, &col1, &col2); + break; default: - break; } @@ -230,6 +296,12 @@ int main(void) case 5: mode = MODE_WHITE_DISCRETE; break; + case 6: + mode = MODE_WHITE_ANGLE; + break; + case 7: + mode = MODE_GREEN_BLUE_ANGLE; + break; case 8: animation_reset(&led_animation); mode = MODE_ANIMATION;