--- /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();
+ }
+}