
/* MalZeit 06/2014 */


#include <dmx_uart.h>

#include <stddef.h>

#include <avr/io.h>
#include <avr/interrupt.h>

#define DMX_UART_STOPPE_DRIE ( UCSR0B &= ~_BV(UDRIE0))
#define DMX_UART_STARTE_DRIE ( UCSR0B |= _BV(UDRIE0))

#define DMX_UART_STARTE_TXC ( UCSR0B |= _BV(TXCIE0))
#define DMX_UART_STOPPE_TXC ( UCSR0B &= ~_BV(TXCIE0))

// 250 kBaud @ 8MHz
// UBBR = F_CPU/(16*Baud) - 1 = 1
#define DMX_UART_UBBR 1
// Dauer >88 µs => >11 µs pro bit => >100 kBaud
#define DMX_UART_UBBR_BREAK 5


static void (*gpDmxUartrCallback) (void) = NULL;


void DmxUartInit(void);
void DmxUartStart(void);

void DmxUartRegistriereCb(void (*callback) (void));

void DmxUartClearTxPort(void);
void DmxUartSetTxPort(void);
void DmxUartEnableDataTx(void);
void DmxUartTxBreak(void);

void DmxUartWarteAufTxc(void);

/**
 * 
 * 
 * 
 */

void DmxUartInit(void)
{
  UBRR0 = DMX_UART_UBBR;
  
  UCSR0B |= _BV(TXEN0);
  
  UCSR0C |= _BV(USBS0); // 2 Stop-Bits
}

/**
 * 
 * 
 * 
 */


void DmxUartStart(void)
{
  //  UCSR0B |= _BV(UDRIE0); // Interrupt enable // Dauerfeuer
//  UCSR0B |= _BV(TXCIE0); // Interrupt enable
   
}

/**
 * 
 * 
 * 
 */
void DmxUartRegistriereCb(void (*callback) (void))
{
  gpDmxUartrCallback = callback;
}

/**
 * 
 * 
 * 
 */

void DmxUartTxData(uint8_t data)
{
  UDR0 = data;
  DMX_UART_STARTE_DRIE;
}

/**
 * 
 * 
 * 
 */

void DmxUartTxBreak(void)
{
  UCSR0A |= _BV(TXC0); // vorher löschen
  UBRR0 = DMX_UART_UBBR_BREAK;
  UDR0 = 0;
  DMX_UART_STARTE_TXC;
}

/**
 * 
 * 
 * 
 */
ISR(USART_TX_vect)
{
  DMX_UART_STOPPE_TXC;
  UBRR0 = DMX_UART_UBBR;
  if(gpDmxUartrCallback != NULL) {
    gpDmxUartrCallback();
  }
  
}

/**
 * 
 * 
 * 
 */

ISR(USART_UDRE_vect)
{
  DMX_UART_STOPPE_DRIE;
  
  if(gpDmxUartrCallback != NULL) {
    gpDmxUartrCallback();
  }
}

/**
 * 
 * 
 * 
 */

void DmxUartWarteAufTxc(void)
{
  /* TODO
  UCSR0A |= _BV(TXC0); // vorher löschen
  if((UCSR0A & _BV(UDRE0)) == 0) {
    while ( (UCSR0A & _BV(TXC0)) == 0) { // TX läuft noch, 
      ;
    }
  }*/
  while ( (UCSR0A & _BV(UDRE0)) == 0) { // TX läuft noch, 
    ;
  }
}

// EOF
