我正在尝试使用 LPSPI 通过 DMA 写入 24 位帧。应用并不重要,但在我的例子中,应用是将数据从内存发送到外部 DAC。我想让它与 DMA 一起工作,因为我最终将使用 TCD 链接列表和 PIT 来连续更新 DAC,而不需要 CPU 开销。这是外部 ADC 和 DAC 的常见应用。16 位 DAC/ADC 具有 24 位帧要求也很常见(顶字节用于命令,低字节用于数据)。我不想使用 uint8_t 数据并将传输分成 3 个字节,我想使用 uint32_t 数据并以 24 位帧大小发送,最上面的字节要忽略。
现在来看看 LPSPI 和 DMA 配置。
1.imxRT1060 SDK 的 API LPSPI_MasterInit 函数的 lpspi_master_config_t 结构允许我将 比特每帧 设置为 24。在不使用 DMA 的情况下进行标准传输时,这不成问题。
2.但是,在使用 DMA 和 API 的 LPSPI_MasterTransferEDMA 函数时,eDMA 硬件是否无法处理或支持 24 位帧大小?在 LPSPI_MasterTransferEDMALite 中,DMA 传输宽度在 edma_transfer_config_t 结构中设置。具体来说,srcTransferSize 和 destTransferSize 字段是根据 bytesEachRead 和 bytesLastWrite 值配置的,这些值来自 SPI 帧大小(bytesPerFrame),方法是:....。
/* LPSPI_MasterTransferPrepareEDMALite */
uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
if (bytesPerFrame <= 4U)
{
handle->bytesEachWrite = (uint8_t)bytesPerFrame; // for 24bit frames = 3
handle->bytesEachRead = (uint8_t)bytesPerFrame; // ....
handle->bytesLastRead = (uint8_t)bytesPerFrame; // ....
}/* now back in LPSPI_MasterTransferEDMALite */
switch (handle->bytesEachRead) //bytes each transfer
{
case (1U):
transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes;
transferConfigRx.minorLoopBytes = 1;
if (handle->isByteSwap)
{
addrOffset = 3;
}
break;
case (2U):
transferConfigRx.srcTransferSize = kEDMA_TransferSize2Bytes;
transferConfigRx.minorLoopBytes = 2;
if (handle->isByteSwap)
{
addrOffset = 2;
}
break;
case (4U):
transferConfigRx.srcTransferSize = kEDMA_TransferSize4Bytes;
transferConfigRx.minorLoopBytes = 4;
break;
default:
transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes;
transferConfigRx.minorLoopBytes = 1;
assert(false);
break;
}我们得到的是默认大小写和一个错误,因为没有处理 3 字节的大小写。EDMA 硬件是否支持 3 字节传输?基本上,我想使用uint32_t数据和帧作为3字节并通过DMA传输,忽略最重要的字节。有可能吗?
你好@azone、
非常感谢您关注我们的产品并使用我们的社区。
请查看以下链接,其中描述了 eDMA 支持 1、2、4、8、16、32、64 字节的传输大小,它不支持 24 位(3 字节)的传输大小。
MCUXpresso SDK API 参考手册:EDMA:增强型直接存储器存取 (eDMA) 控制器驱动程序
顺祝商祺!
MayLiu
好的,谢谢你的确认,这样我就不用浪费时间去尝试让它工作了!因此,真正唯一的方法是使用所有内容都设置为 uint8_t 数据,然后使用 klpspi_masterpcsContinuous 作为三个字节发送。这没关系,因为我们对所有其他外设都是这样做的,但是对于16位DAC的实现,这增加了不必要的开销。谢谢。