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.

[参考译文] TCAN4550-Q1:无 CAN ACK 时出现 SPIERR。 TXFQS 在 SPIERR 后复位。

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

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1535927/tcan4550-q1-spierr-when-no-can-ack-txfqs-resets-after-spierr

器件型号:TCAN4550-Q1

工具/软件:

您好、

只要 CAN 上有 ACK、系统中的 TCAN 就可以正常工作。 如果没有 ACK、则会获得 SPIERR。  有时、它会在数百毫秒后发生、有时会在大约一分钟后发生、但在 ACK 处于 CAN 上时永远不会发生。 奇怪的是,它似乎是依赖于系统的工作时间。 例如、几个小时后、大约一分钟后会发生此错误、每次尝试都会更快地发生(有时是数百毫秒)。  

  • 我使用在 16MHz 处设置的 SPI CLK、但我已尝试在 8、4、2MHz 处进行了尝试、没有任何变化。
  • 具有 10 pF 的 20MHz 晶体。 我也尝试了 18 pF 和 40MHz 和没有任何改变。
  • 当我读取寄存器 0x0008 时、得到 0x00110201。
  • TCAN 不会向 TCAN 发送任何消息。 (因此 TCAN RX 为空)
  • 我在乞讨时清除 M_RAM。
  • 我的 M_RAM 不重叠、并且配置正确。 (Rx0NumElements 64、TxBufferNumElements 32、所有其他元素大小 0、所有元素大小 8 字节数据、TX 作为 FIFO)
  • 仅当 DAR 设置为 0 时才会发生该错误。 当我将其设置为 1 时、不会发生 SPIERR。 我需要 DAR 为 0。

// TxRoutine 伪代码

//步骤 1:读取发送 FIFO/队列状态寄存器
TXFQS = readRegister (0x10C4)// TXFQS:发送 FIFO/队列状态

//步骤 2:检查 Tx FIFO 是否未满且空闲级别梯度是否大于零
如果 (TXFQS.TFQF == 0 && TXFQS.TFFL > 0){

  //步骤 3:计算写消息的基址
  // 0x8400 是 Tx FIFO 的起始地址(在 RX0 之后)
  //每个 Tx 缓冲区为 16 个字节
  地址= 0x8400 +(16 * TXFQS.TFQPI)

  //步骤 4:将消息写入计算出的 Tx 缓冲区地址
  写入 (address、sizeof (4 * u32)、msgBuff)

  //步骤 5: 设置 TxBar
  tmpTxBar = 0
  tmpTxBar = 1 << TXFQS.TFQPI //设置对应于 Tx FIFO Put 索引的位

  //步骤 6:通过 TxBar 触发传输
  写入 (0x10D0、sizeof (u32)、tmpTxBar)
}

如您所见、FIFO 已满时我不添加消息、这时将没有 ACK。

因此我将添加消息、TFFL 将取消搜索、TFQPI 将增加、直到 TFFL 将为 0、TFQPI 将恢复到 0、TFQF 将为 1。 因此、我将仅读取 TXFQS = readRegister (0x10C4)。
(虽然有时我看到 TFGI 增加时没有 ACK 那么是怎么可能的?)

一段时间后,我收到中断 — DEV_ir 0x88 (SPIERR、GLOBALERR)、mcan_ir 0x9810000 (TSW、EP、EW、 PEA)。

然后、我通过首先读取状态寄存器 (0x000C) 来处理 SPIERR、它是 0xA00000C (READ_fifo_empty 、Internal_ERROR_LOG_WRITE、Internal_ERROR_INTERRUPT 、Internal_ACCESS_ACTIVE )。

然后我读取 0x0010、它是 0x0。 然后我将 0xFFFFFFFF 写入 statusReg (0x000C)。 接下来、我读取 0x000C、它是 0x8。

接下来、我读取 EcrReg (0x1040) 以清除 CEL(CAN 错误记录)。

