#include <Wire.h>
#include <U8g2lib.h>
#include <ClickEncoder.h>
#include <TimerOne.h>

int inled = 13; // internal led
int rel1 = 24;  // +-15V PS switch for LV amp
int rel2 = 25;  // PS for digital part of D/A switch
int rel3 = 36;  // left differential signal switch 
int rel4 = 35;  // right differential signal switch 
int rel5 = 34;  // SE signal switch
int rel6 = 40;  // HV trafo swtich
int rel7 = 44;  // LV trafo switch

int vol1;
int volr;
int reg18val;
int val = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;
int val5 = 0;
int atten;

int FA0 = 10;
int FA1 = 11;
int FA2 = 12;
int valFA0 = 0;
int valFA1 = 0;
int valFA2 = 0;
int volume = 0;
int vybermenu;
int defStav;  //vychozi stav enkoderu
int enkStav;  //aktualni stav enkoderu
int tlcStav;  //stav tlacitka enkoderu
int DT = 19; // DT pin enkoderu
int CLK = 18;  // CLK pin enkoderu
int SW = 16; // SW pin enkoderu(tlacitko)
int krok = 1; // nastaveni rychlosti cteni enkoderu
ClickEncoder encoder(DT, CLK, SW, krok); // inicializace enkoderu

int DCLK = 30;
int DDATA = 31;
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, DCLK, DDATA, U8X8_PIN_NONE); // inicializace displaye

int DSD1794 = 0x4c; // adresa D/A prevodniku
#define  reg16 0x10 // adresa registru hlasitosti pro levy kanal
#define  reg17 0x11 // adresa registru hlasitosti pro pravy kanal
#define  reg18 0x12 // adresa registru 18

void setup()
  {       
   Timer1.initialize(1000);
   Timer1.attachInterrupt(timerIsr);
   encoder.setAccelerationEnabled(true);
   defStav = -1;
   
   pinMode(inled, OUTPUT);      
   pinMode(rel1, OUTPUT);
   pinMode(rel2, OUTPUT);
   pinMode(rel3, OUTPUT);
   pinMode(rel4, OUTPUT);
   pinMode(rel5, OUTPUT);
   pinMode(rel6, OUTPUT);
   pinMode(rel7, OUTPUT);
   pinMode(FA0, INPUT);
   pinMode(FA1, INPUT);
   pinMode(FA2, INPUT);
   Wire.begin();
   u8g2.begin();
   }

// Ovladani a vycitani z registru DA prevodniku
//----------------------------------------------------------------------------
void attenuation_load_control()  //zapne možnost ovladani vnitrniho attenuatoru
  { Wire.beginTransmission(DSD1794); //zahajeni komunikace s prevodnikem
    Wire.write(reg18); //vyber registru
    Wire.write(0xD0);  // zapis do registru
    Wire.endTransmission(); } //ukonceni komunikace s prevodnikem
  
void attenuation_load_control2()  //vypne možnost ovladani vnitrniho attenuatoru
  { Wire.beginTransmission(DSD1794);
    Wire.write(reg18); 
    Wire.write(0x50);
    Wire.endTransmission(); }
  
void attenuation_left_channel_control() //zmena hodnoty attenuatoru 
  { Wire.beginTransmission(DSD1794);
    Wire.write(reg16); 
    Wire.write(atten);
    Wire.endTransmission(); }
  
void attenuation_rght_channel_control()  //zmena hodnoty attenuatoru 
  { Wire.beginTransmission(DSD1794);
    Wire.write(reg17); 
    Wire.write(atten);
    Wire.endTransmission(); }
    
void attenuation_left_channel_mute() //zmena hodnoty attenuatoru 
  { Wire.beginTransmission(DSD1794);
    Wire.write(reg16); 
    Wire.write(0);
    Wire.endTransmission(); }
  
void attenuation_rght_channel_mute()  //zmena hodnoty attenuatoru 
  { Wire.beginTransmission(DSD1794);
    Wire.write(reg17); 
    Wire.write(0);
    Wire.endTransmission(); }

void reg16_read() // vycteni registru 16 do teminalu
{ Wire.beginTransmission(DSD1794);
  Wire.write(reg16);
  Wire.endTransmission();
  Wire.requestFrom(DSD1794,1); 
  vol1 = Wire.read();
}

void reg17_read()  // vycteni registru 17 do teminalu
{ Wire.beginTransmission(DSD1794);
  Wire.write(reg17);
  Wire.endTransmission();
  Wire.requestFrom(DSD1794,1); 
  volr = Wire.read();
}

