We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
LPC2368 using RTX
I've spent several days tracking down a problem where the CAN would stop transmitting after a time period - usually after exactly 31845 packets - which is 0x5555.
I found that CAN_hw_tx_empty was returning CAN_TX_BUSY_ERROR, but then the CAN interrupt was never transmitting the message waiting in the mailbox.
Next I looked at the wr_sem semaphore, and found that the token count was increasing with every successful transmission. Eventually the token count was rolling from 0xFFFF to 0x0000, which would cause CAN_hw_tx_empty to fail. Now I see 0x5555 x 3 = 0xFFFF.
Next I found that the wr_sem semaphore was being sent 2 - 3 times from the interrupt runtine.
Looking at the CAN_ISR function it seems that the semaphore is sent every interrupt if the CAN TX hardware is free. This is a bug, because the interrupt is called for receive, as well as TX for the other controller.
if (CAN1GSR & (1 << 3)) { if (isr_mbx_receive (MBX_tx_ctrl[0], (void **)&ptrmsg) != OS_R_OK) { CAN_hw_wr (1, ptrmsg); _free_box(CAN_mpool, ptrmsg); } else { isr_sem_send(wr_sem[0]); /* Return a token back to semaphore */ } }
Adding an additional test for the type of interrupt fixed the problem:
// If the CAN has transmitted if(CAN1ICR & (1<<1)) { // If the CAN hardware is ready to transmit if(CAN1GSR & (1 << 3)) { // See if there are any messages to send if(isr_mbx_receive(MBX_tx_ctrl[0], (void **)&ptrmsg) != OS_R_OK) { CAN_hw_wr(1, ptrmsg); _free_box(CAN_mpool, ptrmsg); } else { // Release semaphore token isr_sem_send(wr_sem[0]); } } }
Hope that this saves someone else 3 days of their life.
I wouldn't call this bug as it is not expected that software FIFO gets overflown, increase the size of software FIFO.