Jump to content
  • 0

How to use Audio on Zybo board


Mehdim

Question

Hello guys;

Can you refer me to a quick guide about how to use Audio signal on ZYbo board?

I just want to know if there is any simple tutorial about how to get data from audio jack and have in on Arm side.

Appreciate your comments in advance.

Link to comment
Share on other sites

Recommended Posts

Thank you for the response;

Yeah I have play with example for days, the thing is that I can write config to ADC through I2C and confirm them by readying values, but when I try to receive from I2S, I get nothing.

Do you have any hint or comment for debugging this issues?

 

Link to comment
Share on other sites

I'm afraid I can't be of much help here. If your I2C is confirmed working, then the only thing to look at is the I2S controller. Make sure your pins are mapped out correctly in the xdc contraints file. Maybe check out the i2s_ctl.vhd file in the looper demo and compare it to the one from the instructables. I haven't gone through the instructable so I don't know what could be wrong, but I can try it out when I find time.

Link to comment
Share on other sites

On 6/23/2016 at 11:24 AM, Mehdim said:

Hello Alex;

Really sorry for the late response;

Here you can find some codes that I used:

/* Audio controller registers */

enum i2s_regs {

                I2S_DATA_RX_L_REG     = 0x00 + AUDIO_BASE,

                I2S_DATA_RX_R_REG    = 0x04 + AUDIO_BASE,

                I2S_DATA_TX_L_REG   = 0x08 + AUDIO_BASE,

                I2S_DATA_TX_R_REG   = 0x0c + AUDIO_BASE,

                I2S_STATUS_REG      = 0x10 + AUDIO_BASE,

};

#endif
 

XIicPs Iic;                              /* Instance of the IIC Device */

XNco Nco;

 

u8 audio_flag;

int AudioInitialize(u16 timerID,  u16 iicID, u32 i2sAddr)

{

                int Status;

                XIicPs_Config *Config;

                u32 i2sClkDiv;


                TimerInitialize(timerID);

                /*

                 * Initialize the IIC driver so that it's ready to use

                 * Look up the configuration in the config table,

                 * then initialize it.

                 */

                Config = XIicPs_LookupConfig(iicID);

                if (NULL == Config) {

                                return XST_FAILURE;

                }

 

                Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

 

                /*

                 * Perform a self-test to ensure that the hardware was built correctly.

                 */

                Status = XIicPs_SelfTest(&Iic);

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

                /*

                 * Set the IIC serial clock rate.

                 */

                Status = XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

 

                /*

                 * Write to the SSM2603 audio codec registers to configure the device. Refer to the

                 * SSM2603 Audio Codec data sheet for information on what these writes do.

                 */

                Status = AudioRegSet(&Iic, 15, 0b000000000); //Perform Reset

                TimerDelay(75000);

                Status |= AudioRegSet(&Iic, 6, 0b000110000); //Power up

                Status |= AudioRegSet(&Iic, 0, 0b000010111);

                Status |= AudioRegSet(&Iic, 1, 0b000010111);

                Status |= AudioRegSet(&Iic, 2, 0b101111001);

                Status |= AudioRegSet(&Iic, 4, 0b000010000);

                Status |= AudioRegSet(&Iic, 5, 0b000000000);

                Status |= AudioRegSet(&Iic, 7, 0b000001010); //Changed so Word length is 24

                Status |= AudioRegSet(&Iic, 8, 0b000000000); //Changed so no CLKDIV2

                TimerDelay(75000);

                Status |= AudioRegSet(&Iic, 9, 0b000000001);

                Status |= AudioRegSet(&Iic, 6, 0b000100000);

 

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

/*

                i2sClkDiv = 1; //Set the BCLK to be MCLK / 4

                i2sClkDiv = i2sClkDiv | (31 << 16); //Set the LRCLK's to be BCLK / 64

 

                Xil_Out32(i2sAddr + I2S_CLK_CTRL_REG, i2sClkDiv); //Write clock div register

*/

                return XST_SUCCESS;

}

/* ------------------------------------------------------------ */

 

int AudioRegSet(XIicPs *IIcPtr, u8 regAddr, u16 regData)

