14.8.2 Transmit Event FIFO Code Example

A code example to save the transmitted messages using TEF is shown in Using the Transmit Event FIFO Code.

Using the Transmit Event FIFO Code

/* Include fuse configuration code here. */
#define MAX_WORDS 100
unsigned int __attribute__((aligned(4)))CanTxBuffer[MAX_WORDS]; //message buffer to be written
unsigned int * currentMessageBuffer; //Points to message buffer to be read
/*data structure to implement a CANFD message buffer. */
/* CANFD Message Time Stamp */
typedef unsigned long CANFD_MSG_TIMESTAMP;

/* CAN TX Message Object Control*/
typedef struct _CANFD_TX_MSGOBJ_CTRL {
    unsigned DLC : 4;
    unsigned IDE : 1;
    unsigned RTR : 1;
    unsigned BRS : 1;
    unsigned FDF : 1;
    unsigned ESI : 1;
    unsigned SEQ : 23;
    unsigned unimplemented1 : 16;
} CANFD_TX_MSGOBJ_CTRL;

/* CANFD TX Message ID*/
typedef struct _CANFD_MSGOBJ_ID {
    unsigned SID : 11;
    unsigned long EID : 18;
    unsigned SID11 : 1;
    unsigned unimplemented1 : 2;
} CANFD_MSGOBJ_ID;

/* CAN TX Message Object*/
typedef union _CANFD_TX_MSGOBJ {

    struct {
        CANFD_MSGOBJ_ID id;
        CANFD_TX_MSGOBJ_CTRL ctrl;
    } bF;
    unsigned int word[4];
    unsigned char byte[8];
} CANFD_TX_MSGOBJ;

/* CANFD TEF Message Object */
typedef union _CAN_TEF_MSGOBJ {

    struct {
        CANFD_MSGOBJ_ID id;
        CANFD_TX_MSGOBJ_CTRL ctrl;
        CANFD_MSG_TIMESTAMP timeStamp;
    } bF;
    unsigned int word[6];
    unsigned char byte[12];
} CANFD_TEF_MSGOBJ;

int main(void) {
    unsigned char index, fifoSize;

    /* 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) &CanTxBuffer;

    /* 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 save transmitted messages in TEF and BRS*/
    C1CONbits.BRSDIS = 0x0;
    C1CONbits.STEF = 0x1;
    C1CONbits.TXQEN = 0x0;          // Disable TXQ

    /* Configure TEF to save 5 messages*/
    C1TEFCONbits.FSIZE = 0x4;       // save 5 messages
    C1TEFCONbits.TEFTSEN = 1;

    /* Configure FIFO1 to transmit 5 messages*/
    C1FIFOCON1bits.FSIZE = 0x4;     // 5 messages
    C1FIFOCON1bits.PLSIZE = 0x7;    // 64 bytes of data
    C1FIFOCON1bits.TXEN = 0x1;      // Set TXEN bit ,transmit fifo

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

    /* Get the address of the message buffer to write to. Load the buffer and
     * then set the UINC bit. Set the TXREQ bit to send the message.
     */
    CANFD_TX_MSGOBJ *txObj;

    /* Transmit 5 messages from FIFO 1 - CANFD base frame with BRS*/
    /* SID = 0x300 , 64 bytes of data */
    for (fifoSize = 0; fifoSize < 5; fifoSize++) {
        txObj = (CANFD_TX_MSGOBJ *) C1FIFOUA1;
        txObj->bF.id.SID = 0x300;
        txObj->bF.id.EID = 0x0000;
        txObj->bF.ctrl.BRS = 1;     //Switch bit rate
        txObj->bF.ctrl.DLC = 0xF;   //64 bytes
        txObj->bF.ctrl.FDF = 1;     //CANFD frame
        txObj->bF.ctrl.IDE = 0;     //Standard frame
        txObj->bF.ctrl.SEQ = fifoSize; //Sequence stored in TEF
        for (index = 0; index < 0x40; index++) {
            //64 bytes of 0xA5
            txObj->byte[index + 8] = 0xA5;
        }
        C1FIFOCON1bits.UINC = 1; // Set UINC bit
    }

    C1FIFOCON1bits.TXREQ = 1; // Set TXREQ bit
    while (C1FIFOCON1bits.TXREQ == 1);

    /* Keep reading the TEF objects until the last transmitted message*/
    for (fifoSize = 0; fifoSize < 5; fifoSize++) {
        while (C1TEFSTAbits.TEFNEIF == 0);
        CANFD_TEF_MSGOBJ *tefObj;
        tefObj = (CANFD_TEF_MSGOBJ *) C1TEFUA;
        //ProcessTEFMessages (currentMessageBuffer) ;
        C1TEFCONbits.UINC = 1; // Set UINC bit
    }
    while (1);
}