diff --git a/main.c b/main.c index 694cca0..4aae709 100644 --- a/main.c +++ b/main.c @@ -58,12 +58,16 @@ int main(void) uint16_t ramp = 0; uint8_t step = 0; + /* wait for complete update */ + rgb_update(COLOR_MASK, 1); + while (1) { + mpm_check_transfer(); + +#if 0 /* wait for complete update */ rgb_update(COLOR_MASK, 1); -#if 1 - // _delay_ms(100); step++; diff --git a/mpmctrl.c b/mpmctrl.c index f6db845..bd801c1 100644 --- a/mpmctrl.c +++ b/mpmctrl.c @@ -21,44 +21,83 @@ #include #include #include +#include /* NULL */ #include "rgb16mpm.h" +/* Dummy Wait: + * req: + * rsp: + */ #define CMD_WAIT 0x00 + +/* Switch Run Mode: + * req: + * rsp: + */ #define CMD_SWITCH_MODE 0x01 + +/* Get Software Version: + * req: + * rsp: + */ #define CMD_GET_VERSION 0x02 -#define CMD_GET_CHIPINFO 0x03 /* bootloader / mpmboot */ -#define CMD_READ_MEMORY 0x11 /* bootloader / mpmboot */ -#define CMD_WRITE_MEMORY 0x12 /* bootloader / mpmboot */ -#define CMD_WRITE_COLOR 0x81 -#define CMD_WRITE_RAW_COLOR 0x82 -#define CMD_READ_RAW_COLOR 0x83 -#define CMD_WRITE_CONFIG 0x81 + +/* Write RAW color: + * req: + * rsp: , + */ +#define CMD_WRITE_RAW_COLOR 0x80 +#define CMD_WRITE_INIT_COLOR 0x82 + +/* Read RAW color: + * req: + * rsp: , + */ +#define CMD_READ_RAW_COLOR 0x81 +#define CMD_READ_INIT_COLOR 0x83 + +/* response causes */ +#define CAUSE_SUCCESS 0x00 +#define CAUSE_NOT_SUPPORTED 0xF0 +#define CAUSE_INVALID_PARAMETER 0xF1 +#define CAUSE_UNSPECIFIED_ERROR 0xFF + +/* parameter for CMD_SWITCH_MODE */ +#define BOOTMODE_BOOTLOADER 0x00 +#define BOOTMODE_APPLICATION 0x80 #define UART_CALC_BAUDRATE(baudRate) (((uint32_t)F_CPU) / (((uint32_t)baudRate)*16) -1) -const static uint8_t versioninfo[16] = "rgb16mpm v0.99"; +static void mpm_reply(uint8_t cmd, uint8_t cause, uint16_t length, uint8_t *data); -static uint8_t rx_cmd; -static uint16_t rx_bcnt = 0xFF; +const static uint8_t versioninfo[16] = VERSION_STRING; + +#define MPM_MAX_DATA_SIZE 64 + +static uint8_t mpm_data[MPM_MAX_DATA_SIZE]; + +static uint8_t rx_cmd; +static uint16_t rx_bcnt; static uint16_t rx_length; +static volatile uint8_t rx_ready; -static uint8_t tx_cmd; -static uint8_t tx_cause; -static uint16_t tx_length; +static uint8_t tx_cmd; +static uint8_t tx_cause; static uint16_t tx_bcnt; +static uint16_t tx_length; +static uint8_t *tx_data; + ISR(USART_RXC_vect) { uint8_t data = UDR; sei(); - if (rx_bcnt == 0xFF) { - /* MPM address stored in TWI address register by bootloader */ - if (data == TWAR) { - UCSRA &= ~(1< enter bootloader */ + if ((tx_cmd == CMD_SWITCH_MODE) && (mpm_data[0] == BOOTMODE_BOOTLOADER)) { wdt_enable(WDTO_15MS); } #endif /* !(STANDALONE) */ } +static void mpm_reply(uint8_t cmd, uint8_t cause, uint16_t length, uint8_t *data) +{ + /* prepare header */ + tx_cmd = cmd; + tx_bcnt = 1; + tx_cause = cause; + tx_length = length; + tx_data = data; + + /* enable RS485 TX */ + PORTD |= (1<= 16) || ((pos +2) >= MPM_MAX_DATA_SIZE)) { + cause = CAUSE_INVALID_PARAMETER; + break; + } + + baseptr[0][COLOR_RED][chan] = mpm_data[pos++]; + baseptr[0][COLOR_GREEN][chan] = mpm_data[pos++]; + baseptr[0][COLOR_BLUE][chan] = mpm_data[pos++]; + chan++; + } + + mpm_reply(rx_cmd, cause, 0, NULL); + + if (rx_cmd == CMD_WRITE_RAW_COLOR) { + rgb_update(COLOR_MASK, 1); + + } else { + eeprom_write(); + } + } + break; + + case CMD_READ_RAW_COLOR: + case CMD_READ_INIT_COLOR: + { + uint8_t chan = mpm_data[0]; + uint8_t count = mpm_data[1]; + uint8_t pos = 0; + uint8_t cause = CAUSE_SUCCESS; + + uint8_t (*baseptr)[3][16] = (rx_cmd == CMD_READ_RAW_COLOR) ? &chan_value : &nvram_data.initialRGB; + + while (count--) { + if ((chan >= 16) || ((pos +2) >= MPM_MAX_DATA_SIZE)) { + cause = CAUSE_INVALID_PARAMETER; + break; + } + + mpm_data[pos++] = baseptr[0][COLOR_RED][chan]; + mpm_data[pos++] = baseptr[0][COLOR_GREEN][chan]; + mpm_data[pos++] = baseptr[0][COLOR_BLUE][chan]; + chan++; + } + + mpm_reply(rx_cmd, cause, pos, mpm_data); + } + break; + + default: + mpm_reply(rx_cmd, CAUSE_UNSPECIFIED_ERROR, 0, NULL); + break; + } +} + void mpm_init(void) { PORTD &= ~(1<