256 lines
6.3 KiB
C
256 lines
6.3 KiB
C
#include <avr/io.h>
|
|
#include <stdint.h>
|
|
|
|
/* DMX buffer: indexed 1..512 */
|
|
extern volatile uint8_t dmx_data[];
|
|
|
|
/* Pin bit definitions (change bit numbers if different on your board) */
|
|
/* PE4, PE5, PG5, PE3, PH3, PH4, PH5, PH6, PB4, PB5, PB6, PB7,
|
|
PL7, PL6, PL5, PL4, PL3, PL2, PL1, PL0, PD4, PD5, PD6, PJ4 */
|
|
|
|
/* For each Dn we need to map which port and bit will hold bit0..bit7 of the
|
|
output byte. Here we assume each DMX channel is presented on a contiguous
|
|
8-bit port where possible. Since the pins are all over, we output each DMX
|
|
byte bit-by-bit to 8 dedicated pins: bit 0 -> mapped pin for bit0, ... bit7
|
|
-> mapped pin for bit7. Replace the per-bit port/bit assignments below to
|
|
match your desired wiring. */
|
|
|
|
/* Example per-bit mapping for channel outputs (one mapping choice). */
|
|
/* For brevity we map bits 0..7 of each channel to the same physical pin for
|
|
that channel, i.e., output the full byte on 8-bit bus is not possible on
|
|
single scattered pin. Instead we simply write the byte value to the port pins
|
|
that form an 8-bit port where possible. We'll implement writing each
|
|
channel's byte to its single port's low 8 bits when that port contains 8
|
|
consecutive pins; otherwise we write the byte on the low 8 bits of a chosen
|
|
port using the relevant mask. */
|
|
|
|
/* Define helper macros for writing masked values */
|
|
static inline void write_masked(volatile uint8_t *port, volatile uint8_t *ddr,
|
|
uint8_t mask, uint8_t value) {
|
|
uint8_t cur = *port & ~mask;
|
|
*port = cur | (value & mask);
|
|
*ddr |= mask; // ensure pins are outputs
|
|
}
|
|
|
|
/* Concrete writers for the pins used (mask and port pointers) */
|
|
/* Adjust masks to the actual bit positions used on each port. The following
|
|
masks assume: PB4..PB7 -> bits 4..7 on PORTB (fits for D8..D11) PL0..PL7 ->
|
|
bits 0..7 on PORTL (fits for D12..D19) PH0..PH7 -> bits 0..7 on PORTH (we use
|
|
PH3..PH6 for D4..D7 -> need masking) PD4..PD6 -> bits 4..6 on PORTD
|
|
(D20..D22) PE0..PE7 -> bits 0..7 on PORTE (we use PE3,PE4,PE5 for D0,D1,D3)
|
|
PJ4 -> bit 4 on PORTJ (D23)
|
|
PG5 -> bit 5 on PORTG (D2)
|
|
*/
|
|
/* Write channel values to ports with appropriate masks */
|
|
void output_dmx_channels_1_24(void) {
|
|
/* D0 -> PE4 : map whole byte to bits 0..7 not possible; instead output
|
|
LSB..MSB across 8 pins For simplicity we output the byte value on an 8-bit
|
|
pseudo-bus using multiple ports: Here we implement a pragmatic approach:
|
|
output each channel value on 8 dedicated IO pins defined below. You must
|
|
adapt bit-to-pin assignments to match your wiring. */
|
|
|
|
/* Example assignment: use PORTL for D12..D19 (8-bit) */
|
|
/* D12..D19 handled below; for single-pin channels we output LSB on that pin
|
|
(as HIGH/LOW) — if you actually need parallel 8-bit outputs on dedicated
|
|
pins per channel, you'll need 8 pins per channel (192 pins) which is
|
|
unlikely. So this snippet writes each channel's byte value as a PWM-like
|
|
ON/OFF level on a single digital pin using thresholding:
|
|
-> if value >= 128 -> set pin HIGH else LOW. */
|
|
|
|
/* Quick implementation: set output pin HIGH if channel value >= 128, else
|
|
LOW. Map each D0..D23 to its port/bit and write accordingly. */
|
|
|
|
uint8_t v;
|
|
/* D0: PE4 (bit 4) */
|
|
v = dmx_data[1];
|
|
if (v >= 128)
|
|
PORTE |= (1 << 4);
|
|
else
|
|
PORTE &= ~(1 << 4);
|
|
DDRE |= (1 << 4);
|
|
|
|
/* D1: PE5 (bit 5) */
|
|
v = dmx_data[2];
|
|
if (v >= 128)
|
|
PORTE |= (1 << 5);
|
|
else
|
|
PORTE &= ~(1 << 5);
|
|
DDRE |= (1 << 5);
|
|
|
|
/* D2: PG5 (bit 5) */
|
|
v = dmx_data[3];
|
|
if (v >= 128)
|
|
PORTG |= (1 << 5);
|
|
else
|
|
PORTG &= ~(1 << 5);
|
|
DDRG |= (1 << 5);
|
|
|
|
/* D3: PE3 (bit 3) */
|
|
v = dmx_data[4];
|
|
if (v >= 128)
|
|
PORTE |= (1 << 3);
|
|
else
|
|
PORTE &= ~(1 << 3);
|
|
DDRE |= (1 << 3);
|
|
|
|
/* D4: PH3 (bit 3) */
|
|
v = dmx_data[5];
|
|
if (v >= 128)
|
|
PORTH |= (1 << 3);
|
|
else
|
|
PORTH &= ~(1 << 3);
|
|
DDRH |= (1 << 3);
|
|
|
|
/* D5: PH4 (bit 4) */
|
|
v = dmx_data[6];
|
|
if (v >= 128)
|
|
PORTH |= (1 << 4);
|
|
else
|
|
PORTH &= ~(1 << 4);
|
|
DDRH |= (1 << 4);
|
|
|
|
/* D6: PH5 (bit 5) */
|
|
v = dmx_data[7];
|
|
if (v >= 128)
|
|
PORTH |= (1 << 5);
|
|
else
|
|
PORTH &= ~(1 << 5);
|
|
DDRH |= (1 << 5);
|
|
|
|
/* D7: PH6 (bit 6) */
|
|
v = dmx_data[8];
|
|
if (v >= 128)
|
|
PORTH |= (1 << 6);
|
|
else
|
|
PORTH &= ~(1 << 6);
|
|
DDRH |= (1 << 6);
|
|
|
|
/* D8: PB4 (bit 4) */
|
|
v = dmx_data[9];
|
|
if (v >= 128)
|
|
PORTB |= (1 << 4);
|
|
else
|
|
PORTB &= ~(1 << 4);
|
|
DDRB |= (1 << 4);
|
|
|
|
/* D9: PB5 (bit 5) */
|
|
v = dmx_data[10];
|
|
if (v >= 128)
|
|
PORTB |= (1 << 5);
|
|
else
|
|
PORTB &= ~(1 << 5);
|
|
DDRB |= (1 << 5);
|
|
|
|
/* D10: PB6 (bit 6) */
|
|
v = dmx_data[11];
|
|
if (v >= 128)
|
|
PORTB |= (1 << 6);
|
|
else
|
|
PORTB &= ~(1 << 6);
|
|
DDRB |= (1 << 6);
|
|
|
|
/* D11: PB7 (bit 7) */
|
|
v = dmx_data[12];
|
|
if (v >= 128)
|
|
PORTB |= (1 << 7);
|
|
else
|
|
PORTB &= ~(1 << 7);
|
|
DDRB |= (1 << 7);
|
|
|
|
/* D12: PL7 (bit 7) */
|
|
v = dmx_data[13];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 7);
|
|
else
|
|
PORTL &= ~(1 << 7);
|
|
DDRL |= (1 << 7);
|
|
|
|
/* D13: PL6 (bit 6) */
|
|
v = dmx_data[14];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 6);
|
|
else
|
|
PORTL &= ~(1 << 6);
|
|
DDRL |= (1 << 6);
|
|
|
|
/* D14: PL5 (bit 5) */
|
|
v = dmx_data[15];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 5);
|
|
else
|
|
PORTL &= ~(1 << 5);
|
|
DDRL |= (1 << 5);
|
|
|
|
/* D15: PL4 (bit 4) */
|
|
v = dmx_data[16];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 4);
|
|
else
|
|
PORTL &= ~(1 << 4);
|
|
DDRL |= (1 << 4);
|
|
|
|
/* D16: PL3 (bit 3) */
|
|
v = dmx_data[17];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 3);
|
|
else
|
|
PORTL &= ~(1 << 3);
|
|
DDRL |= (1 << 3);
|
|
|
|
/* D17: PL2 (bit 2) */
|
|
v = dmx_data[18];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 2);
|
|
else
|
|
PORTL &= ~(1 << 2);
|
|
DDRL |= (1 << 2);
|
|
|
|
/* D18: PL1 (bit 1) */
|
|
v = dmx_data[19];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 1);
|
|
else
|
|
PORTL &= ~(1 << 1);
|
|
DDRL |= (1 << 1);
|
|
|
|
/* D19: PL0 (bit 0) */
|
|
v = dmx_data[20];
|
|
if (v >= 128)
|
|
PORTL |= (1 << 0);
|
|
else
|
|
PORTL &= ~(1 << 0);
|
|
DDRL |= (1 << 0);
|
|
|
|
/* D20: PD4 (bit 4) */
|
|
v = dmx_data[21];
|
|
if (v >= 128)
|
|
PORTD |= (1 << 4);
|
|
else
|
|
PORTD &= ~(1 << 4);
|
|
DDRD |= (1 << 4);
|
|
|
|
/* D21: PD5 (bit 5) */
|
|
v = dmx_data[22];
|
|
if (v >= 128)
|
|
PORTD |= (1 << 5);
|
|
else
|
|
PORTD &= ~(1 << 5);
|
|
DDRD |= (1 << 5);
|
|
|
|
/* D22: PD6 (bit 6) */
|
|
v = dmx_data[23];
|
|
if (v >= 128)
|
|
PORTD |= (1 << 6);
|
|
else
|
|
PORTD &= ~(1 << 6);
|
|
DDRD |= (1 << 6);
|
|
|
|
/* D23: PJ4 (bit 4) */
|
|
v = dmx_data[24];
|
|
if (v >= 128)
|
|
PORTJ |= (1 << 4);
|
|
else
|
|
PORTJ &= ~(1 << 4);
|
|
DDRJ |= (1 << 4);
|
|
}
|