/* $Id: hif_uart.h,v 1.12 2010/07/25 13:08:36 dath Exp $ */
/**
 * @file
 * Internal UART abstraction
 *
 */

#if ! defined(HIF_UART_H) && (HIF_TYPE_IS_UART == 1)
#define HIF_UART_H

/* === types ============================================= */
typedef struct
{
    uint8_t * rxbuf;
    uint16_t rxsize;
    uint8_t * txbuf;
    uint16_t txsize;
} hif_uart_mgm_t;

/* === macros ============================================ */
#define ENCODE_BAUDRATE(br) ((F_CPU)/((br)*16l)-1)

/* === UART definitions for ATmega1281/ATmega128RFA1 === */
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega128RFA1__) \
    || defined(__AVR_ATmega1284P__)
# if HIF_TYPE == HIF_UART_0
#  define HIF_UART_STATUS   UCSR0A
#  define HIF_UART_CONTROL  UCSR0B
#  define HIF_UART_DATA     UDR0
#  define HIF_UART_UDRIE    UDRIE0
#  define HIF_UART_RX_vect  USART0_RX_vect
#  define HIF_UART_TX_vect  USART0_UDRE_vect
#  define HIF_UART_RX_ERROR(status) (status & (_BV(FE)|_BV(DOR)))
#  define HIF_UART_TXIRQ_EI() (HIF_UART_CONTROL |= _BV(UDRIE0))
#  define HIF_UART_TXIRQ_DI() (HIF_UART_CONTROL &= ~_BV(UDRIE0))
   inline void HIF_UART_INIT(uint32_t baudrate)
   {
   uint16_t br;
       /* init uart 0 mega 1281*/
       br = ENCODE_BAUDRATE(baudrate);
       /* Set baud rate */
       if ( br & 0x8000 )
       {
   		   HIF_UART_STATUS = _BV(U2X0);  //Enable 2x speed
   		   br &= ~0x8000;
   	   }
       UBRR0H = (uint8_t)(br>>8);
       UBRR0L = (uint8_t) br;
       
       //UBRR0H = 0x00;
       //UBRR0L = 0x01;
  
  
       /* Enable USART receiver and transmitter and receive complete interrupt */
       HIF_UART_CONTROL = (_BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0));

       /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
       #ifdef URSEL0
       UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
       #else
       UCSR0C = (3<<UCSZ00);
       #endif

   }
# elif HIF_TYPE == HIF_UART_1
#  define HIF_UART_STATUS   UCSR1A
#  define HIF_UART_CONTROL  UCSR1B
#  define HIF_UART_DATA     UDR1
#  define HIF_UART_UDRIE    UDRIE1
#  define HIF_UART_RX_vect  USART1_RX_vect
#  define HIF_UART_TX_vect  USART1_UDRE_vect
#  define HIF_UART_RX_ERROR(status) (status & (_BV(FE)|_BV(DOR)))
#  define HIF_UART_TXIRQ_EI() (HIF_UART_CONTROL |= _BV(UDRIE1))
#  define HIF_UART_TXIRQ_DI() (HIF_UART_CONTROL &= ~_BV(UDRIE1))
   inline void HIF_UART_INIT(uint32_t baudrate)
   {
   /* init uart 1 mega 1281*/
   uint16_t br;
      br = ENCODE_BAUDRATE(baudrate);
      /* Set baud rate */
      if ( br & 0x8000 )
      {
   	      HIF_UART_STATUS = _BV(U2X0);  //Enable 2x speed
   	      br &= ~0x8000;
      }
      UBRR1H = (uint8_t)(br>>8);
      UBRR1L = (uint8_t) br;
      
      //UBRR1H = 0x00;
      //UBRR1L = 0x01;

      /* Enable USART receiver and transmitter and receive complete interrupt */
      HIF_UART_CONTROL = (_BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1));

      /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
      #ifdef URSEL0
      UCSR1C = (1<<URSEL0)|(3<<UCSZ00);
      #else
      //UCSR1C = (3<<UCSZ00);
      
      //muj code
      UCSR1C = ((1<<UCSZ11)|(1<<UCSZ10));
      #endif
   }
# else
#  error "Unknown UART for __AVR_ATmega1281__ or __AVR_ATmega128RFA1__"
# endif /*HIF_UART_x*/

