app: reuse matrix control for WS2812b

This commit is contained in:
King Kévin 2022-07-21 21:24:13 +02:00
parent 3cd3a869f4
commit 479a1316c3
1 changed files with 71 additions and 43 deletions

View File

@ -103,6 +103,9 @@ static volatile uint32_t dial_steps = 0; /**< set to drv8825_steps when dial is
static uint8_t rgbmatrix_data[RGBMATRIX_HEIGHT / 2][RGBMATRIX_WIDTH * 2]; /**< data to be sent to RGB matrix (one byte includes upper and lower half values, each byte has 2 clock edges) */
#define RGBMATRIX_TIMER 3 /**< timer to update lines */
#define WSMATRIX_HEIGHT (2 * 8) /**< WS2812b panel height, in pixels */
#define WSMATRIX_WIDTH 32 /**< WS2812b panel width, in pixels */
// RGBW LED strips
#define STRIP_TIMER 4 /**< timer used for the PWM */
#define STRIP_R_PIN PB9 /**< pin used to drive gate for red channel */
@ -154,56 +157,80 @@ static void rgbmatrix_clear(void)
}
}
/** set color of the LED on the RGB matrix
/** set color of the LED on the RGB matrix or WS2812b panel
* @param[in] ws false to display on RGB matrix, true on WS2812b panel
* @param[in] x horizontal position (0 = left)
* @param[in] y vertical position (0 = top)
* @param[in] r if the red LED should be on
* @param[in] g if the green LED should be on
* @param[in] b if the blue LED should be on
*/
static void rgbmatrix_set(int16_t x, int16_t y, bool r, bool g, bool b)
static void matrix_set(bool ws, int16_t x, int16_t y, bool r, bool g, bool b)
{
if (x < 0 || x >= RGBMATRIX_WIDTH) {
if (x < 0 || x >= (ws ? WSMATRIX_WIDTH : RGBMATRIX_WIDTH)) {
return;
}
if (y < 0 || y >= RGBMATRIX_HEIGHT) {
if (y < 0 || y >= (ws ? WSMATRIX_HEIGHT : RGBMATRIX_HEIGHT)) {
return;
}
const uint8_t row = y % (RGBMATRIX_HEIGHT / 2); // get the actual line/row
const uint8_t col = x * 2; // get the actual column
uint8_t data = 0; // there we will set the color bits
if (y < (RGBMATRIX_HEIGHT / 2)) {
data = rgbmatrix_data[row][col] & 0xe0; // keep lower line colors
if (r) {
data |= (1 << 2);
}
if (g) {
data |= (1 << 3);
}
if (b) {
data |= (1 << 4);
if (ws) {
#define WSMATRIX_BRIGHTNESS 0x20
uint8_t col = 0, row = 0;
if (y < WSMATRIX_HEIGHT / 2) {
col = WSMATRIX_WIDTH - 1 - x;
if (1 == x % 2) {
row = WSMATRIX_HEIGHT / 2 - 1 - y;
} else {
row = y;
}
} else {
col = x + WSMATRIX_WIDTH;
y -= WSMATRIX_HEIGHT / 2;
if (1 == x % 2) {
row = WSMATRIX_HEIGHT / 2 - 1 - y;
} else {
row = y;
}
}
led_ws2812b_set_rgb(col * (WSMATRIX_HEIGHT / 2U) + row, g * WSMATRIX_BRIGHTNESS, r * WSMATRIX_BRIGHTNESS, b * WSMATRIX_BRIGHTNESS);
} else {
data = rgbmatrix_data[row][col] & 0x1c; // keep upper line colors
if (r) {
data |= (1 << 5);
}
if (g) {
data |= (1 << 6);
}
if (b) {
data |= (1 << 7);
const uint8_t row = y % (RGBMATRIX_HEIGHT / 2); // get the actual line/row
const uint8_t col = x * 2; // get the actual column
uint8_t data = 0; // there we will set the color bits
if (y < (RGBMATRIX_HEIGHT / 2)) {
data = rgbmatrix_data[row][col] & 0xe0; // keep lower line colors
if (r) {
data |= (1 << 2);
}
if (g) {
data |= (1 << 3);
}
if (b) {
data |= (1 << 4);
}
} else {
data = rgbmatrix_data[row][col] & 0x1c; // keep upper line colors
if (r) {
data |= (1 << 5);
}
if (g) {
data |= (1 << 6);
}
if (b) {
data |= (1 << 7);
}
}
// set data on low edge
rgbmatrix_data[row][col + 0] &= 0x3; // clear color data (don't touch clock and latch data)
rgbmatrix_data[row][col + 0] |= data; // set the LED data
// set data on high edge
rgbmatrix_data[row][col + 1] &= 0x3; // clear color data (don't touch clock and latch data)
rgbmatrix_data[row][col + 1] |= data; // set the LED data on clock high edge
}
// set data on low edge
rgbmatrix_data[row][col + 0] &= 0x3; // clear color data (don't touch clock and latch data)
rgbmatrix_data[row][col + 0] |= data; // set the LED data
// set data on high edge
rgbmatrix_data[row][col + 1] &= 0x3; // clear color data (don't touch clock and latch data)
rgbmatrix_data[row][col + 1] |= data; // set the LED data on clock high edge
}
/** draw character on RGB matrix
/** draw character on matrix
* @param[in] ws false to display on RGB matrix, true on WS2812b panel
* @param[in] x horizontal position (0 = left)
* @param[in] y vertical position (0 = top)
* @param[in] c character to draw
@ -212,7 +239,7 @@ static void rgbmatrix_set(int16_t x, int16_t y, bool r, bool g, bool b)
* @param[in] g if the character should be drawn in green
* @param[in] b if the character should be drawn in blue
*/
static void rgbmatrix_putc(int16_t x, int16_t y, char c, enum font_name font, bool red, bool green, bool blue)
static void matrix_putc(bool ws, int16_t x, int16_t y, char c, enum font_name font, bool red, bool green, bool blue)
{
// sanity checks
if (font >= FONT_MAX) {
@ -221,10 +248,10 @@ static void rgbmatrix_putc(int16_t x, int16_t y, char c, enum font_name font, bo
if (c < ' ' || c > '~') {
return;
}
if (x + fonts[font].width < 0 || x >= RGBMATRIX_WIDTH) {
if (x + fonts[font].width < 0 || x >= (ws ? WSMATRIX_WIDTH : RGBMATRIX_WIDTH)) {
return;
}
if (y + fonts[font].height < 0 || y >= RGBMATRIX_HEIGHT) {
if (y + fonts[font].height < 0 || y >= (ws ? WSMATRIX_HEIGHT : RGBMATRIX_HEIGHT)) {
return;
}
@ -234,15 +261,16 @@ static void rgbmatrix_putc(int16_t x, int16_t y, char c, enum font_name font, bo
for (uint8_t row = 0; row < fonts[font].height; row++) {
const bool dot = (column >> (fonts[font].height - 1 - row)) & 0x01;
if (dot) {
rgbmatrix_set(x + col, y + row, red, green, blue);
matrix_set(ws, x + col, y + row, red, green, blue);
} else {
rgbmatrix_set(x + col, y + row, false, false, false);
matrix_set(ws, x + col, y + row, false, false, false);
}
}
}
}
/** draw text on RGB matrix
* @param[in] ws false to display on RGB matrix, true on WS2812b panel
* @param[in] x horizontal position (0 = left)
* @param[in] y vertical position (0 = top)
* @param[in] str text to draw
@ -251,7 +279,7 @@ static void rgbmatrix_putc(int16_t x, int16_t y, char c, enum font_name font, bo
* @param[in] g if the character should be drawn in green
* @param[in] b if the character should be drawn in blue
*/
static void rgbmatrix_puts(int16_t x, int16_t y, const char* str, enum font_name font, bool red, bool green, bool blue)
static void matrix_puts(bool ws, int16_t x, int16_t y, const char* str, enum font_name font, bool red, bool green, bool blue)
{
// sanity checks
if (NULL == str) {
@ -260,17 +288,17 @@ static void rgbmatrix_puts(int16_t x, int16_t y, const char* str, enum font_name
if (font >= FONT_MAX) {
return;
}
if (y + fonts[font].height < 0 || y >= RGBMATRIX_HEIGHT) {
if (y + fonts[font].height < 0 || y >= (ws ? WSMATRIX_HEIGHT : RGBMATRIX_HEIGHT)) {
return;
}
const uint8_t len = strlen(str);
for (uint8_t i = 0; i < len; i++) {
if (x >= RGBMATRIX_WIDTH) {
if (x >= (ws ? WSMATRIX_WIDTH : RGBMATRIX_WIDTH)) {
return;
}
if (x + fonts[font].width >= 0) {
rgbmatrix_putc(x, y, str[i], font, red, green, blue);
matrix_putc(ws, x, y, str[i], font, red, green, blue);
}
x += fonts[font].width + 1;
}
@ -1105,7 +1133,7 @@ void main(void)
if (wakeup_flag) { // time to do periodic checks
wakeup_flag = false; // clear flag
rgbmatrix_clear();
rgbmatrix_puts(scroll_pos, 8, scroll_text, FONT_KING14, true, true, true);
matrix_puts(false, scroll_pos, 8, scroll_text, FONT_KING14, true, true, true);
if (scroll_pos < -1 * (int16_t)strlen(scroll_text) * (fonts[FONT_KING14].width + 1)) {
scroll_pos = 64;
} else {