我在 RT600 上有一个使用四个 I2S 端口的新项目。两个用于接收,两个用于发送。我有一个项目正在工作,将音频输入传递到输出(基于示例项目),但需要修改其中一个传递以将数据发送到 DSP 进行处理。我已经查看了文档(存在的很少)和其他示例项目,但似乎缺少有关接收 DMA 中断的关键信息。
我知道我需要两个缓冲区:1 个用于发送到 DSP,而 2 个用于填充传入数据。我可以创建两个缓冲区并将其排队。问题是 I2S DMA 中断在回调中有用户数据,但这个空指针对于特定的 I2S 通道是全局的。它不会根据缓冲区发送或接收数据而改变。所以当中断发生时,不知道刚刚填充或清空了哪个缓冲区。
我认为有一个 DMA 乒乓缓冲区示例项目可以解决问题。但它也只有一个通用用户数据指针。然后中断不指示细节。部分示例代码如下:
sta
tic i2s_transfer_t s_rxTransfer[2] = {{
.data = s_Buffer[0],
.dataSize = DEMO_BUFFER_SIZE,
},
{
.data = s_Buffer[1],
.dataSize = DEMO_BUFFER_SIZE,
}};
static i2s_transfer_t s_txTransfer[2] = {{
.data = s_Buffer[1],
.dataSize = DEMO_BUFFER_SIZE,
},
{
.data = s_Buffer[0],
.dataSize = DEMO_BUFFER_SIZE,
...
I2S_TxTransferCreateHandleDMA(DEMO_I2S_TX, &s_TxHandle, &s_DmaTxHandle, TxCallback, (void *)&s_txTransfer);
I2S_RxTransferCreateHandleDMA(DEMO_I2S_RX, &s_RxHandle, &s_DmaRxHandle, RxCallback, (void *)&s_rxTransfer);
I2S_TransferInstallLoopDMADescriptorMemory(&s_TxHandle, s_txDmaDescriptors, 2U);
I2S_TransferInstallLoopDMADescriptorMemory(&s_RxHandle, s_rxDmaDescriptors, 2U);
if (I2S_TransferSendLoopDMA(DEMO_I2S_TX, &s_TxHandle, &s_txTransfer[0], 2U) != kStatus_Success)
{
assert(false);
}
if (I2S_TransferReceiveLoopDMA(DEMO_I2S_RX, &s_RxHandle, &s_rxTransfer[0], 2U) != kStatus_Success)
{
assert(false);
}
while (1)
{
}
}
static void TxCallback(I2S_Type *base, i2s_dma_handle_t *handle, status_t completionStatus, void *userData)
{
i2s_transfer_t *transfer = userData;
__NOP();
// Where is the data located?
if (transfer->data == s_Buffer[0])
{
// Code never gets here!!!!
__NOP();
}
else if (transfer->data == s_Buffer[1])
{
__NOP();
}
}
static void RxCallback(I2S_Type *base, i2s_dma_handle_t *handle, status_t completionStatus, void *userData)
{
i2s_transfer_t *transfer = userData;
__NOP();
// Where is the data located?
if (transfer->data == s_Buffer[0])
{
__NOP();
}
else if (transfer->data == s_Buffer[1])
{
// Code never gets here...!!!!!
__NOP();
}
}
I2S_TxTransferCreateHandleDMA (Rx) 函数分配用户数据并保持静态,无论哪个缓冲区已填充以生成中断。
是否有我在驱动程序库中没有找到的功能?这应该怎么做?理想情况下,ISR 回调中的用户数据似乎会指向应用程序应该处理的缓冲区。