LPC546xx CAN Rx FIFO infos

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC546xx CAN Rx FIFO infos

2,276 Views
cybaluke
Contributor III

Hi, I'm running on a LPC54608 and MCUXpresso, sdk2.7, I have some problems to understand how to receive many frames from standard CAN bus @125kbps. Starting from sdk mcan interrupt example I can receive a single CAN messages but I have some problems receiveing a burst of many messages (e.g. a burst of 10 messages), basically I think I have some problems to understand how RX FIFO works: where can I find basic informations on how CAN fifo works on LPC5460xx? User Manual specs the registers bits but doesn't help me to understand how to use fifo mechanism... I think I need a dummy reference applied on this peripheral? someone can help me?

thanks. 

Labels (3)
9 Replies

2,029 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Lucan Givin,

In the SDK you can look for the example mcan_interrupt_transfer, this shows an example of how to set the RX FIFO, if you want to receive more frames you will need to modify the RX Filter to accept more than the ID frame given.

I hope this helps you.

Best Regards,

Alexis Andalon

0 Kudos

2,029 Views
cybaluke
Contributor III

Hi Alexis, thanks for your answer.

In the suggested demo code I set the RX buffer lenght to 32 frames:

/* RX fifo0 config. */
rxFifo0.elementSize = 32U;
rxFifo0.watermark = 0;
rxFifo0.opmode = kMCAN_FifoBlocking;
rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
...
MCAN_SetRxFifo0Config(EXAMPLE_MCAN, &rxFifo0);
‍‍‍‍

after this I enabled a receiver function using a non blocking Fifo0 receiver:

MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);


