src/hello-dmx.c
changeset 62 2d68a76322cb
child 65 625f34328820
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hello-dmx.c	Sun Apr 06 18:25:55 2014 +0300
@@ -0,0 +1,105 @@
+/*
+ * DMX output.
+ *
+ * See doc/dmx.txt for the RX-485 bus protocol details...
+ */
+
+#include <avr/io.h>
+#include <util/delay.h>
+
+#include "stdlib.h"
+
+// debug
+#define DEBUG_DDR   DDRB
+#define DEBUG_PORT  PORTB
+#define DEBUG_LED   0
+
+void led_init ()
+{
+    sbi(&DEBUG_DDR, DEBUG_LED);
+}
+
+void led_on ()
+{
+    sbi(&DEBUG_PORT, DEBUG_LED);
+}
+
+void led_off ()
+{
+    cbi(&DEBUG_PORT, DEBUG_LED);
+}
+
+void led_toggle ()
+{
+    xbi(&DEBUG_PORT, DEBUG_LED);
+}
+
+// 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
+}
+
+void main ()
+{
+    led_init();
+    dmx_init();
+
+    // dmx
+    while (true) {
+        dmx_packet(0x00, 0x00, 0xff);
+        dmx_pause(100);
+
+        led_toggle();
+    }
+}