


#define  battery_voltage_pin 21 // пин контроля напряжения батареи, A7
byte button_pin[] = {16,17,12,10}; // пин кнопок Fn RIT DOWN UP
byte led_pin[] = {6,8,13,18,14,19,5}; // пин индикатора A, B, C, D, E, F, G
float  RBand[]={22000,10000,2700,22000}; // резисторы диапазонов R1, R2, R3, R19
float  RUin[]={100000,22000}; // резисторы делителя напряжения питания  R33, R34


#define  band_pin 20 // пин переключателя диапазонов, A6

#define  mute_pin 7
#define  qsk_pin 11
#define  keying_pin 15
byte  dash_pin=1; // тире
byte  dot_pin=0; // точки
byte  man_pin=1;
int IF_mult;
#define  tone_pin 9 // самоконтроль

 #define SCLK 2      
 #define FSYNC 4    
 #define DATA 3  

#define  tone_Hz 650 // частота тона самоконтроля, Гц
#define  backlight_delay 3 //задержка выключения подсветки экрана, сек

byte step_mult = 5;
#define  step_size 50 // мин шаг настройки, Гц
#define  IFreq 4915200 // частота ПЧ, Гц

byte cw_speed = 20;
byte cw_delay;
int QSK_time = 50;
 
byte band;
byte band_prev;
byte bands_quantity=3;
byte buttons_quantity=4;
byte button_No = 0;
unsigned long button_delay=0;


double RIT_freq=0;

double band_frq[4] = {7017800, 10105000, 14020000};
double band_frq_limits[7] = {7000000, 10100000, 14000000,
                             7100000, 10150000, 14100000};

double frq;
double bat_v;
double freq_corr=268435456.00/(60000000.00-6*50.00);
unsigned long time=0;
unsigned long batt_time=0;
unsigned long TX_time=0;
unsigned long band_delay=0;
unsigned long wpm_delay=0;
unsigned long fn_delay=0;

boolean dash = false;
boolean dot = false;
boolean TX = false;
boolean RIT = false;
boolean RXTX = false;
boolean ATT = false;
boolean WPM = false;
boolean ELKEY = true;
boolean REVERSE = true;
boolean KEY_PRESSED = false;
boolean NOSHOW_FREQ = false;
boolean TUNE_MODE = false;


byte seven_seg_digits[22][7] = { 
 { 0,0,0,0,0,0,1 },  // = 0
 { 1,0,0,1,1,1,1 },  // = 1
 { 0,0,1,0,0,1,0 },  // = 2
 { 0,0,0,0,1,1,0 },  // = 3
 { 1,0,0,1,1,0,0 },  // = 4
 { 0,1,0,0,1,0,0 },  // = 5
 { 0,1,0,0,0,0,0 },  // = 6
 { 0,0,0,1,1,1,1 },  // = 7
 { 0,0,0,0,0,0,0 },  // = 8
 { 0,0,0,0,1,0,0 },  // = 9
 { 1,1,1,1,1,1,0 },   // = - 
 { 1,1,1,1,1,1,1 },   // = blank   
 { 1,1,1,1,1,0,1 },   // = rit +250-450 
 { 0,1,1,1,1,1,1 },   // = rit +500-950
 { 1,0,1,1,1,1,1 },   // = rit +1000-1500
 { 1,1,1,1,0,1,1 },   // = rit -250-450 
 { 1,1,1,0,1,1,1 },   // = rit -500-950
 { 1,1,0,1,1,1,1 },   // = rit +1000-1500
 { 1,1,1,1,1,0,0 },   // = rit +50-250  
 { 1,1,1,1,0,1,0 },   // = rit -50-250  
 { 0,0,0,1,0,0,0 },   // = A
 { 0,1,1,1,1,1,0 }    // = =
 
};


 
 #define pulse(pin) {digitalWrite(pin, LOW); digitalWrite(pin, HIGH); }

