Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Wolfson WM8960 DAC

  1. #1
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41

    Wolfson WM8960 DAC

    I fiddled around with a Wolfson WM8960 DAC until I got it sort of working with a Teensy 3.6 and 4.1 as Audio USB to i2s output passthrough for playing music from a (windows) pc

    The code that I mangled use 16 bit and 48kHz - it is from Cirrus Logic for use with an STM32

    I need to get it down to 44.1kHz but I cannot figure out a relatively simple setting for the R4 (04h) register Clocking
    It seems as if I have to switch froma MCLK derived sustem clock to one that use the PLL?
    Am I correct in this?

    Any pointers will be appreciated (page 69 in the data sheet for Reg04 Clocking attached next post)

    Also code use 25MHz/512 but from schematic use a 24MHz crustal
    Therefore need divide by 544(.22) can I use integer PLL page 81 instead of fractional 24bit divide?
    Fraction is 0.0018382
    Is it accurate enough?

    Wolfson docs
    https://www.cirrus.com/products/wm8960/

    Waveshare DAC
    https://www.waveshare.com/wm8960-audio-hat.htm

    Click image for larger version. 

Name:	wm8960.jpg 
Views:	18 
Size:	229.5 KB 
ID:	21520

    I attach my code which plays - although it sometimes need a few tries
    Code:
    // --------------------------------------
    // i2c_scanner
    // http://playground.arduino.cc/Main/I2cScanner
    //
    ////////////////////////////////////////////////////////////////////////////
    //       WM8960-DAC      Teensy 4      Teensy 3.6       Audioboard 3
    //  1,2  VCC      Red    3V3 *         3V3 
    //  3,4  GND    Brown    GND *         GND (not AGnd)
    //  5,6  SDA     Gray    18 SDA0 *     18 SDA0         18 SDA  
    //  7,8  SCL   Orange    19 SCL0 *     19 SCL0         19 SCL  
    //  9,10 CLK     Blue    21 BCLK1 *     9 BCK           9 BCLK
    // 11,12 WS     White    20 LRCLK1 *  23 LRCK          23 LRCLK   I2S Frame clock input
    // 13    RXSDA   Green    7 OUT1A *    22 TX           22 TX      I2S Data output
    // 14    TXSDA    Blue                  22 TX            13 RX      I2S Data input
    // 15    RXMCLK                                                   I2S System Clock(Sending)
    // 16    TXMCLK                                                    I2SSystem Clock(Receive)
    // WM8960_ADDRESS = 0x1a 
    // MCLK signal transmitted (TX MCLK RX) MCLK signal transmitted   
    // * = usb audio working     
    //                                                      11 MCLK
    //                                                       7 MOSI
    //                                                      12 MISO
    //                                                      14 SCLK
    //                                                    6,10 CS
    ///////////////////////////////////////////////////////////////////////////
    // See this post for other type of pcm5102 board 
    // https://forum.pjrc.com/threads/53069-Teensy-with-PCM5102a-Module-via-I2S
    // PCM5102A Teensy 3.6
    //
    // VCC   = Vin
    // 3.3v  = NC
    // GND   = GND
    // FLT   = GND
    // SCL   = GND (also works connected to 11 /MCL)
    // BCK   = BCK (9)
    // DIN   = TX (22)
    // LCK   = LCRLK (23)
    // FMT   = GND
    // XMT   = 3.3V (HIGH)
    // Set Tools -> USB Audio
    ///////////////////////////////////////////////////////
    #include <Wire.h>
    
    int led = LED_BUILTIN;
    
    #define WM8960_ADDRESS  0x1A
    
    //register values
    static uint16_t WM8960_REG_VAL[56] =
    {  
      0x0097, 0x0097, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x000A,
      0x01C0, 0x0000, 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x007B, 0x0100, 0x0032, 0x0000, 0x00C3, 0x00C3, 0x01C0,
      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      0x0100, 0x0100, 0x0050, 0x0050, 0x0050, 0x0050, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0040, 0x0000, 0x0000, 0x0050, 0x0050, 0x0000,
      0x0000, 0x0037, 0x004D, 0x0080, 0x0008, 0x0031, 0x0026, 0x00ED
    };
    
    #include <Audio.h>
    #include <SPI.h>
    
    // GUItool: begin automatically generated code
    AudioInputUSB            usb1;           //xy=121,162
    AudioOutputI2S           i2s1;           //xy=559,166
    AudioConnection          patchCord1(usb1, 0, i2s1, 0);
    AudioConnection          patchCord2(usb1, 1, i2s1, 1);
    // GUItool: end automatically generated code
    
     int delay1 = 10;
     int delay2 = 500;
     
    
    //////////////////////////////////////////////////////////////////////////////////////////////////
    // i2c master first send an address frame for searching slave and setting communication mode. 
    // High 7 bits = address, followed a control bit and finally the response signal
    // Slave device receives the response signal, it will return a response to master device. 
    // Then master device could begin to send data to slave device, which is 8 bits and the high 7 bits are 
    // address and the lowest one is response signal. MSB first.
    // 
    // Registers of WM8960 are 9-bit. Thus, when we send data to it, 
    // should split data to two bytes and add the ID of register to recognized before
    // transmitting. The ID of register flagged by 7-bit.
    //
    // Byte0 = bit7 to bit1 = device address, bit0 = read/write
    // Byte1 = bit7 to bit1 = register number 0-57, bit0 = MSB bit8 of register value
    // Byte2 =                                                 bit7-bit0 register value
    /////////////////////////////////////////////////////////////////////////////////////////////////
    
    /////////////////////////////////////////
    // WM89060 Write RegisterNumber = Value
    /////////////////////////////////////////
    uint8_t WM8960_Write_Reg(uint8_t reg, uint16_t dat)  
    { 
      uint8_t res,I2C_Data[2];
      
      I2C_Data[0] = (reg<<1)|((uint8_t)((dat>>8)&0x0001));  //RegAddr
      I2C_Data[1] = (uint8_t)(dat&0x00FF);                  //RegValue
    
      //digitalWrite(led, HIGH);                              // briefly flash the LED
    
      Wire.beginTransmission(WM8960_ADDRESS);  // transmit to device lsb=0 => write
      //Wire.write(I2C_Data[0]);                  // buffer 1 byte reg1 in b7-b1
      //Wire.write(I2C_Data[1]);                  // buffer 1 byte lsb of val1
      Wire.write(I2C_Data, 2);                    // buffer 1 byte lsb of val1
      res = Wire.endTransmission();               // transmit buffer and then stop
    
      if(res == 0) { WM8960_REG_VAL[reg] = dat;
                     //digitalWrite(led, LOW); 
                   }
    
      return res;
    }
    
    /////////////////////////////////////////
    // WM89060 Inititialise
    /////////////////////////////////////////
    uint8_t WM89060_Init(void)  {
    
      uint8_t res;
      
      //////////////////////////////////////////////////////////  
      // Reset Device 0x0f, 0x0000
      // #define WM8960_RESET    0xf
      // reg<<1 register now in bit7-bit1
      // msb=b8 (ninth bit) of val now in bit0
      // uint8_t  reg1 = ((reg << 1) |(uint8_t)((val >> 8) & 1))
      // val = lsb b7-b0 val and with val msb b15-b18 all = 0
      ////////////////////////////////////////////////////////
      res = WM8960_Write_Reg(0x0f, 0x0000);
      //if (res == 0) Serial.println("WM8960 reset completed"); else return res;
      delay(delay1);
      
      // Set Power Source
      // #define WM8960_POWER1  0x19
      // #define WM8960_POWER2  0x1a
      // #define WM8960_ADDCTL3 0x1b **************
      // #define WM8960_POWER3  0x2f
      res =  WM8960_Write_Reg(0x19, 1<<8 | 1<<7 | 1<<6);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x1A, 1<<8 | 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x2F, 1<<3 | 1<<2);
      //if (res == 0) Serial.println("WM8960 power 1,2,3 completed"); else return res;
      delay(delay1);
      
      // Configure clock
      // MCLK->div1->SYSCLK->DAC/ADC sample Freq = 25MHz(MCLK)/2*256 = 48.8kHz
      res = WM8960_Write_Reg(0x04, 0x0000);
      //if (res == 0) Serial.println("WM8960 Configure clock"); else return res;
      delay(delay1);
    
      // Configure ADC/DAC
      res = WM8960_Write_Reg(0x05, 0x0000);
      //if (res == 0) Serial.println("WM8960 Configure ADC/DAC"); else return res;
      delay(delay1);
      
      // Configure audio interface
      // I2S format 16 bits word length
      res = WM8960_Write_Reg(0x07, 0x0002);
      //if (res == 0) Serial.println("WM8960 Configure audio interface"); else return res;
      delay(delay1);
      
      // Configure HP_L and HP_R OUTPUTS
      res =  WM8960_Write_Reg(0x02, 0x006F | 0x0100);  //LOUT1 Volume Set
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x03, 0x006F | 0x0100);  //ROUT1 Volume Set
      //if (res == 0) Serial.println("WM8960 Configure HP_L and HP_R OUTPUTS"); else return res;
      delay(delay1);
      
      // Configure SPK_RP and SPK_RN
      res =  WM8960_Write_Reg(0x28, 0x007F | 0x0100); //Left Speaker Volume
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x29, 0x007F | 0x0100); //Right Speaker Volume
      //if (res == 0) Serial.println("WM8960 Configure SPK_RP and SPK_RN"); else return res;
      delay(delay1);
    
      // Enable the OUTPUTS
      res = WM8960_Write_Reg(0x31, 0x00F7); //Enable Class D Speaker Outputs
      //if (res == 0) Serial.println("WM8960 Enable Class D Speaker Outputs"); else return res;
      delay(delay1);
    
      // Configure DAC volume
      res =  WM8960_Write_Reg(0x0a, 0x00FF | 0x0100);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x0b, 0x00FF | 0x0100);
      //if (res == 0) Serial.println("WM8960 Configure DAC volume"); else return res;
      delay(delay1);
    
      // 3D
      // WM8960_Write_Reg(0x10, 0x001F);
      
      // Configure MIXER
      res =  WM8960_Write_Reg(0x22, 1<<8 | 1<<7);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x25, 1<<8 | 1<<7);
      //if (res == 0) Serial.println("WM8960 Configure MIXER"); else return res;
      delay(delay1);
    
      // Jack Detect
      res =  WM8960_Write_Reg(0x18, 1<<6 | 0<<5);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x17, 0x01C3);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x30, 0x0009); //0x000D,0x0005
      //if (res == 0) Serial.println("WM8960 Jack Detect"); else return res;
      delay(delay1);
    
      return 0;
    }
    
    /////////////////////////////////////////
    // Setup
    /////////////////////////////////////////
    void setup() 
    {
      uint8_t res;
      pinMode(led, OUTPUT);
      AudioMemory(12);
    
      
      // uncomment these to use alternate pins
      //Wire.setSCL(16);
      //Wire.setSDA(17);
      Wire.begin();           // join i2c bus (address optional for master)
      //Serial.begin(9600);
      
      //while (!Serial);        // Leonardo: wait for serial monitor
      //Serial.println(F("\nI2C Scanner"));
    
      res = WM89060_Init();
      //if (res != 0) Serial.println(res);
    
    }
     
    /////////////////////////////////////////
    // Main
    /////////////////////////////////////////
    void loop() 
    {
      
      delay(100);           // wait 5 seconds for next scan
     
    
    }
    Last edited by Saibot; 08-28-2020 at 03:08 PM. Reason: fixes fixes

  2. #2
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41
    Sorry here is a schematic and datasheet
    Click image for larger version. 

