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.

[参考译文] DK-TM4C129X:GPIO 触发的 SG DMA 卡在"打开"

Guru**** 2332530 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/599911/dk-tm4c129x-gpio-triggered-sg-dma-stuck-on

器件型号:DK-TM4C129X

我已经建立了一个 UDMA 散聚 DMA 任务列表、该任务列表由 GPIO A7上外部 ADC 忙信号的下降沿触发。  任务列表将 四个16位字写入 SSI1发送 FIFO、将0x80写入 GPIO_Porta_AHB_BASE+GPIO_O_O_ICR 以尝试清除 DMA 请求、然后将主 UDMA DMACHCTL 的启动状态复制回该字以循环 DMA。  在添加循环任务之前、 在启动 UDMA 时、SSI 上出现了一个56 (=14*4)脉冲突发、表明 SSI 设置正确且 DMA 传输正常。

但是、当我添加循环任务时、在 GPIO A7的每个下降沿之后、我在 SSI 上获得连续的时钟脉冲流、而不是预期的56脉冲突发。  将 GPIO A7触发脉冲频率降至10KHz 对连续流没有影响。  这向我表明 DMA 请求一直处于"开启"状态。  写入 GPIO_ICR 没有帮助。  如何清除请求以防止连续时钟脉冲?

下面是开始该过程之前通道控制结构表的开始部分:

以下是上面的主条目指向的任务列表:

以下是 GPIO 寄存器内容:

在符号形式中,以下是主通道控制结构体和任务内容,其中一些由类似于 uDMATaskStructEntry()的例程动态初始化:

//! 线圈推杆主 UDMA 条目指向任务列表

const tDMAControlTable adcPusherUdmaPrimary ={

(((char *) adcPusherUdmaTask)+sizeof (adcPusherUdmaTask)-1、

&(uDmaCcs[niudmaAlternateniadcBusyCoilUdmaChannel].ui32Spare)、

UDMA_CHCTL_DSTINC_32 | UDMA_CHCTL_DSTSIZE_32 |

UDMA_CHCTL_SRCINC_32 | UDMA_CHCTL_SRCSIZE 32 |

UDMA_CHCTL_ARBSIZE_4 |

((sizeof (adcPusherUdmaTask)/sizeof (uint32_t)-1)<< UDMA_CHCTL_XFERSIZE)|

UDMA_CHCTL_XFERMODE_PER_SG、

0

};

uint32_t adcPusherUdmaPrimaryInit;

//! 用于推送器自循环复制的 uDMA 源

uint32_t adcPusherUdmaRequestClear = niadcBusyGpioCoilMask

//! 用于推送 UDMA 请求清除的 UDMA 源

(笑声)

//将主 ADC 向任务列表推送 UDMA。

uDmaCcs[ni:udmaPrimary][niadcBusyCoilUdmaChannel]= adcPusherUdmaPrimary;

//保存循环的重新初始化值。

adcPusherUdmaPrimaryInit = adcPusherUdmaPrimary.ui32Control

//向 SSI 推送一个突发时钟。

uDMATaskAssign (

adcPusherUdmaTask[0]、

sizeof (adcPhusher)/sizeof (adcPhuse[0])、UDMA_SIZE_16、

UDMA_SRC_INC_16、adcPusher、

UDMA_DST_INC_NONE、(void *)(niadcSsi + SSI_O_DR)、

UDMA_ARB_1、UDMA_MODE_MEM_散 射_收集

);

//清除 uDMA 请求。

uDMATaskAssign (

adcPusherUdmaTask[1]、

1、UDMA_SIZE_32、

UDMA_SRC_INC_32、&adcPusherUdmaRequestClear、

UDMA_DST_INC_32、(void *)(niadcBusyGpioCoilPort + GPIO_ICR)、

UDMA_ARB_4、UDMA_MODE_MEM_散 射_收集

);

//循环以重复推杆任务。

uDMATaskAssign (

adcPusherUdmaTask[2]、

1、UDMA_SIZE_32、

UDMA_SRC_INC_32、&adcPusherUdmaPrimaryInit、

UDMA_DST_INC_32、

(void *)&(uDmaCcs[ni:udmaPrimary][niadcBusyCoilUdmaChannel].ui32Control)、

UDMA_ARB_4、UDMA_MODE_MEM_散 射_收集

);

此致、

Leo Bredehoft

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    上面引用的位图可从此处下载:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    它现在可以工作了。 我发现有必要使第一个任务成为外设散聚传输、以便在 GPIO A7的下降沿之后产生 SSI 时钟的单次突发。 无需使用 GPIO_O_ICR 进行清除。

    下面是我在此过程中学到的一些有趣的要点:

    1) 1)要循环、只需恢复通道控制结构体的 ui32Control 域、因为前两个域不会被 UDMA 修改。 这样可以节省 DMA 的一些时间。
    2) 2)两种无类型增量的传输似乎并不总是有效。 到目前为止、所有任务至少在源或目的中都有一个实际增量。
    3) 3)散聚任务和通道控制表条目可能未将 ARBSIZE 字段设置为 UDMA_ARB_1。 UDMA_ARB_4在我的案例中工作正常。
    4) 4)外设散聚传输必须在外设类型列表中包含一个任务。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Leo、
    感谢您分享技巧!