/*
 * Mobile_unit.c
 *
 * Created: 17.3.2014 11:29:48
 *  Author: Honzin
 */ 

#define AVR_ATmega16A
#define F_CPU 8000000UL

#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h> 
#include <stdio.h>
#include <util/delay.h>
#include <avr/eeprom.h>
//#include <string.h>			// knihovny pro práci s řetězci znaků

#include "Mobile_unit.h"	

     
#define LED 5
//#define LED_2 5
#define PWR 3
#define kl 1 // jen na test
//#define RE PORTD4  // set bit RX/TX RS485  


//----PORTD---
#define SL 2  // MCP2030
#define CS 7
#define RSII 7 //PORTA7 
#define LFDATA 0 //PORT0 

//-----------------


// Default Setup - 14%, Wakeup Enabled
//#define AFE_LFDATA_DEFAULT          {0x66,0x00,0x00,0x00,0x00,0x20,0xB9};   // Setup AFE for LFDATA
//#define AFE_RSSI_CONFIG_DEFAULT     {0x06,0xC0,0x00,0x00,0x00,0x00,0x39};  // Setup AFE for RSSI
#define AFE_WRITE_COMMAND   7


	
	
//============== I/O  ===============
// Pin Defines
//#define AFE_DATA_LAT        LATB4 //RF-DATA
//#define AFE_DATA_TRIS       TRISB4 // smerovy reg.

//#define AFE_DATA_PORT_READ  RB4  
//#define AFE_DATA_ANSEL      ANSB4

//#define AFE_CLOCK_LAT   LATB0
//#define AFE_CLOCK_TRIS  TRISB0  // smer reg

//#define AFE_CS_LAT     //LATB5
//#define AFE_CS_TRIS     TRISB5 //smer reg 
//----------------




//---------------promene------------
char buffer_0[16]; // na seriak


volatile uint8_t i;

//*************** ID tohoto Tagu ***************
char ID_mobile_tag [10] = {0x25, 0x56, 0x85, '0', '1', '5', '8', '7', '2'};  // |verze|ID| 
//**********************************************


char rx_base_data [6];
char rx_base_data_k [5]  = {'w', 'a', 'k', 'e'};

//***********************konfig. MCP2030***************************

         //============== Functions ===============
void AFE_WriteCommand(uint8_t command) {
    // Select AFE chip for SPI communication
    DDRD  |= (1 << CS); // AFE CS TRIS vystup
	DDRD  |= (1 << SL); //AFE_CLOCK_TRIS = 0; // AVR vystupni log1
    PORTD &= ~ (1 << SL);//AFE_CLOCK_LAT = 0;  
    PORTD &= ~ (1 << CS);// AFE_CS_LAT = 0;  
    DDRD  |= (1 << LFDATA);// AFE_DATA_TRIS = 0
 
    // Send Command Byte
    AFE_WriteByte((uint8_t) ((command & 0x07) << 5));
    //Write dummy byte required by specs
    AFE_WriteByte(0x00);
    // Deselect AFE chip
     
    PORTD &= ~ (1 << SL); //AFE_CLOCK_LAT = 0;
    DDRD  |= (1 << SL); //AFE_CLOCK_TRIS = 0;
	PORTD  |= (1 << CS); //AFE_CS_LAT = 1;
	DDRD  &= ~ (1 << LFDATA);/// AFE_DATA_TRIS = 1;
	DDRD  &= ~ (1 << SL);//AFE_CLOCK_TRIS = 1; // avr vstup naopak
   
}


void AFE_WriteByte(uint8_t byte) {
    
	PORTA |= (1<<LED);
	// Temp varaiables
    uint8_t Position = 0;
    uint8_t ByteValue = byte;
	volatile uint8_t AFE_DATA_LAT = 0;
    // Write byte to AFE
    for (Position = 0; Position < 8; Position++) {
         AFE_DATA_LAT = ((ByteValue >> (uint8_t) (7 - Position)) & 0x01);
        
		if (AFE_DATA_LAT == 1)  // teoreticky by to melo nastavovat bit po bitu podle slova
        {
	   PORTD |= (1 << LFDATA);
        }
		else
		{
	   PORTD &= ~ (1 << LFDATA);
		}			
			
	   _delay_ms(10); //asm("nop");
       PORTD  |= (1 << SL); //AFE_CLOCK_LAT = 1;  
        _delay_ms(10);
       PORTD  &= ~ (1 << SL);  //AFE_CLOCK_LAT = 0;
    }
}


