Basic CAN FIFO clarification

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I'm looking to clarify MCAN operation on the SAME70 based on the example code I've reviewed and the CAN section in the datasheet. The datasheet specifies two FIFO buffers which can be used for RX message storage. My questions are as follows:

 

  1. Can I configure MCAN0 to store both standard and extended messages in FIFO0 and MCAN1 to store both standard and extended messages in FIFO1?
  2. If the above isn't possible (the code I've reviewed seems to use one FIFO for standard and the other for extended), given that there are only 2 available FIFOs across two MCAN interfaces, is there a way to determine from which interface the stored message originated? E.g. if FIFO0 is for standard MCAN0/MCAN1 messages (and FIFO1 for extended MCAN0/MCAN1 messages), when I retrieve a given message from the FIFO, am I able to determine whether it's an MCAN0 or MCAN1 message?

 

I imagine I could keep an index reference array for each of the MCAN0/1 interfaces, so when a new message is received by the MCAN0/1 handler, I assign the index of that particular FIFO message to either the MCAN0 or MCAN1 index array? This would require interrupt handling of every received message, whereas I'd prefer to let a number of messages accumulate and process them in batches (likely using the watermark interrupt) if possible.

 

EDIT: I realised that the MCAN_RX_FIFO_0_NEW_MESSAGE/MCAN_RX_FIFO_1_NEW_MESSAGE interrupt would cause both the MCAN0_INT0_Handler() and MCAN1_INT0_Handler() handlers to be called, so I don't think the above would work?

 

Any clarification would be greatly appreciated!

This topic has a solution.
Last Edited: Thu. Oct 29, 2020 - 04:17 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I believe I'm able to answer this one myself :)

 

The ASF MCAN driver establishes a default configuration for standard and extended messages as follows:

  • Standard message filtering -> Messages are stored in FIFO0
  • Extended message filtering -> Messages are stored in FIFO1

 

There are no hardware constraints on this, this just appears to be an ASF design decision. Without going into the driver source (in the mcan_get_standard_message_filter_element_default() and mcan_get_extended_message_filter_element_default() functions) it's easy to overlook the EFEC register setting.

 

To instead direct extended messages to FIFO0 (so both standard and extended messages use FIFO0), the ASF-based code is as follows:

 

static void mcanSetExtendedFilter0(void)
{
    struct mcan_extended_message_filter_element et_filter;
    mcan_get_extended_message_filter_element_default(&et_filter);
    
    //Change the EFEC value from the FIFO1 default to FIFO0
    et_filter.F0.bit.EFEC = MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F0_EFEC_STF0M_Val;
    
    //Allow all extended message arbitration IDs
    et_filter.F1.reg = MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F1_EFID2(0) |
                       MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F1_EFT_CLASSIC;
    
    mcan_set_rx_extended_filter(&mcan_instance, &et_filter, 0);
}

Hopefully this saves someone some time in the future.