#include "mcp2518fd_can.h" uint8_t SPICS = 0; SPIClass* pSPI; CAN_CONFIG config; APP_Payload payload; // Receive objects CAN_RX_FIFO_CONFIG rxConfig; REG_CiFLTOBJ fObj; REG_CiMASK mObj; CAN_RX_FIFO_EVENT rxFlags; CAN_RX_MSGOBJ rxObj; uint8_t rxd[MAX_DATA_BYTES]; // Transmit objects CAN_TX_FIFO_CONFIG txConfig; CAN_TX_FIFO_EVENT txFlags; CAN_TX_MSGOBJ txObj; uint8_t txd[MAX_DATA_BYTES]; CAN_TX_QUEUE_CONFIG txqueConfig; // Message IDs #define TX_REQUEST_ID 0x300 #define TX_RESPONSE_ID 0x301 #define BUTTON_STATUS_ID 0x201 #define LED_STATUS_ID 0x200 #define PAYLOAD_ID 0x101 #define MAX_TXQUEUE_ATTEMPTS 50 // Transmit Channels #define APP_TX_FIFO CAN_FIFO_CH2 // Receive Channels #define APP_RX_FIFO CAN_FIFO_CH1 // Maximum number of data bytes in message #define MAX_DATA_BYTES 64 // //! SPI Transmit buffer // uint8_t spiTransmitBuffer[96]; // //! SPI Receive buffer // uint8_t spiReceiveBuffer[96]; CAN_BUS_DIAGNOSTIC busDiagnostics; uint8_t tec; uint8_t rec; CAN_ERROR_STATE errorFlags; #define DRV_CANFDSPI_INDEX_0 0 /********************************************************************************************************* ** Function name: MCP_CAN ** Descriptions: Constructor *********************************************************************************************************/ void mcp2518fd::mcp_canbus(uint8_t _CS) { nReservedTx = 0; pSPI = &SPI; init_CS(_CS); } /********************************************************************************************************* ** Function name: init_CS ** Descriptions: init CS pin and set UNSELECTED *********************************************************************************************************/ void mcp2518fd::init_CS(byte _CS) { if (_CS == 0) { return; } SPICS = _CS; pinMode(SPICS, OUTPUT); MCP2518fd_UNSELECT(); } /********************************************************************************************************* ** Function name: begin ** Descriptions: init can and set speed *********************************************************************************************************/ byte mcp2518fd::begin() { SPI.begin(); byte res = mcp2518fd_init(); return ((res == MCP2518fd_OK) ? CAN_OK : CAN_FAILINIT); } void mcp2518fd::mcp2518fd_TransmitMessageQueue(void) { uint8_t attempts = MAX_TXQUEUE_ATTEMPTS; // Check if FIFO is not full do { DRV_CANFDSPI_TransmitChannelEventGet(DRV_CANFDSPI_INDEX_0, APP_TX_FIFO, &txFlags); if (attempts == 0) { Nop(); Nop(); DRV_CANFDSPI_ErrorCountStateGet(DRV_CANFDSPI_INDEX_0, &tec, &rec, &errorFlags); return; } attempts--; } while (!(txFlags & CAN_TX_FIFO_NOT_FULL_EVENT)); // Load message and transmit uint8_t n = DRV_CANFDSPI_DlcToDataBytes((CAN_DLC)txObj.bF.ctrl.DLC); DRV_CANFDSPI_TransmitChannelLoad(DRV_CANFDSPI_INDEX_0, APP_TX_FIFO, &txObj, txd, n, true); } /********************************************************************************************************* ** Function name: sendMsgBuf ** Descriptions: send buf *********************************************************************************************************/ void mcp2518fd::mcp2518fd_sendMsgBuf(const byte* buf,byte len) { return mcp2518fd_sendMsg(buf,len); } /********************************************************************************************************* ** Function name: sendMsg ** Descriptions: send message *********************************************************************************************************/ void mcp2518fd::mcp2518fd_sendMsg(const byte* buf, byte len) { uint8_t n; int i; // Configure message data txObj.word[0] = 0; txObj.word[1] = 0; txObj.bF.id.SID = TX_REQUEST_ID; txObj.bF.ctrl.DLC = CAN_DLC_64; txObj.bF.ctrl.IDE = 0; txObj.bF.ctrl.BRS = true; txObj.bF.ctrl.FDF = 0; //Prepare data for(i = 0; i< len; i++) { txd[i] = buf[i]; } mcp2518fd_TransmitMessageQueue(); } int8_t mcp2518fd::mcp2518fd_receiveMsg() { DRV_CANFDSPI_ReceiveChannelEventGet(DRV_CANFDSPI_INDEX_0, APP_RX_FIFO, &rxFlags); if (rxFlags & CAN_RX_FIFO_NOT_EMPTY_EVENT) { DRV_CANFDSPI_ReceiveMessageGet(DRV_CANFDSPI_INDEX_0, APP_RX_FIFO, &rxObj, rxd, 8); for (int i = 0; i < 8; i++) { Serial.println(rxd[i]); Serial.println("\t"); } Serial.println(); } return 0; } /********************************************************************************************************* ** Function name: mcp2515_init ** Descriptions: init the device *********************************************************************************************************/ uint8_t mcp2518fd::mcp2518fd_init() { // Reset device DRV_CANFDSPI_Reset(DRV_CANFDSPI_INDEX_0); // Enable ECC and initialize RAM DRV_CANFDSPI_EccEnable(DRV_CANFDSPI_INDEX_0); DRV_CANFDSPI_RamInit(DRV_CANFDSPI_INDEX_0, 0xff); // Configure device DRV_CANFDSPI_ConfigureObjectReset(&config); config.IsoCrcEnable = 1; config.StoreInTEF = 0; DRV_CANFDSPI_Configure(DRV_CANFDSPI_INDEX_0, &config); // Setup TX FIFO DRV_CANFDSPI_TransmitChannelConfigureObjectReset(&txConfig); txConfig.FifoSize = 7; txConfig.PayLoadSize = CAN_PLSIZE_64; txConfig.TxPriority = 1; DRV_CANFDSPI_TransmitChannelConfigure(DRV_CANFDSPI_INDEX_0, APP_TX_FIFO, &txConfig); // Setup RX FIFO DRV_CANFDSPI_ReceiveChannelConfigureObjectReset(&rxConfig); rxConfig.FifoSize = 15; rxConfig.PayLoadSize = CAN_PLSIZE_64; DRV_CANFDSPI_ReceiveChannelConfigure(DRV_CANFDSPI_INDEX_0, APP_RX_FIFO, &rxConfig); // Setup RX Filter fObj.word = 0; fObj.bF.SID = 0; fObj.bF.EXIDE = 0; fObj.bF.EID = 0x00; DRV_CANFDSPI_FilterObjectConfigure(DRV_CANFDSPI_INDEX_0, CAN_FILTER0, &fObj.bF); // Setup RX Mask mObj.word = 0; mObj.bF.MSID = 0; mObj.bF.MIDE = 0; // Only allow standard IDs mObj.bF.MEID = 0x0; DRV_CANFDSPI_FilterMaskConfigure(DRV_CANFDSPI_INDEX_0, CAN_FILTER0, &mObj.bF); // Link FIFO and Filter DRV_CANFDSPI_FilterToFifoLink(DRV_CANFDSPI_INDEX_0, CAN_FILTER0, APP_RX_FIFO, true); // Setup Bit Time DRV_CANFDSPI_BitTimeConfigure(DRV_CANFDSPI_INDEX_0, CAN_125K_500K, CAN_SSP_MODE_AUTO, CAN_SYSCLK_20M); // Setup Transmit and Receive Interrupts DRV_CANFDSPI_GpioModeConfigure(DRV_CANFDSPI_INDEX_0, GPIO_MODE_INT, GPIO_MODE_INT); //#ifdef APP_USE_TX_INT DRV_CANFDSPI_TransmitChannelEventEnable(DRV_CANFDSPI_INDEX_0, APP_TX_FIFO, CAN_TX_FIFO_NOT_FULL_EVENT); //#endif DRV_CANFDSPI_ReceiveChannelEventEnable(DRV_CANFDSPI_INDEX_0, APP_RX_FIFO, CAN_RX_FIFO_NOT_EMPTY_EVENT); DRV_CANFDSPI_ModuleEventEnable(DRV_CANFDSPI_INDEX_0,(CAN_MODULE_EVENT)(CAN_TX_EVENT | CAN_RX_EVENT)); // Select Normal Mode DRV_CANFDSPI_OperationModeSelect(DRV_CANFDSPI_INDEX_0, CAN_CLASSIC_MODE); // CAN_OPERATION_MODE abc; // abc = DRV_CANFDSPI_OperationModeGet(0); // Serial.printf("DRV_CANFDSPI_OperationModeGet = %d\n\r",abc); return 0; }