mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 09:49:32 +02:00
Merge pull request #1480 from dalathegreat/bugfix/foxess-can-crash
Restore CAN-FD library to v2.1.4
This commit is contained in:
commit
77b1844151
12 changed files with 624 additions and 591 deletions
|
@ -1,20 +1,20 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// A CAN driver for MCP2517FD, CANFD mode
|
||||
// by Pierre Molinaro
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "ACAN2517FD.h"
|
||||
#include "../../system_settings.h" //Contains task priority //Modded by Battery-Emulator
|
||||
#include "../../system_settings.h" //Contains task priority
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static const uint8_t TXBWS = 0 ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Note about ESP32
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// It appears that Arduino ESP32 interrupts are managed in a completely different way from "usual" Arduino:
|
||||
// - SPI.usingInterrupt is not implemented;
|
||||
|
@ -43,7 +43,7 @@ static const uint8_t TXBWS = 0 ;
|
|||
// #endif
|
||||
// mSPI.endTransaction () ;
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
static void myESP32Task (void * pData) {
|
||||
|
@ -55,9 +55,9 @@ static const uint8_t TXBWS = 0 ;
|
|||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ACAN2517FD register addresses
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static const uint16_t CON_REGISTER = 0x000 ;
|
||||
static const uint16_t NBTCFG_REGISTER = 0x004 ;
|
||||
|
@ -68,85 +68,85 @@ static const uint16_t TREC_REGISTER = 0x034 ;
|
|||
static const uint16_t BDIAG0_REGISTER = 0x038 ;
|
||||
static const uint16_t BDIAG1_REGISTER = 0x03C ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// TXQ REGISTERS
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static const uint16_t TXQCON_REGISTER = 0x050 ;
|
||||
static const uint16_t TXQSTA_REGISTER = 0x054 ;
|
||||
static const uint16_t TXQUA_REGISTER = 0x058 ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// INTERRUPT REGISTERS
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static const uint16_t INT_REGISTER = 0x01C ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// FIFO REGISTERS
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint16_t FIFOCON_REGISTER (const uint16_t inFIFOIndex) { // 1 ... 31
|
||||
return 0x05C + 12 * (inFIFOIndex - 1) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint16_t FIFOSTA_REGISTER (const uint16_t inFIFOIndex) { // 1 ... 31
|
||||
return 0x060 + 12 * (inFIFOIndex - 1) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint16_t FIFOUA_REGISTER (const uint16_t inFIFOIndex) { // 1 ... 31
|
||||
return 0x064 + 12 * (inFIFOIndex - 1) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// FILTER REGISTERS
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint16_t FLTCON_REGISTER (const uint16_t inFilterIndex) { // 0 ... 31 (DS20005688B, page 58)
|
||||
return 0x1D0 + inFilterIndex ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint16_t FLTOBJ_REGISTER (const uint16_t inFilterIndex) { // 0 ... 31 (DS20005688B, page 60)
|
||||
return 0x1F0 + 8 * inFilterIndex ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint16_t MASK_REGISTER (const uint16_t inFilterIndex) { // 0 ... 31 (DS20005688B, page 61)
|
||||
return 0x1F4 + 8 * inFilterIndex ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// OSCILLATOR REGISTER
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static const uint16_t OSC_REGISTER = 0xE00 ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// INPUT / OUPUT CONTROL REGISTER
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static const uint16_t IOCON_REGISTER_00_07 = 0xE04 ;
|
||||
static const uint16_t IOCON_REGISTER_08_15 = 0xE05 ;
|
||||
static const uint16_t IOCON_REGISTER_16_23 = 0xE06 ;
|
||||
static const uint16_t IOCON_REGISTER_24_31 = 0xE07 ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RECEIVE FIFO INDEX
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static const uint8_t RECEIVE_FIFO_INDEX = 1 ;
|
||||
static const uint8_t TRANSMIT_FIFO_INDEX = 2 ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// BYTE BUFFER UTILITY FUNCTIONS
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void enterU32InBufferAtIndex (const uint32_t inValue, uint8_t ioBuffer [], const uint8_t inIndex) {
|
||||
ioBuffer [inIndex + 0] = (uint8_t) inValue ;
|
||||
|
@ -155,7 +155,7 @@ static void enterU32InBufferAtIndex (const uint32_t inValue, uint8_t ioBuffer []
|
|||
ioBuffer [inIndex + 3] = (uint8_t) (inValue >> 24) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint32_t u32FromBufferAtIndex (uint8_t ioBuffer [], const uint8_t inIndex) {
|
||||
uint32_t result = (uint32_t) ioBuffer [inIndex + 0] ;
|
||||
|
@ -165,7 +165,7 @@ static uint32_t u32FromBufferAtIndex (uint8_t ioBuffer [], const uint8_t inIndex
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
static uint16_t u16FromBufferAtIndex (uint8_t ioBuffer [], const uint8_t inIndex) {
|
||||
uint16_t result = (uint16_t) ioBuffer [inIndex + 0] ;
|
||||
|
@ -173,7 +173,8 @@ static uint16_t u16FromBufferAtIndex (uint8_t ioBuffer [], const uint8_t inIndex
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static inline void turnOffInterrupts () {
|
||||
#ifndef DISABLEMCP2517FDCOMPAT
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
|
@ -208,6 +209,7 @@ mINT (inINT),
|
|||
mUsesTXQ (false),
|
||||
mHardwareTxFIFOFull (false),
|
||||
mRxInterruptEnabled (true),
|
||||
mHasDataBitRate (false),
|
||||
mTransmitFIFOPayload (0),
|
||||
mTXQBufferPayload (0),
|
||||
mReceiveFIFOPayload (0),
|
||||
|
@ -221,7 +223,7 @@ mDriverTransmitBuffer ()
|
|||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
|
||||
void (* inInterruptServiceRoutine) (void)) {
|
||||
|
@ -232,7 +234,7 @@ uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
|
|||
return begin (inSettings, inInterruptServiceRoutine, filters) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
|
||||
void (* inInterruptServiceRoutine) (void),
|
||||
|
@ -501,14 +503,17 @@ uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
|
|||
// bits 11-8: TSEG2 - 1
|
||||
// bits 7-4: unused
|
||||
// bits 3-0: SJW - 1
|
||||
data = inSettings.mBitRatePrescaler - 1 ;
|
||||
data <<= 8 ;
|
||||
data |= inSettings.mDataPhaseSegment1 - 1 ;
|
||||
data <<= 8 ;
|
||||
data |= inSettings.mDataPhaseSegment2 - 1 ;
|
||||
data <<= 8 ;
|
||||
data |= inSettings.mDataSJW - 1 ;
|
||||
writeRegister32 (DBTCFG_REGISTER, data) ;
|
||||
mHasDataBitRate = inSettings.mDataBitRateFactor != ::DataBitRateFactor::x1 ;
|
||||
if (mHasDataBitRate) {
|
||||
data = inSettings.mBitRatePrescaler - 1 ;
|
||||
data <<= 8 ;
|
||||
data |= inSettings.mDataPhaseSegment1 - 1 ;
|
||||
data <<= 8 ;
|
||||
data |= inSettings.mDataPhaseSegment2 - 1 ;
|
||||
data <<= 8 ;
|
||||
data |= inSettings.mDataSJW - 1 ;
|
||||
writeRegister32 (DBTCFG_REGISTER, data) ;
|
||||
}
|
||||
//----------------------------------- Request mode (CON_REGISTER + 3, DS20005688B, page 24)
|
||||
// bits 7-4: Transmit Bandwith Sharing Bits ---> 0
|
||||
// bit 3: Abort All Pending Transmissions bit --> 0
|
||||
|
@ -526,14 +531,14 @@ uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
|
|||
}
|
||||
}
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
xTaskCreate (myESP32Task, "ACAN2517Handler", 1024, this, TASK_ACAN2517FD_PRIORITY, &mESP32TaskHandle) ; //Modded by Battery-Emulator
|
||||
xTaskCreate (myESP32Task, "ACAN2517Handler", 1024, this, TASK_ACAN2517FD_PRIORITY, &mESP32TaskHandle) ;
|
||||
#endif
|
||||
if (mINT != 255) { // 255 means interrupt is not used
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
attachInterrupt (itPin, inInterruptServiceRoutine, FALLING) ;
|
||||
#else
|
||||
mSPI.usingInterrupt (itPin) ; // usingInterrupt is not implemented in Arduino ESP32
|
||||
attachInterrupt (itPin, inInterruptServiceRoutine, LOW) ; // Thank to Flole998
|
||||
mSPI.usingInterrupt (itPin) ; // usingInterrupt is not implemented in Arduino ESP32
|
||||
#endif
|
||||
}
|
||||
// If you begin() multiple times without constructor,
|
||||
|
@ -545,13 +550,13 @@ uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
|
|||
return errorCode ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// end method (resets the MCP2517FD, deallocate buffers, and detach interrupt pin)
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
bool ACAN2517FD::end (void) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
turnOffInterrupts () ;
|
||||
//--- Detach interrupt pin
|
||||
if (mINT != 255) { // 255 means interrupt is not used
|
||||
const int8_t itPin = digitalPinToInterrupt (mINT) ;
|
||||
|
@ -592,19 +597,15 @@ bool ACAN2517FD::end (void) {
|
|||
return ok ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// SEND FRAME
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FD::tryToSend (const CANFDMessage & inMessage) {
|
||||
bool ok = inMessage.isValid () ;
|
||||
if (ok) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
taskDISABLE_INTERRUPTS () ;
|
||||
#else
|
||||
noInterrupts () ;
|
||||
#endif
|
||||
turnOffInterrupts () ;
|
||||
if (inMessage.idx == 0) {
|
||||
ok = inMessage.len <= mTransmitFIFOPayload ;
|
||||
if (ok) {
|
||||
|
@ -616,13 +617,13 @@ bool ACAN2517FD::tryToSend (const CANFDMessage & inMessage) {
|
|||
ok = sendViaTXQ (inMessage) ;
|
||||
}
|
||||
}
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts();
|
||||
mSPI.endTransaction () ;
|
||||
}
|
||||
return ok ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FD::enterInTransmitBuffer (const CANFDMessage & inMessage) {
|
||||
bool result ;
|
||||
|
@ -644,7 +645,7 @@ bool ACAN2517FD::enterInTransmitBuffer (const CANFDMessage & inMessage) {
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static uint32_t lengthCodeForLength (const uint8_t inLength) {
|
||||
uint32_t result = inLength & 0x0F ;
|
||||
|
@ -660,7 +661,7 @@ static uint32_t lengthCodeForLength (const uint8_t inLength) {
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::appendInControllerTxFIFO (const CANFDMessage & inMessage) {
|
||||
const uint16_t ramAddr = uint16_t (0x400 + readRegister32Assume_SPI_transaction (FIFOUA_REGISTER (TRANSMIT_FIFO_INDEX))) ;
|
||||
|
@ -685,7 +686,9 @@ void ACAN2517FD::appendInControllerTxFIFO (const CANFDMessage & inMessage) {
|
|||
break ;
|
||||
case CANFDMessage::CANFD_WITH_BIT_RATE_SWITCH :
|
||||
flags |= 1 << 7 ; // Set FDF bit
|
||||
flags |= 1 << 6 ; // Set BRS bit
|
||||
if (mHasDataBitRate) {
|
||||
flags |= 1 << 6 ; // Set BRS bit
|
||||
}
|
||||
break ;
|
||||
}
|
||||
//--- Word count
|
||||
|
@ -711,7 +714,7 @@ void ACAN2517FD::appendInControllerTxFIFO (const CANFDMessage & inMessage) {
|
|||
writeRegister8Assume_SPI_transaction (FIFOCON_REGISTER (TRANSMIT_FIFO_INDEX) + 1, data8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FD::sendViaTXQ (const CANFDMessage & inMessage) {
|
||||
bool ok = mUsesTXQ ;
|
||||
|
@ -748,7 +751,9 @@ bool ACAN2517FD::sendViaTXQ (const CANFDMessage & inMessage) {
|
|||
break ;
|
||||
case CANFDMessage::CANFD_WITH_BIT_RATE_SWITCH :
|
||||
flags |= 1 << 7 ; // Set FDF bit
|
||||
flags |= 1 << 6 ; // Set BRS bit
|
||||
if (mHasDataBitRate) {
|
||||
flags |= 1 << 6 ; // Set BRS bit
|
||||
}
|
||||
break ;
|
||||
}
|
||||
//--- Word count
|
||||
|
@ -777,48 +782,41 @@ bool ACAN2517FD::sendViaTXQ (const CANFDMessage & inMessage) {
|
|||
return ok ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RECEIVE FRAME
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FD::available (void) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
turnOffInterrupts () ;
|
||||
const bool hasReceivedMessage = mDriverReceiveBuffer.count () > 0 ;
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts();
|
||||
mSPI.endTransaction () ;
|
||||
return hasReceivedMessage ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FD::receive (CANFDMessage & outMessage) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
const bool hasReceivedMessage = mDriverReceiveBuffer.remove (outMessage) ;
|
||||
//--- If receive interrupt is disabled, enable it (added in release 2.17)
|
||||
if (mINT == 255) { // No interrupt pin
|
||||
mRxInterruptEnabled = true ;
|
||||
isr_poll_core () ; // Perform polling
|
||||
}else if (!mRxInterruptEnabled) {
|
||||
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
taskDISABLE_INTERRUPTS () ;
|
||||
#else
|
||||
noInterrupts () ;
|
||||
#endif
|
||||
|
||||
mRxInterruptEnabled = true ;
|
||||
uint8_t data8 = readRegister8Assume_SPI_transaction (INT_REGISTER + 2) ;
|
||||
data8 |= (1 << 1) ; // Receive FIFO Interrupt Enable
|
||||
writeRegister8Assume_SPI_transaction (INT_REGISTER + 2, data8) ;
|
||||
|
||||
turnOnInterrupts () ;
|
||||
mSPI.endTransaction () ;
|
||||
}
|
||||
turnOnInterrupts();
|
||||
mSPI.endTransaction () ;
|
||||
return hasReceivedMessage ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FD::dispatchReceivedMessage (const tFilterMatchCallBack inFilterMatchCallBack) {
|
||||
CANFDMessage receivedMessage ;
|
||||
|
@ -836,9 +834,9 @@ bool ACAN2517FD::dispatchReceivedMessage (const tFilterMatchCallBack inFilterMat
|
|||
return hasReceived ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// POLLING (ESP32)
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
void ACAN2517FD::poll (void) {
|
||||
|
@ -848,22 +846,22 @@ bool ACAN2517FD::dispatchReceivedMessage (const tFilterMatchCallBack inFilterMat
|
|||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// POLLING (other than ESP32)
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
void ACAN2517FD::poll (void) {
|
||||
noInterrupts () ;
|
||||
turnOffInterrupts () ;
|
||||
isr_poll_core () ;
|
||||
interrupts () ;
|
||||
turnOnInterrupts () ;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// INTERRUPT SERVICE ROUTINE (ESP32)
|
||||
// https://stackoverflow.com/questions/51750377/how-to-disable-interrupt-watchdog-in-esp32-or-increase-isr-time-limit
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
void ACAN2517FD::isr (void) {
|
||||
|
@ -873,9 +871,9 @@ bool ACAN2517FD::dispatchReceivedMessage (const tFilterMatchCallBack inFilterMat
|
|||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// INTERRUPT SERVICE ROUTINE (other than ESP32)
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
void ACAN2517FD::isr (void) {
|
||||
|
@ -883,9 +881,9 @@ bool ACAN2517FD::dispatchReceivedMessage (const tFilterMatchCallBack inFilterMat
|
|||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// INTERRUPT SERVICE ROUTINES (common)
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::isr_poll_core (void) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
|
@ -935,7 +933,7 @@ void ACAN2517FD::isr_poll_core (void) {
|
|||
mSPI.endTransaction () ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::transmitInterrupt (void) { // Generated if hardware transmit FIFO is not full
|
||||
CANFDMessage message ;
|
||||
|
@ -950,7 +948,7 @@ void ACAN2517FD::transmitInterrupt (void) { // Generated if hardware transmit FI
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::receiveInterrupt (void) {
|
||||
const uint16_t ramAddress = uint16_t (0x400 + readRegister32Assume_SPI_transaction (FIFOUA_REGISTER (RECEIVE_FIFO_INDEX))) ;
|
||||
|
@ -1009,9 +1007,9 @@ void ACAN2517FD::receiveInterrupt (void) {
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// MCP2517FD REGISTER ACCESS, SECOND LEVEL FUNCTIONS (HANDLE CS, ASSUME WITHIN SPI TRANSACTION)
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::writeRegister32Assume_SPI_transaction (const uint16_t inRegisterAddress,
|
||||
const uint32_t inValue) {
|
||||
|
@ -1029,7 +1027,7 @@ void ACAN2517FD::writeRegister32Assume_SPI_transaction (const uint16_t inRegiste
|
|||
deassertCS () ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::writeRegister8Assume_SPI_transaction (const uint16_t inRegisterAddress,
|
||||
const uint8_t inValue) {
|
||||
|
@ -1044,7 +1042,7 @@ void ACAN2517FD::writeRegister8Assume_SPI_transaction (const uint16_t inRegister
|
|||
deassertCS () ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FD::readRegister32Assume_SPI_transaction (const uint16_t inRegisterAddress) {
|
||||
//--- Read word register via 6-byte buffer (speed enhancement, thanks to thomasfla)
|
||||
|
@ -1063,7 +1061,7 @@ uint32_t ACAN2517FD::readRegister32Assume_SPI_transaction (const uint16_t inRegi
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint16_t ACAN2517FD::readRegister16Assume_SPI_transaction (const uint16_t inRegisterAddress) {
|
||||
//--- Read half-word register via 4-byte buffer (speed enhancement, thanks to thomasfla)
|
||||
|
@ -1082,7 +1080,7 @@ uint16_t ACAN2517FD::readRegister16Assume_SPI_transaction (const uint16_t inRegi
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint8_t ACAN2517FD::readRegister8Assume_SPI_transaction (const uint16_t inRegisterAddress) {
|
||||
//--- Read byte register via 3-byte buffer (speed enhancement, thanks to thomasfla)
|
||||
|
@ -1096,71 +1094,71 @@ uint8_t ACAN2517FD::readRegister8Assume_SPI_transaction (const uint16_t inRegist
|
|||
return buffer [2] ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// MCP2517FD REGISTER ACCESS, THIRD LEVEL FUNCTIONS (HANDLE CS AND SPI TRANSACTION)
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::writeRegister8 (const uint16_t inRegisterAddress, const uint8_t inValue) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
writeRegister8Assume_SPI_transaction (inRegisterAddress, inValue) ;
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts () ;
|
||||
mSPI.endTransaction () ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint8_t ACAN2517FD::readRegister8 (const uint16_t inRegisterAddress) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
const uint8_t result = readRegister8Assume_SPI_transaction (inRegisterAddress) ;
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts () ;
|
||||
mSPI.endTransaction () ;
|
||||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint16_t ACAN2517FD::readRegister16 (const uint16_t inRegisterAddress) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
const uint16_t result = readRegister16Assume_SPI_transaction (inRegisterAddress) ;
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts () ;
|
||||
mSPI.endTransaction () ;
|
||||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::writeRegister32 (const uint16_t inRegisterAddress, const uint32_t inValue) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
writeRegister32Assume_SPI_transaction (inRegisterAddress, inValue) ;
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts () ;
|
||||
mSPI.endTransaction () ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FD::readRegister32 (const uint16_t inRegisterAddress) {
|
||||
mSPI.beginTransaction (mSPISettings) ;
|
||||
turnOffInterrupts () ;
|
||||
const uint32_t result = readRegister32Assume_SPI_transaction (inRegisterAddress) ;
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts () ;
|
||||
mSPI.endTransaction () ;
|
||||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// Current MCP2517FD Operation Mode
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
ACAN2517FDSettings::OperationMode ACAN2517FD::currentOperationMode (void) {
|
||||
const uint8_t mode = readRegister8 (CON_REGISTER + 2) >> 5 ;
|
||||
return ACAN2517FDSettings::OperationMode (mode) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
bool ACAN2517FD::recoverFromRestrictedOperationMode (void) {
|
||||
bool recoveryDone = false ;
|
||||
|
@ -1184,9 +1182,9 @@ bool ACAN2517FD::recoverFromRestrictedOperationMode (void) {
|
|||
return recoveryDone ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// Set MCP2517FD Operation Mode
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
void ACAN2517FD::setOperationMode (const ACAN2517FDSettings::OperationMode inOperationMode) {
|
||||
// bits 7-4: Transmit Bandwith Sharing Bits ---> 0
|
||||
|
@ -1194,7 +1192,7 @@ void ACAN2517FD::setOperationMode (const ACAN2517FDSettings::OperationMode inOpe
|
|||
writeRegister8 (CON_REGISTER + 3, uint8_t (inOperationMode));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::reset2517FD (void) {
|
||||
mSPI.beginTransaction (mSPISettings) ; // Check RESET is performed with 800 kHz clock
|
||||
|
@ -1202,14 +1200,14 @@ void ACAN2517FD::reset2517FD (void) {
|
|||
assertCS () ;
|
||||
mSPI.transfer16 (0x00) ; // Reset instruction: 0x0000
|
||||
deassertCS () ;
|
||||
turnOnInterrupts () ;
|
||||
turnOnInterrupts () ;
|
||||
mSPI.endTransaction () ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// Sleep Mode to Configuration Mode
|
||||
// (returns true if MCP2517FD was in sleep mode)
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// The device exits Sleep mode due to a dominant edge on RXCAN or by enabling the oscillator (clearing OSC.OSCDIS).
|
||||
// The module will transition automatically to Configuration mode.
|
||||
|
||||
|
@ -1228,21 +1226,21 @@ bool ACAN2517FD::performSleepModeToConfigurationMode (void) {
|
|||
return inSleepMode ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FD::errorCounters (void) {
|
||||
return readRegister32 (TREC_REGISTER) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FD::diagInfos (const int inIndex) { // thanks to Flole998 and turmary
|
||||
return readRegister32 (inIndex ? BDIAG1_REGISTER: BDIAG0_REGISTER) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// GPIO
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::gpioSetMode (const uint8_t inPin, const uint8_t inMode) {
|
||||
if (inPin <= 1) {
|
||||
|
@ -1262,7 +1260,7 @@ void ACAN2517FD::gpioSetMode (const uint8_t inPin, const uint8_t inMode) {
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::gpioWrite (const uint8_t inPin, const uint8_t inLevel) {
|
||||
if (inPin <= 1) {
|
||||
|
@ -1276,14 +1274,14 @@ void ACAN2517FD::gpioWrite (const uint8_t inPin, const uint8_t inLevel) {
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FD::gpioRead (const uint8_t inPin) {
|
||||
const uint8_t value = readRegister8 (IOCON_REGISTER_16_23) ;
|
||||
return (value >> inPin) & 1 ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ACAN2517FD::configureGPIO0AsXSTBY (void) {
|
||||
uint8_t value = readRegister8 (IOCON_REGISTER_00_07) ;
|
||||
|
@ -1291,4 +1289,4 @@ void ACAN2517FD::configureGPIO0AsXSTBY (void) {
|
|||
writeRegister8 (IOCON_REGISTER_00_07, value) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// A CAN driver for MCP2517FD, CANFD mode
|
||||
// by Pierre Molinaro
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "ACAN2517FDSettings.h"
|
||||
#include "ACAN2517FD_ACANFDBuffer.h"
|
||||
#include "ACAN2517FD_CANMessage.h"
|
||||
#include "ACANFDBuffer.h"
|
||||
#include "CANMessage.h"
|
||||
#include "ACAN2517FDFilters.h"
|
||||
#include <SPI.h>
|
||||
|
||||
|
@ -24,23 +25,23 @@
|
|||
//
|
||||
#define DISABLEMCP2517FDCOMPAT
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ACAN2517FD class
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class ACAN2517FD {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// CONSTRUCTOR
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// CONSTRUCTOR
|
||||
//······················································································································
|
||||
|
||||
public: ACAN2517FD (const uint8_t inCS, // CS input of MCP2517FD
|
||||
SPIClass & inSPI, // Hardware SPI object
|
||||
const uint8_t inINT) ; // INT output of MCP2517FD
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// begin method (returns 0 if no error)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// begin method (returns 0 if no error)
|
||||
//······················································································································
|
||||
|
||||
public: uint32_t begin (const ACAN2517FDSettings & inSettings,
|
||||
void (* inInterruptServiceRoutine) (void)) ;
|
||||
|
@ -72,22 +73,22 @@ class ACAN2517FD {
|
|||
public: static const uint32_t kISRNotNullAndNoIntPin = uint32_t (1) << 19 ;
|
||||
public: static const uint32_t kInvalidTDCO = uint32_t (1) << 20 ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// end method (resets the MCP2517FD, deallocate buffers, and detach interrupt pin)
|
||||
// Return true if end method succeeds, and false otherwise
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// end method (resets the MCP2517FD, deallocate buffers, and detach interrupt pin)
|
||||
// Return true if end method succeeds, and false otherwise
|
||||
//······················································································································
|
||||
|
||||
public: bool end (void) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Send a message
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Send a message
|
||||
//······················································································································
|
||||
|
||||
public: bool tryToSend (const CANFDMessage & inMessage) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Receive a message
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Receive a message
|
||||
//······················································································································
|
||||
|
||||
public: bool receive (CANFDMessage & outMessage) ;
|
||||
public: bool available (void) ;
|
||||
|
@ -97,44 +98,44 @@ class ACAN2517FD {
|
|||
//--- Call back function array
|
||||
private: ACANFDCallBackRoutine * mCallBackFunctionArray = NULL ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Get error counters
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Get error counters
|
||||
//······················································································································
|
||||
|
||||
public: uint32_t errorCounters (void) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Get diagnostic information (thanks to Flole998 and turmary)
|
||||
// inIndex == 0 returns BDIAG0_REGISTER
|
||||
// inIndex != 0 returns BDIAG1_REGISTER
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Get diagnostic information (thanks to Flole998 and turmary)
|
||||
// inIndex == 0 returns BDIAG0_REGISTER
|
||||
// inIndex != 0 returns BDIAG1_REGISTER
|
||||
//······················································································································
|
||||
|
||||
public: uint32_t diagInfos (const int inIndex = 1) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Operation Mode
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Operation Mode
|
||||
//······················································································································
|
||||
|
||||
public: ACAN2517FDSettings::OperationMode currentOperationMode (void) ;
|
||||
|
||||
public: void setOperationMode (const ACAN2517FDSettings::OperationMode inMode) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Recovery from Restricted Operation Mode
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Recovery from Restricted Operation Mode
|
||||
//······················································································································
|
||||
|
||||
public: bool recoverFromRestrictedOperationMode (void) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Sleep Mode to Configuration Mode
|
||||
// (returns true if MCP2517FD was in sleep mode)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Sleep Mode to Configuration Mode
|
||||
// (returns true if MCP2517FD was in sleep mode)
|
||||
//······················································································································
|
||||
|
||||
public: bool performSleepModeToConfigurationMode (void) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Private properties
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Private properties
|
||||
//······················································································································
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
private: TaskHandle_t mESP32TaskHandle = nullptr ;
|
||||
|
@ -146,51 +147,40 @@ class ACAN2517FD {
|
|||
private: bool mUsesTXQ ;
|
||||
private: bool mHardwareTxFIFOFull ;
|
||||
private: bool mRxInterruptEnabled ; // Added in 2.1.7
|
||||
private: bool mHasDataBitRate ;
|
||||
private: uint8_t mTransmitFIFOPayload ; // in byte count
|
||||
private: uint8_t mTXQBufferPayload ; // in byte count
|
||||
private: uint8_t mReceiveFIFOPayload ; // in byte count
|
||||
private: uint8_t mTXBWS_RequestedMode ;
|
||||
private: uint8_t mHardwareReceiveBufferOverflowCount ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Receive buffer
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Receive buffer
|
||||
//······················································································································
|
||||
|
||||
private: ACANFDBuffer mDriverReceiveBuffer ;
|
||||
|
||||
public: uint32_t driverReceiveBufferPeakCount (void) const {
|
||||
return mDriverReceiveBuffer.peakCount () ;
|
||||
}
|
||||
public: uint32_t driverReceiveBufferPeakCount (void) const { return mDriverReceiveBuffer.peakCount () ; }
|
||||
|
||||
public: uint8_t hardwareReceiveBufferOverflowCount (void) const {
|
||||
return mHardwareReceiveBufferOverflowCount ;
|
||||
}
|
||||
public: uint8_t hardwareReceiveBufferOverflowCount (void) const { return mHardwareReceiveBufferOverflowCount ; }
|
||||
|
||||
public: void resetHardwareReceiveBufferOverflowCount (void) {
|
||||
mHardwareReceiveBufferOverflowCount = 0 ;
|
||||
}
|
||||
public: void resetHardwareReceiveBufferOverflowCount (void) { mHardwareReceiveBufferOverflowCount = 0 ; }
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Transmit buffer
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Transmit buffer
|
||||
//······················································································································
|
||||
|
||||
private: ACANFDBuffer mDriverTransmitBuffer ;
|
||||
|
||||
public: uint32_t driverTransmitBufferSize (void) const {
|
||||
return mDriverTransmitBuffer.size () ;
|
||||
}
|
||||
public: uint32_t driverTransmitBufferSize (void) const { return mDriverTransmitBuffer.size () ; }
|
||||
|
||||
public: uint32_t driverTransmitBufferCount (void) const {
|
||||
return mDriverTransmitBuffer.count () ;
|
||||
}
|
||||
public: uint32_t driverTransmitBufferCount (void) const { return mDriverTransmitBuffer.count () ; }
|
||||
|
||||
public: uint32_t driverTransmitBufferPeakCount (void) const {
|
||||
return mDriverTransmitBuffer.peakCount () ;
|
||||
}
|
||||
public: uint32_t driverTransmitBufferPeakCount (void) const { return mDriverTransmitBuffer.peakCount () ; }
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Private methods
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Private methods
|
||||
//······················································································································
|
||||
|
||||
private: void writeRegister32Assume_SPI_transaction (const uint16_t inRegisterAddress, const uint32_t inValue) ;
|
||||
private: void writeRegister8Assume_SPI_transaction (const uint16_t inRegisterAddress, const uint8_t inValue) ;
|
||||
|
@ -212,15 +202,15 @@ class ACAN2517FD {
|
|||
private: bool enterInTransmitBuffer (const CANFDMessage & inMessage) ;
|
||||
private: void appendInControllerTxFIFO (const CANFDMessage & inMessage) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Polling
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Polling
|
||||
//······················································································································
|
||||
|
||||
public: void poll (void) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Interrupt service routine
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Interrupt service routine
|
||||
//······················································································································
|
||||
|
||||
public: void isr (void) ;
|
||||
public: void isr_poll_core (void) ;
|
||||
|
@ -230,9 +220,9 @@ class ACAN2517FD {
|
|||
public: SemaphoreHandle_t mISRSemaphore ;
|
||||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Optimized CS handling (thanks to Flole998)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Optimized CS handling (thanks to Flole998)
|
||||
//······················································································································
|
||||
|
||||
#if defined(__AVR__)
|
||||
private: volatile uint8_t *cs_pin_reg;
|
||||
|
@ -303,8 +293,10 @@ class ACAN2517FD {
|
|||
*(cs_pin_reg+8+2) = cs_pin_mask;
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
// private: volatile uint32_t *cs_pin_reg;
|
||||
private: uint32_t cs_pin_mask;
|
||||
private: inline void initCS () {
|
||||
// cs_pin_reg = (volatile uint32_t*)GPO;
|
||||
cs_pin_mask = 1 << mCS;
|
||||
pinMode(mCS, OUTPUT);
|
||||
}
|
||||
|
@ -341,9 +333,9 @@ class ACAN2517FD {
|
|||
}
|
||||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// GPIO
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// GPIO
|
||||
//······················································································································
|
||||
|
||||
public: void gpioSetMode (const uint8_t inPin, const uint8_t inMode) ;
|
||||
|
||||
|
@ -353,16 +345,16 @@ class ACAN2517FD {
|
|||
|
||||
public: void configureGPIO0AsXSTBY (void) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// No copy
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// No copy
|
||||
//······················································································································
|
||||
|
||||
private: ACAN2517FD (const ACAN2517FD &) = delete ;
|
||||
private: ACAN2517FD & operator = (const ACAN2517FD &) = delete ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// An utility class for:
|
||||
// - ACAN2517FD CAN driver for MCP2517FD (CANFD mode)
|
||||
// by Pierre Molinaro
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef ACAN2517FD_FILTERS_CLASS_DEFINED
|
||||
#define ACAN2517FD_FILTERS_CLASS_DEFINED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "ACAN2517FD_CANFDMessage.h"
|
||||
#include "CANFDMessage.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ACAN2517FDFilters class
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class ACAN2517FDFilters {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// EMBEDDED CLASS
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
private: class Filter {
|
||||
public: Filter * mNextFilter ;
|
||||
|
@ -43,9 +43,9 @@ class ACAN2517FDFilters {
|
|||
private: Filter & operator = (const Filter &) ;
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// ENUMERATED TYPE
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: typedef enum {
|
||||
kFiltersOk,
|
||||
|
@ -58,15 +58,15 @@ class ACAN2517FDFilters {
|
|||
kInconsistencyBetweenMaskAndAcceptance
|
||||
} FilterStatus ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// CONSTRUCTOR
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: ACAN2517FDFilters (void) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// DESTRUCTOR
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: ~ ACAN2517FDFilters (void) {
|
||||
while (mFirstFilter != NULL) {
|
||||
|
@ -76,9 +76,9 @@ class ACAN2517FDFilters {
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// RECEIVE FILTERS
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: void appendPassAllFilter (const ACANFDCallBackRoutine inCallBackRoutine) { // Accept any frame
|
||||
Filter * f = new Filter (0, 0, inCallBackRoutine) ;
|
||||
|
@ -91,7 +91,7 @@ class ACAN2517FDFilters {
|
|||
mFilterCount += 1 ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: void appendFormatFilter (const tFrameFormat inFormat, // Accept any identifier
|
||||
const ACANFDCallBackRoutine inCallBackRoutine) {
|
||||
|
@ -107,7 +107,7 @@ class ACAN2517FDFilters {
|
|||
mFilterCount += 1 ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: void appendFrameFilter (const tFrameFormat inFormat,
|
||||
const uint32_t inIdentifier,
|
||||
|
@ -141,7 +141,7 @@ class ACAN2517FDFilters {
|
|||
mFilterCount += 1 ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: void appendFilter (const tFrameFormat inFormat,
|
||||
const uint32_t inMask,
|
||||
|
@ -196,9 +196,9 @@ class ACAN2517FDFilters {
|
|||
mFilterCount += 1 ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// ACCESSORS
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
public: FilterStatus filterStatus (void) const { return mFilterStatus ; }
|
||||
|
||||
|
@ -206,9 +206,9 @@ class ACAN2517FDFilters {
|
|||
|
||||
public: uint8_t filterCount (void) const { return mFilterCount ; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// PRIVATE PROPERTIES
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
private: uint8_t mFilterCount = 0 ;
|
||||
private: Filter * mFirstFilter = NULL ;
|
||||
|
@ -216,23 +216,23 @@ class ACAN2517FDFilters {
|
|||
private: FilterStatus mFilterStatus = kFiltersOk ;
|
||||
private: uint8_t mFilterErrorIndex = 0 ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// NO COPY
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
private: ACAN2517FDFilters (const ACAN2517FDFilters &) = delete ;
|
||||
private: ACAN2517FDFilters & operator = (const ACAN2517FDFilters &) = delete ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
// Friend
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
friend class ACAN2517FD ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//······················································································································
|
||||
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// A CAN driver for MCP2517FD (CANFD mode)
|
||||
// by Pierre Molinaro
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "ACAN2517FDSettings.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma GCC diagnostic error "-Wswitch-enum"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// sysClock
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::sysClock (const Oscillator inOscillator) {
|
||||
uint32_t sysClock = 40UL * 1000 * 1000 ;
|
||||
|
@ -39,9 +39,9 @@ uint32_t ACAN2517FDSettings::sysClock (const Oscillator inOscillator) {
|
|||
return sysClock ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// CONSTRUCTOR
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
ACAN2517FDSettings::ACAN2517FDSettings (const Oscillator inOscillator,
|
||||
const uint32_t inDesiredArbitrationBitRate,
|
||||
|
@ -51,93 +51,148 @@ mOscillator (inOscillator),
|
|||
mSysClock (sysClock (inOscillator)),
|
||||
mDesiredArbitrationBitRate (inDesiredArbitrationBitRate),
|
||||
mDataBitRateFactor (inDataBitRateFactor) {
|
||||
// First compute data bit rate
|
||||
const uint32_t maxDataTQCount = MAX_DATA_PHASE_SEGMENT_1 + MAX_DATA_PHASE_SEGMENT_2 ; // Setting for slowest bit rate
|
||||
const uint32_t desiredDataBitRate = inDesiredArbitrationBitRate * uint8_t (inDataBitRateFactor) ;
|
||||
uint32_t smallestError = UINT32_MAX ;
|
||||
uint32_t bestBRP = MAX_BRP ; // Setting for lowest bit rate
|
||||
uint32_t bestDataTQCount = maxDataTQCount ; // Setting for lowest bit rate
|
||||
uint32_t dataTQCount = 4 ;
|
||||
uint32_t brp = mSysClock / desiredDataBitRate / dataTQCount ;
|
||||
//--- Loop for finding best BRP and best TQCount
|
||||
while ((dataTQCount <= maxDataTQCount) && (brp > 0)) {
|
||||
//--- Compute error using brp
|
||||
if (brp <= MAX_BRP) {
|
||||
const uint32_t error = mSysClock - desiredDataBitRate * dataTQCount * brp ; // error is always >= 0
|
||||
if (error <= smallestError) {
|
||||
smallestError = error ;
|
||||
bestBRP = brp ;
|
||||
bestDataTQCount = dataTQCount ;
|
||||
if (inDataBitRateFactor == DataBitRateFactor::x1) { // Single bit rate
|
||||
const uint32_t maxTQCount = MAX_ARBITRATION_PHASE_SEGMENT_1 + MAX_ARBITRATION_PHASE_SEGMENT_2 + 1 ; // Setting for slowest bit rate
|
||||
uint32_t BRP = MAX_BRP ;
|
||||
uint32_t smallestError = UINT32_MAX ;
|
||||
uint32_t bestBRP = 1 ; // Setting for highest bit rate
|
||||
uint32_t bestTQCount = 4 ; // Setting for highest bit rate
|
||||
uint32_t TQCount = mSysClock / inDesiredArbitrationBitRate / BRP ;
|
||||
//--- Loop for finding best BRP and best TQCount
|
||||
while ((TQCount <= (MAX_ARBITRATION_PHASE_SEGMENT_1 + MAX_ARBITRATION_PHASE_SEGMENT_2 + 1)) && (BRP > 0)) {
|
||||
//--- Compute error using TQCount
|
||||
if ((TQCount >= 4) && (TQCount <= maxTQCount)) {
|
||||
const uint32_t error = mSysClock - inDesiredArbitrationBitRate * TQCount * BRP ; // error is always >= 0
|
||||
if (error <= smallestError) {
|
||||
smallestError = error ;
|
||||
bestBRP = BRP ;
|
||||
bestTQCount = TQCount ;
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- Compute error using brp+1
|
||||
if (brp < MAX_BRP) {
|
||||
const uint32_t error = desiredDataBitRate * dataTQCount * (brp + 1) - mSysClock ; // error is always >= 0
|
||||
if (error <= smallestError) {
|
||||
smallestError = error ;
|
||||
bestBRP = brp + 1 ;
|
||||
bestDataTQCount = dataTQCount ;
|
||||
//--- Compute error using TQCount+1
|
||||
if ((TQCount >= 3) && (TQCount < maxTQCount)) {
|
||||
const uint32_t error = inDesiredArbitrationBitRate * (TQCount + 1) * BRP - mSysClock ; // error is always >= 0
|
||||
if (error <= smallestError) {
|
||||
smallestError = error ;
|
||||
bestBRP = BRP ;
|
||||
bestTQCount = TQCount + 1 ;
|
||||
}
|
||||
}
|
||||
//--- Continue with next value of BRP
|
||||
BRP -- ;
|
||||
TQCount = (BRP == 0) ? (maxTQCount + 1) : (mSysClock / inDesiredArbitrationBitRate / BRP) ;
|
||||
}
|
||||
//--- Continue with next value of BRP
|
||||
dataTQCount += 1 ;
|
||||
brp = mSysClock / desiredDataBitRate / dataTQCount ;
|
||||
//--- Compute PS2 (1 <= PS2 <= 128)
|
||||
uint32_t PS2 = bestTQCount / 5 ; // For sampling point at 80%
|
||||
if (PS2 == 0) {
|
||||
PS2 = 1 ;
|
||||
}else if (PS2 > MAX_ARBITRATION_PHASE_SEGMENT_2) {
|
||||
PS2 = MAX_ARBITRATION_PHASE_SEGMENT_2 ;
|
||||
}
|
||||
//--- Compute PS1 (1 <= PS1 <= 256)
|
||||
uint32_t PS1 = bestTQCount - PS2 - 1 /* Sync Seg */ ;
|
||||
if (PS1 > MAX_ARBITRATION_PHASE_SEGMENT_1) {
|
||||
PS2 += PS1 - MAX_ARBITRATION_PHASE_SEGMENT_1 ;
|
||||
PS1 = MAX_ARBITRATION_PHASE_SEGMENT_1 ;
|
||||
}
|
||||
//---
|
||||
mBitRatePrescaler = (uint16_t) bestBRP ;
|
||||
mArbitrationPhaseSegment1 = (uint16_t) PS1 ;
|
||||
mArbitrationPhaseSegment2 = (uint8_t) PS2 ;
|
||||
mArbitrationSJW = mArbitrationPhaseSegment2 ; // Always 1 <= SJW <= 128, and SJW <= mArbitrationPhaseSegment2
|
||||
//--- Final check of the nominal configuration
|
||||
const uint32_t W = bestTQCount * mDesiredArbitrationBitRate * bestBRP ;
|
||||
const uint64_t diff = (mSysClock > W) ? (mSysClock - W) : (W - mSysClock) ;
|
||||
const uint64_t ppm = (uint64_t) (1000UL * 1000UL) ; // UL suffix is required for Arduino Uno
|
||||
mArbitrationBitRateClosedToDesiredRate = (diff * ppm) <= (((uint64_t) W) * inTolerancePPM) ;
|
||||
}else{ // Dual bit rate, first compute data bit rate
|
||||
const uint32_t maxDataTQCount = MAX_DATA_PHASE_SEGMENT_1 + MAX_DATA_PHASE_SEGMENT_2 ; // Setting for slowest bit rate
|
||||
const uint32_t desiredDataBitRate = inDesiredArbitrationBitRate * uint8_t (inDataBitRateFactor) ;
|
||||
uint32_t smallestError = UINT32_MAX ;
|
||||
uint32_t bestBRP = MAX_BRP ; // Setting for lowest bit rate
|
||||
uint32_t bestDataTQCount = maxDataTQCount ; // Setting for lowest bit rate
|
||||
uint32_t dataTQCount = 4 ;
|
||||
uint32_t brp = mSysClock / desiredDataBitRate / dataTQCount ;
|
||||
//--- Loop for finding best BRP and best TQCount
|
||||
while ((dataTQCount <= maxDataTQCount) && (brp > 0)) {
|
||||
//--- Compute error using brp
|
||||
if (brp <= MAX_BRP) {
|
||||
const uint32_t error = mSysClock - desiredDataBitRate * dataTQCount * brp ; // error is always >= 0
|
||||
if (error <= smallestError) {
|
||||
smallestError = error ;
|
||||
bestBRP = brp ;
|
||||
bestDataTQCount = dataTQCount ;
|
||||
}
|
||||
}
|
||||
//--- Compute error using brp+1
|
||||
if (brp < MAX_BRP) {
|
||||
const uint32_t error = desiredDataBitRate * dataTQCount * (brp + 1) - mSysClock ; // error is always >= 0
|
||||
if (error <= smallestError) {
|
||||
smallestError = error ;
|
||||
bestBRP = brp + 1 ;
|
||||
bestDataTQCount = dataTQCount ;
|
||||
}
|
||||
}
|
||||
//--- Continue with next value of BRP
|
||||
dataTQCount += 1 ;
|
||||
brp = mSysClock / desiredDataBitRate / dataTQCount ;
|
||||
}
|
||||
//--- Compute data PS2 (1 <= PS2 <= 16)
|
||||
uint32_t dataPS2 = bestDataTQCount / 5 ; // For sampling point at 80%
|
||||
if (dataPS2 == 0) {
|
||||
dataPS2 = 1 ;
|
||||
}
|
||||
//--- Compute data PS1 (1 <= PS1 <= 32)
|
||||
uint32_t dataPS1 = bestDataTQCount - dataPS2 - 1 /* Sync Seg */ ;
|
||||
if (dataPS1 > MAX_DATA_PHASE_SEGMENT_1) {
|
||||
dataPS2 += dataPS1 - MAX_DATA_PHASE_SEGMENT_1 ;
|
||||
dataPS1 = MAX_DATA_PHASE_SEGMENT_1 ;
|
||||
}
|
||||
//---
|
||||
if ((mDesiredArbitrationBitRate * uint32_t (inDataBitRateFactor)) <= (1000UL * 1000)) {
|
||||
mTDCO = 0 ;
|
||||
}else{
|
||||
const int TDCO = bestBRP * dataPS1 ; // According to DS20005678D, §3.4.8 Page 20
|
||||
mTDCO = (TDCO > 63) ? 63 : (int8_t) TDCO ;
|
||||
}
|
||||
mDataPhaseSegment1 = (uint8_t) dataPS1 ;
|
||||
mDataPhaseSegment2 = (uint8_t) dataPS2 ;
|
||||
mDataSJW = mDataPhaseSegment2 ;
|
||||
const uint32_t arbitrationTQCount = bestDataTQCount * uint8_t (mDataBitRateFactor) ;
|
||||
//--- Compute arbiration PS2 (1 <= PS2 <= 128)
|
||||
uint32_t arbitrationPS2 = arbitrationTQCount / 5 ; // For sampling point at 80%
|
||||
if (arbitrationPS2 == 0) {
|
||||
arbitrationPS2 = 1 ;
|
||||
}
|
||||
//--- Compute PS1 (1 <= PS1 <= 256)
|
||||
uint32_t arbitrationPS1 = arbitrationTQCount - arbitrationPS2 - 1 /* Sync Seg */ ;
|
||||
if (arbitrationPS1 > MAX_ARBITRATION_PHASE_SEGMENT_1) {
|
||||
arbitrationPS2 += arbitrationPS1 - MAX_ARBITRATION_PHASE_SEGMENT_1 ;
|
||||
arbitrationPS1 = MAX_ARBITRATION_PHASE_SEGMENT_1 ;
|
||||
}
|
||||
//---
|
||||
mBitRatePrescaler = (uint16_t) bestBRP ;
|
||||
mArbitrationPhaseSegment1 = (uint16_t) arbitrationPS1 ;
|
||||
mArbitrationPhaseSegment2 = (uint8_t) arbitrationPS2 ;
|
||||
mArbitrationSJW = mArbitrationPhaseSegment2 ; // Always 1 <= SJW <= 128, and SJW <= mArbitrationPhaseSegment2
|
||||
//--- Final check of the nominal configuration
|
||||
const uint32_t W = arbitrationTQCount * mDesiredArbitrationBitRate * bestBRP ;
|
||||
const uint64_t diff = (mSysClock > W) ? (mSysClock - W) : (W - mSysClock) ;
|
||||
const uint64_t ppm = (uint64_t) (1000UL * 1000UL) ; // UL suffix is required for Arduino Uno
|
||||
mArbitrationBitRateClosedToDesiredRate = (diff * ppm) <= (((uint64_t) W) * inTolerancePPM) ;
|
||||
}
|
||||
//--- Compute data PS2 (1 <= PS2 <= 16)
|
||||
uint32_t dataPS2 = bestDataTQCount / 5 ; // For sampling point at 80%
|
||||
if (dataPS2 == 0) {
|
||||
dataPS2 = 1 ;
|
||||
}
|
||||
//--- Compute data PS1 (1 <= PS1 <= 32)
|
||||
uint32_t dataPS1 = bestDataTQCount - dataPS2 - 1 /* Sync Seg */ ;
|
||||
if (dataPS1 > MAX_DATA_PHASE_SEGMENT_1) {
|
||||
dataPS2 += dataPS1 - MAX_DATA_PHASE_SEGMENT_1 ;
|
||||
dataPS1 = MAX_DATA_PHASE_SEGMENT_1 ;
|
||||
}
|
||||
//---
|
||||
if ((mDesiredArbitrationBitRate * uint32_t (inDataBitRateFactor)) <= (1000UL * 1000)) {
|
||||
mTDCO = 0 ;
|
||||
}else{
|
||||
const int TDCO = bestBRP * dataPS1 ; // According to DS20005678D, §3.4.8 Page 20
|
||||
mTDCO = (TDCO > 63) ? 63 : (int8_t) TDCO ;
|
||||
}
|
||||
mDataPhaseSegment1 = (uint8_t) dataPS1 ;
|
||||
mDataPhaseSegment2 = (uint8_t) dataPS2 ;
|
||||
mDataSJW = mDataPhaseSegment2 ;
|
||||
const uint32_t arbitrationTQCount = bestDataTQCount * uint8_t (mDataBitRateFactor) ;
|
||||
//--- Compute arbitration PS2 (1 <= PS2 <= 128)
|
||||
uint32_t arbitrationPS2 = arbitrationTQCount / 5 ; // For sampling point at 80%
|
||||
if (arbitrationPS2 == 0) {
|
||||
arbitrationPS2 = 1 ;
|
||||
}
|
||||
//--- Compute PS1 (1 <= PS1 <= 256)
|
||||
uint32_t arbitrationPS1 = arbitrationTQCount - arbitrationPS2 - 1 /* Sync Seg */ ;
|
||||
if (arbitrationPS1 > MAX_ARBITRATION_PHASE_SEGMENT_1) {
|
||||
arbitrationPS2 += arbitrationPS1 - MAX_ARBITRATION_PHASE_SEGMENT_1 ;
|
||||
arbitrationPS1 = MAX_ARBITRATION_PHASE_SEGMENT_1 ;
|
||||
}
|
||||
//---
|
||||
mBitRatePrescaler = (uint16_t) bestBRP ;
|
||||
mArbitrationPhaseSegment1 = (uint16_t) arbitrationPS1 ;
|
||||
mArbitrationPhaseSegment2 = (uint8_t) arbitrationPS2 ;
|
||||
mArbitrationSJW = mArbitrationPhaseSegment2 ; // Always 1 <= SJW <= 128, and SJW <= mArbitrationPhaseSegment2
|
||||
//--- Final check of the nominal configuration
|
||||
const uint32_t W = arbitrationTQCount * mDesiredArbitrationBitRate * bestBRP ;
|
||||
const uint64_t diff = (mSysClock > W) ? (mSysClock - W) : (W - mSysClock) ;
|
||||
const uint64_t ppm = (uint64_t) (1000UL * 1000UL) ; // UL suffix is required for Arduino Uno
|
||||
mArbitrationBitRateClosedToDesiredRate = (diff * ppm) <= (((uint64_t) W) * inTolerancePPM) ;
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ACCESSORS
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::actualArbitrationBitRate (void) const {
|
||||
const uint32_t arbitrationTQCount = 1 /* Sync Seg */ + mArbitrationPhaseSegment1 + mArbitrationPhaseSegment2 ;
|
||||
return mSysClock / mBitRatePrescaler / arbitrationTQCount ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::actualDataBitRate (void) const {
|
||||
if (mDataBitRateFactor == DataBitRateFactor::x1) {
|
||||
|
@ -148,14 +203,14 @@ uint32_t ACAN2517FDSettings::actualDataBitRate (void) const {
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FDSettings::exactArbitrationBitRate (void) const {
|
||||
const uint32_t TQCount = 1 /* Sync Seg */ + mArbitrationPhaseSegment1 + mArbitrationPhaseSegment2 ;
|
||||
return mSysClock == (mBitRatePrescaler * mDesiredArbitrationBitRate * TQCount) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FDSettings::exactDataBitRate (void) const {
|
||||
if (mDataBitRateFactor == DataBitRateFactor::x1) {
|
||||
|
@ -166,7 +221,7 @@ bool ACAN2517FDSettings::exactDataBitRate (void) const {
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool ACAN2517FDSettings::dataBitRateIsAMultipleOfArbitrationBitRate (void) const {
|
||||
bool result = mDataBitRateFactor == DataBitRateFactor::x1 ;
|
||||
|
@ -178,7 +233,7 @@ bool ACAN2517FDSettings::dataBitRateIsAMultipleOfArbitrationBitRate (void) const
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::ppmFromDesiredArbitrationBitRate (void) const {
|
||||
const uint32_t TQCount = 1 /* Sync Seg */ + mArbitrationPhaseSegment1 + mArbitrationPhaseSegment2 ;
|
||||
|
@ -188,7 +243,7 @@ uint32_t ACAN2517FDSettings::ppmFromDesiredArbitrationBitRate (void) const {
|
|||
return (uint32_t) ((diff * ppm) / W) ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::arbitrationSamplePointFromBitStart (void) const {
|
||||
const uint32_t nominalTQCount = 1 /* Sync Seg */ + mArbitrationPhaseSegment1 + mArbitrationPhaseSegment2 ;
|
||||
|
@ -197,7 +252,7 @@ uint32_t ACAN2517FDSettings::arbitrationSamplePointFromBitStart (void) const {
|
|||
return (samplePoint * partPerCent) / nominalTQCount ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::dataSamplePointFromBitStart (void) const {
|
||||
const uint32_t nominalTQCount = 1 /* Sync Seg */ + mDataPhaseSegment1 + mDataPhaseSegment2 ;
|
||||
|
@ -206,7 +261,7 @@ uint32_t ACAN2517FDSettings::dataSamplePointFromBitStart (void) const {
|
|||
return (samplePoint * partPerCent) / nominalTQCount ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::CANBitSettingConsistency (void) const {
|
||||
uint32_t errorCode = 0 ; // Means no error
|
||||
|
@ -274,9 +329,9 @@ uint32_t ACAN2517FDSettings::CANBitSettingConsistency (void) const {
|
|||
return errorCode ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RAM USAGE
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::ramUsage (void) const {
|
||||
uint32_t result = 0 ;
|
||||
|
@ -290,11 +345,11 @@ uint32_t ACAN2517FDSettings::ramUsage (void) const {
|
|||
return result ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
uint32_t ACAN2517FDSettings::objectSizeForPayload (const PayloadSize inPayload) {
|
||||
static const uint8_t kPayload [8] = {16, 20, 24, 28, 32, 40, 56, 72} ;
|
||||
return kPayload [inPayload] ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// A CAN driver for MCP2517FD (CANFD mode)
|
||||
// by Pierre Molinaro
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "ACAN2517FD_DataBitRateFactor.h"
|
||||
#include "ACANFD_DataBitRateFactor.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ACAN2517FDSettings class
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class ACAN2517FDSettings {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// ENUMERATED TYPES
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// ENUMERATED TYPES
|
||||
//······················································································································
|
||||
|
||||
public: typedef enum : uint8_t {
|
||||
OSC_4MHz,
|
||||
|
@ -64,9 +64,9 @@ class ACAN2517FDSettings {
|
|||
PAYLOAD_64 = 7
|
||||
} PayloadSize ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Deprecated enumeration (now use DataBitRateFactor declared in ACANFD_DataBitRateFactor.h)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Deprecated enumeration (now use DataBitRateFactor declared in ACANFD_DataBitRateFactor.h)
|
||||
//······················································································································
|
||||
|
||||
public : typedef enum : uint8_t {
|
||||
DATA_BITRATE_x1 = 1,
|
||||
|
@ -81,18 +81,18 @@ class ACAN2517FDSettings {
|
|||
DATA_BITRATE_x10 = 10
|
||||
} DataBitRateFactor_Deprecated ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// CONSTRUCTOR
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// CONSTRUCTOR
|
||||
//······················································································································
|
||||
|
||||
public: ACAN2517FDSettings (const Oscillator inOscillator,
|
||||
const uint32_t inDesiredArbitrationBitRate,
|
||||
const DataBitRateFactor inDataBitRateFactor,
|
||||
const uint32_t inTolerancePPM = 1000) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// DEPRECATED CONSTRUCTOR (for compatibility with version < 2.1.0)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// DEPRECATED CONSTRUCTOR (for compatibility with version < 2.1.0)
|
||||
//······················································································································
|
||||
|
||||
public: ACAN2517FDSettings (const Oscillator inOscillator,
|
||||
const uint32_t inDesiredArbitrationBitRate,
|
||||
|
@ -101,9 +101,9 @@ class ACAN2517FDSettings {
|
|||
ACAN2517FDSettings (inOscillator, inDesiredArbitrationBitRate, DataBitRateFactor (inDataBitRateFactor), inTolerancePPM) {
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// CAN BIT TIMING
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// CAN BIT TIMING
|
||||
//······················································································································
|
||||
|
||||
private: Oscillator mOscillator ;
|
||||
private: uint32_t mSysClock ; // In Hz
|
||||
|
@ -123,44 +123,44 @@ class ACAN2517FDSettings {
|
|||
//--- Transmitter Delay Compensation Offset
|
||||
public: int8_t mTDCO = 0 ; // -64 ... +63
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// MCP2517FD TXCAN pin is Open Drain ?
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// MCP2517FD TXCAN pin is Open Drain ?
|
||||
//······················································································································
|
||||
|
||||
public: bool mTXCANIsOpenDrain = false ; // false --> Push/Pull Output, true --> Open Drain Output
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// MCP2517FD INT pin is Open Drain ?
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// MCP2517FD INT pin is Open Drain ?
|
||||
//······················································································································
|
||||
|
||||
public: bool mINTIsOpenDrain = false ; // false --> Push/Pull Output, true --> Open Drain Output
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// ISO CRC Enable
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// ISO CRC Enable
|
||||
//······················································································································
|
||||
|
||||
// false --> Do NOT include Stuff Bit Count in CRC Field and use CRC Initialization Vector with all zeros
|
||||
// true --> Include Stuff Bit Count in CRC Field and use Non-Zero CRC Initialization Vector according to ISO 11898-1:2015
|
||||
public: bool mISOCRCEnabled = true ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// CLKO pin function (default value is MCP2517FD power on setting)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// CLKO pin function (default value is MCP2517FD power on setting)
|
||||
//······················································································································
|
||||
|
||||
public: CLKOpin mCLKOPin = CLKO_DIVIDED_BY_10 ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Requested mode
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Requested mode
|
||||
//······················································································································
|
||||
|
||||
public: OperationMode mRequestedMode = NormalFD ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// TRANSMIT FIFO
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// TRANSMIT FIFO
|
||||
//······················································································································
|
||||
|
||||
//--- Driver transmit buffer size
|
||||
public: uint16_t mDriverTransmitFIFOSize = 16 ; // >= 0
|
||||
public: uint16_t mDriverTransmitFIFOSize = 22 ; // >= 0
|
||||
|
||||
//--- Controller transmit FIFO size
|
||||
public: uint8_t mControllerTransmitFIFOSize = 1 ; // 1 ... 32
|
||||
|
@ -174,9 +174,9 @@ class ACAN2517FDSettings {
|
|||
//--- Controller transmit FIFO retransmission attempts
|
||||
public: RetransmissionAttempts mControllerTransmitFIFORetransmissionAttempts = UnlimitedNumber ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// TXQ BUFFER
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// TXQ BUFFER
|
||||
//······················································································································
|
||||
|
||||
//--- TXQ buffer size (0 --> TXQ disabled)
|
||||
public: uint8_t mControllerTXQSize = 0 ; // 0 ... 32
|
||||
|
@ -191,9 +191,9 @@ class ACAN2517FDSettings {
|
|||
public: RetransmissionAttempts mControllerTXQBufferRetransmissionAttempts = UnlimitedNumber ;
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// RECEIVE FIFO
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// RECEIVE FIFO
|
||||
//······················································································································
|
||||
|
||||
//--- Driver receive buffer size
|
||||
public: uint16_t mDriverReceiveFIFOSize = 32 ; // > 0
|
||||
|
@ -204,15 +204,15 @@ class ACAN2517FDSettings {
|
|||
//--- Controller receive FIFO size
|
||||
public: uint8_t mControllerReceiveFIFOSize = 27 ; // 1 ... 32
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// SYSCLOCK frequency computation
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// SYSCLOCK frequency computation
|
||||
//······················································································································
|
||||
|
||||
public: static uint32_t sysClock (const Oscillator inOscillator) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Accessors
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Accessors
|
||||
//······················································································································
|
||||
|
||||
public: Oscillator oscillator (void) const { return mOscillator ; }
|
||||
public: uint32_t sysClock (void) const { return mSysClock ; }
|
||||
|
@ -222,61 +222,61 @@ class ACAN2517FDSettings {
|
|||
public: bool exactDataBitRate (void) const ;
|
||||
public: bool dataBitRateIsAMultipleOfArbitrationBitRate (void) const ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// RAM USAGE
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// RAM USAGE
|
||||
//······················································································································
|
||||
|
||||
public: uint32_t ramUsage (void) const ;
|
||||
|
||||
public: static uint32_t objectSizeForPayload (const PayloadSize inPayload) ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Distance between actual bit rate and requested bit rate (in ppm, part-per-million)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Distance between actual bit rate and requested bit rate (in ppm, part-per-million)
|
||||
//······················································································································
|
||||
|
||||
public: uint32_t ppmFromDesiredArbitrationBitRate (void) const ;
|
||||
public: uint32_t ppmFromDesiredDataBitRate (void) const ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Distance of sample point from bit start (in ppc, part-per-cent, denoted by %)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Distance of sample point from bit start (in ppc, part-per-cent, denoted by %)
|
||||
//······················································································································
|
||||
|
||||
public: uint32_t arbitrationSamplePointFromBitStart (void) const ;
|
||||
public: uint32_t dataSamplePointFromBitStart (void) const ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Bit settings are consistent ? (returns 0 if ok)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Bit settings are consistent ? (returns 0 if ok)
|
||||
//······················································································································
|
||||
|
||||
public: uint32_t CANBitSettingConsistency (void) const ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Constants returned by CANBitSettingConsistency
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Constants returned by CANBitSettingConsistency
|
||||
//······················································································································
|
||||
|
||||
public: static const uint32_t kBitRatePrescalerIsZero = uint32_t (1) << 0 ;
|
||||
public: static const uint32_t kBitRatePrescalerIsGreaterThan256 = uint32_t (1) << 1 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment1IsLowerThan2 = uint32_t (1) << 2 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment1IsGreaterThan256 = uint32_t (1) << 3 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment2IsZero = uint32_t (1) << 4 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment2IsGreaterThan128 = uint32_t (1) << 5 ;
|
||||
public: static const uint32_t kArbitrationSJWIsZero = uint32_t (1) << 6 ;
|
||||
public: static const uint32_t kArbitrationSJWIsGreaterThan128 = uint32_t (1) << 7 ;
|
||||
public: static const uint32_t kArbitrationSJWIsGreaterThanPhaseSegment1 = uint32_t (1) << 8 ;
|
||||
public: static const uint32_t kArbitrationSJWIsGreaterThanPhaseSegment2 = uint32_t (1) << 9 ;
|
||||
public: static const uint32_t kArbitrationTQCountNotDivisibleByDataBitRateFactor = uint32_t (1) << 10 ;
|
||||
public: static const uint32_t kDataPhaseSegment1IsLowerThan2 = uint32_t (1) << 11 ;
|
||||
public: static const uint32_t kDataPhaseSegment1IsGreaterThan32 = uint32_t (1) << 12 ;
|
||||
public: static const uint32_t kDataPhaseSegment2IsZero = uint32_t (1) << 13 ;
|
||||
public: static const uint32_t kDataPhaseSegment2IsGreaterThan16 = uint32_t (1) << 14 ;
|
||||
public: static const uint32_t kDataSJWIsZero = uint32_t (1) << 15 ;
|
||||
public: static const uint32_t kDataSJWIsGreaterThan16 = uint32_t (1) << 16 ;
|
||||
public: static const uint32_t kDataSJWIsGreaterThanPhaseSegment1 = uint32_t (1) << 17 ;
|
||||
public: static const uint32_t kDataSJWIsGreaterThanPhaseSegment2 = uint32_t (1) << 18 ;
|
||||
public: static const uint32_t kBitRatePrescalerIsZero = ((uint32_t) 1) << 0 ;
|
||||
public: static const uint32_t kBitRatePrescalerIsGreaterThan256 = ((uint32_t) 1) << 1 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment1IsLowerThan2 = ((uint32_t) 1) << 2 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment1IsGreaterThan256 = ((uint32_t) 1) << 3 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment2IsZero = ((uint32_t) 1) << 4 ;
|
||||
public: static const uint32_t kArbitrationPhaseSegment2IsGreaterThan128 = ((uint32_t) 1) << 5 ;
|
||||
public: static const uint32_t kArbitrationSJWIsZero = ((uint32_t) 1) << 6 ;
|
||||
public: static const uint32_t kArbitrationSJWIsGreaterThan128 = ((uint32_t) 1) << 7 ;
|
||||
public: static const uint32_t kArbitrationSJWIsGreaterThanPhaseSegment1 = ((uint32_t) 1) << 8 ;
|
||||
public: static const uint32_t kArbitrationSJWIsGreaterThanPhaseSegment2 = ((uint32_t) 1) << 9 ;
|
||||
public: static const uint32_t kArbitrationTQCountNotDivisibleByDataBitRateFactor = ((uint32_t) 1) << 10 ;
|
||||
public: static const uint32_t kDataPhaseSegment1IsLowerThan2 = ((uint32_t) 1) << 11 ;
|
||||
public: static const uint32_t kDataPhaseSegment1IsGreaterThan32 = ((uint32_t) 1) << 12 ;
|
||||
public: static const uint32_t kDataPhaseSegment2IsZero = ((uint32_t) 1) << 13 ;
|
||||
public: static const uint32_t kDataPhaseSegment2IsGreaterThan16 = ((uint32_t) 1) << 14 ;
|
||||
public: static const uint32_t kDataSJWIsZero = ((uint32_t) 1) << 15 ;
|
||||
public: static const uint32_t kDataSJWIsGreaterThan16 = ((uint32_t) 1) << 16 ;
|
||||
public: static const uint32_t kDataSJWIsGreaterThanPhaseSegment1 = ((uint32_t) 1) << 17 ;
|
||||
public: static const uint32_t kDataSJWIsGreaterThanPhaseSegment2 = ((uint32_t) 1) << 18 ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Max values
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
// Max values
|
||||
//······················································································································
|
||||
|
||||
public: static const uint16_t MAX_BRP = 256 ;
|
||||
|
||||
|
@ -288,9 +288,9 @@ class ACAN2517FDSettings {
|
|||
public: static const uint8_t MAX_DATA_PHASE_SEGMENT_2 = 16 ;
|
||||
public: static const uint8_t MAX_DATA_SJW = 16 ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//······················································································································
|
||||
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// A CAN driver for MCP2517FD CAN Controller in CANFD mode
|
||||
// by Pierre Molinaro
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef ACANFD_BUFFER_CLASS_DEFINED
|
||||
#define ACANFD_BUFFER_CLASS_DEFINED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "ACAN2517FD_CANFDMessage.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ACANFDBuffer {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Default constructor
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
public: ACANFDBuffer (void) :
|
||||
mBuffer (NULL),
|
||||
mSize (0),
|
||||
mReadIndex (0),
|
||||
mCount (0),
|
||||
mPeakCount (0) {
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Destructor
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
public: ~ ACANFDBuffer (void) {
|
||||
delete [] mBuffer ;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Private properties
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
private: CANFDMessage * mBuffer ;
|
||||
private: uint32_t mSize ;
|
||||
private: uint32_t mReadIndex ;
|
||||
private: uint32_t mCount ;
|
||||
private: uint32_t mPeakCount ; // > mSize if overflow did occur
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Accessors
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
public: inline uint32_t size (void) const { return mSize ; }
|
||||
public: inline uint32_t count (void) const { return mCount ; }
|
||||
public: inline bool isFull (void) const { return mCount == mSize ; } // Added in release 2.17 (thanks to Flole998)
|
||||
public: inline uint32_t peakCount (void) const { return mPeakCount ; }
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// initWithSize
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
public: void initWithSize (const uint32_t inSize) {
|
||||
delete [] mBuffer ; mBuffer = new CANFDMessage [inSize] ;
|
||||
mSize = inSize ;
|
||||
mReadIndex = 0 ;
|
||||
mCount = 0 ;
|
||||
mPeakCount = 0 ;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// append
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
public: bool append (const CANFDMessage & inMessage) {
|
||||
const bool ok = mCount < mSize ;
|
||||
if (ok) {
|
||||
uint32_t writeIndex = mReadIndex + mCount ;
|
||||
if (writeIndex >= mSize) {
|
||||
writeIndex -= mSize ;
|
||||
}
|
||||
mBuffer [writeIndex] = inMessage ;
|
||||
mCount += 1 ;
|
||||
if (mPeakCount < mCount) {
|
||||
mPeakCount = mCount ;
|
||||
}
|
||||
}else{
|
||||
mPeakCount = mSize + 1 ;
|
||||
}
|
||||
return ok ;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Remove
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
public: bool remove (CANFDMessage & outMessage) {
|
||||
const bool ok = mCount > 0 ;
|
||||
if (ok) {
|
||||
outMessage = mBuffer [mReadIndex] ;
|
||||
mCount -= 1 ;
|
||||
mReadIndex += 1 ;
|
||||
if (mReadIndex == mSize) {
|
||||
mReadIndex = 0 ;
|
||||
}
|
||||
}
|
||||
return ok ;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// No copy
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
private: ACANFDBuffer (const ACANFDBuffer &) = delete ;
|
||||
private: ACANFDBuffer & operator = (const ACANFDBuffer &) = delete ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
119
Software/src/lib/pierremolinaro-ACAN2517FD/ACANFDBuffer.h
Normal file
119
Software/src/lib/pierremolinaro-ACAN2517FD/ACANFDBuffer.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// A CAN driver for MCP2517FD CAN Controller in CANFD mode
|
||||
// by Pierre Molinaro
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef ACANFD_BUFFER_CLASS_DEFINED
|
||||
#define ACANFD_BUFFER_CLASS_DEFINED
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "CANFDMessage.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class ACANFDBuffer {
|
||||
|
||||
//······················································································································
|
||||
// Default constructor
|
||||
//······················································································································
|
||||
|
||||
public: ACANFDBuffer (void) :
|
||||
mBuffer (NULL),
|
||||
mSize (0),
|
||||
mReadIndex (0),
|
||||
mCount (0),
|
||||
mPeakCount (0) {
|
||||
}
|
||||
|
||||
//······················································································································
|
||||
// Destructor
|
||||
//······················································································································
|
||||
|
||||
public: ~ ACANFDBuffer (void) {
|
||||
delete [] mBuffer ;
|
||||
}
|
||||
|
||||
//······················································································································
|
||||
// Private properties
|
||||
//······················································································································
|
||||
|
||||
private: CANFDMessage * mBuffer ;
|
||||
private: uint32_t mSize ;
|
||||
private: uint32_t mReadIndex ;
|
||||
private: uint32_t mCount ;
|
||||
private: uint32_t mPeakCount ; // > mSize if overflow did occur
|
||||
|
||||
//······················································································································
|
||||
// Accessors
|
||||
//······················································································································
|
||||
|
||||
public: inline uint32_t size (void) const { return mSize ; }
|
||||
public: inline uint32_t count (void) const { return mCount ; }
|
||||
public: inline bool isFull (void) const { return mCount == mSize ; } // Added in release 2.17 (thanks to Flole998)
|
||||
public: inline uint32_t peakCount (void) const { return mPeakCount ; }
|
||||
|
||||
//······················································································································
|
||||
// initWithSize
|
||||
//······················································································································
|
||||
|
||||
public: void initWithSize (const uint32_t inSize) {
|
||||
delete [] mBuffer ; mBuffer = new CANFDMessage [inSize] ;
|
||||
mSize = inSize ;
|
||||
mReadIndex = 0 ;
|
||||
mCount = 0 ;
|
||||
mPeakCount = 0 ;
|
||||
}
|
||||
|
||||
//······················································································································
|
||||
// append
|
||||
//······················································································································
|
||||
|
||||
public: bool append (const CANFDMessage & inMessage) {
|
||||
const bool ok = mCount < mSize ;
|
||||
if (ok) {
|
||||
uint32_t writeIndex = mReadIndex + mCount ;
|
||||
if (writeIndex >= mSize) {
|
||||
writeIndex -= mSize ;
|
||||
}
|
||||
mBuffer [writeIndex] = inMessage ;
|
||||
mCount += 1 ;
|
||||
if (mPeakCount < mCount) {
|
||||
mPeakCount = mCount ;
|
||||
}
|
||||
}else{
|
||||
mPeakCount = mSize + 1 ;
|
||||
}
|
||||
return ok ;
|
||||
}
|
||||
|
||||
//······················································································································
|
||||
// Remove
|
||||
//······················································································································
|
||||
|
||||
public: bool remove (CANFDMessage & outMessage) {
|
||||
const bool ok = mCount > 0 ;
|
||||
if (ok) {
|
||||
outMessage = mBuffer [mReadIndex] ;
|
||||
mCount -= 1 ;
|
||||
mReadIndex += 1 ;
|
||||
if (mReadIndex == mSize) {
|
||||
mReadIndex = 0 ;
|
||||
}
|
||||
}
|
||||
return ok ;
|
||||
}
|
||||
|
||||
//······················································································································
|
||||
// No copy
|
||||
//······················································································································
|
||||
|
||||
private: ACANFDBuffer (const ACANFDBuffer &) = delete ;
|
||||
private: ACANFDBuffer & operator = (const ACANFDBuffer &) = delete ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// A CANFD driver
|
||||
// by Pierre Molinaro
|
||||
|
||||
|
@ -6,16 +6,16 @@
|
|||
// https://github.com/pierremolinaro/ACAN_T4
|
||||
// https://github.com/pierremolinaro/ACAN2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef ACANFD_DATA_BIT_RATE_FACTOR_DEFINED
|
||||
#define ACANFD_DATA_BIT_RATE_FACTOR_DEFINED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
enum class DataBitRateFactor : uint8_t {
|
||||
x1 = 1,
|
||||
|
@ -30,6 +30,6 @@ enum class DataBitRateFactor : uint8_t {
|
|||
x10 = 10
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
|
@ -1,21 +1,21 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// Generic CANFD Message
|
||||
// by Pierre Molinaro
|
||||
//
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef GENERIC_CANFD_MESSAGE_DEFINED
|
||||
#define GENERIC_CANFD_MESSAGE_DEFINED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ACAN2517FD_CANMessage.h"
|
||||
#include "CANMessage.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// CANFDMessage class
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// Note that "len" field contains the actual length, not its encoding in CANFD frames
|
||||
// Valid values are: 0, 1, ..., 8, 12, 16, 20, 24, 32, 48, 64.
|
||||
// Having other values is an error that prevents frame to be sent by tryToSend
|
||||
|
@ -23,9 +23,9 @@
|
|||
|
||||
class CANFDMessage {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Constructors
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//·············································································
|
||||
// Constructors
|
||||
//·············································································
|
||||
|
||||
public : CANFDMessage (void) :
|
||||
id (0), // Frame identifier
|
||||
|
@ -36,7 +36,7 @@ class CANFDMessage {
|
|||
data () {
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//·············································································
|
||||
|
||||
public : CANFDMessage (const CANMessage & inMessage) :
|
||||
id (inMessage.id), // Frame identifier
|
||||
|
@ -48,9 +48,9 @@ class CANFDMessage {
|
|||
data64 [0] = inMessage.data64 ;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Enumerated Type
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//·············································································
|
||||
// Enumerated Type
|
||||
//·············································································
|
||||
|
||||
public: typedef enum : uint8_t {
|
||||
CAN_REMOTE,
|
||||
|
@ -59,9 +59,9 @@ class CANFDMessage {
|
|||
CANFD_WITH_BIT_RATE_SWITCH
|
||||
} Type ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Properties
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//·············································································
|
||||
// Properties
|
||||
//·············································································
|
||||
|
||||
public : uint32_t id ; // Frame identifier
|
||||
public : bool ext ; // false -> base frame, true -> extended frame
|
||||
|
@ -80,9 +80,9 @@ class CANFDMessage {
|
|||
uint8_t data [64] ;
|
||||
} ;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Methods
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//·············································································
|
||||
// Methods
|
||||
//·············································································
|
||||
|
||||
public: void pad (void) {
|
||||
uint8_t paddedLength = len ;
|
||||
|
@ -107,7 +107,7 @@ class CANFDMessage {
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//·············································································
|
||||
|
||||
public: bool isValid (void) const {
|
||||
if ((type == CAN_REMOTE) || (type == CAN_DATA)) { // Remote frame
|
||||
|
@ -121,14 +121,14 @@ class CANFDMessage {
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//·············································································
|
||||
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef void (*ACANFDCallBackRoutine) (const CANFDMessage & inMessage) ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Generic CAN Message
|
||||
// by Pierre Molinaro
|
||||
//
|
||||
|
@ -8,16 +8,16 @@
|
|||
// https://github.com/pierremolinaro/acan2517
|
||||
// https://github.com/pierremolinaro/acan2517FD
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef GENERIC_CAN_MESSAGE_DEFINED
|
||||
#define GENERIC_CAN_MESSAGE_DEFINED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class CANMessage {
|
||||
public : uint32_t id = 0 ; // Frame identifier
|
||||
|
@ -38,12 +38,12 @@ class CANMessage {
|
|||
} ;
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef enum {kStandard, kExtended} tFrameFormat ;
|
||||
typedef enum {kData, kRemote} tFrameKind ;
|
||||
typedef void (*ACANCallBackRoutine) (const CANMessage & inMessage) ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
0
Software/src/lib/pierremolinaro-ACAN2517FD/README.md
Executable file → Normal file
0
Software/src/lib/pierremolinaro-ACAN2517FD/README.md
Executable file → Normal file
|
@ -1,9 +0,0 @@
|
|||
name=ACAN2517FD
|
||||
version=2.1.16
|
||||
author=Pierre Molinaro
|
||||
maintainer=Pierre Molinaro <Pierre.Molinaro@pcmolinaro.name>
|
||||
sentence=Driver for MCP2517FD and MCP2518FD CAN Controller (CAN FD mode)
|
||||
paragraph=This library is an Arduino CAN network driver for the MCP2517FD, the MCP2518FD and the MCP251863 CAN Controller, in CAN FD mode. Compatible with ACAN, ACAN2515, ACAN2517 libraries, with ACAN_T4 library from version 2.1.0. Default configuration sends and receives any frame – no default filter to provide. Reception filters (up to 32) can be easily defined. Compatible with ESP32 from version 1.1.0.
|
||||
category=Communication
|
||||
url=https://github.com/pierremolinaro/acan2517FD
|
||||
architectures=*
|
Loading…
Add table
Add a link
Reference in a new issue