- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Sorry for my English, I will try my best to describe my problem.
I was struggling to configure the audio CODEC (WM8731) for a few months and still not figure out the problem :(
So the intention is that I have to configure the audio CODEC
through the HPS, after that using the audio core in Qsys to get the data from the audio chip.
I cannot use NIOS and any OS like Linux.
At very first step, the audio CODEC should be configured before using the audio core, and I face the problem.
I was making the Qsys project with audio core base on the GHRD.
I created the C project in ARM DS-5.
Follow the datasheet, in order to make the HPS access to the audio CODED, the signal of HPS_I2C_CONTROL need to set high.
After that, I used the HWlib that provide with EDS to implement
the I2C communication between the HPS I2C controller and audio CODEC.
However, when I run the debugger, feed the audio from line-in and connect line-out with speaker, no sound appear.
I couldn't figure out what is the problem.
Does anyone can help me?
//the function to set up the HPS_I2C_CONTROL and HPS_LED GPIO
void setup_hps_gpio() {
uint32_t hps_gpio_config_len = 2;
ALT_GPIO_CONFIG_RECORD_t hps_gpio_config[] ={
{HPS_LED_IDX , ALT_GPIO_PIN_OUTPUT, 0, 0, ALT_GPIO_PIN_DEBOUNCE, ALT_GPIO_PIN_DATAZERO},
{HPS_I2C_CONTROL_IDX, ALT_GPIO_PIN_OUTPUT, 0, 0, ALT_GPIO_PIN_DEBOUNCE, ALT_GPIO_PIN_DATAZERO}
};
assert(ALT_E_SUCCESS == alt_gpio_init());
assert(ALT_E_SUCCESS == alt_gpio_group_config(hps_gpio_config, hps_gpio_config_len));
}
void setup_hps_timer() {
assert(ALT_E_SUCCESS == alt_globaltmr_init());
}
//delay function
void delay_us(uint32_t us)
{
uint64_t start_time = alt_globaltmr_get64();
uint32_t timer_prescaler = alt_globaltmr_prescaler_get() + 1;
uint64_t end_time;
alt_freq_t timer_clock;
alt_clk_freq_get(ALT_CLK_MPU_PERIPH, &timer_clock);
end_time = start_time + us * ((timer_clock / timer_prescaler) / 1000000);
while(alt_globaltmr_get64() < end_time)
{
}
}
//The function control the HPS_I2C_CONTORL signal high or low
void handle_hps_i2c_control(bool hps_i2c_ctrl_sw) {
if(hps_i2c_ctrl_sw){
// get the value from the GPIO1 register
uint32_t hps_value = alt_read_word(ALT_GPIO1_SWPORTA_DR_ADDR);
// set the hps_value = 0x0
hps_value = ALT_GPIO_SWPORTA_DR_GPIO_SWPORTA_DR_RESET;
// set the hps_value to be 0x1fffffff
hps_value = hps_value | ALT_GPIO_SWPORTA_DR_GPIO_SWPORTA_DR_SET_MSK;
// turn on HPS_LED
assert(ALT_E_SUCCESS == alt_gpio_port_data_write(HPS_LED_PORT, HPS_LED_MASK, hps_value));
// set HPS_I2C_CONTROL to high
assert(ALT_E_SUCCESS == alt_gpio_port_data_write(HPS_I2C_CONTROL_PORT, HPS_I2C_CONTROL_MASK, hps_value));
}
if(hps_i2c_ctrl_sw == false){
uint32_t hps_value = alt_read_word(ALT_GPIO1_SWPORTA_DR_ADDR);
// set the hps_value = 0x0
hps_value = ALT_GPIO_SWPORTA_DR_GPIO_SWPORTA_DR_RESET;
// turn off HPS_LED
assert(ALT_E_SUCCESS == alt_gpio_port_data_write(HPS_LED_PORT, HPS_LED_MASK, hps_value));
// set HPS_I2C_CONTROL to low
assert(ALT_E_SUCCESS == alt_gpio_port_data_write(HPS_I2C_CONTROL_PORT, HPS_I2C_CONTROL_MASK, hps_value));
}
}
static ALT_STATUS_CODE i2c_init(ALT_I2C_DEV_t* device)
{
ALT_STATUS_CODE status = ALT_E_SUCCESS;
ALT_I2C_MASTER_CONFIG_t cfg;
uint32_t speed;
// Init I2C module
if (status == ALT_E_SUCCESS)
{
printf("INFO: Init I2C module.\n");
status = alt_i2c_init(ALT_I2C_I2C0, device);
}
// Enable I2C module
if (status == ALT_E_SUCCESS)
{
printf("INFO: Enable I2C module.\n");
status = alt_i2c_enable(device);
}
// Configure I2C module
printf("INFO: Configuring I2C parameters.\n");
if (status == ALT_E_SUCCESS)
{
status = alt_i2c_master_config_get(device, &cfg);
}
if (status == ALT_E_SUCCESS)
{
status = alt_i2c_master_config_speed_set(device, &cfg, AUDIO_I2C_SPEED);
}
if (status == ALT_E_SUCCESS)
{
status = alt_i2c_master_config_speed_get(device, &cfg, &speed);
printf("INFO: New I2C speed = %d Hz.\n", (int)speed);
}
if(status == ALT_E_SUCCESS)
{
cfg.addr_mode = ALT_I2C_ADDR_MODE_7_BIT; // 7-bit format for the I2C address
cfg.restart_enable = ALT_E_TRUE;
cfg.fs_spklen = 2;
status = alt_i2c_master_config_set(device, &cfg);
}
return status;
}
bool i2c_write(ALT_I2C_DEV_t * device, uint8_t controlAddr, uint8_t controlData){
ALT_STATUS_CODE status = ALT_E_SUCCESS;
if(status == ALT_E_SUCCESS){
uint8_t send_buffer[2];
const size_t send_size = 2;
send_buffer[0] = controlAddr;
send_buffer[1] = controlData;
// Send the data to the device
status = alt_i2c_master_transmit(device, send_buffer, send_size, ALT_E_FALSE, ALT_E_TRUE);
}
printf("status = %d \r\n", status);
return ALT_E_SUCCESS;
}
//This function is internal function used to initialise the audio codec
bool aduio_RegWrite(ALT_I2C_DEV_t * device, uint8_t reg_index, uint16_t data16){
bool bSuccess;
uint8_t ctrlData, ctrlRegAddr;
if (reg_index <= 10)
reg_file[reg_index] = data16;
ctrlData = data16 & 0xFF;
ctrlRegAddr = (reg_index << 1) & 0xFE;
ctrlRegAddr |= ((data16 >> 8) & 0x01);
printf("[AUDIO] set audio reg[%02d] = %04Xh\r\n", reg_index, data16);
printf("I2C_AUDIO_ADDR = 0x%x, ctrlRegAddr = 0x%x, ctrlData = 0x%x\r\n",I2C_AUDIO_ADDR, ctrlRegAddr, ctrlData);
bSuccess = i2c_write(device, ctrlRegAddr, ctrlData);
printf("bSuccess = %d\r\n", bSuccess);
if (bSuccess != ALT_E_SUCCESS)
printf("[AUDIO] write reg fail!!!!\r\n");
return bSuccess;
}
//The function to configure the audio codec
bool audio_config(ALT_I2C_DEV_t * device){
ALT_STATUS_CODE bSuccess = ALT_E_SUCCESS;
printf("[AUDIO] AUDIO_Init...\r\n");
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 15, 0x0000); // reset
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 9, 0x0000); // inactive interface
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 0, 0x0017); // Left Line In: set left line in volume
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 1, 0x0017); // Right Line In: set right line in volume
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 2, 0x005B); // Left Headphone Out: set left line out volume
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 3, 0x005B); // Right Headphone Out: set right line out volume
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 4, 0x001A); // Analogue Audio Path Control: set line in ad input, and enable dac
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 5, 0x0000); // Digital Audio Path Control: disable soft mute
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 6, 0x0000); // power down control: power on all
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 7, 0x0041); // left justied, iwl=16-bits, Enable slave Mode
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 8, 0x0002); // Normal, Base Over-Sampleing Rate 384 fs (BOSR=1)
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS){
bSuccess = aduio_RegWrite(device, 9, 0x0001); // active interface
delay_us(1000);}
if (bSuccess == ALT_E_SUCCESS)
printf("[AUDIO] AUDIO_Init success\r\n");
else printf("[AUDIO] AUDIO_Init fail\r\n");
return bSuccess;
}
int main(){
ALT_I2C_DEV_t device;
bool bRecordPress, bPlayPress;
printf("DE1-SoC bare-metal - audio\n");
setup_hps_timer();
// set up the HPS_I2C_CONTROL and HPS_LED GPIO
setup_hps_gpio();
// turn on the HPS_LED and set the HPS_I2C_CONTROL to high so HPS can access audio codec
handle_hps_i2c_control(1);
// initialise the i2c controller device to audio
i2c_init(&device);
// configure the audio codec
audio_config(&device);
return 0;
}
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello sir,
Just curious to know, have you tried this video:
https://www.youtube.com/watch?v=zzIi7ErWhAA
It shows some good information regarding how to run the audio CODEC.
furthermore, you might find some interesting information from this link:
https://github.com/bsteinsbo/DE1-SoC-Sound
You might ignore the linux
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Sir,
Thank you for your kindly reply.
Yes, I look that video already and it gave me the general idea how to configure the audio CODEC at beginning.
However, the language that the video used is VHDL and he used FPGA to initialize the chip.
But I have to use the HPS to control the audio CODEC so it doesn't help after.
For the example from github, I look at it before and I couldn't get any information from it since it's really different than the application without OS and using the HWlib (And I have never used linux before so it's even harder for me to completely understand the code) :(

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page