工具/软件:
您好、
只要 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