fixed aw20xxx gain not updating correct registers due to wrong offset used

This commit is contained in:
true 2024-10-26 02:12:00 -07:00
parent 002de13655
commit 4d8e037000
7 changed files with 90 additions and 36 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}
*/

View File

@ -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) { \

View File

@ -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);

View File

@ -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;

View File

@ -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)