diff --git a/nametag8_CH592/user/led/rgbled_prog.c b/nametag8_CH592/user/led/rgbled_prog.c index ef14bf2..64a82a3 100644 --- a/nametag8_CH592/user/led/rgbled_prog.c +++ b/nametag8_CH592/user/led/rgbled_prog.c @@ -33,65 +33,6 @@ const uint8_t rgb_map[RGBLED_COUNT] = { static uint8_t timeout; - -void rgb_solid(uint8_t *a, uint16_t tick) -{ - // 1=bitfield, 2=timeout-set, 4=state, 5=hue, 6=sat, 7=val - // bitfield: - // 7: blank / off - // 3: override altcolor (if bit 1 is not set) - // 1: override hsv - // 0: flash - - int i; - color_hsv hsv = {0, 0, 0}; - - // timeout - if (!timeout || (timeout > a[2])) { - timeout = a[2]; - } else { - timeout--; - return; - } - - if (a[1] & 0x80) { - // override off - hsv.v = 0; - } else { - // color select - if (a[1] & 0x02) { - hsv.h = a[5] * 6; - hsv.s = a[6]; - hsv.v = a[7]; - } else if (a[1] & 0x08) { - hsv.h = uconf.altcolor_hue * 6; - hsv.s = uconf.altcolor_sat; - hsv.v = uconf.altcolor_val; - } else { - hsv.h = uconf.favcolor_hue * 6; - hsv.s = uconf.favcolor_sat; - hsv.v = uconf.favcolor_val; - } - - // flash - if (a[1] & 0x01) { - a[4] ^= 0x01; - if (a[4] & 0x01) hsv.v = 0; - } - } - - // update - hsv_out[0].h = hsv.h; - hsv_out[0].s = hsv.s; - hsv_out[0].v = hsv.v; - - for (i = 1; i < RGBLED_COUNT; i++) { - hsv_out[i].h = hsv_out[0].h; - hsv_out[i].s = hsv_out[0].s; - hsv_out[i].v = hsv_out[0].v; - } -} - // todo: improve fading smoothness by doing fadeout every callback instead of on timeout // this can be done once LED bit depth is increased void rgb_flicker(uint8_t *a, uint16_t tick) @@ -439,192 +380,6 @@ void rgb_waving(uint8_t *a, uint16_t tick) } } - - -void rgb_copmode(uint8_t *a, uint16_t tick) -{ - // 0=work, 1=bitfield, 2=timeout-set, 3=timeout-work, 4=work, 56=steps, 7=val - // bitfield: - // 7 sync to tick 0 - // 6 skip pattern 2 - // 5 skip pattern 1 - // 4 don't override sat/val to maximums (not implemented) - // 3 use different colors on either half during pattern 2 - // 2 use different colors on either half during pattern 1 - // 1 repeat subpattern 1 - // 0 use cop colors instead of pri/alt - // others: - // a[5][7:4] amount of time to delay in pattern 2 - // a[5][0:3] amount of times to repeat pattern 2 (solid color alternate) - // a[6][7:4] amount of strobe pulses in pattern 1 - // a[6][0:3] amount of times to repeat pattern 1 (strobes) - - int i; - - uint8_t pattern, iter; - uint8_t *seq; - uint8_t w, x; - uint8_t b; - - uint8_t cnt[4]; - - color_hsv hsv; - color_hsv hsv2; - color_hsv pri, sec; - - // synchronize - if (a[1] & 0x80) { - if (!tick) { - a[3] = 0; - a[1] &= ~0x80; - } else { - return; - } - } - - // timeout - if (!timeout || (timeout > a[2])) { - timeout = a[2]; - } else { - timeout--; - return; - } - - // colors to use - if (a[1] & 0x01) { - pri.h = 0x000; - pri.s = 0xff; - sec.h = 0x400; - sec.s = 0xff; - } else { - pri.h = uconf.favcolor_hue * 6; - pri.s = uconf.favcolor_sat; - sec.h = uconf.altcolor_hue * 6; - sec.s = uconf.altcolor_sat; - } - - // pattern mode - pattern = a[0] >> 6; - iter = a[0] & 0x3f; - seq = &a[4]; - - cnt[0] = a[6] & 0xf; - cnt[1] = a[6] >> 4; - cnt[2] = a[5] & 0xf; - cnt[3] = a[5] >> 4; - - if ((pattern == 0) && (a[1] & 0x20)) pattern++; - if ((pattern == 1) && (a[1] & 0x40)) pattern++; - - if (pattern > 1) pattern = 0; - - switch (pattern) { - // strobe - case 0: { - w = cnt[1] << 1; - if (!w) w = 32; - b = (a[1] & 0x02) ? 0x02 : 0x01; - x = cnt[0]; - if (!x) x = 16; - x <<= b; - - // set main color - hsv.h = (iter & b) ? sec.h : pri.h; - hsv.s = (iter & b) ? sec.s : pri.s; - hsv.v = 0; - - // p1 alternate color mode - if (a[1] & 0x04) { - hsv2.h = (iter & b) ? pri.h : sec.h; - hsv2.s = (iter & b) ? pri.s : sec.s; - } else { - hsv2.h = hsv.h; - hsv2.s = hsv.s; - } - - // set value if on - if ((*seq < w) && !(*seq & 1)) { - hsv.v = a[7]; - } - - if (*seq > w) { - // iteration done - iter++; - *seq = 0; - if (iter >= x) { - // pattern done - pattern++; - iter = 0; - } - - break; - } - - (*seq)++; - break; - } - - // solid alternate - case 1: { - w = cnt[3] << 1; - if (!w) w = 32; - x = cnt[2] << 1; - if (!x) x = 32; - - // set main color - hsv.h = (iter & 1) ? sec.h : pri.h; - hsv.s = (iter & 1) ? sec.s : pri.s; - hsv.v = 0; - - // p2 alternate color mode - if (a[1] & 0x08) { - hsv2.h = (iter & 1) ? pri.h : sec.h; - hsv2.s = (iter & 1) ? pri.s : sec.s; - } else { - hsv2.h = hsv.h; - hsv2.s = hsv.s; - } - - // set value - hsv.v = a[7]; - - if (*seq > w) { - // iteration done - iter++; - *seq = 0; - if (iter >= x) { - // pattern done - pattern++; - iter = 0; - } - - break; - } - - (*seq)++; - break; - } - } - - // we only have two patterns - pattern %= 2; - - // save state - a[0] = (pattern << 6) | (iter & 0x3f); - - // apply to LEDs - w = RGBLED_COUNT/2; - for (i = 0; i < w; i++) { - hsv_out[rgb_map[i]].h = hsv.h; - hsv_out[rgb_map[i]].s = hsv.s; - hsv_out[rgb_map[i]].v = hsv.v; - - hsv_out[rgb_map[i+w]].h = hsv2.h; - hsv_out[rgb_map[i+w]].s = hsv2.s; - hsv_out[rgb_map[i+w]].v = hsv.v; - } -} - void rgb_fade_from_center(uint8_t *a, uint16_t tick) { @@ -640,16 +395,22 @@ void rgb_gravitycheck(uint8_t *a, uint16_t tick) } +void rgb_solid(uint8_t *a, uint16_t tick); +const uint8_t * rgb_solid_desc(uint8_t idx); + void rgb_rainbow(uint8_t *a, uint16_t tick); const uint8_t * rgb_rainbow_desc(uint8_t idx); +void rgb_copmode(uint8_t *a, uint16_t tick); +const uint8_t * rgb_copmode_desc(uint8_t idx); + // implemented program table const LedProgram rgb_pgm[6] = { - {"Solid Color", rgb_solid, 0}, + {"Solid Color", rgb_solid, rgb_solid_desc}, {"Flicker", rgb_flicker, 0}, {"Circles", rgb_circles, 0}, {"Waving", rgb_waving, 0}, {"Rainbow", rgb_rainbow, rgb_rainbow_desc}, - {"Cop Mode", rgb_copmode, 0}, + {"Cop Mode", rgb_copmode, rgb_copmode_desc}, }; diff --git a/nametag8_CH592/user/led/rgbprog_basic.c b/nametag8_CH592/user/led/rgbprog_basic.c new file mode 100644 index 0000000..cccd6d2 --- /dev/null +++ b/nametag8_CH592/user/led/rgbprog_basic.c @@ -0,0 +1,91 @@ +/* + * rgbprog_basic.c + * Created Nov 1, 2024 + */ + +#include +#include "rgbled.h" + +#include "user_config.h" + + +static uint8_t timeout; + + +const uint8_t * rgb_solid_desc(uint8_t idx) +{ + switch (idx) { + case 0: + case 1: return RGB_STR_UNUSED; + case 2: return ">7 = blank"; + case 3: return "Bitfield"; + case 4: + case 5: return RGB_STR_DELAY; + case 10: + case 11: return "Override Hue"; + case 12: + case 13: return "Override Sat"; + case 14: + case 15: return "Override Val"; + default: + return RGB_STR_RESERVED; + } +} + +void rgb_solid(uint8_t *a, uint16_t tick) +{ + // 1=bitfield, 2=timeout-set, 4=state, 5=hue, 6=sat, 7=val + // bitfield: + // 7: blank / off + // 3: override altcolor (if bit 1 is not set) + // 1: override hsv + // 0: flash + + int i; + color_hsv hsv = {0, 0, 0}; + + // timeout + if (!timeout || (timeout > a[2])) { + timeout = a[2]; + } else { + timeout--; + return; + } + + if (a[1] & 0x80) { + // override off + hsv.v = 0; + } else { + // color select + if (a[1] & 0x02) { + hsv.h = a[5] * 6; + hsv.s = a[6]; + hsv.v = a[7]; + } else if (a[1] & 0x08) { + hsv.h = uconf.altcolor_hue * 6; + hsv.s = uconf.altcolor_sat; + hsv.v = uconf.altcolor_val; + } else { + hsv.h = uconf.favcolor_hue * 6; + hsv.s = uconf.favcolor_sat; + hsv.v = uconf.favcolor_val; + } + + // flash + if (a[1] & 0x01) { + a[4] ^= 0x01; + if (a[4] & 0x01) hsv.v = 0; + } + } + + // update + hsv_out[0].h = hsv.h; + hsv_out[0].s = hsv.s; + hsv_out[0].v = hsv.v; + + for (i = 1; i < RGBLED_COUNT; i++) { + hsv_out[i].h = hsv_out[0].h; + hsv_out[i].s = hsv_out[0].s; + hsv_out[i].v = hsv_out[0].v; + } +} diff --git a/nametag8_CH592/user/led/rgbprog_copmode.c b/nametag8_CH592/user/led/rgbprog_copmode.c new file mode 100644 index 0000000..21d92f4 --- /dev/null +++ b/nametag8_CH592/user/led/rgbprog_copmode.c @@ -0,0 +1,218 @@ +/* + * rgbprog_copmode.c + * Created Nov 1, 2024 + */ + +#include +#include "rgbled.h" + +#include "user_config.h" + + + +static uint8_t timeout; + + + +const uint8_t * rgb_copmode_desc(uint8_t idx) +{ + switch (idx) { + case 2: return "Bitfield Hi"; + case 3: return "Bitfield Lo"; + case 4: + case 5: return RGB_STR_DELAY; + case 10: return "Pat2 Delay"; + case 11: return "Pat2 Cycles"; + case 12: return "Pat1 Delay"; + case 13: return "Pat1 Cycles"; + case 14: + case 15: return RGB_STR_BRIGHTNESS; + default: + return RGB_STR_RESERVED; + } +} + + +void rgb_copmode(uint8_t *a, uint16_t tick) +{ + // 0=work, 1=bitfield, 2=timeout-set, 3=timeout-work, 4=work, 56=steps, 7=val + // bitfield: + // 7 sync to tick 0 + // 6 skip pattern 2 + // 5 skip pattern 1 + // 4 don't override sat/val to maximums (not implemented) + // 3 use different colors on either half during pattern 2 + // 2 use different colors on either half during pattern 1 + // 1 repeat subpattern 1 + // 0 use cop colors instead of pri/alt + // others: + // a[5][7:4] amount of time to delay in pattern 2 + // a[5][0:3] amount of times to repeat pattern 2 (solid color alternate) + // a[6][7:4] amount of strobe pulses in pattern 1 + // a[6][0:3] amount of times to repeat pattern 1 (strobes) + + int i; + + uint8_t pattern, iter; + uint8_t *seq; + uint8_t w, x; + uint8_t b; + + uint8_t cnt[4]; + + color_hsv hsv; + color_hsv hsv2; + color_hsv pri, sec; + + // synchronize + if (a[1] & 0x80) { + if (!tick) { + a[3] = 0; + a[1] &= ~0x80; + } else { + return; + } + } + + // timeout + if (!timeout || (timeout > a[2])) { + timeout = a[2]; + } else { + timeout--; + return; + } + + // colors to use + if (a[1] & 0x01) { + pri.h = 0x000; + pri.s = 0xff; + sec.h = 0x400; + sec.s = 0xff; + } else { + pri.h = uconf.favcolor_hue * 6; + pri.s = uconf.favcolor_sat; + sec.h = uconf.altcolor_hue * 6; + sec.s = uconf.altcolor_sat; + } + + // pattern mode + pattern = a[0] >> 6; + iter = a[0] & 0x3f; + seq = &a[4]; + + cnt[0] = a[6] & 0xf; + cnt[1] = a[6] >> 4; + cnt[2] = a[5] & 0xf; + cnt[3] = a[5] >> 4; + + if ((pattern == 0) && (a[1] & 0x20)) pattern++; + if ((pattern == 1) && (a[1] & 0x40)) pattern++; + + if (pattern > 1) pattern = 0; + + switch (pattern) { + // strobe + case 0: { + w = cnt[1] << 1; + if (!w) w = 32; + b = (a[1] & 0x02) ? 0x02 : 0x01; + x = cnt[0]; + if (!x) x = 16; + x <<= b; + + // set main color + hsv.h = (iter & b) ? sec.h : pri.h; + hsv.s = (iter & b) ? sec.s : pri.s; + hsv.v = 0; + + // p1 alternate color mode + if (a[1] & 0x04) { + hsv2.h = (iter & b) ? pri.h : sec.h; + hsv2.s = (iter & b) ? pri.s : sec.s; + } else { + hsv2.h = hsv.h; + hsv2.s = hsv.s; + } + + // set value if on + if ((*seq < w) && !(*seq & 1)) { + hsv.v = a[7]; + } + + if (*seq > w) { + // iteration done + iter++; + *seq = 0; + if (iter >= x) { + // pattern done + pattern++; + iter = 0; + } + + break; + } + + (*seq)++; + break; + } + + // solid alternate + case 1: { + w = cnt[3] << 1; + if (!w) w = 32; + x = cnt[2] << 1; + if (!x) x = 32; + + // set main color + hsv.h = (iter & 1) ? sec.h : pri.h; + hsv.s = (iter & 1) ? sec.s : pri.s; + hsv.v = 0; + + // p2 alternate color mode + if (a[1] & 0x08) { + hsv2.h = (iter & 1) ? pri.h : sec.h; + hsv2.s = (iter & 1) ? pri.s : sec.s; + } else { + hsv2.h = hsv.h; + hsv2.s = hsv.s; + } + + // set value + hsv.v = a[7]; + + if (*seq > w) { + // iteration done + iter++; + *seq = 0; + if (iter >= x) { + // pattern done + pattern++; + iter = 0; + } + + break; + } + + (*seq)++; + break; + } + } + + // we only have two patterns + pattern %= 2; + + // save state + a[0] = (pattern << 6) | (iter & 0x3f); + + // apply to LEDs + w = RGBLED_COUNT/2; + for (i = 0; i < w; i++) { + hsv_out[rgb_map[i]].h = hsv.h; + hsv_out[rgb_map[i]].s = hsv.s; + hsv_out[rgb_map[i]].v = hsv.v; + + hsv_out[rgb_map[i+w]].h = hsv2.h; + hsv_out[rgb_map[i+w]].s = hsv2.s; + hsv_out[rgb_map[i+w]].v = hsv.v; + } +} diff --git a/nametag8_CH592/user/ui/menu2_led_setup.c b/nametag8_CH592/user/ui/menu2_led_setup.c index 2f03839..cc7215a 100644 --- a/nametag8_CH592/user/ui/menu2_led_setup.c +++ b/nametag8_CH592/user/ui/menu2_led_setup.c @@ -249,7 +249,7 @@ void menu_2_disp(uint8_t idx) // which item selected? switch (idx) { case LI_PROGRAM_SELECT: { - ssd1306fb_draw_str(font_table[0].font, "RGB Program", 1); + ssd1306fb_draw_str(font_table[0].font, "Edge LED Program", 1); ssd1306fb_set_cursor(16, 15); ssd1306fb_draw_str(font_table[0].font, rgb_pgm[uconf.ledprog_rgb_idx].name, 1); @@ -263,7 +263,7 @@ void menu_2_disp(uint8_t idx) s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx]; if (edit_mode == MENU_BTNSTYLE_MENU) { - ssd1306fb_draw_str(font_table[0].font, "RGB Settings", 1); + ssd1306fb_draw_str(font_table[0].font, "Program Settings", 1); } else { if (rgb_pgm[uconf.ledprog_rgb_idx].edit_disp) { topline = (uint8_t *)rgb_pgm[uconf.ledprog_rgb_idx].edit_disp(prog_data_idx); diff --git a/nametag8_CH592/user/user_config.c b/nametag8_CH592/user/user_config.c index 110aedf..bb099b7 100644 --- a/nametag8_CH592/user/user_config.c +++ b/nametag8_CH592/user/user_config.c @@ -21,18 +21,17 @@ uint8_t sysflags; uint16_t uconf_flash_offset; static const uint8_t uconf_edge_defaults[8][8] = { - {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, - {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, - {0x15, 0x42, 0x50, 0x00, 0xa0, 0x30, 0xff, 0x20}, - {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, - {0x03, 0x11, 0x05, 0x00, 0x00, 0x00, 0xff, 0x80}, - {0x00, 0x01, 0x04, 0x00, 0x00, 0x66, 0x46, 0x80}, + {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, // solid color + {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, // flicker + {0x15, 0x42, 0x50, 0x00, 0xa0, 0x30, 0xff, 0x20}, // circles + {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, // waving + {0x03, 0x11, 0x05, 0x00, 0x00, 0x00, 0xff, 0x80}, // rainbow + {0x00, 0x01, 0x01, 0x00, 0x00, 0x66, 0x46, 0x80}, // cop mode {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, {0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0} }; - void uconf_defaults() { int i;