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.

[参考译文] CC3235SF:使用 SPI、UDMA 和 FreeRTOS 从 CC3200移植到 CC3235SF

Guru**** 2539830 points
Other Parts Discussed in Thread: CC3235SF, CC3200, SYSCONFIG

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

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1115976/cc3235sf-porting-from-cc3200-to-cc3235sf-with-spi-and-udma-and-freertos

器件型号:CC3235SF
Thread 中讨论的其他器件: CC3200SysConfig

您好!
我正在尝试将一个在乒乓模式下使用 SPI 和 UDMA 的工作项目从 cc3200移植到 cc3235sf。
具有 cc3235sf 的示例应使用 FreeRTOS。 到目前为止、移植存在重大问题。
微控制器通过 SPI 接口接收数据、并应在缓冲区满后立即触发中断。
正如我看到的、这个中断永远不会被触发。 是否有一个 SPI 与 UDMA、CC3235SF 和 FreeRTOS 配合使用的示例? 我通过 SysConfig 配置 SPI 驱动程序。

在旧示例中、矢量表直接在应用程序文件夹中的文件"startup_ccs.c"文件中定义、在使用 FreeRTOS 的新示例中、该表似乎是在文件中定义的
"startup_cc32xxCC32xx_css.c"。 原因是否在这里? 如果有人能给我带来黑暗中的光、那就更好了。

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

    您能否使用 CC32XX SDK 中的 SPI 示例之一来代替移植?

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

    您好、Sabeeh、

    感谢你的答复。 我正在尝试将现有的工作代码传输到新系统,因此我不能只使用 TI-example。 在旧代码中、乒乓传输在源代码中通过 UDMA_IF.c 进行配置 对于新的构建块、这不再起作用。 乒乓模式似乎是通过 TI 驱动程序 SPICC32XXDMA.h 进行配置的 但是、在 SPI 示例中、这一点从不直接寻址、不会直接调用 SPICC32XXDMA_init (SPI_Handle handle)。 我是否正确理解始终使用乒乓模式? 如何连续传输数据? 使用命令"transfer"?

    在旧代码中、我只调用该函数。 如何使用 SPICC32XXDMA.h 完成此操作?

    uDMA_transfer 旧代码:

    void UDMASetupPingPongTransfer(unsigned long ulChannel, void *pvSrcBuf1,
                                  void *pvDstBuf1, void *pvSrcBuf2,
                                  void *pvDstBuf2, unsigned long size)
    {
        UDMASetupTransfer(ulChannel, UDMA_MODE_PINGPONG, size, UDMA_SIZE_8,
                         UDMA_ARB_8, pvSrcBuf1, UDMA_SRC_INC_8,
                         pvDstBuf1, UDMA_DST_INC_8);
    
        UDMASetupTransfer(ulChannel|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, size,
                          UDMA_SIZE_8, UDMA_ARB_8, pvSrcBuf2, UDMA_SRC_INC_8,
                          pvDstBuf2, UDMA_DST_INC_8);

    (笑声)

    void UDMASetupTransfer(unsigned long ulChannel, unsigned long ulMode,
                                unsigned long ulItemCount, unsigned long ulItemSize,
                                unsigned long ulArbSize, void *pvSrcBuf,
                                unsigned long ulSrcInc, void *pvDstBuf,
                                unsigned long ulDstInc)
    {
        MAP_uDMAChannelControlSet(ulChannel, ulItemSize | ulSrcInc | ulDstInc | ulArbSize);
        MAP_uDMAChannelAttributeEnable(ulChannel,UDMA_ATTR_USEBURST);
        MAP_uDMAChannelTransferSet(ulChannel, ulMode, pvSrcBuf, pvDstBuf, ulItemCount);
        MAP_uDMAChannelEnable(ulChannel);
    }

    谢谢你。

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

    使用 SPICC32XXDMA.h、不会设置乒乓 DMA。 因此、按原样传输代码将不起作用。 因此、我建议使用基于 CC32XX SDK 中示例的 SPI。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我开始在代码中包含 SPI 示例 SPISlave。 但是、在此示例中、仅接收长度为30的消息。 在我的代码中、将传输大量的数据。 我是一个初级入门级的人、涉及到这个 uDMA 传输。 将示例传输到我的定制板后、我可以通过 SPI 传输字长为128的数据、并将其写入阵列。 头文件 SPICC32XXDMA.h 显示:
    /* ## DMA and Queueing * This driver utilizes DMA channels in ping pong mode
     (see device TRM) in * order to overcome the 1024 item DMA channel limit. 
     This means the driver * can execute multi kilo-item transactions without 
     pausing to reconfigure the * DMA and causing gaps in transmission.  */
     
     
    这是如何实现的? 如何通过 SPI 将大量数据传输到缓冲器。 然后、缓冲区将通过网络连接发送到网页。  
    您是否有另一个示例可以让我了解 SPI 和 UDMA 接口的行为? 您指的是哪一个 TI 示例? SPI 从器件/主器件? SPICC32XDMA.h 从未包含在这些示例中。
    如果您能帮助我解决这个问题、我将不胜感激。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Vignesh:  

    在这些示例中、ti/drivers/SPI.h 包含 SPICC32XX.h 文件。 SPISlave 和 SPImaster 只是显示一些流量的示例。 如果您希望发送更多流量、只需更改示例或在您自己的应用中使用相同的原则即可。

    您是否阅读过有关 SPI.h 的文档?  https://dev.ti.com/tirex/explore/node?node=AIQLpsWAlAhNbRw7tZeAww__fc2e6sr__LATEST 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Sabeeh                                                                                                                                                                                                                                           、感谢您的回复。 我现在已经实现了 SPI、如示例中所示。 在我的程序中、一个任务开始、从该任务开始初始化 SPI 并开始传输。 在此设置下、我尝试通过 SPI 传输 FPGA 传输的图像。 FPGA 连续发送8字节字64次、然后 FPGA 在短时间内快速锁定其 SPI。 实际上、我设法传输数据、但这些数据似乎不正确。 当我评估传输的数据时、我可以看到、尽管 jpeg 头文件的第一部分被传输、但后续数据不正确。 我怀疑 SPI 不能正确传输数据、并且参数设置不正确。
    在我们之前的工作设计中、我们以乒乓模式持续运行传输、直到达到一定数量的字节。 使用我们的当前代码、传递 函数被调用、直到达到特定数量的帧。          
    static void CamControllerInit()
    {
    
    
       MAP_PRCMPeripheralReset(PRCM_GSPI);
    
       SPI_Params      spiParams;
    
       // deafult-Werte der SPI laden
       SPI_Params_init(&spiParams);
    
       //spiParams.bitRate = SPI_IF_BIT_RATE;
       spiParams.mode = SPI_SLAVE;
       spiParams.dataSize = 8;
    
       slaveSpi = SPI_open(CONFIG_SPI_0, &spiParams);
    
       if (slaveSpi == NULL)
       {
           Display_printf(display, 0, 0, "Error initializing slave SPI\n");
           while (1);
       }
    
       else
       {
           Display_printf(display, 0, 0, "Slave SPI initialized\n");
       }
    
    }
    
    
    //*****************************************************************************
    static unsigned short CaptureImage(char** WriteBuffer)
    {
        memset(g_image.g_image_buffer,0xF80F,sizeof(g_image.g_image_buffer));    // fill image array with value 0f
        p_buffer = &(g_image.g_image_buffer[0]);                                 // p_buffer gets address from img array
    
    
    
            bool            transferOK;
            SPI_Transaction transaction;
    
            g_frame_size_in_bytes = 0;
    
    GPIO_IF_Set(GPIO3, g_uiCC3200_RDY_I, g_ucCC3200_RDY_I,true); // fpga activate
    
    
    while(g_frame_size_in_bytes < 40000) {
    
                // p_buffer++;
    
                // transaction.count = TOTAL_DMA_ELEMENTS;
                transaction.count = 64; // 8*8 = 64 -- 5000 * 8 = 40.000 8 bit frames übertragen
                transaction.txBuf = NULL;
                transaction.rxBuf = (void *) p_buffer;                  // in den P_Buffer schreiben
    
              transferOK = SPI_transfer(slaveSpi, &transaction);
    
              if (transferOK)
               {
    
             //   Display_printf(display, 0, 0, "Transfer ok");
                p_buffer += 64;
                g_frame_size_in_bytes += (32*sizeof(unsigned char));
    
              }
    
               else
              {
                    Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer");
                 // break;
               }
    
           }
    
    //    SPI_transferCancel(slaveSpi);
        GPIO_IF_Set(GPIO3, g_uiCC3200_RDY_I, g_ucCC3200_RDY_I,false); // fpga deactivate
    
        // Imagebuffer als hexwerte ausgeben
         printImageBuffer();
    
    
    
      *WriteBuffer = &(g_image.g_image_buffer[0]); // passing address of image array to the pointer
    
      size_t testarraysize = sizeof(testarray1)/sizeof(testarray1[0]);
    
    // *WriteBuffer = &(testarray1[0]); // passing address of image array to the pointer
    
    
     //g_frame_size_in_bytes = (sizeof(unsigned char) * testarraysize);
     Display_printf(display, 0, 0, "gframesizeinbytes %d\n", g_frame_size_in_bytes);
    
       return(g_frame_size_in_bytes);
    
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Vignesh、  

    我在 您的 CamControllerInit 函数中看不到任何对 PHAx 和 Poly 的引用。 这将解释为什么数据接收不正确。  

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

    您好、Sabeeh、

    据我所知,这些参数是在文件 spi.h 中的函数 spi_Params_init()中设置的 初始值 SPI_POL0_PHA0 (与旧版本一样)  
     *  Defaults values are:
     *  * SPI_Params.transferMode        = #SPI_MODE_BLOCKING
     *  * SPI_Params.transferTimeout     = #SPI_WAIT_FOREVER
     *  * SPI_Params.transferCallbackFxn = NULL
     *  * SPI_Params.mode                = #SPI_MASTER
     *  * SPI_Params.bitRate             = 1000000 (Hz)
     *  * SPI_Params.dataSize            = 8 (bits)
     *  * SPI_Params.frameFormat         = #SPI_POL0_PHA0
     */
    extern void SPI_Params_init(SPI_Params *params);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    同时、我获取通过 SPI 接口传输的图像数据、也可以通过 WebSocket 将其发送到我的 html 应用程序。 不过、传输延迟较高、会产生图像干扰。 我仍然不太清楚 SPI.h 和 SPICC32XMA.c 如何实现 UDMA 传输、即使从您不会真正智能的示例中也是如此。

    我知道数据大小被解释为 uint8_t 但是、我如何确保数据是地址对齐还是在内部完成? 有人能给我一些灵感、告诉我如何改善图像传输(jpeg 压缩)?

    目前、我通过 SPI 传输40、000帧、将其写入缓冲区、并通过 Web 套接字连接按数据包传输此缓冲区数据包。
    当前、SPI 传输(回调模式、被信标阻止)以及 Web 套接字传输发生在一个相同的任务中。 这可能不是最佳的、WebSocket 传输应该在其自己的任务中。 我的想法是通过 TaskNotifications 交替阻止 SPI 和 WebSocket 任务。 或者、有人可能对如何更好地处理高延迟和错误图像传输问题有什么想法?

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

    尊敬的 Vignesh:

    SPI 示例中使用了 DMA。 如何管理 FPGA 和 CC32xx 之间的通信? 如果您遇到延迟问题、则可能需要实施某种握手。 您可以通过使用 FPGA 到 CC32xx 的两个 GPIO 来实现这一点。 一个可以是"准备发送"标志、另一个可以是"清除发送"标志。  

    有多少字节被损坏? 数据线路本身上的数据是损坏的、还是仅 CC32xx 上的接收缓冲区? 您可能需要使用另一个器件或示波器来验证总线。 听起来您可能需要 CRC 来验证整个映像。  

    此外、似乎问题可能与 FPGA 有关。 情况不是这样吗?  

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

    您好、Sabeeh、
    很抱歉、我的回答很晚、我在过去2周内一直在其他地方忙。

    FPGA 由 CC32xx 通过低脉冲激活、然后开始通过 SPI 发送图像数据。
    FPGA 发送的数据应该可以、因为我们在旧设置中对 CC3200使用相同的设计。
    来自 FPGA 的数据被写入缓冲区、然后通过 WebSocket 发送。
    我现在已将 SPI 传输和 WebSocket 传输打包到各个任务中。
    TaskNotification 在这两个任务之间来回切换。 对于从 FPGA 到 SPI 的数据传输、我使用命令 SPI_transfer 和40000的 transaction.count。
    在旧设计中、通过 UDMA 发送了64字节 ping 和64字节 pong。 这是在达到40、000字节的取消条件之前完成的。
    如前所述、cc32xx 通过 uDMA 传输是通过 SPICC32XXDMA.h 实现的、我假设使用 SPI_transfer 时会发生与旧设计相同的情况。
    另一个区别是、在我们的旧设计中、没有使用 FreeRTOS、并且只有一项任务用于图像传输和 WebSocket 传输。
    你有其他想法吗?

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

    尊敬的 Vignesh:  

    因此、适用于 CC32xx 的 TI 驱动程序无法进行乒乓传输。 硬件确实支持乒乓传输、但 SPI TI 驱动程序中的软件不支持这种传输。 但 DMA 仍然被使用。  

    因此、您的交易将比 CC31xx 花费更长的时间。 为了进行实验、我建议尝试处理单个任务、甚至 noRTOS、以验证 FPGA/CC32xx 之间的图像传输。尽管这可能会降低延迟、但您至少可以验证系统的"稳健性"。  

    我难以 理解的是、您提到存在图像干扰。 您能否理解这是否由 SPI 传输引起? 如果是、您能否确认 SPI 相位和极性与 FPGA 的相位和极性匹配? 图像干扰是否由 WiFi 传输引起?

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

    您好、Sabeeh、

    这不是好消息。 我们已切换到 CC32xx 以增加5GHz 的数据吞吐量。 如果我们现在通过 SPI 进行数据传输的速度比以前慢、这对我们来说并不是很好。 我不太了解驱动程序不使用乒乓模式、而是使用 DMA 吗? 那么、我们是否需要编写自己的驱动程序? 现在、我强烈怀疑 SPI 是主要问题。

    我已经做了一个测试:我已经读取了由 SPI 通过 Hterm 填充的缓冲器。 然后、我使用 Base64转换器对从 hterm 接收到的十六进制值进行编码。 我已将 html 中的编码字符串显示为图像。 此图像不正确且不完整。 我将图片附加到此帖子。 这意味着我认为 WebSocket 传输不是问题。 它必须是 SPI。 数据必须在传输过程中的某个位置丢失。 极性和相位(均为模式0)我从旧设计中接管、FPGA 没有变化。 我测试了所有模式。 在模式00和模式11下、我在其他模式下得到一个结果、没有发生任何情况。

    项目的当前状态为:数据传输具有极高的延迟和部分失真图像。 我怀疑来自 SPI 的图像数据部分正确、部分损坏。 由于它与旧的构建块一起使用、我认为它必须使用 UDMA 和接口的另一种方式。

    感谢 Sabeeh 的帮助和建议。

    这是我直接从 SPI 获取的图像(手动解码)。 我还在我的 webapp 中看到了这种错误。

    decoded by Hand (Hterm, hex, base64)

    这是我在 Webapp (通过 WebSocket 发送)中收到的损坏图像的一个示例、其破坏程度随时间而异