diff --git a/src/driver/drv_sm16703P.c b/src/driver/drv_sm16703P.c
index e0e011ce..0593dbd6 100644
--- a/src/driver/drv_sm16703P.c
+++ b/src/driver/drv_sm16703P.c
@@ -22,12 +22,16 @@
#include "drv_spidma.h"
+#define SM16703P_MAX_CHANNELS (8)
+
static uint8_t data_translate[4] = {0b10001000, 0b10001110, 0b11101000, 0b11101110};
-UINT8 *send_buf;
-struct spi_message *spi_msg;
+UINT8 *send_buf = NULL;
+struct spi_message *spi_msg = NULL;
BOOLEAN initialized = false;
uint32_t pixel_count = 0;
+uint8_t channel_count = 3;
+uint8_t channel_map[SM16703P_MAX_CHANNELS];
static uint8_t translate_2bit(uint8_t input) {
//ADDLOG_INFO(LOG_FEATURE_CMD, "Translate 0x%02x to 0x%02x", (input & 0b00000011), data_translate[(input & 0b00000011)]);
@@ -58,7 +62,7 @@ static void SM16703P_setMultiplePixel(uint32_t pixel, UINT8 *data) {
// Iterate over pixel
uint8_t *dst = spi_msg->send_buf + 2;
- for (uint32_t i = 0; i < pixel * 3; i++) {
+ for (uint32_t i = 0; i < pixel * channel_count; i++) {
uint8_t input = *data++;
*dst++ = translate_2bit((input >> 6));
*dst++ = translate_2bit((input >> 4));
@@ -66,14 +70,21 @@ static void SM16703P_setMultiplePixel(uint32_t pixel, UINT8 *data) {
*dst++ = translate_2bit(input);
}
}
-void SM16703P_setPixel(int pixel, int r, int g, int b) {
- translate_byte(r, spi_msg->send_buf + (2 + 0 + (pixel * 3 * 4)));
- translate_byte(g, spi_msg->send_buf + (2 + 4 + (pixel * 3 * 4)));
- translate_byte(b, spi_msg->send_buf + (2 + 8 + (pixel * 3 * 4)));
+void SM16703P_setPixel(int pixel, int r, int g, int b, int w, int c) {
+ translate_byte(r, spi_msg->send_buf + (2 + channel_map[0]*4 + (pixel * channel_count * 4)));
+ translate_byte(g, spi_msg->send_buf + (2 + channel_map[1]*4 + (pixel * channel_count * 4)));
+ translate_byte(b, spi_msg->send_buf + (2 + channel_map[2]*4 + (pixel * channel_count * 4)));
+
+ if (channel_count >= 4) {
+ translate_byte(w, spi_msg->send_buf + (2 + channel_map[3]*4 + (pixel * channel_count * 4)));
+ }
+ if (channel_count >= 5) {
+ translate_byte(c, spi_msg->send_buf + (2 + channel_map[4]*4 + (pixel * channel_count * 4)));
+ }
}
commandResult_t SM16703P_CMD_setPixel(const void *context, const char *cmd, const char *args, int flags) {
- int pixel, i, r, g, b;
+ int pixel, i, r, g, b, w, c;
Tokenizer_TokenizeString(args, 0);
if (Tokenizer_GetArgsCount() != 4) {
@@ -86,32 +97,43 @@ commandResult_t SM16703P_CMD_setPixel(const void *context, const char *cmd, cons
g = Tokenizer_GetArgIntegerRange(2, 0, 255);
b = Tokenizer_GetArgIntegerRange(3, 0, 255);
- ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i", pixel, r, g, b);
+ if (channel_count >= 4) {
+ w = Tokenizer_GetArgIntegerRange(4, 0, 255);
+ }
+
+ if (channel_count >= 5) {
+ c = Tokenizer_GetArgIntegerRange(5, 0, 255);
+ }
+
+ if (channel_count <= 3) {
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i", pixel, r, g, b);
+ } else if (channel_count <= 4) {
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i W %i", pixel, r, g, b, w);
+ } else {
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i W %i C %i", pixel, r, g, b, w, c);
+ }
if (pixel < 0) {
for (i = 0; i < pixel_count; i++) {
- SM16703P_setPixel(i, r, g, b);
+ SM16703P_setPixel(i, r, g, b, w, c);
}
}
- else {
- SM16703P_setPixel(pixel, r, g, b);
-
- ADDLOG_INFO(LOG_FEATURE_CMD, "Raw Data 0x%02x 0x%02x 0x%02x 0x%02x - 0x%02x 0x%02x 0x%02x 0x%02x - 0x%02x 0x%02x 0x%02x 0x%02x",
- spi_msg->send_buf[2 + 0 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 1 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 2 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 3 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 4 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 5 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 6 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 7 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 8 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 9 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 10 + (pixel * 3 * 4)],
- spi_msg->send_buf[2 + 11 + (pixel * 3 * 4)]);
+ else if (pixel < pixel_count) {
+ SM16703P_setPixel(pixel, r, g, b, w, c);
+
+ for (i = 0; i < channel_count; i++) {
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Raw Data CH%i 0x%02x 0x%02x 0x%02x 0x%02x",
+ i,
+ spi_msg->send_buf[2 + 0 + i*4 + (pixel * channel_count * 4)],
+ spi_msg->send_buf[2 + 1 + i*4 + (pixel * channel_count * 4)],
+ spi_msg->send_buf[2 + 2 + i*4 + (pixel * channel_count * 4)],
+ spi_msg->send_buf[2 + 3 + i*4 + (pixel * channel_count * 4)]);
+ }
+ } else {
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Bad pixel index %i", pixel);
+ return CMD_RES_BAD_ARGUMENT;
}
-
return CMD_RES_OK;
}
@@ -120,30 +142,64 @@ static void SM16703P_Send(byte *data, int dataSize) {
}
commandResult_t SM16703P_Start(const void *context, const char *cmd, const char *args, int flags) {
-
+ int i;
Tokenizer_TokenizeString(args, 0);
if (Tokenizer_GetArgsCount() == 0) {
- ADDLOG_INFO(LOG_FEATURE_CMD, "Not Enough Arguments for init SM16703P: Amount of LEDs missing");
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Not Enough Arguments for init SM16703P: Pixel count is missing");
return CMD_RES_NOT_ENOUGH_ARGUMENTS;
}
pixel_count = Tokenizer_GetArgIntegerRange(0, 0, 255);
+ if (Tokenizer_GetArgsCount() >= 2) {
+ channel_count = Tokenizer_GetArgIntegerRange(1, 0, SM16703P_MAX_CHANNELS);
+ } else {
+ channel_count = 3;
+ }
+
+ if (Tokenizer_GetArgsCount() >= 3) {
+ for (i = 0; i < channel_count; i++) {
+ channel_map[i] = Tokenizer_GetArgIntegerRange(2+i, 0, 8);
+ if (channel_map[i] >= channel_count) {
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Bad channel index %i for channel %i", channel_map[i], i);
+ return CMD_RES_BAD_ARGUMENT;
+ }
+ }
+ } else {
+ for (i = 0; i < channel_count; i++) {
+ channel_map[i] = i;
+ }
+ }
+
ADDLOG_INFO(LOG_FEATURE_CMD, "Register driver with %i LEDs", pixel_count);
+ // Free the old buffer if one was allocated.
+ if (initialized) {
+ os_free(send_buf);
+ }
+
// Prepare buffer
- uint32_t buffer_size = 2 + (pixel_count * 3 * 4); //Add two bytes for "Reset"
+ uint32_t buffer_size = 2 + (pixel_count * channel_count * 4); //Add two bytes for "Reset"
send_buf = (UINT8 *)os_malloc(sizeof(UINT8) * (buffer_size)); //18LEDs x RGB x 4Bytes
- int i;
send_buf[0] = 0;
send_buf[1] = 0;
+ // Turn on all channels on all pixels at maximum brightness.
+ // TODO: Is this REALLY what we want to do? Shouldn't we be
+ // be setting the initial value to be encoded zero bits
+ // instead of encoded 1 bits? Consider changing to
+ // 0b10001000 after discussion.
for (i = 2; i < buffer_size; i++) {
send_buf[i] = 0b11101110;
}
+ // Free the old buffer if one was allocated.
+ if (initialized) {
+ os_free(spi_msg);
+ }
+
spi_msg = os_malloc(sizeof(struct spi_message));
spi_msg->send_buf = send_buf;
spi_msg->send_len = buffer_size;