From 6b6589e93cc4c57fe9859c55f53fe7b7169cada1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Fri, 17 Jul 2015 10:01:43 +0200 Subject: [PATCH] implement atmolight protocol --- firmware/main.c | 119 ++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 75 deletions(-) diff --git a/firmware/main.c b/firmware/main.c index 9359f74..6496d13 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -31,14 +31,12 @@ #include "ws2812b.h" // to control WS2812B LEDs /* global variables */ -const uint8_t leds_per_channel[WS2812B_NB_CHANNELS] = {11,5,9,11,5,9}; // the led strips (top 1, top 2, left, bottom 1, bottom 2, right) -uint8_t nb_leds = 0; // the total number of LEDs (will be calculated on the number of LEDs per channel) -volatile uint8_t uart_in[16]; // input from USART, enough space for one fnordlight command or sync sequence +volatile uint8_t uart_in[19]; // input from USART, enough space for one atmolight message +volatile uint8_t uart_in_i = 0; // UART input index /* flags, set in the interrupts and handled in the main program */ volatile bool uart_flag = false; // data on UART has been received volatile char uart_char = 0; // UART data -volatile bool command_flag = false; // a command has been received /* switch off LED */ void led_off(void) @@ -70,39 +68,10 @@ void wdt_init(void) /* receive UART input */ ISR(USART_RX_vect) { /* UART receive interrupt */ - uart_char = getchar(); // save current character - uart_flag = true; // warm main programm -} - -/* process command */ -void command_action(void) -{ - /* parse command */ - switch (uart_in[1]) { - case 0x01: // set LED colors - if (uart_in[0]=15) { // end of sync sequence - uart_in_i = 0; // reset input but don't handle sync sequence - } - escape_count = 0; // restart count - } - if (uart_in_i>=15 && escape_count<15) { // end of command - command_flag = true; // notify a command is ready - uart_in_i = 0; // reset input - } uart_flag = false; - } - while (command_flag) { // UART input command is ready - led_on(); - command_action(); // process command - command_flag = false; // clear flag - led_off(); + if (((uart_in_i==1) && !(uart_in[0]==0xff)) || + ((uart_in_i==2) && !(uart_in[1]==0x00)) || + ((uart_in_i==3) && !(uart_in[2]==0x00)) || + ((uart_in_i==4) && !(uart_in[3]==0x0f))) { // wait for start sequence + led_on(); // indicate something is wrong + uart_in_i = 0; // reset if start sequence is not detected + } else { + led_off(); + /* process colors on channels */ + if (uart_in_i==10) { // left atmolight channel received (WS2812B channel 2) + for (uint8_t led=0; led<11; led++) { + ws2812b_set_led_color(2,led,uart_in[7],uart_in[8],uart_in[9]); + } + } else if (uart_in_i==13) { // right atmolight channel received (WS2812B channel 5) + for (uint8_t led=0; led<11; led++) { + ws2812b_set_led_color(5,led,uart_in[10],uart_in[11],uart_in[12]); + } + } else if (uart_in_i==16) { // top atmolight channel received (WS2812B channel 0+1) + for (uint8_t led=0; led<11; led++) { + ws2812b_set_led_color(0,led,uart_in[13],uart_in[14],uart_in[15]); + } + for (uint8_t led=0; led<8; led++) { + ws2812b_set_led_color(1,led,uart_in[13],uart_in[14],uart_in[15]); + } + } else if (uart_in_i==19) { // bottom atmolight channel received (WS2812B channel 3+4) + for (uint8_t led=0; led<11; led++) { + ws2812b_set_led_color(3,led,uart_in[16],uart_in[17],uart_in[18]); + } + for (uint8_t led=0; led<8; led++) { + ws2812b_set_led_color(4,led,uart_in[16],uart_in[17],uart_in[18]); + } + } + if (uart_in_i>=sizeof(uart_in)) { // end of message + uart_in_i = 0; // start with next message + ws2812b_show(); // show the new colors + } + } } } return 0;