src/dmx_frame.c
changeset 62 2d68a76322cb
equal deleted inserted replaced
61:a960cf5981f7 62:2d68a76322cb
       
     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 }