#include <avr/io.h> 
#include <util/delay.h> 
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdint.h>
#include "1wire.h"
#include "pwm.h"
#include "lcd.h"
#include "i2c.h"
#include "ds1307.h"
#include "keyboard.h"
#include "rfm01.h"

// ******************************************************************************
// FCE: hlavni program obsahujici nekonecnou smycku a fci "main"
// INC: "1wire.h", "pwm.h", "lcd.h", "i2c.h", "ds1307.h", "keyboard.h", "rfm01.h"
// DAT: 8.3.2012
// VER: 2 
// ******************************************************************************


#define LENGTH_MSG      20		// delka prenaseneho slova

#define SDI            PB5		// definice pinu RFM modulu
#define SDI_PORT       PORTB
#define SDI_DDR        DDRB

#define SDO            PB6           
#define SDO_PORT       PORTB
#define SDO_DDR        DDRB
#define SDO_PIN        PINB

#define SCK            PB7
#define SCK_PORT       PORTB
#define SCK_DDR        DDRB

#define nIRQ           PB2     
#define nIRQ_PORT      PORTB
#define nIRQ_DDR       DDRB
#define nIRQ_PIN       PINB

#define nSEL           PB1
#define nSEL_PORT      PORTB
#define nSEL_DDR       DDRB

#define LED_ERR        PD3		// LED ERR
#define LED__ERR_PORT  PORTD
#define LED_ERR_DDR    DDRD

#define LED            PD2		// LED COM
#define LED_PORT       PORTD
#define LED_DDR        DDRD

// interni stavove definice
#define SDI_H           SDI_PORT |= _BV(SDI)
#define SDI_L           SDI_PORT &= (~(_BV(SDI)))
#define SDI_INIT        SDI_DDR |= _BV(SDI)

#define SDO_INPUT       (SDO_PIN & _BV(SDO))
#define SDO_INIT        SDO_DDR &= (~(_BV(SDO)))

#define SCK_H           SCK_PORT |= _BV(SCK)
#define SCK_L           SCK_PORT &= (~(_BV(SCK)))
#define SCK_INIT        SCK_DDR |= _BV(SCK)

#define nIRQ_INPUT      (nIRQ_PIN & _BV(nIRQ))
#define nIRQ_INIT       nIRQ_DDR &= (~(_BV(nIRQ)))

#define nSEL_H          nSEL_PORT |= _BV(nSEL)
#define nSEL_L          nSEL_PORT &= (~(_BV(nSEL)))
#define nSEL_INIT       nSEL_DDR |= _BV(nSEL)

#define LED_H           LED_PORT |= _BV(LED)
#define LED_L           LED_PORT &= (~(_BV(LED)))
#define LED_INIT        LED_DDR |= _BV(LED)

#define LED_ERR_H       LED__ERR_PORT |= _BV(LED_ERR)
#define LED__ERR_L      LED_ERR_PORT &= (~(_BV(LED_ERR)))
#define LED_ERR_INIT    LED_ERR_DDR |= _BV(LED_ERR)

#define START_FIFO      RF_WRITE_CMD(CMD_FIFO|FIFO_8|FIFO_VDI_WORD|FIFO_FF|FIFO_FE)
//#define START_FIFO    RF_WRITE_CMD(CMD_FIFO|FIFO_8|FIFO_ALWAYS|FIFO_FF|FIFO_FE)
#define STOP_FIFO       RF_WRITE_CMD(CMD_FIFO)
#define BLIK_LED        tik262ms=1

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

uint8_t rx_buf[LENGTH_MSG+1];	// pole bufferu RFM
volatile uint8_t tik262ms;

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


char buffer1[12];	// DS18B20 buffer
char buffer2[9];	// Time, Date buffer

unsigned int screen;	// definice pomocnych promennych 
unsigned int h;
unsigned int s = 0;

extern unsigned int key;
unsigned int lastkey = 0;

// inicializace definovanych pinu RFM a LED
void IO_INIT(void)
{
        SDI_INIT;
        SDO_INIT;
        SCK_INIT;
        nIRQ_INIT;
        nSEL_INIT;
        LED_INIT;
}

// definice pocatecnych stavu modulu
void RF_INIT(void)
{
   nSEL_H;
   SDI_H;
   SCK_L;
   nIRQ_INPUT;
   SDO_INPUT;
}

// zapis instrukce do modulu
uint16_t RF_WRITE_CMD(uint16_t cmd)
{
   uint8_t i;
   uint16_t temp;

   SCK_L;
   nSEL_L;
   temp=0;
   for (i=0;i<16;i++)
   {
      if (cmd & 0x8000) SDI_H;
      else SDI_L;
          SCK_H;
      cmd <<= 1;
          temp <<= 1;
          if(SDO_INPUT) temp |= 0x0001;
          SCK_L;
   }
   SCK_L;
   nSEL_H;
   return (temp);
}

// zapis dat do moduli
void RF_WRITE_DATA(uint8_t data)
{
      while (nIRQ_INPUT);
      RF_WRITE_CMD(0xB800 + data);
}

// cteni dat z modulu
uint8_t RF_READ_DATA(void)
{
		
        uint8_t i,result;

		if(s==0)
		{
			lcd_gotoxy(0,0);
			lcd_puts("Please, turn on");
			lcd_gotoxy(0,1);
			lcd_puts("wireless sensor");
		}		

        while (nIRQ_INPUT);

		if(s==0) lcd_clrscr();
		s++;

        SCK_L;
        nSEL_L;
        SDI_L;
        result=0;
        for (i=0;i<24;i++)
        {
                result <<= 1;
                if (SDO_INPUT) result |= 0x01;
                SCK_H;
                SCK_L;
        }
        nSEL_H;
        return (result);
}



