#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);
}
}