/**************************************************************************
Name            - uart_putchar
Parameters      - character - data to be putin the uart queue
Responsibility  - Write a character to the UATR output queue.
                
Notes           - If a queue full condition is detected it will wait
                  for the uart buffer empty flag to be set and then
                  re-enable interrupts. This is done to resolve a race
                  condition between the interupt routine and uart_putchar
                  regarding the interrupt enable.

                  I decided to make the uart queue self blocking since routines
                  that depend on stdout stream (like printf) cannot deal
                  with this situation very well.
                  This should provide maximum throughput since this routine
                  will only block while the uart queue is full. The uart
                  buffer empty interrupt
                  routine should quickly make space for the next character in
                  the uart queue and release the blocked condition.

                  There IS NO flow control mechanism implemented in this
                  version.  This may result in garbled output if the
                  receiving device is overloaded.

                  Note that this is NOT a recursive safe function and will 
                  cause trouble if you execute it in both mainline and interrupt
                  code sections. That means it is not recommended to use printf
                  in interrupt code sections since it depands on stdout which
                  depends on uart_putchar().
                  -----------
                  Why have this routine?
                  Because I use a splitter cable on the rotor unit and send the
                  output to a terminal or terminal emulator program for DEBUGGING.
                  Be cautious since this operation will block and all will stop
                  if DEBUG is on and the terminal is not there.
                  ------------

                 
Returns           0 --- to make the stdout stream  happy
Autor             wje
                  Based on Atmel application note - AVR313
**************************************************************************/
#include <stdio.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

#define LOCAL
#include "uart_putchar.h"

int uart_putchar(char c, FILE *stream) {
    if ((((head_cnt+1)& QUEUE_MASK) != tail_cnt)) {
        // queue is NOT full - drop the data if it is!
        UART_buffer[head_cnt] = c;
        ++head_cnt;
        head_cnt &= QUEUE_MASK;      
    }
    UCSRB |= _BV(UDRIE);  // enable the  UART data buffer empty interrupt
    return 0;
}


//SIGNAL (SIG_UART_DATA) {
ISR (USART_TXC_vect) {
    if(head_cnt != tail_cnt) {
        // queue NOT empty
        UDR = UART_buffer[tail_cnt];                      // Send next byte
        ++tail_cnt;
        tail_cnt &= QUEUE_MASK;
    }
    else {
         //queue IS EMPTY - turn off the buffer empty interrupt
         UCSRB &= 0xDF;
   }
}
