主题中讨论的其他部件:TLV320AIC3120, SIMPLELINK-CC13XX-CC26XX-SDK, Z-STACK
大家好,
我有与I2S外设相关的奇怪问题。 我会尽可能详细地描述它。
我正在开发一种可以连接到ZigBee网络并充当门铃的设备。
音频样本存储在外部闪存中。 当触发器来自ZigBee网络时,将从读取音频数据
外部闪存并通过I2S外围设备传输至音频编解码器。 总的来说,它很好,但我正在努力处理一个奇怪的案例。
也就是说,如果执行了配对过程,然后触发器出现,则播放的旋律听起来不像预期的那样(这是噪音或 哮鸣)。
正如我所说,只有在执行配对时才会显示。 无论自播放后配对过程后经过多长时间,我都会听到噪音。 但如果我重置
设备,然后再次发送触发器,音乐播放良好。
现在提供一些技术信息
我正在使用SimpleLink SDK 4.30。
MCU:CC2652R1
音频编解码器:TLV320AIC3120
音频播放器模块在单独的任务中运行,它通过信号与I2S写回调同步。
此任务也是我的应用程序中的最高优先级任务。
你可以在这里看到一些伪代码(因为我不能与你分享真实的代码)。
音频播放器任务和I2S写回:
/* Wait for semaphore posted from I2S write callback. */
bool Audio_WaitForAudioStreamComplete(void){
return Semaphore_pend(audioSemaphoreHandle, BIOS_WAIT_FOREVER);
}
/* AudioPlayer task main loop */
void AudioTask_Main(UArg arg0, UArg arg1){
while(1){
if(Audio_WaitForAudioStreamComplete()){
/* In this function i'm reading audio data from external flash
and put it to the I2S transactions queue.
*/
AudioPlayer_Loop();
}
}
}
/* I2S driver WriteCallback */
static void I2SWriteCallback(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transaction){
/* Check if list is empty... */
/* ... */
// We must consider previous transaction as the current one is not over
I2S_Transaction* finished = (I2S_Transaction*)List_prev(&transaction->queueElement);
if(finished){
// Remove already processed transaction and put it to the list to get new audio data
List_remove(&toWriteAudioStream, (List_Elem*)finished);
finished->queueElement.prev = NULL;
finished->queueElement.next = NULL;
List_put(toReadFromFlashAudioStream, (List_Elem*)finished);
}
/* Check status for errors or I2S_ALL_TRANSACTIONS_SUCCESS */
/* ... */
/* Post semaphore to the AudioTask. */
AudioTask_Wakeup();
}
触发网络连接过程的功能。
/* Send Commisioning request to the stack. */
static void ZigbeeNetwork_JoinRequest(void){
zstack_bdbStartCommissioningReq_t startCommisioniongReq = {
.commissioning_mode = DEFAULT_COMISSIONING_MODE };
Zstackapi_bdbStartCommissioningReq(networkConfig.applicationTaskId, &startCommisioniongReq);
}按下按钮后触发此功能。
我已经使用逻辑分析器进行了一些测量。 这就是我注意到的。
1.当此问题发生在I2SWriteCallback呼叫之间的间隔太长时(因此旋律听起来像噪音)。
您可以在屏幕截图中看到以下内容。
我正在使用以下设置传输音频数据:
采样率:44.1kHz
字长:16位
扬声器:单声道
事务缓冲区大小:256个样本
因此,单个缓冲区的传输应大约花费5.8毫秒,但正如您在上面看到的那样,它从~20毫秒到~40毫秒不等。
下面您可以看到一切正常时的外观:
我还检查了从发布信号到任务唤醒所需的时间,但看起来不错(十分之一微秒)。
我还试图提高I2S hwi的优先级,但没有任何帮助。
我跟踪了从按键到发送通信请求消息的整个执行路径,但没有发现任何可能导致ISR呼叫之间存在如此长的时间间隔的原因。
音频任务是最高优先级,因此不应被任何其他任务取代。 我相信SDK中没有HWI或SWI,它们可以执行超过20毫秒。
我还测量了从外部闪存读取数据的时间,它也适合(大约1毫秒)。 除此之外,这种情况很好,但不包括这一种情况。
现在我注意到了两件奇怪的事。
1.当我将信号超时更改为150 tick或更少时,就不会出现此问题。
我不知道半保尔的超时会对I2S ISR呼叫产生什么影响... RTOS中是否可能存在一些错误?
/* Wait for semaphore posted from I2S write callback. */
bool Audio_WaitForAudioStreamComplete(void){
return Semaphore_pend(audioSemaphoreHandle, /*BIOS_WAIT_FOREVER*/ 100); // OK, no noise, but if timout is higher than 150 then it's not OK :<
}2.当应用程序从除毛刺机启动时,不会出现此问题(即使是Sempahote_pen()中的BIOS_WAY_Forever)。
我尝试从图形分析器工具获取一些信息,但在调试过程中,一切都正常,然后在图表上也正常。


我对此感到很困住了。 如果有人知道我还能检查什么,请告诉我。
我特别想知道这个信号的超时是什么。
此致,
MF