{

                int Status;

                u8 SendBuffer[2];

 

                SendBuffer[0] = regAddr << 1;

                SendBuffer[0] = SendBuffer[0] | ((regData >> 8) & 0b1);

 

                SendBuffer[1] = regData & 0xFF;

 

                Status = XIicPs_MasterSendPolled(IIcPtr, SendBuffer,

                                                                 2, IIC_SLAVE_ADDR);

                if (Status != XST_SUCCESS) {

                                //xil_printf("IIC send failed\n\r");

                                return XST_FAILURE;

                }

                /*

                 * Wait until bus is idle to start another transfer.

                 */

                while (XIicPs_BusIsBusy(IIcPtr)) {

                                /* NOP */

                }

                return XST_SUCCESS;

}

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioSampleR(u32 *data, u32 number)

{

u32 i;

for(i=0;i<number;i++)

{

                data = Xil_In32(I2S_DATA_RX_R_REG);

}

return;

}

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioSampleL(u32 *data, u32 number)

{

                u32 i;

                for(i=0;i<number;i++)

                {

                                data = Xil_In32(I2S_DATA_RX_L_REG);

                }

                return;

}

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioPlayR(u32 *data, u32 number)

{

u32 i;

for(i=0;i<number;i++)

{

                Xil_Out32(I2S_DATA_TX_R_REG, data);

}

return;

}

 

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioPlayL(u32 *data, u32 number)

{

u32 i;

for(i=0;i<number;i++)

{

                Xil_Out32(I2S_DATA_TX_L_REG, data);

}

return;

}

 

 

Hope it helps. If you have any further question shoot me an email at mehdim@umich.edu

 

Link to comment
Share on other sites

Hello again guys,

I am trying to simplify the project on

http://www.instructables.com/id/Digital-Filters-on-Zybo-Board/?ALLSTEPS

and run it on a standalone OS. So I just added “axi_i2s_adi_0” IP core to design and mapped IOs to audio codec ports.

The issue is that right now I can capture data from microphone or line-in and see signal on “SDATA_I” port on oscilloscope; but when I try to send this data to I2S, I cannot see” SDATA_O” and it stuck on 0; and therefore I have no audio on “HPH out”

VHeGVp1.jpg

 

une7KTm.jpg

Do you have any comment or hint on this?

Link to comment
Share on other sites

Hello again guys;

Finally I found the solution; to  me there is something wrong with the IP core at http://www.instructables.com/id/Digital-Filters-on-Zybo-Board/?ALLSTEPS

As a solution, I have download ip core entitled “zed_audio_ctrl_0” from

http://embeddedcentric.com/adc-dac-and-digital-audio-processing/

then all you have to do is to configure the codec from I2C and then easily read and write from\to I2S channel by

                     in_left = Xil_In32(I2S_DATA_RX_L_REG);

                     in_right = Xil_In32(I2S_DATA_RX_R_REG);

 

                     Xil_Out32(I2S_DATA_TX_L_REG, in_left);

                     Xil_Out32(I2S_DATA_TX_R_REG, in_right);95d819f.jpg

 

 

if it helps and i can be of more help please let me know

 

Link to comment
Share on other sites

Hi!

Could you be so kind and give some further information about your implementation?

For my university course we have to implement a wav-file player and this is my first project after doing the zynq book exercises. Normally we use the zedboard in the course, but i have the zybo at home, and would like to use it!

I have some resources how to configure the zedboard audio chip, but according to https://forums.xilinx.com/t5/Welcome-Join/ZYBO-I2S-BCLK/td-p/433246

post #7, using the one on zybo is much more complex.

I already build the block design like yours and put the constraints file together (maybe do you know if the zybo has write protection feature for sd card?).

But for the configuration i would need some help, maybe you could provide me with a c source file!

 

Thank you in advance

Alex

Link to comment
Share on other sites

Hello Alex;

Really sorry for the late response;

Here you can find some codes that I used:

/* Audio controller registers */

enum i2s_regs {

                I2S_DATA_RX_L_REG     = 0x00 + AUDIO_BASE,

                I2S_DATA_RX_R_REG    = 0x04 + AUDIO_BASE,

                I2S_DATA_TX_L_REG   = 0x08 + AUDIO_BASE,

                I2S_DATA_TX_R_REG   = 0x0c + AUDIO_BASE,

                I2S_STATUS_REG      = 0x10 + AUDIO_BASE,

};

#endif
 

