//////////////////////////////////
// tef6901ah tuner chip routines

//////////////////////////////////

// #define tun_SCL  PIN_C3
// #define tun_SDA  PIN_C4


int16 c_PLL;
char c_band,w_band;
float c_freq;
//
char rbyte0,rbyte1,rbyte2,rbyte3,rbyte4,rbyte5,rbyte6;
int16 level_tt;

int8 tas;
short ifcapg;
char ifcap_val,ifcf_val,init_val;
//char r_LEV;
char level;


char read_tef(void);
char write_tef(char msa_wr, char data_wr);
char write_tun(char w_band5, int16 w_PLL5);
char init_tef(void);

char tun_goto_freq(char w_band2, float w_freq);
char tun_goto_PLL(char w_band3, int16 w_PLL);
char tun_seek(short seek_dir);
char show_level(short level_mode);

void change_band(void);
void show_freq(void);

void ifcap_align(void);
void ifcf_align(void);
void init_circuit(void);


///////////////////////////////////////////////////////////////////////////////////////////////////////
char read_tef() {

rbyte0=0;rbyte1=0;rbyte2=0;rbyte3=0;rbyte4=0;rbyte5=0;rbyte6=0;

i2c_start(tef);
	
if ((i2c_write(tef,0xc3))==1){printf("err01 ");return 1;}		// return error code 1 when no ack 

rbyte0=i2c_read(tef,1);
rbyte1=i2c_read(tef,1);
rbyte2=i2c_read(tef,1);
rbyte3=i2c_read(tef,1);
rbyte4=i2c_read(tef,1);
rbyte5=i2c_read(tef,1);

rbyte6=i2c_read(tef,0);

i2c_stop(tef);
//
stin = bit_test(rbyte3,2);
tas = rbyte3&0x03;
ifcapg = bit_test(rbyte5,7);

//printf("stin= %u* ",stin);
//printf("tas= %u* ",tas);
//printf("%u %u %u %u %u %u %u \n\r",rbyte0,rbyte1,rbyte2,rbyte3,rbyte4,rbyte5,rbyte6);

return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char write_tef(char msa_wr, char data_wr)
{
 
i2c_start(tef);
if ((i2c_write(tef,0xc2))==1){return 1;}			// return error code 1 when no ack 
  
if ((i2c_write(tef,msa_wr))==1){return 2;}
if ((i2c_write(tef,data_wr))==1){return 3;}	
i2c_stop(tef);


return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char write_tun(char w_band5, int16 w_PLL5)
{
char bw,pllm,plll,daa,agc,band;

bw=0xfe;
daa=0x60;
agc=0x0c;

if (w_band5==0){band=0x20;}			// FM
else if (w_band5==1){band=0xec;}	// MW
else if (w_band5==2){band=0xec;}	// LW
else if (w_band5==3){band=0xd0;}	// SW1
else if (w_band5==4){band=0xb0;}	// SW2
else if (w_band5==5){band=0x90;}	// SW3
else if (w_band5==6){band=0x70;}	// SW4

plll=w_PLL5;
pllm=w_PLL5>>8;

i2c_start(tef);
if ((i2c_write(tef,0xc2))==1){return 4;}	// return error code 4 when no ack 	
  
if ((i2c_write(tef,0x20))==1){return 5;}	
if ((i2c_write(tef,bw))==1){return 6;}	
if ((i2c_write(tef,pllm))==1){return 7;}
if ((i2c_write(tef,plll))==1){return 8;}
if ((i2c_write(tef,daa))==1){return 9;}	
if ((i2c_write(tef,agc))==1){return 10;}	
if ((i2c_write(tef,band))==1){return 11;}

i2c_stop(tef);


return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char init_tef()
{

// check IFCAP	
// EEPROM address 0xfe
ifcap_val = read_EEPROM(0xfe);
if (ifcap_val==0xff){ifcap_val=8;}

// check IFCF	
// EEPROM address 0xfd
ifcf_val = read_EEPROM(0xfd);
if (ifcf_val==0xff){ifcf_val=32;}



write_tef(0x20,0xfe);	// bandwidth
write_tef(0x21,0x08);	// PLLM
write_tef(0x22,0x5e);	// PLLL		085e= 96.4MhZ
write_tef(0x23,0x60);	// DAA
write_tef(0x24,0x0c);	// AGC
write_tef(0x25,0x20);	// BAND: FM, FREF=100khZ, hi injection
//write_tef(0x25,0xec);	// BAND: AM
//
//
write_tef(0x26,0x84);	// 
write_tef(0x27,ifcf_val);	// IFCF
write_tef(0x28,ifcap_val);	// IFCAP
write_tef(0x29,0x4a);	// ACD
write_tef(0x2a,0x85);	// SENSE, weak signal
write_tef(0x2b,0x66);	// 
write_tef(0x2c,0x7c);	// SNC
write_tef(0x2d,0x6f);	// HIGHCUT

write_tef(0x2e,0x6a);	// SOFTMUTE
//write_tef(0x2f,0x09);	// RADIO: stereo, direct RDS
write_tef(0x2f,0x19);	// RADIO: stereo, buffered RDS
write_tef(0x30,0x0a);	// INPUT: radio, db... muted

write_tef(0x31,0x1c);	// VOLUME
write_tef(0x32,0x0c);	// 
write_tef(0x33,0x0c);	// 
write_tef(0x34,0x00);	// 
write_tef(0x35,0x03);	// OUTPUT: rear muted
write_tef(0x36,0x80);	// 
write_tef(0x37,0x1c);	// LOUDNESS on

write_tef(0x38,0x06);	// power

write_tef(0x39,0x00);	// reserved
write_tef(0x3a,0x00);	// 
write_tef(0x3b,0x00);	// 
write_tef(0x3c,0x00);	// 
write_tef(0x3d,0x00);	// 
write_tef(0x3e,0x00);	// 
write_tef(0x3f,0x00);	// test

//rdcl=1;


// check INIT
// EEPROM address 0xfc
init_val = read_EEPROM(0xfc);
if (init_val==0xff){init_circuit();}




return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
char tun_goto_freq(char w_band2, float w_freq)
{
float w_PLL2;
int16 w_PLL3;
float w_freq2;

if(w_band2==0){		// FM
			w_freq2 = w_freq*1000000;
			if((w_freq<=87.45)||(w_freq>=108.05)){return 1;}	// FM band 87.5 .. 108.0 MhZ
			w_PLL2 = ((w_freq2+10700000)*2) / 100000;		// FM, high side injection
			w_PLL3 = (int16)w_PLL2;
			}

else if((w_band2==1)||(w_band2==2)){		// MW or LW
			w_freq2 = w_freq*1000;
			if((w_freq<=143)||(w_freq>=1711)){return 1;}		// MW band 522 .. 1710 khZ
			w_PLL2 = ((w_freq2+10700000)*20) / 20000;		// AM
			w_PLL3 = (int16)w_PLL2;
			
			//write_tef(0x25,0xec);	// BAND: MW or LW
			}

else if(w_band2==3){		// SW1
			w_freq2 = w_freq*1000;
			if((w_freq<=2299)||(w_freq>=5101)){return 1;}		// SW1 band 2300 .. 5100 khZ
			w_PLL2 = ((w_freq2+10700000)*16) / 10000;		// AM
			w_PLL3 = (int16)w_PLL2;
			
			//write_tef(0x25,0xd0);	// BAND: SW1
			}

else if(w_band2==4){		// SW2
			w_freq2 = w_freq*1000;
			if((w_freq<=5799)||(w_freq>=13871)){return 1;}		// SW2 band 5800 .. 13870 khZ
			w_PLL2 = ((w_freq2+10700000)*10) / 10000;		// AM
			w_PLL3 = (int16)w_PLL2;
			
			//write_tef(0x25,0xb0);	// BAND: SW2
			}

else if(w_band2==5){		// SW3
			w_freq2 = w_freq*1000;
			if((w_freq<=11499)||(w_freq>=19021)){return 1;}		// SW1 band 11500 .. 19020 khZ
			w_PLL2 = ((w_freq2+10700000)*8) / 10000;		// AM
			w_PLL3 = (int16)w_PLL2;
			
			//write_tef(0x25,0x90);	// BAND: SW3
			}

else if(w_band2==6){		// SW4
			w_freq2 = w_freq*1000;
			if((w_freq<=17479)||(w_freq>=26101)){return 1;}		// SW2 band 17480 .. 26100 khZ
			w_PLL2 = ((w_freq2+10700000)*6) / 10000;		// AM
			w_PLL3 = (int16)w_PLL2;
			
			//write_tef(0x25,0x70);	// BAND: SW4
			}



write_tun(w_band2, w_PLL3);

c_band = w_band2;
c_freq = w_freq;
c_PLL = w_PLL3;

show_freq();

return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
char tun_goto_PLL(char w_band3, int16 w_PLL4)
{
int32 w_PLL3;
float w_PLL2;
float w_freq2;

if(w_band3==0){		// FM
			w_PLL3 = ((int32)(w_PLL4));		
			w_PLL3*=50000;			// 100000/2
			w_PLL3-=10700000;
			w_PLL2 = ((float)(w_PLL3));
			w_freq2 = w_PLL2/1000000;
			}

if((w_band3==1)||(w_band3==2)){		// MW or LW
			w_PLL3 = ((int32)(w_PLL4));	
			w_PLL3*=1000;			// 20000/20
			w_PLL3-=10700000;
			w_PLL2 = ((float)(w_PLL3));
			w_freq2 = w_PLL2/1000;
			
			//write_tef(0x25,0xec);	// BAND: MW or LW
			}

if(w_band3==3){		// SW1
			w_PLL3 = ((int32)(w_PLL4));	
			w_PLL3*=625;			// 10000/16
			w_PLL3-=10700000;
			w_PLL2 = ((float)(w_PLL3));
			w_freq2 = w_PLL2/1000;
			
			//write_tef(0x25,0xd0);	// BAND: SW1
			}

if(w_band3==4){		// SW2
			w_PLL3 = ((int32)(w_PLL4));	
			w_PLL3*=1000;			// 10000/10
			w_PLL3-=10700000;
			w_PLL2 = ((float)(w_PLL3));
			w_freq2 = w_PLL2/1000;
			
			//write_tef(0x25,0xb0);	// BAND: SW2
			}

if(w_band3==5){		// SW3
			w_PLL3 = ((int32)(w_PLL4));	
			w_PLL3*=1250;			// 10000/8
			w_PLL3-=10700000;
			w_PLL2 = ((float)(w_PLL3));
			w_freq2 = w_PLL2/1000;
			
			//write_tef(0x25,0x90);	// BAND: SW3
			}

if(w_band3==6){		// SW4
			w_PLL3 = ((int32)(w_PLL4));	
			w_PLL3*=1666.6666667;			// 10000/6
			w_PLL3-=10700000;
			w_PLL2 = ((float)(w_PLL3));
			w_freq2 = w_PLL2/1000;
			
			//write_tef(0x25,0x70);	// BAND: SW4
			}


write_tun(w_band3, w_PLL4);

c_band = w_band3;
c_freq = w_freq2;
c_PLL = w_PLL4;

show_freq();
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////

char tun_seek(short seek_dir)
{
float w_freq3;

//
if(seek_dir){						// tuning step up
			if (c_band==0){w_freq3=c_freq+0.05;}
			else if ((c_band==1)||(c_band==2)){w_freq3=c_freq+1;}
			else if (c_band==3){w_freq3=c_freq+0.625;}
			else if (c_band==4){w_freq3=c_freq+1;}
			else if (c_band==5){w_freq3=c_freq+1.25;}
			else if (c_band==6){w_freq3=c_freq+1.67;}
			}
//
else if (!seek_dir){				// step down
					if (c_band==0){w_freq3=c_freq-0.05;}
					else if ((c_band==1)||(c_band==2)){w_freq3=c_freq-1;}
					else if (c_band==3){w_freq3=c_freq-0.625;}
					else if (c_band==4){w_freq3=c_freq-1;}
					else if (c_band==5){w_freq3=c_freq-1.25;}
					else if (c_band==6){w_freq3=c_freq-1.67;}
					}		
//
tun_goto_freq(c_band,w_freq3);

show_freq();
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
char show_level(short level_mode)
{
if (level_mode){goto level_cont;}

if (level_tt!=500){level_tt++;return 1;}
else {level_tt=0;}


level_cont:

//if (level_tt>=500){level_tt=0;}
//else if (level_tt>=1){level_tt++;return 1;}
//else if (level_tt==0){level_tt=1;}

i2c_start(tef);
if ((i2c_write(tef,0xc3))==1){return 1;}		// return error code 1 when no ack 
rbyte0=i2c_read(tef,1);
rbyte1=i2c_read(tef,1);
rbyte2=i2c_read(tef,1);
rbyte3=i2c_read(tef,0);
i2c_stop(tef);

stin = bit_test(rbyte3,2);
level=rbyte1;

nokia_gotoxy(0,5);
printf(nokia_printchar,"%03u",level);

return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////

void change_band()
{

preset_char= '*';

if (c_band==0){tun_goto_freq(1,648);}						// goto BAND 1: MW
else if (c_band==1){tun_goto_freq(2,235);}					// goto BAND 2: LW
else if (c_band==2){tun_goto_freq(3,2300);}					// goto BAND 3: SW1
else if (c_band==3){tun_goto_freq(4,7880);}					// goto BAND 4: SW2
else if (c_band==4){tun_goto_freq(5,11500);}				// goto BAND 5: SW3
else if (c_band==5){tun_goto_freq(6,26000);}				// goto BAND 6: SW4
else if (c_band==6){tun_goto_freq(0,92.0);rds_init();}		// goto BAND 0: FM

printf(" ** band change ** ");
//
//



}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void show_freq()
{

nokia_erase_y(1);
nokia_gotoxy(0,1);						// Show the current tuner frequency 

if(c_band==0){printf(nokia_printchar,"FM %3.2g MhZ",c_freq);}
else if(c_band==1){printf(nokia_printchar,"MW %4.0g khZ",c_freq);}
else if(c_band==2){printf(nokia_printchar,"LW %3.0g khZ",c_freq);}
else if(c_band==3){printf(nokia_printchar,"SW1 %4.2g",c_freq);}
else if(c_band==4){printf(nokia_printchar,"SW2 %5.2g",c_freq);}
else if(c_band==5){printf(nokia_printchar,"SW3 %5.2g",c_freq);}
else if(c_band==6){printf(nokia_printchar,"SW4 %5.2g",c_freq);}
}




//////////////////////////////////////////////////////////////////////////////////////////////////////
void ifcap_align()
{
char ifcap_val2;

nokia_gotoxy(10,3);printf(nokia_printchar,"IFCAP align 1");
delay_ms(1000);

for (ifcap_val2=0x0f;ifcap_val2!=0;ifcap_val2--){
											write_tef(0x28,(ifcap_val2|0x80));
											read_tef();
											if (!ifcapg){
														ifcap_val=ifcap_val2;
														break;
														}
												}

write_tef(0x28,(ifcap_val&0x0f));
//printf("ifcap_val= %u ",ifcap_val);

write_EEPROM(0xfe,ifcap_val);
nokia_gotoxy(10,3);printf(nokia_printchar,"IFCAP=%3u  ",ifcap_val);

}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void ifcf_align()
{
char i;
char ifcf_val2,ifcf_val3;
char ifcf_lev_under[65];
char ifcf_lev_over[65];
short ifcf_set;
char level;
signed char ifcf_diff[65],ifcf_diff2;
signed char cf_v;

//ifcap_val=8;	// set to center position;
ifcf_val=32;

write_tef(0x27,ifcf_val);	// IFCF
//write_tef(0x28,ifcap_val);	// IFCAP

ifcf_set=0;

nokia_gotoxy(10,3);printf(nokia_printchar,"IFCF align ");
// tun_goto_freq(0,96.40);		// please tune to a station in the middle of FM band

write_tef(0x27,0x80);		// IFCFA to 1
delay_ms(100);
write_tef(0x27,0xc0);		// IFNBW to 1
delay_ms(100);
//
tun_goto_freq(0,c_freq-0.05);		// tune to RF -50khZ
delay_ms(100);
//
for (ifcf_val2=0;ifcf_val2!=64;ifcf_val2++){
											write_tef(0x27,ifcf_val2);delay_ms(100);
											i2c_start(tef);
											if ((i2c_write(tef,0xc3))==1){;}		
											rbyte0=i2c_read(tef,1);
											rbyte1=i2c_read(tef,0);
											i2c_stop(tef);
											level=rbyte1;
											ifcf_lev_under[ifcf_val2] = level;
											//printf("u%u=%u ",ifcf_val2,ifcf_lev_under[ifcf_val2]);
											}
//
tun_goto_freq(0,c_freq+0.10);		// tune to RF +50khZ
delay_ms(100);

//
for (ifcf_val2=0;ifcf_val2!=64;ifcf_val2++){
											write_tef(0x27,ifcf_val2);delay_ms(100);
											i2c_start(tef);
											if ((i2c_write(tef,0xc3))==1){;}	
											rbyte0=i2c_read(tef,1);
											rbyte1=i2c_read(tef,0);
											i2c_stop(tef);
											level=rbyte1;
											ifcf_lev_over[ifcf_val2] = level;
											//printf("o%u=%u ",ifcf_val2,ifcf_lev_over[ifcf_val2]);
											}
//

for (i=0;i!=64;i++){
					ifcf_diff[i]= ifcf_lev_over[i] - ifcf_lev_under[i];
					//printf("diff%d ",ifcf_diff[i]);
					}
//


for(cf_v=0;cf_v!=50;cf_v++){
							if(ifcf_set==1){break;}
							//printf(" cf_v=%u ",cf_v);

							for (i=0;i!=64;i++){
												ifcf_diff2 = ifcf_diff[i];
												ifcf_val3=i;
												if ((ifcf_diff2>=-cf_v)&&(ifcf_diff2<=cf_v)){ifcf_set=1;break;}
												}


								}
////


//ifcf_val3=16;	// test


write_tef(0x27,ifcf_val3);		// IFCFA to 0 and IFNBW to 0
delay_ms(100);


ifcf_val=ifcf_val3-4;


//printf("ifcf_val= %u ",ifcf_val);
nokia_gotoxy(10,3);printf(nokia_printchar,"IFCF=%3u   ",ifcf_val);
write_EEPROM(0xfd,ifcf_val);

tun_goto_freq(0,c_freq-0.05);		// tune to RF 

}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void init_circuit()
{
int16 rtt;
float search_freq;
char init_ok;
//float f_radio[9]={97.90,98.60,93.70,97.50,100.10,100.60,100.90,101.80,102.10};
char fix,level_1,level_2;



init_ok=0;


write_tef(0x30,0x00);	// INPUT: radio, db... 
write_tef(0x35,0x00);	// OUTPUT: not muted

blank_displays();

//nokia_gotoxy(0,2);printf(nokia_printchar,"Starting....");
//nokia_gotoxy(0,3);printf(nokia_printchar,"init");


//
/*
for(fix=0;fix!=9;fix++){
						tun_goto_freq(0,f_radio[fix]);
						delay_ms(100);
						get_level();	// level = signal level 0..255
						lcd_module_display();
						if(level>=220){break;}
						}
*/


blank_displays();
nokia_gotoxy(1,1);printf(nokia_printchar,"IFCF align? ");
nokia_gotoxy(1,3); printf(nokia_printchar,"ENTER to accept");
nokia_gotoxy(1,4); printf(nokia_printchar,"< > to cancel ");
while(btn_enter);delay_ms(100);


while((!btn_left)&&(!btn_right)&&(!btn_enter)){;}
if(btn_enter){

				// IFCAP	
				ifcap_align();
				
				nokia_gotoxy(1,1);printf(nokia_printchar,"*** IFCF align  *** ");
				nokia_gotoxy(1,2);printf(nokia_printchar,"Please tune to a    ");
				nokia_gotoxy(1,3);printf(nokia_printchar,"known f near 98.0  ");
				nokia_gotoxy(1,4);printf(nokia_printchar,"and press ENTER.    ");
				while(btn_enter);
				delay_ms(1500);
				blank_displays();
				nokia_gotoxy(1,1);printf(nokia_printchar,"                   ");
				
				tun_goto_freq(0,98.0);
				//lcd_module_display();
				nokia_lcd_display();
				nokia_gotoxy(10,3);printf(nokia_printchar,"tune+ENTER ");
				
				
				while(!btn_enter){
									if(btn_left){tun_seek(0);preset_char= '*';
												//lcd_module_display();
												nokia_lcd_display();
												while(btn_left);}
									else if(btn_right){tun_seek(1);preset_char= '*';
														//lcd_module_display();
														nokia_lcd_display();
														while(btn_right);}
									}
				
				
				//  IFCF	
				ifcf_align();
				delay_ms(1000);

			}

nokia_gotoxy(1,1);printf(nokia_printchar,"                    ");
blank_displays();

// IFCAP	2nd pass
ifcap_align();
delay_ms(1000);


blank_displays();
nokia_gotoxy(1,1);printf(nokia_printchar,"Init presets?       ");
nokia_gotoxy(1,3);printf(nokia_printchar,"Push ENTER to accept");
nokia_gotoxy(1,4);printf(nokia_printchar,"Press < > to cancel ");
while((!btn_left)&&(!btn_right)&&(!btn_enter)){;}
if(btn_enter){
			nokia_gotoxy(1,1);printf(nokia_printchar,"                    ");
			blank_displays();
			for(ix=0;ix!=252;ix++){write_EEPROM(ix,0xff);}	// reset EEPROM	
			write_EEPROM(0xfc,0x11);
			
			search_freq=87.50;
			
			for(fix=0;fix!=15;fix++){
									
									station_searching=1;
									preset=fix; goto_preset(2);		// goto preset in mode 2 (no up/down)
									tun_goto_freq(0,search_freq);
									while(station_searching){
													delay_ms(20);
													show_level(1);	// level = signal level 0..255
													
													nokia_gotoxy(1,1);printf(nokia_printchar,"                    ");
													blank_displays();
													//lcd_module_display();
													nokia_lcd_display();
													nokia_gotoxy(9,3);printf(nokia_printchar,"init presets");
													if(level>=160){
																	level_1=level;
																	search_freq+=0.05;tun_seek(1);
																	delay_ms(20);
																	show_level(1);	// level = signal level 0..255
																	level_2=level;
			
																	if(level_2>=level_1){;}
																	else{search_freq-=0.05;tun_seek(0);}		// goto strongest signal
			
																	for(rtt=0;rtt<=3000;rtt++){rds_main();if(syndrome_detected==1){rtt+=50;};}
																	//
																	if(rds_q>=2){
																				for(rtt=0;rtt<=10000;rtt++){rds_main();if(syndrome_detected==1){rtt+=50;};}
																				save_preset();
																				station_searching=0;search_freq+=0.10;tun_seek(1);
																				}
																	else{search_freq+=0.05;tun_seek(1);}
																	if(c_freq>=108.0){break;}
																	}
													else{search_freq+=0.05;tun_seek(1);}
													if(c_freq>=108.0){break;}
													}
									}
station_searching=0;			

			}
// 

nokia_gotoxy(1,1);printf(nokia_printchar,"                    ");
blank_displays();

preset=0; goto_preset(2);		// goto preset in mode 2 (no up/down)
}
//////////////////////////////////////////////////////////////////////////////////////////////////////

