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