void AFE_WriteRegister(uint8_t address, uint8_t data) {
 /** Setup AFE into LFDATA mode by custom setup
   * @param byte(0-6) - AFE Register 0 - 6 setup */

	// Temp variables
    uint8_t position = 0,
            parity = 0,
            temp = 0,
            afeData1 = 0,
            afeData0 = 0;
    // prepare parity bit
    parity = 1;
    // Calculate the parity bit
    for (position = 0; position < 8; position++) {
        temp = (uint8_t) (data >> position);
        parity ^= temp;
    }
    // prepare data
    afeData1 = (uint8_t) ((AFE_WRITE_COMMAND << 5) | (address << 1) | temp);
    afeData0 = (uint8_t) (data << 1 | (parity & 0x01));
    // Select AFE chip for SPI communication
    DDRD  |= (1 << CS); // vystup
	DDRD  |= (1 << SL); //AFE_CLOCK_TRIS = 0; // AVR vystupni log1
    PORTD &= ~ (1 << SL);//AFE_CLOCK_LAT = 0;  
    PORTD &= ~ (1 << CS);// AFE_CS_LAT = 0;  
    DDRD  |= (1 << LFDATA);// AFE_DATA_TRIS = 0
      
   // AFE_CLOCK_TRIS = 0;
   // AFE_CLOCK_LAT = 0;
   // AFE_CS_LAT = 0;
   // AFE_DATA_TRIS = 0;
    
	// Write Address and Data
    AFE_WriteByte(afeData1);
    AFE_WriteByte(afeData0);
    // Deselect AFE chip
  
    PORTD &= ~ (1 << SL); //AFE_CLOCK_LAT = 0;
    DDRD  |= (1 << SL); //AFE_CLOCK_TRIS = 0;
	PORTD  |= (1 << CS); //AFE_CS_LAT = 1;
	DDRD  &= ~ (1 << LFDATA);/// AFE_DATA_TRIS = 1;
	DDRD  &= ~ (1 << SL);//AFE_CLOCK_TRIS = 1; // avr vstup naopak
	
	//AFE_CLOCK_LAT = 0;
    //AFE_CLOCK_TRIS = 0;
   // AFE_CS_LAT = 1;
   // AFE_DATA_TRIS = 1;
   // AFE_CLOCK_TRIS = 1;
}

//*********************************************



//**********INIT****************

void init()
{
_delay_ms(1000);
PORTA &= ~(1<<LED);	// ladeni



//- pzam. musi se nastavit driv nez USART	
//*************init MCP2030********
//                 reg,  bity,

AFE_WriteRegister(0x00, 0b11110000); //TOEH = 4ms  TOEL = 4ms
	
//AFE_WriteRegister(0x04, 0b111110000);
AFE_WriteRegister(0x05, 0b00010000);	// 8% hloubka modulace
	

//******inicializace USART*********
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 1200
UCSRA=0x00;
//UCSRB=0x18;
UCSRB=0x00;
UCSRB |= (1<<RXEN)|(1<<RXCIE);//|(1<<TXEN);
//--UCSRC=0x86;
UBRRH=0x01;
UBRRL=0xA0;
//**************************** /
    	 
//TCCR0  |= (1<<CS02); //nastavi preddelicku na 256
//TIMSK  |= (1<<TOIE0); // povoli preruseni pri preteceni 

//----init----

//MCUCR |= (1<<ISC00); // any LOG
//GICR  |= (1<<INT0); // enable INT0



DDRA =  0b00100000; //LED PA5 OUT
DDRC =  0b00001000; //PWR - IO  PC3 OUT
DDRD =  0b00000010; //

//sei();
// -- moyna kvuli prog
PORTC |= (1<<PWR); // vypni napajeni mod. IO -  LOG "1"
_delay_ms(1000);
_delay_ms(1000);

// rezim spanku MCU
//MCUCR |= (1<<SE);//|(1<<TXEN);(1<<SM1)|

}