Name:	WM8960_Audio_Board_Schematic..jpg 
Views:	22 
Size:	85.3 KB 
ID:	21521

    WM8960_v4.2.pdf
    Last edited by Saibot; 08-28-2020 at 01:39 PM.

  3. #3
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41
    ok sorry formula is on page 60 PLLK = int (2^24 (R-PLLN)) and examples in table 44

    44,10kHz
    f2 = 4 x 2 x 11.2896Hz = 90.3168MHz
    R = 90.316 / 12 = 7.5264
    PLLN = int R = 7
    k = int ( 2^24 x (7.5264 – 7)) = 8831526

    So why do these changes not work?

    Code:
    // Configure clock
      // MCLK->div1->SYSCLK->DAC/ADC sample Freq = 24MHz(MCLK)/2*256 = 46.875kHz
      res = WM8960_Write_Reg(0x04, 0x0001); // Select PLL
      //if (res == 0) Serial.println("WM8960 Configure clock"); else return res;
      delay(delay1);
    
      // Configure PLL 1  0011 0111 = 37h
      res = WM8960_Write_Reg(0x34, 0x0037); // Select PLL 1
      delay(delay1);
    
      // Configure PLL 2  bit 8 reserved 7-0 data
      res = WM8960_Write_Reg(0x35, 0x0086); // Select PLL 2
      delay(delay1);
    
      // Configure PLL 3   
      res = WM8960_Write_Reg(0x36, 0x00C2); // Select PLL 3
      delay(delay1);
    
      // Configure PLL 4   
      res = WM8960_Write_Reg(0x37, 0x0026); // Select PLL 4
      delay(delay1);
    Last edited by Saibot; 08-28-2020 at 04:57 PM.

  4. #4
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,901
    @Saibot
    Funny I have a couple of those sitting around somewhere but never did anything with them. You are making me want to pull them out. Interesting to see what your final code looks like to play a file

  5. #5
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41
    Quote Originally Posted by mjs513 View Post
    @Saibot
    Funny I have a couple of those sitting around somewhere but never did anything with them. You are making me want to pull them out. Interesting to see what your final code looks like to play a file
    Yes I started with the Raspberry Pi hat versions:
    https://www.waveshare.com/wm8960-audio-hat.htm

    Oops this is link for first post general DAC
    https://www.waveshare.com/wm8960-audio-board.htm

    And they sounded very good with h/phones

    Could not find any Arduino code and the Linux drivers are complicated

    But anyway it is Friday night and time for a Red Heart and Coke Zero..

    Found the bug must be switched on

    PLL R26 (1Ah)
    Power
    management (2)
    0 PLLEN 0 PLL Enable
    0 = PLL off
    1 = PLL on
    Last edited by Saibot; 08-28-2020 at 06:54 PM. Reason: many eyeballs and deep bugs

  6. #6
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41
    Code:
      // 1111 1100 b0 =1 PLL on
      res += WM8960_Write_Reg(0x1A, 1<<8 | 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1);
    All done

  7. #7
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41
    Final code and Teensy 4.0 also tested

    Click image for larger version. 

