When I briefly short the CAN1 bus of a PCAN Router-FD it stops receiving or sending CAN on that bus until the power is cycled.
I can see with CANalyzer that the CAN1 bus is active, but the CAN1 Rx light does not flash.
I can send a message on CAN2 and get the CAN2 Rx light to flash but the message does not get gatewayed to CAN1.
Is there a way to detect this busoff condition and fix it on-the-fly?
Brian
busoff
Re: busoff
Hello Brian,
please have a look at the examples, e.g. "1_ROUTING".
In the file can_user.c you find:
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:
Regards, Gunnar Bohlen
please have a look at the examples, e.g. "1_ROUTING".
In the file can_user.c you 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
// 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;
}
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;
Re: busoff
Gunnar,
Thanks for the response.
That looks like the logic I already have in can_user.c since I started with the 1_ROUTING example
If you try that example and short the FD bus, does your Router recover?
I'm using the following bit timing for a 500k/2M CANFD system:
#define _80M_500K_80____2M_80_ISO { CAN_CLOCK_80M, 4, 31, 8, 8, 96, 0, 1, 4, 7, 2, 2} // 80 MHz, 500K 80%, 2M 80%, ISO
Brian
Thanks for the response.
That looks like the logic I already have in can_user.c since I started with the 1_ROUTING example
If you try that example and short the FD bus, does your Router recover?
I'm using the following bit timing for a 500k/2M CANFD system:
#define _80M_500K_80____2M_80_ISO { CAN_CLOCK_80M, 4, 31, 8, 8, 96, 0, 1, 4, 7, 2, 2} // 80 MHz, 500K 80%, 2M 80%, ISO
Brian
Re: busoff
Hello Brian,
the issue comes from the CAN controller. A status notification (a status frame) is generated to much, so the router will hang up in an endless loop. There are two solutions for that:
1) Workaround
See attached can_user.c file. Look for variable busOFF[2] and modify your code like in the file. The mod will consider only status notifications coming from a real status change. This will break the status -> re-initialize endless loop.
2) new FPGA image
Rename the ...FPGA_v4.txt file to *.bin and flash it like a firmware to the router. This is critical. Do not cycle power during the process, maybe isolate the router from your CAN bus and do this on your desk. The new CAN controller will fix the issue. After flashing is finished you need a power cycle.
Regards
the issue comes from the CAN controller. A status notification (a status frame) is generated to much, so the router will hang up in an endless loop. There are two solutions for that:
1) Workaround
See attached can_user.c file. Look for variable busOFF[2] and modify your code like in the file. The mod will consider only status notifications coming from a real status change. This will break the status -> re-initialize endless loop.
2) new FPGA image
Rename the ...FPGA_v4.txt file to *.bin and flash it like a firmware to the router. This is critical. Do not cycle power during the process, maybe isolate the router from your CAN bus and do this on your desk. The new CAN controller will fix the issue. After flashing is finished you need a power cycle.
Regards
- Attachments
-
- can_user.c
- Code for workaround
- (1.81 KiB) Downloaded 675 times
-
PCAN-Router_FD_FPGA_v4.txt
- New FPGA image, rename to *.bin
- (816 KiB) Downloaded 652 times
--------------------------------------------
PEAK-System HW development Team
support@peak-system.com
phone: +49-6151-8173-20
fax: +49-6151-8173-29
--------------------------------------------
PEAK-System HW development Team
support@peak-system.com
phone: +49-6151-8173-20
fax: +49-6151-8173-29
--------------------------------------------