Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12600 Discussions

Need help to configure the audio CODEC (WM8731) on DE1-SoC board through the HPS

wlin25
Beginner
3,044 Views

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; }

 

0 Kudos
2 Replies
Fawaz_Al-Jubori
Employee
1,613 Views

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

0 Kudos
wlin25
Beginner
1,613 Views

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) :(

 

0 Kudos
Reply