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.

[参考译文] TM4C129XNCZAD:开关数据宽度后的奇怪 SPI 总线输出

Guru**** 2394295 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/685374/tm4c129xnczad-strange-spi-bus-output-after-switching-data-widths

器件型号:TM4C129XNCZAD

我已经用自己的头在墙上打了几天、试图弄清楚 SPI 总线通信可能出现的问题。 我使用一条总线与两个不同的器件通信。 器件 A 使用8位数据宽度、器件 B 使用16位数据宽度。

如果我从未与 器件 B 通信、则与器件 A 的通信正常。 但是、如果我与器件 B 通信、然后切换到器件 A、我会遇到奇怪的行为。

我正在使用 Beagle SPI 总线监听器来检查在 Tiva 和设备 A 之间传输的数据。当我向设备 A 发送0xB0命令代码时、监听器会显示正在传输一个包含正确值的字节。 但是、如果我首先与器件 B 通信、当我将 SPI 重新配置为8位模式并将0xB0发送到器件 A 时、监听器会指示发送了2个字节- 0x58和0x00。 值得注意的是、0x58是向右移动一位的0xB0。 监听 器还会为事务标记"部分最后字节"错误。 后续交易似乎可以。

在两种情况下(与器件 B 通信之前和之后)、我都在发送之前检查了 SSI 寄存器的内容、它们是相同的:

SSI_CR0 0x000013C7 SSI 控制0 [存储器映射]
SSI_CR0_SCR 00010011 SSI 串行时钟速率
SSI_CR0_SPH 1 SSI 串行时钟相位
SSI_CR0_SpO 1 SSI 串行时钟极性
SSI_CR0_FRF 00 - SSI 帧格式选择
SSI_CR0_DSS 0111 - SSI 数据大小选择
SSI_CR1 0x00000000 SSI 控制1 [存储器映射]
SSI_CR1_EOM 0停止帧(消息结束)
SSI_CR1_FSSHLDFRM 0 FSS 保持帧
SSI_CR1_HSCLKEN 0高速时钟使能
SSI_CR1_DIR 0 SSI 工作方向
SSI_CR1_MODE 00 - SSI 模式
SSI_CR1_EOT 0传输结束
SSI_CR1_MS 0 SSI 主/从选择
SSI_CR1_SSE 0 SSI 同步串行端口使能
SSI_CR1_LBM 0 SSI 环回模式
SSI_DR 0x00000000 SSI 数据[存储器映射]
SSI_SR 0x00000003 SSI 状态[存储器映射]
SSI_SR_BSY 0 SSI 忙位
SSI_SR_RFF 0 SSI 接收 FIFO 满
SSI_SR_RNE 0 SSI 接收 FIFO 不为空
SSI_SR_TNF 1 SSI 发送 FIFO 未满
SSI_SR_TFE 1 SSI 发送 FIFO 空
SSI_CPSR 0x00000002 SSI 时钟预分频[存储器映射]
SSI_IM 0x00000000 SSI 中断屏蔽[存储器映射]
SSI_RIS 0x00000048 SSI 原始中断状态[存储器映射]
SSI_MIS 0x00000000 SSI 屏蔽中断状态[存储器映射]
SSI_ICR 0x00000000 SSI 中断清除[存储
器映射] SSI_DMACTL [Memory 映射]
SSI_PP 0x0000000D SSI 外设属性[存储器映射]
SSI_CC 0x00000000 SSI 时钟配置[存储器映射] 

如果 SSI 寄存器在这两种情况下都相同、您有什么想法吗? 您有什么建议可以让我找到更多线索、或者解决此问题的任何可能方法吗?

此致、