void reg18_read()  // vycteni registru 18 do teminalu
{ Wire.beginTransmission(DSD1794);
  Wire.write(reg18);
  Wire.endTransmission();
  Wire.requestFrom(DSD1794,1); 
  reg18val = Wire.read();
 }
//----------------------------------------------------------------------------
void power_on()  // zapnuti napajeni
{
  delay(200); 
  digitalWrite(inled, HIGH);
}
void frekvence()
{
  valFA0 = digitalRead(FA0);
  valFA1 = digitalRead(FA1);
  valFA2 = digitalRead(FA2);
  u8g2.setFont(u8g2_font_helvB14_tr);
  if(valFA2 == HIGH && valFA1 == HIGH && valFA0 ==HIGH)
    {
     u8g2.drawStr( 0,60 , "44.1kHz");
    }
  if(valFA2 == HIGH && valFA1 == HIGH && valFA0 ==LOW)
    {
     u8g2.drawStr( 0,60 , "48kHz");
    }
  if(valFA2 == HIGH && valFA1 == LOW && valFA0 ==HIGH)
    {
     u8g2.drawStr( 0,60 , "88,2kHz");
    }
  if(valFA2 == HIGH && valFA1 == LOW && valFA0 ==LOW)
    {
     u8g2.drawStr( 0,60 , "96kHz");
    }
  if(valFA2 == LOW && valFA1 == HIGH && valFA0 ==HIGH)
    {
     u8g2.drawStr( 0,60 , "176,4kHz");
    }
  if(valFA2 == LOW && valFA1 == HIGH && valFA0 ==LOW)
    {
     u8g2.drawStr( 0,60 , "192kHz");
    }
  }

void da_mute()
{
  attenuation_load_control();
  attenuation_left_channel_mute();
  attenuation_rght_channel_mute();
  reg16_read();
  reg17_read();
  if( vol1 == 0 && volr ==0)
  {val4++; }  
  else
  {
  attenuation_load_control();
  attenuation_left_channel_mute();
  attenuation_rght_channel_mute(); 
  }
}

void timerIsr() 
  { encoder.service(); }

//funkce pro vykreslovani na displayi
//----------------------------------------------------------------------------
void ovladani_hlasitosti_display()  //vykresleni obrazovky pro regulaci hlasitosti
  {
    if (val5 < 1)
    {
    u8g2.firstPage(); 
      do {u8g2.setFont(u8g2_font_helvB08_tr);
          char buf[3];
          u8g2.setFont(u8g2_font_fub30_tr);
          sprintf (buf, "%d", volume);
          u8g2.drawStr(80, 55, buf);
          frekvence();}
          while( u8g2.nextPage() );
        val++;
          }
          char buf[3];
          sprintf (buf, "%d", volume);
          u8g2.drawStr(80, 55, buf);
          frekvence();
          }

void uvodni_obrazovka() //vykresleni uvodni obrazovky
  {
         digitalWrite(rel1, LOW);
         digitalWrite(rel2, LOW);
         digitalWrite(rel3, LOW);
         digitalWrite(rel4, LOW);
         digitalWrite(rel5, LOW);
         digitalWrite(rel6, LOW);
         digitalWrite(rel7, LOW);
         val2 = 0;
         val4 = 0;
         enkStav = 1; 
         volume = 0;}
//----------------------------------------------------------------------------

void tlacitko_enkoderu()  //funkce pro vycteni stavu tlacitka enkoderu
  {tlcStav = encoder.getButton();
      if (tlcStav != 0) 
         {switch (tlcStav) 
            {case ClickEncoder::Open:          //0
             break;
             case ClickEncoder::Closed:        //1
             break;
             case ClickEncoder::Pressed:       //2
             break;
             case ClickEncoder::Held:          //3
             break;
             case ClickEncoder::Released:      //4
             break;
             case ClickEncoder::Clicked:       //5
             break;
             case ClickEncoder::DoubleClicked: //6
             break; }}}

void hlasitost() // funkce ovladani hlasitosti enkoderem
{ 
  
  
  enkStav += encoder.getValue(); //porovnani hodnoty enkoderu a vyhodnoceni
  if (enkStav != defStav)   // pokud je nova hodnota jina, zapise se tato hodnota jako vychozi    
     {defStav = enkStav;
      
      if (enkStav >= 51) //omezeni maximalni hodnoty na 51
         { enkStav = 51;
           atten = 255;}
      if (enkStav <= 16) //omezeni minimalni hodnoty na 1
         {enkStav = 16; }
      atten = enkStav * 5; 
      volume = enkStav - 16;    
      attenuation_left_channel_control();   //zapsani hodnoty enkoderu do registru
      attenuation_rght_channel_control(); }
   ovladani_hlasitosti_display(); 
   tlacitko_enkoderu();
   if (tlcStav == 5) //pokud je tlacitko enkoderu jendou zmacknuto, display se vrati o uroven nize
      {uvodni_obrazovka();}}

