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.

[参考译文] CCS/TM4C129ENCPDT:从器件的 QSSI 写入-不工作

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/579880/ccs-tm4c129encpdt-qssi-write-from-slave---not-working

器件型号:TM4C129ENCPDT

工具/软件:Code Composer Studio

您好!

我有两块板、一个是 TM4CZAD 定制设计、 另一个是 TI TM4C129EXL 开发板。 这两个板通过 QSSI、定制板上的端口1、TI 开发板上的端口3进行连接。 我已经使用几种工作模式测试了 QSSI:

自定义设置为主 QSSI、向接头连接器(使用 DSO 探测连接器)写入8位帧- CSS、CLK 和4条数据线按预期工作。 注意:定制板没有外部晶振;时钟通过片上时钟源。

TI 电路板设为主 QSSI、向与端口3对应的 BoosterPack HDR 引脚写入8位帧。 同样、使用 DSO 探测连接器引脚可按预期工作。

3.自定义电路板设为主 QSSI,TI DEV 设为从 QSSI,主器件向从器件发送一个8位序列(自定义 BD 至 TI DEV BD),从器件接收数据,两个电路板 的开关模式,以便主器件从写模式切换到读模式, TI 开发 BD 从读取切换到写入、然后从电路板将数据发送回主器件(或主器件从从从从器件读取数据-这是我的困惑所在、这部分事务是如何启动的、从器件将数据发送回主器件?)

此时、当主器件发出 SSIDataGet 并且从器件已到达对 SSIDataPut 的调用时、案例#3失败。  在从主器件到从器件的初始写入之后、不会发送任何数据(在示波器上观察)、并且两个调试器会话(一个连接到主器件、另一个连接到从器件)滞留在这两个 SSIDataXXX 调用中。

我一直在研究以下以前的论坛;

https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/341195/1202177#1202177

e2e.ti.com/.../1384533

我认为,我已经应用了所提出的所有建议。 我认为我在这里做了一些根本错误的事情、但似乎无法让我的头脑四处走动。 希望这里的人能让我走上正轨。

主代码段来自 main:

  InitGPIO();
   SysCtlClockFreqSet (SYSCTL_OSC_INT、SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL);
   时钟= SysCtlClockGet ();

     Board_initQSSI (clock、baud _rate、0);


     SSIDataPut (SSI1_base、0xA5);
     SSIAdvModeSet (SSI1_base、SSI_ADV_MODE_Quad_Read);
     //SSIDataPutNonBlocking (SSI1_base、0x4000); //虚拟写入以使时钟运行到配置从器件、0x20=QuadMode  ->这没什么区别
     while (1)
        {
        SSIDataGet (SSI1_base、rcv_data);---------- >在这里挂起
        System_printf ("已接收:%d\n"、rcv_data[0]);
        //SysCtlDelay (1000);
        }

从器件的主代码段
    Board_initGeneral();
   Board_initGPIO();
   Board_initEMAC();
   Board_initUART();    
   //Board_initSPI ();    

   时钟= MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
           SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
           SYSCTL_CFG_VCO_480)、120000000);
           
   Board_initQSSI (clock、baud _rate、1);

   while (go =0)
     {
         SSIDataGet (SSI3_base、dataBuffer);
         if (dataBuffer[0]=165)
            GO = 1;
     }
      SSIAdvModeSet (SSI3_base、SSI_ADV_MODE_Quad_WRITE);
      SSIDataPutNonBlocking (SSI3_base、0x4000); //虚拟写入以使时钟运行到配置从器件
      system_printf ("切换到发送模式\n");
     while (1){
          SSIDataPut (SSI3_base、0x53);--- >在这里挂起
          System_printf ("已发送%x\n"、0x53);
          //SysCtlDelay (1000);
      }

最后、上述每个指令中对 Board_initQSSI 的调用、其中最后一个输入参数为0、对应于主控方;1、corrsp 对应于从控方:


