diff -r a960cf5981f7 -r 2d68a76322cb src/dmx_frame.c --- /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) + ); +}