Dave

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

    当然、供应商会建议您"使用 API "、这提供了许多示例、但没有一个示例会冒险进入您(相当独特)的地形。

    我敢肯定、您实施"MCU SPI 外设复位"时、"从"8更改为16"(或反之)将会正确-但这是(公认的)极端!

    "值得注意的是"您的"测量仪器"显然没有参与您(现在)的报告。

    您(即使是临时)使用 API -只是为了查看此类"可能会解决"问题-对于添加的见解而言似乎是合理的-它(可能)提供...

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

    我已经在使用 TivaWare API 函数来设置所有内容并执行数据写入和读取。 我尝试在环回模式下执行简单测试、在这种模式下、我只是来回更改了数据宽度、但无法重现问题。 因此、除了数据宽度之外、可能还有其他事情正在进行、尽管我目前看不到数据宽度。

    您建议以专业的方式重置 SSI 外设、这是一种诊断工具。 但是、正如您所说的、对于实时操作来说、这有点极端。

    此致、

    Dave
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    正如 CB1建议的那样、我在写入器件 A 之前尝试对 SSI 外设进行完全复位:

    SysCtlPeripheralReset (SYSCTL_Periph_SSI3);
    while (!SysCtlPeripheralReady (SYSCTL_Periph_SSI3))



    这实际上使事情变得更糟。 它会导致相同的错误行为(发送0x58、0x00)、但没有与器件 B 交谈! 我认为这是一个好的线索,但它肯定似乎是不符合逻辑的。 也许一夜安眠会让我更清楚。

    此致、

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

    [编辑]请注意、Dave 的帖子(17:20)和我的帖子(17:21)刚刚交叉!   (下面的文章-对 Dave 最近的调查结果没有任何了解)  [edit]部分(蓝色)有这样的了解!

    您好、Dave、

    我同意-但作为一名 Sailor (我本人和供应商的 Bob)... "风暴中的任何端口"(即可怕的 Periph)。 重置)证明欢迎。

    我的公司一般认为、一旦我们能够取得(部分)成功(通常是(全部)成功)、就会"更快/更容易"地获得成功。   我相信、除了"最专业的供应商代理"、我不会"梳理您的 DRM 代码"、尝试"调出"(您的)答案。   我曾在这个论坛(也有几个论坛)、"从未"注意到您描述的问题。

    如果您的"四个器件"是相同的"拆分"、以便"类似数据宽度"的器件可以共存、那么这是理想的做法。    

    作为"完整外设复位"的替代方案-也许您可以采用"重复 SPI 总线配置"-以确保您的"更改"... 真的生效了!

    另一个想法-您是否使用了"外设就绪功能"、以便不"假设"总线配置。 已执行-但为了"确保"它已执行? 这可能是高级建议-来自此帖子的愤怒...

    [编辑] 阅读最新帖子(上面一个)后: 我看到您在最新帖子中部署了"外设就绪"功能-至少在"一点"上。

    我必须为 "外设复位功能"辩护-如您所述-当此类功能"保证将外设置于适当且中立的状态"时、我几乎可以确保(某处)您的 SPI 外设设置和配置不正确!   我毫不怀疑!  

    现在您的代码确实显示了"Peripheral Reset()"-但并未显示"SPI 外设所需的初始化(重新初始化)!   (真的)发生了这种情况吗?   这一点至关重要!

    我还想补充一点、即使您"对 Beagle Board 的信任"也是如此、清晰可辨的"Scope-Cap"至少在帧中显示两个 SPI 字节、这将非常有帮助!   请注意-您必须"手动控制 CS 线路-连接到每个 单独的从设备。   (这一点尤其在您尝试"生成"多字节"SPI 传输时证明!")   我不记得这是不是以前提到过的-但是值得重新说明一下...

    "可能"的匆忙代码加法"错过了一些关键部分"并不少见、而且"外设复位"和"适当的外设初始化"始终有效!

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

    您好、 CB1、

    实际上、在每次使用前都会重新配置 SPI 总线。 是的、在与器件通信时启用了芯片选择线路。 已知该代码在 Stellaris 处理器上可以正常工作。 我一直在处理将其移植到 Tiva 的工作。 唯一的区别是接口已从 SSI0移动到 SSI3。

    我没有显示设置代码、部分原因是实际源代码使用多个抽象层、而对 TivaWare 库的调用是存储在上下文结构中的传递值。 因此、即使我展示了代码、也无法看到实际配置的内容。 这就是为什么我选择在我的初始帖子中包含实际的 SSI 寄存器内容。 您可以确切地看到器件的配置方式。

    令我不安的是、器件配置在正常工作的情况下和在正常工作的情况下完全相同。 标志表明 TX 和 RX FIFO 都是空的。 那么、为什么东西的工作方式不同呢? SSI 寄存器之外是否还有其他也会影响外设操作的东西? (请注意、我在此实现中不使用 DMA 或中断。)

    我将继续研究我在外设复位方面发现的问题、并发布任何发现。

    此致、

    Dave

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

    感受您的痛苦-但并不是您所能做到的程度。

    您正在监控的 SPI 寄存器(我想通过 IDE)是否可能是"读取敏感"的-这些寄存器是"寻址"的简单事实-是否"屏蔽了它们的内容?"   (我不再做太多的编码-员工证明在该领域非常出色... 我们部署了三家供应商的 ARM MCU -这一家除外。)

    "kiss"-我已经上瘾了-要求您以尽可能低的数据速率"开始您的测试/验证过程"。   即使您的从站(看起来)正常工作(有时)-我更希望您以最慢的速率工作-直到问题得到正确识别和解决。

    对于从器件芯片选择-您确实意识 到-由从器件指定-您可能必须在"多字节"事务的整个过程中"命令单个"CS"保持"活动"。   (这就是为什么"FSS 引脚(MCU 控制模式)"受到有限使用的原因...)

    虽然不方便-尤其是当您"现场"时-请求的示波器电容-清楚地揭示了"两字节"(失败)交易将证明具有巨大的价值。   (我是特定的供应商员工-会同意。)  串行接口具有吸引力-但却是一场"噩梦"-当发生故障且正确的测试设备"不可用"时。   当我们"进入现场"时、我的公司采用多个 Tek 便携式望远镜(隔离式通道和电池供电)。    (我认为 Beagle Board 功能强大-单凭它-并不"完全胜任这项诊断任务。")

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

    乍一看、我对芯片选择持怀疑态度。 您如何验证"与器件通信时启用了芯片选择线路"? 还需要验证在不需要时未选择它们。

    您能否从原型板上物理移除器件 B? 如果问题仍然存在、但 B 消失、则可能是固件问题。 正如 CB1所指出的那样、用一个非常慷慨的灵魂来梳理您的行为准则、这是一种良好的意愿。

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

    您好、Peter、

    感谢您的回复。 我有单步执行代码来验证是否正确启用/禁用了芯片选择。 我使用调试器检查 GPIO 端口的状态、以验证控制的端口和位是否正确。 此外、SPI 总线监听器仅在 CS 处于低电平时捕获数据、其输出与 CS 正确一致。 最后、正如我之前提到的、只要我只与一个器件或另一个器件通信、代码就可以正常工作。

    遗憾的是、无法轻松删除器件 B。我不怀疑固件存在问题、我当然不会要求任何人对代码进行梳理。 我只是问是否有人知道、为什么即使配置寄存器看起来是相同的、SSI 端口的性能也会有所不同。

    此致、

    Dave

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

    您能否发布所有相关代码块供我们查看? 似乎您只使用 TivaWare API、如果使用、我们可以详细查看、这将有助于我们努力提供帮助。

    我还将备份 CB1在提供 SPI 线路的示波器截图时请求的内容。

    对于每个 SPI 器件、有关其相位和极性要求的规格将很有用(即什么 SPI 模式)。

    最后、您操作 SPI 总线的时钟速度是多少?SS 线路是由 TM4C SPI 外设处理、还是由固件通过 GPIO 切换手动处理?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ralph、

    器件 A 以2000000bps、模式3、8位运行。 器件 B 以500000bps、模式0、16位运行。 SS 线路通过 GPIO 切换手动控制。

    相同的代码用于配置两个器件。 一个上下文结构被传递给函数以指定所需的配置:

    SNativeInt setSPIConfig ( PCONTEXT_DEVSPI pContext ){
    uint32_t ulMode、ulDMA;
    
    /*禁用 SPI 控制器,以便我们可以对其进行配置*/
    SSIDisable ( pContext->uBase );
    
    if (pContext->bMaster){
    ulMode = SSI_MODE_MASTER;
    }
    否则,如果(pContext->bDisableOutput){
    ulMode = SSI_MODE_SLAVE_OD;
    }
    否则{
    ulMode = SSI_MODE_SLAVE;
    }
    
    uldma = 0;
    if (pContext->bDMARX){
    ulDMA |= SSI_DMA_RX;
    }
    if (pContext->bDMATX){
    ulDMA |= SSI_DMA_TX;
    }
    
    /*将配置映射到硬件*/
    SSIConfigSetExpClk (pContext->uBase、getSystemClockFreqHz()、
    pContext->uMode、ulMode、pContext->uBitRate、pContext->uDataBits);
    
    SSIDMADisable ( pContext->uBase,~ulDMA );
    SSIDMAEnable ( pContext->uBase,ulDMA );
    
    返回0;
    }
    

    这些变量的值如下:

    稍后在代码中启用 CS。 然后调用以下函数来传输数据。 在这种情况下、有一个字节将被发送(0xB0):

    INT WRITE_DevSPI (
    bsp_dev_pdeviceCONTEXT pContext、
    const void *pData、int nbytes、
    unsigned short uTimeout_ms){
    PCONTEXT_DEVSPI pDev =(PCONTEXT_DEVSPI) pContext;
    SNativeInt NElement、NElements;
    
    if (device_tag_DEVSPI!= pDev->uDeviceTag){
    /*不是有效的设备*/
    errno =默认值;
    _pl 错误( errno );
    返回-1;
    }
    
    /*
    此例程只允许传输深度尽可能大的
    SPI FIFO;8个字节或8个字。 必须进行较大的传输
    以降低软件不会出现的风险
    能够跟上 SSI 控制器的传输速率(这已经实现了
    发生了)。
    *
    nElements=( pDev->uDataBits <= 8)? nbytes:nbytes/2;
    if (((nbytes < 0)||(nElements > SSI_FIFO_DEPTH)){
    errno = EINVAL;
    _pl 错误( errno );
    返回-1;
    }
    
    /*禁用 SPI 控制器*/
    SSIDisable (pDev->uBase);
    
    
    /*确保 RX FIFO 被清除*/
    clearRxFIFO ( pDev );
    
    if ( pDev->uDataBits <= 8){
    /*一个字节/元素*/
    uint8 const* puData =(uint8 const*) pData;
    
    对于(nElement=0;nElement<nElements;++nElement){
    SSIDataPutNonBlocking (pDev->uBase、(UINT32_t)*(puData++));
    }
    }
    否则{
    /*两个字节/元素*/
    uint16 const* puData =(uint16 const*) pData;
    
    nbytes = nElementes * 2;
    对于(nElement=0;nElement<nElements;++nElement){
    SSIDataPutNonBlocking (pDev->uBase、(UINT32_t)*(puData++));
    }
    }
    
    /*启用 SPI */
    SSIEnable (pDev->uBase);
    
    /*等待 SPI FIFO 开始传输*/
    SysCtlDelay (SPI_ENABLE_DELAY_COUNT);//延迟3个 CPU 周期
    
    /*等待 FIFO 清空后再返回*/
    while ( SSIBusy ( pDev->uBase )){
    /*在这里等待... */
    }
    
    返回 nbytes;
    }
    

    clearRxFIFO 函数定义为:

    void clearRxFIFO (PCONTEXT_DEVSPI pDev){
    uint32_t ulValue;
    
    /*
    通过持续读取直到 FIFO 报告、将 RX FIFO 清零
    它是空的。 提供此函数的原因是 SPI 写入操作
    也会导致 RX FIFO 填满。 但是、SPI 写入例程确实如此
    当前未从 RX FIFO 中读取以将其清除。
    *
    while (0!= SSIDataGetNonBlocking (pDev->uBase、&ulValue)){
    }
    } 

    稍后禁用 CS。

    以下是良好交易的 SPI 监听器跟踪:

    下面是坏的跟踪:

    下面是不良交易的错误报告:

    就获得示波器跟踪而言、这可能很困难。 我目前不在我的正常工作地点工作、因此我无法访问多通道范围。 不过、我可能能够跟踪逻辑分析仪。

    此致、

    Dave

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

    您之前没有提到 DMA、它用于传输 SPI 数据吗? 如果是、我还想查看该配置的完整详细信息。 这会在所有这些方面增加另一层复杂性。

    此外、我看不到 SPI 外设和 GPIO 的初始配置、例如 SysCtlPeripheralEnable 和 GPIOPinConfigure/GPIOPinTypeSSI、您也可以共享这些详细信息吗? 我想帮助验证在配置方面没有缺少任何东西。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ralph、

    我们仅将 DMA 用于大数据传输。 对于发生故障的情况、DMA 未被使用。

    以下是配置 GPIO 以供 SPI 使用的代码:

    #define common_SPI_sysctl SYSCTL_PERIPH_SSI3
    #define common_SPI_base SSI3_base
    
    #define common_SPI_MOSI GPIO_PQ2_SSI3XDAT0
    #define common_SPI_MOSI_PORT GPIO_PORTQ_BASE
    #define common_SPI_MOSI_PIN GPIO_PIN_2
    
    #define common_SPI_MISO GPIO_PF0_SSI3XDAT1
    #define common_SPI_MISO 端口 GPIO_PORTF_BASE
    #define common_SPI_MISO/PIN GPIO_PIN_0
    
    #define common_SPI_CLK GPIO_PQ0_SSI3CLK
    #define common_SPI_CLK_PORT GPIO_PORTQ_BASE
    #define common_SPI_CLK_PIN GPIO_PIN_0
    
    // AM (CPLD) SPI 芯片选择
    #define AM_CSn_PORT GPIO_PORTQ_BASE
    #define AM_CSn_PIN GPIO_PIN_1
    
    //显示 SPI 芯片选择
    #define LCD_CSn_PORT GPIO_Porth_BASE
    #define LCD_CSn_PIN GPIO_PIN_5
    
    GPIOPinConfigure (common_SPI_MOSI );
    GPIOPinTypeSSI (common_SPI_MOSI_port、common_SPI_MOSI_PIN);
    
    GPIOPinConfigure (common_SPI_MISO );
    GPIOPinTypeSSI (common_SPI_Miso_port、common_SPI_Miso_PIN);
    
    GPIOPinConfigure (common_SPI_CLK );
    GPIOPinTypeSSI (common_SPI_CLK_port、common_SPI_CLK_PIN);
    
    //芯片选择
    GPIOPinTypeGPIOOutput (AM_CSn_port、AM_CSn_PIN);
    GPIOPinTypeGPIOOutput (LCD_CSn_port、LCD_CSn_PIN);
    
    GPIOPadSet (common_SPI_CLK_pin、CLK_pin
    GPIO_Strength 8mA_SC、GPIO_PIN_TYPE_STD);
    
    //将所有 SPI 芯片选择置于非活动状态*/
    GPIOPinWrite (FLASH_CSn_PORT、FLASH_CSn_PIN、FLASH_CSn_PIN);
    GPIOPinWrite (AM_CSn_PORT、AM_SYSCSn_PIN、AM_CSn_CSn_PIN);GPIO_CSn_PIN_COMMON (
    _SYSCN
    
    
    );{_SYSRBLE_SYSRPT_SYSRT_SP_PIN_SYSRT}(_SN_SYSRT_SYNOT_SY_SYSRT_SYSRT_SYSRTL_NOT_SYN)
    
    ;GPIOPEN_SN_NOT_SY 

    此致、

    Dave

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

    您的代码显示" 跨端口使用!"

    #define common_SPI_MOSI GPIO_PQ2_SSI3XDAT0
    #define common_SPI_MOSI_PORT GPIO_PORTQ_BASE
    #define common_SPI_MOSI_PIN GPIO_PIN_2
    
    #define common_SPI_MISO GPIO_PF0_SSI3XDAT1
    #define common_SPI_MISO 端口 GPIO_PORTF_BASE
    #define common_SPI_MISO/PIN GPIO_PIN_0 

    可能不是"法律"。 供应商代理可能会知道-但我不相信这是一个"好主意"。 实际上、对于(非 SPI 引擎)"GPIO as Chip Select"来说、这是"可以"的-但我对它(成功)提出了疑问
    和持续使用)。

    不同的注释:您针对两个 SPI 从器件中的每一个使用不同的 SPI 时钟速率。 至少现在-在" germlin geat mode"期间-我强烈建议您将这些内容呈现为通用-
    个数据速率中较低的一个! 是纯粹的“亲吻”,你需要一切可能的东西——在你身边!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    CB1、

    我不熟悉术语"跨端口使用"。 这到底是什么意思? 它是好还是坏?  :-)  

    此致、

    Dave

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

    再次查看我的两个项目(前面的文章、上面的文章)、"置于突出显示状态"。

    #define COMON_SPI_MOSI_PORT GPIO_PORTQ_BASE

    #define common_SPI_MISO 端口 GPIO_PORTF_BASE

    记下不同端口的每个弹簧。  (即 Q 和 F) 现在-如果您的"SSI3"将它们描述为"真正"SSI3""耦合引脚-那么这是可以接受的做法。   然而、如果不是-从(不同端口)抽取引脚以在 SPI 引擎下运行-则不太可能成功。

    通常-但并非总是- MOSI 和 MISO -来自同一 MCU 端口。   只要 MCU 手册将这些引脚列为"SSI3" 、您就可以了。   如果不是-这是一个问题...

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

    很抱歉,我第一次看你的帖子,只是第一句。 刷新浏览器后、帖子的其余部分出现了幻影。

    对于 SSI3、这些是 MISO 和 MOSI 的正确端口/引脚分配。 我认为这也很奇怪、但这就是 TI 对它的映射方式。

    我尝试以较低的速度运行这两个器件、但没有什么不同。 测试后、我再次使它们不同、这样我就可以轻松地验证是否将正确的数据写入 SSI 配置寄存器。

    此致、

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

    好的-作为一个、"相当成功/成长-基于诊断-技术公司"-我们努力离开、"不(可能)不会被石头扔了!"

    在"重新初始化"每个单独的 SPI 外设之前、您是否继续使用"外设复位"和"等待完成"?

    另一个想法-通常是"拯救"-(幽默、sil vous plaît)-在 SPI 初始化中、在每个函数调用之间添加延迟。 事实上,(稍后)我们会尽快地——我们会对他们课税——但现在却是“在黑暗中”和“绝望”——任何港口都会做……

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我整天都在尝试各种东西、有一次我删除了外设复位、以免被发现。 我可能会尝试将其放在代码的较低级别、以便它实际上在每次更改配置时都会执行。

    我已经尝试在这里和那里添加延迟、但没有效果。

    此致、

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

    感受您的痛苦-然而、"在这里和在这里"并不"以工作著称!" (例如、您如何知道"在这里"真正(或最好)居住的地方?)
    如果我可以的话--所需要的是一项有大量文件记载的系统努力--以"尽可能消除尽可能多的(可能造成损害的)变量"。

    我们应该问-您是否有第二(或第三)个 TM4C 板-以及(完全相同)鼠疫-也存在于那里?    单板异常(始终)为"制造真切!"

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

    您好、CB1、

    我有另一个开发套件板、但 我正在使用的设置包括连接到另一个 PC 板的开发板。 这是一个真正的老鼠窝、因此不可能只换出开发板。 如果未连接 PC 板、代码将无法通过自检。 我想我可能能够破解代码来解决这个问题。 但问题似乎是由于开发板损坏造成的。 我想、如果我足够失望、我可能会尝试一下。 但我认为我的下一步是将调试打印语句添加到 TivaWare SSI 库函数中、这样我就可以准确地看到外设是如何配置的。

    此致、

    Dave

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    该位定义了帮助重申端口使用情况。 如果 SSI3数据引脚不在端口 Q 引脚2上、宏 GPIO_PQ2_SSI3XDAT0将(应该)不存在。

    TivaWare 函数没有太多可调试的内容;大多数情况下、只需将该值置为有效、然后设置寄存器即可。 如果有疑问、您可以在调试会话期间检查寄存器的设置是否正确。 请注意、在为外设调用 SysCtlPeripheralEnable()之前、不能读取寄存器。 这让我跳了一次...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我向 TivaWare SSI 库函数添加了一些调试 printf。 下面的输出显示了针对以下序列进行的调用:

    1) 1)写入器件 A (模式3、8位数据、2000000 bps)

    2) 2)写入器件 B (模式0、16位数据、500000bps)

    3) 3)写入器件 A (模式3、8位数据、2000000 bps)

    写入器件 A
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、3、0、2000000、 8)
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、3、0、2000000、 8)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0xb0)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x10)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIEnable (0x4000b000)-------------------------------------------------------
    
    写入器件 B
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、3、0、50000、 16)
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、0、0、50000、 16)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x5)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、0、0、50000、 16)
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、0、0、50000、 16)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x6)
    SSIDataPutNonBlocking (0x4000b000、0xDead)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、0、0、50000、 16)
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、0、0、50000、 16)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x7)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIEnable (0x4000b000)-------------------------------------------------------
    
    写入器件 A
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、0、0、2000000、 8)
    SSIDisable (0x4000b000)
    SSIConfigSetExpClk (0x4000b000、8000000、3、0、2000000、 8)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0xb0)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x10)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIEnable (0x4000b000)
    SSIDisable (0x4000b000)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIDataPutNonBlocking (0x4000b000、0x0)
    SSIEnable (0x4000b000)
    
    

    这是 SPI 监听器跟踪。 在(波浪形)红线以上是对器件 A 的第一次写入。在该线以下是第二次写入。 (我无法同时捕获两个设备、因为监听器只有一条 CS 线路需要监控。)

    您可以看到、第一次正确发送0xB0。 第二次发送0x58、0x00。 但就我所能说的、两个会话的 SSI 配置是相同的。

    我确实注意到有几个奇怪的事情。 一个是 SSIConfigSetExpClock()函数每次调用两次。 这是因为通信驱动程序的写入方式为两个不同的函数设置波特率和其他参数。 我不知道该代码的作者为什么认为这样做更好、但这就是我继承的内容。

    另一件事是在使能 SSI 之前将数据写入 FIFO 中。 再说一次、我不知道作者为什么想这么做。 但我在写入 FIFO 之前尝试启用、没有什么不同。

    配置顺序是否有任何不正确的地方?

    我只掌握了一个逻辑分析仪、并将尝试弄清楚如何获得一条迹线、以便我们可以看到实际的信号。

    此致、

    Dave

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

    [引用用户="Dave Hohl"]... 一些奇怪的事情。 一个是 SSIConfigSetExpClock()函数每次调用两次。 这是因为通信驱动程序的写入方式、它在两个不同的函数中设置波特率和其他参数。

    根据我的经验、  "SSIConfigSetExpClock()"中包含的'Most Recenty'参数将(过写)之前发送的那些(功能相同)参数。   如果参数"不重叠" (即加载了不同的功能参数) -我不确定加载的"较早"参数是否会持续存在-或(可能)被"默认值"替换。    

    这个(背对背)'SSIConfigSetExpClock ()'传输- 代表'new Ground!'    我在这方面没有经验——“回头”。   承认(不必要)变量-我不认为-符合您的最佳利益...   虽然代码不是您的代码-校正的责任由您承担-并且如果 可能的话、这将受益于更"正常/习惯"的传输(即单个"SSIConfigSetExpClock()"传输)...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    连接逻辑分析仪后、我想我已经知道正在发生什么。 在我有机会进行一些测试以验证我的理论后、我稍后会发布更多详细信息。

    是的、CB1、我有纠正 SPI 驱动程序代码的不幸任务。 遗憾的是,它是由一个似乎对 KICS 哲学(保持复杂、愚蠢!)有归属感的人写的,所以需要仔细编辑。 :-)

    此致、

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

    好的、我想我终于解决了这个问题。 SPI 驱动程序代码在 调用 SSIConfigSetExpClk()之前启用 CS 信号。 由于 SPI 模式0和3具有相反的时钟极性、因此与器件 B (模式0)通信后、SCLK 信号保持低电平状态。 当 调用 SSIConfigSetExpClk()以切换到模式3时,SCLK 信号变为高电平。 器件 A (和 SPI 监听器)将其解释为计时输出第一个位。 这就是为什么应该发送的0xB0值在接收端被视为移位了一位(0x58)。 当 SSI 使能时、它再输出8位时钟、因此在 CS 禁用后、接收器只获得了它认为是第二个字节的第一个位(值0)、并且用零填充字节的其余部分。

    这是逻辑分析仪跟踪的屏幕截图。 红色箭头表示 SCLK 在响应 SSIConfigSetExpClk()调用时转换的位置。

    下面是重现问题的代码(与逻辑分析仪跟踪相对应):

    uint32_t dummy = 0;
    
    //***** 器件 A 写入
    GPIOPinWrite (LCD_CSn_PORT、LCD_CSn_PIN、0);//芯片选择低电平
    SSIDisable (SSI3_base);
    SSIConfigSetExpClk (SSI3_base、getSystemClockFreqHz ()、
    SSI_FRF_MOTO_MODE_3、
    SSI_MODE_MASTER、
    2000000L、
    8);
    
    SSIEnable (SSI3_base);
    
    //确保 Rx FIFO 为空
    while (0!= SSIDataGetNonBlocking (SSI3_base、&dummy))
    {
    }
    
    SSIDataPutNonBlocking (SSI3_base、0xB0);
    SSIDataGet (SSI3_base、&dummy);
    GPIOPinWrite (LCD_CSn_PORT、LCD_CSn_PIN、LCD_CSn_PIN);//芯片选择高电平
    
    
    //***** 器件 B 写入
    GPIOPinWrite (AM_CSn_PORT、AM_CSn_PIN、0);//芯片选择低电平
    SSIDisable (SSI3_base);
    SSIConfigSetExpClk (SSI3_base、getSystemClockFreqHz ()、
    SSI_FRF_MOTO_MODE_0、
    SSI_MODE_MASTER、
    500000L、
    16);
    SSIEnable (SSI3_base);
    
    //确保 Rx FIFO 为空
    while (0!= SSIDataGetNonBlocking (SSI3_base、&dummy))
    {
    }
    
    SSIDataPutNonBlocking (SSI3_base、0x1234);
    SSIDataGet (SSI3_base、&dummy);
    GPIOPinWrite (AM_CSn_PORT、AM_CSn_PIN、AM_CSn_PIN);//芯片选择高电平
    
    //***** 器件 A 写入
    GPIOPinWrite (LCD_CSn_PORT、LCD_CSn_PIN、0);//芯片选择低电平
    SSIDisable (SSI3_base);
    SSIConfigSetExpClk (SSI3_base、getSystemClockFreqHz ()、
    SSI_FRF_MOTO_MODE_3、
    SSI_MODE_MASTER、
    2000000L、
    8);
    
    SSIEnable (SSI3_base);
    
    //确保 Rx FIFO 为空
    while (0!= SSIDataGetNonBlocking (SSI3_base、&dummy))
    {
    }
    
    SSIDataPutNonBlocking (SSI3_base、0xB0);
    SSIDataGet (SSI3_base、&dummy);
    GPIOPinWrite (LCD_CSn_PORT、LCD_CSn_PIN、LCD_CSn_PIN);//芯片选择高电平
    

    一个令人好奇的事情是、为什么该代码在基于 Stellaris 的系统中已经使用了多年。 也许 Stellaris 和 Tiva 之间的 SSI 实现已经改变?

    无论如何、我很确定、如果我在配置更改期间启用 CS、问题是否得到解决、问题是否可以解决。

    感谢大家的帮助、尤其是来自 CB1的众多建议(其中之一就是获得信号跟踪!)。

    此致、

    Dave

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

    感谢您发布此更新、我建议您提供 CB1验证答案或2个用于他的帖子、以帮助您解决此问题! 我相信他会感谢他的所有帮助(我也很感激!)。

    感谢您分享有关问题和解决方法的详细信息。 我已经讨论过许多 SPI 器件、当运行不符合预期时、示波器快照会在很大程度上说明问题。 很高兴修复程序现在已清除。

    至于区别、TM4C129x 系列是比 Stellaris 更新的器件系列、因此 SSI 实现不是100%完全相同也不足为奇。 我在这里并不确定、现在具体改变了什么来影响这一点、但我并不感到惊讶、因为行为各不相同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Ralph、

    关于标记 CB1的一个帖子的好主意! 我标记了他建议使用信号跟踪来解决我的问题的位置。

    此致、

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

    您好、Ralph、

    非常好的总结-非常感谢您的关注。

    Dave 因"在那里闲逛"-他承受了压力-我们只是外人、 "试图鼓励-也许-有效 的"创意片段"和方法...而受到了赞扬。"

    在现场工作-减去适当的测试设备-是没有乐趣的。   (年轻的 CB1度过了整个感恩节假期(4天)、生活在(困住)一个小的飞机吊架上-不够智能、无法携带合适的测试设备-并且"无法"将塞斯纳固定为 "飞出"。)   (笑声)   洛杉矶 北部的圣保拉机场(不要闪烁)   "触控即走"的家。

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

    我又想到了一个想法、但它并没有明确地指出"a-ha"! 关于此问题、我们有几个文档列出了 TM4C129x 和其他器件之间的差异。 您可能会发现这些对您有所帮助。

    www.ti.com/.../spma063.pdf
    www.ti.com/.../spma065.pdf
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢、Ralph。 我之前实际上已经看过了 Stellaris 到 Tiva 的更改文档。 但对 SSI 变化的描述非常详细。 我不会期望这种微妙的区别(如果我们所怀疑的实际上是真的)将其变成这样一份文件。

    此致、

    Dave