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