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.

[参考译文] SK-AM64:如何将 DMA 用于使用裸机的 CPSW

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1230751/sk-am64-how-to-use-dma-for-cpsw-using-bare-metal

器件型号:SK-AM64
主题中讨论的其他器件:AM6442SysConfig

您好!

 

(我的请求、如果您愿意、请跳过):

首先、我想谈一谈 TI 文档的糟糕之处有多么荒谬。 一年前我选择了在 AM64x 上进行开发、因为在简要阅读完产品页面和参考手册后、我了解到支持裸机/寄存器编程、您可以控制 SOC。 几个月后,我意识到我是如此的错误。 如此强大的硬件才是真正的浪费、因为只有 TI 自己知道如何使用它、甚至不知道(在浏览过 TI e2e 论坛之后)。 文档制作过程就像通过一个工具解析了源代码,将其转换为 HTML 页一样,一个随机的人只是对高级功能发表一个线性评论,甚至不会解释什么是函数参数。 如果我知道文件是如此糟糕,我将永远不会选择这个平台的发展,但我实施了太多的努力,时间,和大脑损害,在这一点退出将是这样的浪费一切。 因此、现在的信息几乎可以忽略不计、我能够编写自己的引导 API、时钟、DDR、GPIO、UART、 参考手册中的 MMCSD、PRU、PRU 高速 GPIO、PRU RMII、CPSW、中断控制器和 R5F 上的任务切换。 只编写了令人满意的部分:焊盘配置、GPIO 和 UART。 糟糕的情况是配置 PRU、学习如何对 PRU 进行编程、以及了解如何编写汇编代码、PRU 的 RMII 接口和 CPSW。 DDR 文档完全不存在。 我以某种方式设法通过对 GEL 脚本进行逆向工程来运行 DDR、尽管我不知道它是如何工作的、但它确实如此。 因此、现在很遗憾、AM6442电路板上的任何地方、我都不得不自愿地在 SK-AM64x 上使用相同的 DDR 芯片、并且会遇到库存问题。 虽然我不得不在 TI 提供的某些地方使用 SCICLIENT API、因为 DMSC 是专有的、没有文档、并且对于我来说太复杂、难以进行逆向工程。

 

目标:

我正在尝试使用 BareMetal 使用 AM6442构建基于 EtherCAT 的 CNC 运动控制器(我无法使用 LinuxRT、原因太多、无法在此处讨论)。 目前、我使用 SK-AM64x 进行原型设计。 此电路板上有两个以太网端口:一个是 CPSW、一个是 CPSW 和 ICSSG。 我成功运行了 ICSSG。 我需要为应用提供两个以太网端口、一个用于 EtherCAT、另一个用于与 Windows PC 通信。 我目前已经成功地实现了一个到 Windows 的1Gbps 链路、用于通过 Step Dir 控制 ICSSG 上的 CNC。 现在我还需要一个用于 EtherCAT 的 CSSG、因此我将针对 EtherCAT 使用 ICSSG、针对 Windows 使用 CSPW ONE。

 

问题:

我想使用裸机/寄存器编程对 CSPW 进行编程。 根据文档、从 CPSW 读取数据的唯一方法是使用 DMA。 我的确成功配置了 CPSW (我认为是这样)、但我无法配置 DMA 以从 CPSW 读取数据。 TRM 显示 CPSW 通过 PSIL 发送数据。 我不确定、但根据我的理解、您需要 PKTDMA 才能从 PSIL 读取数据。 由于 PSIL 寄存器看起来太小、并且不足以直接从 CPSW 获取数据、请更正我的错误。 TRM 还提到使用 RINGACC 来使用 PKTDMA。 我本来可以独自完成所有这一切、但在解释 DMA 的工作原理以及如何配置方面、相关文档却极其缺乏。 我试图通过深入 TI Nortos CPSW 示例来理解所有这些内容、但后来又放弃了、因为代码非常庞大、以至于只能从 CPSW 读取数据包数据、而且根本无法发挥任何作用。 在示例中、DMA INIT 函数似乎对 DMA 寄存器什么也没做、而是更多地是填充自己的数据结构和处理信标。 RM init 函数使用 sciclent 的原因是我不明白的、TRM 提到了一些有关 PSIL 线程配对的东西、但我不明白为什么你需要 DMSC 来执行它、以及为什么 R5或 A53内核不能执行它。 这里没有关于如何将 DMA 连接到 CPSW、如何将 RINGACC 连接到 DMA、如何处理以太网和 DMA 描述符以及将它们放置在何处并按照什么顺序馈送到哪个寄存器的信息。 没有任何意义、甚至开始解释事情必须按照什么顺序进行。 我很确定我有很多事情与我的理解错误,请原谅我,如果我太远。 到目前为止、DMA 文档是 TRM 中最糟糕的。 我本来想写这一段的、以便于阅读、但 DMA 所尝试的内容并没有开头或结尾。 "我知道,我一定会喜欢的。" 我是否可以阅读任何资源以便于理解内容?

 

我的问题顺序随机:

1.) 是否有办法可以在没有 DMA 或 PSIL 的情况下直接从 CPSW 读取数据包数据? (我认为答案是否定的、但值得一试。)

2.) 我只能在不使用 PKTDMA 的情况下直接从 PSIL 寄存器读取分组数据吗?

3.) 是否可以在不使用 RINGACC 的情况下直接从 PKDMTA 读取分组数据?

4.) 如何将 DMA 连接到 CPSW?

5.) 从 CPSW 读取数据而忽视效率的最低配置是什么?

6.) 主机/缓冲区/传输请求解码器的放置位置?

7.) DMA 寄存器的编程顺序是什么?

8.) 是否有一个具有类似 CPSW 的类似 SOC 可以正常工作并有详尽文档记录、以便我可以阅读它的 TRM 来了解 AM64x 的相关信息?

