Bus off detection on PCAN_Router Pro FD.

Programmable 6-Channel Router for CAN and CAN FD with I/O and Data Logger
Locked
gregstarns
Posts: 4
Joined: Mon 20. Jul 2020, 12:54

Bus off detection on PCAN_Router Pro FD.

Post by gregstarns » Mon 20. Jul 2020, 13:00

I have been creating the framework code for a new project on the Router Pro FD, and have made great progress. Its a great piece of kit. However I am trying to detect BUS OFF and passive errors on the 6 CAN ports without success. I can see when the TX buffer is full, but this is some time away from the CAN being disconnected (about 20 seconds in my application). Is there a document describing how to detect error states in the CAN module on the FPGA? or example code i have missed. none of the examples seem to do this.
Thanks
Greg Starns

M.Heidemann
Sales & Support
Sales & Support
Posts: 425
Joined: Fri 20. Sep 2019, 13:31

Re: Bus off detection on PCAN_Router Pro FD.

Post by M.Heidemann » Mon 20. Jul 2020, 13:37

Hello Greg,

please have a look at the examples, e.g. "1_ROUTING".

In the file can_user.c you'll find:

Code: Select all

CANResult_t  CAN_UserRead ( CANHandle_t  hBus, void  *buff)
{
	CANResult_t  ret;
	CANBuffer_t  *rx_buff;
	
	
	ret = CAN_ERR_RX_EMPTY;
	rx_buff = buff;
	
	if ( CAN_Read ( hBus, rx_buff) == CAN_ERR_OK)
	{
		// buffer read from CANx. Check type of buffer.
		switch ( rx_buff->bufftype)
		{

			case CAN_BUFFER_STATUS:
				// the buffer is a status notification from the CAN controller.
				if ( rx_buff->status.bus_status)
				{
					// CAN controller not involved into bus activities
					
					// Here you could further analyze which information the status message contains,
					//see below
					
					// uninitialize (this includes a TX-path flush)
					CAN_UnInitialize ( hBus);
					
					// initialize CAN controller
					CAN_Initialize ( hBus, &Timing_CANx[hBus]);
				}
				break;
				
			case CAN_BUFFER_RX_MSG:
				// the buffer is a receive message. Forward to application.
				ret = CAN_ERR_OK;
				break;
				
				
			case CAN_BUFFER_CRITICAL:
				// receive queue level was critical. Data might be lost.
				break;
		}
	}
	
	return ret;
}
If CAN_Read() returns a buffer-type "CAN_BUFFER_STATUS" then this is a status-message, not a data-message.
rx_buff->status.bus_status==1 means: bus off .

This code does an uninitialize followed by an initialize of the CAN-Controller.

Please look at the file "can.h" to find the structure of CANStatus_t:

Code: Select all

//! @brief
//! struct for a status notification from the CAN controller.
typedef struct {

uint16_t  size;					//!< size of the whole struct
uint16_t  bufftype;				//!< type of the BUFFER (CAN_BUFFER_STATUS)

uint32_t  time[2];				//!< timestamp of status change

uint8_t   res1:4;					//!< reserved
uint8_t   res2:1;					//!< reserved
uint8_t   err_passive:1;		//!< 0=error active, 1=error passive
uint8_t   err_status:1;			//!< 0=no error status, 1=error status (depends on warning limit)
uint8_t   bus_status:1;			//!< 1=bus status (CAN controller not involved in bus activity)
uint8_t   res3[3];				//!< reserved

} CANStatus_t;
As you can see, it is also possible to check for the error states using CANStatus_t. You could modify the above code to fit your needs,
add an check for the error states in case the receive buffer contains a status message.

Please report back to me, if this was helpful to you.

Best Regards

Marvin

gregstarns
Posts: 4
Joined: Mon 20. Jul 2020, 12:54

Re: Bus off detection on PCAN_Router Pro FD.

Post by gregstarns » Wed 22. Jul 2020, 11:04

That that is useful, but still does not solve my problem. I'm already using this code, with a slight modification. I am counting errors