void loop() //hlavni smyčka
  {if (val < 1)   //zapnuti napajení při startu zařízení
      {power_on();
       val++; }

   if (val2 < 1)  //prepnuti na ovladani hlasitosti
       { enkStav += encoder.getValue();
  if (enkStav != defStav) 
    { defStav = enkStav;
      if (enkStav >= 5) 
         { enkStav = 5;}
      if (enkStav <= 1) 
         {enkStav = 1; }     
       vybermenu = enkStav;
    }
    
      if (vybermenu == 1)
    {
     u8g2.firstPage(); 
     do {
          u8g2.setFont(u8g2_font_helvB10_tr);
          u8g2.drawStr( 20,40 , "DAC Line Out");
        } 
     while( u8g2.nextPage() );

      
      }
    if (vybermenu == 2)
    {
      u8g2.firstPage(); 
     do {
          u8g2.setFont(u8g2_font_helvB10_tr);
          u8g2.drawStr( 20,40 , "HV ext");
        } 
     while( u8g2.nextPage() );
      }
      if (vybermenu == 3)
    {
      u8g2.firstPage(); 
     do {
          u8g2.setFont(u8g2_font_helvB10_tr);
          u8g2.drawStr( 20,40 , "HV + DAC");
        } 
     while( u8g2.nextPage() );
      }
      if (vybermenu == 4)
    {
      u8g2.firstPage(); 
     do {
          u8g2.setFont(u8g2_font_helvB10_tr);
          u8g2.drawStr( 20,40 , "LV ext");
        } 
     while( u8g2.nextPage() );
      }
       if (vybermenu == 5)
    {
      u8g2.firstPage(); 
     do {
          u8g2.setFont(u8g2_font_helvB10_tr);
          u8g2.drawStr( 20,40 , "LV + DAC");
        } 
     while( u8g2.nextPage() );
      }
      {tlacitko_enkoderu();
       if (tlcStav == 5)
          { 
           val2++;  } }}
   if (val2 > 0)
      {

    if(vybermenu ==1)
    {
    digitalWrite(rel2, HIGH);
    delay(500);
    digitalWrite(rel7, HIGH);
    delay(10);
    if (val4 < 1)
    {
      da_mute();
      }
    hlasitost();
    }
    
     
     if(vybermenu ==2)
    {  
    u8g2.firstPage(); 
     do {
          u8g2.setFont(u8g2_font_helvB10_tr);
          u8g2.drawStr( 20,40 , "High voltage amp");
          u8g2.drawStr( 20,50 , "External input");
        } 
     while( u8g2.nextPage() );
     digitalWrite(rel6, HIGH);
    delay(100);
      tlacitko_enkoderu();
     
    if (tlcStav == 5)
    { 
    val2 = 0;
    enkStav = 1;
    volume = 0;
    } 
    }
     if(vybermenu ==3)
    {
    digitalWrite(rel6, HIGH);
    delay(500);
    digitalWrite(rel2, HIGH);
    delay(500);
    digitalWrite(rel7, HIGH);
    delay(500);
    digitalWrite(rel3, HIGH);
    digitalWrite(rel4, HIGH);
    if (val4 < 1)
    {
      da_mute();
      enkStav = 31;
     }
   
    hlasitost();
      delay(1000);
    digitalWrite(rel6, HIGH);
    }
     if(vybermenu ==4)
    {
     u8g2.firstPage(); 
     do {
          u8g2.setFont(u8g2_font_helvB10_tr);
          u8g2.drawStr( 20,40 , "Low voltage amp");
          u8g2.drawStr( 20,50 , "External input");
        } 
     while( u8g2.nextPage() );
      digitalWrite(rel1, HIGH);
    delay(500);
    digitalWrite(rel7, HIGH);
    delay(500); 
     tlacitko_enkoderu();
    if (tlcStav == 5)
    { val2 = 0;
    enkStav = 1;
    volume = 0;
    }
    }
     if(vybermenu ==5)
    {
    digitalWrite(rel1, HIGH);
    delay(500);
    digitalWrite(rel2, HIGH);
    delay(500);
    digitalWrite(rel7, HIGH);
    delay(500);
    digitalWrite(rel5, HIGH);
    if (val4 < 1)
    {da_mute();}
    hlasitost();
    }      
      }
    
}
 
