14.7.16 Message Transmission Code Example

Message Transmission Code

#include <xc.h>
/* This code example demonstrates a method to configure the CAN FD module to
transmit Standard and Extended ID CAN FD messages. This uses CAN1, TXQ and FIFO1. TXQ size is 1 and FIFO1 size is 2. */
/* Include fuse configuration code here. */

#define MAX_WORDS 100
unsigned int __attribute__((aligned(4)))CanTxBuffer[MAX_WORDS];
/*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;

int main(void) {
    unsigned char index;

    /* 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 enable Transmit Queue and BRS*/
    C1CONbits.BRSDIS = 0x0;
    C1CONbits.STEF = 0x0;           //Don't save transmitted messages in TEF
    C1CONbits.TXQEN = 0x1;

    /* Configure TXQ to transmit 1 message*/
    C1TXQCONbits.FSIZE = 0x0;       // single message
    C1TXQCONbits.PLSIZE = 0x7;      // 64 bytes of data

    /* Configure FIFO1 to transmit 2 messages*/
    C1FIFOCON1bits.FSIZE = 0x1;     //2 messages
    C1FIFOCON1bits.PLSIZE = 0x2;    //16 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 next to send the message. */
    CANFD_TX_MSGOBJ *txObj;

    /* Transmit message from TXQ - CANFD base frame with BRS*/
    /* SID = 0x100, 64 bytes of data */
    txObj = (CANFD_TX_MSGOBJ *) C1TXQUA;
    txObj->bF.id.SID = 0x100;
    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
    for (index = 0; index < 0x40; index++) {
        //64 bytes of 0x5A
        txObj->byte[index + 8] = 0x5A;
    }
    C1TXQCONbits.UINC = 1;          // Set UINC bit
    C1TXQCONbits.TXREQ = 1;         // Set TXREQ bit

    /* Transmit message 0 from FIFO 1 - CANFD base frame with BRS*/
    /* SID = 0x300 , 16 bytes of data */
    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 = 0xA;       //16 bytes
    txObj->bF.ctrl.FDF = 1;         //CANFD frame
    txObj->bF.ctrl.IDE = 0;         //Standard frame
    for (index = 0; index < 0x10; index++) {
        //16 bytes of 0xA5
        txObj->byte[index + 8] = 0xA5;
    }

    C1FIFOCON1bits.UINC = 1;        //Set UINC bit
    C1FIFOCON1bits.TXREQ = 1;       //Set TXREQ bit
    /* Transmit message 1 from FIFO 1 - CANFD base frame with BRS*/
    /* SID = 0x500, EID = 0xC000, 12 bytes of data */
    txObj = (CANFD_TX_MSGOBJ *) C1FIFOUA1;
    txObj->bF.id.SID = 0x500;
    txObj->bF.id.EID = 0xC000;
    txObj->bF.ctrl.BRS = 1;         //Switch bit rate
    txObj->bF.ctrl.DLC = 0x9;       //12 bytes
    txObj->bF.ctrl.FDF = 1;         //CANFD frame
    txObj->bF.ctrl.IDE = 1;         //Extended frame
    for (index = 0; index < 0xC; index++) {
        //12 bytes of 0x55
        txObj->byte[index + 8] = 0x55;
    }

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