dmx: implement output
authorTero Marttila <terom@paivola.fi>
Fri, 11 Apr 2014 15:57:48 +0300
changeset 66 0cf14786b909
parent 65 625f34328820
child 67 53743ecc9150
dmx: implement output
src/dmx.c
src/hello-dmx.c
--- a/src/dmx.c	Fri Apr 11 14:42:30 2014 +0300
+++ b/src/dmx.c	Fri Apr 11 15:57:48 2014 +0300
@@ -44,14 +44,12 @@
 
 #include "dmx_frame.c"
 
-static void dmx_packet (byte r, byte g, byte b)
+static void dmx_packet (byte count, byte *out)
 {
     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 < count; i++) {
+        dmx_frame(out[i]);
+    }
 }
--- a/src/hello-dmx.c	Fri Apr 11 14:42:30 2014 +0300
+++ b/src/hello-dmx.c	Fri Apr 11 15:57:48 2014 +0300
@@ -37,15 +37,16 @@
 }
 
 // dmx
+#define DMX_COUNT 255
+
 /*
  * DMX state
  */
 static struct dmx_state {
-    byte out[256];
+    byte out[DMX_COUNT];
     byte count;
 } dmx;
 
-
 enum state {
     START       = '\n',
     CMD         = ';',
@@ -53,22 +54,89 @@
     ERROR       = '!',
 };
 
-enum cmd {
-    CMD_
-};
-
 #define CONSOLE_ARGS 8
 
 /*
  * Console input state.
  */
 static struct console {
-    enum state state;
+    byte state;
+    byte cmd;
+    byte argc;
+    byte argv[CONSOLE_ARGS];
+} console;
 
-    enum cmd cmd;
-    char argc;
-    char argv[CONSOLE_ARGS];
-} console;
+/*
+ * Clear output (no state).
+ */
+int cmd_clear ()
+{
+    dmx.count = 0;
+
+    return 0;
+}
+
+/*
+ * Set output to given sequence.
+ */
+int cmd_out ()
+{
+    byte i;
+
+    for (i = 0; i < console.argc; i++) {
+        dmx.out[i] = console.argv[i];
+    }
+
+    dmx.count = i;
+
+    return 0;
+}
+
+/*
+ * Set output at offset.
+ */
+int cmd_set ()
+{
+    if (console.argc < 1) {
+        return '!';
+    }
+
+    byte i = console.argv[0];
+
+    for (byte a = 1; a < console.argc; a++) {
+        dmx.out[i++] = console.argv[a];
+    }
+
+    if (i > dmx.count)
+        dmx.count = i;
+
+    return 0;
+}
+
+/*
+ * Set output to max. zeroes
+ */
+int cmd_zero ()
+{
+    byte count;
+
+    if (console.argc == 0) {
+        count = DMX_COUNT;
+    } else if (console.argc == 1) {
+        count = console.argv[0];
+    } else {
+        return '!';
+    }
+
+    // set
+    byte i;
+    for (i = 0; i < count; i++) {
+        dmx.out[i] = 0;
+    }
+    dmx.count = i;
+
+    return 0;
+}
 
 /*
  * Process console command.
@@ -76,8 +144,12 @@
 int command ()
 {
     switch (console.cmd) {
-        default:
-            return '?';
+        case 'c':       return cmd_clear();
+        case 'o':       return cmd_out();
+        case 's':       return cmd_set();
+        case 'z':       return cmd_zero();
+
+        default:        return '?';
     }
 }
 
@@ -108,21 +180,21 @@
         
         // return to START with response
         console.state = START;
-        return ret;
+        return '\n'; // XXX: required to delimit command reponses..
     
-    } else if (c == ' ' || c == '\t') {
+    } else if (c == ' ' || c == '\t' || c == ',') {
         // argument
         if (console.state == CMD) {
             console.state = ARG;
             console.argc = 0;
 
-            return c;
+            return ',';
 
         } else if (console.state == ARG) {
             if (console.argc++ < CONSOLE_ARGS) {
                 console.argv[console.argc] = 0;
 
-                return c;
+                return ',';
             }
         }
 
@@ -158,12 +230,7 @@
  */
 void update ()
 {
-    dmx_break();
-    dmx_frame(0);
-
-    for (byte i = 0; i < dmx.count; i++) {
-        dmx_frame(dmx.out[i]);
-    }
+    dmx_packet(dmx.count, dmx.out);
 }
 
 void main ()
@@ -171,19 +238,23 @@
     led_init();
     timer_init();
     serial_init();
-    //dmx_init();
+    dmx_init();
 
     // mainloop
     char c = '>';
     unsigned timeout = 8000; // 2Hz
     
+    // start
     sei();
+    serial_write(c);
 
     while (true) {
         // sleep
         //led_on();
         if (timer_sleep(timeout)) {
-            c = '.';
+            //c = ' ';
+            led_toggle();
+            c = 0;
 
         } else if ((c = serial_read())) {
             // got serial data
@@ -195,12 +266,11 @@
         }
         //led_off();
         
-        // respond
-        serial_write(c);
+        if (c)
+            // respond
+            serial_write(c);
         
         // output
         update();
-        
-        led_toggle();
     }
 }