NXP LPC18xx series CMSIS based CAN gateway

Hi guys!

We're moving from NXP's LPC175x MCU to LPC18xx MCU. On LPC175x we use both CAN controllers making some kind of gateway between 2 CAN networks. The logic is quite simply, any frame coming from CAN0 network is transferred to CAN1 network and any frame coming from CAN1 network goes to CAN0 network. The setup is quite simple too, all IDs are accepted on both controllers (acceptance filters are not used). LPC175x devices have triple CAN Tx buffer on each controller so everything works just fine even at high network loads.

Now it appears that on LPC18xx series the CAN controllers are quite different, they gone for "message-objects" setup with message memory map. So we're trying to learn how to use them in our application. And we kinda stuck now. We got the CMSIS based CAN example coming for MCB1800 Keil board, using Keil v5 environment. Got rid of real time OS and moved few things around the CMSIS driver.

The idea is to create a RX message object using  ObjectSetFilter(1, ARM_CAN_FILTER_ID_MASKABLE_ADD, ARM_CAN_STANDARD_ID(0x1FFU), 0U); We're supposing this will cover all 11bits frame IDs. And it looks like we're able to receive all ID from 1 to 1FF.

Then we're trying to recreate our triple Tx buffer by allocating 3 Tx message-objects for this purpose. Then the logic is simple,  getting Rx interrupt coming from CAN0 Rx message-object, picking up frame data, setting up Rx flag to indicate the new data available then in the main loop transmit the data through CAN1 controller. Same for CAN1 controller, get the data and send all through CAN0. Main loop is just a while(1){ read the flag / send the message } for test purposes.

All this seems to work but we have some important frame loss somewhere in between. This never happened with LPC175x series MCUs. And honestly, we cannot believe that the LPC18xx with double operating clock frequency cannot move frames between both controllers fast enough! Something is definitely wrong with our approach and all this message-object setup. We're thinking the single Rx message object could be the reason but no idea how to create multiple ones with same mask. Would you, please, suggest the direction to dig?

Thanks all!   

Parents
  • Hi Dim.

    I think older LPC1700 device had CAN controller implemented by NXP, and LPC1800 has C_CAN controller which is Bosch IP.

    I would suggest you try using more than 1 message object for reception as well as for transmission.

    For example try using 3 Rx message objects with same filter setting for reception, expecting that when 1 message object is filled, reception would continue into a second one.

    Since you are doing a bridge, do you know if you have some arbitration issues?

    If you are sending something and another device on the same network is also sending then arbitration would determine which message would continue to be transmitted, and the device that lost arbitration would back off.

    Best regards, Milorad

  • Milorad, 

    Thanks for this suggestion! I was working in this direction but no results so far. I've tried to split the incoming traffic into 3 different Rx buffers, just by creating some masks. Even with this and 15 Tx buffers we are still losing some frames. Way less than before but still not good. Also the mask splitting will not work in real application with tens of unknown frame IDs. 

    For example try using 3 Rx message objects with same filter setting for reception, expecting that when 1 message object is filled, reception would continue into a second one.

    I'm very curious, how can you possibly do this? So far, while setting up the #1 filter and accepting all IDs the controller will definitely not use the filters #2, #3 etc (I tried :) ). And I don't think the built in FIFO can be used since it supposes to have the same ID frame but with different frame data. In my understanding, the concatenating FIFO for message-object is used when you don't have enough time to get all data from Rx buffer but this shouldn't work with different IDs. But perhaps I'm completely wrong, the user's manual has some unclear points. About the frame loss, this is not an arbitration issue. All injected frames have different IDs so we exclude the possibility having 2 CAN sources transmitting the same ID within the same network.

    Best regards,

    Dimitri 

  • Hi Dimitri.

    From the C_CAN documentation it seems like the only way you would be able to do that is to use the FIFO buffer concept.

    In my understanding, the concatenating FIFO for message-object is used when you don't have enough time to get all data from Rx buffer but this shouldn't work with different IDs.

    I don;t think so, I think it is exactly for situation like yours when you do not have enough time to read data from message object but you want to still be able to receive message with ID passing same filter to another message object.

    the documentation on FIFO buffer says:

    the identifiers and masks (if used) of these Message Objects have to be programmed to matching values.

    That means that you set multiple message objects use same filter settings and act as a FIFO.

    Meaning when first message is received to message object 0 then second message will continue to be received into message object 1 until message object 0 is free again.

    I thought that with 3 separate messages it would behave this way but it will not unless FIFO mode is used meaning all message objects that are a part of FIFO except last must have EoB bit cleared and last one must have EoB set.

    Did you check that MsgLst gets activated in message objects meaning your message was overwritten before it was read.

    Perhaps you can also do a software buffering,.

    For example when message is received put it into message queue and then have a thread which would just write it to the other CAN controller message object for transmission.

    Depending on the speed of your CAN communication after the message is received there is time until new identifier is received to read out the received data (if single message object is used).

    What is the CAN speed in your situation?

    First, try to test if you are able to receive all the data without transmit just to check that reception is working as expected then if you manage to receive all messages you see how to transmit them while still keeping the reception responsive.

    I think you did not get the part about arbitration, the arbitration I was talking about is the one that happens on the bus it is not that same IDs must not clash, but it means that if two nodes try to send data at the same time the lower ID wins the arbitration and the one that tried to send message with higher ID had to back off and has to re-transmit the message at later time.

    Best regards, Milorad

Reply
  • Hi Dimitri.

    From the C_CAN documentation it seems like the only way you would be able to do that is to use the FIFO buffer concept.

    In my understanding, the concatenating FIFO for message-object is used when you don't have enough time to get all data from Rx buffer but this shouldn't work with different IDs.

    I don;t think so, I think it is exactly for situation like yours when you do not have enough time to read data from message object but you want to still be able to receive message with ID passing same filter to another message object.

    the documentation on FIFO buffer says:

    the identifiers and masks (if used) of these Message Objects have to be programmed to matching values.

    That means that you set multiple message objects use same filter settings and act as a FIFO.

    Meaning when first message is received to message object 0 then second message will continue to be received into message object 1 until message object 0 is free again.

    I thought that with 3 separate messages it would behave this way but it will not unless FIFO mode is used meaning all message objects that are a part of FIFO except last must have EoB bit cleared and last one must have EoB set.

    Did you check that MsgLst gets activated in message objects meaning your message was overwritten before it was read.

    Perhaps you can also do a software buffering,.

    For example when message is received put it into message queue and then have a thread which would just write it to the other CAN controller message object for transmission.

    Depending on the speed of your CAN communication after the message is received there is time until new identifier is received to read out the received data (if single message object is used).

    What is the CAN speed in your situation?

    First, try to test if you are able to receive all the data without transmit just to check that reception is working as expected then if you manage to receive all messages you see how to transmit them while still keeping the reception responsive.

    I think you did not get the part about arbitration, the arbitration I was talking about is the one that happens on the bus it is not that same IDs must not clash, but it means that if two nodes try to send data at the same time the lower ID wins the arbitration and the one that tried to send message with higher ID had to back off and has to re-transmit the message at later time.

    Best regards, Milorad

Children
More questions in this forum