// ****** MAIN ****************************** MAIN *******************


void main()
{	 

	lcd_init(); 		// LDC init
	lcd_clrscr();		// LCD clear	
	InitPWM(100);		// PWM init

	_delay_ms(500);		// ochranna pauza

	I2CInit();			// I2C init

//	TimeInit();			// DS1307 init - FIX!

	key = 2;			// nastaveni defaultní obrazovky
	
	_delay_ms(500);
	
	uint8_t i,ChkSum;	// def. promennych 
    uint8_t b;

	IO_INIT();			
	RF_INIT();
	sei();
    _delay_ms(100);
    LED_L;
	// nastaveni parametru prijimaciho modulu
    RF_WRITE_CMD(CMD_SETTING        |BAND_868 | C_12pF | BANDWIDTH_134 | SETTING_DC);
    RF_WRITE_CMD(CMD_FREQUENCY      |FREQUENCY_868);
    RF_WRITE_CMD(CMD_RATE           |RATE_9600);
    RF_WRITE_CMD(CMD_FILTER         |FILTER_AL | FILTER_S0 | DQD_4);
    RF_WRITE_CMD(CMD_AFC            |AFC_POWER_ON | AFC_RANG_8 | AFC_ST | AFC_OE | AFC_EN);
    RF_WRITE_CMD(CMD_RX);
    RF_WRITE_CMD(CMD_RX             |VDI_CLOCK | LNA_GAIN_0 | DRSSI_103 | RX_EN);
    RF_WRITE_CMD(CMD_FIFO);

	for (b=0;b<3;b++){BLIK_LED;_delay_ms(100);}
	
	while(1)		// zacatek nekonecne smycky
	{	
		h = 0;

		cli();		
        START_FIFO;		// zacatek vycitani prijatych dat
        ChkSum = 0;
        for(i=0;i<LENGTH_MSG;i++) 
        {
        	b = RF_READ_DATA();
            LED_H;
            rx_buf[i] = b;
            ChkSum += b;
        }
											            
        b = RF_READ_DATA();
        RF_READ_DATA();

		STOP_FIFO;
        LED_L;
        //sei();

		TimeRead();				// cteni casu a data
		ThermRead(buffer1);		// cteni mistni teploty

		

		if(Time!=MeasTime)		// zaznam casu prijatych dat
		{
			for(h=0;h<9;h++) MeasTime[h] = Time[h];
		}
		
		for(h=0;h<5;h++) Time2[h] = Time[h];
 
		DDRD |= 0x00;		// nastaveni portu C a D
		PORTD |= 0xf0;
		DDRC |= 0xf0;		
		PORTC |= 0xf0;
		
		PORTC = 0xbf;
		check1();
		PORTC = 0x7f;
		check2();				
		PORTC = 0xdf;
		check3();
 

		switch(key){	// kontrola klavesnice > zobrazeni prislusne obrazovky
		case 0:
		{
			if(key!=lastkey) lcd_clrscr();		// podekovani :)
			lcd_gotoxy(0,0);
			lcd_puts("*      ABOUT       *"); 
			lcd_gotoxy(0,2);
	    	lcd_puts("Thanks for helping  ");
			lcd_gotoxy(0,3);
	    	lcd_puts("Ing. T.Gotthans     ");				
		}
		 	break;
	
		case 1:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*   LOCAL SENSOR   *");
		
			sprintf(buffer2,Date);				// zobrazeni data
			lcd_gotoxy(0,2);
			lcd_puts(buffer2);

		//	sprintf(buffer2,Time2);				// zobrazeni casu
			lcd_gotoxy(15,2);
			lcd_puts(MeasTime);
			
			lcd_puts(buffer2);

			lcd_gotoxy(0,3); 					// zobrazeni mistni teploty
			lcd_puts(buffer1); 
			lcd_putc('C'); 	
		}
			break;
		
		case 2:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("* WIRELESS SENSOR  *");	// zobrazeni dat z bezdratoveho senzoru
			
			lcd_gotoxy(0,2); 				
			lcd_puts("Temp[˛C]:");
			if (ChkSum == b) 
        	{
        		lcd_gotoxy(10,2);
	    		lcd_puts(rx_buf);	
        	}
        	else 
        	{
           		lcd_gotoxy(11,2); 				
				lcd_puts("N/A");
        	}
			
			lcd_gotoxy(0,3); 				
			lcd_puts("MeasTime:");
			lcd_gotoxy(10,3); 				
			lcd_puts(MeasTime);	
		}
			break;

		case 3:									// nevyuzite obrazovky
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");
		}
		 	break;
		case 4:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");	
		}
			break;
		case 5:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");	
		}
			break;

		case 6:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");
		}
		 	break;
		case 7:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");	
		}
			break;

		case 8:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");
		}
		 	break;
		case 9:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");	
		}
			break;
		case 10:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0); 				
			lcd_puts("*      UNUSED      *");	
		}
			break;
		case 11:
		{
			if(key!=lastkey) lcd_clrscr();
			lcd_gotoxy(0,0);
			lcd_puts("*      UNUSED      *");
		}
		 	break;	
		default:
		    break;
		}

		lastkey = key;		// ulozeni posledni zmacknute klavesy

	}


}	// END of MAIN











