// WINAVR    GCC   
// ATmega8        
// clock: internal 8Mhz   
   
#include <util/twi.h>
#include <avr/io.h>   
#include <avr/interrupt.h> 
#include "lcd_drv.h"
#include "main.h"
#include "mydefs.h"
#include <stdlib.h>
#include <util/delay.h>
  
#define uchar uint8_t   
#define uint  uint16_t   
   
#define SLA_W 0b11000000      //Slave Adress und Write
#define SLA_R 0b11000001      //Slave Adress und Read

#define UP PB1
#define DO PB0
 
uchar senddata[5];   
uchar readdata[5];   
uchar search = 0;   
uchar search_up = 0;
   
/*****************************************************************/   
void set5767(void);   
void read5767(void);   
void show_frequency(void);   
void show_rx_power(void);      
void init(void);   
//-------------------------------   

   
void set5767(void)   
{   
    uchar i = 0;  
       
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);           // SEND START SIGNAL   
    while (!(TWCR & (1<<TWINT)));                 // WAIT FOR START SIG   
    	if ((TWSR & 0xF8) != TW_START){
			lcd_pos(0,0);
			lcd_text("            ");
  			lcd_pos(0,0);
  			lcd_text("Fehler Start");
			_delay_ms(500);
		}   
       
    TWDR = SLA_W;                                   // send address   
    TWCR = (1<<TWINT) | (1<<TWEN);   
    while (!(TWCR & (1<<TWINT)));   
    		if((TWSR & 0xF8) != TW_MT_SLA_ACK){
			lcd_pos(0,0);
			lcd_text("            ");
  			lcd_pos(0,0);
  			lcd_text("Fehler Adresse");
			_delay_ms(500);
		}   	   
       
    for ( i = 0; i<5; i++ )   
    {   
        TWDR = senddata[i];   
        TWCR = (1<<TWINT) | (1<<TWEN);              // send data   
        while (!(TWCR & (1<<TWINT)));   
    		if ((TWSR & 0xF8) != TW_MT_DATA_ACK){
			lcd_pos(0,0);
			lcd_text("            ");
  			lcd_pos(0,0);
  			lcd_text("Fehler Data");
			_delay_ms(500);
		}     
    }   
       
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);       //SEND STOP SIGNAL   
          
}   
    
   
void read5767(void)   
{   
	lcd_pos(0,0);
	lcd_text("            ");
    uchar i = 0;   
       
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);       // SEND START SIGNAL   
    while (!(TWCR & (1<<TWINT)));                 // WAIT FOR START SIG  
		if ((TWSR & 0xF8) != TW_START){
  			lcd_pos(0,0);
  			lcd_text("Fehler LStart");
			_delay_ms(500);
		}    
       
    TWDR = SLA_R;                                   // send address   
    TWCR = (1<<TWINT) | (1<<TWEN);   
    while (!(TWCR & (1<<TWINT)));
		if ((TWSR & 0xF8) != TW_MR_SLA_ACK){
  			lcd_pos(0,0);
  			lcd_text("Fehler AdHolen");
			_delay_ms(1000);
		}
	_delay_us(10); 	      
       
    for ( i = 0; i<5; i++ )   
    {   
        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);              // read data   
        while (!(TWCR & (1<<TWINT)));
			if ((TWSR & 0xF8) != TW_MR_DATA_ACK){
	  			lcd_pos(0,0);
	  			lcd_text("ERR DatHol");
				_delay_ms(500);
			}else{  
	        	readdata[i] = TWDR ;
			}   
	_delay_us(100);                     
           
    }   
    _delay_ms(1);   
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);       //SEND STOP SIGNAL 

	PORTB &= ~(1<<PB2); 
    
}   

 
void show_rx_power(void)
{   
    uchar temp;   
       
    temp = (readdata[3]>>4);
	lcd_pos(0,0);
	lcd_text("            "); 
	lcd_data((temp/10)%10 + 0x30);
	lcd_data(temp%10 + 0x30);

	_delay_ms(500);  
         
}   
   
