This test will configure the WM8960 via I2C, read the audio data from the WM8960 (using Line In or MIC In as the input source), and then loop it back to the WM8960 for output through headphones or speakers.
Create a new Vivado project. Follow the previous steps to configure the PS's Quad SPI FLASH, UART, and DDR controller. Since this experiment uses the I2C controller to configure the WM8960 via the I2C interface, note that the WM8960's I2C interface (scl and sda) is hardware-connected to the PL pins. Therefore, the PS's I2C controller needs to be connected to two PL pins via EMIO.
The configuration result is as follows:
In the diagram, click to select the IIC_0 interface indicated by the arrow, then right-click and choose "Make External" from the pop-up menu to bring out the I2C interface. After bringing out the interface, rename it to "aud_iic", as shown below:
Add a new IP core: Click the "+" symbol in the Diagram toolbar to add an IP. In the search box that pops up, enter "i2s". You will see two IP cores: I2S Receiver and I2S Transmitter. We need to add both to the design.
Configure as shown below (the transmitter is configured similarly):
Bring out the interfaces for communication between the two I2S IP cores and the WM8960 chip. The I2S Receiver module is responsible for capturing the audio data output from the WM8960, so the audio data input interface "sdata_0_in" needs to be brought out via "Make External". After bringing out the interface, rename it to "aud_adc_data".
Typically, the I2S Receiver and I2S Transmitter IP cores only support master mode. However, this experiment requires clock synchronization using the onboard clock of the WM8960 chip. Therefore, set the I2S Receiver to slave mode and the I2S Transmitter to master mode.
Double-click the I2S Receiver core and change the C_IS_MASTER value to 0, as shown below:
After setting the I2S Receiver to slave mode and the I2S Transmitter to master mode, the Irclk_in/sclk_in of the Receiver end is provided by the Irclk_out/sclk_out of the Transmitter end.
The I2S Transmitter module is responsible for outputting the audio data to be played to the WM8960. Similarly, bring out the audio data output interface "sdata_0_out" via "Make External", then rename this interface to "aud_dac_data". The diagram also shows an interface sclk_out brought out from the I2S Transmitter module, which is the bit clock BCLK in the I2S transmission protocol. To synchronize the bit clocks at both ends, connect this interface of the Transmitter to the sclk_in interface of the Receiver, as shown below:
To achieve the audio loopback function, connect the m_axis_aud interface of the I2S Receiver module to the s_axis_aud interface of the I2S Transmitter module. This means directly outputting the AXI4-Stream format audio data from the receiver module to the transmitter module, as shown below:
Search for and add the clock module:
Configure the clock: On the Clocking Options page, set the input clock to be provided by the MCLK pin of the WM8960 module. The frequency of the MCLK output from the WM8960 module is 24MHz. Therefore, set the input frequency to manual ("MANUAL") and change the clock frequency to 24MHz.
On the Output Clocks page, set the frequency of the output clock clk_out1 to 18.432MHz to provide MCLK for the I2S Receiver/I2S Transmitter modules. This clock frequency is an integer multiple of 128 * Fs, where Fs is the audio sampling rate. In this experiment, the audio sampling rate Fs used is 48KHz, so the clock frequency of clk_out1 is N × 128 × 48 KHz, where N is a positive integer. When N is 3, the calculated clock frequency is 3 × 128 × 48000 = 18432000Hz, i.e., 18.432MHz.
At the bottom of the Output Clocks page, uncheck the clock module's reset interface "reset". After setting, click "OK" in the lower right corner of the diagram.
Bring out the clk_in1 in the above diagram via "Make External" and rename it to "aud_mclk"; then connect clk_out1 to the I2S Receiver and I2S Transmitter. After setting, it looks like the following:
Search for "vector" and add the "Utility Vector Logic" IP core, configuring it as follows:
Use this NOT gate to invert the "locked" signal output from the clock module, then connect the inverted signal to the aud_mrst interface of the I2S Receiver and I2S Transmitter modules. After the clock output from the clock module stabilizes, the locked signal will go high; while the aud_mrst signal is active high for reset, so a NOT gate is needed to invert the locked signal. As shown below:
Next, click "Run Block Automation" and "Run Connection Automation" at the top of the Diagram window to let the tool automatically connect the remaining module interfaces:
In the dialog that pops up after clicking "Run Connection Automation", check "All Automation" on the left to perform automatic connections. After connection is complete, press CTRL+S to save the project and proceed to generate the top-level HDL file.
Add pin constraints: Right-click Constraints --> Add Source
Add the xdc file:
xcreate_clock -period 20.000 -name sys_clk
set_property -dict {PACKAGE_PIN L19 IOSTANDARD LVCMOS33} [get_ports aud_iic_scl_io]set_property -dict {PACKAGE_PIN L20 IOSTANDARD LVCMOS33} [get_ports aud_iic_sda_io]set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS33} [get_ports aud_adc_data]set_property -dict {PACKAGE_PIN G17 IOSTANDARD LVCMOS33} [get_ports aud_dac_data]set_property -dict {PACKAGE_PIN H18 IOSTANDARD LVCMOS33} [get_ports aud_bclk]set_property -dict {PACKAGE_PIN J18 IOSTANDARD LVCMOS33} [get_ports aud_mclk]
set_property PACKAGE_PIN J19 [get_ports aud_adc_lrc]set_property IOSTANDARD LVCMOS33 [get_ports aud_adc_lrc]set_property PACKAGE_PIN G18 [get_ports aud_dac_lrc]set_property IOSTANDARD LVCMOS33 [get_ports aud_dac_lrc]Perform synthesis, implementation, and export the .xsa file.
Create a new platform project, application project, import the xsa file, and create a .c file.
The core code is as follows, mainly involving register operations:
xxxxxxxxxx//audio sample rate 48Khz//Main clock: 3*128*fs//WM8960 i2c slave address//I2C clock rate
// use line in or mic
uint8_t uart_rcv_buf[UART_RCV_BUF_LEN];uint8_t audio_mode = 0; // 0-LineIN, 1-Mic
XI2srx_Config *I2s_Rx_Config;XI2stx_Config *I2s_Tx_Config;XIicPs_Config *I2c_Config;
XI2s_Rx I2s_rx;XI2s_Tx I2s_tx;XIicPs Iic;XUartPs Uart_Ps;int Uart_Status;extern EmbeddedCli *cli;
extern void init_cmd_cli();
uint16_t wm8960_line_cfg[] = { // addr, data 15, 0x0000, // reset
//Audio Interface // bit[7:8] bit[6] bit[5] bit[4:3] bit[2:1] bit[0] // 00, ALRCGPIO=1, WL8=0, DACCOMP=00, ADCCOMP=00, LOOPBACK=0 9, (0x1 << 6),
// power management1 // bit[8:7] bit6 bit5 bit4 bit3 bit2 bit1 bit0 // VMIDSEL[1:0]=01b, VREF=1, AINL=1, AINR=1, ADCL=1, ADCR=1, MICB=0, DIGENB=0 25, (0x02 << 7) | (0x01 << 6) | (0x01 << 5) | (0x00 << 4) | (0x01 << 3) | (0x01 << 2) | (0x00 << 1) | 0x00, // power management2 // bit8 bit7 bit6 bit5 bit4 bit3 bit1 bit0 // DACL=1, DACR=1, LOUT1=1, ROUT1=1, SPKL=1, SPKR=1, OUT3=0, PLL_EN=1 26, (0x01<<8) | (0x01<<7) | (0x01<<6) | (0x01<<5) | (0x01<<4) | (0x01<<3) | (0x00<<1) | (0x01<<0),
// power management3 // bit5 bit4 bit3 bit2 // LMIC=0, RMIC=0, LOMIX=1, ROMIX=1 47, (0x00<<5) | (0x00<<4) | (0x01<<3) | (0x01<<2), // disable MIC input
// ADCL signal path // bit[8] bit[7] bit[6] bit[5:4] bit3 // LMN1=0, LMP3=0, LMP2=0, LMICBOOST[1:0]=00b, LMIC2B=0 32, (0x00<<8) | (0x00<<7) | (0x00<<6) | (0x00<<4) | (0x00<<3),
// ADCR signal path // bit[8] bit[7] bit[6] bit[5:4] bit3 // RMN1=0, RMP3=0, RMP2=0, RMICBOOST[1:0]=00b, RMIC2B=0 33, (0x00<<8) | (0x00<<7) | (0x00<<6) | (0x00<<4) | (0x00<<3),
// left input volume // bit8 bit7 bit6, bit[5:0] // IPVU=1, LINMUTE=0, LIZC=0, LINVOL[5:0]=0x17 0, (0x01<<8) | (0x00<<7) | (0x17<<0),
// right input volume // bit8 bit7 bit6, bit[5:0] // IPVU=1, RINMUTE=0, RIZC=0, RINVOL[5:0]=0x17 1, (0x01<<8) | (0x00<<7) | (0x17<<0),
// automatic level control 17, (0x02<<7) | (0x07<<4) | (0x0B<<0), 18, (0x00<<4) | (0x00<<0), 19, (0x00<<8) | (0x03<<4) | (0x02<<0),
// left out mix: Choose one of three // bit[8] bit[7] bit[6:4] // LD2LO=1, LI2LO=0, LI2LOVOL[2:0]=000b 34, (0x01<<8), // (1)enable Left DAC To Left output Mixer, LI2LO=0 // LD2LO=0, LI2LO=1, LI2LOVOL[2:0]=000b // 34, (0x01<<7), // (2)enable LINPUT3 To Left output Mixer // 34, 0, // (3)enable Left Input Boost Mixer Output To Left output Mixer // bit7 bit[6:4] // LB2LO=1, LB2LOVOL[2:0]=000b // 45, (0x01<<7), // (3)enable Left Input Boost Mixer Output To Left output Mixer
// right out mix: choose one of two // bit[8] bit[7] bit[6:4] // RD2Ro=1, RI2RO=0, RI2ROVOL[2:0]=000b 37, (0x01<<8), // (1)enable Right DAC To Right output Mixer // RD2RO=0, RI2RO=0, RI2ROVOL[2:0]=000b // 37, 0, // (2)enable Right Input Boost Mixer Output To Right output Mixer // bit7 bit[6:4] // RB2RO=1, RB2ROVOL[2:0]=000b // 46, (0x01<<7), // (2)enable Right Input Boost Mixer Output To Right output Mixer
// ADC & DAC control // bit7 bit[6:5] bit3 bit[2:1] bit0 //DACDIV2=0, ADCPOL[1:0], DACMU=0, DEEMPH[1:0]=0, ADCPHD=1 5, 0x0001, // DAC unmute, enable high pass filter on left and right channels
// LOUT1 volume // bit8 bit7 bit6~0 // OUT1VU=1, LO1ZC=0, LOUT1VOL[6:0]=0x79->0dB 2, (0x01<<8) | (0x00<<7) | 0x79,
// ROUT1 volume // bit8 bit7 bit6~0 // OUT1VU=1, LO1ZC=0, LOUT1VOL[6:0]=0x79->0dB 3, (0x01<<8) | (0x00<<7) | 0x79,
// Class D Control(3) // bit[5:3] bit[2:0] // DCGAIN[2:0]=011b, ACGAIN[2:0]=011b 51, 0x80 | (0x03<<3) | (0x03<<0), //speaker gain
// Class D Control(1) // bit[7:6] // SPK_OP_EN[1:0]=11b 49, 0x0037 | (0x03<<6), // enable left & right speaker
// LOUT2 volume // bit[8] bit[7] bit[6:0] // SPKVU=1, SPKLZC=0, SPKLVOL[6:0]=0x7F 40, (0x01<<8) | 0x007F, // ROUT2 volume // bit[8] bit[7] bit[6:0] // SPKVU=1, SPKLZC=0, SPKLVOL[6:0]=0x7F 41, (0x01<<8) | 0x007F,
// Input boost mixer (1) // bit[6:4] bit[3:1] // LIN3BOOST[2:0]=101b, LIN2BOOST[2:0]=000b 43, (0x0000<<4) | (0x0005<<1), //enable Left Line in2, disable left line in3 // Input boost mixer (2) // bit[6:4] bit[3:1] // RIN3BOOST[2:0]=000b, RIN2BOOST[2:0]=101b 44, (0x0000<<4) | (0x0005<<1), //enable Right Line in2, diable right line in3
// Audio Interface // bit8 bit7 bit6 bit5 bit4 bit[3:2] bit[1:0] // ALRSWAP=0, BCLKINV=0, MS=0, DLRSWAP=0, LRP=0, WL[1:0]=10b, FORMAT[1:0]=10b 7, (0x02<<2) | (0x02<<0), // I2S mode, slave mode, 24bit
// Clocking // bit[8:6] bit[5:3] bit[2:1] bit0 // ADCDIV[2:0]=0, DACDIV[2:0]=0, SYSCLKDIV[1:0]=10b, CLKSEL=1 4, (0x02<<1) | (0x01<<0), //sample rate:48K, SYSCLKDIV=2:enable PLL
// set PLL, MCLK=24MHz, SYSCLK=12.288MHz: 0x3126E8 // bit[8:6] bit5 bit4 bit[3:0] // OPCLKDIV[2:0]=0, SDM=1, PLLRESCALE=1, PLLN[3:0]=8 52, (0x01<<5) | (0x01<<4) | (0x08<<0), // Reg53: PLLK[23:16] 53, (0x3126E8 >> 16) & 0xFF, // Reg54: PLLK[15:8] 54, (0x3126E8 >> 8) & 0xFF, // Reg55: PLLK[7:0] 55, (0x3126E8 & 0xFF),
// Additional control(1) // bit[8] bit[7:6] bit[4] bit[3:2] bit1 bit0 // TSDEN=1, VSEL[1:0]=11b, DMONOMIX=0, DATSEL[1:0]=00b, TOCLKSEL=0, TOEN=1 23, (0x01<<8) | (0x03<<6) | (0x00<<4) | (0x00<<2) | (0x00<<1) | (0x01<<0),
// Headphone insert detection // Additional control (2) // bit[6] bit[5] bit[3] bit[2] // HPSWEN=1, HPSWPOL=0, TRIS=0, LRCM=0 24, (0x01<<6) | (0x00<<5) | (0x00<<3) | (0x00<<2),
// Additional Control (4) // bit[7] bit[6:4] bit[3:2] bit[1] bit[0] // GPIOPOL=0, GPIOSEL[2:0]=000b, HPSEL[1:0]=11b, TSENSEN=1, MBSEL=0 48, (0x03<<2) | (0x01<<1) | (0x00<<0), // MBSEL=0: Bias voltag->0.9*AVDD};
uint16_t wm8960_mic_cfg[] = { // addr, data 15, 0x0000, // reset
//Audio Interface // bit[7:8] bit[6] bit[5] bit[4:3] bit[2:1] bit[0] // 00, ALRCGPIO=1, WL8=0, DACCOMP=00, ADCCOMP=00, LOOPBACK=0 9, (0x1 << 6),
// power management1 // bit[8:7] bit6 bit5 bit4 bit3 bit2 bit1 bit0 // VMIDSEL[1:0]=01b, VREF=1, AINL=1, AINR=1, ADCL=1, ADCR=1, MICB=1, DIGENB=0 25, (0x02 << 7) | (0x01 << 6) | (0x01 << 5) | (0x01 << 4) | (0x01 << 3) | (0x01 << 2) | (0x01 << 1) | 0x00,
// power management2 // bit8 bit7 bit6 bit5 bit4 bit3 bit1 bit0 // DACL=1, DACR=1, LOUT1=1, ROUT1=1, SPKL=1, SPKR=1, OUT3=0, PLL_EN=1 26, (0x01<<8) | (0x01<<7) | (0x01<<6) | (0x01<<5) | (0x01<<4) | (0x01<<3) | (0x00<<1) | (0x01<<0),
// power management3 // bit5 bit4 bit3 bit2 // LMIC=1, RMIC=1, LOMIX=1, ROMIX=1 47, (0x01<<5) | (0x01<<4) | (0x01<<3) | (0x01<<2),
// ADCL signal path // bit[8] bit[7] bit[6] bit[5:4] bit3 // LMN1=1, LMP3=0, LMP2=0, LMICBOOST[1:0]=00b, LMIC2B=1 32, (0x01<<8) | (0x00<<7) | (0x00<<6) | (0x00<<4) | (0x01<<3),
// ADCR signal path // bit[8] bit[7] bit[6] bit[5:4] bit3 // RMN1=1, RMP3=0, RMP2=0, RMICBOOST[1:0]=00b, RMIC2B=1 33, (0x01<<8) | (0x00<<7) | (0x00<<6) | (0x00<<4) | (0x01<<3),
// left input volume // bit8 bit7 bit6, bit[5:0] // IPVU=1, LINMUTE=0, LIZC=0, LINVOL[5:0]=0x1F 0, (0x01<<8) | (0x00<<7) | (0x1F<<0),
// right input volume // bit8 bit7 bit6, bit[5:0] // IPVU=1, RINMUTE=0, RIZC=0, RINVOL[5:0]=0x3F 1, (0x01<<8) | (0x00<<7) | (0x1F<<0),
// automatic level control 17, (0x02<<7) | (0x07<<4) | (0x0B<<0), 18, (0x00<<4) | (0x00<<0), 19, (0x00<<8) | (0x03<<4) | (0x02<<0),
// left out mix: choose one of three // bit[8] bit[7] bit[6:4] // LD2LO=1, LI2LO=0, LI2LOVOL[2:0]=000b 34, (0x01<<8), // (1)enable Left DAC To Left output Mixer, LI2LO=0 // LD2LO=0, LI2LO=1, LI2LOVOL[2:0]=000b // 34, (0x01<<7), // (2)enable LINPUT3 To Left output Mixer // 34, 0, // (3)enable Left Input Boost Mixer Output To Left output Mixer // bit7 bit[6:4] // LB2LO=1, LB2LOVOL[2:0]=000b // 45, (0x01<<7), // (3)enable Left Input Boost Mixer Output To Left output Mixer
// right out mix: choose one of two // bit[8] bit[7] bit[6:4] // RD2Ro=1, RI2RO=0, RI2ROVOL[2:0]=000b 37, (0x01<<8), // (1)enable Right DAC To Right output Mixer // RD2RO=0, RI2RO=0, RI2ROVOL[2:0]=000b // 37, 0, // (2)enable Right Input Boost Mixer Output To Right output Mixer // bit7 bit[6:4] // RB2RO=1, RB2ROVOL[2:0]=000b // 46, (0x01<<7), // (2)enable Right Input Boost Mixer Output To Right output Mixer
// ADC & DAC control // bit7 bit[6:5] bit3 bit[2:1] bit0 //DACDIV2=0, ADCPOL[1:0], DACMU=0, DEEMPH[1:0]=0, ADCPHD=0 5, 0x0001, // DAC unmute,enable high pass filter on left and right channels
// LOUT1 volume // bit8 bit7 bit6~0 // OUT1VU=1, LO1ZC=0, LOUT1VOL[6:0]=0x79->0dB 2, (0x01<<8) | (0x00<<7) | 0x79,
// ROUT1 volume // bit8 bit7 bit6~0 // OUT1VU=1, LO1ZC=0, LOUT1VOL[6:0]=0x79->0dB 3, (0x01<<8) | (0x00<<7) | 0x79,
// Class D Control(3) // bit[5:3] bit[2:0] // DCGAIN[2:0]=011b, ACGAIN[2:0]=011b 51, 0x80 | (0x03<<3) | (0x03<<0), //speaker gain
// Class D Control(1) // bit[7:6] // SPK_OP_EN[1:0]=11b 49, 0x0037 | (0x03<<6), // enable left & right speaker
// LOUT2 volume // bit[8] bit[7] bit[6:0] // SPKVU=1, SPKLZC=0, SPKLVOL[6:0]=0x79 40, (0x01<<8) | 0x0079, // ROUT2 volume // bit[8] bit[7] bit[6:0] // SPKVU=1, SPKLZC=0, SPKLVOL[6:0]=0x79 41, (0x01<<8) | 0x0079,
// Input boost mixer (1) // bit[6:4] bit[3:1] // LIN3BOOST[2:0]=000b, LIN2BOOST[2:0]=000b 43, (0x0000<<4) | (0x0000<<1), //disable Left Line in2/3 // Input boost mixer (2) // bit[6:4] bit[3:1] // RIN3BOOST[2:0]=000b, RIN2BOOST[2:0]=101b 44, (0x0000<<4) | (0x0000<<1), //disable Right Line in2/3
// Audio Interface // bit8 bit7 bit6 bit5 bit4 bit[3:2] bit[1:0] // ALRSWAP=0, BCLKINV=0, MS=0, DLRSWAP=0, LRP=0, WL[1:0]=10b, FORMAT[1:0]=10b 7, (0x02<<2) | (0x02<<0), // I2S mode, slave mode, 24bit
// Clocking // bit[8:6] bit[5:3] bit[2:1] bit0 // ADCDIV[2:0]=0, DACDIV[2:0]=0, SYSCLKDIV[1:0]=10b, CLKSEL=1 4, (0x02<<1) | (0x01<<0), //sample rate: 48K, SYSCLKDIV=2: enable PLL
// set PLL, MCLK=24MHz, SYSCLK=12.288MHz: 0x3126E8 // bit[8:6] bit5 bit4 bit[3:0] // OPCLKDIV[2:0]=0, SDM=1, PLLRESCALE=1, PLLN[3:0]=8 52, (0x01<<5) | (0x01<<4) | (0x08<<0), // Reg53: PLLK[23:16] 53, (0x3126E8 >> 16) & 0xFF, // Reg54: PLLK[15:8] 54, (0x3126E8 >> 8) & 0xFF, // Reg55: PLLK[7:0] 55, (0x3126E8 & 0xFF),
// Additional control(1) // bit[8] bit[7:6] bit[4] bit[3:2] bit1 bit0 // TSDEN=1, VSEL[1:0]=11b, DMONOMIX=0, DATSEL[1:0]=00b, TOCLKSEL=0, TOEN=1 23, (0x01<<8) | (0x03<<6) | (0x00<<4) | (0x00<<2) | (0x00<<1) | (0x01<<0),
// HP insert detection // Additional control (2) // bit[6] bit[5] bit[3] bit[2] // HPSWEN=1, HPSWPOL=0, TRIS=0, LRCM=0 24, (0x01<<6) | (0x00<<5) | (0x00<<3) | (0x00<<2),
// Additional Control (4) // bit[7] bit[6:4] bit[3:2] bit[1] bit[0] // GPIOPOL=0, GPIOSEL[2:0]=000b, HPSEL[1:0]=11b, TSENSEN=1, MBSEL=0 // 48, (0x03<<2) | (0x01<<1) | (0x00<<0), // MBSEL=0: Bias voltag->0.9*AVDD};
int main(){ uint32_t rd_bytes = 0; XUartPs_Config *Uart_Config; init_platform();
// init UART Uart_Config = XUartPs_LookupConfig(UART_DEVICE_ID); if (Uart_Config == NULL) { return XST_FAILURE; } Uart_Status = XUartPs_CfgInitialize(&Uart_Ps, Uart_Config, Uart_Config->BaseAddress); if (Uart_Status != XST_SUCCESS) { return XST_FAILURE; } // set baudrate XUartPs_SetBaudRate(&Uart_Ps, 115200);
//init I2S Receiver I2s_Rx_Config = XI2s_Rx_LookupConfig(I2S_RX_DEVICE_ID); XI2s_Rx_CfgInitialize(&I2s_rx, I2s_Rx_Config, I2s_Rx_Config->BaseAddress); //set the BCLK clock of I2S Receiver XI2s_Rx_SetSclkOutDiv(&I2s_rx, MCLK, FS); //enable I2S Receiver XI2s_Rx_Enable(&I2s_rx, TRUE);
//init I2S Transmitter I2s_Tx_Config = XI2s_Tx_LookupConfig(I2S_TX_DEVICE_ID); XI2s_Tx_CfgInitialize(&I2s_tx, I2s_Tx_Config, I2s_Tx_Config->BaseAddress); //set th BLCK clock of I2S Transmitter XI2s_Tx_SetSclkOutDiv(&I2s_tx, MCLK, FS); //enable I2S Transmitter XI2s_Tx_Enable(&I2s_tx,TRUE);
//init IIC I2c_Config = XIicPs_LookupConfig(IIC_DEVICE_ID); XIicPs_CfgInitialize(&Iic, I2c_Config, I2c_Config->BaseAddress); XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
init_cmd_cli();
set_audio_mode(audio_mode);
print("Audio mode: Line IN\n\r");
while (1) { rd_bytes = XUartPs_Recv(&Uart_Ps, uart_rcv_buf, UART_RCV_BUF_LEN); if (rd_bytes > 0) { for (uint32_t i = 0; i < rd_bytes; i++) { embeddedCliReceiveChar(cli, uart_rcv_buf[i]); //input cmd } embeddedCliProcess(cli); } }
cleanup_platform(); return 0;
}
//write data to WM8960 regvoid WM8960_Write_Reg(u8 reg_addr, u16 reg_data){ uint8_t I2C_Data[2];
I2C_Data[0] = (reg_addr<<1) | ((u8)((reg_data>>8) & 0x0001)); I2C_Data[1] = (u8)(reg_data & 0x00FF);
XIicPs_MasterSendPolled(&Iic, I2C_Data, 2, IIC_SLAVE_ADDR);
while (XIicPs_BusIsBusy(&Iic)) ;}
//config audio modevoid set_audio_mode(uint8_t mode){ audio_mode = mode; if (mode == 0) // LINE IN { WM8960_Write_Reg(wm8960_line_cfg[0], wm8960_line_cfg[1]); usleep(10000); // sleep for a while after reset
for (uint32_t i = 1; i < sizeof(wm8960_line_cfg)/(2 *sizeof(uint16_t)); i++) { WM8960_Write_Reg(wm8960_line_cfg[2 * i], wm8960_line_cfg[2 * i + 1]); } } else // MIC { WM8960_Write_Reg(wm8960_mic_cfg[0], wm8960_mic_cfg[1]); usleep(10000); // sleep for a while after reset
for (uint32_t i = 1; i < sizeof(wm8960_line_cfg)/(2 *sizeof(uint16_t)); i++) { WM8960_Write_Reg(wm8960_mic_cfg[2 * i], wm8960_mic_cfg[2 * i + 1]); } }}
Connect one end of the audio cable to an audio playback device and the other end to the development board's LINE_IN interface;
Connect the computer to the JTAG interface on the bottom board using a USB cable.
Then, connect the USB_UART interface on the left side of the development board to the computer using a USB cable for serial communication.