This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28377D: SPI_DMA方式与外部芯片通信

Part Number: TMS320F28377D

尊敬的TI工程师

您好,我在使用28377d的SPI的DMA模式时发现问题,请求您的帮助解答。

首先我在syscfg中将SPI与DMA配置如下图。

在board.c中生成的初始化部分对应代码如下:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void Board_init()
{
EALLOW;
PinMux_init();
DMA_init();
SPI_init();
EDIS;
}
//*****************************************************************************
//
// PINMUX Configurations
//
//*****************************************************************************
void PinMux_init()
{
//
// PinMux for modules assigned to CPU1
//
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

我在使用该SPI模块时发现,当我使用NonFIFO的primitive模式或pollingFIFO模式时,都能正确传输,但是当我用DMA模式时,传输故障,具体表现为:传输主机端完成发送接收动作后跳出该轮任务并判定传输失败,但从机却一直处在准备态,等待主机发起传输。

我把主机端的SPI应用函数放在下面这里:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
typedef union SPI_ExchangeData
{
uint16_t data16[2]; // 16-bit representation
uint32_t data32; // 32-bit representation
} SPI_ExchangeData;
SPI_ExchangeData gdataSendSPI[DualMCUCommSPI_BUFFER_SIZE_32BIT];
SPI_ExchangeData gdataReceiveSPI[DualMCUCommSPI_BUFFER_SIZE_32BIT];
const void *DualMCUCommSPI_destAddress = (const void*) gdataReceiveSPI;
const void *DualMCUCommSPI_srcAddress = (const void*) gdataSendSPI;
typedef enum
{
PRIMITIVE,
POLLING,
DMA,
} TRANSFER_METHOD;
void DualMCUCommSPI_transfer(TRANSFER_METHOD transferMethod)
{
switch(transferMethod)
{
case PRIMITIVE:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

SPI_DMA的方式我在F28388D上面曾验证测试通过,现在同样的调用方法在F28377D上却行不通,您帮我看看故障原因是DMA配置有误还是调用方式有误,除了开启TX和RX的DMA通道 还需要别的动作吗。

  • 感谢您对TI产品的关注!
    已经收到了您的案例,调查需要些时间,感谢您的耐心等待

  • 加油老铁

  • 你好,

    很抱歉回复延迟。浏览你的帖子,我有一个快速的问题——当你说传输主机完成了发送和接收操作时,你是说在失败之前有一个完整的通信,还是说主机从来没有真正与辅助设备通信,只是准备它?

    如果是前者,请参阅设备TRM中关于连续模式的部分,并确保您正确地重新启用了通道。或者,还要确保所有SPI外围中断标志也被清除。

  • 回答您的问题:主机从来没有真正与从机通信。

    我观察到的现象是:从机先启动,从机的SPI_DMA一直在准备就绪状态,等待主机发起SPI_DMA任务,但主机的SPI任务已结束。

    传输动作的关键部分如下:

    Fullscreen
    1
    2
    3
    4
    DMA_startChannel(SPIA_TX_DMA_BASE);
    DMA_startChannel(SPIA_RX_DMA_BASE);
    while ((DMA_getTransferStatusFlag(SPIA_TX_DMA_BASE))
    || (DMA_getTransferStatusFlag(SPIA_RX_DMA_BASE)));
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    主机执行完SPI_DMA启动通道后,已跳出状态忙等待,并已在执行后续操作,因此我确定主机已结束DMA任务,但由于从机的SPI一直等待,说明主机的SPI消息并未真正发送。我目前的疑点是F28377D是否支持DMA通道开启激活对应的SPI任务,意思是说,由于我用DMA状态作为任务是否完成的判据,有没有可能DMA启动了,但SPI没启动,主机看到DMA搬运完后跳出等待并认为SPI_DMA完成,实则DMA开启并未触发SPI收发。

  • 很抱歉回复延迟。

    你能用示波器观察SPI信号吗?
    请在代码跳出while循环后发送DMA控制寄存器状态的屏幕截图。
    验证FIFO级别是否设置为1?它必须与DMA的突发大小相匹配,该大小设置为1。