在线时间198 小时
UID3112506
注册时间2016-7-8
NXP金币0
TA的每日心情 | 开心 2021-4-13 21:11 |
---|
签到天数: 550 天 [LV.9]以坛为家II
金牌会员
- 积分
- 2417
- 最后登录
- 2022-6-16
|
本帖基于ok1052进一步完善音频驱动,增加音频接收部分。通过上一贴分析【飞凌RT1052】2、rt-thread 音频驱动分析,主要修改两个文件drv_codec.c和fsl_wm8960.c。
1、wm8960.c主要修改WM8960_Init函数,使能音频wm8960音频输入,代码省略了不需要修改的部分。
- void WM8960_Init(wm8960_handle_t *handle, wm8960_config_t *config)
- {
- ...
- WM8960_WriteReg(handle, WM8960_POWER1, 0xFE);
- ...
- WM8960_WriteReg(handle, WM8960_POWER3, 0x3C);
- ...
- WM8960_WriteReg(handle, WM8960_LINPATH, 0x1B8);
- WM8960_WriteReg(handle, WM8960_RINPATH, 0x138);
- ...
- WM8960_WriteReg(handle, WM8960_INBMIX1, 0x00);
- WM8960_WriteReg(handle, WM8960_INBMIX2, 0x00);
- ...
- ...
- WM8960_WriteReg(handle, WM8960_ADDCTL1, 0x0C0);
- ...
- WM8960_WriteReg(handle, WM8960_LINVOL, 0x117);
- WM8960_WriteReg(handle, WM8960_RINVOL, 0x117);
- }
复制代码
2、drv_codec.c修改,这里主要由4部分。
a、增加音频接收需要的数据结构并增加主控音频外设初始化部分
- struct imxcodec
- {
- ...
- uint8_t rx_started;
- sai_edma_handle_t rxHandle;
- uint8_t rxbuff[RX_BUFFER_SIZE];
- ...
- edma_handle_t dmaRxHandle;
- ...
- };
- static rt_err_t icodec_init(struct rt_audio_device *audio)
- {
- ...
- EDMA_CreateHandle(&icodec->dmaRxHandle, EXAMPLE_DMA, EXAMPLE_RX_CHANNEL);
- ...
- DMAMUX_SetSource(DMAMUX0, EXAMPLE_RX_CHANNEL, EXAMPLE_SAI_RX_SOURCE);
- DMAMUX_EnableChannel(DMAMUX0, EXAMPLE_RX_CHANNEL);
- ...
- SAI_TransferRxCreateHandleEDMA(icodec->sai, &icodec->rxHandle, saidma_callback, audio, &icodec->dmaRxHandle);
- ...
- SAI_TransferRxSetFormatEDMA(icodec->sai, &icodec->rxHandle, format, mclkSourceClockHz, format->masterClockHz);
- ...
- }
复制代码
b、音频设备注册时增加读权限,以便上层应用可以读取音频数据
- int rt_hw_codec_init(void)
- {
- ...
- result = rt_audio_register(audio,"sound0", RT_DEVICE_FLAG_RDWR, &_g_imxcodec);
- ...
- }
复制代码
c、完善音频接收部分,音频接收函数icodec_transmit和接收完成中断回调saidma_callback
- static rt_size_t icodec_transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size)
- {
- ...
- else
- {
- sai_transfer_t xfer;
- xfer.data = (uint8_t *)readBuf;
- xfer.dataSize = size;
- if (size%32 == 0)
- icodec->rxHandle.count = 16;
- else
- icodec->rxHandle.count = 1;
- if (SAI_TransferReceiveEDMA(icodec->sai, &icodec->rxHandle, &xfer) != kStatus_Success)
- return 0;
- return size;
- }
- ...
- }
- static void saidma_callback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
- {
- ...
- struct rt_audio_device *audio = (struct rt_audio_device *)userData;
- struct imxcodec *icodec = audio->parent.user_data;
- if(handle == &icodec->txHandle)
- {
- ind = handle->queueDriver;
- saddr = (rt_uint8_t*)handle->saiQueue[ind].data;
- rt_audio_tx_complete(userData, saddr);
- }
- else if(handle == &icodec->rxHandle)
- {
- rt_audio_rx_done(userData, icodec->rxbuff, RX_BUFFER_SIZE);
- if(icodec->rx_started == 1)
- {
- icodec_transmit(userData, RT_NULL, icodec->rxbuff, RX_BUFFER_SIZE);
- }
- }
- }
复制代码
d、实现音频接收功能的开始icodec_start与停止icodec_stop功能
- rt_err_t icodec_start(struct rt_audio_device *audio,int stream)
- {
- struct imxcodec *icodec = audio->parent.user_data;
- if(stream == AUDIO_STREAM_RECORD)
- {
- icodec->rx_started = 1;
- icodec_transmit(audio, RT_NULL, icodec->rxbuff, RX_BUFFER_SIZE);
- }
- return RT_EOK;
- }
- rt_err_t icodec_stop(struct rt_audio_device *audio,int stream)
- {
- struct imxcodec *icodec = audio->parent.user_data;
- if(stream == AUDIO_STREAM_RECORD)
- {
- icodec->rx_started = 1;
- }
- return RT_EOK;
- }
复制代码
3、编写测试代码sound_test.c,测方法音频回环测试,将接收到的音频数据发送到音频播放。
-
- while(1)
- {
- i = rt_device_read(device, 0, read_buffer, BUFF_SIZE);
- ...
- rt_memcpy(write_buffer, read_buffer, BUFF_SIZE);
- ...
- i = rt_device_write(device, 0, write_buffer, BUFF_SIZE);
- ...
- }
复制代码
4、最后附上代码,用法参考【飞凌RT1052】1、rt-thread移植适配第六部分,覆盖对应文件
代码:
imxrt1052-evk.zip
(1.41 MB, 下载次数: 124)
|
|