change color via mpm

This commit is contained in:
Olaf Rempel 2012-03-04 17:29:01 +01:00
parent 953c12a3c7
commit 48775284b1
3 changed files with 182 additions and 47 deletions

8
main.c
View File

@ -58,12 +58,16 @@ int main(void)
uint16_t ramp = 0; uint16_t ramp = 0;
uint8_t step = 0; uint8_t step = 0;
/* wait for complete update */
rgb_update(COLOR_MASK, 1);
while (1) { while (1) {
mpm_check_transfer();
#if 0
/* wait for complete update */ /* wait for complete update */
rgb_update(COLOR_MASK, 1); rgb_update(COLOR_MASK, 1);
#if 1
// _delay_ms(100); // _delay_ms(100);
step++; step++;

218
mpmctrl.c
View File

@ -21,44 +21,83 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <stdio.h> /* NULL */
#include "rgb16mpm.h" #include "rgb16mpm.h"
/* Dummy Wait:
* req: <cmd:0x00> <len[2]:0x0000>
* rsp: <cmd:0x00 <cause:0x00> <len[2]:0x0000>
*/
#define CMD_WAIT 0x00 #define CMD_WAIT 0x00
/* Switch Run Mode:
* req: <cmd:0x01> <len[2]:0x0001> <mode>
* rsp: <cmd:0x01> <cause> <len[2]:0x0000>
*/
#define CMD_SWITCH_MODE 0x01 #define CMD_SWITCH_MODE 0x01
/* Get Software Version:
* req: <cmd:0x02> <len[2]:0x0000>
* rsp: <cmd:0x02> <cause> <len[2]> <version>
*/
#define CMD_GET_VERSION 0x02 #define CMD_GET_VERSION 0x02
#define CMD_GET_CHIPINFO 0x03 /* bootloader / mpmboot */
#define CMD_READ_MEMORY 0x11 /* bootloader / mpmboot */ /* Write RAW color:
#define CMD_WRITE_MEMORY 0x12 /* bootloader / mpmboot */ * req: <cmd:0x80> <len[2]> <firstchannel> <RGB[x][3]>
#define CMD_WRITE_COLOR 0x81 * rsp: <cmd:0x80> <cause>,<len[2]:0x0000>
#define CMD_WRITE_RAW_COLOR 0x82 */
#define CMD_READ_RAW_COLOR 0x83 #define CMD_WRITE_RAW_COLOR 0x80
#define CMD_WRITE_CONFIG 0x81 #define CMD_WRITE_INIT_COLOR 0x82
/* Read RAW color:
* req: <cmd:0x80> <len[2]> <firstchannel> <count>
* rsp: <cmd:0x80> <cause>,<len[2]> <RGB[x][3]>
*/
#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) #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; const static uint8_t versioninfo[16] = VERSION_STRING;
static uint16_t rx_bcnt = 0xFF;
#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 uint16_t rx_length;
static volatile uint8_t rx_ready;
static uint8_t tx_cmd; static uint8_t tx_cmd;
static uint8_t tx_cause; static uint8_t tx_cause;
static uint16_t tx_length;
static uint16_t tx_bcnt; static uint16_t tx_bcnt;
static uint16_t tx_length;
static uint8_t *tx_data;
ISR(USART_RXC_vect) ISR(USART_RXC_vect)
{ {
uint8_t data = UDR; uint8_t data = UDR;
sei(); sei();
if (rx_bcnt == 0xFF) { /* MPM address stored in TWI address register by bootloader */
/* MPM address stored in TWI address register by bootloader */ if ((UCSRA & (1<<MPCM)) && (data == TWAR)) {
if (data == TWAR) { UCSRA &= ~(1<<MPCM);
UCSRA &= ~(1<<MPCM); rx_bcnt = 0;
rx_bcnt = 0;
}
} else { } else {
if (rx_bcnt == 0) { if (rx_bcnt == 0) {
@ -67,29 +106,33 @@ ISR(USART_RXC_vect)
} else if ((rx_bcnt == 1) || (rx_bcnt == 2)) { } else if ((rx_bcnt == 1) || (rx_bcnt == 2)) {
rx_length = (rx_length << 8) | data; rx_length = (rx_length << 8) | data;
} else if ((rx_bcnt -3) < rx_length) { } else if ((rx_bcnt -3) < MPM_MAX_DATA_SIZE) {
// TODO: get data mpm_data[rx_bcnt -3] = data;
} }
/* message complete */
if ((rx_bcnt -2) == rx_length) { if ((rx_bcnt -2) == rx_length) {
/* enable RS485 TX */ switch (rx_cmd) {
PORTD |= (1<<RXTX); case CMD_WAIT:
case CMD_SWITCH_MODE:
mpm_reply(rx_cmd, CAUSE_SUCCESS, 0, NULL);
break;
/* first byte */ case CMD_GET_VERSION:
tx_cmd = rx_cmd; mpm_reply(rx_cmd, CAUSE_SUCCESS, sizeof(versioninfo), (uint8_t *)versioninfo);
UDR = rx_cmd; break;
/* prepare header */ case CMD_WRITE_RAW_COLOR:
tx_bcnt = 1; case CMD_WRITE_INIT_COLOR:
tx_cause = 0; case CMD_READ_RAW_COLOR:
tx_length = 0; case CMD_READ_INIT_COLOR:
rx_ready = 1;
break;
if (tx_cmd == CMD_GET_VERSION) { default:
tx_length = sizeof(versioninfo); mpm_reply(rx_cmd, CAUSE_NOT_SUPPORTED, 0, NULL);
break;
} }
/* enable interrupt */
UCSRB |= (1<<UDRIE);
} }
rx_bcnt++; rx_bcnt++;
} }
@ -102,9 +145,8 @@ ISR(USART_UDRE_vect)
sei(); sei();
if ((tx_bcnt < 4) || (tx_bcnt -4) < tx_length) { if ((tx_bcnt < 4) || (tx_bcnt -4) < tx_length) {
uint16_t pos = (tx_bcnt -4);
uint8_t data = 0xFF;
uint8_t data = 0xAA;
if (tx_bcnt == 1) { if (tx_bcnt == 1) {
data = tx_cause; data = tx_cause;
@ -114,11 +156,8 @@ ISR(USART_UDRE_vect)
} else if (tx_bcnt == 3) { } else if (tx_bcnt == 3) {
data = (tx_length & 0xFF); data = (tx_length & 0xFF);
} else if (tx_cmd == CMD_GET_VERSION) { } else if ((tx_bcnt -4) < tx_length) {
data = versioninfo[pos]; data = tx_data[tx_bcnt -4];
} else {
data = 0xAA;
} }
UDR = data; UDR = data;
@ -136,16 +175,105 @@ ISR(USART_TXC_vect, ISR_NOBLOCK)
PORTD &= ~(1<<RXTX); PORTD &= ~(1<<RXTX);
/* enable MP mode again */ /* enable MP mode again */
UCSRA |= (1<<MPCM); UCSRA |= (1<<MPCM);
rx_bcnt = 0xFF; // FIXME: cli?
#if !(STANDALONE) #if !(STANDALONE)
if (tx_cmd == CMD_SWITCH_MODE) { // FIXME: check mode /* reset MCU -> enter bootloader */
if ((tx_cmd == CMD_SWITCH_MODE) && (mpm_data[0] == BOOTMODE_BOOTLOADER)) {
wdt_enable(WDTO_15MS); wdt_enable(WDTO_15MS);
} }
#endif /* !(STANDALONE) */ #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<<RXTX);
/* first byte and enable interrupt */
UDR = tx_cmd;
UCSRB |= (1<<UDRIE);
}
void mpm_check_transfer(void)
{
if (rx_ready == 0)
return;
rx_ready = 0;
switch (rx_cmd) {
case CMD_WRITE_RAW_COLOR:
case CMD_WRITE_INIT_COLOR:
{
uint8_t chan = mpm_data[0];
uint8_t pos = 1;
uint8_t cause = CAUSE_SUCCESS;
uint8_t (*baseptr)[3][16] = (rx_cmd == CMD_WRITE_RAW_COLOR) ? &chan_value : &nvram_data.initialRGB;
while ((pos < rx_length)) {
if ((chan >= 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) void mpm_init(void)
{ {
PORTD &= ~(1<<RXTX); PORTD &= ~(1<<RXTX);

View File

@ -21,6 +21,8 @@
#define MPM_ADDRESS 0x11 #define MPM_ADDRESS 0x11
#endif /* STANDALONE */ #endif /* STANDALONE */
#define VERSION_STRING "rgb16mpm v0.99"
#define COLOR_RED 0 #define COLOR_RED 0
#define COLOR_GREEN 1 #define COLOR_GREEN 1
#define COLOR_BLUE 2 #define COLOR_BLUE 2
@ -47,6 +49,7 @@ void eeprom_read(void);
/* mpmctrl.c funcs */ /* mpmctrl.c funcs */
void mpm_init(void); void mpm_init(void);
void mpm_check_transfer(void);
/* rgbctrl.c vars */ /* rgbctrl.c vars */
extern uint8_t chan_value[3][16]; extern uint8_t chan_value[3][16];