/*************************************************************************** * mpm comms * * * * Copyright (C) 2011 - 2012 by Olaf Rempel * * razzor AT kopf MINUS tisch DOT de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License, * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #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 /* 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) static void mpm_reply(uint8_t cmd, uint8_t cause, uint16_t length, uint8_t *data); 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_bcnt; static uint16_t tx_length; static uint8_t *tx_data; ISR(USART_RXC_vect) { uint8_t data = UDR; sei(); /* MPM address stored in TWI address register by bootloader */ if ((UCSRA & (1<> 8); } else if (tx_bcnt == 3) { data = (tx_length & 0xFF); } else if ((tx_bcnt -4) < tx_length) { data = tx_data[tx_bcnt -4]; } UDR = data; /* re-enable for next round */ UCSRB |= (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][chan][COLOR_RED] = mpm_data[pos++]; baseptr[0][chan][COLOR_GREEN] = mpm_data[pos++]; baseptr[0][chan][COLOR_BLUE] = 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)[16][3] = (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][chan][COLOR_RED]; mpm_data[pos++] = baseptr[0][chan][COLOR_GREEN]; mpm_data[pos++] = baseptr[0][chan][COLOR_BLUE]; 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<>8) & 0xFF; UBRRL = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF); /* MPM address stored in TWI address register */ TWAR = MPM_ADDRESS; #endif /* (STANDALONE) */ }