LPC11C24 CCAN ROM DRIVER - Transmit Lockup

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by emh203 on Wed Jun 03 07:19:05 MST 2015

I have a problem with usage of the CCAN ROM drivers in the LPC11C24.       1st off,  I do know about reserving memory space for the drivers so that is not it... :-)

I have a test setup that consists of 4 LPC11C24 devices on a CAN network at 500KB.    The network also has a Peak Systems USB to CAN adapter to monitor/transmit messages.   I have a test program that routinely sends out data from a PC which causes the 4 different nodes to respond with traffic. 

Here is the problem....    Eventually all of the LPC11C24 nodes will stop transmitting.      After lots of debugging,  it *looks* like the problem is that the CAN_tx callback is not always called.       When using the ROM drivers,  this is critical as there is no way to know if there are free message objects before I make a call to LPC_CCAN_API->can_transmit().

Here is the flow...

1.)   In my system,  I have a software queue of CAN messages.
2.)  when I want to transmit, I put a message in the queue
3.)  A foreground routine will periodically check the queue and call the CCAN API as needed.
4.)  When a message is sent with the API,  A TxReady flag (which is declared a volatile)  is reset to indicate that I am sending a message.   The CAN_tx callback sets this flag to indicate the previous transmission is finished.

When happens over time is that my "TxReady" flag never gets set.   This means that the callback for transmission is not getting called.     I also have the error handler callback setup (and I enable the proper bits in the config register).     At no time does this callback ever get called.  So,   from the software point of view, it appears that there are no errors and the CAN_tx callback is not always getting called.

Also, the error handler resets all software flags and re-inits the CAN controller (although I never get a call to it)

The CAN API provides no mechanism to know if there are free message objects for me to send data so it seems that I must rely on a software flag to know.     Some more documentation on the API would be helpful.

Some snippets.....

/*CAN transmit callback */
/*Function is executed by the Callback handler after
    a CAN message has been transmitted */
void CAN_tx(uint8_t msg_obj_num)

CAN_TxReady = TRUE;


void CAN_Process()
uint16_t i,j;
CAN_t TempMsg;
CCAN_MSG_OBJ_T msg_obj;

i = CAN_MessagesInQueue(&CAN_TxQueue);

//if there is data to send, then dequeue and send.
if(CAN_TxReady && i>0)
CAN_TxReady = FALSE;

//move from our CAN_t queue to the Rom driver routine

msg_obj.msgobj  = 16;
msg_obj.mode_id = CAN_MSGOBJ_EXT | TempMsg.ID;
msg_obj.mask    = 0x0;
msg_obj.dlc    = TempMsg.DLC;


msg_obj.data[j] = TempMsg.Data[j];



Some other notes

a.)   It looks like the CAN API ignores the msg_obj field in the CAN struct.   I manually set this to 16 but I noticed that the can_tx callback sometimes indicates it use a different msg_obj.
b.)  I currently only use one msg_obj and a software queue.  I would like to use more of the available msg_objects but I cannot see any reliable way to know what is free via the CAN API.    The documentation on the ROM API is spare.

I am at a point where I am considering disassembly the ROM code to see the behavior of the tx function.... Or simply writing my own from scratch.    

Any ideas?