Complete animation mode
This commit is contained in:
parent
d85591c41e
commit
7904dae4bf
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
*.jdebug
|
*.jdebug
|
||||||
*.jdebug.user
|
*.jdebug.user
|
||||||
|
.vscode/*
|
||||||
|
|
||||||
# ClangD Ignopre files
|
# ClangD Ignopre files
|
||||||
.cache/*
|
.cache/*
|
||||||
|
138
animation.c
138
animation.c
@ -1,6 +1,23 @@
|
|||||||
#include <animation.h>
|
#include <animation.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <systick.h>
|
#include <systick.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define WHITE_FLASH_COUNT 5u
|
||||||
|
#define WHITE_FLASH_ON_TIME 60u
|
||||||
|
#define WHITE_FLASH_OFF_TIME 260u
|
||||||
|
|
||||||
|
#define RAINBOW_MAX_COL 240u
|
||||||
|
#define RAINBOW_INCR 40u
|
||||||
|
#define RAINBOW_LED_COUNT 32u
|
||||||
|
|
||||||
|
static void reset_rainbow_to_start(struct animation *ani)
|
||||||
|
{
|
||||||
|
ani->rb_start_state = RAINBOW_RY;
|
||||||
|
ani->rb_start_color.red = RAINBOW_MAX_COL;
|
||||||
|
ani->rb_start_color.blue = 0u;
|
||||||
|
ani->rb_start_color.green = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
void animation_reset(struct animation *ani)
|
void animation_reset(struct animation *ani)
|
||||||
{
|
{
|
||||||
@ -11,6 +28,7 @@ void animation_reset(struct animation *ani)
|
|||||||
ani->step = 0u;
|
ani->step = 0u;
|
||||||
ani->last_tick = systick_get_global_tick();
|
ani->last_tick = systick_get_global_tick();
|
||||||
ani->next_interval = 0ul;
|
ani->next_interval = 0ul;
|
||||||
|
reset_rainbow_to_start(ani);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_dmx_universe(uint8_t *universe, uint32_t len)
|
static void clear_dmx_universe(uint8_t *universe, uint32_t len)
|
||||||
@ -44,6 +62,107 @@ static enum animation_state next_col_state(enum animation_state current)
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Advance to the next color in the rainbow
|
||||||
|
*
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
enum rainbow_state state;
|
||||||
|
|
||||||
|
state = *current_state;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case RAINBOW_RY:
|
||||||
|
/* Increment green color */
|
||||||
|
col->green += RAINBOW_INCR;
|
||||||
|
if (col->green >= RAINBOW_MAX_COL) {
|
||||||
|
state = RAINBOW_YG;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RAINBOW_YG:
|
||||||
|
/* Decrement red color */
|
||||||
|
col->red -= RAINBOW_INCR;
|
||||||
|
if (col->red == 0) {
|
||||||
|
state = RAINBOW_GC;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RAINBOW_GC:
|
||||||
|
/* Increment blue color */
|
||||||
|
col->blue += RAINBOW_INCR;
|
||||||
|
if (col->blue >= RAINBOW_MAX_COL) {
|
||||||
|
state = RAINBOW_CB;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RAINBOW_CB:
|
||||||
|
/* Decrement green color */
|
||||||
|
col->green -= RAINBOW_INCR;
|
||||||
|
if (col->green == 0) {
|
||||||
|
state = RAINBOW_BM;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RAINBOW_BM:
|
||||||
|
/* Increment red color */
|
||||||
|
col->red += RAINBOW_INCR;
|
||||||
|
if (col->red >= RAINBOW_MAX_COL) {
|
||||||
|
state = RAINBOW_MR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RAINBOW_MR:
|
||||||
|
/* Decrement blue color */
|
||||||
|
col->blue -= RAINBOW_INCR;
|
||||||
|
if (col->blue == 0) {
|
||||||
|
state = RAINBOW_RY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*current_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param ani
|
||||||
|
* @param dmx_universe
|
||||||
|
* @return true Animation completed
|
||||||
|
* @return false Animation ongoing
|
||||||
|
*/
|
||||||
|
static bool animation_rainbow(struct animation *ani, uint8_t *dmx_universe)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
enum rainbow_state led_state;
|
||||||
|
struct rgb_color color;
|
||||||
|
uint32_t idx;
|
||||||
|
|
||||||
|
/* Get the start state of first led */
|
||||||
|
led_state= ani->rb_start_state;
|
||||||
|
color = ani->rb_start_color;
|
||||||
|
ani->step++;
|
||||||
|
|
||||||
|
for (idx = 0; idx < RAINBOW_LED_COUNT; idx++) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Sdvance rainbow color */
|
||||||
|
rainbow_color_advance(&led_state, &color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance the start */
|
||||||
|
rainbow_color_advance(&ani->rb_start_state, &ani->rb_start_color);
|
||||||
|
|
||||||
|
if (ani->step > 500) {
|
||||||
|
reset_rainbow_to_start(ani);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void animation_process(struct animation *ani, uint8_t *dmx_universe)
|
void animation_process(struct animation *ani, uint8_t *dmx_universe)
|
||||||
{
|
{
|
||||||
uint32_t tick;
|
uint32_t tick;
|
||||||
@ -72,7 +191,8 @@ void animation_process(struct animation *ani, uint8_t *dmx_universe)
|
|||||||
case ANI_RED:
|
case ANI_RED:
|
||||||
case ANI_GREEN:
|
case ANI_GREEN:
|
||||||
case ANI_BLUE:
|
case ANI_BLUE:
|
||||||
for (i = 0; i < 32; i++) {
|
dmx_universe[RAINBOW_LED_COUNT * 4] = 0u;
|
||||||
|
for (i = 0; i < RAINBOW_LED_COUNT; i++) {
|
||||||
dmx_universe[i * 4 + 0] = ani->state == ANI_RED ? (uint8_t)ani->step : 0u;
|
dmx_universe[i * 4 + 0] = ani->state == ANI_RED ? (uint8_t)ani->step : 0u;
|
||||||
dmx_universe[i * 4 + 1] = ani->state == ANI_GREEN ? (uint8_t)ani->step : 0u;
|
dmx_universe[i * 4 + 1] = ani->state == ANI_GREEN ? (uint8_t)ani->step : 0u;
|
||||||
dmx_universe[i * 4 + 2] = ani->state == ANI_BLUE ? (uint8_t)ani->step : 0u;
|
dmx_universe[i * 4 + 2] = ani->state == ANI_BLUE ? (uint8_t)ani->step : 0u;
|
||||||
@ -87,17 +207,21 @@ void animation_process(struct animation *ani, uint8_t *dmx_universe)
|
|||||||
ani->next_interval = 20;
|
ani->next_interval = 20;
|
||||||
break;
|
break;
|
||||||
case ANI_RAINBOW:
|
case ANI_RAINBOW:
|
||||||
|
dmx_universe[RAINBOW_LED_COUNT * 4] = 0u;
|
||||||
/* TODO: Implement Rainbow mode */
|
/* TODO: Implement Rainbow mode */
|
||||||
ani->next_interval = 10;
|
ani->next_interval = 20;
|
||||||
clear_dmx_universe(dmx_universe, 129u);
|
if (animation_rainbow(ani, dmx_universe)) {
|
||||||
ani->state = ANI_FLASH_WHITE;
|
clear_dmx_universe(dmx_universe, RAINBOW_LED_COUNT * 4 + 1);
|
||||||
|
ani->state = ANI_FLASH_WHITE;
|
||||||
|
ani->step = 0ul;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ANI_FLASH_WHITE:
|
case ANI_FLASH_WHITE:
|
||||||
dmx_universe[128] = ani->step & 1 ? 0xFF : 0;
|
dmx_universe[RAINBOW_LED_COUNT * 4] = ani->step & 1 ? 0xFF : 0;
|
||||||
ani->next_interval = ani->step & 1 ? 60 : 260;
|
ani->next_interval = ani->step & 1 ? WHITE_FLASH_ON_TIME : WHITE_FLASH_OFF_TIME;
|
||||||
ani->step += 1u;
|
ani->step += 1u;
|
||||||
|
|
||||||
if (ani->step >= 11u) {
|
if (ani->step >= (2 * WHITE_FLASH_COUNT + 1)) {
|
||||||
ani->state = ANI_RED;
|
ani->state = ANI_RED;
|
||||||
ani->step = 0u;
|
ani->step = 0u;
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,25 @@ enum animation_state {
|
|||||||
ANI_FLASH_WHITE,
|
ANI_FLASH_WHITE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rgb_color {
|
||||||
|
uint8_t red;
|
||||||
|
uint8_t green;
|
||||||
|
uint8_t blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum rainbow_state {
|
||||||
|
RAINBOW_RY,
|
||||||
|
RAINBOW_YG,
|
||||||
|
RAINBOW_GC,
|
||||||
|
RAINBOW_CB,
|
||||||
|
RAINBOW_BM,
|
||||||
|
RAINBOW_MR,
|
||||||
|
};
|
||||||
|
|
||||||
struct animation {
|
struct animation {
|
||||||
enum animation_state state;
|
enum animation_state state;
|
||||||
|
enum rainbow_state rb_start_state;
|
||||||
|
struct rgb_color rb_start_color;
|
||||||
uint32_t step;
|
uint32_t step;
|
||||||
uint32_t last_tick;
|
uint32_t last_tick;
|
||||||
uint32_t next_interval;
|
uint32_t next_interval;
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
#define _SYSTICK_H_
|
#define _SYSTICK_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
void systick_wait_ms(uint32_t ms);
|
void systick_wait_ms(uint32_t ms);
|
||||||
uint32_t systick_get_global_tick(void);
|
uint32_t systick_get_global_tick(void);
|
||||||
|
bool systick_get_blink_state(void);
|
||||||
|
|
||||||
#endif /* _SYSTICK_H_ */
|
#endif /* _SYSTICK_H_ */
|
||||||
|
14
main.c
14
main.c
@ -69,15 +69,13 @@ static void setup_pins(void)
|
|||||||
static void process_mode(enum color_mode mode, const struct poti_values *poti_vals)
|
static void process_mode(enum color_mode mode, const struct poti_values *poti_vals)
|
||||||
{
|
{
|
||||||
uint32_t odr;
|
uint32_t odr;
|
||||||
static uint32_t last_tick = 0ul;
|
static bool last_blink_state = false;
|
||||||
uint32_t tick;
|
bool blink_state;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
odr = GPIOA->ODR;
|
odr = GPIOA->ODR;
|
||||||
odr &= ~((1<<5) | (1<<6) | (1<<7));
|
odr &= ~((1<<5) | (1<<6) | (1<<7));
|
||||||
|
|
||||||
tick = systick_get_global_tick();
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MODE_RED:
|
case MODE_RED:
|
||||||
case MODE_GREEN:
|
case MODE_GREEN:
|
||||||
@ -115,14 +113,17 @@ static void process_mode(enum color_mode mode, const struct poti_values *poti_va
|
|||||||
animation_process(&led_animation, dmx_universe);
|
animation_process(&led_animation, dmx_universe);
|
||||||
break;
|
break;
|
||||||
case MODE_DMX_SHUTDOWN:
|
case MODE_DMX_SHUTDOWN:
|
||||||
port_expander_set_leds(0xFF);
|
blink_state = systick_get_blink_state();
|
||||||
|
if (blink_state != last_blink_state) {
|
||||||
|
port_expander_set_leds(blink_state ? (1<<0) : (1<<4));
|
||||||
|
}
|
||||||
|
last_blink_state = blink_state;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_tick = tick;
|
|
||||||
GPIOA->ODR = odr;
|
GPIOA->ODR = odr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,6 +155,7 @@ static bool mode_is_continuous(enum color_mode mode)
|
|||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MODE_ANIMATION:
|
case MODE_ANIMATION:
|
||||||
|
case MODE_DMX_SHUTDOWN:
|
||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
15
systick.c
15
systick.c
@ -1,8 +1,10 @@
|
|||||||
#include <systick.h>
|
#include <systick.h>
|
||||||
#include <stm32f0xx.h>
|
#include <stm32f0xx.h>
|
||||||
|
|
||||||
volatile uint32_t global_systick = 0;
|
static volatile uint32_t global_systick = 0;
|
||||||
volatile uint32_t systick_wait_counter;
|
static volatile uint32_t systick_wait_counter;
|
||||||
|
static volatile uint32_t blink_cntr = 0;
|
||||||
|
static volatile bool blink_state = false;
|
||||||
|
|
||||||
void systick_wait_ms(uint32_t ms)
|
void systick_wait_ms(uint32_t ms)
|
||||||
{
|
{
|
||||||
@ -12,6 +14,11 @@ void systick_wait_ms(uint32_t ms)
|
|||||||
__WFI();
|
__WFI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool systick_get_blink_state(void)
|
||||||
|
{
|
||||||
|
return blink_state;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t systick_get_global_tick(void)
|
uint32_t systick_get_global_tick(void)
|
||||||
{
|
{
|
||||||
return global_systick;
|
return global_systick;
|
||||||
@ -21,4 +28,8 @@ void SysTick_Handler(void)
|
|||||||
{
|
{
|
||||||
global_systick++;
|
global_systick++;
|
||||||
systick_wait_counter--;
|
systick_wait_counter--;
|
||||||
|
if (++blink_cntr > 250ul) {
|
||||||
|
blink_cntr = 0ul;
|
||||||
|
blink_state = !blink_state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user