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.

[参考译文] RTOS/EK-TM4C1294XL:QuadSPI DMA 块

Guru**** 2481875 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/699113/rtos-ek-tm4c1294xl-quadspi-dma-blocks

器件型号:EK-TM4C1294XL
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

员工、

我所做的是创建一个单个 RTOS 任务、使用 uDMA 从 TX 缓冲区中向 SSI3发送一些字节。 当我将 SSI3设置为传统模式(=单个数据线路、MOSI)并使用 SPI_transfer (masterSpi、&masterTransaction)时、它就能完美工作。

但当通过设置四通道 SPI 模式时
SSIAdvModeSet (SSI3_base、SSI_ADV_MODE_Quad_WRITE);

任务被永久阻止。 DMA 不会设置信号量    semaphore_post (semaphore_handle (&(对象   semaphore_post (semaphore_handle (&(object->transferComplete))));

t->transferComplete));

我已经检查了4条 DATx 线路上的信号。 它们还不错,和预期的一样。 可以看到完整的传输,包括 FSS 失效。 为什么 DMA 仍然处于活动状态?

我可以通过哪些方法来找出出现了什么问题? 有很多处理 SPI 四路传输的勘误表-是另一个错误吗? 感谢您的任何帮助...

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

    您能否发布 SSI 和 DMA 的完整配置代码?

    我不知道会影响这一点的勘误项、因此我怀疑某个项目配置不正确。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Ralf:
    感谢您的关注。 请允许我再次指出、在使用默认 SPI 单数据线路模式(=传统模式)时、一切都正常。 下面是我要使用的代码:

    *********************************************** 常设专家委员会的评论意见--------------------
    *如勘误表中所示、SSI1仅在传统模式下工作
    *在 EK-TM4C1294电路板上使用 SSI0和 SSI2线*
    => SSI3用于高级 SPI 四路模式
    */
    
    // XDCtools 头文件
    #include 
    #include 
    // BIOS 头文件
    #include 
    #include 
    // TI-RTOS 头文件
    #include 
    #include 
    // TI-TIVAWARE Driverlib
    #include 
    #include "inc/hw_memmap.h"
    //示例/板头文件
    #include "Board.h"
    
    #define SPI_MSG_LENGTH 28
    #define TASKSTACKSIZE 768
    
    Task_StructureINT0Struct;
    Char INT0Stack[TASKSTACKSIZE];
    UINT8 TxBuffer[SPI_MSG_LENG];
    
    UTS0 Transitmaster0
    
    
    
    
    
    
    ;USPI transfer_0 (USpmaster0);USpmaster0处理 USpart_Spag_Spag_0;USpmaster0 (USpmaster0) i<28;i++) masterTxBuffer[i]= i;//填充 TxBuffer
    masterSpi = SPI_open (Board_SPI0、NULL);//如果
    
    (masterSpi = NULL) System_abort ("初
    始化 SPI\n");否则 System_printf ("SPI master\n"
    
    )、请将 SPI 句柄初始化为默认主控方;如果下面的所有内容都已初始化、请注释掉/
    SSIAdvModeSet (SSI3_base、SSI_ADV_MODE_Quad_WRITE);//设置为四倍写入模式
    
    taskTransaction.count = SPI_MSG_length;//初始化主 SPI 事务结构
    masterTransaction.txBuf =(ptr) masterTxBuffer;
    masterTransaction.rxBuf = NULL;
    
    transferOK = SPI_transfer (sp_transfer (spi_transfer_parf
    )
    
    
    
    
    
    
    ;masterspi_transfer ("spi_transfer_shunt);task_transfer_shunt ("spi_transfer_sp"(spi_transfer);task_spi_spi_transfer_main_tisorf);task ("spi_transfer_shunt)(
    
    //构造 BIOS 对象
    
    Board_initGeneral();//调用电路板初始化函数。
    Board_initGPIO ();
    Board_initSPI ();
    
    Task_Params_init (&taskParams);//构造任务线程
    taskParams.priority = 1;
    taskParams.STACKSIZE = TASKSTACKSIZE;
    taskParams.stack =&0Stack;
    Task_con构(&task0Strasktr、(Task_cpuxfunt、(Task_taskTaskFtaskPxtaskt) &taskParams、NULL);
    
    GPIO_WRITE (Board_LED0、Board_LED_ON);//打开用户 LED
    BIOS_start ();//开始 BIOS
    返回(0);
    }
    

    这里是 EK_TM4C1294XL.c 文件的 SPI 部分:

    /*
    ================================================ SPI ========================================================
    */
    *放入子段以允许 TI 链接器正确删除项目*/
    #if defined (__TI_Compiler_version__)
    #pragma DATA_SECTION (SPI_CONFIG、".CONST:SPI_CONFIG")
    #pragma DATA_SECTION (spiTivaDMAHWAttrs、".const:TivaDMAHWAttrs
    
    
    )#include Tiva 
    #include 
    
    SPITivaDMA_Object spiTivaDMAObjects[EK_TM4C1294XL_SPICOUNT];
    
    #if defined (__TI_Compiler_version__)
    #defaultma data_align (TivaDMAscratchBuf、32)
    #elif defender_TI_systems_ic_ pragma
    
    
    
    
    
    
    
    
    
    
    (#tinatf_tidt_unt = tv_tintrun32_t&tintradas_t.pragma (#tinu_unt)= tintrinu.pragma = tidt.pragu_unt = t.pragma (#tidt_unt)#t_unt = tidt_unt = t.api20_unt = t.pragu.pragu.pragma~
    (#t_unt = t.pragu.pragu.pragu_t_unt = t.pragu.ape&t_unt = t.pragu.ape&t.ina32_t_t.pragma (#t.pr
    
    rxChannelIndex = 14、
    .txChannelIndex = 15、
    .channelMappingFxn = uDMAChannelAssign、
    .rxChannelMappingFxnArg = UDMA_CH14_SSI3RX、
    .spiChannelMapping&FxnArg = UDMA_CH15_IappingFxnARg = UDMA_NULL= 0*
    
    
    
    
    
    
    
    
    
    
    
    
    、TXDS_DP= 0.TS= 0.TS_0*= 0.TSN = 0.TSN = 0*= 0.tv_DP_0_N = nTv_TS_0_TS_TS_0_TSN = 0.TSN = 0.TSN = 0.TSN = 0.TSN = 0.TSN = nTv_N &F&F&FxN = 0*= nTv_N = nTv_N = 0_N = nTv_N
    EK_TM4C1294XL_initSPI ===
    //
    void EK_TM4C1294XL_initSPI (void)
    {
    
    // SSI3
    SysCtlPeripheralEnable (SYSCTL_Periph_SSI3);
    
    GPIOPinConfigure (GPIO_PQ0_SSI3CLK);
    GPIOPinConfigure (GPIO_PQ1_SSI3Q2);
    GPIOPinConfigure (GPIO_SSI3Q3_SSII_GPIOQ3
    )
    GPIOPinConfigure (GPIO_PF4_SSI3XDAT2);
    GPIOP1_SSI3XDAT3);
    
    GPIOPinTypeSSI (GPIO_PORTQ_BASE、GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    GPIOPINTypeSSI (GPIO_PHIN
    )、GPIO_PIN_1);GPIOP_PHIN (GPIO_PHIN)
    
    EK_TM4C1294XL_initDMA();
    SPI_init();
    }
    
    在头文件 EK_TM4C1294XL.h 中,SPI 定义如下:
    
    /*!
    *@def EK_TM4C1294XL_SPIName
    *@EK_TM4C1294XL 开发板上 SPI 名称的简短枚举
    */
    typedef enum EK_TM4C1294XL_SPIName{
    EK_TM4C1294XL_SPI3 = 0、
    
    EK_TM4C1294XL_SPICUNC_SPIName
    };EK-TM4C1294XL_SPIING_TM4C1294XL_SPIING_TM4C1294XL_SPIING_TM4C1294XL_SPIING_TM4C
    




    此致 Claus

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

    克劳斯、您好!

    感谢大家的分享、我希望配置能提供一些我想澄清的信息、那就是如果 SSI 模块按照 SSIAdvModeSet 的注释进行了正确配置:

    //! 当使用一个高级运行模式时、SSI 模块必须已经//
    ! 配置为八个数据位和\b SSI_FRF_MOTO_MODE_0协议。
    //! 所选的高级模式操作仅适用于新数据
    //! 写入 FIFO;FIFO 中已存在的数据为
    //! 当数据为
    //时、使用有效的高级操作模式进行处理! 书面。 

    您能否验证是否满足该配置要求?

    如果只有 DMA 信标导致问题、并且它不会仅发生在 QSSI 信标上、您是否在没有 DMA 的情况下尝试过此操作以进行跟踪? (不确定对您而言、变更的工作量有多大)

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

    拉尔夫的美好一天

    我现在尝试了几个不同的版本。 每次 SSI3正确配置为8位时、模式0。 RTOS 驱动程序堆栈提供的 SPIDMA 传输仍然无法与高级四通道 SPI 配合使用。

    为了验证 SSI3本身是否正常工作、我使用了 for 循环直接写入 TX-FIFO。 工作完成了。 它还可以与 SSIAdvFrameHoldEnable (SSI3_base)配合使用和不配合使用。

    接下来、我尝试在不使用 RTOS 驱动程序的情况下设置 DMA。 在数据表中进行一些阅读后、我设法使 DMA 正常工作。 我发送了一个模式、从00、01、02、03开始。 下面是时钟、FSS、DAT0、DAT1的屏幕截图:

    我想我必须使用该代码、而不是尝试找出 SPITivaDMA.c 中正在发生的情况

    /*---------------- 常设专家委员会的评论意见--------------------
     *与勘误表中一样、SSI1仅在传统模式(单个 SPI)下工作
     *在 quadSPI 中、Dat0 - Dat1线路也会交换
     否则在 EK-TM4C1294电路板上使用 SSI0和 SSI2线
     因此仅保留 SSI3。
     *使用 uDMA
     *

    // XDCtools 头文件
    #include
    #include
    #include
    #include
    // BIOS 头文件
    #include
    #include
    #include
    #include
    // TI-RTOS 头文件
    #include
    #include
    // TI-TIVAWARE Driverlib
    #include
    #include
    #include "inc/hw_memmap.h"
    #include "inc/hw_ssi.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    //示例/板头文件
    #include "Board.h"

    #define SSI_buffer_size  270
    #define TASKSTACKSIZE    768
    #define MSG_LENGTH       28

    Task_Structtask0Struct;
    char task0stack[TASKSTACKSIZE];
    Hwi_Handle SSI3IH;

    uint8 ui8SSITxBuf[SSI_buffer_size]; // Tx 缓冲器
    uint32 ui32uDMAErrCount = 0;


    //
    // SSI3中断处理程序
    //******** uDMAErrorHandler *********
    空 SSI3IntHandler (空)

       uint32 ui32状态;

       ui32Status = SSIIntStatus (SSI3_base、1);
       SSIIntClear (SSI3_base、ui32Status);
       //信号传输结束
       HWREG (SSI3_base + SSI_O_CR1)|= SSI_CR1_EOM;
       HWREG (SSI3_base + SSI_O_DR)= ui8SSITxBuf[MSG_LENGTH - 1];



    void masterTaskFxn (UARg arg0、UARg arg1){

       Types_FreqHz 频率;
       uint16 i;

       for (i=0;<SSI_BUFFER_SIZE; i++) {
           ui8SSITxBuf[i]=(uint8) i; //用模式填充 txBuff
       }

       //配置 SSI3
       BIOS_getCpuFreq (&freq);    // SPI 初始化1兆波特、8位、主控
       SSIConfigSetExpClk (SSI3_base、freq.lo、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、10000000、 8);
       SSIAdvModeSet (SSI3_base、SSI_ADV_MODE_Quad_WRITE); //设置为四路写入模式
       SSIAdvFrameHoldEnable (SSI3_base);  //保持 FSS

       //配置 uDMA
       SSIDMAEnable (SSI3_base、SSI_DMA_TX);   //为 TX 通道启用 UDMA 接口。
       //uDMA SSI3 TX
       //清除 UDMA SSI3TX 通道的属性,默认情况下应该已经完成。
       uDMAChannelAttributeDisable (15、UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIOR| UDMA_ATTR_REQMASK);
       //设置 UDMA SSI3TX 通道的 USEBURST 属性。  这将会
       //强制控制器在从 TX 缓冲区传输数据时始终使用突发
       uDMAChannelAttributeEnable (15、UDMA_ATTR_USEBURST);
       //配置 SSI3 TX 的控制参数。
       uDMAChannelControlSet (15、UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
       //设置 uDMA SSI3 TX 通道的传输参数。
       uDMAChannelTransferSet (15、uDMA_MODE_BASIC、ui8SSITxBuf、(void *)(SSI3_base + SSI_O_DR)、MSG_LENGTH-1);
       uDMAChannelAssign (UDMA_CH15_SSI3TX);   //分配通道映射
       uDMAChannelEnable (15);             //填充 SSI3 Tx FIFO
       SSIIntEnable (SSI3_base、SSI_DMATX | SSI_DMARX);//启用 SSI3 DMA TX/RX 中断。
       SSIIntEnable (SSI3_base、SSI_DMATX);//启用 SSI3 DMA TX 中断。
       SSIEnable (SSI3_base);              //启用 SSI3,现在将发送 txfio 中的所有字节

       System_printf ("done");
       Hwi_delete (&SSI3IH);
       uDMAChannelDisable (15);
       SSIDisable (SSI3_base);              //关闭 SSI3
       system_flush();


    int main (空)

       Task_Params taskParams;        //构造 BIOS 对象
       Hwi_Params HwiParams;
       ERROR_Block EB;

       board_initGeneral();       //调用电路板初始化函数。
       Board_initGPIO();
       Board_initSPI();

       Hwi_Params_init (hwiParams);
       hwiParams.priority =-1;
       SSI3IH = Hwi_create (INT_SSI3、   (Hwi_FuncPtr)(SSI3IntHandler)、  &hwiParams、&EB);

       Task_Params_init (&taskParams);   //构造任务线程
       taskParams.priority = 1;
       taskParams.STACKSIZE = TASKSTACKSIZE;
       taskParams.stack =_task0Stack;
       Task_construct(&task0Struct,(Task_FuncPtr) masterTaskFxn、&taskParams、NULL);

       GPIO_WRITE (Board_LED0、Board_LED_ON);  //打开用户 LED
       BIOS_start();   //启动 BIOS
       返回(0);


    致 Klaus-Michael

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

    由于您能够让它处理 TivaWare 调用而不是 TI-RTOS 调用、因此我将把这个主题传递给 TI-RTOS 团队、他们应该能够提供进一步的帮助。 感谢您采取这些步骤来证明 TI-RTOS 上的信号量存在问题。 让我们看看 RTOS 团队会回来、然后您才能在 TI-RTOS 实现中使用 TivaWare API。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Claus、

    请附上您正在工作的 CCS 项目吗?

    谢谢、

    Janet

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

    Janet 的美好一天

    请查找随附的压缩文件项目....

    此致 Klaus-Michaele2e.ti.com/.../QuadSPI_5F00_13_5F00_EK_5F00_sce.zip

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

    Klaus、您好!

    我更深入地研究了 Tiva 的 SPI 驱动程序、我认为由于它当前已实现、它无法支持四路模式。  我在两个 MSP432E4电路板上使用四路模式设置 SPI 主器件/ SPI 从器件示例(与 EK-TM4C129XL 非常相似)。  结果是从器件从主器件获得了第一条消息、但主器件卡在第一个 SPI_TRANSLT()调用中。  似乎 SPI 驱动器总是希望返回一些内容、即使您将 SPI 事务中的 RX 缓冲区设置为 NULL 也是如此。  这导致主器件在第一个 SPI_TRANSFER ()调用中被阻止。

    我针对 SPI 驱动程序提交了一个错误以支持此操作。

    此致、

    Janet

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

    我将其标记为"TI 认为已解决"、因为我们不支持当前驱动程序中的四通道模式。 我不确定我们是否会在未来的版本中解决这一问题。 解决方法是将 SPI 代码添加到项目中并自行添加四通道支持。 我意识到这不是可取的、但实际上、TI 现在只能在这个问题上提供它。

    我们希望在今年晚些时候为 MSP432E4器件添加四路模式支持。

    Todd