你好@Xanderwangx、
你好@Xanderwangx、
谢谢您的答复。但是,RT 系列不在我的支持范围内。我主要支持 MCX 和 Kinetis 系列。另外,这是MCX频道,不适用于RT产品。
你能在 i.MX RT 跨界 MCU - NXP 社区 下写一篇新文章吗?RT 支持团队将能为您提供帮助。
BR
西莱斯特
MCU :MIMXRT685-EVK (i.MX RT685)
主板 :基于 RT685 的定制产品板。
我正在使用 带有乒乓缓冲区的 循环 DMA 模式 。 DMA 使用 2 个描述符配置
i2s_transferSendLoopdMA ()。在 DMA 回调中,我填充下一个缓冲区,循环自动继续。
void I2S1_TDM_Init(void)
{
I2S_Type *base = I2S1;
/* I2S Configuration */
i2s_config_t cfg;
I2S_TxGetDefaultConfig(&cfg);
cfg.masterSlave = kI2S_MasterSlaveNormalMaster;
cfg.mode = kI2S_ModeDspWsShort; /* TDM = DSP mode */
cfg.divider = 24576000 / (TDM_SAMPLE_RATE * TDM_SLOT_NUM * TDM_SLOT_WIDTH);
cfg.dataLength = TDM_SLOT_WIDTH; /* 32-bit */
cfg.frameLength = TDM_FRAME_LENGTH; /* 256-bit */
cfg.oneChannel = false;
cfg.position = 0;
cfg.wsPol = true; /* DSP A or B */
I2S_TxInit(base, &cfg);
/* Enable 8 slots (Primary + 3 Secondary Channels) */
/* Note: Using 4 channels to cover 8 slots with 32-bit data */
I2S_EnableSecondaryChannel(base, kI2S_SecondaryChannel1, false, 32 * 2);
I2S_EnableSecondaryChannel(base, kI2S_SecondaryChannel2, false, 32 * 4);
I2S_EnableSecondaryChannel(base, kI2S_SecondaryChannel3, false, 32 * 6);
/* DMA Loop Transfer Setup */
DMA_Init(DMA0);
DMA_EnableChannel(DMA0, I2S_TX_DMA_CH);
DMA_SetChannelPriority(DMA0, I2S_TX_DMA_CH, kDMA_ChannelPriority3);
DMA_CreateHandle(&dma_handle, DMA0, I2S_TX_DMA_CH);
I2S_TxTransferCreateHandleDMA(base, &i2s_handle, &dma_handle,
I2S1_Callback, tdm_xfer);
I2S_TransferInstallLoopDMADescriptorMemory(&i2s_handle, tdm_desc, 2);
if (I2S_TransferSendLoopDMA(base, &i2s_handle, &tdm_xfer[0], 2)
!= kStatus_Success) {
while (1); /* Fails if TDM_FRAMES * 8 > DMA_MAX_TRANSFER_COUNT(1024) */
}
}插槽偏移量在电源循环之间是随机的,并非固定值。我之前还尝试过在 DMA 传输前后禁用中断以强制同步,但插槽错位的问题仍然存在。
在 RT685 上,I2S_TransferSendLoopDMA() 是否保证 DMA 启动时对齐到帧边界?如果不行,该如何强制对齐到 WS 边界?
i.MX-RT600