void setup() {
  
// Serial.begin(9600);

       


  
  cw_delay = 1200/cw_speed;
  pinMode(tone_pin, OUTPUT);
          
  pinMode(dash_pin, INPUT);
  digitalWrite(dash_pin, HIGH);
  pinMode(dot_pin, INPUT); 
  digitalWrite(dot_pin, HIGH);
  
  if (!digitalRead(dot_pin))
  {
    ELKEY = false;
  }
  else
  {
  if (!digitalRead(dash_pin)) 
  {
    REVERSE = !REVERSE;
  }
  
        if (REVERSE)
      {
    byte revtemp = dash_pin;
    dash_pin = dot_pin;
    dot_pin = revtemp;
//    man_pin = dash_pin; 
      }
      else
      {
//       man_pin = dot_pin;  
      }
  }
  
    
    
  
  
  pinMode(FSYNC, OUTPUT);
  pinMode(SCLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(mute_pin, OUTPUT);
  digitalWrite(mute_pin, HIGH);
  pinMode(qsk_pin, OUTPUT);
  digitalWrite(qsk_pin, HIGH);
  pinMode(keying_pin, OUTPUT);
  digitalWrite(keying_pin, LOW);
  
  digitalWrite(FSYNC, HIGH);
  digitalWrite(SCLK, HIGH);
  tfr_word(0x2108);
  tfr_word(0x2238);
    
  pinMode(battery_voltage_pin, INPUT);
  for (int  i=0; i < buttons_quantity; i++)
  {
  pinMode(button_pin[i], INPUT);
  digitalWrite(button_pin[i], HIGH);
  }
  for (int  i=0; i <= 7; i++)
  {
  pinMode(led_pin[i], OUTPUT);
    digitalWrite(led_pin[i], HIGH);
  }
  pinMode(band_pin, INPUT);
   

  band = check_band_pin();
  
  if (band_frq[band]<14000000)
  {IF_mult = 1;}
    else
  {IF_mult = -1;} 

  frq = band_frq[band]+IF_mult*IFreq;
  sendFrequency(frq+RIT*RIT_freq,TX);

             band_prev=band;
  //check_battery_voltage();


     

  
}


void clear_display()
{
    sevenSegWrite(11);
}

void display_RXTX()
{
  clear_display();
  sevenSegWrite(21);
}

  
void display_rit()
{
    clear_display();
    if (RIT_freq==0)
    {
    sevenSegWrite(0);
    }
    if (RIT_freq>49&&RIT_freq<250)
    {
    sevenSegWrite(18);
    }
    if (RIT_freq>249&&RIT_freq<450)
    {
    sevenSegWrite(12);
    }
    if (RIT_freq>449&&RIT_freq<950)
    {
    sevenSegWrite(13);
    }
    if (RIT_freq>949&&RIT_freq<1501)
    {
    sevenSegWrite(14);
    }   
    if (RIT_freq<-49&&RIT_freq>-250)
    {
    sevenSegWrite(19);
    }
    if (RIT_freq<-249&&RIT_freq>-450)
    {
    sevenSegWrite(15);
    }
    if (RIT_freq<-449&&RIT_freq>-950)
    {
    sevenSegWrite(16);
    }
    if (RIT_freq<-949&&RIT_freq>-1501)
    {
    sevenSegWrite(17);
    }      
}

void display_att()
{
      clear_display();
    sevenSegWrite(20);
}
void display_wpm()
{
      clear_display();
    sevenSegWrite(5);
}



/*
void display_elkey()
{
     lcd.setCursor ( 0, 1 );
    if (ELKEY)
    {
      lcd.print("  EL_KEY");
    }
     lcd.print(" MAN_KEY");
}  
*/

/*
void display_reverse()
{
     lcd.setCursor ( 0, 1 );
    if (REVERSE)
    {
     lcd.print(" REVERSE");
    }
     lcd.print("  NORMAL");
}  
*/
void  display_speed()
{
  clear_display();
  sevenSegWrite(cw_speed%10);
}
  
void display_bat(unsigned long bat_DISP)

{
    unsigned long bat_tmp = bat_DISP;
    clear_display();
    delay(500);    
    bat_DISP = bat_DISP/1000;
    if (bat_DISP!=0)
    {
    sevenSegWrite(bat_DISP);
    delay(750);
    clear_display();
    delay(100);
    }    
    bat_DISP = bat_tmp%1000;
    bat_DISP = bat_DISP/100;
    sevenSegWrite(bat_DISP);
    delay(750);
    sevenSegWrite(10);
    delay(750);  
    bat_DISP = bat_tmp%100;
    bat_DISP = bat_DISP/10;
    sevenSegWrite(bat_DISP);
    delay(750);
    bat_DISP = bat_tmp%10;
    bat_DISP = bat_DISP;
    sevenSegWrite(bat_DISP);
    delay(750);
    clear_display();  
}

void display_freq(unsigned long freq_DISP)
{
  
  freq_DISP = frq-IF_mult*IFreq;
    unsigned long freq_tmp = freq_DISP/100;
    clear_display();
    delay(500);    
    freq_DISP = freq_tmp%10000;
    freq_DISP = freq_DISP/1000;
    sevenSegWrite(freq_DISP);
    delay(750);
    clear_display();
    delay(100);    
    freq_DISP = freq_tmp%1000;
    freq_DISP = freq_DISP/100;
    sevenSegWrite(freq_DISP);
    delay(750);
    clear_display();
    delay(100);   
    freq_DISP = freq_tmp%100;
    freq_DISP = freq_DISP/10;
    sevenSegWrite(freq_DISP);
    delay(750); 
    sevenSegWrite(10);
    delay(750);        
    freq_DISP = freq_tmp%10;
//    freq_DISP = freq_DISP/1;
    sevenSegWrite(freq_DISP);
    delay(750);      
    clear_display();    
}


void tfr_word(word data)
{
  digitalWrite(FSYNC, LOW);
    for (int i=0; i<16; i++) {
    bool value=data & 0x8000;
    digitalWrite(DATA, value);
    data <<=1;
    data &=0xFFFF;
    pulse(SCLK);
  }
  digitalWrite(FSYNC, HIGH);
}

void sendFrequency(double frequency, boolean TX1) {
  
 
  if (TX1)
  {
    int32_t freq = (frequency-IF_mult*IFreq-RIT*RIT_freq)* freq_corr;
  word regLo=freq&0x3FFF;
  word regHi=freq>>14;
  regLo |=0x4000;
  regHi |=0x4000;
  
  tfr_word(0x2138);
  tfr_word(regLo);
  tfr_word(regHi);
  tfr_word(0xC000);
  tfr_word(0x2038);
  }
  
  else 
  {
  int32_t freq = (frequency-IF_mult*tone_Hz) * freq_corr;
  word regLo=freq&0x3FFF;
  word regHi=freq>>14;
  regLo |=0x4000;
  regHi |=0x4000;
  
  tfr_word(0x2118);
  tfr_word(regLo);
  tfr_word(regHi);
  tfr_word(0xC000);
  tfr_word(0x2018);
  }

}
  
  void check_paddle() {

if (ELKEY)
{
dash = digitalRead(dash_pin);
dot = digitalRead(dot_pin);
 if ((!dash)||(!dot))
 {
   TX = true; 

   digitalWrite(qsk_pin, LOW);   
   digitalWrite(mute_pin, LOW);

   sendFrequency(frq+RIT*RIT_freq,TX);

   TX_time = millis();
 }
 
 while ((millis()-TX_time)<QSK_time)
 
 {
 
if (!digitalRead(dash_pin)) //Тире
{ 

TX = true;
digitalWrite(keying_pin, HIGH);
tone(tone_pin, tone_Hz);
delay(3*cw_delay);
noTone(tone_pin);
digitalWrite(keying_pin, LOW);
TX_time = millis(); 
delay(cw_delay);

} 

if (!digitalRead(dot_pin)) //Точки
{ 
  dot=!dot;
TX = true;
digitalWrite(keying_pin, HIGH);
tone(tone_pin, tone_Hz);
delay(cw_delay);
noTone(tone_pin);
digitalWrite(keying_pin, LOW);
TX_time = millis(); 
delay(cw_delay);
} 
 }
 
 if (TX) 
 {
   TX = !TX;
     sendFrequency(frq+RIT*RIT_freq,TX);
     
     if (!ATT) 
     {
   digitalWrite(qsk_pin, HIGH);  
 }
   digitalWrite(mute_pin, HIGH);
 }


}
else
{
dot = digitalRead(man_pin);

 if (!dot)
 {
   TX = true; 
   digitalWrite(qsk_pin, LOW);   
   digitalWrite(mute_pin, LOW);

   sendFrequency(frq+RIT*RIT_freq,TX);

   TX_time = millis();
 }
 
 while ((millis()-TX_time)<QSK_time)
 
 {
 
dot = digitalRead(man_pin);

 if (!dot) //
{ 
if (!KEY_PRESSED)
{
TX = true;
KEY_PRESSED = true;
digitalWrite(keying_pin, HIGH);
tone(tone_pin, tone_Hz);
}
TX_time = millis();
}

else
{
if (KEY_PRESSED)
{
noTone(tone_pin);
digitalWrite(keying_pin, LOW);
KEY_PRESSED = false;
TX_time = millis();
}
}


 }
 
 if (TX) 
 {
   TX = !TX;
     sendFrequency(frq+RIT*RIT_freq,TX);
          if (!ATT) 
     {
   digitalWrite(qsk_pin, HIGH);   
        }
   digitalWrite(mute_pin, HIGH);     
 }



}

}

byte check_button_pin()

{
     
     for (byte i=0; i< buttons_quantity; i++)
     {
       
     int button_V = digitalRead(button_pin[i]);
     if (button_V==0)
     {
        return i+1;
     }
     }
     return 0;
}    



void check_button()

{
  byte temp_but = check_button_pin();
  
  boolean tone_ON = false;
  
  if (temp_but != 0)
  {
    button_No = temp_but;
    button_delay = millis();
    do
    {
      
       
    if (((millis() - button_delay)>1000))
    {
      if(!RXTX)
      {
        
       if (button_No == 1) // WPM
        {
          wpm_delay = millis();
         WPM = true;
         display_wpm();
        }
        
       if (button_No == 2) // ATT 
  { 
    button_delay = millis()-250;
    ATT = !ATT;
        if (ATT)
    {
      digitalWrite(qsk_pin, LOW);      
           if (RIT)
      {
        display_att();
        delay(300);
        display_rit();
      }
      else
      {
      display_att();
      }
      

    }
    else
    {
      digitalWrite(qsk_pin, HIGH);
      if (RIT)
      {
        display_att();
        delay(300);
        display_rit();
      }
      else
      {
       clear_display();
      }
          
    }
    
  }
      
  if (((button_No == 3)||(button_No == 4))&&(!RIT)&&(!WPM)) // step 
  {  
  if ((frq + (button_No*2-7)*step_size*2-IF_mult*IFreq)<band_frq_limits[band]||(frq + (button_No*2-7)*step_size*2-IF_mult*IFreq)>band_frq_limits[band+bands_quantity])
{
band_end_beep();
}
else
{
 frq = frq + (button_No*2-7)*step_size*2;
  sendFrequency(frq+RIT*RIT_freq,TX);
  delay(step_size*2);

}
  }
  
    }
  
  else
  
  {
        if (!tone_ON)
        {
digitalWrite(mute_pin, LOW);
tone(tone_pin, tone_Hz);
delay(cw_delay);
noTone(tone_pin);
digitalWrite(mute_pin, HIGH);
        tone_ON = true;
        }
  }
      
    }
    temp_but = check_button_pin();
    }
    while (temp_but!=0);
    button_delay = millis() - button_delay;
    
}
 
}



void band_end_beep()
{
digitalWrite(mute_pin, LOW);
tone(tone_pin, tone_Hz);
delay(cw_delay);
noTone(tone_pin);
delay(cw_delay);
tone(tone_pin, tone_Hz);
delay(cw_delay);
noTone(tone_pin);
digitalWrite(mute_pin, HIGH);
delay(10*cw_delay);
}

void process_button()
{
  if (((button_No == 1)&&(button_delay<250))) // frequency readout
  {     
        if (RIT)
    {
      RXTX=!RXTX;
      sendFrequency(frq+RIT*RIT_freq*(1-RXTX),TX);
      if (RXTX)
      {

        display_RXTX();
      }
      else
      {
        display_rit();
      }
     
    }
    else
    {
      fn_delay = millis();
      while((millis()-fn_delay)<500)
      {
      check_button();
        if (((button_No == 4)&&(button_delay<250)))
        {
          bat_v = analogRead(battery_voltage_pin)*5*(RUin[0]+RUin[1])/RUin[1]/1024;
//                 Serial.print(bat_v);
                 display_bat(bat_v*100);
                 NOSHOW_FREQ = true;
               fn_delay = fn_delay-750;
             }
                     if (((button_No == 3)&&(button_delay<250)))
        {
//                 Serial.print(111111);
                 TUNE_MODE = true;
                 NOSHOW_FREQ = true;
               fn_delay = fn_delay-750;
             }
      }
                 
      if (!NOSHOW_FREQ)
      {
    display_freq(frq);
      }
      else 
      {
        NOSHOW_FREQ = false;
      }
    }
  }
  
  if(!RXTX)
  {
  if (((button_No == 2)&&(button_delay<250))) // frequency readout
  {     
    RIT=!RIT;
       sendFrequency(frq+RIT*RIT_freq,TX);
    if (RIT)
    {
      display_rit();
    }
    else
    {
      if (ATT)
      {
        display_att();
      }
      else
      {
       clear_display();
      }
    }
  }
  
  if (((button_No == 3)||(button_No == 4))) // step down
  {  
    
    if(!WPM)
    {
    
    if(!RIT)
    {
  if ((frq + (button_No*2-7)*step_size-IF_mult*IFreq)<band_frq_limits[band]||(frq + (button_No*2-7)*step_size-IF_mult*IFreq)>band_frq_limits[band+bands_quantity])
{
band_end_beep();
}
else
{
 frq = frq + (button_No*2-7)*step_size;


}
    }
            
    else
    {
      if( ((button_No*2-7)*RIT_freq)<1500)
      {
       RIT_freq = RIT_freq + (button_No*2-7)*step_size;
             display_rit();

      }
    }
      sendFrequency(frq+RIT*RIT_freq,TX);
  }
  
  else
  {
    if ((millis()-wpm_delay)<1000)
    {
    wpm_delay = millis();  
    cw_speed=cw_speed + (button_No*2-7);
    display_speed();

    }

  }
  }
  }
     if (WPM)
     {
      if ((millis()-wpm_delay)>1000)
    {
      WPM = false;
      wpm_delay = 0;
      clear_display();
      cw_delay=1200/cw_speed;
    }
     }
 button_No = 0;
 button_delay = 0;
 
}


byte check_band_pin()

{
  while(band<bands_quantity)
  {
     float band_V = analogRead(band_pin);
     
     for (byte i=0; i< bands_quantity; i++)
     {
       if ( (band_V < (1023*RBand[i]/(RBand[i]+RBand[bands_quantity])+25))&&(band_V > (1023*RBand[i]/(RBand[i]+RBand[bands_quantity])-25)))
     {
       
               
       return i;
     }
     }
     
//     return band;
  }
     
} 

void check_band()
  {
    
    byte itemp = check_band_pin();
    


        if (itemp!=band)
        {
          band_delay=millis();

          band=itemp;

            
        }

       if (((millis()-band_delay)>500)&&(band_delay!=0))
  {
                        
  band_frq[band_prev] = frq - IF_mult*IFreq;
    band_delay = 0;
  if (band_frq[band]<14000000)
  {IF_mult = 1;}
    else
  {IF_mult = -1;} 
  frq = band_frq[band]+IF_mult*IFreq;
    RIT_freq=0;
    RIT = false;
   
    sendFrequency(frq,TX);

  display_freq(frq);
  band_prev=band;

  } 
  }
  
  void sevenSegWrite(byte digit) {
  byte pin = 0;
  for (byte segCount = 0; segCount < 7; ++segCount) {
    digitalWrite(led_pin[pin], seven_seg_digits[digit][segCount]);
    ++pin;
  }
  }
  
  
  
  
void loop() 
{
check_band();
check_paddle();
check_button();
process_button();
check_paddle();
}
