Tool/software:
Hi,
Here is a strange behavior we observed and would like to get some help to understand what is happening and why it is happening.
We are working on setting up CAN peripheral on one of our products. We setup the CAN and ISR as below:
void setup_can(void)
{
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
// Initialize the CAN controller
CAN_initModule(CANA_BASE);
//
// setup Auto Bus On and delay time (in clock cycles - default is 0h)
//
CAN_setAutoBusOnTime(CANA_BASE, 0UL);
CAN_enableAutoBusOn(CANA_BASE);
// Set up the CAN bus bit rate depending on CAN_SPEED_UC digital input; 0 = 250kBits/s / 1 = 500kBits/s
if (0u == GpioDataRegs.GPADAT.bit.GPIO11)
{
CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 250000, 16);
}
else
{
CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 25);
}
// Enable interrupts on the CAN peripheral.
CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR);
CAN_enableRetry(CANA_BASE);
// Start CAN module operations
CAN_startModule(CANA_BASE);
}
__interrupt void can_isr(void)
{
#define CAN_ERROR_COUNT 25
uint32_t status_ui32, status2_ui32;
uint16_t can_msg_frame_type[1];
//Allow ADC1/SCIB_TX/Timer0/Timer1/SCIB_Rx to pre-empt ISR
IER |= (M_INT1|M_INT9|M_INT13);
IER &= (M_INT1|M_INT9|M_INT13);
// Enable PIE interrupt group 1 - Interrupt 1 (ADCA1)
// Enable PIE interrupt group 1 - Interrupt 3 (ADCC1)
// Enable PIE interrupt group 1 - Interrupt 7 (TIMER0)
// Enable PIE interrupt group 9 - Interrupt 4 (SCIB_TX)
// Enable PIE interrupt group 9 - Interrupt 3 (SCIB_RX)
// Enable PIE interrupt group 9 - Interrupt 4 (SCIB_TX)
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
PieCtrlRegs.PIEIER1.bit.INTx3 = 1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
PieCtrlRegs.PIEIER9.bit.INTx3 = 1;
PieCtrlRegs.PIEIER9.bit.INTx4 = 1;
// Clear ACK to allow group 1 INT
// Clear ACK to allow group 9 INT
PieCtrlRegs.PIEACK.bit.ACK1 = 1;
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
// Wait one cycle as per errata
asm(" NOP");
EINT;
// Read the CAN interrupt status to find the cause of the interrupt
status_ui32 = CAN_getInterruptCause(can_base_ui16);
// If the cause is a controller status interrupt, then get the status
if (status_ui32 < RX_MSG_OBJ_ID_END)
{
can_msg_count_ui32++;
// TX interrupt occurred on message object and the message TX is complete
if(status_ui32 <= TX_MSG_OBJ_ID_END)
{
//Clear the message object interrupt
CAN_clearInterruptStatus(can_base_ui16, status_ui32);
}
// RX interrupt occurred on message object and the message RX is complete
else
{
// Get the received message
CAN_readMessageWithID(can_base_ui16, status_ui32, can_msg_frame_type, (uint32_t *)can_rx_msg_identifer29_ui32, can_rx_msg_data_buffer_ui16);
// CAN bus message receive data parser
can_rx_msg_parser(status_ui32);
//Clear the message object interrupt
CAN_clearInterruptStatus(can_base_ui16, status_ui32);
}
}
else
{
// Spurious interrupt handling can go here.
}
// Clear the global interrupt flag for the CAN interrupt line
CAN_clearGlobalInterruptStatus(can_base_ui16, CAN_GLOBAL_INT_CANINT0);
// Acknowledge the PIE interrupt
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
DINT;
}
What we observed is during startup of the customer system due to initial noise all the nodes on the CAN bus except our node resulting in no ack to all our tx messages. The expectation is that node enters passive error state until system node acks the messages, but what we noticed is that the micro gets reset due to watchdog reset, we believe that this is cause of CAN trying to resend while we are trying to send more messages as per tx scheduler. Is this what is expected?
Also this behavior resulted in cross conduction of our complementary PWM signals resulting in unit failure.
I have captured some plots here:

Green signal = Testpin set at the start of application
Red and Blue signals = Complementary PWM signals
You can clearly see the cross conduction of PWM and unknown toggling of the testpin just before the watchdog reset.
Our question is why did the PWM and testpin get affected due to the CAN hanging?
We were able to solve the reset issue by reading error and status register in the ISR using CAN_getStatus(can_base_ui16); this is just for your information but we still want to know why the strange behavior was observed and will it be of any concern with other type of errors.
Regards,
Harsha

