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.

[参考译文] BOOSTXL-CANFD-LIN:内部写入错误安培;内部中断错误

Guru**** 2457760 points
Other Parts Discussed in Thread: CC1310, TCAN4550

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

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1488987/boostxl-canfd-lin-internal-write-error-internal-interrupt-error

器件型号:BOOSTXL-CANFD-LIN
主题中讨论的其他器件:CC1310TCAN4550

工具与软件:

您好、TI:

我正在使 TCAN4550能够在低于1 CC1310微控制器上正常工作、但无法初始化 CAN。  我相信 SPI 设置正确、具有以下设置:

  spiParams.frameFormat = SPI_POL0_PHA0;
  spiParams.bitrate =   8000000
  spiParams.mode     = SPI_MASTER;
  spiParams.transferMode = SPI_MODE_BLOCKING;

我正在使用 TCAN4550演示软件、以便初始化 TCAN 芯片、但我无法写入 TCAN 芯片。 在读取错误状态寄存器(0x000C)期间、它读取以下内容:

0x18 0x00 0x00 0x0C、这意味着存在写入错误和内部中断错误。  

我无法通过查看产品说明书来解决此问题、是否可以采取任何步骤来调试过程?

     

这是 SPI 通信的快照。

任何帮助都很好。

此致

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

    您好、Thomas:

    大多数初始 SPI 启动问题与片选信号相对于数据转换错误相关。  数据的时钟极性看起来正确、但我无法看到包括 nCS 信号在内的完整 SPI 事务。  

    TCAN4550要求 nCS 信号在 SPI 读取/写入事务开始时转换为低电平、并在数据部分完成之前保持低电平。  对于单个寄存器读取/写入、这意味着 NCS 信号必须在总共64个 SCLK 周期(或64位)内处于低电平。  

    该器件在 SPI 接口上使用 FIFO 来处理 OSC 时钟频率域交叉的 SPI 时钟频率、以便跟踪 FIFO 两侧有多少位是输入和输出。  

    在 SPI 侧、如果在 NCS 信号处于低电平时检测到错误数量的 SPI 时钟周期、则 FIFO 中的位过少或过多会导致错误。

    同样、如果 OSC 时钟(20MHz 或40MHz 的晶体或单端 CMOS 时钟)出现问题、数字内核无法处理数据、从而导致错误。  

    请注意、寄存器0x0000至0x002F 仅需要 SPI 时钟并在逻辑中实现。  它们通常与 SPI FIFO 接口的状态信息相关。  但0x0800和0x1000域中的所有其他寄存器都要求 OSC 时钟才能成功进行 SPI 读取/写入。

    在运行初始 SPI 驱动器时需要检查的常见问题是、在长度字段等于1的单次寄存器 SPI 读取中、NCS 信号在确切的64个时钟周期内处于低电平。  默认情况下、许多 MCU SPI 驱动器功能都会在每8、16或32位数据后设置 nCS、具体取决于该功能一次可以处理的位数。 如果 nCS 在正确的周期数之前被拉至高电平、则会导致 TCAN4550中止 SPI 读取、而不在读取时提供请求的数据、或者在写入时丢弃数据、以避免使用可能无效的数据损坏器件。

    此外、SCLK 信号应处于低电平、而 nCS 在事务开始时转换为低电平、以确保第一个 SCLK 边沿是上升沿。  

    您的时钟与数据相位的关系看起来已经正确、并且在 SCLK 的上升沿对数据进行采样。

    您能否捕获显示包括 NCS 转换在内的全部4个 SPI 信号的完整 SPI 事务?

    此致、

    Jonathan

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

    尊敬的 Jonathan:

    感谢您的答复。

    我检查了 nCS 信号是否在64个周期内处于低电平。 下面是这方面的证明:


    我还检查了0x0820上的任何中断启用标志寄存器是否能够被读取、以排除 OSC 时钟问题。 我能够正确读取寄存器。



    仍然、初始化示例代码未正确初始化、因为 TCAN4550将在3分钟后进入睡眠状态。  

       
       void Init_CAN(void){
       TCAN4x5x_Device_ClearSPIERR();                              // Clear any SPI ERR flags that might be set as a result of our pin mux changing during MCU startup
    
        /* Step one attempt to clear all interrupts */
    	TCAN4x5x_Device_Interrupt_Enable dev_ie = {0};				// Initialize to 0 to all bits are set to 0.
    	TCAN4x5x_Device_ConfigureInterruptEnable(&dev_ie);	        // Disable all non-MCAN related interrupts for simplicity
    
    	TCAN4x5x_Device_Interrupts dev_ir = {0};					// Setup a new MCAN IR object for easy interrupt checking
    	TCAN4x5x_Device_ReadInterrupts(&dev_ir);					// Request that the struct be updated with current DEVICE (not MCAN) interrupt values
    	
    
    	if (dev_ir.PWRON)                    
    	{                       // If the Power On interrupt flag is set
    		TCAN4x5x_Device_ClearInterrupts(&dev_ir);               // Clear it because if it's not cleared within ~4 minutes, it goes to sleep
    	}
    	/* Configure the CAN bus speeds */
    	TCAN4x5x_MCAN_Nominal_Timing_Simple TCANNomTiming = {0};	// 500k arbitration with a 40 MHz crystal ((40E6 / 2) / (32 + 8) = 500E3)
    	TCANNomTiming.NominalBitRatePrescaler = 2;
    	TCANNomTiming.NominalTqBeforeSamplePoint = 32;
    	TCANNomTiming.NominalTqAfterSamplePoint = 8;
    
    	TCAN4x5x_MCAN_Data_Timing_Simple TCANDataTiming = {0};		// 2 Mbps CAN FD with a 40 MHz crystal (40E6 / (15 + 5) = 2E6)
    	TCANDataTiming.DataBitRatePrescaler = 1;
    	TCANDataTiming.DataTqBeforeSamplePoint = 15;
    	TCANDataTiming.DataTqAfterSamplePoint = 5;
    
    	/* Configure the MCAN core settings */
    	TCAN4x5x_MCAN_CCCR_Config cccrConfig = {0};					// Remember to initialize to 0, or you'll get random garbage!
    	cccrConfig.FDOE = 1;										// CAN FD mode enable
    	cccrConfig.BRSE = 1;										// CAN FD Bit rate switch enable
    
    	/* Configure the default CAN packet filtering settings */
    	TCAN4x5x_MCAN_Global_Filter_Configuration gfc = {0};
    	gfc.RRFE = 1;                                               // Reject remote frames (TCAN4x5x doesn't support this)
    	gfc.RRFS = 1;                                               // Reject remote frames (TCAN4x5x doesn't support this)
    	gfc.ANFE = TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO0;                // Default behavior if incoming message doesn't match a filter is to accept into RXFIO0 for extended ID messages (29 bit IDs)
    	gfc.ANFS = TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO0;                // Default behavior if incoming message doesn't match a filter is to accept into RXFIO0 for standard ID messages (11 bit IDs)
    
    	/* ************************************************************************
    	 * In the next configuration block, we will set the MCAN core up to have:
    	 *   - 1 SID filter element
    	 *   - 1 XID Filter element
    	 *   - 5 RX FIFO 0 elements
    	 *   - RX FIFO 0 supports data payloads up to 64 bytes
    	 *   - RX FIFO 1 and RX Buffer will not have any elements, but we still set their data payload sizes, even though it's not required
    	 *   - No TX Event FIFOs
    	 *   - 2 Transmit buffers supporting up to 64 bytes of data payload
    	 */
    	TCAN4x5x_MRAM_Config MRAMConfiguration = {0};
    	MRAMConfiguration.SIDNumElements = 1;						// Standard ID number of elements, you MUST have a filter written to MRAM for each element defined
    	MRAMConfiguration.XIDNumElements = 1;						// Extended ID number of elements, you MUST have a filter written to MRAM for each element defined
    	MRAMConfiguration.Rx0NumElements = 5;						// RX0 Number of elements
    	MRAMConfiguration.Rx0ElementSize = MRAM_64_Byte_Data;		// RX0 data payload size
    	MRAMConfiguration.Rx1NumElements = 0;						// RX1 number of elements
    	MRAMConfiguration.Rx1ElementSize = MRAM_64_Byte_Data;		// RX1 data payload size
    	MRAMConfiguration.RxBufNumElements = 0;						// RX buffer number of elements
    	MRAMConfiguration.RxBufElementSize = MRAM_64_Byte_Data;		// RX buffer data payload size
    	MRAMConfiguration.TxEventFIFONumElements = 0;				// TX Event FIFO number of elements
    	MRAMConfiguration.TxBufferNumElements = 2;					// TX buffer number of elements
    	MRAMConfiguration.TxBufferElementSize = MRAM_64_Byte_Data;	// TX buffer data payload size
    
    
    	/* Configure the MCAN core with the settings above, the changes in this block are write protected registers,      *
    	 * so it makes the most sense to do them all at once, so we only unlock and lock once                             */
    
    	TCAN4x5x_MCAN_EnableProtectedRegisters();					// Start by making protected registers accessible
    	TCAN4x5x_MCAN_ConfigureCCCRRegister(&cccrConfig);			// Enable FD mode and Bit rate switching
    	TCAN4x5x_MCAN_ConfigureGlobalFilter(&gfc);                  // Configure the global filter configuration (Default CAN message behavior)
    	TCAN4x5x_MCAN_ConfigureNominalTiming_Simple(&TCANNomTiming);// Setup nominal/arbitration bit timing
    	TCAN4x5x_MCAN_ConfigureDataTiming_Simple(&TCANDataTiming);	// Setup CAN FD timing
    	TCAN4x5x_MRAM_Clear();										// Clear all of MRAM (Writes 0's to all of it)
    	TCAN4x5x_MRAM_Configure(&MRAMConfiguration);				// Set up the applicable registers related to MRAM configuration
    	TCAN4x5x_MCAN_DisableProtectedRegisters();					// Disable protected write and take device out of INIT mode
    
    
    	/* Set the interrupts we want to enable for MCAN */
    	TCAN4x5x_MCAN_Interrupt_Enable mcan_ie = {0};				// Remember to initialize to 0, or you'll get random garbage!
    	mcan_ie.RF0NE = 1;											// RX FIFO 0 new message interrupt enable
    
    	TCAN4x5x_MCAN_ConfigureInterruptEnable(&mcan_ie);			// Enable the appropriate registers
    
    
    	/* Setup filters, this filter will mark any message with ID 0x055 as a priority message */
    	TCAN4x5x_MCAN_SID_Filter SID_ID = {0};
    	SID_ID.SFT = TCAN4x5x_SID_SFT_CLASSIC;						// SFT: Standard filter type. Configured as a classic filter
    	SID_ID.SFEC = TCAN4x5x_SID_SFEC_PRIORITYSTORERX0;			// Standard filter element configuration, store it in RX fifo 0 as a priority message
    	SID_ID.SFID1 = 0x055;										// SFID1 (Classic mode Filter)
    	SID_ID.SFID2 = 0x7FF;										// SFID2 (Classic mode Mask)
    	TCAN4x5x_MCAN_WriteSIDFilter(0, &SID_ID);					// Write to the MRAM
    
    
    	/* Store ID 0x12345678 as a priority message */
    	TCAN4x5x_MCAN_XID_Filter XID_ID = {0};
    	XID_ID.EFT = TCAN4x5x_XID_EFT_CLASSIC;                      // EFT
    	XID_ID.EFEC = TCAN4x5x_XID_EFEC_PRIORITYSTORERX0;           // EFEC
    	XID_ID.EFID1 = 0x12345678;                                  // EFID1 (Classic mode filter)
    	XID_ID.EFID2 = 0x1FFFFFFF;                                  // EFID2 (Classic mode mask)
    	TCAN4x5x_MCAN_WriteXIDFilter(0, &XID_ID);                   // Write to the MRAM
    
    	/* Configure the TCAN4550 Non-CAN-related functions */
    	TCAN4x5x_DEV_CONFIG devConfig = {0};                        // Remember to initialize to 0, or you'll get random garbage!
    	devConfig.SWE_DIS = 0;                                      // Keep Sleep Wake Error Enabled (it's a disable bit, not an enable)
    	devConfig.DEVICE_RESET = 0;                                 // Not requesting a software reset
    	devConfig.WD_EN = 0;                                        // Watchdog disabled
    	devConfig.nWKRQ_CONFIG = 0;                                 // Mirror INH function (default)
    	devConfig.INH_DIS = 0;                                      // INH enabled (default)
    	devConfig.GPIO1_GPO_CONFIG = TCAN4x5x_DEV_CONFIG_GPO1_MCAN_INT1;    // MCAN nINT 1 (default)
    	devConfig.FAIL_SAFE_EN = 0;                                 // Failsafe disabled (default)
    	devConfig.GPIO1_CONFIG = TCAN4x5x_DEV_CONFIG_GPIO1_CONFIG_GPO;      // GPIO set as GPO (Default)
    	devConfig.WD_ACTION = TCAN4x5x_DEV_CONFIG_WDT_ACTION_nINT;  // Watchdog set an interrupt (default)
    	devConfig.WD_BIT_RESET = 0;                                 // Don't reset the watchdog
    	devConfig.nWKRQ_VOLTAGE = 0;                                // Set nWKRQ to internal voltage rail (default)
    	devConfig.GPO2_CONFIG = TCAN4x5x_DEV_CONFIG_GPO2_NO_ACTION; // GPO2 has no behavior (default)
    	devConfig.CLK_REF = 1;                                      // Input crystal is a 40 MHz crystal (default)
    	devConfig.WAKE_CONFIG = TCAN4x5x_DEV_CONFIG_WAKE_BOTH_EDGES;// Wake pin can be triggered by either edge (default)
    	TCAN4x5x_Device_Configure(&devConfig);                      // Configure the device with the above configuration
    
    	TCAN4x5x_Device_SetMode(TCAN4x5x_DEVICE_MODE_NORMAL);       // Set to normal mode, since configuration is done. This line turns on the transceiver
    
    	TCAN4x5x_MCAN_ClearInterruptsAll();                         // Resets all MCAN interrupts (does NOT include any SPIERR interrupts)
    	}



    是否还有其他要执行的检查?

    此致
    Thomas

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

    您好、Thomas:

    我仍然看到中断寄存器0x0820的位3被设置为1、即 SPI 错误位(SPIERR)。 您可以读取状态寄存器0x000C、以便我们可以获得关于为什么设置了 SPIERR 的更多信息吗?

    为了防止器件在4分钟后进入睡眠模式、只需向中断寄存器(0x0820[20])中的 PWRON 位写入"1"、或者针对正常模式将运行模式和引脚配置寄存器中的 MODE_SEL 字段配置为"10"(0x0800[7:6])。

    您是否能够尝试简单地读取寄存器0x0820、0x000C、然后将"1"写入其中每个寄存器的设置位、或者只是简单地将"0xFFFFF"写入这两个寄存器并读回它们?  任何设置的位都应该已经被清除。

    另请尝试向测试寄存器和暂存区写入一个自定义值、然后在测试中读回 SPI 写入和读取功能均正确的值。  您应该读回刚刚写入该寄存器的自定义值。

    您是否还可以尝试将配置序列结束时的所有器件寄存器读回日志文件、以便我们比较代码写入的实际寄存器值并识别任何错误?

    此致、

    Jonathan