From 4d8e037000cebfcb9a1d2482d1433da4004d22e9 Mon Sep 17 00:00:00 2001 From: true Date: Sat, 26 Oct 2024 02:12:00 -0700 Subject: [PATCH] fixed aw20xxx gain not updating correct registers due to wrong offset used --- nametag8_CH592/user/hw/aw20xxx.c | 2 +- nametag8_CH592/user/hw/aw20xxx.h | 3 +- nametag8_CH592/user/led/hsv2rgb.c | 86 +++++++++++++++++++++++-------- nametag8_CH592/user/led/hsv2rgb.h | 11 ++-- nametag8_CH592/user/led/rgbled.c | 18 +++++-- nametag8_CH592/user/main.c | 4 +- nametag8_CH592/user/user_config.h | 2 +- 7 files changed, 90 insertions(+), 36 deletions(-) diff --git a/nametag8_CH592/user/hw/aw20xxx.c b/nametag8_CH592/user/hw/aw20xxx.c index 213a8f7..3e17440 100644 --- a/nametag8_CH592/user/hw/aw20xxx.c +++ b/nametag8_CH592/user/hw/aw20xxx.c @@ -161,7 +161,7 @@ void aw20x_set_dim_global(struct AW20x *aw, uint8_t dim) // send buffer for each column row = offset = 0; for (i = 0; i < aw->cols; i++) { - AW20X_I2C_writereg(aw->addr, row, aw_buf, aw->rows); + AW20X_I2C_writereg(aw->addr, offset, aw_buf, aw->rows); while (AW20X_I2C_busy()); row += aw->rows; offset += AW20X_MAX_ROWS; diff --git a/nametag8_CH592/user/hw/aw20xxx.h b/nametag8_CH592/user/hw/aw20xxx.h index 0813fad..e180e71 100644 --- a/nametag8_CH592/user/hw/aw20xxx.h +++ b/nametag8_CH592/user/hw/aw20xxx.h @@ -169,11 +169,10 @@ enum aw20x_size { typedef struct AW20x { uint8_t addr; uint8_t config; // settings for the chip - uint8_t hw_rows; // maximum hardware rows in your chip (108, 072, 036: 12, 054: 9) uint8_t state; // keeps track of active page, and high bit is set if asleep uint8_t cols; // highest column used by application, 1-9 uint8_t rows; // highest row used by application, 1-12 - uint8_t pad[2]; + uint8_t pad[3]; uint8_t *fade; // led buffer location for FADE (required), of size cols+rows uint8_t *gain; // led buffer location for GAIN (optional), of size cols+rows } AW20x; diff --git a/nametag8_CH592/user/led/hsv2rgb.c b/nametag8_CH592/user/led/hsv2rgb.c index 14050d4..0e05e16 100644 --- a/nametag8_CH592/user/led/hsv2rgb.c +++ b/nametag8_CH592/user/led/hsv2rgb.c @@ -26,6 +26,7 @@ #include "hsv2rgb.h" +/* void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b) { uint8_t sextant; @@ -46,10 +47,10 @@ void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , u *g = v; // Top level // Perform actual calculations - /* - * Bottom level: v * (1.0 - s) - * --> (v * (255 - s) + error_corr) / 256 - */ + + // Bottom level: v * (1.0 - s) + // --> (v * (255 - s) + error_corr) / 256 + bb = ~s; ww = v * bb; ww += 1; // Error correction @@ -60,10 +61,10 @@ void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , u if(!(sextant & 1)) { // *r = ...slope_up...; - /* - * Slope up: v * (1.0 - s * (1.0 - h)) - * --> (v * (255 - (s * (256 - h) + error_corr1) / 256) + error_corr2) / 256 - */ + + // Slope up: v * (1.0 - s * (1.0 - h)) + // --> (v * (255 - (s * (256 - h) + error_corr1) / 256) + error_corr2) / 256 + ww = !h_fraction ? ((uint16_t)s << 8) : (s * (uint8_t)(-h_fraction)); ww += ww >> 8; // Error correction 1 bb = ww >> 8; @@ -73,10 +74,10 @@ void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , u *r = ww >> 8; } else { // *r = ...slope_down...; - /* - * Slope down: v * (1.0 - s * h) - * --> (v * (255 - (s * h + error_corr1) / 256) + error_corr2) / 256 - */ + + // Slope down: v * (1.0 - s * h) + // --> (v * (255 - (s * h + error_corr1) / 256) + error_corr2) / 256 + ww = s * h_fraction; ww += ww >> 8; // Error correction 1 bb = ww >> 8; @@ -85,15 +86,14 @@ void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , u ww += v >> 1; // Error correction 2 *r = ww >> 8; - /* - * A perfect match for h_fraction == 0 implies: - * *r = (ww >> 8) + (h_fraction ? 0 : 1) - * However, this is an extra calculation that may not be required. - */ + // A perfect match for h_fraction == 0 implies: + // *r = (ww >> 8) + (h_fraction ? 0 : 1) + // However, this is an extra calculation that may not be required. } } +*/ -void hsv2rgb_32b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b) +void hsv2rgb_32b_8(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g , uint8_t *b) { HSV_MONOCHROMATIC_TEST(s, v, r, g, b); // Exit with grayscale if s == 0 @@ -105,10 +105,11 @@ void hsv2rgb_32b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , *g = v; // Top level - /* - * Bottom level: v * (1.0 - s) - * --> (v * (255 - s) + error_corr + 1) / 256 - */ + // Perform actual calculations + + // Bottom level: v * (1.0 - s) + // --> (v * (255 - s) + error_corr + 1) / 256 + uint16_t ww; // Intermediate result ww = v * (255 - s); // We don't use ~s to prevent size-promotion side effects ww += 1; // Error correction @@ -132,3 +133,44 @@ void hsv2rgb_32b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , *r = d >> 16; } } + +/* +void hsv2rgb_32b_16(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b) +{ + HSV_MONOCHROMATIC_TEST(s, v, r, g, b); // Exit with grayscale if s == 0 + + uint8_t sextant = h >> 8; + + HSV_SEXTANT_TEST(sextant); // Optional: Limit hue sextants to defined space + + HSV_POINTER_SWAP(sextant, r, g, b); // Swap pointers depending which sextant we are in + + *g = v; // Top level + + // Bottom level: v * (1.0 - s) + // --> (v * (255 - s) + error_corr + 1) / 256 + + uint16_t ww; // Intermediate result + ww = v * (255 - s); // We don't use ~s to prevent size-promotion side effects + ww += 1; // Error correction + ww += ww >> 8; // Error correction + *b = ww >> 8; + + uint8_t h_fraction = h & 0xff; // 0...255 + uint32_t d; // Intermediate result + + if(!(sextant & 1)) { + // *r = ...slope_up...; + d = v * (uint32_t)((255 << 8) - (uint16_t)(s * (256 - h_fraction))); + d += d >> 8; // Error correction + d += v; // Error correction + *r = d >> 16; + } else { + // *r = ...slope_down...; + d = v * (uint32_t)((255 << 8) - (uint16_t)(s * h_fraction)); + d += d >> 8; // Error correction + d += v; // Error correction + *r = d >> 16; + } +} +*/ diff --git a/nametag8_CH592/user/led/hsv2rgb.h b/nametag8_CH592/user/led/hsv2rgb.h index cd333f7..721a55e 100644 --- a/nametag8_CH592/user/led/hsv2rgb.h +++ b/nametag8_CH592/user/led/hsv2rgb.h @@ -56,11 +56,13 @@ typedef struct color_hsv { /* Options: */ #define HSV_USE_SEXTANT_TEST /* Limit the hue to 0...360 degrees */ -#define hsv2rgb(h,s,v,r,g,b) hsv2rgb_32b(h,s,v,r,g,b) +#define hsv2rgb(h,s,v,r,g,b) hsv2rgb_32b_8(h,s,v,r,g,b) -void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b); -void hsv2rgb_32b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b); +//void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b); +void hsv2rgb_32b_8(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g , uint8_t *b); +//void hsv2rgb_32b_16(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b); + /* @@ -100,7 +102,8 @@ void hsv2rgb_32b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , * r <-> g * } */ -#define HSV_SWAPPTR(a,b) do { uint16_t *tmp = (a); (a) = (b); (b) = tmp; } while(0) +#define HSV_SWAPPTR(a,b) do { uint8_t *tmp = (a); (a) = (b); (b) = tmp; } while(0) +//#define HSV_SWAPPTR(a,b) do { uint16_t *tmp = (a); (a) = (b); (b) = tmp; } while(0) #define HSV_POINTER_SWAP(sextant,r,g,b) \ do { \ if((sextant) & 2) { \ diff --git a/nametag8_CH592/user/led/rgbled.c b/nametag8_CH592/user/led/rgbled.c index 7bf1d92..857edd7 100644 --- a/nametag8_CH592/user/led/rgbled.c +++ b/nametag8_CH592/user/led/rgbled.c @@ -45,6 +45,11 @@ static const uint16_t pwm_cie_256in_1024out[] = { }; */ +static const uint8_t rgbled_map[12] = { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11 +}; + AW20x awled; @@ -77,7 +82,7 @@ void rgbled_init() aw20x_set_dim_global(&awled, AW20X_DIM); aw20x_set_fade(&awled); - aw20x_led_enable_range(&awled, 0, 47); // 9x4, but need to send 12x4 + aw20x_led_enable_range(&awled, 0, (AW20X_COLS * AW20X_MAX_ROWS) - 1); } void rgbled_flag_update() @@ -87,16 +92,21 @@ void rgbled_flag_update() void rgbled_send() { + int8_t i; + uint8_t *fade = awled_fade; + if (led_matrix_needs_update) { led_matrix_needs_update = 0; // leds off? - if ((uconf.flags & UCONF_FLAGS_LEDS_DISABLE) || !(uconf.flags & UCONF_FLAGS_LEDS_DISABLE)) { + if ((uconf.flags & UCONF_FLAGS_LEDS_DISABLE) || !(uconf.flags & UCONF_FLAGS_LEDS_ENABLE)) { // yes, clear the data memset(awled_fade, 0x00, sizeof(awled_fade)); } else { - // render our data to output buffer - // todo + for (i = 0; i < RGBLED_COUNT; i++) { + hsv2rgb(hsv_out[i].h, hsv_out[i].s, hsv_out[i].v, fade+0, fade+1, fade+2); + fade += 3; + } } aw20x_set_fade(&awled); diff --git a/nametag8_CH592/user/main.c b/nametag8_CH592/user/main.c index 952eb48..43ca559 100644 --- a/nametag8_CH592/user/main.c +++ b/nametag8_CH592/user/main.c @@ -338,9 +338,9 @@ void RTC_IRQHandler(void) } // operations - switch (st_tick & 0x7) { + switch (st_tick & 0x3) { case 0: - case 3: { + case 2: { // make sure a valid program is selected if (uconf.ledprog_rgb_idx > (sizeof(rgb_pgm) / sizeof(rgb_pgm[0]))) { uconf.ledprog_rgb_idx = 0; diff --git a/nametag8_CH592/user/user_config.h b/nametag8_CH592/user/user_config.h index 0561dd3..9dc47be 100644 --- a/nametag8_CH592/user/user_config.h +++ b/nametag8_CH592/user/user_config.h @@ -32,7 +32,7 @@ #define UCONF_FLAGS_AUTOROTATE_ENA (1 << 0) #define UCONF_FLAGS_LEDS_DISABLE (1 << 3) // used by programs to temporarily disable LEDs #define UCONF_FLAGS_FAVOR_SPEED (1 << 4) // todo: increase clock rather than reduce framerate -#define UCONF_FLAGS_LEDS_ENABLE (1 << 5) +#define UCONF_FLAGS_LEDS_ENABLE (1 << 5) // used by user in options menu to enable / disable RGBLEDs #define UCONF_FLAGS_SHOW_CPU_USAGE (1 << 6) #define UCONF_FLAGS_SHOW_ACCEL_ANGLE (1 << 7)