/**************************************************************
Function     - uart_getchar
               Is a dummy routing required to be present

               ISR(USART_RXC_VECT)
               is the USART receive complete interrupt vector

               A better name for this function would be
               uart_getrecord since it actually returns a 
               satellite position record in rx_buffer[]

**************************************************************/
#include <stdio.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

#define LOCAL
#include "uart_getchar.h"

#define TRUE 1
/********************************************
This is just a place-holder 
*******************************************/
int uart_getchar(char c, FILE *stream) {
    return 0;
}


//SIGNAL (SIG_UART_RECV) {
ISR (USART_RXC_vect) {

        int i;
    // get_record would be a better name for this function
        unsigned char temp;
        temp = UDR;
        switch(rx_state) {
          case RXBA: // Data Bufer Available
            {
            int i;
            rx_ptr = rx_buffer;
            // clean out the buffer
            for (i=0; i< sizeof(rx_buffer); ++i) rx_buffer[i]=0;
                // Are we at the beginning of a data record?
                if(temp != '\r' && temp !='\n'){
                    // yes so save first valid character
                    *rx_ptr++ = temp;
                    rx_state = RRIP;
                }
            }
            break;
        case RRIP: // Record Receive In Progress
            if(rx_ptr < &rx_buffer[RX_BUFFER_SZ]){
                // bufer is not full
                if(temp == '\r' || temp =='\n'){
                    if(rx_ptr > rx_buffer){
                        new_auto_bearing = TRUE;
                        rx_state = WFRXBA;
                    }
                    // else EOL symbol - just ignore it
                }
                else {
                    // save in buffer
                    *rx_ptr++ = temp;
                }
            }
            else{
                // buffer overrun
                rx_ptr = rx_buffer;
                rx_state = WFNL;
            }
            break;
        case WFRXBA: // Wait For rx_buffer to be Available
            if(!new_auto_bearing){
                // mainline has processes data
                rx_ptr = rx_buffer;
                // clean out the buffer 
                for (i=0; i< sizeof(rx_buffer); ++i) rx_buffer[i]=0;
                // Ignore any EOL characters
                if(temp != '\r' && temp !='\n'){
                   *rx_ptr++ = temp;
                   rx_state = RRIP;
                }
            }
            else{
                // mainline has not procesed record but new character has arived
                if(temp != '\r' && temp !='\n'){
                   /*
                   Missed the first character of the next record
                   So consume the rest of the line & wait For Next Record
                   */
                   rx_state = WFNL;
                }
            }
            break;
        case WFNL: //  Wait For Next Line
            if(temp == '\r' || temp =='\n'){
                rx_state = RXBA;
            }

            break;
        }
}
