//===========================================================================================
// FM TUNER (ATMEGA32, TEA5767, NOKIA3310)
// FM Module file
// Autor: Andrew Doynikov (01-04-2012)
//===========================================================================================
#define TEA5767_ADR_W 0xC0
#define TEA5767_ADR_R 0xC1

#define MUTE_ON     senddata[0] |= 0x80
#define MUTE_OFF    senddata[0] &= ~0x80
#define DTC75       senddata[4] |= 0x40 
#define DTC50       senddata[4] &= ~0x40
#define HCC_ON      senddata[3] |= 0x04 
#define HCC_OFF     senddata[3] &= ~0x04
#define SMUTE_ON    senddata[3] |= 0x08 
#define SMUTE_OFF   senddata[3] &= ~0x08
#define HiBYTE(w) (uint8_t)((w >> 8) & 0x00ff)
#define LoBYTE(w) (uint8_t)((w >> 0) & 0x00ff)
#define F_MIN  8700
#define F_MAX 10870
#define F_STEP   10
#define F_CHANEL_MAX     20
#define F_DEF  10000
#define TEA5767_STEREO_MASK    0x80
//===========================================================================================
void tea5768_read(void);
void tea5768_write(void);
char rx_qual(void);
char if_count(void);
void send_freq(void);
unsigned char fm_stereo(void);                                   
unsigned char valid_freq(void);
unsigned char senddata[5] ;
unsigned char readdata[5] ;
unsigned long freq;                             //частота 
unsigned int PLLfreq;
unsigned char n_chanel = 1;
unsigned long freqs[F_CHANEL_MAX] = {10120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char bass[F_CHANEL_MAX] = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8};
unsigned char treble[F_CHANEL_MAX] = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8};
//===========================================================================================
//*****************************************************************************
void tea5768_read(void )
{
cli();
unsigned char i = 0;
i2c_start();
i2c_write(TEA5767_ADR_R);
for ( i = 0; i < 5; i++ )
{
  readdata[i] = i2c_read(1);
  _delay_ms(1);
}
i2c_stop();
sei();
}
//*****************************************************************************
void tea5768_write(void )
{
cli();
unsigned char i = 0;
i2c_start();
i2c_write(TEA5767_ADR_W);
for ( i = 0; i < 5; i++ )
{
  i2c_write(senddata[i]);
  _delay_ms(1);
}
i2c_stop();
sei();
}
//*****************************************************************************
char if_count(void)                                       
{
unsigned char y;
tea5768_read();
y = readdata[2] & 0x7F;
_delay_ms(10);
return y;    
}
//*****************************************************************************
void lcd_freq(unsigned char nfont)
{
unsigned char display_bit[4];
unsigned int freq_lcd;
if (valid_freq())
{
  freq_lcd = freq;
  display_bit[0] = (freq_lcd / 10000) % 10;
  if ( display_bit[0] == 0 ) display_bit[0] = 0x20; else display_bit[0] += 0x30;
  display_bit[1] = (freq_lcd / 1000) % 10 + 0x30;
  display_bit[2] = (freq_lcd / 100) % 10 + 0x30;
  display_bit[3] = (freq_lcd / 10) % 10 + 0x30;
  LcdChr(nfont,display_bit[0]);
  LcdChr(nfont,display_bit[1]);
  LcdChr(nfont,display_bit[2]);
  LcdChr(nfont,'.');
  LcdChr(nfont,display_bit[3]);
  LcdChr(nfont,'0');
} else {
  LcdChr(nfont,'-');
  LcdChr(nfont,'-');
  LcdChr(nfont,'-');
  LcdChr(nfont,'.');
  LcdChr(nfont,'-');
  LcdChr(nfont,'-');
}
}
//*****************************************************************************
char rx_qual(void)                                   
{
unsigned char x, r;
tea5768_read();
x = readdata[3] >> 4;
if ((x > 0) && (x <= 3)) { r = 1; }
if ((x >= 4) && (x <= 7)) { r = 2; }
if ((x >= 8) && (x <= 11)) { r = 3; }   
if ((x >= 12) && (x <= 15)) { r = 4; }
return r;    
}
//*****************************************************************************
unsigned char fm_stereo(void)                                   
{
unsigned char x;
tea5768_read();
x = (readdata[2] & TEA5767_STEREO_MASK);
return x ? 1 : 0;    
}
//*****************************************************************************
void send_freq(void)
{
if (valid_freq())
{
  senddata[0] = 0xB0;
  senddata[1] = 0x2A;
  senddata[2] = 0x00;
  senddata[3] = 0x1E;
  senddata[4] = 0x00;
  PLLfreq = 4 * ((freq * 10000) - 225000L) / 32768L;
  senddata[0] = ((PLLfreq >> 8) & 0x3F);
  senddata[1] = (PLLfreq & 0xFF);
  MUTE_OFF;
} else {
  MUTE_ON;
}
tea5768_write();
_delay_ms(60);
}
//*****************************************************************************
unsigned char valid_freq(void)
{
if ((freq < F_MIN) || (freq > F_MAX))
{ 
  return 0;
} else {
  return 1;
}
}
//*****************************************************************************
