14.10.5 Message Reception Code Example

A code example to receive the CAN FD extended frame using Filter 0, and saving the messages in FIFO 1, is shown in Message Reception Code.

Message Reception Code

#include <xc.h>
/* This code example demonstrates a method to configure the CAN FD module to
receive the extended ID CAN FD messages. This uses CAN1, FIFO1 and filter 0. FIFO1 is configured to receive 2 messages. */
/* Include fuse configuration code here. */
#define MAX_WORDS 100
unsigned int __attribute__((aligned(4)))CanRxBuffer[MAX_WORDS];
/*data structure to implement a CANFD message buffer. */
/* CANFD Message Time Stamp */
typedef unsigned long CANFD_MSG_TIMESTAMP;

/* CANFD RX Message Object Control*/
typedef struct _CANFD_RX_MSGOBJ_CTRL {
    unsigned DLC : 4;
    unsigned IDE : 1;
    unsigned RTR : 1;
    unsigned BRS : 1;
    unsigned FDF : 1;
    unsigned ESI : 1;
    unsigned unimplemented1 : 2;
    unsigned FilterHit : 5;
    unsigned unimplemented2 : 16;
} CANFD_RX_MSGOBJ_CTRL; /* CANFD RX Message ID*/

typedef struct _CANFD_MSGOBJ_ID {
    unsigned SID : 11;
    unsigned long EID : 18;
    unsigned SID11 : 1;
    unsigned unimplemented1 : 2;
} CANFD_MSGOBJ_ID;

/* CANFD RX Message Object */
typedef union _CANFD_RX_MSGOBJ {
    struct {
        CANFD_MSGOBJ_ID id;
        CANFD_RX_MSGOBJ_CTRL ctrl;
        CANFD_MSG_TIMESTAMP timeStamp;
    } bF;
    unsigned int word[6];
    unsigned char byte [12]
} CANFD_RX_MSGOBJ;

int main(void) {
    /* The dsPIC33A device features I/O remap. This I/O remap configuration for
    the CAN FD module can be performed here. */
    SetIORemapForCANFDModule();

    /* Configure the CRU clock generator unit corresponding to CANFD to yield
     * 40MHz clock. This clock is CANFD module clock */
    ConfigureCANFDClockFor40MHz(); // FCAN = 40 MHz

    /* Enable the CANFD module */
    C1CONbits.ON = 1;

    /* Place CAN module in configuration mode */
    C1CONbits.REQOP = 4;
    while (C1CONbits.OPMOD != 4);

    /* Initialize the C1FIFOBA with the start address of the CAN FIFO message
    buffer area. */
    C1FIFOBA = (unsigned int) &CanRxBuffer;

    /* Set up the CANFD module for 1Mbps Nominal bit rate speed and
     * 2Mbps Data bit rate.
     */
    C1NBTCFG = 0x001E0707;
    C1DBTCFG = 0x000E0303;
    C1TDC = 0x00020F00;             //TDCMOD is Auto

    /* Configure CANFD module to enable BRS */
    C1CONbits.BRSDIS = 0x0;
    C1CONbits.STEF = 0x0;           //Don't save transmitted messages in TEF
    C1CONbits.TXQEN = 0x0;          //No TXQ

    /* Configure FIFO1 to Receive 2 messages*/
    C1FIFOCON1bits.FSIZE = 0x1;     //2 messages
    C1FIFOCON1bits.PLSIZE = 0x7;    //64 bytes of data
    C1FIFOCON1bits.TXEN = 0x0;      //Receive fifo
    C1FIFOCON1bits.RXTSEN = 0x1;    //Enable receive fifo timestamp

    /* Configure filter 0 and MASK 0 to accept extended id messages
    with id = 2 and 3 */
    C1FLTCON0bits.F0BP = 1; // message stored in FIFO1
    C1FLTOBJ0 = 0x40001000; // EID = 0x00002 with extended identifier address
    C1MASK0 = 0xFFFFF7FF; // MEID = 0x1FFFE:Last bit is 0. Match message types
    C1FLTCON0bits.FLTEN0 = 1; // Enable the filter 0

    /* Place the CAN module in Normal mode. */
    C1CONbits.REQOP = 0;
    while (C1CONbits.OPMOD != 0);

    /* Get the address of the message buffer to read the received messages.*/
    /* set UINC bit to update the FIFO tail */
    CANFD_RX_MSGOBJ *rxObj;
    rxObj = (CANFD_RX_MSGOBJ *) C1FIFOUA1;
    while (C1FIFOSTA1bits.TFNRFNIF == 0);

    //Process the received messages
    C1FIFOCON1bits.UINC = 1;        // Update the FIFO message pointer.
    while (1);
}