void init(void)   
{   
    DDRB =  (1<<PB2);   
         
    DDRB &= ~((1<<UP)|(1<<DO));						//1 Pin als Eingang (Taster)
	PORTB |= (1<<UP)|(1<<DO);   
       
    DDRC = 0x00;   
    PORTC = 0xFF;      //  IO init   
       
    _delay_ms(100);   
    //TWI   
    TWBR = 32; //12  
    TWCR = (1<<TWEN); //SEND STOP SIGNAL   

    OSCCAL=0x9d;    //0b10011101    
    
    lcd_init(); 
   
}   

   
int main(void)   
{   
	char buffer [9];
    init();   
    
	unsigned long frequency;
	unsigned int frequencyB;

	frequency=10560; //starting frequency 105.6

  	frequencyB=4*(frequency*10000+225000)/32768; //calculating PLL word

  	senddata[0]=frequencyB>>8;

  	senddata[1]=frequencyB&0xff;

    senddata[2] = 0b00110000;   
    senddata[3] = 0b00010000;        //Org 0b10010000  32.768 kHz                                                                    
    senddata[4] = 0b00000000;   
       
    lcd_text(" FM STEREO ");    
    set5767();
    //show_frequency();

	   
    while(1){   
   
        if (!(PINB & (1<<UP))){  //um 5 erhöhen, funktioniert
			_delay_ms(50);
			if (!(PINB & (1<<UP))){
				PORTB |= (1<<PB2);
				lcd_pos(1,15); 
				lcd_data(1); 

				frequency += 5;

    			frequencyB=4*(frequency*10000+225000)/32768;

    			senddata[0] = (frequencyB>>8)&0x3f;
    			senddata[1] = frequencyB&0xff;
				senddata[2] = 0b00110000;
				senddata[3] = 0b00010010;
				   
                set5767();   
   
                search_up = 0;   
                //search = 1;
				read5767();
				show_rx_power();
			}    
        }   
           
        if (!(PINB & (1<<DO)) && search==0){   //Suchen nach unten
            _delay_ms(50);   
            if (!(PINB & (1<<DO)))   
            {   
                PORTB |= (1<<PB2); 
				lcd_pos(1,15); 
				lcd_data(0);
                  
    			senddata[0]|= 0x40;
 
				senddata[2]=0b01000000;  //Suchen nach unten
				senddata[3]=0b00010000;
				senddata[4]=0b00000000; 			   

			
				
				set5767();    
                //search_up = 1;   
                search = 1;   
                   
            }   
        }   
           
        		
        if (search ){   
			_delay_ms(100);
            read5767();   
            
			/*_delay_ms(50);
            if ( readdata[0] & 0x40 ){           //reach band end   
               
				lcd_pos(1,0);
				lcd_text("Bandende");
				_delay_ms(1000); 
                if ( search_up )   
                {   
                    senddata[0] = 0b01101001;    // load 88Mhz pll   
                    senddata[1] = 0b11011010;   
                    set5767();   
                }   
                else                     
                {   
                    senddata[0] = 0b01110011;    //  108Mhz pll   
                    senddata[1] = 0b01100100;   
                    set5767();   
                }   
            }*/   
                  
            if ( readdata[0] & 0x80){          //Station gefunden   
    			
				if(readdata[2]& 0x80){
					lcd_pos(1,0);
  					lcd_text("Stereo");
				}else{
					lcd_pos(1,0);
  					lcd_text("Mono");
				}
				lcd_pos(0,0);                                   
				lcd_text("            s0"); 
				itoa(readdata[0],buffer,2);
  				lcd_pos(0,0);
				lcd_text(buffer);
				lcd_pos(1,0);                            
				lcd_text("            s1");
				itoa(readdata[1],buffer,2);
  				lcd_pos(1,0);
				lcd_text(buffer);
	  
                show_rx_power();  //Level  
                senddata[0] = (readdata[0] & 0x3f);//|0x40);  //01+PLL
                senddata[1] = readdata[1];      //record the pll   
                search = 0; 
		
            }   
            frequency=((((unsigned long)(senddata[0]&0x3f)<<8)| senddata[1])*8192-225000)/10000;   
        } 
		
		itoa((frequency),buffer,10);
		lcd_pos(1,0);
		lcd_text(buffer);  

    } 

return 1;  
}   
   

