mirror of
https://github.com/whowechina/aic_pico.git
synced 2025-01-31 12:13:47 +01:00
Refactoring rainbow effect for future patterns
This commit is contained in:
parent
53a23921ce
commit
a84ceb5531
@ -86,7 +86,7 @@ uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t apply_level_by(uint32_t color, uint8_t level)
|
static inline uint32_t apply_level(uint32_t color, uint8_t level)
|
||||||
{
|
{
|
||||||
unsigned r = (color >> 16) & 0xff;
|
unsigned r = (color >> 16) & 0xff;
|
||||||
unsigned g = (color >> 8) & 0xff;
|
unsigned g = (color >> 8) & 0xff;
|
||||||
@ -99,12 +99,6 @@ static inline uint32_t apply_level_by(uint32_t color, uint8_t level)
|
|||||||
return r << 16 | g << 8 | b;
|
return r << 16 | g << 8 | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t curr_level = 0;
|
|
||||||
static inline uint32_t apply_level(uint32_t color)
|
|
||||||
{
|
|
||||||
return apply_level_by(color, curr_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 6 segment regular hsv color wheel, better color cycle
|
/* 6 segment regular hsv color wheel, better color cycle
|
||||||
* https://www.arnevogel.com/rgb-rainbow/
|
* https://www.arnevogel.com/rgb-rainbow/
|
||||||
* https://www.instructables.com/How-to-Make-Proper-Rainbow-and-Random-Colors-With-/
|
* https://www.instructables.com/How-to-Make-Proper-Rainbow-and-Random-Colors-With-/
|
||||||
@ -118,11 +112,71 @@ static void generate_color_wheel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAINBOW_PITCH 37
|
static inline uint8_t lerp8u(uint8_t a, uint8_t b, uint8_t t)
|
||||||
#define RAINBOW_MIN_SPEED 1
|
{
|
||||||
static uint32_t curr_speed = RAINBOW_MIN_SPEED;
|
return a + (b - a) * t / 255;
|
||||||
|
}
|
||||||
|
|
||||||
static void rainbow_update()
|
static struct {
|
||||||
|
struct {
|
||||||
|
int current;
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
} speed;
|
||||||
|
struct {
|
||||||
|
int current;
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
} level;
|
||||||
|
int smooth_ms;
|
||||||
|
int elapsed;
|
||||||
|
} rainbow = { { 1, 1, 1 }, { 255, 255, 255 }, 0, 0 };
|
||||||
|
|
||||||
|
void light_rainbow(int8_t speed, uint32_t smooth_ms, uint8_t level)
|
||||||
|
{
|
||||||
|
if (smooth_ms != 0) {
|
||||||
|
rainbow.speed.from = rainbow.speed.current;
|
||||||
|
rainbow.speed.to = speed;
|
||||||
|
rainbow.smooth_ms = smooth_ms;
|
||||||
|
rainbow.level.from = rainbow.level.current;
|
||||||
|
rainbow.level.to = level;
|
||||||
|
rainbow.elapsed = 0;
|
||||||
|
} else {
|
||||||
|
rainbow.speed.current = speed;
|
||||||
|
rainbow.level.current = level;
|
||||||
|
rainbow.smooth_ms = 0;
|
||||||
|
rainbow.elapsed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rainbow_control()
|
||||||
|
{
|
||||||
|
static uint64_t last_time;
|
||||||
|
uint64_t now = time_us_64();
|
||||||
|
uint32_t delta = (now - last_time) / 1000;
|
||||||
|
last_time = now;
|
||||||
|
|
||||||
|
if ((rainbow.smooth_ms == 0) || (rainbow.elapsed == rainbow.smooth_ms)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rainbow.elapsed += delta;
|
||||||
|
if (rainbow.elapsed > rainbow.smooth_ms) {
|
||||||
|
rainbow.elapsed = rainbow.smooth_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
int range = rainbow.speed.to - rainbow.speed.from;
|
||||||
|
int progress = range * rainbow.elapsed / rainbow.smooth_ms;
|
||||||
|
rainbow.speed.current = rainbow.speed.from + progress;
|
||||||
|
|
||||||
|
range = rainbow.level.to - rainbow.level.from;
|
||||||
|
progress = range * rainbow.elapsed / rainbow.smooth_ms;
|
||||||
|
rainbow.level.current = rainbow.level.from + progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RAINBOW_PITCH 37
|
||||||
|
|
||||||
|
static void rainbow_render()
|
||||||
{
|
{
|
||||||
static uint64_t last = 0;
|
static uint64_t last = 0;
|
||||||
uint64_t now = time_us_64();
|
uint64_t now = time_us_64();
|
||||||
@ -132,53 +186,21 @@ static void rainbow_update()
|
|||||||
last = now;
|
last = now;
|
||||||
|
|
||||||
static uint32_t rotator = 0;
|
static uint32_t rotator = 0;
|
||||||
rotator = (rotator + curr_speed) % COLOR_WHEEL_SIZE;
|
rotator = (rotator + rainbow.speed.current) % COLOR_WHEEL_SIZE;
|
||||||
|
|
||||||
for (int i = 0; i < RGB_NUM; i++) {
|
for (int i = 0; i < RGB_NUM; i++) {
|
||||||
uint32_t index = (rotator + RAINBOW_PITCH * i) % COLOR_WHEEL_SIZE;
|
uint32_t index = (rotator + RAINBOW_PITCH * i) % COLOR_WHEEL_SIZE;
|
||||||
rgb_buf[i] = apply_level(color_wheel[index]);
|
rgb_buf[i] = apply_level(color_wheel[index], rainbow.level.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < LED_NUM; i++) {
|
for (int i = 0; i < LED_NUM; i++) {
|
||||||
uint32_t index = (rotator + RAINBOW_PITCH * 2 * i) % COLOR_WHEEL_SIZE;
|
uint32_t index = (rotator + RAINBOW_PITCH * 2 * i) % COLOR_WHEEL_SIZE;
|
||||||
led_buf[i] = apply_level(color_wheel[index]) & 0xff;
|
led_buf[i] = apply_level(color_wheel[index], rainbow.level.current) & 0xff;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void light_stimulate()
|
|
||||||
{
|
|
||||||
curr_speed = 48;
|
|
||||||
curr_level = aic_cfg->light.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rainbow_fade()
|
|
||||||
{
|
|
||||||
static uint64_t last = 0;
|
|
||||||
uint64_t now = time_us_64();
|
|
||||||
if (now - last < 200000) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
last = now;
|
|
||||||
|
|
||||||
if (curr_speed > RAINBOW_MIN_SPEED) {
|
|
||||||
curr_speed = curr_speed * 90 / 100;
|
|
||||||
}
|
|
||||||
if (curr_level > aic_cfg->light.min) {
|
|
||||||
curr_level -= (curr_level - aic_cfg->light.min) / 10 + 1;
|
|
||||||
} else if (curr_level < aic_cfg->light.min) {
|
|
||||||
curr_level += (aic_cfg->light.min - curr_level) / 10 + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drive_led()
|
static void drive_led()
|
||||||
{
|
{
|
||||||
static uint64_t last = 0;
|
|
||||||
uint64_t now = time_us_64();
|
|
||||||
if (now - last < 4000) { // no faster than 250Hz
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
last = now;
|
|
||||||
|
|
||||||
for (int i = 0; i < RGB_NUM; i++) {
|
for (int i = 0; i < RGB_NUM; i++) {
|
||||||
uint32_t color = aic_cfg->light.rgb ? rgb_buf[i] << 8u : 0;
|
uint32_t color = aic_cfg->light.rgb ? rgb_buf[i] << 8u : 0;
|
||||||
pio_sm_put_blocking(pio0, 0, color);
|
pio_sm_put_blocking(pio0, 0, color);
|
||||||
@ -193,7 +215,7 @@ static void drive_led()
|
|||||||
void light_set_color(uint32_t color)
|
void light_set_color(uint32_t color)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < RGB_NUM; i++) {
|
for (int i = 0; i < RGB_NUM; i++) {
|
||||||
rgb_buf[i] = apply_level_by(color, aic_cfg->light.max);
|
rgb_buf[i] = apply_level(color, aic_cfg->light.max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +238,8 @@ void light_set_brg(unsigned index, const uint8_t *brg_array, size_t num)
|
|||||||
uint8_t b = brg_array[i * 3 + 0];
|
uint8_t b = brg_array[i * 3 + 0];
|
||||||
uint8_t r = brg_array[i * 3 + 1];
|
uint8_t r = brg_array[i * 3 + 1];
|
||||||
uint8_t g = brg_array[i * 3 + 2];
|
uint8_t g = brg_array[i * 3 + 2];
|
||||||
rgb_buf[index + i] = apply_level(rgb32(r, g, b, false));
|
uint32_t color = apply_level(rgb32(r, g, b, false), aic_cfg->light.max);
|
||||||
|
rgb_buf[index + i] = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,21 +261,28 @@ void light_init()
|
|||||||
pwm_init(slice, &cfg, true);
|
pwm_init(slice, &cfg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
curr_level = aic_cfg->light.min;
|
|
||||||
generate_color_wheel();
|
generate_color_wheel();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rainbow = true;
|
static bool rainbow_mode = true;
|
||||||
void light_set_rainbow(bool enable)
|
void light_set_rainbow(bool enable)
|
||||||
{
|
{
|
||||||
rainbow = enable;
|
rainbow_mode = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void light_update()
|
void light_update()
|
||||||
{
|
{
|
||||||
if (rainbow && (time_us_64() > last_hid + 1000000)) {
|
static uint64_t last = 0;
|
||||||
rainbow_update();
|
uint64_t now = time_us_64();
|
||||||
|
if (now - last < 4000) { // no faster than 250Hz
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last = now;
|
||||||
|
|
||||||
|
rainbow_control();
|
||||||
|
|
||||||
|
if (rainbow_mode && (time_us_64() > last_hid + 1000000)) {
|
||||||
|
rainbow_render();
|
||||||
}
|
}
|
||||||
rainbow_fade();
|
|
||||||
drive_led();
|
drive_led();
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,14 @@ void light_update();
|
|||||||
uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix);
|
uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix);
|
||||||
uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v);
|
uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v);
|
||||||
|
|
||||||
|
void light_color(uint32_t color, uint32_t fading_ms);
|
||||||
|
void light_color_n(uint32_t repeat, int count, ...);
|
||||||
|
|
||||||
|
void light_rainbow(int8_t speed, uint32_t smooth_ms, uint8_t level);
|
||||||
|
|
||||||
void light_set_color(uint32_t color);
|
void light_set_color(uint32_t color);
|
||||||
void light_hid_light(uint8_t r, uint8_t g, uint8_t b);
|
void light_hid_light(uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
void light_set_rainbow(bool enable);
|
void light_set_rainbow(bool enable);
|
||||||
void light_stimulate();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -103,7 +103,8 @@ static void light_effect()
|
|||||||
light_set_color(bana_led_color());
|
light_set_color(bana_led_color());
|
||||||
} else {
|
} else {
|
||||||
if (memcmp(hid_cardio.current, "\0\0\0\0\0\0\0\0\0", 9) != 0) {
|
if (memcmp(hid_cardio.current, "\0\0\0\0\0\0\0\0\0", 9) != 0) {
|
||||||
light_stimulate();
|
light_rainbow(40, 0, aic_cfg->light.max);
|
||||||
|
light_rainbow(1, 2500, aic_cfg->light.min);
|
||||||
}
|
}
|
||||||
light_set_rainbow(true);
|
light_set_rainbow(true);
|
||||||
}
|
}
|
||||||
@ -304,6 +305,8 @@ void init()
|
|||||||
save_init(0xca340a1c, &core1_io_lock);
|
save_init(0xca340a1c, &core1_io_lock);
|
||||||
|
|
||||||
light_init();
|
light_init();
|
||||||
|
light_rainbow(1, 0, aic_cfg->light.min);
|
||||||
|
|
||||||
keypad_init();
|
keypad_init();
|
||||||
|
|
||||||
nfc_init_i2c(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ);
|
nfc_init_i2c(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user