1

Тема: CS8416 + WM8740

http://forum.rcl-radio.ru/uploads/images/2020/11/f2faf7cf7f5c16bb57b1180c10db8e88.gif

http://forum.rcl-radio.ru/uploads/images/2020/11/666199386da3f0c876aefebf56d2451f.png

http://forum.rcl-radio.ru/uploads/images/2020/11/81575965e8ef2ab009c4bed6df5311b9.png

http://forum.rcl-radio.ru/uploads/images/2020/11/e00f036e96149af2b310a17810188382.png

http://forum.rcl-radio.ru/uploads/images/2020/11/8353e79c73694052af0e7050836b2fec.png

#define CS   2  // ML WM8740
#define CLK  3  // MC WM8740
#define DATA 4  // MD WM8740

#include <Wire.h> 
#include <EEPROM.h>
#include <Encoder.h>  // https://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // https://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> //Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 Encoder myEnc(9, 8);//CLK, DT
      byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};
      byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};      
      byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};
      byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};
      byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};
      byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};
      int a[3],vol,vol_d,menu,in,dem,form;
      byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
      unsigned long times,times1,oldPosition  = -999,newPosition;
      bool w,w1,www=1,mute;
      byte rol,dac_i2s,dac_iw,dem_res,for_dac,for_res,err,err_old;

void setup(){
   Wire.begin();
   Serial.begin(9600);
   MsTimer2::set(1, to_Timer);MsTimer2::start();
   lcd.init();lcd.backlight();
   lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
   pinMode(10,INPUT);   // SW энкодер
   pinMode(11,INPUT_PULLUP); // кнопка MUTE      
   pinMode(CS,OUTPUT);  // ML WM8740
   pinMode(CLK,OUTPUT); // MC WM8740
   pinMode(DATA,OUTPUT);// MD WM8740
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
  vol = EEPROM.read(0);in = EEPROM.read(1);dem_res = EEPROM.read(3);for_dac = EEPROM.read(4);for_res = EEPROM.read(5);
  dac_i2s = EEPROM.read(6);dac_iw = EEPROM.read(7);rol = EEPROM.read(8);
   lcd.setCursor(0,0);lcd.print(" CS8416  WM8740 ");
   lcd.setCursor(0,1);lcd.print(" 24 bit  192kHz ");
  // Write WM8740 SPI
  wireWrite(0b000100000000);//reg0
  wireWrite(0b001100000000);//reg1
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  wireWrite(0b110000000000);//reg4
// Write 8416 I2C
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(2000);lcd.clear();
  // Write WM8740 SPI
  wireWrite(0b000100000000 + vol);//reg0
  wireWrite(0b001100000000 + vol);//reg1
  }

