# HG changeset patch # User Tero Marttila # Date 1397216550 -10800 # Node ID 625f34328820accb8c4fa6f7ba0db2a3627f33da # Parent f9221fa50c75cec57119ad3afe7ba0a633b604df dmx: split out dmx.c module; implement console diff -r f9221fa50c75 -r 625f34328820 src/dmx.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dmx.c Fri Apr 11 14:42:30 2014 +0300 @@ -0,0 +1,57 @@ +#include + +// DMX +#define DMX_DDR DDRB +#define DMX_PORT PORTB +#define DMX_DATA 3 // SPI MOSI + +// baud rate: 250k = 4µs / bit +#define DMX_BAUD (250 * 1000) +#define DMX_US 4 + +// CPU cycles / bit: 64 @ 16Mhz +#define DMX_CYCLES (F_CPU / DMX_BAUD) + +void dmx_init () +{ + // dmx data out: idle (high) + sbi(&DMX_PORT, DMX_DATA); + sbi(&DMX_DDR, DMX_DATA); +} + +static inline void dmx_high () +{ + sbi(&DMX_PORT, DMX_DATA); +} + +static inline void dmx_low () +{ + cbi(&DMX_PORT, DMX_DATA); +} + +#define dmx_pause(bits) _delay_us((DMX_US * bits)) + +static void dmx_break () +{ + // break + dmx_low(); + dmx_pause(22); + + // mark-after-break (MAB) + dmx_high(); + dmx_pause(2); +} + +#include "dmx_frame.c" + +static void dmx_packet (byte r, byte g, byte b) +{ + dmx_break(); + dmx_frame(0); + + dmx_frame(0); // control + dmx_frame(r); + dmx_frame(g); + dmx_frame(b); + dmx_frame(0); // madness +} diff -r f9221fa50c75 -r 625f34328820 src/hello-dmx.c --- a/src/hello-dmx.c Fri Apr 11 14:42:19 2014 +0300 +++ b/src/hello-dmx.c Fri Apr 11 14:42:30 2014 +0300 @@ -5,9 +5,11 @@ */ #include -#include #include "stdlib.h" +#include "timer.c" +#include "serial.c" +#include "dmx.c" // debug #define DEBUG_DDR DDRB @@ -34,72 +36,171 @@ xbi(&DEBUG_PORT, DEBUG_LED); } -// DMX -#define DMX_DDR DDRB -#define DMX_PORT PORTB -#define DMX_DATA 3 // SPI MOSI +// dmx +/* + * DMX state + */ +static struct dmx_state { + byte out[256]; + byte count; +} dmx; -// baud rate: 250k = 4µs / bit -#define DMX_BAUD (250 * 1000) -#define DMX_US 4 -// CPU cycles / bit: 64 @ 16Mhz -#define DMX_CYCLES (F_CPU / DMX_BAUD) +enum state { + START = '\n', + CMD = ';', + ARG = ',', + ERROR = '!', +}; -void dmx_init () +enum cmd { + CMD_ +}; + +#define CONSOLE_ARGS 8 + +/* + * Console input state. + */ +static struct console { + enum state state; + + enum cmd cmd; + char argc; + char argv[CONSOLE_ARGS]; +} console; + +/* + * Process console command. + */ +int command () { - // dmx data out: idle (high) - sbi(&DMX_PORT, DMX_DATA); - sbi(&DMX_DDR, DMX_DATA); + switch (console.cmd) { + default: + return '?'; + } } -static inline void dmx_high () +/* + * Process console input. + */ +char input (char c) { - sbi(&DMX_PORT, DMX_DATA); -} + // control + if (c == '\r') { + char ret = '?'; -static inline void dmx_low () -{ - cbi(&DMX_PORT, DMX_DATA); + if (console.state == CMD) { + console.argc = 0; + } else if (console.state == ARG) { + console.argc++; + } else { + console.state = START; + return '\n'; + } + + // command + if ((ret = command(console.cmd))) { + + } else { + ret = '\n'; + } + + // return to START with response + console.state = START; + return ret; + + } else if (c == ' ' || c == '\t') { + // argument + if (console.state == CMD) { + console.state = ARG; + console.argc = 0; + + return c; + + } else if (console.state == ARG) { + if (console.argc++ < CONSOLE_ARGS) { + console.argv[console.argc] = 0; + + return c; + } + } + + // printable + } else if (32 < c && c < 128) { + // process input char + if (console.state == START) { + console.cmd = c; + console.state = CMD; + + return c; + + } else if (console.state == ARG) { + if (c >= '0' && c <= '9') { + console.argv[console.argc] *= 10; + console.argv[console.argc] += (c - '0'); + + return c; + } + } + } else { + // ignore + return ' '; + } + + // reject + console.state = ERROR; + return ERROR; } -#define dmx_pause(bits) _delay_us((DMX_US * bits)) - -static void dmx_break () -{ - // break - dmx_low(); - dmx_pause(22); - - // mark-after-break (MAB) - dmx_high(); - dmx_pause(2); -} - -#include "dmx_frame.c" - -static void dmx_packet (byte r, byte g, byte b) +/* + * Tick output state + */ +void update () { dmx_break(); dmx_frame(0); - dmx_frame(0); // control - dmx_frame(r); - dmx_frame(g); - dmx_frame(b); - dmx_frame(0); // madness + for (byte i = 0; i < dmx.count; i++) { + dmx_frame(dmx.out[i]); + } } void main () { led_init(); - dmx_init(); + timer_init(); + serial_init(); + //dmx_init(); - // dmx + // mainloop + char c = '>'; + unsigned timeout = 8000; // 2Hz + + sei(); + while (true) { - dmx_packet(0x00, 0x00, 0xff); - dmx_pause(100); + // sleep + //led_on(); + if (timer_sleep(timeout)) { + c = '.'; + } else if ((c = serial_read())) { + // got serial data + c = input(c); + + } else { + // unknown interrupt + c = '?'; + } + //led_off(); + + // respond + serial_write(c); + + // output + update(); + led_toggle(); } }