and into my receiver function when I detect a valid IRQ received message I read all the received frames in the buffer checking the RxFifo0 F0FL fill level value with the code below:

    if((rxComplete == true))
    {
        /* check for all the received frames in the buffer */
        while (((USE_MCAN->RXF0S & CAN_RXF0S_F0FL_MASK) >> CAN_RXF0S_F0FL_SHIFT) >0)
        {
            MCAN_ReadRxFifo(USE_MCAN, 0,&rxFrame);
            /* use here the received frame from the buffer */
            ....
        }
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Is this correct or I'm missing something?

0 Kudos

2,029 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Luca,

That looks good. Is the module working after the modifications?

Best Regards,

Alexis Andalon

0 Kudos

2,029 Views
cybaluke
Contributor III

In my target board the firmware coded starting from the example "lpcxpresso54608_mcan_interrupt_transfer"  from the sdk.2.7 and with new sdk.2.7 MCAN drivers basically seems to work (enough); I solved the problem on CAN receiver that I had with MCAN_TransferReceiveFifoNonBlocking and IRQ callback functions on sdk.2.6 (as I already wrote in my first question the previous CAN manager stops working receiving multiple frames; with the new RX FIFO BUFFER manager described above and sdk.2.7 this problem doesn't happen).

...BUT...

I'm not so really sure that everything works well because I'm also founding some new Bus_Off error detections in the IRQ callback function where the previous firmware based on sdk.2.6 didn't  had!

Maybe the new problems are not really correlated with the RX FIFO frames length (as reported above) but more in general seems to depend on other changes in sdk.2.7  IRQ callback management... 

Any suggestion on the changes from sdk2.6 to sdk2.7 about MCAN drivers?

0 Kudos

2,029 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Luca,

Bus off means that the transmit error counter (see explanation further down) has reached 256. So it could be that the package sent has not the same ID or the filter set for the FIFO is filtering the package, also the baud-rate could be an option. 

Is the same ID that causes drops in the transmission?

Best Regards,

Alexis Andalon

0 Kudos

2,029 Views
cybaluke
Contributor III

Hi Alexis,

thanks for the explanations, but I think my problem is on how the callback IRQ function detect ErrorPassive and Buss-Off state: it seems that the standard callback uint32_t result parameter in

static void mcan_callback(CAN_Type *base, mcan_handle_t *handle, status_t status, uint32_t result, void *userData)

can't distinguish from BussOff, ErrorPassive or  ErrorWarning (using flags kMCAN_ErrorWarningIntFlag, kMCAN_ErrorPassiveIntFlag or kMCAN_BusOffIntFlag) because in sdk.2.7  the MCAN_TransferHandleIRQ function in fsl_mcan.c file sets always all the three flags as result even if there is only one condition detected. 

void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle)
{
  [...]
    do
    {
        if (0U != (valueIR & ((uint32_t)kMCAN_ErrorWarningIntFlag |
                              (uint32_t)kMCAN_ErrorPassiveIntFlag |
                              (uint32_t)kMCAN_BusOffIntFlag)))
        {
            /* Here it seems to set always all the three flags even if
             * only 1 condition causes the IRQ? */
            result = (uint32_t)kMCAN_ErrorWarningIntFlag |
                     (uint32_t)kMCAN_ErrorPassiveIntFlag |
                     (uint32_t)kMCAN_BusOffIntFlag;
            status = kStatus_MCAN_ErrorStatus;
        }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Is this correct?

Starting from this point now I detect the real error condition/status in my callback manager:

/*detect the state */
/* check for BUS_OFF status */
if(((USE_MCAN->PSR & CAN_PSR_BO_MASK)>>CAN_PSR_BO_SHIFT)==1)
{
   /* manage bus-off status, in my case I completely reset 
    * the CAN controller, I restart it and then I check if the 
    * bus-off state is solved*/
    MCAN_Deinit(USE_MCAN);
    open_can();
    /* wait the busoff recovery finished */
    while((((USE_MCAN->PSR & CAN_PSR_LEC_MASK)>>CAN_PSR_LEC_SHIFT)==0x5) ||
  (((USE_MCAN->PSR & CAN_PSR_BO_MASK)>>CAN_PSR_BO_SHIFT)==1));
} 

/* check for error passive status */
else if(((USE_MCAN->PSR & CAN_PSR_EP_MASK)>>CAN_PSR_EP_SHIFT)==1)
{
   /* manage error passive status, in my app I simply clean the error
    * restarting the can controller */
   USE_MCAN->CCCR |= CAN_CCCR_INIT_MASK;
   /* Confirm the value has been accepted. */
   while (!((USE_MCAN->CCCR & CAN_CCCR_INIT_MASK) >> CAN_CCCR_INIT_SHIFT));
   
   MCAN_EnterNormalMode(USE_MCAN);

}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

What do you think about this?

I think my wrong BusOff detections  were not bus-off problems but error passive detections caused by the cable disconnection manager...  so now the firmware should manage the ErrorPassive status... any suggestion to recovery the Error_Passive status?

0 Kudos

2,029 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello,

As you mention, I also think the driver should recognize between errors so you could use the approach you handle or only add the valueIR to the result assignment as follows so you could identify in the callback which error is being triggered:

 if (0U != (valueIR & ((uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |
                              (uint32_t)kMCAN_BusOffIntFlag)))
        {
            /* Solve error. */
            result = valueIR & ((uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |
                     (uint32_t)kMCAN_BusOffIntFlag);
            status = kStatus_MCAN_ErrorStatus;
        }

The passive error quickly can be converted to a bus_off condition, so be careful how you handle this:

¨A node starts out in Error Active mode. When any one of the two Error Counters raises above 127, the node will enter a state known as Error Passive and when the Transmit Error Counter raises above 255, the node will enter the Bus Off state.¨  (font)

As far as I know, the node will be possible to recover if it not enter the bus_off condition, after it enter will require the correct recovery sequence, check the second Remark in the page 709 to know more about this.

Let me know if this helps you.

Best Regards,

Alexis Andalon

2,029 Views
cybaluke
Contributor III

Hi, you're really really  helpful... thanks for the link!

In my app the CAN driver has to detect and manage a "cable detaching/disconnection" and "cable  re-connection" condition and as I can see the errors are just generated from these operations (of course in case of cable disconnection, after the detection of the AckError - The message transmitted by the M_CAN was not acknowledged by another node - in PSR register, I already stop the transmission of new frames and I abort any pending TX message ....)

From my last debugs I've found that, as you mentioned, the error_passive drives quickly in a bus_off error if not managed, but I've also found that the simple re-init of the block using the instruction:      USE_MCAN->CCCR |= CAN_CCCR_INIT_MASK; as indicated in my previous code is not sufficient to really recover the block from the error_passive caused by a cable detach. Maybe a complete reset and restarting of the CAN block is more appropriate.

I don't know if you or someone in the community has a deeper experience or has already solved these kind of problems and has some suggestions...

0 Kudos

2,029 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Luca,

Usually when a module suffers a critical error the best way to recover it will be a reinitialization of the module, so I think you could try this.

Best Regards,

Alexis Andalon