--- /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 <util/delay.h>
+
+// 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
+}
--- 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 <avr/io.h>
-#include <util/delay.h>
#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();
}
}