XIicPs Iic;                              /* Instance of the IIC Device */

XNco Nco;

 

u8 audio_flag;

int AudioInitialize(u16 timerID,  u16 iicID, u32 i2sAddr)

{

                int Status;

                XIicPs_Config *Config;

                u32 i2sClkDiv;


                TimerInitialize(timerID);

                /*

                 * Initialize the IIC driver so that it's ready to use

                 * Look up the configuration in the config table,

                 * then initialize it.

                 */

                Config = XIicPs_LookupConfig(iicID);

                if (NULL == Config) {

                                return XST_FAILURE;

                }

 

                Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

 

                /*

                 * Perform a self-test to ensure that the hardware was built correctly.

                 */

                Status = XIicPs_SelfTest(&Iic);

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

                /*

                 * Set the IIC serial clock rate.

                 */

                Status = XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

 

                /*

                 * Write to the SSM2603 audio codec registers to configure the device. Refer to the

                 * SSM2603 Audio Codec data sheet for information on what these writes do.

                 */

                Status = AudioRegSet(&Iic, 15, 0b000000000); //Perform Reset

                TimerDelay(75000);

                Status |= AudioRegSet(&Iic, 6, 0b000110000); //Power up

                Status |= AudioRegSet(&Iic, 0, 0b000010111);

                Status |= AudioRegSet(&Iic, 1, 0b000010111);

                Status |= AudioRegSet(&Iic, 2, 0b101111001);

                Status |= AudioRegSet(&Iic, 4, 0b000010000);

                Status |= AudioRegSet(&Iic, 5, 0b000000000);

                Status |= AudioRegSet(&Iic, 7, 0b000001010); //Changed so Word length is 24

                Status |= AudioRegSet(&Iic, 8, 0b000000000); //Changed so no CLKDIV2

                TimerDelay(75000);

                Status |= AudioRegSet(&Iic, 9, 0b000000001);

                Status |= AudioRegSet(&Iic, 6, 0b000100000);

 

                if (Status != XST_SUCCESS) {

                                return XST_FAILURE;

                }

/*

                i2sClkDiv = 1; //Set the BCLK to be MCLK / 4

                i2sClkDiv = i2sClkDiv | (31 << 16); //Set the LRCLK's to be BCLK / 64

 

                Xil_Out32(i2sAddr + I2S_CLK_CTRL_REG, i2sClkDiv); //Write clock div register

*/

                return XST_SUCCESS;

}

/* ------------------------------------------------------------ */

 

int AudioRegSet(XIicPs *IIcPtr, u8 regAddr, u16 regData)

{

                int Status;

                u8 SendBuffer[2];

 

                SendBuffer[0] = regAddr << 1;

                SendBuffer[0] = SendBuffer[0] | ((regData >> 8) & 0b1);

 

                SendBuffer[1] = regData & 0xFF;

 

                Status = XIicPs_MasterSendPolled(IIcPtr, SendBuffer,

                                                                 2, IIC_SLAVE_ADDR);

                if (Status != XST_SUCCESS) {

                                //xil_printf("IIC send failed\n\r");

                                return XST_FAILURE;

                }

                /*

                 * Wait until bus is idle to start another transfer.

                 */

                while (XIicPs_BusIsBusy(IIcPtr)) {

                                /* NOP */

                }

                return XST_SUCCESS;

}

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioSampleR(u32 *data, u32 number)

{

u32 i;

for(i=0;i<number;i++)

{

                data = Xil_In32(I2S_DATA_RX_R_REG);

}

return;

}

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioSampleL(u32 *data, u32 number)

{

                u32 i;

                for(i=0;i<number;i++)

                {

                                data = Xil_In32(I2S_DATA_RX_L_REG);

                }

                return;

}

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioPlayR(u32 *data, u32 number)

{

u32 i;

for(i=0;i<number;i++)

{

                Xil_Out32(I2S_DATA_TX_R_REG, data);

}

return;

}

 

 

//--------------------------------------------------------------------------------------------------------------------------------------

void AudioPlayL(u32 *data, u32 number)

{

u32 i;

for(i=0;i<number;i++)

{

                Xil_Out32(I2S_DATA_TX_L_REG, data);

}

return;

}

 

 

Hope it helps. If you have any further question shoot me an email at mehdim@umich.edu

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...