Files
leuchtstoff/main.c
2026-05-23 00:16:44 +02:00

123 lines
2.7 KiB
C

#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#define F_CPU 16000000UL
#define DMX_CHANNELS 512
volatile uint8_t dmx_data[DMX_CHANNELS + 1]; // 1..512
volatile uint16_t dmx_index = 0;
volatile bool dmx_frame_ready = false;
volatile bool receiving = false;
extern void output_dmx_channels_1_24(void);
/* --- USART3 (DMX) init & ISR --- */
void uart3_init(void) {
// uint16_t ubrr = (F_CPU / (16UL * 250000UL)) - 1; // 250000 baud
// UBRR3H = (uint8_t)(ubrr >> 8);
// UBRR3L = (uint8_t)ubrr;
UBRR3L = 3;
UCSR3B = (1 << RXEN3) | (1 << RXCIE3);
UCSR3C = (1 << USBS3) | (1 << UCSZ31) | (1 << UCSZ30); // 8N2
}
ISR(USART3_RX_vect) {
uint8_t status = UCSR3A;
uint8_t data = UDR3;
if (status & (1 << FE3)) {
// Break detected: start new DMX packet
receiving = true;
dmx_index = 0;
dmx_frame_ready = false;
return;
}
if (!receiving)
return;
if (dmx_index == 0) {
// start code (usually 0) - ignore/store as needed
dmx_index++; // next byte will be channel 1
return;
}
if (dmx_index <= DMX_CHANNELS) {
dmx_data[dmx_index] = data;
dmx_index++;
if (dmx_index > DMX_CHANNELS) {
dmx_frame_ready = true;
receiving = false;
}
} else {
dmx_frame_ready = true;
receiving = false;
}
}
/* --- USART0 (printf/debug) init & putchar --- */
void uart0_init(uint32_t baud) {
// uint16_t ubrr = (uint16_t)((F_CPU / (16UL * baud)) - 1UL);
// UBRR0H = (uint8_t)(ubrr >> 8);
// UBRR0L = (uint8_t)ubrr;
UBRR0L = 8;
UCSR0B = (1 << TXEN0); // enable transmitter
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 data, 1 stop, no parity
}
int uart0_putchar(char c, FILE *stream) {
if (c == '\n')
uart0_putchar('\r', stream); // CRLF
while (!(UCSR0A & (1 << UDRE0)))
; // wait until buffer empty
UDR0 = (uint8_t)c;
return 0;
}
/* Create a FILE stream for stdout */
static FILE uart0_stdout =
FDEV_SETUP_STREAM(uart0_putchar, NULL, _FDEV_SETUP_WRITE);
int main(void) {
cli();
DDRJ |= 1 << 5; // enable rs485 receiver
uart3_init();
uart0_init(115200); // debug baud
// Hook stdout to UART0
stdout = &uart0_stdout;
// init DMX buffer
for (uint16_t i = 1; i <= DMX_CHANNELS; ++i)
dmx_data[i] = 0;
sei();
// Example usage
printf("DMX receiver started\r\n");
while (1) {
if (dmx_frame_ready) {
// Example debug: print first 8 channels
printf("DMX frame received. Ch1..8: ");
for (uint8_t i = 1; i <= 8; ++i) {
printf("%u ", dmx_data[i]);
}
printf("\r\n");
dmx_frame_ready = false;
}
output_dmx_channels_1_24();
// other app code...
}
return 0;
}