我还读取 PSR (0x1040) 以查看 BO、EP、EW、该位等于 0x7E5 所以 BO(总线关闭)标志被设置。 然后我读取 CCCR (0x1018)、它为 0x1。 然后我将 0x0 写入 CCCR (0x1018)。

现在、我清除中断、以便将这个 dev_ir 和 mcan_ir 的值写入它们。 完成此操作以进行调试后、我再次读取它们、并读取 0x4000 TXFF

此 TXFQF 全部为 0、因此出现错误、因为如果 TFFL == 0、则 TFQF 必须为 1。

我不知道在没有 ACK 时为什么会发生 SPIERR 以及如何处理。 为什么它会影响 TXFQF? 期待您的答复!

此致、
Mateusz

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

    您好、Mateusz

    CAN ACK 脉冲和 SPI 错误之间的关系是数字内核处理 SPI 通信所需的底层高速时钟(晶体)、MCAN 控制器也需要该时钟来处理 CAN 通信。  如果该时钟中断、数字内核和 MCAN 控制器将基本上暂停、直到时钟恢复。  如果在 SPI 或 CAN 消息期间发生这种中断、则可能会导致错误。

    TCAN4550-Q1 通过 OSC1 和 OSC2 引脚支持晶体和单端时钟。  OSC2 引脚上有一个电压比较器、用于检查是否存在小于大约 100mV 的电压、以指示“接地“引脚、将时钟模式切换至单端模式并使 OSC1 引脚作为输入。  如果 OSC2 引脚上的电压大于 100mV、则会启用晶体放大器、并将电流从 OSC1 引脚拉出晶体。

    在晶体模式下有一个自动增益控制 (AGC) 电路、该电路将尝试调节放大器电流、以在振荡波形中保持大约 1Vpp 的峰峰值电压幅度。  但是、有一个始终来自源的最小输出电流电平、如果最小输出电流电平的振幅超过 1Vpp、则 OSC2 引脚上波形的最低电压电平可能会下降到足够低的水平、从而导致器件切换到单端时钟模式并禁用电流放大器。  

    如果发生这种情况、数字内核和 MCAN 控制器将没有功能时钟、并且晶体振荡振幅将开始衰减、原因是电路中电阻的能量损耗。  最终、OSC2 电压电平将高于比较器检测阈值、器件将再次切换到晶体模式。  然后、此过程可以在一个周期内重复、直到负载条件发生变化。  如果有足够的时间、中断可能会与 SPI 或 CAN 消息对齐、从而导致错误。

    您提到、这似乎取决于系统的工作时间。  这是另一条线索、因为晶体看到的总负载电容包括 PCB 布线的寄生电容以及 OSC1 和 OSC2 引脚电容。  这种寄生电容在整个温度范围内不如具有良好温度系数的实际陶瓷电容器那么稳定。  因此、随着系统运行、温度升高、总负载电容趋于减小。  这会导致电压幅度增加、从而使其更容易受到单端时钟模式开关的影响。

    您提到过您尝试了一些不同的电容和晶体频率、但可能需要进一步调整。  如果这是问题的原因、那么解决方案是减小 OSC2 引脚上振荡波形的幅度。  这通过调整晶体电路中的负载电容和串联电阻值来实现。

    推荐的解决方案是在 OSC1 引脚和晶体之间包含一个串联的“阻尼“电阻器、以减少流经晶体的电流、从而减少机械振动、进而减小电压幅度。  当需要电阻器时、30 至 50 欧姆通常就足够了、但通常小于 100 欧姆就可以解决此问题。

    如果电路中没有串联电阻器、则将负载电容器增大到更大的值有助于吸收该电流、并使电路保持在 AGC 可以调节的范围内。  将每个电容增大 2pF 至 4pF 会将 OSC2 电压电平增加一个等效量、通常由 30-50 Ω 串联电阻器检测到。

    有关更多信息、请参阅 TCAN455x 时钟优化和设计指南应用报告 (链接)

    尝试增加 OSC1 和晶体之间的串联电阻、或向晶体添加额外的电容、看看它是否可以解决您的通信误差。

    此致、

    Jonathan