/*
 * uart.c
 *
 * Created: 29.11.2011 19:24:29
 *  Author: Zbynek
 * poskocil@email.cz
 * Funkce pro praci s USARTem - inicializace, prijem a odeslani znaku
 */ 

#include <avr/io.h>
#include <stdlib.h>
#include "uart.h"
#include "LED.h"
#include "Globals.h"
#include <avr/interrupt.h> 
#include <string.h>
#include <util/delay.h>




/************************************************************************
* Funkce: SIGNAL
* Ucel:  Funkce se vola pri prijmuti znaku od USART0
* Vstup: Zdroj preruseni
* Vystup:  Zadny                                                                      
************************************************************************/
SIGNAL (USART_RX_vect)
{
        char znak = UDR0;
   if (RX0_buffer.zaplneno_bytu < VELIKOST_PRIJIMACIHO_BUFFERU-1)
   {
           RX0_buffer.obsah[RX0_buffer.zaplneno_bytu] = znak;
           RX0_buffer.obsah[RX0_buffer.zaplneno_bytu+1] = 0; // konec stringu
           RX0_buffer.zaplneno_bytu++;
   } 
   else
   {
           USART0_smaz_buffer();
           RX0_buffer.obsah[RX0_buffer.zaplneno_bytu] = znak;
           RX0_buffer.zaplneno_bytu++;   
        }
        
        if (zacatek_zpravy != 1 && strstr(RX0_buffer.obsah,"$GPGGA") != 0)
        {
                zacatek_zpravy = 1;
                USART0_smaz_buffer(); // aby se zprava ukladala od zacatku bufferu
        }

        if (znak == '*' && zacatek_zpravy == 1) // cela zprava je prijata
        {               
                //USART0_posli_retezec(RX0_buffer.obsah);
                strcpy(NMEA_retezec.obsah,RX0_buffer.obsah); // NMEA zprava se prekopiruje do NMEA_retezec, aby pri pozadavku na vycteni dat byla data v kuse a nenastal pripad, ze bude NMEA zprava teprve vycitana.
                NMEA_retezec.zaplneno_bytu = RX0_buffer.zaplneno_bytu;
                zacatek_zpravy = 0;
        }               
} 

 


/************************************************************************
* Funkce: dekoduj_zpravu_GPS
* Ucel:  Z RX0_buffer vytahne informace o soucasne poloze, je tam ulozena cela veta RMC
* Vstup: Zadny
* Vystup:  Zadny                                                                      
************************************************************************/
void dekoduj_zpravu_GPS (void)
{
        cli();  
        
        short i, j = 0, k = 0, l = 0;
        short pocet_carek = 0;
        for ( i = 0; i < NMEA_retezec.zaplneno_bytu; i++)
        {
                if (pocet_carek == 1)
                {
                        UTC_time[l] = NMEA_retezec.obsah[i];
                        l++;
                }
                if (pocet_carek == 2 || pocet_carek == 3)
                {
                        Latitude[k] = NMEA_retezec.obsah[i];
                        k++;
                }
                if (pocet_carek == 4 || pocet_carek == 5)
                {

                        Longitude[j] = NMEA_retezec.obsah[i];
                        j++;
                }
                if (pocet_carek == 6)
                {
                        UTC_time[l-1] = 0;
                        Latitude[k-1] = 0;
                        Longitude[j-1] = 0;

                        Status_GPS = NMEA_retezec.obsah[i-1];
                        j = 0;
                }
                
                if (pocet_carek == 9)
                {
                        Altitude[j] = NMEA_retezec.obsah[i];
                        j++;
                }
                
                if (NMEA_retezec.obsah[i] == ',')
                {
                        pocet_carek++;
                }
                if (pocet_carek >9)
                {
                        Altitude[j-1] = 0; // konec Stringu
                        break;  // nema vyznam dal zapisovat, potrebne je zapsano v Altitude
                }
        }
        
        sei();
}

/************************************************************************
* Funkce: USART0_smaz_buffer
* Ucel:  Smaze (zaplni nulami) prijimaci buffer
* Vstup: Jaky buffer ma smazat (pro USART 0 nebo 1)
* Vystup:  Zadny                                                                      
************************************************************************/
void USART0_smaz_buffer (void)
{
        cli();
        unsigned char i;

        for (i=0; i <= VELIKOST_PRIJIMACIHO_BUFFERU;i++) // maze se cely buffer pro jistotu
        {
                RX0_buffer.obsah[i] = 0;
        }
        RX0_buffer.zaplneno_bytu = 0;


        sei();
}

/************************************************************************
* Funkce: USART_Init()
* Ucel:  Inicializuje oba USARTy a nastavi rychslost v baud, je treba definovat pozadovanou rychlost pomoci #define UARTn_BAUD_RATE
*                Zapne preruseni pri prichodu noveho znaku a globalni preruseni
* Vstup: Frekvence procesoru
* Vystup:  Zadny                                                                      
************************************************************************/
void USART_Init(void)
{
        unsigned int baud;
        baud = F_CPU/16/UART0_BAUD_RATE -1;
        /* Set baud rate */
        UBRR0H = (unsigned char)(baud>>8);
        UBRR0L = (unsigned char)baud;
        /* Enable receiver and transmitter, enable interrupt after receiving a new byte */
        UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
        /* Set frame format: 8data, 1stop bit */
        UCSR0C = (3<<UCSZ00);
                        
                USART0_posli_znak('A');
                USART0_posli_znak('K');
                USART0_posli_znak('\n');
                USART0_posli_znak('\r');
                //delay_ms(3000);       // modulu se musi dat cas na vypocet baud rychlosti             
}

/************************************************************************
* Funkce: USART0_posli_znak()
* Ucel:  Posle znak po seriove lince, hned pote, co se uvolni vysilaci buffer
* Vstup: Znak, ktery se ma odeslat
* Vystup: Zadny                                                                      
************************************************************************/
void USART0_posli_znak( unsigned char data )
{
        /* Wait for empty transmit buffer */
        while ( !( UCSR0A & (1<<UDRE0)) )
        ;
        /* Put data into buffer, sends the data */
        UDR0 = data;
}

/************************************************************************
* Funkce: USART0_posli_retezec()
* Ucel:  Odesle postupne znak po znaku zadany retezec pres USART0
* Vstup: Retezec k odeslani
* Vystup:  Zadny                                                                      
************************************************************************/
void USART0_posli_retezec (const unsigned char *retezec )
{
    while (*retezec) 
      USART0_posli_znak(*retezec++);

}

/************************************************************************
* Funkce: USART0_prijmi_znak()
* Ucel:  Prijme znak ze seriove linky, pokud je nejaky neprecteny znak
* Vstup: Zadny
* Vystup:  Prijaty znak                                                                      
************************************************************************/
unsigned char USART0_prijmi_znak( void )
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) )
;
/* Get and return received data from buffer */
return UDR0;
}