src/dmx.c
author Tero Marttila <terom@paivola.fi>
Thu, 29 Jan 2015 23:11:44 +0200
changeset 107 05707929ff6f
parent 101 18c461237630
permissions -rw-r--r--
qmsk.web.async: handle HTTPExceptions
#include <util/delay.h>

// DMX
#define DMX_DDR     DDRD
#define DMX_PORT    PORTD
#define DMX_DATA    2

// baud rate: 250k = 4µs / bit
#define DMX_BAUD    (250 * 1000)
#define DMX_US      4

// CPU cycles / bit: 64 @ 16Mhz
#define DMX_CYCLES  (F_CPU / DMX_BAUD)

void dmx_init ()
{
    // dmx data out: idle (high)
    sbi(&DMX_PORT, DMX_DATA);
    sbi(&DMX_DDR, DMX_DATA);
}

static inline void dmx_high ()
{
    sbi(&DMX_PORT, DMX_DATA);
}

static inline void dmx_low ()
{
    cbi(&DMX_PORT, DMX_DATA);
}

#define dmx_pause(bits) _delay_us((DMX_US * bits))

static void dmx_break ()
{
    // break
    dmx_low();
    dmx_pause(22);

    // mark-after-break (MAB)
    dmx_high();
    dmx_pause(3); // min 2, recommended 3
}

#include "dmx_frame.c"

/*
 * Send out a full DMX packet, including the start-code frame and a frame for each channel given.
 *
 * Uses 3-bit mark-times between frames, since some fixtures don't seem happy with 2-bit mark-times.
 */
static void dmx_packet (byte count, byte *out)
{
    dmx_break();
    dmx_frame(0);
    dmx_pause(1); // MTBF 2+1 = 3

    for (byte i = 0; i < count; i++) {
        dmx_frame(out[i]);

        // MTBF 2+1 = 3
        dmx_pause(1);
    }
}