/* * A DMX receiver that filters out one channel and * sends it out via soft uart * used to display HD images on a Raspberry PI * * ATmega48A @ 8 MHz * */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include "main.h" volatile uint16_t soft_tx; // data for soft UART volatile uint8_t soft_tx_active; // just for info, maybe needed later? // main int main(void) { // IO init DDRB = (1<<PB1) | (1<<PB0); // PB1: soft UART tx, PB0: TEST PORTB = 0xFF; // internal pull ups DDRC = 0x0; // internal pull ups PORTC = 0xFF; DDRD = 0; // internal pull ups PORTD = 0xFF; // UART init UBRR0H = UBRR_VAL >> 8; UBRR0L = UBRR_VAL & 0xFF; // timer 1 init // OCRA1 for soft UART tx // mode 0, prescaler 1 TCCR1A = 0; TCCR1B = (1<<CS10); // activate UART for DMX reception UCSR0B = (1<<RXCIE0) | (1<<RXEN0); sei(); // endless main loop while (1) { set_sleep_mode(SLEEP_MODE_IDLE); sleep_mode(); } } // UART RX complete interrupt ISR(USART_RX_vect) { uint8_t status, data; static int16_t i, dmx_adr; // read UART data, also clears interrupt flag status = UCSR0A; data = UDR0; if (status & (1<<FE0)) { // frame error if (data==0) { // break -> DMX Reset //TEST_HIGH; i = -1; READ_DMX_ADR; //SEND_SOFT_UART(dmx_adr); } } else { // normal reception //TEST_LOW; i++; if (i == dmx_adr && !soft_tx_active) { // send data via soft UART SEND_SOFT_UART(data); TEST_HIGH; } else TEST_LOW; } } // Timer 1 Output COMPARE A Interrupt // driver for hybrid UART TX ISR(TIMER1_COMPA_vect) { uint16_t tmp = soft_tx; if (tmp == 0) { TIMSK1 &= ~(1<<OCIE1A); // disable ISR, we are done soft_tx_active = 0; } else { // next bit OCR1A += BIT_TIME; if (tmp & 1) { // UART sends LSB first TCCR1A = (1<<COM1A1) | (1<<COM1A0); // set output } else { TCCR1A = (1<<COM1A1); // clear output } soft_tx = tmp >> 1; } }