|
1 /* |
|
2 * Per-frame timing-critical bit-banging. |
|
3 * |
|
4 * Shamelessly stolen from |
|
5 * http://code.google.com/p/tinkerit/source/browse/trunk/DmxSimple/DmxSimple.cpp |
|
6 * |
|
7 * Copyright (c) 2008-2009 Peter Knight, Tinker.it! |
|
8 * |
|
9 * Consumes approx. 11 * 64 ~= 705 clock cycles |
|
10 * Leaves the line idle (high) on return. |
|
11 */ |
|
12 void dmx_frame (volatile byte value) |
|
13 { |
|
14 uint8_t bitCount, delCount; |
|
15 __asm__ volatile ( |
|
16 "cli\n" |
|
17 "ld __tmp_reg__,%a[dmxPort]\n" |
|
18 "and __tmp_reg__,%[outMask]\n" |
|
19 "st %a[dmxPort],__tmp_reg__\n" |
|
20 "ldi %[bitCount],11\n" // 11 bit intervals per transmitted byte |
|
21 "rjmp bitLoop%=\n" // Delay 2 clock cycles. |
|
22 "bitLoop%=:\n"\ |
|
23 "ldi %[delCount],%[delCountVal]\n" |
|
24 "delLoop%=:\n" |
|
25 "nop\n" |
|
26 "dec %[delCount]\n" |
|
27 "brne delLoop%=\n" |
|
28 "ld __tmp_reg__,%a[dmxPort]\n" |
|
29 "and __tmp_reg__,%[outMask]\n" |
|
30 "sec\n" |
|
31 "ror %[value]\n" |
|
32 "brcc sendzero%=\n" |
|
33 "or __tmp_reg__,%[outBit]\n" |
|
34 "sendzero%=:\n" |
|
35 "st %a[dmxPort],__tmp_reg__\n" |
|
36 "dec %[bitCount]\n" |
|
37 "brne bitLoop%=\n" |
|
38 "sei\n" |
|
39 : |
|
40 [bitCount] "=&d" (bitCount), |
|
41 [delCount] "=&d" (delCount) |
|
42 : |
|
43 [dmxPort] "e" (&DMX_PORT), |
|
44 [outMask] "r" (~(1 << DMX_DATA)), |
|
45 [outBit] "r" ((1 << DMX_DATA)), |
|
46 [delCountVal] "M" (F_CPU/1000000-3), |
|
47 [value] "r" (value) |
|
48 ); |
|
49 } |