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);
}