4 Replies Latest reply on Jul 9, 2015 6:39 AM by doumdi

    Audio Block for Intel Edison

    SergeyK

      I have designed an Audio Block for Intel Edison. The block is based on Wolfson WM8731 codec and it uses Edison's I2S interface. It provides high quality stereo input and output (24 bit samples, up to 96 kHz sample rate), and it includes a built-in headphones' amplifier. The block's form factor is compatible with SparkFun Edison modules.

       

      The project documentation including schematic, PCB design files, and software setup instructions are available here: Audio Block for Intel Edison

       

      Thanks,

      Sergey

      Edison_Audio_Block.jpg

        • 1. Re: Audio Block for Intel Edison
          doumdi

          Good job! Thanks for sharing this information. I was also able to connect the TI TLV320AIC3107 to the Edison. Here is the code I have for testing. It seems I cannot record from the device though, this might be related to the alsa mixer. Any thoughts?

           

           

          
          #include <stdio.h>
          #include <unistd.h>
          #include <stdlib.h>
          #include <sys/types.h>
          #include <sys/stat.h>
          #include <sys/ioctl.h>
          #include <fcntl.h>
          #include <linux/fs.h>
          #include <errno.h>
          #include <string.h>
          #include <linux/i2c-dev.h>
          #include <linux/i2c.h>
          #include <sys/types.h>
          #include <mraa.h>
          #include <math.h>
          
          
          typedef unsigned char uint8_t;
          
          #define TLV320AIC3107_ADDRESS 0x18
          
          //REGISTERS
          
          
          int main(int argc, char* argv[])
          {
          
            mraa_result_t result;
            mraa_i2c_context i2c;
            i2c = mraa_i2c_init(6); // port i2c-6
          
          
            result = mraa_i2c_address(i2c,TLV320AIC3107_ADDRESS);
          
            //Page 0 & Reset
            printf("Reset... (wait 1s) \n");
            mraa_i2c_write_byte_data(i2c,0x00,0x00);
            mraa_i2c_write_byte_data(i2c,0x80,0x01);
          
            sleep(1);
          
            //Enable class-D amplifier sequence
            /*
            1. 0x00 0x0D
            2. 0x0D 0x0D
            3. 0x08 0x5C
            4. 0x08 0x5D
            5. 0x08 0x5C
            6. 0x00 0x00
            */
            mraa_i2c_write_byte_data(i2c,0x0D,0x00);
            mraa_i2c_write_byte_data(i2c,0x0D,0x0D);
            mraa_i2c_write_byte_data(i2c,0x5C,0x08);
            mraa_i2c_write_byte_data(i2c,0x5D,0x08);
            mraa_i2c_write_byte_data(i2c,0x5C,0x08);
          
          
          #define REG_PAGE_SELECT 0
            //Select page 0
            mraa_i2c_write_byte_data(i2c, 0x00, REG_PAGE_SELECT);
           
            //We assume a 12.288 MHz clock
          #define REG_PLL_A 3
            //P=1, Q=2, PLL enabled
            //mraa_i2c_write_byte_data(i2c,0x91, REG_PLL_A);
            mraa_i2c_write_byte_data(i2c, 0x20, REG_PLL_A);
          
          #define REG_PLL_B 4
            //J = 8
            //mraa_i2c_write_byte_data(i2c,0x20, REG_PLL_B);
          
          #define REG_PLL_C 5
            //D = 1920
            //mraa_i2c_write_byte_data(i2c,0x1E, REG_PLL_C);
          #define REG_PLL_D 6
            //D = 1920
            //mraa_i2c_write_byte_data(i2c,0x00,REG_PLL_D);
          
          #define REG_CODEC_DATAPATH_SETUP 7
            mraa_i2c_write_byte_data(i2c,0x0A, REG_CODEC_DATAPATH_SETUP);
          
          #define REG_AUDIO_SDI_CTRL_B 9
            //24 bits, DSP mode
            mraa_i2c_write_byte_data(i2c,0x60, REG_AUDIO_SDI_CTRL_B);
          
          #define REG_AUDIO_CODEC_OVERFLOW_FLAG 11
            mraa_i2c_write_byte_data(i2c,0x01,REG_AUDIO_CODEC_OVERFLOW_FLAG);
          
          #define REG_HEADSET_BUTTON_PRESS_DETECT 14
            mraa_i2c_write_byte_data(i2c,0x08, REG_HEADSET_BUTTON_PRESS_DETECT); 
          
          #define REG_LEFT_ADC_PGA_GAIN_CTRL 15
            //PGA Not muted, 59.5dB Gain
            mraa_i2c_write_byte_data(i2c,0x3F, REG_LEFT_ADC_PGA_GAIN_CTRL);
          
          #define REG_RIGHT_ADC_PGA_GAIN_CTRL 16
            //PGA Not muted, 59.5dB Gain
            mraa_i2c_write_byte_data(i2c,0x3F, REG_RIGHT_ADC_PGA_GAIN_CTRL);
          
          #define REG_LINE1L_TO_LEFT_ADC_CTRL 19
            //0dB, Powered up
            mraa_i2c_write_byte_data(i2c,0x04, REG_LINE1L_TO_LEFT_ADC_CTRL);
          
          #define REG_LINE1R_TO_RIGHT_ADC_CTRL 22
            //0dB, Powered up
            mraa_i2c_write_byte_data(i2c,0x04, REG_LINE1R_TO_RIGHT_ADC_CTRL);
          
          #define REG_DAC_POWER_OUTPUT_DRIVER_CTRL 37
            //Left & Right DAC powered, HPCOM is independent single-ended
            mraa_i2c_write_byte_data(i2c,0xE0, REG_DAC_POWER_OUTPUT_DRIVER_CTRL);
          
          #define REG_HIGH_POWER_DRIVER_CTRL 38
            //If short circuit, power down the output driver
            mraa_i2c_write_byte_data(i2c,0x02, REG_HIGH_POWER_DRIVER_CTRL); 
          
          #define REG_DAC_OUTPUT_SWITCHING_CTRL 41
            //Left DAC DAC_L3, Right DAC DAC_R3
            mraa_i2c_write_byte_data(i2c,0x50, REG_DAC_OUTPUT_SWITCHING_CTRL);
          
          #define REG_LEFT_DAC_VOLUME_CTRL 43
            //DAC not muted, GAIN = 0dB
            mraa_i2c_write_byte_data(i2c,0x00, REG_LEFT_DAC_VOLUME_CTRL);
          
          #define REG_RIGHT_DAC_VOLUME_CTRL 44
            //DAC not muted, GAIN = 0dB
            mraa_i2c_write_byte_data(i2c,0x00, REG_RIGHT_DAC_VOLUME_CTRL);
          
          #define REG_HPLOUT_OUTPUT_LEVEL_CTRL 51
            //HPLOUT 0dB, Not muted, full power
            mraa_i2c_write_byte_data(i2c,0x09, REG_HPLOUT_OUTPUT_LEVEL_CTRL);
          
          #define REG_HPROUT_OUTPUT_LEVEL_CTRL 65
            //HPROUT 0dB, Not muted, full power
            mraa_i2c_write_byte_data(i2c,0x09, REG_HPROUT_OUTPUT_LEVEL_CTRL);
          
          #define REG_CLASS_D_BYPASS_SWITCH_CTRL 73
            //Left & right gain = 0dB, class D channel enabled (left & right)
            mraa_i2c_write_byte_data(i2c,0x0C, REG_CLASS_D_BYPASS_SWITCH_CTRL);
          
          #define REG_LEFT_LOP_OUTPUT_LEVEL_CTRL 86
            //0dB, not muted
            mraa_i2c_write_byte_data(i2c,0x08, REG_LEFT_LOP_OUTPUT_LEVEL_CTRL);
          
          #define REG_RIGHT_LOP_OUTPUT_LEVEL_CTRL 93
            //OdB, not muted
            mraa_i2c_write_byte_data(i2c,0x08, REG_RIGHT_LOP_OUTPUT_LEVEL_CTRL);
          
          
          #define REG_CLOCK_GENERATION_CTRL 102
            //CLKDIV_IN uses BCLK, PLLCLK_IN uses BCLK, PLL N = 16
            mraa_i2c_write_byte_data(i2c,0xA0,REG_CLOCK_GENERATION_CTRL);
          
          
            //Read ADC STATUS
          #define REG_ADC_FLAG 36
            unsigned int val = mraa_i2c_read_byte_data(i2c,REG_ADC_FLAG);
            printf("ADC STATUS = %2.2x \n",val); 
          
          
            return 0;
          }
          
          • 2. Re: Audio Block for Intel Edison
            SergeyK

            I am not familiar with TLV320AIC3107 codec particularly. But assuming that you have configured it correctly (using I2C) including setting up recording volume and enabling ADC and set up the ALSA routing it should be working. I was able to record sound with my setup, using an ALSA machine driver rather than dummy codec / configuring the codec directly using I2C. Still I think the SSP2 configuration is the same (TDM, 4 channel / 24-bit per channel)

            • 3. Re: Audio Block for Intel Edison
              doumdi
              1. #define REG_PLL_A 3 
              2.   //P=1, Q=2, PLL disabled
              3.   mraa_i2c_write_byte_data(i2c, 0x10, REG_PLL_A); 

               

              I disabled the PLL and fixed te PLL_A register to use Q = 2. It seems it fixed the sampling rate to 12.288MHz / 256  (48000 Hz). I can now record and playback with the device. The codec is nice since it includes a class-D amplifier. I am using it with mems microphones, it makes a nice wireless communication device with the Edison. Thanks for your help.

              • 4. Re: Audio Block for Intel Edison
                doumdi

                I also found that the ALSA mixer in this mode is tricky. Distorsion often occurs when we try to rise the volume above 80, it seems some kind of software gain is applied for the dummy driver.