编辑:我修复了我的坏语法:)

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

    Abhimanyu,

    感谢您提供详尽的反馈。 让我 看看你的所有问题,并回到你. 请预计下周前回复。

    此致

    安舒

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

    尊敬的  Abhimanyu:

    根据我的理解、您使用的是来自 R5F 的 CPSW、所使用的是 NORTOS。  

    您可以在以下位置找到参考的示例:

    C:\ti\mcu_plus_sdk_am64x_08_05_00_24\examples\networking\lwip\enet_cpsw_rawttpserver\am64x-evm\r5fss0-0_nortos

    C:\ti\mcu_plus_sdk_am64x_08_05_00_24\examples\networking\enet_layer2_cpsw\am64x-sk\r5fss0-0_freertos

    您正在使用哪个 SDK 基线?

    此致

    阿什瓦尼

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

    尊敬的 Ashwani Goel:

    是的、我使用的是同一个 SDK。 我已经多次尝试尝试了解 Enet 示例。 但它们是没有道理的,因为问题是多方面的。 这就意味着、例如、rawhttpserver 示例中有多个组件一起工作、这使得单独了解每个组件变得非常困难。 我假设、该示例需要执行以下步骤:启用所有模块并配置其时钟、配置 MDIO、使用 MDIO 外设配置 PHY、配置 CPSW、配置 ENET 驱动程序、以某种方式从 UDMA 接收和发送数据、以及最重要的是将所有数据移植到 LWIP。 好的、这并不是了解如何使用 API 的好示例。 这就像要求某人通过只给他们提供源代码来了解 Windows 的工作方式一样。 这就是我很久以前放弃使用 NORTOS 库、而是通过读取 TRM 来使用寄存器编程的原因、因为它相对更容易。 我并不是说这很容易,但至少 TRM 打算解释它的含义,不像 NORTOS API 文档。 例如、考虑 MCU+SDK 文档中的以下示例:

    ◆ EnetDma_openRxCh()
    EnetDma_RxChHandle EnetDma_openRxCh	(	EnetDma_Handle 	hDma,
    const void * 	pRxChCfg 
    )		
    Enet DMA open RX channel.
    
    Opens the Enet DMA RX channel based on the channel parameters. This function configures the DMA channel. This also configures event if notifyCb is not null. Refer to SOC DMA specific RX channel config structure for specific config details.
    
    Enet DMA is peripheral-aware as peripherals in a given SoC may need different handling, i.e. DMA descriptor's extra fields having different meaning for two peripherals using same DMA engine. This peripheral-awareness is given to the RX channel/flow via EnetDma_Handle passed at open time.
    
    Parameters
    hDma	Enet DMA handle
    pRxChCfg	RX channel configuration parameters. This parameter can't be NULL.
    Returns
    RX channel opaque handle if opened. Otherwise, NULL.

    在整个文档的任何一页中都无法了解必须传递到 pRxChCfg 参数的内容。 甚至有人会如何猜测如何使用此函数? 您应该参考这些示例以了解它是如何工作的。 是的、我可以深入研究代码、找到使用了某些函数但并非所有函数的地方。 在大多数情况下、我们不打算在示例所要使用的函数中使用这些函数、我很少谈到这是错误的层级数。 注意我的语言、但 MCU + SDK 中的 API 参考部分简直是垃圾、 而指南部分,如网络部分只是在他们的解释是不完整的,就像如果你想教某人如何驾驶一辆汽车,唯一的解释是如何把钥匙在钥匙孔和转动钥匙。 我的意思是、MCU + SDK 在任何地方都没有提到如何在 Enet API 中接收或发送数据。 每个指南章节都是如此。

    我需要的是一些关于如何编程这些模块的文献、并附有合理的解释。 我现在确实期望是勺子吃的,并有代码写给我。 我已准备好投入辛勤的工作、并像 TRM 一样了解信息、然后像为每个其他外设/模块所做的那样单独对每个寄存器进行编程。 但 DMA 部分的 TRM 不完整。 我刚才已提及在原来的质询中,有甚么问题。 此外、如果您能开始回答其中的一些问题、我将不胜感激:

    [报价用户 id="540037" url="~/support/processors-group/processors/f/processors-forum/1230751/sk-am64-how-to-use-dma-for-cpsw-using-bare-metal "]

    我的问题顺序随机:

    1.) 是否有办法可以在没有 DMA 或 PSIL 的情况下直接从 CPSW 读取数据包数据? (我认为答案是否定的、但值得一试。)

    2.) 我只能在不使用 PKTDMA 的情况下直接从 PSIL 寄存器读取分组数据吗?

    3.) 是否可以在不使用 RINGACC 的情况下直接从 PKDMTA 读取分组数据?

    4.) 如何将 DMA 连接到 CPSW?

    5.) 从 CPSW 读取数据而忽视效率的最低配置是什么?

    6.) 主机/缓冲区/传输请求解码器的放置位置?

    7.) DMA 寄存器的编程顺序是什么?

    8.) 是否有一个具有类似 CPSW 的类似 SOC 可以正常工作并有详尽文档记录、以便我可以阅读它的 TRM 来了解 AM64x 的相关信息?

    [/报价]

    谢谢

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

    尊敬的 Abhimanyu:

    我假定:启用所有模块并配置它们的时钟、配置 MDIO、使用 MDIO 外设配置 PHY、配置 CPSW、配置 ENET 驱动程序、以某种方式从 UDMA 接收和传输数据、以及最重要的是将所有这些数据移植到 LWIP。 好的、这并不是了解如何使用 API 的好示例。 这就像要求某人通过只给他们提供源代码来了解 Windows 的工作方式。

    感谢您解释痛点。 我确认描述 DMA 的使用并不简单。 示例中使用的 API 在其下方具有多个层。 我已经向开发团队传达了您的信息。  

    1.) 是否有办法可以在没有 DMA 或 PSIL 的情况下直接从 CPSW 读取数据包数据? (我相信答案是否定的、但值得一试。)

    我正在与开发团队合作、以获取您的问题的答案

    请允许我花点时间与您联系。

    此致

    阿什瓦尼

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

    感谢你的帮助 Ashwani ,我非常伟大。 我们将热切地等待您的回复。

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

    尊敬的 Abhimanyu:

    我会继续发布回复可能不是按顺序进行的。

    1.) 是否有办法可以在没有 DMA 或 PSIL 的情况下直接从 CPSW 读取数据包数据? (我相信答案是否定的、但值得一试。)

    否。  DMA 接口为 PSIL。

    此致

    阿什瓦尼

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

    硬件接口为 PSIL。

    此致

    阿什瓦尼

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

    您能详细说明一下吗? 如何对 PSIL 接口进行编程? 以下是 TRM 中的一个片段:

    基本上只有六个寄存器、其中前两个不言自明、剩下的只有4个寄存器。 如果不是太 麻烦,你能提供一个小代码或示例,解释如何使用它们。 也许从其他一些不是 AM64x 的器件也可以、我只需要有关如何使用这些寄存器4寄存器来连接 PSIL 的提示。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    2.) 我只能在不使用 PKTDMA 的情况下直接从 PSIL 寄存器读取数据包数据吗?

    不会将 PSIL 的数据端口映射到 MMR、因此只能通过设置通道描述符并将数据包发送到存储器来读取数据包。

    此致

    阿什瓦尼

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

    我明白了、因此 PKTDMA 是从 CPSW 获取数据的容器

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    3.) 是否可以在不使用 RINGACC 的情况下直接从 PKDMTA 读取数据包?

    对于 PKTDMA、没有 RINGACC、您只需将数据包提交到 PKTDMA 的 RING 和 RINGRT 区域中通道的环网。

    此致

    阿什瓦尼

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    5. 从 CPSW 读取数据而忽略效率的最低配置是什么?

    启用该通道并在该通道的环形基址创建一个主机描述符、然后向门铃寄存器写入该通道的1。

    6.) 在哪里放置主机/缓冲区/传输请求解码器?

    DMA 可以访问的任何存储器。 但到 DMA 的延迟最低的内部 SRAM 将提供最佳性能、

    此致

    阿什瓦尼

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

    尊敬的 Ashwani:

    感谢您这么长时间的跟进。 我感谢您的持续支持。 同时、我试图抓取"enet_layer2_cpsw"示例以了解其工作原理。 我设法计算了什么是 uDMA 函数被调用、以及为了更好地理解、虽然问题比答案还多、但我认为这是进展。

    启用通道并在通道的环形基址创建单个主机描述符,然后为通道向门铃寄存器写入1。

    因此我编写了一些使用 uDMA API 的小代码来准确执行您所要求的操作。 很遗憾、无法正常工作、我怀疑这是因为 RX 通道配置不正确。 看,如果你能理解我做错了什么,请原谅我,如果我离得太远:

    struct EthernetFrame
    {
        uint8 MACreciever[6];
        uint8 MACsender[6];
        uint16 typecode;
        uint8 raw[1518];
        uint32 crc;
    };
    
    Udma_DrvObject udmadriver;
    
    Udma_ChObject udmarxchdriver;
    Udma_RingObject* udmarxringhandle;
    
    uint64 ringrx[32] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    
    struct FrameDescriptor
    {
        struct PacketDescriptor
        {
            uint32 packetinfo[4];
            uint32 linkinginfo[2];
            uint32 bufferinfo[3];
            uint32 originalbufferinfo[3];
            uint32 extendedpacketinfo[16];
            uint32 protocolspecificdata[16];
            uint32 reserved[48];
        }packetdescriptor[4];
        EthernetFrame frame;
    
        FrameDescriptor()
        {
            //Broken down 1536 bytes ethernet frame into 4 parts becuase this is what is done in the "enet_layer2_cpsw" example
            //Also the rest of descriptor config is almost similar to the example
            
            packetdescriptor[0].packetinfo[0] = 0x61000000;
            packetdescriptor[0].linkinginfo[0] = (uint32)&packetdescriptor[1];
            packetdescriptor[0].bufferinfo[0] = (uint32)&frame + 0x0000;
            packetdescriptor[0].bufferinfo[2] = 0x180;
            packetdescriptor[0].originalbufferinfo[0] = packetdescriptor[0].bufferinfo[2];
            packetdescriptor[0].originalbufferinfo[1] = packetdescriptor[0].linkinginfo[0];
    
            packetdescriptor[1].packetinfo[0] = 0;
            packetdescriptor[1].linkinginfo[0] = (uint32)&packetdescriptor[2];
            packetdescriptor[1].bufferinfo[0] = (uint32)&frame + 0x0180;
            packetdescriptor[1].bufferinfo[2] = 0x180;
            packetdescriptor[1].originalbufferinfo[0] = packetdescriptor[1].bufferinfo[2];
            packetdescriptor[1].originalbufferinfo[1] = packetdescriptor[1].linkinginfo[0];
    
            packetdescriptor[2].packetinfo[0] = 0;
            packetdescriptor[2].linkinginfo[0] = (uint32)&packetdescriptor[3];
            packetdescriptor[2].bufferinfo[0] = (uint32)&frame + 0x0300;
            packetdescriptor[2].bufferinfo[2] = 0x180;
            packetdescriptor[2].originalbufferinfo[0] = packetdescriptor[2].bufferinfo[2];
            packetdescriptor[2].originalbufferinfo[1] = packetdescriptor[2].linkinginfo[0];
    
            packetdescriptor[3].packetinfo[0] = 0;
            packetdescriptor[3].linkinginfo[0] = 0;
            packetdescriptor[3].bufferinfo[0] = (uint32)&frame + 0x480;
            packetdescriptor[3].bufferinfo[2] = 0x180;
            packetdescriptor[3].originalbufferinfo[0] = packetdescriptor[3].bufferinfo[2];
            packetdescriptor[3].originalbufferinfo[1] = packetdescriptor[3].linkinginfo[0];
        }
    }framedescriptor[32];
    
    int main()
    {
        //All other peripherals including CPSW have already been initialised in the custom SBL so this main intents to use DMA for learning purpose
    
        uint32 status = 0;
        status = Sciclient_init(CSL_CORE_ID_R5FSS0_0);
    
    
        Udma_InitPrms udmaparameters;
        udmaparameters.instId             = UDMA_INST_ID_PKTDMA_0;
        udmaparameters.skipGlobalEventReg = 0;
        udmaparameters.virtToPhyFxn       = Udma_defaultVirtToPhyFxn;
        udmaparameters.phyToVirtFxn       = Udma_defaultPhyToVirtFxn;
        status = Udma_init(&udmadriver, &udmaparameters);
    
        Udma_ChPrms udmarxchparameters;
        Udma_ChRxPrms udmarxchrxparameters;
        UdmaChPrms_init(&udmarxchparameters, UDMA_CH_TYPE_RX_MAPPED);
        UdmaChRxPrms_init(&udmarxchrxparameters, UDMA_CH_TYPE_RX_MAPPED);
        udmarxchparameters.chNum = 16;//UDMA_DMA_CH_ANY;
        udmarxchparameters.peerChNum = UDMA_PSIL_CH_CPSW2_RX;
        udmarxchparameters.mappedChGrp =  UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxchparameters.appData = 0;
        udmarxchparameters.fqRingPrms.ringMem = &ringrx;
        udmarxchparameters.fqRingPrms.ringMemSize = sizeof(ringrx);
        udmarxchparameters.fqRingPrms.mode = 0;
        udmarxchparameters.fqRingPrms.elemCnt = 32;
        udmarxchparameters.fqRingPrms.elemSize = UDMA_RING_ES_8BYTES ;
        udmarxchparameters.fqRingPrms.orderId = 0;
        udmarxchparameters.fqRingPrms.asel = UDMA_RINGACC_ASEL_ENDPOINT_PHYSADDR;
        udmarxchparameters.fqRingPrms.mappedRingGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxchrxparameters.dmaPriority = 1;
        udmarxchrxparameters.configDefaultFlow = 0;
        status = Udma_chOpen (&udmadriver, &udmarxchdriver,UDMA_CH_TYPE_RX_MAPPED, &udmarxchparameters);
        status = Udma_chConfigRx(&udmarxchdriver, &udmarxchrxparameters);
        status = Udma_chEnable(&udmarxchdriver);
        udmarxringhandle = (Udma_RingObject*)Udma_chGetFqRingHandle(&udmarxchdriver);
    
        for(uint32 i=0; i < 1; i++)
        {
            status = Udma_ringQueueRaw(udmarxringhandle,(uint32)&framedescriptor[i]);
        }
    
        for(int32 i=0; i < 1; i++)
        {
            uint64* pointer = (uint64*)(&framedescriptor[i]);
            status = Udma_ringDequeueRaw(udmarxringhandle, pointer);                // I get status value -4 over here digging into the Udma_ringDequeueRaw I see it returns as failure because the ring is empty
            if(status != 0)
                i--;
        }
    
        while(1)
        {
        }
    
    }

    我怀疑我还需要使用以下函数:

    1.udma_flowAttached

    uDMA_flowConfig

    因为它们在"enet_layer2_cpsw"示例中被触发。 我编写了一个使用这两个函数的代码变体、但没有改变结果。

    由于某种神秘的原因、"enet_layer2_cpsw"示例创建了两个环、并调用 udma_flowAttachMapped 和 udma_flowConfig 两次。

    如果您知道原因、敬请告知。

    再次感谢您的支持。

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

    以下是即使使用流 API 且所有 configs 都作为 ditto 的变体的代码、如 "enet_layer2_cpsw"中使用的示例:

    Udma_DrvObject udmadriver;
    
    Udma_ChObject udmarxchdriver;
    Udma_RingObject udmarxringhandle0;
    Udma_RingObject udmarxringhandle1;
    uint64 ringrx0[2] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    uint64 ringrx1[32] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    Udma_FlowObject_t udmarxflowdriver0;
    Udma_FlowObject_t udmarxflowdriver1;
    
    struct FrameDescriptor
    {
        EthernetFrame frame;
        struct PacketDescriptor
        {
            uint32 packetinfo[4];
            uint32 linkinginfo[2];
            uint32 bufferinfo[3];
            uint32 originalbufferinfo[3];
            uint32 extendedpacketinfo[16];
            uint32 protocolspecificdata[16];
            uint32 reserved[48];
        }packetdescriptor[4];
    
        FrameDescriptor()
        {
            packetdescriptor[0].packetinfo[0] = 0x61000000;
            packetdescriptor[0].linkinginfo[0] = (uint32)&packetdescriptor[1];
            packetdescriptor[0].bufferinfo[0] = (uint32)&frame + 0x0000;
            packetdescriptor[0].bufferinfo[2] = 0x180;
            packetdescriptor[0].originalbufferinfo[0] = packetdescriptor[0].bufferinfo[2];
            packetdescriptor[0].originalbufferinfo[1] = packetdescriptor[0].linkinginfo[0];
    
            packetdescriptor[1].packetinfo[0] = 0;
            packetdescriptor[1].linkinginfo[0] = (uint32)&packetdescriptor[2];
            packetdescriptor[1].bufferinfo[0] = (uint32)&frame + 0x0180;
            packetdescriptor[1].bufferinfo[2] = 0x180;
            packetdescriptor[1].originalbufferinfo[0] = packetdescriptor[1].bufferinfo[2];
            packetdescriptor[1].originalbufferinfo[1] = packetdescriptor[1].linkinginfo[0];
    
            packetdescriptor[2].packetinfo[0] = 0;
            packetdescriptor[2].linkinginfo[0] = (uint32)&packetdescriptor[3];
            packetdescriptor[2].bufferinfo[0] = (uint32)&frame + 0x0300;
            packetdescriptor[2].bufferinfo[2] = 0x180;
            packetdescriptor[2].originalbufferinfo[0] = packetdescriptor[2].bufferinfo[2];
            packetdescriptor[2].originalbufferinfo[1] = packetdescriptor[2].linkinginfo[0];
    
            packetdescriptor[3].packetinfo[0] = 0;
            packetdescriptor[3].linkinginfo[0] = 0;
            packetdescriptor[3].bufferinfo[0] = (uint32)&frame + 0x480;
            packetdescriptor[3].bufferinfo[2] = 0x180;
            packetdescriptor[3].originalbufferinfo[0] = packetdescriptor[3].bufferinfo[2];
            packetdescriptor[3].originalbufferinfo[1] = packetdescriptor[3].linkinginfo[0];
    
        }
    }framedescriptor[32];
    
    int main()
    {
        uint32 status = 0;
        status = Sciclient_init(CSL_CORE_ID_R5FSS0_0);
    
        Udma_InitPrms udmaparameters;
        udmaparameters.instId             = UDMA_INST_ID_PKTDMA_0;
        udmaparameters.skipGlobalEventReg = 0;
        udmaparameters.virtToPhyFxn       = Udma_defaultVirtToPhyFxn;
        udmaparameters.phyToVirtFxn       = Udma_defaultPhyToVirtFxn;
        status = Udma_init(&udmadriver, &udmaparameters);
    
        Udma_ChPrms udmarxchparameters;
        Udma_ChRxPrms udmarxchrxparameters;
        UdmaChPrms_init(&udmarxchparameters, UDMA_CH_TYPE_RX_MAPPED);
        UdmaChRxPrms_init(&udmarxchrxparameters, UDMA_CH_TYPE_RX_MAPPED);
        udmarxchparameters.chNum = 16;//UDMA_DMA_CH_ANY;
        udmarxchparameters.peerChNum = UDMA_PSIL_CH_CPSW2_RX;
        udmarxchparameters.mappedChGrp =  UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxchparameters.appData = 0;
        udmarxchrxparameters.dmaPriority = 1;
        udmarxchrxparameters.configDefaultFlow = 0;
        status = Udma_chOpen (&udmadriver, &udmarxchdriver,UDMA_CH_TYPE_RX_MAPPED, &udmarxchparameters);
        status = Udma_chConfigRx(&udmarxchdriver, &udmarxchrxparameters);
        status = Udma_chEnable(&udmarxchdriver);
    
        Udma_RingPrms udmarxring0parameters;
        UdmaRingPrms_init (&udmarxring0parameters);
        udmarxring0parameters.ringMem = & ringrx0;
        udmarxring0parameters.ringMemSize = sizeof(ringrx0);
        udmarxring0parameters.mode = 0;
        udmarxring0parameters.elemCnt = 2;
        udmarxring0parameters.elemSize = UDMA_RING_ES_8BYTES;
        udmarxring0parameters.orderId = 0;
        udmarxring0parameters.asel = UDMA_RINGACC_ASEL_ENDPOINT_PHYSADDR;
        udmarxring0parameters.mappedRingGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxring0parameters.mappedChNum = 16;
        status = Udma_ringAlloc(&udmadriver,&udmarxringhandle0,UDMA_RING_ANY,&udmarxring0parameters);
    
        Udma_FlowAllocMappedPrms udmarxflowallocmappedparameters0;
        udmarxflowallocmappedparameters0.mappedChNum = 17;              //Why is this 17 I didnt know why I just blindly copied
        udmarxflowallocmappedparameters0.mappedFlowGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        status = Udma_flowAttachMapped(&udmadriver, &udmarxflowdriver0, 17, &udmarxflowallocmappedparameters0);  //Why is flow num 17 I didnt know why I just blindly copied
    
        Udma_FlowPrms udmarxflowparameters0;
        UdmaFlowPrms_init(&udmarxflowparameters0, UDMA_CH_TYPE_RX);
        udmarxflowparameters0.errorHandling = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_ERR_DROP;
        udmarxflowparameters0.psInfoPresent = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_PSINFO_PRESENT;
        udmarxflowparameters0.defaultRxCQ = Udma_ringGetNum(&udmarxringhandle0);
        udmarxflowparameters0.fdq0Sz0Qnum = Udma_ringGetNum(&udmarxringhandle0);
        udmarxflowparameters0.fdq0Sz1Qnum = Udma_ringGetNum(&udmarxringhandle0);
        udmarxflowparameters0.fdq0Sz2Qnum = Udma_ringGetNum(&udmarxringhandle0);
        udmarxflowparameters0.fdq0Sz3Qnum = Udma_ringGetNum(&udmarxringhandle0);
        udmarxflowparameters0.fdq1Qnum = Udma_ringGetNum(&udmarxringhandle0);
        udmarxflowparameters0.fdq2Qnum = Udma_ringGetNum(&udmarxringhandle0);
        udmarxflowparameters0.fdq3Qnum = Udma_ringGetNum(&udmarxringhandle0);
        status = Udma_flowConfig(&udmarxflowdriver0, 0, &udmarxflowparameters0);
    
        Udma_RingPrms udmarxring1parameters;
        UdmaRingPrms_init (&udmarxring1parameters);
        udmarxring1parameters.ringMem = & ringrx1;
        udmarxring1parameters.ringMemSize = sizeof(ringrx1);
        udmarxring1parameters.mode = 0;
        udmarxring1parameters.elemCnt = 32;
        udmarxring1parameters.elemSize = UDMA_RING_ES_8BYTES;
        udmarxring1parameters.orderId = 0;
        udmarxring1parameters.asel = UDMA_RINGACC_ASEL_ENDPOINT_PHYSADDR;
        udmarxring1parameters.mappedRingGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxring1parameters.mappedChNum = 16;
        status = Udma_ringAlloc(&udmadriver,&udmarxringhandle1,UDMA_RING_ANY,&udmarxring1parameters);
    
        Udma_FlowAllocMappedPrms udmarxflowallocmappedparameters1;
        udmarxflowallocmappedparameters1.mappedChNum = 16;
        udmarxflowallocmappedparameters1.mappedFlowGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        status = Udma_flowAttachMapped(&udmadriver, &udmarxflowdriver1, 18, &udmarxflowallocmappedparameters1);     //Why is flow num 18 I didnt know why I just blindly copied
    
        Udma_FlowPrms udmarxflowparameters1;
        UdmaFlowPrms_init(&udmarxflowparameters1, UDMA_CH_TYPE_RX);
        udmarxflowparameters1.errorHandling = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_ERR_DROP;
        udmarxflowparameters1.psInfoPresent = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_PSINFO_PRESENT;
        udmarxflowparameters1.einfoPresent = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_EINFO_PRESENT;
        udmarxflowparameters1.srcTagLoSel = 4;
        udmarxflowparameters1.sizeThresh0 = 1536;
        udmarxflowparameters1.sizeThresh1 = 1536;
        udmarxflowparameters1.sizeThresh2 = 1536;
        udmarxflowparameters1.defaultRxCQ = Udma_ringGetNum(&udmarxringhandle1);
        udmarxflowparameters1.fdq0Sz0Qnum = Udma_ringGetNum(&udmarxringhandle1);
        udmarxflowparameters1.fdq0Sz1Qnum = Udma_ringGetNum(&udmarxringhandle1);
        udmarxflowparameters1.fdq0Sz2Qnum = Udma_ringGetNum(&udmarxringhandle1);
        udmarxflowparameters1.fdq0Sz3Qnum = Udma_ringGetNum(&udmarxringhandle1);
        udmarxflowparameters1.fdq1Qnum = Udma_ringGetNum(&udmarxringhandle1);
        udmarxflowparameters1.fdq2Qnum = Udma_ringGetNum(&udmarxringhandle1);
        udmarxflowparameters1.fdq3Qnum = Udma_ringGetNum(&udmarxringhandle1);
        status = Udma_flowConfig(&udmarxflowdriver1, 0, &udmarxflowparameters1);
    
        for(uint32 i=0; i < 32; i++)
        {
            status = Udma_ringQueueRaw(&udmarxringhandle1,(uint32)&framedescriptor[i]);
        }
    
        for(int32 i=0; i < 32; i++)
        {
            uint64* pointer = (uint64*)(&framedescriptor[i]);
            status = Udma_ringDequeueRaw(&udmarxringhandle1, pointer);  //Still -4
            if(status != 0)
                i--;
            else
                status = 0;// No significance, just for debug break only
        }
    
        while(1)
        {
        }
    
    }

    仍然剂量不起作用

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

    这里是另一个代码变体,我修改了我的理解,真的希望它会起作用,但不幸的是,仍然不工作剂量

    struct EthernetFrame
    {
        uint8 MACreciever[6];
        uint8 MACsender[6];
        uint16 typecode;
        uint8 raw[1518];
        uint32 crc;
    };
    
    Udma_DrvObject udmadriver;
    
    Udma_ChObject udmarxchdriver;
    Udma_RingObject* udmarxringdriver;
    uint64 ringrx[32] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    Udma_FlowObject_t udmarxflowdriver;
    
    struct FrameDescriptor
    {
        EthernetFrame frame;
        struct PacketDescriptor
        {
            uint32 packetinfo[4];
            uint32 linkinginfo[2];
            uint32 bufferinfo[3];
            uint32 originalbufferinfo[3];
            uint32 extendedpacketinfo[16];
            uint32 protocolspecificdata[16];
            uint32 reserved[48];
        }packetdescriptor[4];
    
        FrameDescriptor()
        {
            //Broken down 1536 bytes ethernet frame into 4 parts becuase this is what is done in the "enet_layer2_cpsw" example
            //Also the rest of descriptor config is almost similar to the example
        
            packetdescriptor[0].packetinfo[0] = 0x61000000;
            packetdescriptor[0].linkinginfo[0] = (uint32)&packetdescriptor[1];
            packetdescriptor[0].bufferinfo[0] = (uint32)&frame + 0x0000;
            packetdescriptor[0].bufferinfo[2] = 0x180;
            packetdescriptor[0].originalbufferinfo[0] = packetdescriptor[0].bufferinfo[2];
            packetdescriptor[0].originalbufferinfo[1] = packetdescriptor[0].linkinginfo[0];
    
            packetdescriptor[1].packetinfo[0] = 0;
            packetdescriptor[1].linkinginfo[0] = (uint32)&packetdescriptor[2];
            packetdescriptor[1].bufferinfo[0] = (uint32)&frame + 0x0180;
            packetdescriptor[1].bufferinfo[2] = 0x180;
            packetdescriptor[1].originalbufferinfo[0] = packetdescriptor[1].bufferinfo[2];
            packetdescriptor[1].originalbufferinfo[1] = packetdescriptor[1].linkinginfo[0];
    
            packetdescriptor[2].packetinfo[0] = 0;
            packetdescriptor[2].linkinginfo[0] = (uint32)&packetdescriptor[3];
            packetdescriptor[2].bufferinfo[0] = (uint32)&frame + 0x0300;
            packetdescriptor[2].bufferinfo[2] = 0x180;
            packetdescriptor[2].originalbufferinfo[0] = packetdescriptor[2].bufferinfo[2];
            packetdescriptor[2].originalbufferinfo[1] = packetdescriptor[2].linkinginfo[0];
    
            packetdescriptor[3].packetinfo[0] = 0;
            packetdescriptor[3].linkinginfo[0] = 0;
            packetdescriptor[3].bufferinfo[0] = (uint32)&frame + 0x480;
            packetdescriptor[3].bufferinfo[2] = 0x180;
            packetdescriptor[3].originalbufferinfo[0] = packetdescriptor[3].bufferinfo[2];
            packetdescriptor[3].originalbufferinfo[1] = packetdescriptor[3].linkinginfo[0];
        }
    }framedescriptor[32];
    
    int main()
    {
        //All other peripherals including CPSW have already been initialised in the custom SBL so this main intents to use DMA for learning purpose
    
        uint32 status = 0;
        status = Sciclient_init(CSL_CORE_ID_R5FSS0_0);
    
        Udma_InitPrms udmaparameters;
        udmaparameters.instId             = UDMA_INST_ID_PKTDMA_0;
        udmaparameters.skipGlobalEventReg = 0;
        udmaparameters.virtToPhyFxn       = Udma_defaultVirtToPhyFxn;
        udmaparameters.phyToVirtFxn       = Udma_defaultPhyToVirtFxn;
        status = Udma_init(&udmadriver, &udmaparameters);
    
        Udma_ChPrms udmarxchparameters;
        Udma_ChRxPrms udmarxchrxparameters;
    
        UdmaChPrms_init(&udmarxchparameters, UDMA_CH_TYPE_RX_MAPPED);
        UdmaChRxPrms_init(&udmarxchrxparameters, UDMA_CH_TYPE_RX_MAPPED);
        udmarxchparameters.chNum = 16;//UDMA_DMA_CH_ANY;
        udmarxchparameters.peerChNum = UDMA_PSIL_CH_CPSW2_RX;
        udmarxchparameters.mappedChGrp =  UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxchparameters.appData = 0;
        udmarxchparameters.fqRingPrms.ringMem = & ringrx;
        udmarxchparameters.fqRingPrms.ringMemSize = sizeof(ringrx);
        udmarxchparameters.fqRingPrms.mode = 0;
        udmarxchparameters.fqRingPrms.elemCnt = 32;
        udmarxchparameters.fqRingPrms.elemSize = UDMA_RING_ES_8BYTES;
        udmarxchparameters.fqRingPrms.orderId = 0;
        udmarxchparameters.fqRingPrms.asel = UDMA_RINGACC_ASEL_ENDPOINT_PHYSADDR;
        udmarxchparameters.fqRingPrms.mappedRingGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxchparameters.fqRingPrms.mappedChNum = 16;
        udmarxchrxparameters.pauseOnError = 1;
        udmarxchrxparameters.flowEInfoPresent = 1;
        udmarxchrxparameters.flowPsInfoPresent = 1;
        udmarxchrxparameters.dmaPriority = 0;
        udmarxchrxparameters.configDefaultFlow = 1;
        status = Udma_chOpen (&udmadriver, &udmarxchdriver,UDMA_CH_TYPE_RX_MAPPED, &udmarxchparameters);
        status = Udma_chConfigRx(&udmarxchdriver, &udmarxchrxparameters);
        status = Udma_chEnable(&udmarxchdriver);
        udmarxringdriver = (Udma_RingObject*)Udma_chGetFqRingHandle(&udmarxchdriver);
    
        Udma_FlowAllocMappedPrms udmarxflowallocmappedparameters;
        Udma_FlowPrms udmarxflowparameters;
        UdmaFlowPrms_init(&udmarxflowparameters, UDMA_CH_TYPE_RX_MAPPED);
        udmarxflowallocmappedparameters.mappedChNum = 16;
        udmarxflowallocmappedparameters.mappedFlowGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxflowparameters.errorHandling = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_ERR_DROP;
        udmarxflowparameters.psInfoPresent = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_PSINFO_PRESENT;
        udmarxflowparameters.einfoPresent = TISCI_MSG_VALUE_RM_UDMAP_RX_FLOW_EINFO_PRESENT;
        udmarxflowparameters.sizeThresh0 = 1536;
        udmarxflowparameters.sizeThresh1 = 1536;
        udmarxflowparameters.sizeThresh2 = 1536;
        udmarxflowparameters.defaultRxCQ = Udma_ringGetNum(udmarxringdriver);
        udmarxflowparameters.fdq0Sz0Qnum = Udma_ringGetNum(udmarxringdriver);
        udmarxflowparameters.fdq0Sz1Qnum = Udma_ringGetNum(udmarxringdriver);
        udmarxflowparameters.fdq0Sz2Qnum = Udma_ringGetNum(udmarxringdriver);
        udmarxflowparameters.fdq0Sz3Qnum = Udma_ringGetNum(udmarxringdriver);
        udmarxflowparameters.fdq1Qnum = Udma_ringGetNum(udmarxringdriver);
        udmarxflowparameters.fdq2Qnum = Udma_ringGetNum(udmarxringdriver);
        udmarxflowparameters.fdq3Qnum = Udma_ringGetNum(udmarxringdriver);
        status = Udma_flowAllocMapped(&udmadriver, &udmarxflowdriver, &udmarxflowallocmappedparameters);
        status = Udma_flowConfig(&udmarxflowdriver, 0, &udmarxflowparameters);
    
        for(uint32 i=0; i < 32; i++)
        {
            status = Udma_ringQueueRaw(udmarxringdriver,(uint32)&framedescriptor[i]);
        }
    
        for(int32 i=0; i < 32; i++)
        {
            uint64* pointer = 0;
            status = Udma_ringDequeueRaw(udmarxringdriver, pointer);    // I get status value -4 over here, digging into the Udma_ringDequeueRaw I see it returns as failure because the ring is empty
            if(status != 0)
                i--;
            else
                status = 0;                                             //Statment has no significance, used only for debugbreak
        }
    
        while(1);
    }

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

    尊敬的 Abhimanyu:

    以下是其余2个问题的答案。

    7.) DMA 寄存器的编程顺序是什么?

    首先设置凭据寄存器、然后写入通道配置寄存器中的寄存器、最后写入使能寄存器。 在通道的 RTCFG 区域中写入门铃寄存器。

    8.) 是否有类似 SOC 具有可用且文档丰富的类似 CPSW、以便我可以阅读其 TRM 来了解 AM64x 的任何意义?

    J7ES、J7VCL、AM67

    但我不认为、我可以在这里支持自定义代码编写。

    如果在执行任何示例代码时遇到任何问题、请告诉我。

    有关 Enet-LLD API、请参阅以下页面

    https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_06_00_45/exports/docs/api_guide_am64x/ENET_LLD.html

    以下是网络主页

    https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_06_00_45/exports/docs/api_guide_am64x/NETWORKING.html

    此致

    阿什瓦尼

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

    大家好!

     

    我目前使用 TI 的 MCU+SDK UDMA 驱动程序 API (不使用 Enet LLD、 因为我确信没有适当的文档、这太复杂了、任何人都不能理解(除了编写文档的 TI 人员)。 我对一切的工作原理还没有完全的了解、但读完 TRM 后、至少读过 TRM 20次、分离了 Enet 示例、 还有大量的试错、我有一个很小的工作代码能够捕获以太网到内存中。 我不会草率地发表一个不完善的解决办法,因为它只会给未来的读者造成混乱。 此外、我尚不能使 DMA 的发送器部分正常工作。 当我对一切都有了满意的理解后、我会在这里发布两个版本的解决方案:一个使用的是驱动程序 API 库、另一个使用的是裸机归档器编程方法、这是最初的目标。

     

    由于我将花时间发布解决方案、与此同时、如果有其他人更早需要解决方案、请在此 Ping、我将发布一个最起码的解决方案。

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

    大家好!

    以下是工作代码(即使没有 SysConfig 也能正常工作):

    Udma_DrvObject udmadriver;
    
    Udma_ChObject udmarxchdriver;
    Udma_ChObject udmatxchdriver;
    Udma_RingObject* udmarxringdriver;
    Udma_RingObject* udmatxringdriver;
    uint64 ringrx[32] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    uint64 ringtx[32] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    Udma_FlowObject_t udmarxflowdriver;
    
    struct EthernetFrame
    {
        uint8 MACreciever[6];
        uint8 MACsender[6];
        uint16 typecode;
        uint8 raw[1518];
    };
    
    struct FrameDescriptor
    {
        EthernetFrame frame;
        struct PacketDescriptor
        {
            uint32 packetdescriptor[12];
            uint32 extendeddescriptor[12];
        }packetdescriptor;  //Make sure packetdescriptor is aligned or things won't work 
        uint8 padding[0x800 - sizeof(frame) - sizeof(packetdescriptor)];
    
        FrameDescriptor()
        {
            packetdescriptor.packetdescriptor[0] = 0x40000000;
            packetdescriptor.packetdescriptor[6] = (uint32)&frame;
            packetdescriptor.packetdescriptor[8] = sizeof(frame);
        }
    }framedescriptor[32] __attribute__((aligned(256))); //This struct can be packed more tightly, my deisgn was for easy readability and debugging
    
    int main()
    {
        uint32 status = 0;
        status = Sciclient_init(CSL_CORE_ID_R5FSS0_0);
        
        //CPSW Config
        *CTRLMMR_ENET1_CTRL = 2;
        *CTRLMMR_ENET2_CTRL = 2;
        _cpsw->control.STATPORTEN =  BIT02|BIT01|BIT00;
        _cpsw->control.CONTROL = BIT19|BIT14|BIT02;
        _cpsw->control.FREQUENCY = 250;
        _cpsw->control.P0CONTROL|= BIT19|BIT17|BIT01|BIT00;
        _cpsw->control.P0FLOWIDOFFSET = 16;
        _cpsw->control.P1CONTROL|= BIT01;
        _cpsw->control.P1MACCONTROL = BIT24|BIT23|BIT22|BIT17|BIT07|BIT05|BIT00;
        _cpsw->ale.CONTROL |=  BIT31|BIT04;
        _cpsw->ale.I0ALEPORTCTL00 = BIT12|BIT01|BIT00;
        _cpsw->ale.I1ALEPORTCTL01 = BIT12|BIT01|BIT00;
        _cpsw->ale.I2ALEPORTCTL02 = BIT12|BIT01|BIT00;
        _cpsw->ale.CONTROL |=  BIT30;
    
        //UDMA Config
        Udma_InitPrms udmaparameters;
        udmaparameters.instId             = UDMA_INST_ID_PKTDMA_0;
        udmaparameters.skipGlobalEventReg = 0;
        udmaparameters.virtToPhyFxn       = Udma_defaultVirtToPhyFxn;
        udmaparameters.phyToVirtFxn       = Udma_defaultPhyToVirtFxn;
        status = Udma_init(&udmadriver, &udmaparameters);
    
        //UDMA Rx Config
        Udma_ChPrms udmarxchparameters;
        Udma_ChRxPrms udmarxchrxparameters;
        Udma_FlowAllocMappedPrms udmarxflowallocmappedparameters;
        Udma_FlowPrms udmarxflowparameters;
        UdmaChPrms_init(&udmarxchparameters, UDMA_CH_TYPE_RX_MAPPED);
        UdmaChRxPrms_init(&udmarxchrxparameters, UDMA_CH_TYPE_RX_MAPPED);
        UdmaFlowPrms_init(&udmarxflowparameters, UDMA_CH_TYPE_RX_MAPPED);
        udmarxchparameters.chNum = 16;
        udmarxchparameters.peerChNum = UDMA_PSIL_CH_CPSW2_RX;
        udmarxchparameters.mappedChGrp =  UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxchparameters.appData = 0;
        udmarxchparameters.fqRingPrms.ringMem = & ringrx;
        udmarxchparameters.fqRingPrms.ringMemSize = sizeof(ringrx);
        udmarxchparameters.fqRingPrms.mode = 0;
        udmarxchparameters.fqRingPrms.elemCnt = 32;
        udmarxchparameters.fqRingPrms.elemSize = UDMA_RING_ES_8BYTES;
        udmarxchparameters.fqRingPrms.orderId = 0;
        udmarxchparameters.fqRingPrms.asel = UDMA_RINGACC_ASEL_ENDPOINT_PHYSADDR;
        udmarxchparameters.fqRingPrms.mappedRingGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxchparameters.fqRingPrms.mappedChNum = 16;
        udmarxchrxparameters.pauseOnError = 0;
        udmarxchrxparameters.flowEInfoPresent = 1;
        udmarxchrxparameters.flowPsInfoPresent = 1;
        udmarxchrxparameters.dmaPriority = 0;
        udmarxchrxparameters.configDefaultFlow = 1;
        udmarxflowallocmappedparameters.mappedChNum = 16;
        udmarxflowallocmappedparameters.mappedFlowGrp = UDMA_MAPPED_RX_GROUP_CPSW;
        udmarxflowparameters.errorHandling = 0;
        udmarxflowparameters.psInfoPresent = 1;
        udmarxflowparameters.einfoPresent = 1;
        udmarxflowparameters.sizeThresh0 = 1536;
        udmarxflowparameters.sizeThresh1 = 1536;
        udmarxflowparameters.sizeThresh2 = 1536;
        udmarxflowparameters.defaultRxCQ = 128;
        udmarxflowparameters.fdq0Sz0Qnum = 128;
        udmarxflowparameters.fdq0Sz1Qnum = 128;
        udmarxflowparameters.fdq0Sz2Qnum = 128;
        udmarxflowparameters.fdq0Sz3Qnum = 128;
        udmarxflowparameters.fdq1Qnum = 128;
        udmarxflowparameters.fdq2Qnum = 128;
        udmarxflowparameters.fdq3Qnum = 128;
        status = Udma_chOpen (&udmadriver, &udmarxchdriver,UDMA_CH_TYPE_RX_MAPPED, &udmarxchparameters);
        status = Udma_chConfigRx(&udmarxchdriver, &udmarxchrxparameters);
        status = Udma_chEnable(&udmarxchdriver);
        status = Udma_flowAllocMapped(&udmadriver, &udmarxflowdriver, &udmarxflowallocmappedparameters);
        status = Udma_flowConfig(&udmarxflowdriver, 0, &udmarxflowparameters);
        udmarxringdriver = (Udma_RingObject*)Udma_chGetFqRingHandle(&udmarxchdriver);
    
        //UDMA Tx Config
        Udma_ChPrms udmatxchparameters;
        Udma_ChTxPrms udmatxchtxparameters;
        UdmaChPrms_init(&udmatxchparameters, UDMA_CH_TYPE_TX_MAPPED);
        UdmaChTxPrms_init(&udmatxchtxparameters, UDMA_CH_TYPE_TX_MAPPED);
        udmatxchparameters.chNum = 16;
        udmatxchparameters.peerChNum = UDMA_PSIL_CH_CPSW2_TX;
        udmatxchparameters.mappedChGrp =  UDMA_MAPPED_TX_GROUP_CPSW;
        udmatxchparameters.appData = 0;
        udmatxchparameters.fqRingPrms.ringMem = & ringtx;
        udmatxchparameters.fqRingPrms.ringMemSize = sizeof(ringtx);
        udmatxchparameters.fqRingPrms.mode = 0;
        udmatxchparameters.fqRingPrms.elemCnt = 32;
        udmatxchparameters.fqRingPrms.elemSize = UDMA_RING_ES_8BYTES;
        udmatxchparameters.fqRingPrms.orderId = 0;
        udmatxchparameters.fqRingPrms.asel = UDMA_RINGACC_ASEL_ENDPOINT_PHYSADDR;
        udmatxchparameters.fqRingPrms.mappedRingGrp = UDMA_MAPPED_TX_GROUP_CPSW;
        udmatxchparameters.fqRingPrms.mappedChNum = 16;
        udmatxchtxparameters.pauseOnError = 0;
        udmatxchtxparameters.dmaPriority = 0;
        status = Udma_chOpen (&udmadriver, &udmatxchdriver,UDMA_CH_TYPE_TX_MAPPED, &udmatxchparameters);
        status = Udma_chConfigTx(&udmatxchdriver, &udmatxchtxparameters);
        status = Udma_chEnable(&udmatxchdriver);
        udmatxringdriver = (Udma_RingObject*)Udma_chGetFqRingHandle(&udmatxchdriver);
        
        //Recieve 32 Packets
        for(uint32 i=0; i < 32; i++)
        {
            status = Udma_ringQueueRaw(udmarxringdriver,(uint32)&framedescriptor[i].packetdescriptor);
        }
    
        for(int32 i=0; i < 32; i++)
        {
            uint64* pointer = 0;
            status = Udma_ringDequeueRaw(udmarxringdriver, pointer);
            if(status != 0)
                i--;
        }
    
        //Send 32 Packets
        framedescriptor[0].frame.MACreciever[0] = 0x1C;
        framedescriptor[0].frame.MACreciever[1] = 0x61;
        framedescriptor[0].frame.MACreciever[2] = 0xB4;
        framedescriptor[0].frame.MACreciever[3] = 0xBE;
        framedescriptor[0].frame.MACreciever[4] = 0xFA;
        framedescriptor[0].frame.MACreciever[5] = 0x4B;
        framedescriptor[0].frame.MACsender[0] = macaddress0;
        framedescriptor[0].frame.MACsender[1] = macaddress1;
        framedescriptor[0].frame.MACsender[2] = macaddress2;
        framedescriptor[0].frame.MACsender[3] = macaddress3;
        framedescriptor[0].frame.MACsender[4] = macaddress4;
        framedescriptor[0].frame.MACsender[5] = macaddress5;
        framedescriptor[0].frame.typecode = 0xADDE;
        framedescriptor[0].frame.data.raw[0] = 0;
        framedescriptor[0].frame.data.raw[1] = 1;
        framedescriptor[0].frame.data.raw[2] = 2;
        framedescriptor[0].frame.data.raw[3] = 3;
        framedescriptor[0].frame.data.raw[4] = 4;
        framedescriptor[0].frame.data.raw[5] = 5;
        framedescriptor[0].frame.data.raw[6] = 6;
        framedescriptor[0].frame.data.raw[7] = 7;
        framedescriptor[0].frame.data.raw[8] = 8;
        framedescriptor[0].frame.data.raw[9] = 9;
        framedescriptor[0].frame.data.raw[10] = 10;
        framedescriptor[0].frame.data.raw[11] = 11;
        framedescriptor[0].frame.data.raw[12] = 12;
        framedescriptor[0].frame.data.raw[13] = 13;
        framedescriptor[0].frame.data.raw[14] = 14;
        framedescriptor[0].frame.data.raw[15] = 15;
        framedescriptor[0].packetdescriptor.packetdescriptor[0] |= 64;
        framedescriptor[0].packetdescriptor.packetdescriptor[1] = 16;
    
        for(uint32 i=0; i < 32; i++)
        {
            status = Udma_ringQueueRaw(udmatxringdriver,(uint32)&framedescriptor[0].packetdescriptor);
            uint64* pointer = 0;
            status = Udma_ringDequeueRaw(udmatxringdriver,pointer);
        }
    
        while(1)
        {
        }
    
    }

    希望这将有助于,如果任何人有问题感到自由 射击。

    我强烈建议 TI 包含这样的简单代码。 如果编写正确、通常会有100行代码用于接收或单独发送。 可轻松适应 MCU+SDK 文档的单页。 它将有助于浩瀚。 我甚至建议为其余的外设执行此操作、许多外设仍然严重缺乏等效的信息。

    仅像我对 CPSW 配置所做的那样通过原始存储器编程尝试在没有使用 uDMA API 的情况下实现上述更新: 在 TI 的帮助下、我获得了有关不使用 UDMA API 所执行的 DMSC 可能无法对 DMA 进行编程的信息。 出于 安全和系统完整性方面的原因、硬件可能不允许这样做。  话虽如此、我仍会尝试拆分 uDMA 库、尽可能删除内容、然后得出结论、是否可行。

    特别感谢帮助我    真的很感激。

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

    阅读您的实现以了解 PKTDMA 非常有帮助。 它比 TRM 更好、并提供了示例。 我有几个问题给你 Abhimanyu Singh

    • 对我来说、没有 DMSC 似乎无法配置 DMA 通道和振铃。 不过、写入 SPI、UART 等寄存器不需要 DMSC。 是这样吗?
    • 此外、DMA 使用调度程序和控制器等。 这些都在 M3 cortex (DMSC)上实现了吗?
    • 为什么您尚未定义 PacketLength、它是 packetdescriptor[0] bits 21:0
    • 此外、我看到您的数据包中包含扩展的信息块。 但是、表示该数据包存在的位(基于 TRM:数据包描述符字0位29)没有置位。 为什么?
    • 在本例中,协议特定的数据是 FrameDescriptor,这也是负载缓冲区。
    • 此外、如果存在扩展数据包信息、DMASS 会在 word0 (Timestamp Info)中写入一些内容吗? 例如已传输的时间戳?

    提前感谢、  
    博什拉

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

    尊敬的 Boshra:

    我对迟交的答复表示歉意,

    对于我来说,没有 DMSC 似乎无法配置 DMA 通道和振铃。 不过、写入 SPI、UART 等寄存器不需要 DMSC。 是这样吗?

    是的、回答正确。 我已经在未使用 DMSC 的情况下实现了 SPI、UART 等、并且它们可以正常工作。

    此外,DMA 正在使用调度程序和控制器等。 这些都在 M3 cortex (DMSC)上实现了吗?

    我不确定这一点。 但是、如果我猜猜猜、结果会是否定的。 我认为它们是在 DMA 本身的硬件中实现的。

    为什么您还没有定义 packetLength,它是 packetdescriptor [0]位21:0

    如果将数据包长度设置为64字节、则读取第184行的最后代码。 由于数据包长度会随每个数据包而变化、因此将在计算数据包长度后写入该数据包。 由于我的样本测试数据包太短、我将其设置为以太网规范中定义的最小数据包长度64。

    此外,我看到您的数据包中有扩展的信息块。 但是、表示该数据包存在的位(基于 TRM:数据包描述符字0位29)没有置位。 为什么?

    为了安全起见、我定义了扩展的数据包信息、即使在我不需要时也是如此。 在接收数据包时、如果由于某种原因(因为我对系统没有完全的了解)而硬件想要写入扩展的数据包信息、则会溢出并损坏我的帧描述符数据结构。

    在本例中,协议特定的数据是帧描述符,它也是负载缓冲区。

    我不确定这里的协议特定数据是什么意思。 TRM 中提到的特定于协议的数据位于扩展数据包信息之后。 我在扩展数据包信息描述符中使用了一个缺失的前导名称、即"extendeddescription"、它实际上同时保存扩展数据包信息和特定于协议的数据 、尽管 就像我之前所说的那样、我不会使用其中任何一个。  我的负载缓冲区是 EthernetFrame、它是 FrameDescriptor 中的"帧"。

    此外,如果存在扩展数据包信息,DMASS 是否会以 word0 (时间戳信息)写入某些内容? 类似于已传输的时间戳?

    否。 我还没有启用时间戳配置。 默认情况下、没有时间戳数据。

    请随时提出更多问题。 我很乐意提供帮助。