void Board_initQSSI (uint32_t SYSCLK_Freq、uint32_t baud _rate、bool 从站)

    //启用 QSSI 外设
  if (slave=0){  //在  QSSI1 - RevX 主设备上使用端口 B、D、E
     MAP_SysCtlPeripheralEnable (SYSCTL_Periph_SSI1);
      MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
      MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
      MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
  }
  否则{ //在 QSSI3 - TI 开发 BD 从设备上使用端口 P、Q
     MAP_SysCtlPeripheralEnable (SYSCTL_Periph_SSI3);
      MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOP);
      MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOQ);      
  }


    //通过复用设置实现引脚功能。 这个宏被映射到 ROM_MAP.h 内的 GPIOPinConfigure
  // GPIOPinConfigure 在 GPIO.c 中为 def
  if (slave=0){ //使用 QSSI1上的端口 B、D、E
       MAP_GPIOPinConfigure (GPIO_PB5_SSI1CLK);
       MAP_GPIOPinConfigure (GPIO_PB4_SSI1FSS);
       MAP_GPIOPinConfigure (GPIO_PE4_SSI1XDAT0);
       MAP_GPIOPinConfigure (GPIO_PE5_SSI1XDAT1);
       MAP_GPIOPinConfigure (GPIO_PD4_SSI1XDAT2);
       MAP_GPIOPinConfigure (GPIO_PD5_SSI1XDAT3);
    }
    否则{ //使用 QSSI3上的端口 P、Q
       MAP_GPIOPinConfigure (GPIO_PQ0_SSI3CLK);
       MAP_GPIOPinConfigure (GPIO_PQ1_SSI3FSS);
       MAP_GPIOPinConfigure (GPIO_PQ2_SSI3XDAT0);
       MAP_GPIOPinConfigure (GPIO_PQ3_SSI3XDAT1);
       MAP_GPIOPinConfigure (GPIO_PP0_SSI3XDAT2);
       MAP_GPIOPinConfigure (GPIO_P1_SSI3XDAT3);     
    }
  
  //引脚操作设置。 这个宏被映射到 ROM_MAP.h 内的 GPIOPinTypeSSI
  // GPIOPinTypeSSI 在 GPIO.c 中为 def
  if (slave=0){  //使用 QSSI1上的端口 B、D、E    
      MAP_GPIOPinTypeSSI (GPIO_PORTB_AHB_BASE、GPIO_PIN_5 | GPIO_PIN_4);
      MAP_GPIOPinTypeSSI (GPIO_PORTD_AHB_BASE、GPIO_PIN_4 | GPIO_PIN_5);
      MAP_GPIOPinTypeSSI (GPIO_Porte AHB_BASE、GPIO_PIN_4 | GPIO_PIN_5);
  }
  否则{ //使用 QSSI3上的端口 P、Q
      MAP_GPIOPinTypeSSI (GPIO_PORTP_BASE、GPIO_PIN_0 | GPIO_PIN_1);
      MAP_GPIOPinTypeSSI (GPIO_PORTQ_BASE、GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
  }      

    //针对 QSSI (高级)模式设置为 SPI 模式0;设置主模式
    if (slave=0){
      MAP_SSIConfigSetExpClk (SSI1_base、SYSCLK_Freq、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、BAUD_RATE、 8);
      SSIAdvModeSet (SSI1_base、SSI_ADV_MODE_Quad_WRITE);
    }
    否则{
       SSIConfigSetExpClk (SSI3_base、SYSCLK_Freq、SSI_FRF_MOTO_MOTO_0、SSI_MODE_SLAVE、BAUD_RATE、 8);
       SSIAdvModeSet (SSI3_base、SSI_ADV_MODE_Quad_Read);     
     SSIDataPut (SSI3_base、0x4000); //虚拟写入以使时钟运行到配置从器件
    }
    //启用 QSSI
    if (slave=0){   
      MAP_SSIEnable (SSI1_BASE);
    }
    否则{
     MAP_SSIEnable (SSI3_base);
  }   

对 SSIDataPut 的调用是根据上述参考论坛的指导添加的。

总之、主器件最初向从器件发送一个帧、从器件接收该帧、然后继续切换模式、从读取模式切换到写入模式。 与此同时、主器件从写入切换到读取。

我正在运行此命令、以便从机可以运行、在第一个(也是唯一的) SSIDataGet 处等待。 在两个电路板上使用调试器进行步进、在两个电路板上完成对开关模式的调用后、操作停止。

我可以用一些帮助来解决这个问题 -任何建议都值得赞赏。

谢谢你。

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

    您好 Erik、

    我设置了一个简单的项目来向自己演示如何执行此操作。 我使用了一个 EK-TM4C129XL 电路板、其中 SSI1用作主器件、而 SSI3用作从器件。 实际上、我使用的是 BI 模式而不是四路模式、因为硬件上存在一些引脚冲突、但原理是相同的。

    在 BI 和 Quad 模式下、SSI 为半双工、但在某些情况下仍表现为全双工。 这就是从主器件发送到从器件的原因、我们使用一些虚拟数据来预填充从器件、以便它为传输做好准备。 同样,当我们从从器件向主器件发送数据时,我们在主器件上执行虚拟 SSIDataPut ()以生成时钟。

    这是我的简单示例。 它不使用 FIFO、中断或 DMA、但它可能有助于您了解和开始:

    //
    //
    // qssi.c -在2位(BI)模式下由 SSI 传输数据的简单示例。
    //
    //版权所有(c) 2013-2017 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    //德州仪器(TI)提供此软件仅供
    和//仅供 TI 的微控制器产品使用。 软件归
    // TI 和/或其供应商所有,并受适用的版权
    //法律保护。 您不能将此软件与"病毒"开源
    //软件组合在一起以形成更大的程序。
    //
    //此软件按“原样”提供,且存在所有故障。
    //对于
    
    本软件,不作任何明示、暗示或法定的保证,包括但不限于对适销性和适用性的暗示保证//特定用途。 在任何
    //情况下、TI 不对任何
    原因造成的特殊、意外或必然//损害负责。
    ////////
    
    *************
    
    #include 
    #include 
    #include "tm4c1294ncppdt.h"
    #include "sysctl.h"
    #include "rom_map.h"
    #include
    "pin_map.h"
    #include "HW_memmap.h"
    #include "gpio.h"
    
    #define master SSI1_base
    #define slave slave SSI3_base (void
    
    
    
    
    
    
    
    )#include "hw_memmap.h"#include "gpode_symt intradt void (ssnature32)、intrid eq.inct intrid (intrl 32)、intrid eq.intrid (intrap_pru.intrid) uint32_t baud _rate);
    void QSSISlaveReadMode (void);
    void QSSISlaveWriteMode (void);
    
    //*********
    //
    //! \addtogroup example_list
    //! 

    QSSI (QSSI)

    //! //! 一个非常简单的示例、使用直接寄存器 //! 使用 BI SSI 模式访问、发送和接收 // /********* int main (void) { uint32_t ui32Loop; uint32_t SYSCLK_Freq、波特率、数据; SysCtlClockFreqSet (SYSCTL_OSC_INT、SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL); SYSCLK_Freq = SysCtlClockGet (); BAUD_RATE = SYSCLK_FREQ >> 4U; // //启用用于板载 LED 的 GPIO 端口。 // SYSCTL_RCGCGPIO_R = SYSCTL_RCGCGPIO_R12; // //执行虚拟读取以在启用外设后插入几个周期。 // ui32Loop = SYSCTL_RCGCGPIO_R; // //为 LED (PN0)启用 GPIO 引脚。 将方向设置为输出、然后 //启用 GPIO 引脚以实现数字功能。 // GPIO_PORTN_DIR_R = 0x01u; GPIO_PORTN_DEN_R = 0x01u; //将 SSI1初始化为 BI 主控方 QSSIMasterInit (SYSCLK_Freq、BAUD_RATE); //将 SSI3初始化为 BI 从设备 QSSISlaveInit (SYSCLK_Freq、BAUD_RATE); // //永久循环。 // while (1) { // //打开 LED。 // GPIO_PORTN_DATA_R |= 0x01; // //将数据从主设备发送出去,并由从设备读取 // QSSISlaveReadMode(); QSSIMasterWriteMode(); for (ui32Loop = 0U;ui32Loop < 256u;ui32Loop +) { SSIDataPutNonBlocking (slave、0U);//虚拟写入使从设备就绪 SSIDataPut (主器件、ui32Loop); SSIDataGet (从站、数据); if (data!= ui32Loop) { for (;;); } } // //关闭 LED。 // GPIO_PORTN_DATA_R &=~(0x01u); // //将数据从从设备发送出去,并由主设备读入 // QSSIMasterReadMode(); QSSISlaveWriteMode(); for (ui32Loop = 0U;ui32Loop < 256u;ui32Loop +) { SSIDataPut (从器件、ui32Loop);//向从器件写入数据 SSIDataPut (主器件、0U);//虚拟写入主器件以生成时钟 SSIDataGet (主设备、&data); if (data!= ui32Loop) { for (;;); } } } //初始化 QSSI1作为主 器件空 QSSIMasterInit (uint32_t SYSCLK_Freq、uint32_t baud _rate) { map_SysCtlPeripheralEnable (sysctl_Periph_SSI1); MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE); MAP_GPIOPinConfigure (GPIO_PB5_SSI1CLK); MAP_GPIOPinConfigure (GPIO_PB4_SSI1FSS); MAP_GPIOPinConfigure (GPIO_PE4_SSI1XDAT0); MAP_GPIOPinConfigure (GPIO_PE5_SSI1XDAT1); MAP_GPIOPinTypeSSI (GPIO_PORTB_AHB_BASE、GPIO_PIN_4 | GPIO_PIN_5); MAP_GPIOPinTypeSSI (GPIO_Porte AHB_BASE、GPIO_PIN_4 | GPIO_PIN_5); MAP_SSIConfigSetExpClk (主器件、SYSCLK_Freq、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、BAUD_RATE、 8); MAP_SSIEnable (master); } void QSSIMasterReadMode() { SSIAdvModeSet (master、SSI_ADV_MODE_BI_READ); } void QSSIMasterWriteMode () { SSIAdvModeSet (主器件、SSI_ADV_MODE_BI_WRITE); } void QSSISlaveInit (uint32_t SYSCLK_Freq、uint32_t baud_rate) { MAP_SysCtlPeripheralEnable (SYSCTL_Periph_SSI3); MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOQ); MAP_GPIOPinConfigure (GPIO_PQ0_SSI3CLK); MAP_GPIOPinConfigure (GPIO_PQ1_SSI3FSS); MAP_GPIOPinConfigure (GPIO_PQ2_SSI3XDAT0); MAP_GPIOPinConfigure (GPIO_PQ3_SSI3XDAT1); MAP_GPIOPinTypeSSI (GPIO_PORTQ_BASE、GPIO_PIN_0 | GPIO_PIN_1 |GPIO_PIN_2 | GPIO_PIN_3); MAP_SSIConfigSetExpClk (从器件、SYSCLK_Freq、SSI_FRF_MOTO_MOTO_0、SSI_MODE_SLAVE、BAUD_RATE、 8); MAP_SSIEnable (从站); } void QSSISlaveReadMode() { SSIAdvModeSet (slave、SSI_ADV_MODE_BI_READ); } void QSSISlaveWriteMode () { SSIAdvModeSet (从站、SSI_ADV_MODE_BI_WRITE); }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    该示例明确且明确地说明了如何进行主从写入和从从主从读取。 谢谢你。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    同意海报 Erik (和类似)、尽管似乎"主/从定义"(第34/35行)与评论(第85/88行)冲突。

    (即 SSI1定义为主设备(第34行)但注释(第85行)注释 SSI3为(新)主设备...)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CB1、
    感谢您发现该错误。 像往常一样、进行良好的软件审核非常有价值。 我已编辑了我之前的帖子并更正了第85行和第88行的注释。