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.

[参考译文] MSPM0G3507:具有 DMA 的 CAN RX

Guru**** 2457760 points
Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1484192/mspm0g3507-can-rx-with-dma

器件型号:MSPM0G3507
主题中讨论的其他器件:SysConfig

工具与软件:

你(们)好、

我想使用 DMA 实现 CAN RX。

是否有任何可供我参考和学习的相应文档、教程、SysConfig 和代码示例?

不幸的是,我没有找到很多合适的。

提前非常感谢。

Matze

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

    尊敬的 Matze:

    我们没有确切的 CAN DMA 示例、但您可以使用基本的 CAN 示例并添加 DMA 以在缓冲区之间移动数据。 重要的部分是正确配置 DMA、以处理从源到目标的数据传输。

    对于 RX、源将是 CAN RX 寄存器、目标将是一些您设置用于接收数据的缓冲区/阵列。 传输次数应为预期报文的大小除以数据包大小。 您需要将目标地址递增、而不是将源地址递增。

    TX 与源递增且目的保持不变完全相反。 转移的数量和规模将是相同的意识形态。  

    我建议在 RX 侧通过 CAN RX 中断触发 DMA (使用事件系统)。

    值得关注的示例:

    • mcan_multi_message_tx
    • mcan_message_rx
    • DMA 交互
      • uart_tx_multibyte_fifo_dma_interrupts
      • uart_rx_multibyte_fifo_interrupts

    此致、
    Luke

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

    谢谢!

    对于 RX 源、我认为必须使用 RX FIFO0起始地址172

    因为我使用的是

    过滤器元素配置 如果过滤器匹配、则存储在 Rx FIFO 0中

    但是、当我查看"Memory"视图时、我只看到以下内容:

    ________________________________________________________________

    关于"memory"视图的第1个问题:

    地址192被"DL_MCAN_msgRAMConfig"占用、尽管我配置了10个 FIFO0元素、并且 FIFO0应在332结束、而不是192结束。

    ________________________________________________________________

    第二个关于存储器视图的问题:

    当我收到 CAN 消息时、该消息不会显示在存储器视图中。 所有值保持不变。 接收本身起作用、因为消息出现在我的 rxMsg-Struct 中。 但为什么我在存储器视图中看不到它?

    ________________________________________________________________

    编辑:恐怕我把 RAM 和 ROM 混淆了。 是这样吗? 我在 RAM 中配置 FIFO0元素的地址。 存储器视图显示了 ROM、对吧?

    是否可以查看消息 RAM FIFO 的内容?

    当我指定源地址时、我如何指示 DMA 引用 RAM 而不是 ROM?

    ________________________________________________________________

    [报价用户 id="452230" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1484192/mspm0g3507-can-rx-with-dma/5700238 #5700238"]uart_rx_multibyte_fifo_interrupts

    我查看了此示例并尝试根据我的项目调整此示例项目中 DMA 的实现。

    我在 main_msp***.c 中添加了以下行:

    volatile uint8_t gRxDataframe[16];
    
    int main(void)
    {
        SYSCFG_DL_init();
    
      /* Configure DMA source, destination and size */
        DL_DMA_setSrcAddr(DMA, DMA_CH0_CANRX_CHAN_ID, (uint32_t)(CAN_Info.gMCAN0MsgRAMConfigParams.rxFIFO0startAddr));
        DL_DMA_setDestAddr(DMA, DMA_CH0_CANRX_CHAN_ID, (uint32_t) &gRxDataframe[0]);
        DL_DMA_enableChannel(DMA, DMA_CH0_CANRX_CHAN_ID);
    
        /* Confirm DMA channel is enabled */
        while (false == DL_DMA_isChannelEnabled(DMA, DMA_CH0_CANRX_CHAN_ID)) {
            __BKPT(0);
        }
    
        NVIC_EnableIRQ(MCAN0_INST_INT_IRQN);
    
        gCheckCAN = false;
    
        DL_SYSCTL_disableSleepOnExit();
        /* Wait in SLEEP mode until DMA interrupt is triggered */
        while (false == gCheckCAN) {
            __WFE();
        }
    
        DL_SYSCTL_enableSleepOnExit();

    我对 SysConfig 进行了以下更改:

    DMA.associatedChannels.create(1);
    DMA.associatedChannels[0].addressMode           = "f2b";
    DMA.associatedChannels[0].srcLength             = "BYTE";
    DMA.associatedChannels[0].dstLength             = "BYTE";
    DMA.associatedChannels[0].configureTransferSize = true;
    DMA.associatedChannels[0].transferMode          = "FULL_CH_REPEAT_BLOCK";
    DMA.associatedChannels[0].transferSize          = 16;
    DMA.associatedChannels[0].destIncrement         = "INCREMENT";
    DMA.associatedChannels[0].enableInterrupt       = true;
    DMA.associatedChannels[0].$name                 = "DMA_CH0_CANRX";
    DMA.associatedChannels[0].peripheral.$assign    = "DMA_CH0";

    我还需要做什么?

    ________________________________________________________________

    我建议在 RX 端通过 CAN RX 中断触发 DMA (使用事件系统)。

    我尝试了许多不同的可能性、但在 SysConfig 中找不到任何解决方案如何将 CAN Rx 中断链接到 DMA (通过事件系统进行任何连接触发)。 请帮助我理解这一点并找到正确的配置方法。

    我有个想法、DL_DMA_startTransfer()可能就是我要查找的函数。

    我将其添加到了 CAN RX 中断中、但在 Rx_Interrupt 和执行后的观察表达式"gRxDataframe"中看不到任何数据DL_DMA_startTransfer()

    提前感谢!

    Matze

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

    尊敬的 Matze:

    对于 RX、DMA 设置看起来正确、我没有设置传输数量、因此请确保对于每次传输要传输的数据量、使用正确的数字。 我必须仔细检查、但 CAN 模块只有 CPU 中断、因此您的过程是正确的、即创建中断处理程序来在收到 RX 中断时启动 DMA 传输。

    不过、显示的存储器地址不是 ROM、它是正常的闪存区域。 我正在查看您需要查看的地址空间、以查看 RX CAN 缓冲区。

    此致、
    Luke

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

    您好、谢谢!

    我没有看到设置的传输次数、因此请确保您对于每次传输的传输数据量具有正确的数字。

    "转账数量"一词是什么意思?

    ________________________________________________________________

    [报价 userid="452230" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1484192/mspm0g3507-can-rx-with-dma/5704929 #5704929"]我正在研究您需要查看哪个地址空间来查看 RX CAN 缓冲区。

    谢谢、我在地址0x2010.0000中快速找到了 CAN RX FIFO0。 我可以看到存储器中从该地址开始接收到的每个 CAN Msg。

    我想知道为什么每个 CAN 帧在该内存中占用42 * 32位。

    根据图21-21、我预期一个具有8个数据字节的 CAN 帧的大小为4 * 32位。

    请澄清;)

    ________________________________________________________________

    还有一个简短的问题:是否可以调整视图以便我在一个新行中看到每个新消息(即在此内存视图中的每个 CAN 帧后有一个换行符)?

    ________________________________________________________________

    我还在"memory"视图中看到了"&gRxDataframe[0]、DMA 传输的目标。 但是、即使我收到一条 CAN 消息、存储器值也保持为"0"、在 FIFO 存储器视图中看到它、并且-通过断点调试-               "DL_DMA_startTransfer (DMA、DMA_CH0_CANRX_CHAN_ID);"已执行。

    我遗漏了什么想法? 仍然会出现什么问题?

    提前感谢! 此致!

    Matze

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

    尊敬的 Matze:

    传输次数为 DMASZ 位、传输大小应为需要传输的总数据大小/传输大小(字节、字、2个字等)。

    这里您的数据看起来确实很奇怪、如果您的数据只应该为1或0、那么看起来像是您只在整个32位 int 中存储1位。。。

    对于元素地址、您应该查看如何 创建 DL_MCAN_readMsgRam ()函数(位于 dl_mcan.c 中)。 我将稍微分解一下、但我确实建议查看该函数、基本上您需要遵循 FIFO 路径、而不是 readMsg 函数、您可以使用 DMA、将 elemAddr 作为源地址、将缓冲区作为目标地址。

    正如您在元素结构中看到的、MCAN 数据包具有一组标头信息和数据。 DL_MCAN_readMsg 函数将分解所有位并将它们放入正确的组织中、因为 DMA 只会直接从寄存器中拉取数据。 因此、您需要对传输进行结构化、以便以预期数据包的倍数传输和递增所有数据。 应使用增量和传输大小来覆盖整个预期数据集

    ---

    /*Start Addr intitial value is from your MCAN_RXF0C_F0SA setting
    ElemSize inital value is from your MCAN_RXESC_F0DS
    idx is from your MCAN_RXF0S_F0GI setting*/
    
    
    startAddr = (uint32_t)(startAddr << 2U);
    elemSize  = DL_MCAN_getMsgObjSize(elemSize);
    elemSize *= 4U;
    elemAddr = startAddr + (elemSize * idx);
    elemAddr += MCAN_MCAN_MSG_MEM;
    DL_MCAN_readMsg((uint32_t) mcan, elemAddr, elem);