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.

[参考译文] TMS570LC4357:MIBSPI RX DMA 在传输组中最后一个之外的缓冲器上触发不可靠

Guru**** 2478765 points
Other Parts Discussed in Thread: TMS570LC4357, HALCOGEN

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/681166/tms570lc4357-mibspi-rx-dma-triggers-on-buffers-other-than-the-last-in-a-transfer-group-don-t-work-reliably

器件型号:TMS570LC4357
主题中讨论的其他器件: HALCOGEN

我观察到、在使用环回和"暂停单次传输"或"暂停单次传输覆盖保护"缓冲模式时、如果在写入该缓冲器和下一个缓冲器之间时间过长、除了传输组中的最后一个缓冲器之外、任何其他缓冲器上的 MIBSPI RX DMA 都不会触发。 我不明白"太长"到底意味着什么、但它比等待 INTFLTGSUS 位被置位更长、并且确实取决于配置的波特率。 为了确保 DMA 通道被可靠触发、我必须遵循哪些约束条件?

请注意、我会看到类似的症状、即 DMA 通道没有像实际代码那样多次触发、而是在环回模式之外使用与另一个 MCU 进行通信并使用非挂起缓冲模式、我认为这可能是同一个问题、 但是、由于时间和其他复杂性、这种情况很难重现、因此我认为有必要先尝试并解决易于重现的问题、先进行环回。

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

    e2e.ti.com/.../2262.MIBSPI_2D00_DMA-weirdness-repro-TI-toolchain.zip

    附件是用于演示此问题的 TMS570LC4357 HDK 的 CCS 项目。 HL_sys_main.c 之外的所有内容都未修改 HALCOGEN 输出。 它在 SCI1 (在 HDK 上通过 USB 连接的输出)上以115、200波特输出。 在 hL_sys_main.c 中、有一个#if 树用于配置用于写入外设的方法。 我很确定这三个位都应该产生相同的 MIBSPI DMA 通道触发结果(然后禁用它们、因为它们处于 OneShot 模式)、并且使用 MibspiSetData 或仅按顺序写入缓冲区会产生该结果。 但是、在写入两个缓冲区之间插入 printf 时(延迟相对较长)、第一个 DMA 通道不会触发。 我已经在更复杂的测试中验证了连接的 DMA 通道实际上无法启动、但在这个简化的示例中、我没有配置任何实际的 DMA 通道来使其更简单。

    对两项评论表示歉意。 我无法确定如何在原始帖子中附加文件...

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

    更新了:在调试权变措施时、我最终修改了 MCU 向 Hercules 发送数据、以便在每个帧之间插入(相对较长)暂停。 这确实能够在非回送模式下以及在传输组中的最后一个缓冲区上可靠地重现此行为。

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

    在您的第二个帖子中、"第一个 DMA 通道未触发"是什么意思? 我只是看一下您的示例代码、您不启用并使用 DMA 与 MibSPI RAM 之间传输数据。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    正如我在最初的帖子中所述、我避免了在我的示例中实际配置 DMA 来简化它。 我只讨论 MIBSPI 外设中的 DMA 通道、这不会触发。 TRM 将"DMAxCTRL"寄存器描述为"DMA 通道控制寄存器"、所以这是我能想到的最好的描述;请告诉我是否有一个不太容易混淆的术语要使用。

    具体来说、DMA0CTRL 寄存 器中的 COUNTX 域无法递减、这也会导致 RXDMAENAx 域变为0、因为 OneShot 域设置为1。 这是在写入两个帧之间没有长时间延迟的情况下发生的、但在两个帧之间插入延迟时失败。

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

    对此进行了任何更新? 自我作出回应以来已经24小时了、一周多了、TI 没有做出实质性回应。 这似乎是 MIBSPI 外设 DMA 功能的一个非常严重的问题、我非常想知道是否有任何权变措施。

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

    您好 Brian、

    MibSPI 提供多达8个 DMA 通道(用于 TX 和 RX)。 所有的 DMA 通道都是可单独编程的、并且可以连接到多缓冲器 RAM 中的任何缓冲器。  MibSPIP 提供多达16条 DMA 请求线路、可对来自任何通道的 DMA 请求进行编程、从而通过这16条线路中的任何一条进行路由。 DMA 传输可由 TX 和 RX 事件触发。

    只能将一个 DMA 读取通道和一个 DMA 写入通道分配给1个传输组。 不能将 DMA 通道0分配给 TG0 wordc0、将 DMA 通道1分配给 TG0 word1、以此类推。

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

    您好!

    感谢您对 MIBSPI-DMA 通道工作原理的总结。 这符合我在 TRM 中的理解。

    您认为问题在同一个传输组中使用两个 MIBSPI-DMA 通道的理论似乎与现实不符。 我最初没有明确声明它、但我之前观察到这种行为、只配置了一个 MIBSPI-DMA 通道。 我的示例代码仅使用两个来证明它们配置正确、并且有时会触发。 我发布的带有第二个 MIBSPI-DMA 通道(mibspiREG1->DMACTRL[1])的示例代码与第一个通道显示的行为完全相同、在第一个通道中、当向传输组中的第一个缓冲区和第二个缓冲区写入数据之间存在延迟时、它不会触发。 下面是一个修改版本、其中添加了注释、以便100%清楚地了解我所谈论的内容: e2e.ti.com/.../8117.MIBSPI_2D00_DMA-weirdness-repro-TI-toolchain-single-DMA.zip

    此外、TRM 和数据表没有提到我可以找到的这种限制;如果我错过了限制、请指出限制的位置。 此外,TI 的 spna231应用手册(高速串行总线在基于 HerculesTm的微控制器上使用 MibSPIP 模块,由 Christian Herget 提供)甚至在单个传输组中使用了两个接收 MIBSPI-DMA 通道的示例配置。

    请再次查看此问题、因为您的解释似乎不正确。

    Brian Silverman

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

    您好 Brian、

    很抱歉我的误导性消息。 当然、您可以将不同的通道分配给同一传输组中的不同缓冲区。 但一个传输组只有一个触发事件。 例如、TG0有4个缓冲区、DMA 通道0被分配给 TG0缓冲区0、 DMA 通道1被分配给 TG0缓冲区1、 DMA 通道2被分配给 TG0缓冲区2、  并且 DMA 通道3被分配给 TG0 buffer3、每当定义的触发事件发生时、所有缓冲区都将被传输。

    我修改了您的项目、添加了通过 DMA 从 TG0 buffer0/1/2/3读取数据的代码。 它运行良好。 只有一个触发器针对整个组(TG0)。

    e2e.ti.com/.../4645.MIBSPI_2D00_DMA-weirdness-repro-TI-toolchain.7z

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

    您好 Brian、

    以下显示修改项目的测试结果:

    在断点1 (第190行)处:

    DMAxCtrl 中的计数值都为0x1。  

    4个 DMA 通道的 TX 数据为0x5A01、0x5A02、0x5A03和0x5A04。 RXDATA00/01/02/04是 DMA 从 MibSPI RAM 传输到 MCU SRAM 的数据

    MibSPI RAM:TX 数据、和 RX 数据

    2.在断点2处(第202行)

    计数减少到0x0

    接收到的数据与 TX 数据相同:

    MibSPI RAM 中的 TX 数据:

    MibSPI RAM:RX 数据

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

    我同意、如果您对其进行修改、以便在传输之间毫不延迟地将接收缓冲器传输到其中、则可以正常工作。 这就是像您那样移动 mibspiTransfer 呼叫的效果。 但是、正如我在最初的帖子和后续帖子中所述、我观察到的问题行为仅在传输到接收缓冲区之间存在延迟时发生、无论是因为在回送模式下写入发送缓冲区之间存在延迟、还是外部主器在非回送模式下插入延迟。 如果我取消注释上述传输到最新测试代码中的缓冲区的 mibspiTransfer 调用、我会再次观察到有问题的行为:

    > MDW 0xFFF7F4d8
    0xFF7f4d8:80108001
    > MDW 0xFFF7F4dc
    0xFF7f4dc:81008001
    > MDW 0xFFF7F4e0
    0xFF7f4e0:82a08001
    > MDW 0xFFF7F4e4
    0xFF7f4e4:83300000

    作为参考、此处显示的是在未修改的情况下运行附加的代码(在移动数据后使用 mibspiTransfer 调用)的样子。 我还不知道如何让 CCS 云与 HDK 通信、因此我只使用 openocd:

    > MDW 0xFFF7F4d8
    0xFF7f4d8:80100000
    > MDW 0xFFF7F4dc
    0xFF7f4dc:81000000
    > MDW 0xFFF7F4e0
    0xFF7f4e0:82a00000
    > MDW 0xFFF7F4e4
    0xFF7f4e4:83300000

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

    您好 Brian、

    如果您希望在不同 DMA 传输通道之间使用延迟、我建议您使用不同的传输组。 每个 DAM 通道连接到一个传输组。 最多可以有8个传输组、每个组可以有1~127缓冲区。 每个传输组可以使用不同的触发源和触发事件。

    这就是 TRM 所说的:

    • 为每个缓冲器配置八个可用 BUFMODE 中的一个。
    • 在 TXRAM 缓冲器的 TXDATA 域中填充要发送的数据。
    • 配置 TGENA 位以启用所需的传输组。  
    • 在发生正确的触发事件时、传输组将被触发、数据在 CPU 干预之外的情况下一个接一个地传输和接收。
    • 您可以轮询传输组中断标志或等待传输完成的中断读取新数据并将其写入缓冲区。

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

    我不想添加延迟。 我正在尝试使用 Hercules 作为从器件从外部主器件接收数据。 但是、我需要知道外部主器件对时序的要求是确保其可靠运行、因此我可以评估我的设计是否与该外部主器件配合使用、或者我是否需要重新设计以解决 Hercules 的这一(严重)限制。 我在 TRM 或数据表中没有看到任何内容提到"帧之间的最大延迟"或类似的内容、因此我不明白为什么 Hercules 将使用的可接受 SPI 主器件会有这样的要求。

    当我观察到 MIBSPI-DMA 触发器在具有单独外部主器件的完整应用中运行不正常以及其他各种复杂问题时、就会启动这一操作。 我们一直在讨论的示例就是这样:一个示例。 它被故意(高度)简化、这样它只使用单个 Hercules 来重现此问题、并且在回送模式中执行此操作。 再说一次:我正在尝试了解如何使用 DMA 通过 MIBSPI 外设可靠地接收数据、同时让 Hercules 充当从器件、因此有关如何使 Hercules 作为主器件以不同方式工作的建议无关紧要。

    此外、我在外部主器件和 Hercules 之间只有一条 CS 线路。 TRM 在"28.2.6.7多缓冲器配置中的 MibSPI 从器件"中非常清楚地表明、这意味着我只能使用一个传输组。 鉴于此、我根本看不到您的最新建议是如何应用的。

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

    我运行您的项目、并重现了相同的问题。 第二个接收到的数据没有触发 DMA 传输。

    这就是原因:在 TG 中使用一个 TX 端、2个缓冲区、这2个缓冲区中的数据循环回 RX RAM 中的2个缓冲区。 但 DMA 仅传输1个缓冲器。 第2个缓冲区不会触发 DMA 传输。

    我将修改您的代码以使用 SPI1和 SPI3、而不是回送。

    SPI1:主器件、具有延迟的耦合通道、1 TG
    SPI3:从器件、1通道和1 TG

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

    您好、Brain、

    要在缓冲区之间添加延迟、请使用在 FMT0 (数据格式0)中定义的 WDELAY。

      mibspiREG1->FMT0 =(uint32)((uint32) 10U <<24U) // wdelay

    对于每个缓冲器的 MibSPI 在 MibSPI RAM 设置中启用此功能:

           mibspiRAM1->TX[i].control =(uint16)((uint16) 4U <<13U) /*缓冲模式*/

                         |(uint16)((uint16) 1U << 12U) /*芯片选择保持*/

                         |(uint16)((uint16) 0U << 10U) //启用 WDELAY *

                         |(uint16)((uint16) 0U << 11U) /*锁定传输*/

                         |(uint16)((uint16) 0U << 8U) /*数据格式*/

                         |((uint16)(~((uint16) 0xFFU ^(uint16) CS_0))和(uint16) 0x00FFU); /*芯片选择*

    延迟可高达257个 VCLK 周期。 例如、VCLK 为100MHz、最大延迟可为2.57us。

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

    您好 Brian、

    两个缓冲器传输之间的延迟不会影响从器件侧的数据接收和 DMA 传输。 您代码中的触发方法不正确。 一个传输组只有一个触发事件和一个触发源。 当传输组中的所有缓冲区都准备就绪时、应发出触发信号。  

    如果要测试延迟的影响、请在 FMTx 寄存器中使用 WDELAY。 附件是一个示例代码。

    MibSPI1:主器件、1个具有8个缓冲器的 TG、数据直接写入 TXRAM。 两个缓冲器之间的传输延迟为3.43uS (WDELAY=0xFF)。

    MIPI3:从器件、1个 TG、只有1个缓冲器、DMA 用于将数据从 RXRAM 传输到 SRAM (数据阵列)

    数据被正确传输和接收。

    e2e.ti.com/.../4186.TMS570LC4357_5F00_MibSPI1_2600_3_5F00_DMA.7z 

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

    您好 Brian、

    您能否查看我的示例代码以了解它是否符合您的要求? 我为 MibSPI DMA 设置、传输组设置、MibSPI RAM 配置添加了注释。 如有任何问题、请告知我们。 以下是我的示例工程的 main()函数的代码:

    /*包含文件*/

    #include "hL_sys_common.h"

    /*用户代码开始(1)*/

    #include "hL_mibspi.h"

    #include "HL_SYS_DMA.h"

    #include "hL_sys_core.h"

    #include "hL_sci.h"

    #include "HL_REG_ESM.h"

    #include

    #include

    #define E_COUNT   1/* 元素计数*/

    #define F_COUNT   8 /*帧计数*/

    #define D_SIZE   E_COUNT * F_COUNT

    #define TG0     1

    #define TG1     0

    /*用户代码结束*/

    /**@fn void main (void)

    * @应用程序主函数简介

    * @请注意、默认情况下、此函数为空。

    *

    * 此函数在启动后调用。

    * 用户可以使用此函数来实现应用程序。

    *

    /*用户代码开始(2)*/

    void loadDataPattern (uint32 psize、uint16* pptr、uint16 pattern);

    void dmaConfigCtrlRxPacket (uint32 Sadd、uint32 dadd、uint16 ElmntCnt、uint16 FrameCnt);

    void dmaConfigCtrlTxPacket (uint32 Sadd、uint32 dadd、uint16 ElmntCnt、uint16 FrameCnt);

    /* TG 起始地址*/

    uint16 tgPSTRT[8];

    g_dmaCTRL g_dmaCTRLPKT_RX、g_dmaCTRLPKT_TX;

    #pragma SET_DATA_SECTION (".sharedRAM")

    uint16 TXDATA[D_SIZE];     系统 RAM、MibSPI1 TG0中的/*发送缓冲器*/

    uint16 RXDATA[D_SIZE]={0};   //系统 RAM、MibSPI1 TG0中的接收缓冲器*/

    #pragma SET_DATA_SECTION ()

    uint16 TX_data1[8]={0x5A11、0x5A22、0x5A33、0x5A44、0x5A55、0x5A66、0x5A77、0x5A88};

    /*用户代码结束*/

    int main (空)

    /*用户代码开始(3)*/

      uint16 i;

      esmREG->SR1[0]= 0xFFFFFFFF;

      esmREG->SR1[1]= 0xFFFFFFFF;

      esmREG->SR1[2]= 0xFFFFFFFF;

      esmREG->EKR = 0x0000000A;

      esmREG->EKR = 0x00000000;

      sciInit();

      printf ("hello\n");

      /*启用 RQ 中断*/

      _enable_IRQ_interrupt_();

      //初始化 MibSPI1和 MibSPI3 -启用 TG 0,长度127 (halcogen 文件)*/

      mibspiInit();

      /*传输之间或2个缓冲帧之间的延迟*/

      /*要应用的延迟等于: (WDELAY+2)×PVCLK、其中 PVCLK 是 VCLK 的周期*/

      /*在本例中,VCLK=75MHz,PVCLK=13.33ns,2个缓冲帧之间的延迟为:257*13.33=3.43us*/

      mibspiREG1->FMT0 &=(uint32)(0x00FFFFFF); //清除 WDELAY 位:bit 31~24 *

      mibspiREG1->FMT0 |=(uint32)(0xFF << 24); //添加延迟:0xFF,最大值*/

      /* MibSPI1:主器件

      * TG0:8个缓冲器、

      * OneShot 传输已设置:在发生有效触发事件后、从 TG0传输只会执行一次

      *触发事件:始终

      *触发源:禁用

      *通过将 TRIGSRC 设置为0、将 TRIGEVT 设置为7h (始终)、并将 ONESHOTx 位设置为1、软件可以触发

      *此 TG。 设置 TGENA 位后、TG 立即被触发。

      *

      mibspiREG1->TGCTRL[0U]=(uint32)((uint32) 1U << 30U) /* OneShot *

                 |(UINT32)((UINT32) 0U << 29U) /* pcurrent reset */

                 |(uint32)((uint32) TRG_AYeUS<< 20U) /*触发事件*/

                 |(UINT32)((UINT32) TRG_DISABLED << 16U) /*触发源*/

                 |(uint32)((uint32) 0U << 8U); //开始缓冲区

      mibspiREG1->TGCTRL[1U]=(uint32)((uint32) 1U <<30U) /* OneShot *

                 |(UINT32)((UINT32) 0U << 29U) /* pcurrent reset */

                 |(UINT32)((UINT32) TRG_Always << 20U) /*触发事件*/

                 |(UINT32)((UINT32) TRG_DISABLED << 16U) /*触发源*/

                 |(uint32)((uint32) 8U << 8U); //开始缓冲区

      /*配置 MibSPI1 TG0的 TX RAM:

      * Bufmode:挂起单次传输模式。 挂起到等待、直到相应的 TXFULL 标志被置位(序列发生器停止

      *      直到 TXDATA 域中写入新的发送数据为止。

      *芯片选择保持:关闭时、芯片选择信号在传输结束时被禁用

      * WDELAY 启用、延迟在 FMT0中定义

      *锁定传输:禁用后、任何更高优先级的 TG 都可以在当前事务结束时开始

      *数据 fornat:FMT0

      *芯片选择:CS0

      ***/

      对于(i=0;i<8;i++)

      {

        mibspiRAM1->TX[i].control =(uint16)((uint16) 5U << 13U) /*缓冲模式*/

                     |(uint16)((uint16) 0U << 12U) /*芯片选择保持*/

                     |(uint16)((uint16) 1U << 10U) /*启用 WDELAY */

                     |(uint16)((uint16) 0U << 11U) /*锁定传输*/

                     |(uint16)((uint16) 0U << 8U) /*数据格式*/

                     |((uint16)(~((uint16) 0xFFU ^(uint16) CS_0))和(uint16) 0x00FFU); /*芯片选择*

      }

      /* MibSPI3:从器件,1 TG

      * TG0:仅1个缓冲器

      * OneShot 传输被复位:TGX 在每次触发事件发生且 TGENA 被置位时启动传输。

      *在从机模式下、序列发生器不会考虑触发源和触发事件等字段。

      *只有 SPICS 引脚才能触发传输组。

      ***/

      mibspiREG3->TGCTRL[0U]=(uint32)((uint32) 0U << 30U) /* OneShot *

                 |(UINT32)((UINT32) 0U << 29U) /* pcurrent reset */

                 |(UINT32)((UINT32) TRG_Always << 20U) /*触发事件*/

                 |(UINT32)((UINT32) TRG_DISABLED << 16U) /*触发源*/

                 |(uint32)((uint32) 0U << 8U); //开始缓冲区

      mibspiREG3->TGCTRL[1U]=(uint32)((uint32) 0U <<30U) /* OneShot *

                 |(UINT32)((UINT32) 0U << 29U) /* pcurrent reset */

                 |(UINT32)((UINT32) TRG_Always << 20U) /*触发事件*/

                 |(UINT32)((UINT32) TRG_DISABLED << 16) /*触发源*/

                 |(uint32)((uint32) 1U << 8U); /*启动缓冲器*/

      /*配置 MibSPI1 TG0的 TX RAM:

      * Bufmode:挂起覆盖保护模式。 挂起到等待、直到相应的 RXEMPTY 标志被置位

      *      (序列发生器在当前缓冲区停止、直到主机读取之前接收到的数据。)

      *芯片选择保持:0。 如果缓冲器中的 CSHOLD 位在从 MibSPI 中清零、即使在移位操作完成后、

      * MibSPI 等待直到 SPICS 引脚被取消置位、以将接收到的数据复制到 RXRAM。

      *如果 CSHOLD 位在所有缓冲区中保持为0、那么处于多缓冲区模式的从器件需要它

      *在任意两个缓冲器传输之间将被取消置位的 SPICS 引脚;否则、从器件 SPI 将无法取消置位

      *响应下一个数据传输。

      *数据 fornat:FMT0

      *芯片选择:CS0

      ***/

      for (i=0;i<1;i++){

        mibspiRAM3->TX[i].control =(uint16)((uint16) 6U << 13U) /*缓冲模式*/

                     |(uint16)((uint16) 0U << 12U)/*芯片选择保持*/

                     |(uint16)((uint16) 0U << 10U) //启用 WDELAY *

                     |(uint16)((uint16) 0U << 8U) /*数据格式*/

                     |((uint16)(~((uint16) 0xFFU ^(uint16) CS_0))和(uint16) 0x00FFU); /*芯片选择*

     }

    #if 0

      /* TG 起始地址。 PSTARTx 存储相应 TG 的起始地址。 相应的*/

      /*结束地址由后续 TG 起始地址减1 (PENDx[TXG]=  */)内在定义

      /* PSTARTx[TGX+1]-1)。 在以下情况下,PSTARTx 被复制到 PCURRENTx 中:*/

      for (i=0;i<8;i++){

       tgPSTART[i]=(mibspiREG1->TGCTRL[i]>> 8)& 0xFF;

      }

      /*MibSPI1 TG0,DMA config*/

      /*-在系统 RAM 中创建数据块,以...开始 *

      /* TXDATA_TG10 ->MibSPI1 TG0 */

      loadDataPattern (D_size、&TXDATA[0]、0x5A00);

      dmaConfigCtrlTxPacket ((uint32) TXDATA、(uint32)&(mibspiRAM1->TX[tgPSTART[0]).data)、E_COUNT、F_COUNT);

      //将 DAM_CH0用于 RX、将 DMA_CH1用于 TX

      /*-设置 DMA 控制数据包*/

      dmaSetCtrlPacket (dma_CH1、g_dmaCTRLPKT_TX); //TX

      dmaSetChEnable (DMA_CH1、DMA_HW);

      dmaReqAssign (DMA_CH1、DMA_REQ1);//DMA 请求线路1、TX

      //设置 MIBSPI DMA 通道触发器。

      uint32_t dmactrl_base1 =(1U << 31)/* OneShot *

                 |(1U <<14)/* TXDMAEN */

                 |(7U << 8)/* ICOUNT */;

      mibspiREG1->DMACTRL[0]= dmacTRL_base1

                 |(7U << 24)/* BUFID */

                 |(0U << 16)/* TXDMA_MAP */;

    #endif

      /* MibSPI3、从器件、TG0、DMA*/

      /* DMA 源地址:MibSPI RX RAM 缓冲器0 */

      /* DMA 目标地址:数据数组:RXDATA[]*/

      /* DMA 通道8,请求线路:5*/

      dmaConfigCtrlRxPacket ((uint32)&(mibspiRAM3->Rx[0].data)、(uint32) RXDATA、E_COUNT、F_COUNT);

      /*-设置 DMA 控制数据包*/

      dmaSetCtrlPacket (dma_CH8、g_dmaCTRLPKT_RX); //rx

      dmaSetChEnable (DMA_CH8、DMA_HW);

      dmaReqAssign (DMA_CH8、DMA_REQ5);

      /*选择 DMAxCOUNT 计数器。 写入 DMAxCTRL 寄存器不会修改 ICOUNT 值。

      *在中的 RXDMAENA 或 TXDMAENA 位置位之前、必须在 DMAxCOUNT 寄存器中写入 ICOUNT 值

      * DMAxCTRL 寄存器。 DMAxCOUNT 寄存器应用于读取计数或 ICOUNT。

      ***/

      mibspiREG3->DMACNTLEN = 0x1;

      mibspiREG3->DMACOUNT[0]=(F_COUNT*E_COUNT - 1)<< 16;

      /*设置 MIBSPI DMA 通道触发器。

      * OneShot 已设置。 允许定义长度的块传输(ICOUNTx+1)

      * BUFID 为0 (E_COUNT=1)

      ***/

      uint32_t dmactrl_base3 =(1U << 31)/* OneShot *

                 |(1U <<15)/* RXDMAEN */

                 |(7U << 8)/* ICOUNT */;

      mibspiREG3->DMACTRL[0]= dmacTRL_base3

                 |((E_COUNT - 1)<< 24)/* BUFID */

                 |(3U << 20)/* RXDMA_MAP */;

      /*启用 DMA */

      dmaEnable();

      /*启用 MibSPI3传输组0*/

      mibspiTransfer (mibspiREG3、0);

      /*将数据直接写入 TX RAM 缓冲区:配置8个缓冲区

      * 2个缓冲器之间的传输延迟在 FMT0中定义。 它是3.43us

      ***/

      mibspiRAM1->TX[0].data = TX_data1[0];

      mibspiRAM1->TX[1].data = TX_DATA1[1];

      mibspiRAM1->TX[2].data = TX_data1[2];

      mibspiRAM1->TX[3].data = TX_data1[3];

      mibspiRAM1->TX[4].data = TX_data1[4];

      mibspiRAM1->TX[5].data = TX_data1[5];

      mibspiRAM1->TX[6].data = TX_data1[6];

      mibspiRAM1->TX[7].data = TX_data1[7];

      /*-启动 Mibspi 传输 TG 0

      *每个传输组只有1个触发事件和触发源。 当其中的所有缓冲器都被发出时、触发器被发出

      *传输组已准备好传输

      *

      *此 SW 触发器是一个脉冲

      ***/

      mibspiTransfer (mibspiREG1、0);

    while (1);

     /*用户代码结束*/

      返回0;

    /*用户代码开始(4)*/

    /**使用配置 mibspi DMA

    *

    *   channel > mibspi DMA channel number

    *   txchannel >专用于 mibspi 的传输通道

    *   rxchannel >专用于 mibspi 的接收通道

    *

    void mibspiDmaConfig (mibspi_t * mibspi、uint32通道、uint32 txchannel、uint32 rxchannel)

      //uint32 bufid =(通道+ 1)* E_COUNT - 1;

      uint32 bufid = tgPSTART[通道]+ E_COUNT - 1;

      /*设置发送和接收通道*/

      mibspi->DMACTRL[通道]|=(rxchannel << 20)|(txchannel << 16);

      如果(F_COUNT > 1){

        mibspi->TGCTRL[通道]&= 0xBFFFFFFF;//禁用 OneShot

      }否则{

        mibspi->TGCTRL[通道]|= 0x40000000;//启用 OneShot

      }

      /*启用发送和接收 DMA */

      mibspi->DMACTRL[通道]|= 0x8000C000;

      /*设置 DMA 传输的初始计数和用于 DMA 传输的缓冲区*/

      mibspi->DMACTRL[通道]|= (bufid=24);

      /*启用大计数传输*/

      mibspi->DMACNTLEN = 0x1;

      mibspi->DMACOUNT[通道]=(F_COUNT - 1)<< 16;

    void loadDataPattern (uint32 psize、uint16* pptr、uint16模式)

      int i;

      for (i=0;<psize;i++))

      {

        *(pptr++)=图形+ I;

      }

    void dmaConfigCtrlTxPacket (uint32 Sadd、uint32 dadd、uint16 ElmntCnt、uint16 FrameCnt)

       G_dmaCTRLPKT_TX.Sadd   =添加;        /*源地址       *

       G_dmaCTRLPKT_TX.DADD   =添加;        /*目标 地址   */

       G_dmaCTRLPKT_TX.CHCTTRL  = 0;          /*通道控制       *

       G_dmaCTRLPKT_TX.FRCNT   =帧 cnt;      /*帧计数         *

       G_dmaCTRLPKT_TX.ELCNT   = ElmntCnt;      /*元素计数        *

       G_dmaCTRLPKT_TX.ELDOFFSET = 4;          /*元素目标偏移量*/

       G_dmaCTRLPKT_TX.ELSOFFSET = 0;          /*元素源偏移*/

       G_dmaCTRLPKT_TX.FRDOFFSET = 0;          /*帧目的偏移 量*/

       G_dmaCTRLPKT_TX.FRSOFFSET = 0;          /*帧目的偏移 量*/

       G_dmaCTRLPKPT_TX.PORTASGN = PORTA_READ_PORTB_WRITE;         /*端口 b           *

       G_dmaCTRLPKT_TX.RDSIZE  = ACCESS_16_BIT;   /*读取大小          *

       G_dmaCTRLPKT_TX.WRSIZE  = ACCESS_16_BIT;   /*写入大小         *

       G_dmaCTRLPKT_TX.tType   = FRAME_TRANSFSION;  /*传输类型        *

       G_dmaCTRLPKT_TX.ADDMODERD = ADDR_INC1;      读取/*地址模式      *

       G_dmaCTRLPKPT_TX.ADDMODEWR = ADDR_OFFSET;    /*地址模式写入     *

       G_dmaCTRLPKT_TX.AUTOINIT = AUTOINIT_OFF;   /*自动初始化          *

       //返回 g_dmaCTRLPKT_TX;

    void dmaConfigCtrlRxPacket (uint32 Sadd、uint32 dadd、uint16 ElmntCnt、uint16 FrameCnt)

       G_dmaCTRLPKT_RX.Sadd   =添加;        /*源地址       *

       G_dmaCTRLPKT_RX.DADD   =添加;      /*目标 地址   */

       G_dmaCTRLPKT_RX.CHCTRL  = 0;         /*通道控制       *

       G_dmaCTRLPKT_RX.FRCNT   =帧 cnt;         /*帧计数         *

       G_dmaCTRLPKT_RX.ELCNT   = ElmntCnt;       /*元素计数        *

       G_dmaCTRLPKT_RX.ELDOFFSET = 0;         /*元素目标偏移量*/

       G_dmaCTRLPKT_RX.ELSOFFSET = 4;         /*元素目标偏移量*/

       G_dmaCTRLPKT_RX.FRDOFFSET = 0;          /*帧目的偏移 量*/

       G_dmaCTRLPKT_RX.FRSOFFSET = 0;         /*帧目的偏移 量*/

       G_dmaCTRLPKPT_RX.PORTASGN = PORTB_READ_PORTA_WRITE; //端口 b           *

       G_dmaCTRPKT_RX.RDSIZE  = ACCESS_16_BIT;   /*读取大小          *

       G_dmaCTRLPKT_RX.WRSIZE  = ACCESS_16_BIT;   /*写入大小         *

       G_dmaCTRLPKT_RX.tType   = FRAME_TRANSFSION; /*传输类型        *

       G_dmaCTRLPKT_RX.ADDMODERD = ADDR_OFFSET;     读取/*地址模式      *

       G_dmaCTRLPKT_RX.ADDMODEWR = ADDR_INC1;   /*地址模式写入     *

       G_dmaCTRLPKT_RX.AUTOINIT = AUTOINIT_ON;   /*自动初始化          *

       //返回 g_dmaCTRLPKT_RX;