/* === UART definitions for ATmega644P === */
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__)
# if HIF_TYPE == HIF_UART_0
#  define HIF_UART_STATUS   UCSR0A
#  define HIF_UART_CONTROL  UCSR0B
#  define HIF_UART_DATA     UDR0
#  define HIF_UART_UDRIE    UDRIE0
#  define HIF_UART_RX_vect  USART0_RX_vect
#  define HIF_UART_TX_vect  USART0_UDRE_vect
#  define HIF_UART_RX_ERROR(status) (status & (_BV(FE)|_BV(DOR)))
#  define HIF_UART_TXIRQ_EI() (HIF_UART_CONTROL |= _BV(UDRIE0))
#  define HIF_UART_TXIRQ_DI() (HIF_UART_CONTROL &= ~_BV(UDRIE0))
   inline void HIF_UART_INIT(uint16_t baudrate)
   {
   uint16_t br;
       /* init uart 0 mega 644p*/
       br = ENCODE_BAUDRATE(baudrate);
       /* Set baud rate */
       if ( br & 0x8000 )
       {
   		   HIF_UART_STATUS = _BV(U2X0);  //Enable 2x speed
   		   br &= ~0x8000;
   	   }
       UBRR0H = (uint8_t)(br>>8);
       UBRR0L = (uint8_t) br;

       /* Enable USART receiver and transmitter and receive complete interrupt */
       HIF_UART_CONTROL = (_BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0));

       /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
       #ifdef URSEL0
       UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
       #else
       UCSR0C = (3<<UCSZ00);
       #endif

   }
# elif HIF_TYPE == HIF_UART_1
#  define HIF_UART_STATUS   UCSR1A
#  define HIF_UART_CONTROL  UCSR1B
#  define HIF_UART_DATA     UDR1
#  define HIF_UART_UDRIE    UDRIE1
#  define HIF_UART_RX_vect  USART1_RX_vect
#  define HIF_UART_TX_vect  USART1_UDRE_vect
#  define HIF_UART_RX_ERROR(status) (status & (_BV(FE)|_BV(DOR)))
#  define HIF_UART_TXIRQ_EI() (HIF_UART_CONTROL |= _BV(UDRIE1))
#  define HIF_UART_TXIRQ_DI() (HIF_UART_CONTROL &= ~_BV(UDRIE1))
   inline void HIF_UART_INIT(uint16_t baudrate)
   {
   /* init uart 1 mega 644p*/
   uint16_t br;
      br = ENCODE_BAUDRATE(baudrate);
      /* Set baud rate */
      if ( br & 0x8000 )
      {
   	      HIF_UART_STATUS = _BV(U2X0);  //Enable 2x speed
   	      br &= ~0x8000;
      }
      UBRR1H = (uint8_t)(br>>8);
      UBRR1L = (uint8_t) br;

      /* Enable USART receiver and transmitter and receive complete interrupt */
      HIF_UART_CONTROL = (_BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1));

      /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
      #ifdef URSEL0
      UCSR1C = (1<<URSEL0)|(3<<UCSZ00);
      #else
      UCSR1C = (3<<UCSZ00);
      #endif
   }
# else
#  error "Unknown UART for __AVR_ATmega644__ or __AVR_ATmega644P__"
# endif /*HIF_UART_x*/

/* === UART definitions for ATmega16 === */
#elif defined(__AVR_ATmega16__)
# if HIF_TYPE == HIF_UART_0
#  define HIF_UART_DATA     UDR
#  define HIF_UART_STATUS   UCSRA
#  define HIF_UART_CONTROL  UCSRB
#  define HIF_UART_UDRIE    UDRIE
#  define HIF_UART_RX_vect  USART_RXC_vect
#  define HIF_UART_TX_vect  USART_UDRE_vect
#  define HIF_UART_RX_ERROR(status) (status & (_BV(FE)|_BV(DOR)))
#  define HIF_UART_TXIRQ_EI() (HIF_UART_CONTROL |= _BV(UDRIE))
#  define HIF_UART_TXIRQ_DI() (HIF_UART_CONTROL &= ~_BV(UDRIE))
   inline void HIF_UART_INIT(uint16_t baudrate)
   {
   /* init uart 1 mega 1281*/
   uint16_t br;
      br = ENCODE_BAUDRATE(baudrate);
      /* Set baud rate */
      if ( br & 0x8000 )
      {
   	      HIF_UART_STATUS = _BV(U2X);  //Enable 2x speed
   	      br &= ~0x8000;
      }
      UBRRH = (uint8_t)(br>>8);
      UBRRL = (uint8_t) br;
      /* Enable USART receiver and transmitter and receive complete interrupt */
      HIF_UART_CONTROL = (_BV(RXCIE)|(1<<RXEN)|(1<<TXEN));

      /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
      UCSRC = (1<<URSEL)|(3<<UCSZ0);
   }