Name:	teensy40-wm8960.jpg 
Views:	22 
Size:	172.1 KB 
ID:	21525

    Code:
    ////////////////////////////////////////////////////////////////////////////
    // GPL3 license Aug 2020
    // Based on Wolfson WM8960 STM32 demo code from Waveshare
    // Demo code BSD license from STMicroelectronics
    //
    ////////////////////////////////////////////////////////////////////////////
    //       WM8960-DAC      Teensy 4.1    Teensy 3.6       Audioboard 3
    //  1,2  VCC      Red    3V3 *         3V3 
    //  3,4  GND    Brown    GND *         GND (not AGnd)
    //  5,6  SDA     Gray    18 SDA0 *     18 SDA0         18 SDA  
    //  7,8  SCL   Orange    19 SCL0 *     19 SCL0         19 SCL  
    //  9,10 CLK     Blue    21 BCLK1 *     9 BCK           9 BCLK
    // 11,12 WS     White    20 LRCLK1 *  23 LRCK          23 LRCLK   I2S Frame clock input
    // 13    RXSDA   Green    7 OUT1A *    22 TX           22 TX      I2S Data output
    // 14    TXSDA    Blue                 13 RX           13 RX      I2S Data input
    // 15    RXMCLK                                                   I2S System Clock(Sending)
    // 16    TXMCLK                                                   I2SSystem Clock(Receive)
    // WM8960_ADDRESS = 0x1a 
    // MCLK signal transmitted (TX MCLK RX) MCLK signal transmitted   
    // * = usb audio working     
    //                                                      11 MCLK
    //                                                       7 MOSI
    //                                                      12 MISO
    //                                                      14 SCLK
    //                                                    6,10 CS
    ///////////////////////////////////////////////////////////////////////////
    
    #include <Wire.h>
    
    int led = LED_BUILTIN;
    
    #define WM8960_ADDRESS  0x1A
    
    //register values
    static uint16_t WM8960_REG_VAL[56] =
    {  
      0x0097, 0x0097, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x000A,
      0x01C0, 0x0000, 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x007B, 0x0100, 0x0032, 0x0000, 0x00C3, 0x00C3, 0x01C0,
      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
      0x0100, 0x0100, 0x0050, 0x0050, 0x0050, 0x0050, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0040, 0x0000, 0x0000, 0x0050, 0x0050, 0x0000,
      0x0000, 0x0037, 0x004D, 0x0080, 0x0008, 0x0031, 0x0026, 0x00ED
    };
    
    #include <Audio.h>
    #include <SPI.h>
    
    // GUItool: begin automatically generated code
    AudioInputUSB            usb1;           //xy=121,162
    AudioOutputI2S           i2s1;           //xy=559,166
    AudioConnection          patchCord1(usb1, 0, i2s1, 0);
    AudioConnection          patchCord2(usb1, 1, i2s1, 1);
    // GUItool: end automatically generated code
    
     int delay1 = 10;
     int delay2 = 500;
     
    
    //////////////////////////////////////////////////////////////////////////////////////////////////
    // Registers of WM8960 are 9-bit. Thus, when we send data to it, 
    // should split data to two bytes and add the ID of register to recognized before
    // transmitting. The ID of register flagged by 7-bit.
    //
    // Byte0 = bit7 to bit1 = device address, bit0 = read/write
    // Byte1 = bit7 to bit1 = register number 0-57, bit0 = MSB bit8 of register value
    // Byte2 =                                                 bit7-bit0 register value
    /////////////////////////////////////////////////////////////////////////////////////////////////
    
    /////////////////////////////////////////
    // WM89060 Write RegisterNumber = Value
    /////////////////////////////////////////
    uint8_t WM8960_Write_Reg(uint8_t reg, uint16_t dat)  
    { 
      uint8_t res,I2C_Data[2];
      
      I2C_Data[0] = (reg<<1)|((uint8_t)((dat>>8)&0x0001));  //RegAddr
      I2C_Data[1] = (uint8_t)(dat&0x00FF);                  //RegValue
    
      //digitalWrite(led, HIGH);                              // briefly flash the LED
    
      Wire.beginTransmission(WM8960_ADDRESS);  // transmit to device lsb=0 => write
      //Wire.write(I2C_Data[0]);                  // buffer 1 byte reg1 in b7-b1
      //Wire.write(I2C_Data[1]);                  // buffer 1 byte lsb of val1
      Wire.write(I2C_Data, 2);                    // buffer 1 byte lsb of val1
      res = Wire.endTransmission();               // transmit buffer and then stop
    
      if(res == 0) { WM8960_REG_VAL[reg] = dat;
                     //digitalWrite(led, LOW); 
                   }
    
      return res;
    }
    
    /////////////////////////////////////////
    // WM89060 Inititialise
    /////////////////////////////////////////
    uint8_t WM89060_Init(void)  {
    
      uint8_t res;
      
      //////////////////////////////////////////////////////////  
      // Reset Device 0x0f, 0x0000
      // #define WM8960_RESET    0xf
      // reg<<1 register now in bit7-bit1
      // msb=b8 (ninth bit) of val now in bit0
      // uint8_t  reg1 = ((reg << 1) |(uint8_t)((val >> 8) & 1))
      // val = lsb b7-b0 val and with val msb b15-b18 all = 0
      ////////////////////////////////////////////////////////
      res = WM8960_Write_Reg(0x0f, 0x0000);
      //if (res == 0) Serial.println("WM8960 reset completed"); else return res;
      delay(delay1);
      
      // Set Power Source
      // #define WM8960_POWER1  0x19
      // #define WM8960_POWER2  0x1a
      // #define WM8960_ADDCTL3 0x1b **************
      // #define WM8960_POWER3  0x2f
      res =  WM8960_Write_Reg(0x19, 1<<8 | 1<<7 | 1<<6);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x1A, 1<<8 | 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x2F, 1<<3 | 1<<2);
      //if (res == 0) Serial.println("WM8960 power 1,2,3 completed"); else return res;
      delay(delay1);
      
      // Configure clock
      // MCLK->PLL->SYSCLK->DAC/ADC sample Freq = 24MHz/544.217 = 44.100kHz
      // See calculation pages 60 and table 44 in manual
      // f2 = 4 x 2 x 11.2896Hz = 90.3168MHz
      // R = 90.316 / 12 = 7.5264
      // PLLN = int R = 7
      // k = int ( 2^24 x (7.5264  7)) = 8831526
      // N = 7
      // Fractional 24bit value = 86C226h
      res = WM8960_Write_Reg(0x04, 0x0001); // Select PLL
      //if (res == 0) Serial.println("WM8960 Configure clock"); else return res;
      delay(delay1);
    
      // Configure PLL 1  0011 0111 = 37h
      //                 00010 0111   27h
      res = WM8960_Write_Reg(0x34, 0x0027); // Select PLL 1
      delay(delay1);
    
      // Configure PLL 2  bit 8 reserved 7-0 data
      res = WM8960_Write_Reg(0x35, 0x0086); // Select PLL 2
      delay(delay1);
    
      // Configure PLL 3   
      res = WM8960_Write_Reg(0x36, 0x00C2); // Select PLL 3
      delay(delay1);
    
      // Configure PLL 4   
      res = WM8960_Write_Reg(0x37, 0x0026); // Select PLL 4
      delay(delay1);
    
      // Configure ADC/DAC
      res = WM8960_Write_Reg(0x05, 0x0000);
      //if (res == 0) Serial.println("WM8960 Configure ADC/DAC"); else return res;
      delay(delay1);
      
      // Configure audio interface
      // I2S format 16 bits word length
      res = WM8960_Write_Reg(0x07, 0x0002);
      //if (res == 0) Serial.println("WM8960 Configure audio interface"); else return res;
      delay(delay1);
      
      // Configure HP_L and HP_R OUTPUTS
      res =  WM8960_Write_Reg(0x02, 0x006F | 0x0100);  //LOUT1 Volume Set
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x03, 0x006F | 0x0100);  //ROUT1 Volume Set
      //if (res == 0) Serial.println("WM8960 Configure HP_L and HP_R OUTPUTS"); else return res;
      delay(delay1);
      
      // Configure SPK_RP and SPK_RN
      res =  WM8960_Write_Reg(0x28, 0x007F | 0x0100); //Left Speaker Volume
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x29, 0x007F | 0x0100); //Right Speaker Volume
      //if (res == 0) Serial.println("WM8960 Configure SPK_RP and SPK_RN"); else return res;
      delay(delay1);
    
      // Enable the OUTPUTS
      res = WM8960_Write_Reg(0x31, 0x00F7); //Enable Class D Speaker Outputs
      //if (res == 0) Serial.println("WM8960 Enable Class D Speaker Outputs"); else return res;
      delay(delay1);
    
      // Configure DAC volume
      res =  WM8960_Write_Reg(0x0a, 0x00FF | 0x0100);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x0b, 0x00FF | 0x0100);
      //if (res == 0) Serial.println("WM8960 Configure DAC volume"); else return res;
      delay(delay1);
    
      // 3D
      // WM8960_Write_Reg(0x10, 0x001F);
      
      // Configure MIXER
      res =  WM8960_Write_Reg(0x22, 1<<8 | 1<<7);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x25, 1<<8 | 1<<7);
      //if (res == 0) Serial.println("WM8960 Configure MIXER"); else return res;
      delay(delay1);
    
      // Jack Detect
      res =  WM8960_Write_Reg(0x18, 1<<6 | 0<<5);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x17, 0x01C3);
      delayMicroseconds(delay2);
      res += WM8960_Write_Reg(0x30, 0x0009); //0x000D,0x0005
      //if (res == 0) Serial.println("WM8960 Jack Detect"); else return res;
      delay(delay1);
    
      return 0;
    }
    
    /////////////////////////////////////////
    // Setup
    /////////////////////////////////////////
    void setup() 
    {
      uint8_t res;
      pinMode(led, OUTPUT);
      AudioMemory(12);
    
      Wire.begin();           // join i2c bus (address optional for master)
      //Serial.begin(9600);
      
      res = WM89060_Init();
      //if (res != 0) Serial.println(res);
    
    }
     
    /////////////////////////////////////////
    // Main
    /////////////////////////////////////////
    void loop() 
    {
      
      delay(100);           // wait 5 seconds for next scan
     
    
    }
    Last edited by Saibot; 08-29-2020 at 12:03 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •