dmx-web: slightly better RGB colorpicker control..
#include <avr/io.h>
#include "stdlib.h"
// XXX
#include "timer.c"
#include "serial.c"
#include "spi.c"
#include "led7.c"
static enum state {
START = '\n',
CMD_SET = 's',
CMD_INC = '+',
CMD_DEC = '-',
CMD_READ = 'r',
ARG_CHAR = '0',
ERROR = '!',
} state = START, cmd = 0;
static enum {
CMD_LED_1 = 0,
} cmd_led = 0;
static char arg_char;
static unsigned char led_state = 0;
int command (enum state cmd)
{
switch (cmd) {
case CMD_SET:
led_state = arg_char;
return 0;
case CMD_INC:
if (led_state == 0xff)
return 1;
led_state++;
return 0;
case CMD_DEC:
if (!led_state)
return 1;
led_state--;
return 0;
case CMD_READ:
led_state = spi_rx[1]; // XXX
return 0;
default:
return 1;
}
}
char input (char c)
{
if (c == '\r') {
char ret = '?';
// command state
switch (state) {
case START:
cmd = 0;
break;
case CMD_SET:
case CMD_INC:
case CMD_DEC:
break;
case ARG_CHAR:
break;
case ERROR:
cmd = 0;
break;
}
// command
if (!cmd) {
ret = ' ';
} else if (command(cmd)) {
ret = '!';
} else {
ret = '\n';
}
// return to START with response
state = START;
return ret;
} else if (31 < c && c < 128) {
// process input char
switch (state) {
case START:
if (c == 's') {
cmd = CMD_SET;
state = ARG_CHAR;
arg_char = 0;
} else if (c == 'S') {
cmd = state = CMD_SET;
arg_char = 255;
} else if (c == '+') {
cmd = state = CMD_INC;
} else if (c == '-') {
cmd = state = CMD_DEC;
} else if (c == 'r') {
cmd = state = CMD_READ;
} else {
break;
}
return state;
break;
/*
case CMD_SET:
if (c == '1') {
cmd_led = CMD_LED_1;
state = ARG_CHAR;
arg_char = 0;
} else {
state = ERROR;
}
break;
*/
case ARG_CHAR:
if (c >= '0' && c <= '9') {
arg_char *= 10;
arg_char += (c - '0');
} else {
break;
}
return c;
break;
}
// reject
state = ERROR;
return ERROR;
} else {
// ignore
return ' ';
}
}
#define DEBUG_DDR DDRB
#define DEBUG_PORT PORTB
#define DEBUG_LED 0
int main (void)
{
led7_init();
timer_init();
serial_init();
spi_init();
// led_init();
sbi(&DEBUG_DDR, DEBUG_LED);
sei();
// start
char c;
unsigned short timeout = 0;
serial_write(state);
while (true) {
// TODO: SPI timer
led7_update(led_state);
spi_update();
// toggle
if (led_state == 0) {
timeout = 0;
cbi(&DEBUG_PORT, DEBUG_LED);
} else if (led_state == 255) {
timeout = 0;
sbi(&DEBUG_PORT, DEBUG_LED);
} else {
// as Hz
timeout = (16000 / led_state);
xbi(&DEBUG_PORT, DEBUG_LED);
}
// sleep
if (timer_sleep(timeout)) {
c = '.';
} else if ((c = serial_read())) {
// got serial data
c = input(c);
} else {
c = '?';
}
// output...
serial_write(c);
}
}