--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dmx_frame.c Sun Apr 06 18:25:55 2014 +0300
@@ -0,0 +1,49 @@
+/*
+ * Per-frame timing-critical bit-banging.
+ *
+ * Shamelessly stolen from
+ * http://code.google.com/p/tinkerit/source/browse/trunk/DmxSimple/DmxSimple.cpp
+ *
+ * Copyright (c) 2008-2009 Peter Knight, Tinker.it!
+ *
+ * Consumes approx. 11 * 64 ~= 705 clock cycles
+ * Leaves the line idle (high) on return.
+ */
+void dmx_frame (volatile byte value)
+{
+ uint8_t bitCount, delCount;
+ __asm__ volatile (
+ "cli\n"
+ "ld __tmp_reg__,%a[dmxPort]\n"
+ "and __tmp_reg__,%[outMask]\n"
+ "st %a[dmxPort],__tmp_reg__\n"
+ "ldi %[bitCount],11\n" // 11 bit intervals per transmitted byte
+ "rjmp bitLoop%=\n" // Delay 2 clock cycles.
+ "bitLoop%=:\n"\
+ "ldi %[delCount],%[delCountVal]\n"
+ "delLoop%=:\n"
+ "nop\n"
+ "dec %[delCount]\n"
+ "brne delLoop%=\n"
+ "ld __tmp_reg__,%a[dmxPort]\n"
+ "and __tmp_reg__,%[outMask]\n"
+ "sec\n"
+ "ror %[value]\n"
+ "brcc sendzero%=\n"
+ "or __tmp_reg__,%[outBit]\n"
+ "sendzero%=:\n"
+ "st %a[dmxPort],__tmp_reg__\n"
+ "dec %[bitCount]\n"
+ "brne bitLoop%=\n"
+ "sei\n"
+ :
+ [bitCount] "=&d" (bitCount),
+ [delCount] "=&d" (delCount)
+ :
+ [dmxPort] "e" (&DMX_PORT),
+ [outMask] "r" (~(1 << DMX_DATA)),
+ [outBit] "r" ((1 << DMX_DATA)),
+ [delCountVal] "M" (F_CPU/1000000-3),
+ [value] "r" (value)
+ );
+}