# else
#  error "Unknown UART for __AVR_ATmega16__"
# endif
#elif defined(__AVR_ATmega8__)
# if HIF_TYPE == HIF_UART_0
#  define HIF_UART_DATA     UDR
#  define HIF_UART_STATUS   UCSRA
#  define HIF_UART_CONTROL  UCSRB
#  define HIF_UART_UDRIE    UDRIE
#  define HIF_UART_RX_vect  USART_RXC_vect
#  define HIF_UART_TX_vect  USART_UDRE_vect
#  define HIF_UART_RX_ERROR(status) (status & (_BV(FE)|_BV(DOR)))
#  define HIF_UART_TXIRQ_EI() (HIF_UART_CONTROL |= _BV(UDRIE))
#  define HIF_UART_TXIRQ_DI() (HIF_UART_CONTROL &= ~_BV(UDRIE))
   inline void HIF_UART_INIT(uint16_t baudrate)
   {
   /* init uart 1 mega 1281*/
   uint16_t br;
      br = ENCODE_BAUDRATE(baudrate);
      /* Set baud rate */
      if ( br & 0x8000 )
      {
   	      HIF_UART_STATUS = _BV(U2X);  //Enable 2x speed
   	      br &= ~0x8000;
      }
      UBRRH = (uint8_t)(br>>8);
      UBRRL = (uint8_t) br;
      /* Enable USART receiver and transmitter and receive complete interrupt */
      HIF_UART_CONTROL = (_BV(RXCIE)|(1<<RXEN)|(1<<TXEN));

      /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
      UCSRC = (1<<URSEL)|(3<<UCSZ0);
   }
# else
#  error "Unknown UART for __AVR_ATmega8__"
# endif
#elif defined(__AVR_ATmega88__)
# if HIF_TYPE == HIF_UART_0
#  define HIF_UART_DATA     UDR0
#  define HIF_UART_STATUS   UCSR0A
#  define HIF_UART_CONTROL  UCSR0B
#  define HIF_UART_UDRIE    UDRIE0
#  define HIF_UART_RX_vect  USART_RX_vect
#  define HIF_UART_TX_vect  USART_UDRE_vect
#  define HIF_UART_RX_ERROR(status) (status & (_BV(FE0)|_BV(DOR0)))
#  define HIF_UART_TXIRQ_EI() (HIF_UART_CONTROL |= _BV(UDRIE0))
#  define HIF_UART_TXIRQ_DI() (HIF_UART_CONTROL &= ~_BV(UDRIE0))
   inline void HIF_UART_INIT(uint16_t baudrate)
   {
   /* init uart 1 mega 1281*/
   uint16_t br;
      br = ENCODE_BAUDRATE(baudrate);
      /* Set baud rate */
      if ( br & 0x8000 )
      {
   	      HIF_UART_STATUS = _BV(U2X0);  //Enable 2x speed
   	      br &= ~0x8000;
      }
      UBRR0H = (uint8_t)(br>>8);
      UBRR0L = (uint8_t) br;
      /* Enable USART receiver and transmitter and receive complete interrupt */
      HIF_UART_CONTROL = (_BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0));

      /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
      #ifdef URSEL0
      UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
      #else
      UCSR0C = (3<<UCSZ00);
      #endif
   }
# else
#  error "Unknown UART for __AVR_ATmega88__"
# endif

#else
# error "An UART is not supported for the current MCU type."
#endif /* defined(__ARV_xxxxx__) */

#endif /* ! defined(HIF_UART_H) && HIF_TYPE_IS_UART */