Code: Select all

		switch ( rx_buff->bufftype)
		{
			case CAN_BUFFER_STATUS:
				// the buffer is a status notification from the CAN controller.
				if ( rx_buff->status.bus_status)
				{
					// CAN controller not involved into bus activities
					
					// uninitialize (this includes a TX-path flush)
					CAN_UnInitialize ( hBus);
					dbgprintf("Reset bus %d\n",hBus);
					bus_off_count[hBus]++;
					// initialize CAN controller
					CAN_Initialize ( hBus, &Timing_CANx[hBus]);
				}
				break;
and then in one of my threads i am printing out

Code: Select all

	    for(int i=0;i<6;i++)
		dbgprintf("Bus %d=%d ",i,bus_off_count[i]);
	    dbgprintf("\n");
I only have one port connected and i am not getting any bus_off_counts even on the ports that are not connected. I am transmitting on the not connected ports 1& 2 (as well as the connected port 0, where the debug is coming out) . It also does not fire the message if i unplug the cable briefly on the port that is outputting the debug. it should go error passive then after 128 error frames go bus_off , but im not seeing that behaviour.
this is the print out of the debug after about 30 secs of disconnect, and after the TX buffer is full, but this is too long to detect a cable disconnect. It should fail on the 1st message not being able to go out.

Code: Select all

[09:59:04] RX/s=132028 TX/S=132028 Proc/S=132028 Digi 00, AD=8 RTC is 22.07.20 10:59:27
[09:59:04] Bus 0=0 Bus 1=0 Bus 2=0 Bus 3=0 Bus 4=0 Bus 5=0 
[09:59:04] CAN BUS 1 is full
[09:59:04] CAN BUS 2 is full
[09:59:05] CAN BUS 1 is full
[09:59:05] CAN BUS 2 is full
Any idea what I am doing wrong ?

gregstarns
Posts: 4
Joined: Mon 20. Jul 2020, 12:54

Re: Bus off detection on PCAN_Router Pro FD.

Post by gregstarns » Wed 22. Jul 2020, 11:14

Ok I think i have answered my own question for anyone else finding this.
i added this code to the CAN_user.c

Code: Select all

				// the buffer is a status notification from the CAN controller.
				if ( rx_buff->status.err_status)
				{
					error_status_count[hBus]++;

				}
				if(rx_buff->status.err_passive)
				    {
					error_passive_count[hBus]++;
				    }

				if ( rx_buff->status.bus_status)
				{
					// CAN controller not involved into bus activities
					
					// uninitialize (this includes a TX-path flush)
					CAN_UnInitialize ( hBus);
					dbgprintf("Reset bus %d\n",hBus);
					bus_off_count[hBus]++;
					// initialize CAN controller
					CAN_Initialize ( hBus, &Timing_CANx[hBus]);
				}
				break;
	
and now i can see error status immediately i transmit a message on a bad bus, using this code

Code: Select all

	    for(int i=0;i<6;i++)
		dbgprintf("Bus %d=%d %d %d ",i,bus_off_count[i],error_passive_count[i],error_status_count[i]);
	    dbgprintf("\n");

Code: Select all

[10:11:43] RX/s=212100 TX/S=212100 Proc/S=212100 Digi 00, AD=8 RTC is 22.07.20 11:12:06
[10:11:43] Bus 0=0 0 0 Bus 1=0 1 2 Bus 2=0 1 2 Bus 3=0 0 0 Bus 4=0 0 0 Bus 5=0 0 0 
[10:11:44] CAN BUS 1 is full
[10:11:44] CAN BUS 2 is full
I think this means the transceiver is not going bus off, but the FPGA is reporting an error state, which is what i was looking for. Thanks for the great support, you pointed me in the right direction.
Greg.

M.Heidemann
Sales & Support
Sales & Support
Posts: 425
Joined: Fri 20. Sep 2019, 13:31

Re: Bus off detection on PCAN_Router Pro FD.

Post by M.Heidemann » Thu 23. Jul 2020, 13:49

Hello,

We are glad that you were able to resolve this issue.

Best Regards

Marvin

-closed-

Locked