void loop(){ 
 /// MENU //////////////////////////////
  if(digitalRead(10)==LOW){menu++;if(menu>4){menu=0;};delay(200);lcd.clear();times=millis();w=1;w1=1;www=1;}
 /// MUTE /////////////////////////////
 if(digitalRead(11)==LOW && mute==0){mute=1; wireWrite(0b010000000001 + (dac_iw << 3));delay(300);www=1;} 
 if(digitalRead(11)==LOW && mute==1){mute=0; wireWrite(0b010000000000 + (dac_iw << 3));delay(300);www=1;} 
  
   if(menu==0){
  if (newPosition != oldPosition){oldPosition = newPosition;www=0;
     vol=vol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(vol<155){vol=155;}if(vol>255){vol=255;}
    wireWrite(0b000100000000 + vol);//reg0
    wireWrite(0b001100000000 + vol);//reg1
    Serial.println(vol);// vol = 155...255 step 0.5 dB
  }
  if(www==1||w==1){www=0;w=0;
      if(mute==1){         lcd.setCursor(0,0);lcd.print("MUTE    ");}
      if(err==0&&mute==0){ lcd.setCursor(0,0);lcd.print("VOLUME  ");}
      if(err==22&&mute==0){lcd.setCursor(0,0);lcd.print("ERROR   ");}
      if(err==8&&mute==0){ lcd.setCursor(0,0);lcd.print("NO SOUND");}
 
      lcd.setCursor(0,1);lcd.print("COAX ");lcd.print(in);
     vol_d=vol-156;a[0]=vol_d/10;a[1]=vol_d%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 //////// INPUT ////////////////////////////////////  
  if(menu==1){
    if (newPosition != oldPosition){oldPosition = newPosition;
     in=in-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(in<0){in=0;}if(in>7){in=7;}
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();}
  delay(10);
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("INPUT SELECTOR");  
  lcd.setCursor(0,1);lcd.print("COAXIAL "); lcd.print(in);lcd.print(" ");
  }}
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// DE-EMPHASIS //////////////////////////////////
  if(menu==2){
    if (newPosition != oldPosition){oldPosition = newPosition;
     dem=dem-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(dem<0){dem=0;}if(dem>3){dem=3;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("DE-EMPHASIS SEL");  
  lcd.setCursor(0,1);
  switch(dem){
  case 0: lcd.print("No De-emphasis");dem_res=0;break;
  case 1: lcd.print("44.1 kHz      ");dem_res=2;break;
  case 2: lcd.print("48.0 kHz      ");dem_res=3;break;
  case 3: lcd.print("32.0 kHz      ");dem_res=1;break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ///  FILTER ROLL-OFF //////////////////////////////////
  if(menu==3){
    if (newPosition != oldPosition){oldPosition = newPosition;
     rol=rol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(rol<0){rol=0;}if(rol>1){rol=1;}
      
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("ROLL-OFF SELECT ");  
  lcd.setCursor(0,1);
  switch(rol){
  case 0: lcd.print("Sharp");break;
  case 1: lcd.print("Slow ");break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// Serial Format Select //////////////////////////////////
  if(menu==4){
    if (newPosition != oldPosition){oldPosition = newPosition;
     form=form-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
     if(form<0){form=0;}if(form>2){form=2;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("FORMAT SELECT");  
  lcd.setCursor(0,1);
  switch(form){
  case 0: lcd.print("L-Just 24 bit");dac_i2s=0;dac_iw=3;for_res=0;break;
  case 1: lcd.print("I2S    24 bit");dac_i2s=1;dac_iw=1;for_res=5;break;
  case 2: lcd.print("R-Just 24 bit");dac_i2s=0;dac_iw=2;for_res=8;break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////

  /// read registr error 
  if(millis()-times1>1000){times1=millis();err = wireRead(0x10,0x0C);delay(10);}
  if(err!=err_old){err_old = err;www=1;}       
  /// EEPROM write
  if(millis()-times>10000 && w1==1){w1=0;EEPROM.update(0,vol);EEPROM.update(1,in);
  EEPROM.update(3,dem_res);EEPROM.update(4,for_dac);EEPROM.update(5,for_res);
  EEPROM.update(6,dac_i2s);EEPROM.update(7,dac_iw);EEPROM.update(8,rol);
  menu=0;www=1;if(menu!=0){lcd.clear();}}
  delay(100);
  }// loop  

void wireWrite(int data){        // SPI
  digitalWrite(CLK,HIGH);digitalWrite(CS,HIGH);delay(1);
     for(int i = 15; i >= 0; i--){
        digitalWrite(CLK,LOW);
        digitalWrite(DATA, (data >> i) & 0x01);delay(1);
        digitalWrite(CLK,HIGH);delay(1);}
  digitalWrite(CS,LOW);delay(1);digitalWrite(CS,HIGH);
  }

byte wireRead(int addr, int reg){ // I2C
  Wire.beginTransmission(addr);
  Wire.write (reg);
  Wire.endTransmission();
  delay(10);
  Wire.requestFrom(addr,1);
  while(Wire.available()<1);
  byte value = Wire.read();
  return value;
  }  

void to_Timer(){newPosition = myEnc.read()/4;}  

2

Re: CS8416 + WM8740

Добавлен баланс +/- 5 дБ (шаг регулировки 0,5 дБ)

http://forum.rcl-radio.ru/uploads/images/2020/11/cd3607005cf79ebf3bbfd8da92035c08.png
http://forum.rcl-radio.ru/uploads/images/2020/11/95c12cc331d90318eb72c1023c641304.png
http://forum.rcl-radio.ru/uploads/images/2020/11/28b02aef70f5497e5d6f865100d30955.png

#define CS   2  // ML WM8740
#define CLK  3  // MC WM8740
#define DATA 4  // MD WM8740

#include <Wire.h> 
#include <EEPROM.h>
#include <Encoder.h>  // https://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // https://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> //Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 Encoder myEnc(9, 8);//CLK, DT
      byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};
      byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};      
      byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};
      byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};
      byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};
      byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};
      int a[3],vol,vol_d,menu,in,dem,form,ball,rol;
      byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
      unsigned long times,times1,oldPosition  = -999,newPosition;
      bool w,w1,www=1,mute;
      byte dac_i2s,dac_iw,dem_res,for_dac,for_res,err,err_old;

void setup(){
   Wire.begin();
   Serial.begin(9600);
   MsTimer2::set(1, to_Timer);MsTimer2::start();
   lcd.init();lcd.backlight();
   lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
   pinMode(10,INPUT);   // SW энкодер
   pinMode(11,INPUT_PULLUP); // кнопка MUTE      
   pinMode(CS,OUTPUT);  // ML WM8740
   pinMode(CLK,OUTPUT); // MC WM8740
   pinMode(DATA,OUTPUT);// MD WM8740
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
  vol = EEPROM.read(0);in = EEPROM.read(1);dem_res = EEPROM.read(3);for_dac = EEPROM.read(4);for_res = EEPROM.read(5);
  dac_i2s = EEPROM.read(6);dac_iw = EEPROM.read(7);rol = EEPROM.read(8);ball = EEPROM.read(9)-10;
   lcd.setCursor(0,0);lcd.print(" CS8416  WM8740 ");
   lcd.setCursor(0,1);lcd.print(" 24 bit  192kHz ");
  // Write WM8740 SPI
  wireWrite(0b000100000000);//reg0
  wireWrite(0b001100000000);//reg1
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  wireWrite(0b110000000000);//reg4
// Write 8416 I2C
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(200);lcd.clear();
  // Write WM8740 SPI
   wireWrite(0b000100000000 + vol+10 + ball);//reg0
   wireWrite(0b001100000000 + vol+10 - ball);//reg1
  }

void loop(){ 
 /// MENU //////////////////////////////
  if(digitalRead(10)==LOW){menu++;if(menu>5){menu=0;};delay(200);lcd.clear();times=millis();w=1;w1=1;www=1;}
 /// MUTE /////////////////////////////
 if(digitalRead(11)==LOW && mute==0){mute=1; wireWrite(0b010000000001 + (dac_iw << 3));delay(300);www=1;} 
 if(digitalRead(11)==LOW && mute==1){mute=0; wireWrite(0b010000000000 + (dac_iw << 3));delay(300);www=1;} 

 /// VOLUME /////////////////////////////////// 
   if(menu==0){
  if (newPosition != oldPosition){oldPosition = newPosition;www=0;
     vol=vol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(vol<145){vol=145;}if(vol>245){vol=245;}
    wireWrite(0b000100000000 + vol+10 + ball);//reg0
    wireWrite(0b001100000000 + vol+10 - ball);//reg1
    Serial.println(vol);// vol = 145...245 step 0.5 dB + 10 balance
  }
  if(www==1||w==1){www=0;w=0;
      if(mute==1){         lcd.setCursor(0,0);lcd.print("MUTE    ");}
      if(err==0&&mute==0){ lcd.setCursor(0,0);lcd.print("VOLUME  ");}
      if(err==22&&mute==0){lcd.setCursor(0,0);lcd.print("ERROR   ");}
      if(err==8&&mute==0){ lcd.setCursor(0,0);lcd.print("NO SOUND");}
 
      lcd.setCursor(0,1);lcd.print("COAX ");lcd.print(in);
     vol_d=vol-156;a[0]=vol_d/10;a[1]=vol_d%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 /// BALANCE ////////////////////////////
   if(menu==1){
  if (newPosition != oldPosition){oldPosition = newPosition;www=0;
     ball=ball-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(ball<-10){ball=-10;}if(ball>10){ball=10;}
    wireWrite(0b000100000000 + vol+10 + ball);//reg0
    wireWrite(0b001100000000 + vol+10 - ball);//reg1
    Serial.println(ball);
  }
  if(www==1||w==1){www=0;w=0;
      if(ball<0){lcd.setCursor(8,1);lcd.write((uint8_t)0);
                 lcd.setCursor(0,1);lcd.print("L > R");}                
      if(ball>0){lcd.setCursor(8,1);lcd.print(" ");
                 lcd.setCursor(0,1);lcd.print("L < R");}
     if(ball==0){lcd.setCursor(8,1);lcd.print(" ");
                 lcd.setCursor(0,1);lcd.print("L = R");}
      lcd.setCursor(0,0);lcd.print("BALANCE ");

      a[0]=abs(ball)/10;a[1]=abs(ball)%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}

 //////// INPUT ////////////////////////////////////  
  if(menu==2){
    if (newPosition != oldPosition){oldPosition = newPosition;
     in=in-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(in<0){in=0;}if(in>7){in=7;}
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();}
  delay(10);
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("INPUT SELECTOR");  
  lcd.setCursor(0,1);lcd.print("COAXIAL "); lcd.print(in);lcd.print(" ");
  }}
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// DE-EMPHASIS //////////////////////////////////
  if(menu==3){
    if (newPosition != oldPosition){oldPosition = newPosition;
     dem=dem-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(dem<0){dem=0;}if(dem>3){dem=3;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("DE-EMPHASIS SEL");  
  lcd.setCursor(0,1);
  switch(dem){
  case 0: lcd.print("No De-emphasis");dem_res=0;break;
  case 1: lcd.print("44.1 kHz      ");dem_res=2;break;
  case 2: lcd.print("48.0 kHz      ");dem_res=3;break;
  case 3: lcd.print("32.0 kHz      ");dem_res=1;break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ///  FILTER ROLL-OFF //////////////////////////////////
  if(menu==4){
    if (newPosition != oldPosition){oldPosition = newPosition;
     rol=rol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(rol<0){rol=1;}if(rol>1){rol=0;}
      
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("ROLL-OFF SELECT ");  
  lcd.setCursor(0,1);
  switch(rol){
  case 0: lcd.print("Sharp");break;
  case 1: lcd.print("Slow ");break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// Serial Format Select //////////////////////////////////
  if(menu==5){
    if (newPosition != oldPosition){oldPosition = newPosition;
     form=form-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
     if(form<0){form=0;}if(form>2){form=2;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("FORMAT SELECT");  
  lcd.setCursor(0,1);
  switch(form){
  case 0: lcd.print("L-Just 24 bit");dac_i2s=0;dac_iw=3;for_res=0;break;
  case 1: lcd.print("I2S    24 bit");dac_i2s=1;dac_iw=1;for_res=5;break;
  case 2: lcd.print("R-Just 24 bit");dac_i2s=0;dac_iw=2;for_res=8;break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////

  /// read registr error 
  if(millis()-times1>1000){times1=millis();err = wireRead(0x10,0x0C);delay(10);}
  if(err!=err_old){err_old = err;www=1;}       
  /// EEPROM write
  if(millis()-times>10000 && w1==1){w1=0;EEPROM.update(0,vol);EEPROM.update(1,in);
  EEPROM.update(3,dem_res);EEPROM.update(4,for_dac);EEPROM.update(5,for_res);
  EEPROM.update(6,dac_i2s);EEPROM.update(7,dac_iw);EEPROM.update(8,rol);EEPROM.update(9,ball+10);
  www=1;if(menu!=0){lcd.clear();}menu=0;}
  delay(100);
  }// loop  

void wireWrite(int data){        // SPI
  digitalWrite(CLK,HIGH);digitalWrite(CS,HIGH);delay(1);
     for(int i = 15; i >= 0; i--){
        digitalWrite(CLK,LOW);
        digitalWrite(DATA, (data >> i) & 0x01);delay(1);
        digitalWrite(CLK,HIGH);delay(1);}
  digitalWrite(CS,LOW);delay(1);digitalWrite(CS,HIGH);
  }

byte wireRead(int addr, int reg){ // I2C
  Wire.beginTransmission(addr);
  Wire.write (reg);
  Wire.endTransmission();
  delay(10);
  Wire.requestFrom(addr,1);
  while(Wire.available()<1);
  byte value = Wire.read();
  return value;
  }  

void to_Timer(){newPosition = myEnc.read()/4;}  

3

Re: CS8416 + WM8740

Добавлен список поддерживаемых входных форматов:

  • L-Just 24 bit

  • I2S    24 bit

  • R-Just 24 bit

  • L-Just 20 bit

  • I2S    20 bit

  • I2S    16 bit

#define CS   2  // ML WM8740
#define CLK  3  // MC WM8740
#define DATA 4  // MD WM8740

#include <Wire.h> 
#include <EEPROM.h>
#include <Encoder.h>  // https://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // https://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> //Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 Encoder myEnc(9, 8);//CLK, DT
      byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};
      byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};      
      byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};
      byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};
      byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};
      byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};
      int a[3],vol,vol_d,menu,in,dem,form,ball,rol;
      byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
      unsigned long times,times1,oldPosition  = -999,newPosition;
      bool w,w1,www=1,mute;
      byte dac_i2s,dac_iw,dem_res,for_dac,for_res,err,err_old;

void setup(){
   Wire.begin();
   Serial.begin(9600);
   MsTimer2::set(1, to_Timer);MsTimer2::start();
   lcd.init();lcd.backlight();
   lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
   pinMode(10,INPUT);   // SW энкодер
   pinMode(11,INPUT_PULLUP); // кнопка MUTE      
   pinMode(CS,OUTPUT);  // ML WM8740
   pinMode(CLK,OUTPUT); // MC WM8740
   pinMode(DATA,OUTPUT);// MD WM8740
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
  vol = EEPROM.read(0);in = EEPROM.read(1);dem_res = EEPROM.read(3);for_dac = EEPROM.read(4);for_res = EEPROM.read(5);
  dac_i2s = EEPROM.read(6);dac_iw = EEPROM.read(7);rol = EEPROM.read(8);ball = EEPROM.read(9)-10;
   lcd.setCursor(0,0);lcd.print(" CS8416  WM8740 ");
   lcd.setCursor(0,1);lcd.print(" 24 bit  192kHz ");
  // Write WM8740 SPI
  wireWrite(0b000100000000);//reg0
  wireWrite(0b001100000000);//reg1
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  wireWrite(0b110000000000);//reg4
// Write 8416 I2C
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(200);lcd.clear();
  // Write WM8740 SPI
   wireWrite(0b000100000000 + vol+10 + ball);//reg0
   wireWrite(0b001100000000 + vol+10 - ball);//reg1
  }

void loop(){ 
 /// MENU //////////////////////////////
  if(digitalRead(10)==LOW){menu++;if(menu>5){menu=0;};delay(200);lcd.clear();times=millis();w=1;w1=1;www=1;}
 /// MUTE /////////////////////////////
 if(digitalRead(11)==LOW && mute==0){mute=1; wireWrite(0b010000000001 + (dac_iw << 3));delay(300);www=1;} 
 if(digitalRead(11)==LOW && mute==1){mute=0; wireWrite(0b010000000000 + (dac_iw << 3));delay(300);www=1;} 

 /// VOLUME /////////////////////////////////// 
   if(menu==0){
  if (newPosition != oldPosition){oldPosition = newPosition;www=0;
     vol=vol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(vol<145){vol=145;}if(vol>245){vol=245;}
    wireWrite(0b000100000000 + vol+10 + ball);//reg0
    wireWrite(0b001100000000 + vol+10 - ball);//reg1
    Serial.println(vol);// vol = 145...245 step 0.5 dB + 10 balance
  }
  if(www==1||w==1){www=0;w=0;
      if(mute==1){         lcd.setCursor(0,0);lcd.print("MUTE    ");}
      if(err==0&&mute==0){ lcd.setCursor(0,0);lcd.print("VOLUME  ");}
      if(err==22&&mute==0){lcd.setCursor(0,0);lcd.print("ERROR   ");}
      if(err==8&&mute==0){ lcd.setCursor(0,0);lcd.print("NO SOUND");}
 
      lcd.setCursor(0,1);lcd.print("COAX ");lcd.print(in);
     vol_d=vol-156;a[0]=vol_d/10;a[1]=vol_d%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 /// BALANCE ////////////////////////////
   if(menu==1){
  if (newPosition != oldPosition){oldPosition = newPosition;www=0;
     ball=ball-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(ball<-10){ball=-10;}if(ball>10){ball=10;}
    wireWrite(0b000100000000 + vol+10 + ball);//reg0
    wireWrite(0b001100000000 + vol+10 - ball);//reg1
    Serial.println(ball);
  }
  if(www==1||w==1){www=0;w=0;
      if(ball<0){lcd.setCursor(8,1);lcd.write((uint8_t)0);
                 lcd.setCursor(0,1);lcd.print("L > R");}                
      if(ball>0){lcd.setCursor(8,1);lcd.print(" ");
                 lcd.setCursor(0,1);lcd.print("L < R");}
     if(ball==0){lcd.setCursor(8,1);lcd.print(" ");
                 lcd.setCursor(0,1);lcd.print("L = R");}
      lcd.setCursor(0,0);lcd.print("BALANCE ");

      a[0]=abs(ball)/10;a[1]=abs(ball)%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}

 //////// INPUT ////////////////////////////////////  
  if(menu==2){
    if (newPosition != oldPosition){oldPosition = newPosition;
     in=in-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(in<0){in=0;}if(in>7){in=7;}
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();}
  delay(10);
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("INPUT SELECTOR");  
  lcd.setCursor(0,1);lcd.print("COAXIAL "); lcd.print(in);lcd.print(" ");
  }}
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// DE-EMPHASIS //////////////////////////////////
  if(menu==3){
    if (newPosition != oldPosition){oldPosition = newPosition;
     dem=dem-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(dem<0){dem=0;}if(dem>3){dem=3;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("DE-EMPHASIS SEL");  
  lcd.setCursor(0,1);
  switch(dem){
  case 0: lcd.print("No De-emphasis");dem_res=0;break;
  case 1: lcd.print("44.1 kHz      ");dem_res=2;break;
  case 2: lcd.print("48.0 kHz      ");dem_res=3;break;
  case 3: lcd.print("32.0 kHz      ");dem_res=1;break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ///  FILTER ROLL-OFF //////////////////////////////////
  if(menu==4){
    if (newPosition != oldPosition){oldPosition = newPosition;
     rol=rol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(rol<0){rol=1;}if(rol>1){rol=0;}
      
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("ROLL-OFF SELECT ");  
  lcd.setCursor(0,1);
  switch(rol){
  case 0: lcd.print("Sharp");break;
  case 1: lcd.print("Slow ");break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// Serial Format Select //////////////////////////////////
  if(menu==5){
    if (newPosition != oldPosition){oldPosition = newPosition;
     form=form-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
     if(form<0){form=0;}if(form>5){form=5;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  wireWrite(0b000100000000);//reg0
  wireWrite(0b001100000000);//reg1
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  wireWrite(0b000100000000 + vol+10 + ball);//reg0
  wireWrite(0b001100000000 + vol+10 - ball);//reg1
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("FORMAT SELECT");  
  lcd.setCursor(0,1);
  switch(form){
  case 0: lcd.print("L-Just 24 bit");dac_i2s=0;dac_iw=3;for_res=0;break;
  case 1: lcd.print("I2S    24 bit");dac_i2s=1;dac_iw=1;for_res=5;break;
  case 2: lcd.print("R-Just 24 bit");dac_i2s=0;dac_iw=2;for_res=8;break;
  case 3: lcd.print("L-Just 20 bit");dac_i2s=1;dac_iw=3;for_res=0;break; 
  case 4: lcd.print("I2S    20 bit");dac_i2s=1;dac_iw=2;for_res=5;break; 
  case 5: lcd.print("I2S    16 bit");dac_i2s=1;dac_iw=0;for_res=5;break;
  
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////

  /// read registr error 
  if(millis()-times1>1000){times1=millis();err = wireRead(0x10,0x0C);delay(10);}
  if(err!=err_old){err_old = err;www=1;}       
  /// EEPROM write
  if(millis()-times>10000 && w1==1){w1=0;EEPROM.update(0,vol);EEPROM.update(1,in);
  EEPROM.update(3,dem_res);EEPROM.update(4,for_dac);EEPROM.update(5,for_res);
  EEPROM.update(6,dac_i2s);EEPROM.update(7,dac_iw);EEPROM.update(8,rol);EEPROM.update(9,ball+10);
  www=1;if(menu!=0){lcd.clear();}menu=0;}
  delay(100);
  }// loop  

void wireWrite(int data){        // SPI
  digitalWrite(CLK,HIGH);digitalWrite(CS,HIGH);delay(1);
     for(int i = 15; i >= 0; i--){
        digitalWrite(CLK,LOW);
        digitalWrite(DATA, (data >> i) & 0x01);delay(1);
        digitalWrite(CLK,HIGH);delay(1);}
  digitalWrite(CS,LOW);delay(1);digitalWrite(CS,HIGH);
  }

byte wireRead(int addr, int reg){ // I2C
  Wire.beginTransmission(addr);
  Wire.write (reg);
  Wire.endTransmission();
  delay(10);
  Wire.requestFrom(addr,1);
  while(Wire.available()<1);
  byte value = Wire.read();
  return value;
  }  

void to_Timer(){newPosition = myEnc.read()/4;}  

4

Re: CS8416 + WM8740

Коррекция ошибок в CS8416:

HOLD[1:0] – Determine how received audio sample is affected when a receive error occurs
Default = ‘00’
00 – hold last audio sample.
01 – replace the current audio sample with all zeros (mute).
10- do not change the received audio sample.
11 - reserved

http://forum.rcl-radio.ru/uploads/images/2020/11/197a39d33b6934e860cbe87faf0e9faf.png

Установлены биты HOLD  HOLD[1:0] = 01

#define CS   2  // ML WM8740
#define CLK  3  // MC WM8740
#define DATA 4  // MD WM8740

#include <Wire.h> 
#include <EEPROM.h>
#include <Encoder.h>  // https://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // https://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <LiquidCrystal_I2C.h> //Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 Encoder myEnc(9, 8);//CLK, DT
      byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};
      byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};      
      byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};
      byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};
      byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};
      byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};
      int a[3],vol,vol_d,menu,in,dem,form,ball,rol;
      byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
      unsigned long times,times1,oldPosition  = -999,newPosition;
      bool w,w1,www=1,mute;
      byte dac_i2s,dac_iw,dem_res,for_dac,for_res,err,err_old;

void setup(){
   Wire.begin();
   Serial.begin(9600);
   MsTimer2::set(1, to_Timer);MsTimer2::start();
   lcd.init();lcd.backlight();
   lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
   pinMode(10,INPUT);   // SW энкодер
   pinMode(11,INPUT_PULLUP); // кнопка MUTE      
   pinMode(CS,OUTPUT);  // ML WM8740
   pinMode(CLK,OUTPUT); // MC WM8740
   pinMode(DATA,OUTPUT);// MD WM8740
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
  vol = EEPROM.read(0);in = EEPROM.read(1);dem_res = EEPROM.read(3);for_dac = EEPROM.read(4);for_res = EEPROM.read(5);
  dac_i2s = EEPROM.read(6);dac_iw = EEPROM.read(7);rol = EEPROM.read(8);ball = EEPROM.read(9)-10;
   lcd.setCursor(0,0);lcd.print(" CS8416  WM8740 ");
   lcd.setCursor(0,1);lcd.print(" 24 bit  192kHz ");
  // Write WM8740 SPI
  wireWrite(0b000100000000);//reg0
  wireWrite(0b001100000000);//reg1
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  wireWrite(0b110000000000);//reg4
// Write 8416 I2C
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000110);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(200);lcd.clear();
  // Write WM8740 SPI
   wireWrite(0b000100000000 + vol+10 + ball);//reg0
   wireWrite(0b001100000000 + vol+10 - ball);//reg1
  }

void loop(){ 
 /// MENU //////////////////////////////
  if(digitalRead(10)==LOW){menu++;if(menu>5){menu=0;};delay(200);lcd.clear();times=millis();w=1;w1=1;www=1;}
 /// MUTE /////////////////////////////
 if(digitalRead(11)==LOW && mute==0){mute=1; wireWrite(0b010000000001 + (dac_iw << 3));delay(300);www=1;} 
 if(digitalRead(11)==LOW && mute==1){mute=0; wireWrite(0b010000000000 + (dac_iw << 3));delay(300);www=1;} 

 /// VOLUME /////////////////////////////////// 
   if(menu==0){
  if (newPosition != oldPosition){oldPosition = newPosition;www=0;
     vol=vol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(vol<145){vol=145;}if(vol>245){vol=245;}
    wireWrite(0b000100000000 + vol+10 + ball);//reg0
    wireWrite(0b001100000000 + vol+10 - ball);//reg1
    Serial.println(vol);// vol = 145...245 step 0.5 dB + 10 balance
  }
  if(www==1||w==1){www=0;w=0;
      if(mute==1){         lcd.setCursor(0,0);lcd.print("MUTE    ");}
      if(err==0&&mute==0){ lcd.setCursor(0,0);lcd.print("VOLUME  ");}
      if(err==22&&mute==0){lcd.setCursor(0,0);lcd.print("ERROR   ");}
      if(err==8&&mute==0){ lcd.setCursor(0,0);lcd.print("NO SOUND");}
 
      lcd.setCursor(0,1);lcd.print("COAX ");lcd.print(in);
     vol_d=vol-156;a[0]=vol_d/10;a[1]=vol_d%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 /// BALANCE ////////////////////////////
   if(menu==1){
  if (newPosition != oldPosition){oldPosition = newPosition;www=0;
     ball=ball-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(ball<-10){ball=-10;}if(ball>10){ball=10;}
    wireWrite(0b000100000000 + vol+10 + ball);//reg0
    wireWrite(0b001100000000 + vol+10 - ball);//reg1
    Serial.println(ball);
  }
  if(www==1||w==1){www=0;w=0;
      if(ball<0){lcd.setCursor(8,1);lcd.write((uint8_t)0);
                 lcd.setCursor(0,1);lcd.print("L > R");}                
      if(ball>0){lcd.setCursor(8,1);lcd.print(" ");
                 lcd.setCursor(0,1);lcd.print("L < R");}
     if(ball==0){lcd.setCursor(8,1);lcd.print(" ");
                 lcd.setCursor(0,1);lcd.print("L = R");}
      lcd.setCursor(0,0);lcd.print("BALANCE ");

      a[0]=abs(ball)/10;a[1]=abs(ball)%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}

 //////// INPUT ////////////////////////////////////  
  if(menu==2){
    if (newPosition != oldPosition){oldPosition = newPosition;
     in=in-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(in<0){in=0;}if(in>7){in=7;}
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000110);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();}
  delay(10);
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("INPUT SELECTOR");  
  lcd.setCursor(0,1);lcd.print("COAXIAL "); lcd.print(in);lcd.print(" ");
  }}
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// DE-EMPHASIS //////////////////////////////////
  if(menu==3){
    if (newPosition != oldPosition){oldPosition = newPosition;
     dem=dem-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(dem<0){dem=0;}if(dem>3){dem=3;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000110);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("DE-EMPHASIS SEL");  
  lcd.setCursor(0,1);
  switch(dem){
  case 0: lcd.print("No De-emphasis");dem_res=0;break;
  case 1: lcd.print("44.1 kHz      ");dem_res=2;break;
  case 2: lcd.print("48.0 kHz      ");dem_res=3;break;
  case 3: lcd.print("32.0 kHz      ");dem_res=1;break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ///  FILTER ROLL-OFF //////////////////////////////////
  if(menu==4){
    if (newPosition != oldPosition){oldPosition = newPosition;
     rol=rol-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
      if(rol<0){rol=1;}if(rol>1){rol=0;}
      
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  delay(10);
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("ROLL-OFF SELECT ");  
  lcd.setCursor(0,1);
  switch(rol){
  case 0: lcd.print("Sharp");break;
  case 1: lcd.print("Slow ");break;
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////

   /// Serial Format Select //////////////////////////////////
  if(menu==5){
    if (newPosition != oldPosition){oldPosition = newPosition;
     form=form-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;
     if(form<0){form=0;}if(form>5){form=5;}
  
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000110);
  Wire.write (0b00000000 + (dem_res << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000000 + (for_res));
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  wireWrite(0b000100000000);//reg0
  wireWrite(0b001100000000);//reg1
  wireWrite(0b010000000000 + (dac_iw << 3));//reg2
  wireWrite(0b011000000000 + dac_i2s + (rol << 3));//reg3
  wireWrite(0b000100000000 + vol+10 + ball);//reg0
  wireWrite(0b001100000000 + vol+10 - ball);//reg1
  }
  if(www==1||w==1){www=0;w=0;
  lcd.setCursor(0,0);lcd.print("FORMAT SELECT");  
  lcd.setCursor(0,1);
  switch(form){
  case 0: lcd.print("L-Just 24 bit");dac_i2s=0;dac_iw=3;for_res=0;break;
  case 1: lcd.print("I2S    24 bit");dac_i2s=1;dac_iw=1;for_res=5;break;
  case 2: lcd.print("R-Just 24 bit");dac_i2s=0;dac_iw=2;for_res=8;break;
  case 3: lcd.print("L-Just 20 bit");dac_i2s=1;dac_iw=3;for_res=0;break; 
  case 4: lcd.print("I2S    20 bit");dac_i2s=1;dac_iw=2;for_res=5;break; 
  case 5: lcd.print("I2S    16 bit");dac_i2s=1;dac_iw=0;for_res=5;break;
  
  }}}
  ////////////////////////////////////////////////////////////////////////////////////////////////////////

  /// read registr error 
  if(millis()-times1>1000){times1=millis();err = wireRead(0x10,0x0C);delay(10);}
  if(err!=err_old){err_old = err;www=1;}       
  /// EEPROM write
  if(millis()-times>10000 && w1==1){w1=0;EEPROM.update(0,vol);EEPROM.update(1,in);
  EEPROM.update(3,dem_res);EEPROM.update(4,for_dac);EEPROM.update(5,for_res);
  EEPROM.update(6,dac_i2s);EEPROM.update(7,dac_iw);EEPROM.update(8,rol);EEPROM.update(9,ball+10);
  www=1;if(menu!=0){lcd.clear();}menu=0;}
  delay(100);
  }// loop  

void wireWrite(int data){        // SPI
  digitalWrite(CLK,HIGH);digitalWrite(CS,HIGH);delay(1);
     for(int i = 15; i >= 0; i--){
        digitalWrite(CLK,LOW);
        digitalWrite(DATA, (data >> i) & 0x01);delay(1);
        digitalWrite(CLK,HIGH);delay(1);}
  digitalWrite(CS,LOW);delay(1);digitalWrite(CS,HIGH);
  }

byte wireRead(int addr, int reg){ // I2C
  Wire.beginTransmission(addr);
  Wire.write (reg);
  Wire.endTransmission();
  delay(10);
  Wire.requestFrom(addr,1);
  while(Wire.available()<1);
  byte value = Wire.read();
  return value;
  }  

void to_Timer(){newPosition = myEnc.read()/4;}