src/dmx_frame.c
author Tero Marttila <terom@paivola.fi>
Thu, 29 Jan 2015 23:11:44 +0200
changeset 107 05707929ff6f
parent 62 2d68a76322cb
permissions -rw-r--r--
qmsk.web.async: handle HTTPExceptions
/*
 * 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)
  );
}