//********* USART - RX *************
unsigned char USART_receive(void){
  	while(1)
	{
	  if(bit_is_set(UCSRA,RXC)) //je li RXC plny zkopiruj data do temp   
	    {
	 // temp = UDR;   //prijmute data v TEMP
	     return(UDR);
	    }
		return(0);
	}
}

void USART_send( unsigned char data){
	 
 while(!(UCSRA & (1<<UDRE)));
	 UDR = data;
}

void USART_putstring(volatile char* StringPtr){
		  
	 while(*StringPtr != 0x00){
	 USART_send(*StringPtr);
	 StringPtr++;}
}
//*************


//*******************TX_SEND************

void TX_send()
{
	//--- zatim posila jen jednoduche znaky
	 PORTC  &= ~(1<<PWR); // napajeni ostatnich IO	 
	 UCSRB |= (1<<TXEN);  // povoli TX UART
	 _delay_ms(500);	// synchr
     sprintf ( buffer_0 , "xxx"); //
     USART_putstring(buffer_0);
	// pro jistotu jeste jednou - test
	_delay_ms(100);	
    sprintf ( buffer_0 , "@", ID_mobile_tag, "%"); // posle platna data  |start| ID | stop | 
    USART_putstring(buffer_0);
	
	UCSRB &= ~ (1<<TXEN);  // TX UART // kvuli radeji kvuli proudum
	PORTC |= (1<<PWR); // vypni log "1"	
}

//****************

//*************************Preruseni*****************

ISR(INT0_vect)
{
GICR  &= ~ (1<<INT0); // disable INT0         

//----------RX  Data--------------

 unsigned char temp = 0;
 uint8_t flag = 0;
  
 for (i = 0 ; i < 200 ; i++ )  //smycka ceka 5 sec na prichozi znak kdyz ne - vdal jed problem
 {
  _delay_ms(10);  //bude cekaat 5 sec na prichozi znak
  temp = USART_receive();
   
  	if (temp == '*')// ceka na synch znak
    {
	  i = 220;
    }
	
 }
  
   for (uint8_t i = 0 ; i<4; i++)
  { 		  
   rx_base_data [i] = USART_receive();  // ulozi do pole prichozi znaky
  }  

//---------porovnani prichozich dat--------
   
   for (uint8_t i = 0 ; i<4; i++)
  { 		  
  
	 if ( rx_base_data [i] == rx_base_data_k [i]) 
	 {
	  flag = 1;  
	 } 
    else
	 {
	  flag = 0; // nevyhovel 
	 }
  }  

    
 if(flag == 1)  // vyhovuji data proved
  {
	  
 //-------------odpoved - kdyz vzhovy------
    
	TX_send();
	
//------------------------------ pro ladeni------
		 
     PORTA |= (1<<LED);  // trikrat blikne
  	 _delay_ms(100);
     PORTA  &= ~(1<<LED);
    _delay_ms(50);
     PORTA |= (1<<LED);
	_delay_ms(100);
     PORTA  &= ~(1<<LED);
  }   
   

_delay_ms(10);     // 
GICR  |= (1<<INT0);  // enable
GIFR=0x00;

}	




int main(void)
{
	
	init();
	PORTD  &= ~(1<<kl); // hodi klic do nuly
	
    while(1)
    {
    
	// PORTC  &= ~(1<<PWR); //zapni LOG 0 
     PORTA |= (1<<LED);
	_delay_ms(50);
   
    //	PORTC |= (1<<PWR); // vypni log "1"
     PORTA &= ~(1<<LED);
	_delay_ms(50);
  
 // -----  test vysilani
  
    // _delay_ms(1000);
	// PORTC  &= ~(1<<PWR); // napajeni ostatnich IO
/*	while (1){
		
   _delay_ms(1000);	
   sprintf ( buffer_0 , "aaaaaa"); //
   USART_putstring_0(buffer_0);
	
	
	PORTC |= (1<<PWR); // vypni log "1"		
	}*/
	

  
   }
}