diff --git a/mcp2518fd_can.cpp b/mcp2518fd_can.cpp new file mode 100644 index 0000000..bbd562b --- /dev/null +++ b/mcp2518fd_can.cpp @@ -0,0 +1,830 @@ +#include "mcp2518fd_can.h" + +CAN_CONFIG config; +// Transmit objects +CAN_TX_FIFO_CONFIG txConfig; +CAN_TX_FIFO_EVENT txFlags; +CAN_TX_MSGOBJ txObj; +uint8_t txd[MAX_DATA_BYTES]; + +// 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]; + +/********************************************************************************************************* +** 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: enableTxInterrupt +** Descriptions: enable interrupt for all tx buffers +*********************************************************************************************************/ +void mcp2518fd::enableTxInterrupt(bool enable) { + byte interruptStatus = mcp2518fd_readRegister(MCP_CANINTE); + + if (enable) { + interruptStatus |= MCP_TX_INT; + } else { + interruptStatus &= ~MCP_TX_INT; + } + + mcp2518fd_setRegister(MCP_CANINTE, interruptStatus); +} + +/********************************************************************************************************* +** Function name: begin +** Descriptions: init can and set speed +*********************************************************************************************************/ +byte mcp2518fd::begin(byte speedset, const byte clockset) { + pSPI->begin(); + byte res = mcp2518fd_init(speedset, clockset); + + return ((res == MCP2515_OK) ? CAN_OK : CAN_FAILINIT); +} + + +/********************************************************************************************************* +** Function name: init_Mask +** Descriptions: init canid Masks +*********************************************************************************************************/ +byte mcp2518fd::init_Mask(byte num, byte ext, unsigned long ulData) { + byte res = MCP2515_OK; + #if DEBUG_EN + Serial.print("Begin to set Mask!!\r\n"); + #else + delay(10); + #endif + res = mcp2518fd_setCANCTRL_Mode(MODE_CONFIG); + if (res > 0) { + #if DEBUG_EN + Serial.print("Enter setting mode fall\r\n"); + #else + delay(10); + #endif + return res; + } + + if (num == 0) { + mcp2518fd_write_id(MCP_RXM0SIDH, ext, ulData); + + } else if (num == 1) { + mcp2518fd_write_id(MCP_RXM1SIDH, ext, ulData); + } else { + res = MCP2515_FAIL; + } + + res = mcp2518fd_setCANCTRL_Mode(mcpMode); + if (res > 0) { + #if DEBUG_EN + Serial.print("Enter normal mode fall\r\n"); + #else + delay(10); + #endif + return res; + } + #if DEBUG_EN + Serial.print("set Mask success!!\r\n"); + #else + delay(10); + #endif + return res; +} + +/********************************************************************************************************* +** Function name: init_Filt +** Descriptions: init canid filters +*********************************************************************************************************/ +byte mcp2518fd::init_Filt(byte num, byte ext, unsigned long ulData) { + byte res = MCP2515_OK; + #if DEBUG_EN + Serial.print("Begin to set Filter!!\r\n"); + #else + delay(10); + #endif + res = mcp25fd_setCANCTRL_Mode(MODE_CONFIG); + if (res > 0) { + #if DEBUG_EN + Serial.print("Enter setting mode fall\r\n"); + #else + delay(10); + #endif + return res; + } + + switch (num) { + case 0: + mcp2518fd_write_id(MCP_RXF0SIDH, ext, ulData); + break; + + case 1: + mcp2518fd_write_id(MCP_RXF1SIDH, ext, ulData); + break; + + case 2: + mcp2518fd_write_id(MCP_RXF2SIDH, ext, ulData); + break; + + case 3: + mcp2518fd_write_id(MCP_RXF3SIDH, ext, ulData); + break; + + case 4: + mcp2518fd_write_id(MCP_RXF4SIDH, ext, ulData); + break; + + case 5: + mcp2518fd_write_id(MCP_RXF5SIDH, ext, ulData); + break; + + default: + res = MCP2515_FAIL; + } + + res = mcp2518fd_setCANCTRL_Mode(mcpMode); + if (res > 0) { + #if DEBUG_EN + Serial.print("Enter normal mode fall\r\nSet filter fail!!\r\n"); + #else + delay(10); + #endif + return res; + } + #if DEBUG_EN + Serial.print("set Filter success!!\r\n"); + #else + delay(10); + #endif + + return res; +} + + +/********************************************************************************************************* +** Function name: setSleepWakeup +** Descriptions: Enable or disable the wake up interrupt (If disabled the MCP2515 will not be woken up by CAN bus activity) +*********************************************************************************************************/ +void mcp2518fd::setSleepWakeup(const byte enable) { + mcp2518fd_modifyRegister(MCP_CANINTE, MCP_WAKIF, enable ? MCP_WAKIF : 0); +} + +/********************************************************************************************************* +** Function name: sleep +** Descriptions: Put mcp2515 in sleep mode to save power +*********************************************************************************************************/ +byte mcp2518fd::sleep() { + if (getMode() != MODE_SLEEP) { + return mcp2518fd_setCANCTRL_Mode(MODE_SLEEP); + } else { + return CAN_OK; + } +} + +/********************************************************************************************************* +** Function name: wake +** Descriptions: wake MCP2515 manually from sleep. It will come back in the mode it was before sleeping. +*********************************************************************************************************/ +byte mcp2518fd::wake() { + byte currMode = getMode(); + if (currMode != mcpMode) { + return mcp2518FD_setCANCTRL_Mode(mcpMode); + } else { + return CAN_OK; + } +} + +/********************************************************************************************************* +** Function name: setMode +** Descriptions: Sets control mode +*********************************************************************************************************/ +byte mcp2518fd::setMode(const byte opMode) { + if (opMode != + MODE_SLEEP) { // if going to sleep, the value stored in opMode is not changed so that we can return to it later + mcpMode = opMode; + } + return mcp2518fd_setCANCTRL_Mode(opMode); +} + +/********************************************************************************************************* +** Function name: getMode +** Descriptions: Returns current control mode +*********************************************************************************************************/ +byte mcp2518fd::getMode() { + return mcp2518fd_readRegister(MCP_CANSTAT) & MODE_MASK; +} + +/********************************************************************************************************* +** Function name: checkReceive +** Descriptions: check if got something +*********************************************************************************************************/ +byte mcp2518fd::checkReceive(void) { + byte res; + res = mcp2518fd_readStatus(); // RXnIF in Bit 1 and 0 + return ((res & MCP_STAT_RXIF_MASK) ? CAN_MSGAVAIL : CAN_NOMSG); +} + +/********************************************************************************************************* +** Function name: checkError +** Descriptions: if something error +*********************************************************************************************************/ +byte mcp2518fd::checkError(void) { + byte eflg = mcp2518fd_readRegister(MCP_EFLG); + return ((eflg & MCP_EFLG_ERRORMASK) ? CAN_CTRLERROR : CAN_OK); +} + + +/********************************************************************************************************* +** Function name: readMsgBufID +** Descriptions: Read message buf and can bus source ID according to status. +** Status has to be read with readRxTxStatus. +*********************************************************************************************************/ +byte mcp2518fd::readMsgBufID(byte status, volatile unsigned long* id, volatile byte* ext, volatile byte* rtrBit, + volatile byte* len, volatile byte* buf) { + byte rc = CAN_NOMSG; + + if (status & MCP_RX0IF) { // Msg in Buffer 0 + mcp2518fd_read_canMsg(MCP_READ_RX0, id, ext, rtrBit, len, buf); + rc = CAN_OK; + } else if (status & MCP_RX1IF) { // Msg in Buffer 1 + mcp2518fd_read_canMsg(MCP_READ_RX1, id, ext, rtrBit, len, buf); + rc = CAN_OK; + } + + if (rc == CAN_OK) { + rtr = *rtrBit; + // dta_len=*len; // not used on any interface function + ext_flg = *ext; + can_id = *id; + } else { + *len = 0; + } + + return rc; +} + +/********************************************************************************************************* +** Function name: trySendMsgBuf +** Descriptions: Try to send message. There is no delays for waiting free buffer. +*********************************************************************************************************/ +byte mcp2518fd::trySendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte* buf, byte iTxBuf) { + byte txbuf_n; + + if (iTxBuf < MCP_N_TXBUFFERS) { // Use specified buffer + if (mcp2518fd_isTXBufFree(&txbuf_n, iTxBuf) != MCP2515_OK) { + return CAN_FAILTX; + } + } else { + if (mcp2518fd_getNextFreeTXBuf(&txbuf_n) != MCP2515_OK) { + return CAN_FAILTX; + } + } + + mcp2518fd_write_canMsg(txbuf_n, id, ext, rtrBit, len, buf); + + return CAN_OK; +} + + +/********************************************************************************************************* +** Function name: sendMsgBuf +** Descriptions: Send message by using buffer read as free from CANINTF status +** Status has to be read with readRxTxStatus and filtered with checkClearTxStatus +*********************************************************************************************************/ +byte mcp2518fd::sendMsgBuf(byte status, unsigned long id, byte ext, byte rtrBit, byte len, volatile const byte* buf) { + byte txbuf_n = statusToTxSidh(status); + + if (txbuf_n == 0) { + return CAN_FAILTX; // Invalid status + } + + mcp2518fd_modifyRegister(MCP_CANINTF, status, 0); // Clear interrupt flag + mcp2518fd_write_canMsg(txbuf_n, id, ext, rtrBit, len, buf); + + return CAN_OK; +} + +/********************************************************************************************************* +** Function name: sendMsgBuf +** Descriptions: send buf +*********************************************************************************************************/ +byte mcp2518fd::sendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte* buf, bool wait_sent) { + return sendMsg(id, ext, rtrBit, len, buf, wait_sent); +} + +/********************************************************************************************************* +** Function name: sendMsgBuf +** Descriptions: send buf +*********************************************************************************************************/ +byte mcp2518fd::sendMsgBuf(unsigned long id, byte ext, byte len, const byte* buf, bool wait_sent) { + return sendMsg(id, ext, 0, len, buf, wait_sent); +} + + +/********************************************************************************************************* +** Function name: clearBufferTransmitIfFlags +** Descriptions: Clear transmit interrupt flags for specific buffer or for all unreserved buffers. +** If interrupt will be used, it is important to clear all flags, when there is no +** more data to be sent. Otherwise IRQ will newer change state. +*********************************************************************************************************/ +void mcp2518fd::clearBufferTransmitIfFlags(byte flags) { + flags &= MCP_TX_INT; + if (flags == 0) { + return; + } + mcp2518fd_modifyRegister(MCP_CANINTF, flags, 0); +} + +/********************************************************************************************************* +** Function name: readRxTxStatus +** Descriptions: Read RX and TX interrupt bits. Function uses status reading, but translates. +** result to MCP_CANINTF. With this you can check status e.g. on interrupt sr +** with one single call to save SPI calls. Then use checkClearRxStatus and +** checkClearTxStatus for testing. +*********************************************************************************************************/ +byte mcp2518fd::readRxTxStatus(void) { + byte ret = (mcp2518fd_readStatus() & (MCP_STAT_TXIF_MASK | MCP_STAT_RXIF_MASK)); + ret = (ret & MCP_STAT_TX0IF ? MCP_TX0IF : 0) | + (ret & MCP_STAT_TX1IF ? MCP_TX1IF : 0) | + (ret & MCP_STAT_TX2IF ? MCP_TX2IF : 0) | + (ret & MCP_STAT_RXIF_MASK); // Rx bits happend to be same on status and MCP_CANINTF + return ret; +} + +/********************************************************************************************************* +** Function name: checkClearRxStatus +** Descriptions: Return first found rx CANINTF status and clears it from parameter. +** Note that this does not affect to chip CANINTF at all. You can use this +** with one single readRxTxStatus call. +*********************************************************************************************************/ +byte mcp2518fd::checkClearRxStatus(byte* status) { + byte ret; + + ret = *status & MCP_RX0IF; *status &= ~MCP_RX0IF; + + if (ret == 0) { + ret = *status & MCP_RX1IF; + *status &= ~MCP_RX1IF; + } + + return ret; +} + +/********************************************************************************************************* +** Function name: checkClearTxStatus +** Descriptions: Return specified buffer of first found tx CANINTF status and clears it from parameter. +** Note that this does not affect to chip CANINTF at all. You can use this +** with one single readRxTxStatus call. +*********************************************************************************************************/ +byte mcp2518fd::checkClearTxStatus(byte* status, byte iTxBuf) { + byte ret; + + if (iTxBuf < MCP_N_TXBUFFERS) { // Clear specific buffer flag + ret = *status & txIfFlag(iTxBuf); *status &= ~txIfFlag(iTxBuf); + } else { + ret = 0; + for (byte i = 0; i < MCP_N_TXBUFFERS - nReservedTx; i++) { + ret = *status & txIfFlag(i); + if (ret != 0) { + *status &= ~txIfFlag(i); + return ret; + } + }; + } + + return ret; +} + +/********************************************************************************************************* +** Function name: mcpPinMode +** Descriptions: switch supported pins between HiZ, interrupt, output or input +*********************************************************************************************************/ +bool mcp2518fd::mcpPinMode(const byte pin, const byte mode) { + byte res; + bool ret = true; + + switch (pin) { + case MCP_RX0BF: + switch (mode) { + case MCP_PIN_HIZ: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B0BFE, 0); + break; + case MCP_PIN_INT: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B0BFM | B0BFE, B0BFM | B0BFE); + break; + case MCP_PIN_OUT: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B0BFM | B0BFE, B0BFE); + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin mode request\r\n"); + #endif + return false; + } + return true; + break; + case MCP_RX1BF: + switch (mode) { + case MCP_PIN_HIZ: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B1BFE, 0); + break; + case MCP_PIN_INT: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B1BFM | B1BFE, B1BFM | B1BFE); + break; + case MCP_PIN_OUT: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B1BFM | B1BFE, B1BFE); + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin mode request\r\n"); + #endif + return false; + } + return true; + break; + case MCP_TX0RTS: + res = mcp2518fd_setCANCTRL_Mode(MODE_CONFIG); + if (res > 0) { + #if DEBUG_EN + Serial.print("Entering Configuration Mode Failure...\r\n"); + #else + delay(10); + #endif + return false; + } + switch (mode) { + case MCP_PIN_INT: + mcp2518fd_modifyRegister(MCP_TXRTSCTRL, B0RTSM, B0RTSM); + break; + case MCP_PIN_IN: + mcp2518fd_modifyRegister(MCP_TXRTSCTRL, B0RTSM, 0); + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin mode request\r\n"); + #endif + ret = false; + } + res = mcp2518fd_setCANCTRL_Mode(mcpMode); + if (res) { + #if DEBUG_EN + Serial.print("`Setting ID Mode Failure...\r\n"); + #else + delay(10); + #endif + return false; + } + return ret; + break; + case MCP_TX1RTS: + res = mcp2518fd_setCANCTRL_Mode(MODE_CONFIG); + if (res > 0) { + #if DEBUG_EN + Serial.print("Entering Configuration Mode Failure...\r\n"); + #else + delay(10); + #endif + return false; + } + switch (mode) { + case MCP_PIN_INT: + mcp2518fd_modifyRegister(MCP_TXRTSCTRL, B1RTSM, B1RTSM); + break; + case MCP_PIN_IN: + mcp2518fd_modifyRegister(MCP_TXRTSCTRL, B1RTSM, 0); + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin mode request\r\n"); + #endif + ret = false; + } + res = mcp2518fd_setCANCTRL_Mode(mcpMode); + if (res) { + #if DEBUG_EN + Serial.print("`Setting ID Mode Failure...\r\n"); + #else + delay(10); + #endif + return false; + } + return ret; + break; + case MCP_TX2RTS: + res = mcp2518fd_setCANCTRL_Mode(MODE_CONFIG); + if (res > 0) { + #if DEBUG_EN + Serial.print("Entering Configuration Mode Failure...\r\n"); + #else + delay(10); + #endif + return false; + } + switch (mode) { + case MCP_PIN_INT: + mcp2518fd_modifyRegister(MCP_TXRTSCTRL, B2RTSM, B2RTSM); + break; + case MCP_PIN_IN: + mcp2518fd_modifyRegister(MCP_TXRTSCTRL, B2RTSM, 0); + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin mode request\r\n"); + #endif + ret = false; + } + res = mcp2518fd_setCANCTRL_Mode(mcpMode); + if (res) { + #if DEBUG_EN + Serial.print("`Setting ID Mode Failure...\r\n"); + #else + delay(10); + #endif + return false; + } + return ret; + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin for mode request\r\n"); + #endif + return false; + } +} + + +/********************************************************************************************************* +** Function name: mcpDigitalWrite +** Descriptions: write HIGH or LOW to RX0BF/RX1BF +*********************************************************************************************************/ +bool mcp2518fd::mcpDigitalWrite(const byte pin, const byte mode) { + switch (pin) { + case MCP_RX0BF: + switch (mode) { + case HIGH: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B0BFS, B0BFS); + return true; + break; + default: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B0BFS, 0); + return true; + } + break; + case MCP_RX1BF: + switch (mode) { + case HIGH: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B1BFS, B1BFS); + return true; + break; + default: + mcp2518fd_modifyRegister(MCP_BFPCTRL, B1BFS, 0); + return true; + } + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin for mcpDigitalWrite\r\n"); + #endif + return false; + } +} + +/********************************************************************************************************* +** Function name: mcpDigitalRead +** Descriptions: read HIGH or LOW from supported pins +*********************************************************************************************************/ +byte mcp2518fd::mcpDigitalRead(const byte pin) { + switch (pin) { + case MCP_RX0BF: + if ((mcp2518fd_readRegister(MCP_BFPCTRL) & B0BFS) > 0) { + return HIGH; + } else { + return LOW; + } + break; + case MCP_RX1BF: + if ((mcp2518fd_readRegister(MCP_BFPCTRL) & B1BFS) > 0) { + return HIGH; + } else { + return LOW; + } + break; + case MCP_TX0RTS: + if ((mcp2518fd_readRegister(MCP_TXRTSCTRL) & B0RTS) > 0) { + return HIGH; + } else { + return LOW; + } + break; + case MCP_TX1RTS: + if ((mcp2518fd_readRegister(MCP_TXRTSCTRL) & B1RTS) > 0) { + return HIGH; + } else { + return LOW; + } + break; + case MCP_TX2RTS: + if ((mcp2518fd_readRegister(MCP_TXRTSCTRL) & B2RTS) > 0) { + return HIGH; + } else { + return LOW; + } + break; + default: + #if DEBUG_EN + Serial.print("Invalid pin for mcpDigitalRead\r\n"); + #endif + return LOW; + } +} + + +/********************************************************************************************************* +** Function name: mcp2515_reset +** Descriptions: reset the device +*********************************************************************************************************/ +void mcp2518fd::mcp2518fd_reset(void) { + #ifdef SPI_HAS_TRANSACTION + SPI_BEGIN(); + #endif + MCP2518fd_SELECT(); + spi_readwrite(MCP_RESET); + MCP2515_UNSELECT(); + #ifdef SPI_HAS_TRANSACTION + SPI_END(); + #endif + delay(10); +} + +/********************************************************************************************************* +** Function name: mcp2518fd_readRegister +** Descriptions: read register +*********************************************************************************************************/ +byte mcp2518fd::mcp2518fd_readRegister(const byte address) { + byte ret; + + #ifdef SPI_HAS_TRANSACTION + SPI_BEGIN(); + #endif + MCP2518fd_SELECT(); + spi_readwrite((MCP_READ << 4) + ((address >> 8) & 0xF)); + spi_readwrite(address & 0xFF); + spi_readwrite(0); + ret = spi_read(); + MCP2518fd_UNSELECT(); + #ifdef SPI_HAS_TRANSACTION + SPI_END(); + #endif + + return ret; +} + +/********************************************************************************************************* +** Function name: mcp2518fd_readRegisterS +** Descriptions: read registerS +*********************************************************************************************************/ +void mcp2518fd::mcp2518fd_readRegisterS(const byte address, byte values[], const byte n) { + byte i; + #ifdef SPI_HAS_TRANSACTION + SPI_BEGIN(); + #endif + MCP2518fd_SELECT(); + spi_readwrite((MCP_READ << 4) + ((address >> 8) & 0xF)); + spi_readwrite(address & 0xFF); + spi_readwrite(0); + // mcp2518 has auto-increment of address-pointer + for (i = 0; i < n && i < CAN_MAX_CHAR_IN_MESSAGE; i++) { + values[i] = spi_read(); + } + MCP2518fd_UNSELECT(); + #ifdef SPI_HAS_TRANSACTION + SPI_END(); + #endif +} + + +/********************************************************************************************************* +** Function name: mcp2518_setRegister +** Descriptions: set register +*********************************************************************************************************/ +void mcp2518fd::mcp2518fd_setRegister(const byte address, const byte value) { + #ifdef SPI_HAS_TRANSACTION + SPI_BEGIN(); + #endif + MCP2518fd_SELECT(); + spi_readwrite((MCP_WRITE << 4) + ((address >> 8) & 0xF)); + spi_readwrite(address & 0xFF); + spi_readwrite(value); + MCP2518fd_UNSELECT(); + #ifdef SPI_HAS_TRANSACTION + SPI_END(); + #endif +} + +/********************************************************************************************************* +** Function name: mcp2518_setRegisterS +** Descriptions: set registerS +*********************************************************************************************************/ +void mcp2518fd::mcp2518fd_setRegisterS(const byte address, const byte values[], const byte n) { + byte i; + #ifdef SPI_HAS_TRANSACTION + SPI_BEGIN(); + #endif + MCP2518fd_SELECT(); + spi_readwrite((MCP_WRITE << 4) + ((address >> 8) & 0xF)); + spi_readwrite(address & 0xFF); + + for (i = 0; i < n; i++) { + spi_readwrite(values[i]); + } + MCP2518fd_UNSELECT(); + #ifdef SPI_HAS_TRANSACTION + SPI_END(); + #endif +} + + +/********************************************************************************************************* +** Function name: mcp2515_init +** Descriptions: init the device +*********************************************************************************************************/ +byte mcp2518fd::mcp2518fd_init(const byte canSpeed, const byte clock) { + + byte res; + // Reset device + mcp2518fd_reset(); + + 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 = 0xda; + 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 = 0x0; + mObj.bF.MIDE = 1; // 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_500K_2M, CAN_SSP_MODE_AUTO, CAN_SYSCLK_40M); + + // 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_TX_EVENT | CAN_RX_EVENT); + + // Select Normal Mode + DRV_CANFDSPI_OperationModeSelect(DRV_CANFDSPI_INDEX_0, CAN_NORMAL_MODE); + + + + + } + return res; + +} \ No newline at end of file diff --git a/mcp2518fd_can.h b/mcp2518fd_can.h new file mode 100644 index 0000000..0a9bc32 --- /dev/null +++ b/mcp2518fd_can.h @@ -0,0 +1,70 @@ +#include "mcp_can.h" +#include "mcp2518fd_canfdspi_api.h" +#include "mcp2518fd_can_dfs.h" +#include "mcp2518fd_can_def.h" + + +typedef struct _CAN_CONFIG { + uint32_t DNetFilterCount : 5; + uint32_t IsoCrcEnable : 1; + uint32_t ProtocolExpectionEventDisable : 1; + uint32_t WakeUpFilterEnable : 1; + uint32_t WakeUpFilterTime : 2; + uint32_t BitRateSwitchDisable : 1; + uint32_t RestrictReTxAttempts : 1; + uint32_t EsiInGatewayMode : 1; + uint32_t SystemErrorToListenOnly : 1; + uint32_t StoreInTEF : 1; + uint32_t TXQEnable : 1; + uint32_t TxBandWidthSharing : 4; +} CAN_CONFIG; + +typedef uint8_t CANFDSPI_MODULE_ID; + + +class mcp2518fd : public MCP_CAN { +public: + + void init_CS(byte _CS); + void enableTxInterrupt(bool enable = true); // enable transmit interrupt + byte begin(byte speedset, const byte clockset = MCP_16MHz); // init can + byte init_Mask(byte num, byte ext, unsigned long ulData); + byte init_Filt(byte num, byte ext, unsigned long ulData); // init filters + void setSleepWakeup(const byte enable); + byte sleep(); + byte wake(); + byte setMode(byte opMode); + byte getMode(); + byte checkReceive(void); + byte checkError(void); + byte readMsgBufID(byte status, volatile unsigned long* id, volatile byte* ext, volatile byte* rtr, volatile byte* len, + volatile byte* buf); + byte trySendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte* buf, byte iTxBuf); + byte sendMsgBuf(byte status, unsigned long id, byte ext, byte rtrBit, byte len, volatile const byte* buf); + byte sendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte* buf, bool wait_sent = true); // send buf + byte sendMsgBuf(unsigned long id, byte ext, byte len, const byte* buf, bool wait_sent = true); // send buf + void clearBufferTransmitIfFlags(byte flags); + byte readRxTxStatus(void); + byte checkClearRxStatus(byte* status); + byte checkClearTxStatus(byte* status, byte iTxBuf); + bool mcpPinMode(const byte pin, const byte mode); + bool mcpDigitalWrite(const byte pin, const byte mode); + byte mcpDigitalRead(const byte pin); + + + void mcp2518fd_reset(void); // reset mcp2515 + byte mcp2518fd_init(const byte canSpeed, const byte clock); // mcp2515init + + byte mcp2518fd_readRegister(const byte address); + void mcp2518fd_readRegisterS(const byte address, + byte values[], + const byte n); + void mcp2518fd_setRegister(const byte address, // set mcp2515's register + const byte value); + + void mcp2518fd_setRegisterS(const byte address, // set mcp2515's registers + const byte values[], + const byte n); + + +}; \ No newline at end of file