diff --git a/examples/LoopBackDemoTeensy3xExtendedFilterTest/LoopBackDemoTeensy3xExtendedFilterTest.ino b/examples/LoopBackDemoTeensy3xExtendedFilterTest/LoopBackDemoTeensy3xExtendedFilterTest.ino new file mode 100644 index 0000000..f28cd9d --- /dev/null +++ b/examples/LoopBackDemoTeensy3xExtendedFilterTest/LoopBackDemoTeensy3xExtendedFilterTest.ino @@ -0,0 +1,123 @@ +//—————————————————————————————————————————————————————————————————————————————— +// ACAN2517FD Filter Demo in loopback mode, using hardware SPI1 +// This sketch tests extended receive filters +//—————————————————————————————————————————————————————————————————————————————— + +#include + +//—————————————————————————————————————————————————————————————————————————————— +// MCP2517 connections: adapt theses settings to your design +// As hardware SPI is used, you should select pins that support SPI functions. +// This sketch is designed for a Teensy 3.5, using SPI1 +// But standard Teensy 3.5 SPI1 pins are not used +// SCK input of MCP2517 is connected to pin #32 +// SDI input of MCP2517 is connected to pin #0 +// SDO output of MCP2517 is connected to pin #1 +// CS input of MCP2517 should be connected to a digital output port +// INT output of MCP2517 should be connected to a digital input port, with interrupt capability +//—————————————————————————————————————————————————————————————————————————————— + +static const byte MCP2517_SCK = 32 ; // SCK input of MCP2517 +static const byte MCP2517_SDI = 0 ; // SDI input of MCP2517 +static const byte MCP2517_SDO = 1 ; // SDO output of MCP2517 + +static const byte MCP2517_CS = 31 ; // CS input of MCP2517 +static const byte MCP2517_INT = 38 ; // INT output of MCP2517 + +//—————————————————————————————————————————————————————————————————————————————— +// MCP2517 Driver object +//—————————————————————————————————————————————————————————————————————————————— + +ACAN2517FD can (MCP2517_CS, SPI1, MCP2517_INT) ; + +//—————————————————————————————————————————————————————————————————————————————— +// SETUP +//—————————————————————————————————————————————————————————————————————————————— + +void setup () { +//--- Switch on builtin led + pinMode (LED_BUILTIN, OUTPUT) ; + digitalWrite (LED_BUILTIN, HIGH) ; +//--- Start serial + Serial.begin (38400) ; +//--- Wait for serial (blink led at 10 Hz during waiting) + while (!Serial) { + delay (50) ; + digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ; + } +//----------------------------------- Define alternate pins for SPI1 (see https://www.pjrc.com/teensy/td_libs_SPI.html) + SPI1.setMOSI (MCP2517_SDI) ; + SPI1.setMISO (MCP2517_SDO) ; + SPI1.setSCK (MCP2517_SCK) ; +//----------------------------------- Begin SPI1 + SPI1.begin () ; +//----------------------------------- Configure ACAN2517FD + Serial.println ("Configure ACAN2517FD") ; + ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, ACAN2517FDSettings::DATA_BITRATE_x4) ; // CAN bit rate 125 kb/s + settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack; // Select loopback mode +//----------------------------------- Append filters + ACAN2517FDFilters filters ; + for (uint32_t i=0 ; i<29 ; i++) { + filters.appendFrameFilter (kExtended, 1 << i, NULL) ; // Filter #i: receive extended frame with identifier 1 << i + } +//----------------------------------- Enter configuration + const uint32_t errorCode = can.begin (settings, [] { can.isr () ; }, filters) ; +//----------------------------------- Config ok ? + if (errorCode != 0) { + Serial.print ("Configuration error 0x") ; + Serial.println (errorCode, HEX) ; + } +} + +//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— + +static unsigned gBlinkLedDate = 0 ; +static uint32_t gPhase = 0 ; +static uint32_t gReceiveFlags = (1 << 29) - 1 ; + +//—————————————————————————————————————————————————————————————————————————————— + +void loop () { + CANFDMessage frame ; + if (gBlinkLedDate < millis ()) { + gBlinkLedDate += 100 ; + digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ; + if (gPhase < 29) { + frame.ext = true ; + frame.id = 1 << gPhase ; + frame.data32 [0] = 1 << gPhase ; + frame.len = 4 ; + const bool ok = can.tryToSend (frame) ; + if (ok) { + gPhase +=1 ; + } + } + } +//--- Dispatch received messages + if (can.receive (frame)) { + bool ok = (frame.len == 4) && frame.ext ; + if (ok) { + ok = frame.data32 [0] == (1U << frame.idx) ; + } + if (!ok) { + Serial.print ("Receive error: idx ") ; + Serial.print (frame.idx) ; + Serial.print (", data ") ; + Serial.print (frame.data32 [0], HEX) ; + Serial.print (", length ") ; + Serial.print (frame.len) ; + Serial.print (", ext ") ; + Serial.println (frame.ext) ; + }else if ((gReceiveFlags & (1 << frame.idx)) == 0) { + Serial.print ("Multiple reception ") ; + Serial.println (frame.idx) ; + }else{ + gReceiveFlags &= ~ (1 << frame.idx) ; + if (gReceiveFlags == 0) { + Serial.println ("Done, all extended frames received") ; + } + } + } +} + +//—————————————————————————————————————————————————————————————————————————————— diff --git a/examples/LoopBackDemoTeensy3xStandardFilterTest/LoopBackDemoTeensy3xStandardFilterTest.ino b/examples/LoopBackDemoTeensy3xStandardFilterTest/LoopBackDemoTeensy3xStandardFilterTest.ino new file mode 100644 index 0000000..56d8363 --- /dev/null +++ b/examples/LoopBackDemoTeensy3xStandardFilterTest/LoopBackDemoTeensy3xStandardFilterTest.ino @@ -0,0 +1,123 @@ +//—————————————————————————————————————————————————————————————————————————————— +// ACAN2517FD Filter Demo in loopback mode, using hardware SPI1 +// This sketch tests standard receive filters +//—————————————————————————————————————————————————————————————————————————————— + +#include + +//—————————————————————————————————————————————————————————————————————————————— +// MCP2517 connections: adapt theses settings to your design +// As hardware SPI is used, you should select pins that support SPI functions. +// This sketch is designed for a Teensy 3.5, using SPI1 +// But standard Teensy 3.5 SPI1 pins are not used +// SCK input of MCP2517 is connected to pin #32 +// SDI input of MCP2517 is connected to pin #0 +// SDO output of MCP2517 is connected to pin #1 +// CS input of MCP2517 should be connected to a digital output port +// INT output of MCP2517 should be connected to a digital input port, with interrupt capability +//—————————————————————————————————————————————————————————————————————————————— + +static const byte MCP2517_SCK = 32 ; // SCK input of MCP2517 +static const byte MCP2517_SDI = 0 ; // SDI input of MCP2517 +static const byte MCP2517_SDO = 1 ; // SDO output of MCP2517 + +static const byte MCP2517_CS = 31 ; // CS input of MCP2517 +static const byte MCP2517_INT = 38 ; // INT output of MCP2517 + +//—————————————————————————————————————————————————————————————————————————————— +// MCP2517 Driver object +//—————————————————————————————————————————————————————————————————————————————— + +ACAN2517FD can (MCP2517_CS, SPI1, MCP2517_INT) ; + +//—————————————————————————————————————————————————————————————————————————————— +// SETUP +//—————————————————————————————————————————————————————————————————————————————— + +void setup () { +//--- Switch on builtin led + pinMode (LED_BUILTIN, OUTPUT) ; + digitalWrite (LED_BUILTIN, HIGH) ; +//--- Start serial + Serial.begin (38400) ; +//--- Wait for serial (blink led at 10 Hz during waiting) + while (!Serial) { + delay (50) ; + digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ; + } +//----------------------------------- Define alternate pins for SPI1 (see https://www.pjrc.com/teensy/td_libs_SPI.html) + SPI1.setMOSI (MCP2517_SDI) ; + SPI1.setMISO (MCP2517_SDO) ; + SPI1.setSCK (MCP2517_SCK) ; +//----------------------------------- Begin SPI1 + SPI1.begin () ; +//----------------------------------- Configure ACAN2517FD + Serial.println ("Configure ACAN2517FD") ; + ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, ACAN2517FDSettings::DATA_BITRATE_x4) ; + settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack; // Select loopback mode +//----------------------------------- Append filters + ACAN2517FDFilters filters ; + for (uint32_t i=0 ; i<11 ; i++) { + filters.appendFrameFilter (kStandard, 1 << i, NULL) ; // Filter #i: receive standard frame with identifier 1 << i + } +//----------------------------------- Enter configuration + const uint32_t errorCode = can.begin (settings, [] { can.isr () ; }, filters) ; +//----------------------------------- Config ok ? + if (errorCode != 0) { + Serial.print ("Configuration error 0x") ; + Serial.println (errorCode, HEX) ; + } +} + +//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— + +static unsigned gBlinkLedDate = 0 ; +static uint32_t gPhase = 0 ; +static uint32_t gReceiveFlags = (1 << 11) - 1 ; + +//—————————————————————————————————————————————————————————————————————————————— + +void loop () { + CANFDMessage frame ; + if (gBlinkLedDate < millis ()) { + gBlinkLedDate += 100 ; + digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ; + if (gPhase < 11) { + frame.ext = false ; + frame.id = 1 << gPhase ; + frame.data32 [0] = 1 << gPhase ; + frame.len = 4 ; + const bool ok = can.tryToSend (frame) ; + if (ok) { + gPhase +=1 ; + } + } + } +//--- Dispatch received messages + if (can.receive (frame)) { + bool ok = (frame.len == 4) && !frame.ext ; + if (ok) { + ok = frame.data32 [0] == (1U << frame.idx) ; + } + if (!ok) { + Serial.print ("Receive error: idx ") ; + Serial.print (frame.idx) ; + Serial.print (", data ") ; + Serial.print (frame.data32 [0], HEX) ; + Serial.print (", length ") ; + Serial.print (frame.len) ; + Serial.print (", ext ") ; + Serial.println (frame.ext) ; + }else if ((gReceiveFlags & (1 << frame.idx)) == 0) { + Serial.print ("Multiple reception ") ; + Serial.println (frame.idx) ; + }else{ + gReceiveFlags &= ~ (1 << frame.idx) ; + if (gReceiveFlags == 0) { + Serial.println ("Done, all standard frames received") ; + } + } + } +} + +//—————————————————————————————————————————————————————————————————————————————— diff --git a/extras/acan2517FD.pdf b/extras/acan2517FD.pdf index fdf37d6..9a602e8 100644 Binary files a/extras/acan2517FD.pdf and b/extras/acan2517FD.pdf differ diff --git a/library.properties b/library.properties index 6c9eb6c..c29e1fc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ACAN2517FD -version=1.0.3 +version=1.0.4 author=Pierre Molinaro maintainer=Pierre Molinaro sentence=Driver for MCP2517FD CAN Controller (CAN FD mode) diff --git a/src/ACAN2517FDFilters.h b/src/ACAN2517FDFilters.h index de3565f..d8096b9 100644 --- a/src/ACAN2517FDFilters.h +++ b/src/ACAN2517FDFilters.h @@ -122,9 +122,15 @@ class ACAN2517FDFilters { mFilterStatus = kStandardIdentifierTooLarge ; mFilterErrorIndex = mFilterCount ; } - //--- Enter filter + //--- Re order bits if extended filter const uint32_t mask = (1 << 30) | ((inFormat == kExtended) ? 0x1FFFFFFF : 0x7FF) ; - const uint32_t acceptance = inIdentifier | ((inFormat == kExtended) ? (1 << 30) : 0) ; + uint32_t acceptance ; + if (inFormat == kExtended) { + acceptance = ((inIdentifier >> 18) & 0x7FF) | ((inIdentifier & 0x3FFFF) << 11) | (1 << 30) ; + }else{ + acceptance = inIdentifier ; + } + //--- Enter filter Filter * f = new Filter (mask, acceptance, inCallBackRoutine) ; if (mFirstFilter == NULL) { mFirstFilter = f ; @@ -166,9 +172,20 @@ class ACAN2517FDFilters { mFilterStatus = kStandardMaskTooLarge ; mFilterErrorIndex = mFilterCount ; } + //--- Re order bits if extended filter + uint32_t mask = 1 << 30 ; + if (inFormat == kExtended) { + mask |= ((inMask >> 18) & 0x7FF) | ((inMask & 0x3FFFF) << 11) ; + }else{ + mask |= inMask ; + } + uint32_t acceptance ; + if (inFormat == kExtended) { + acceptance = ((inAcceptance >> 18) & 0x7FF) | ((inAcceptance & 0x3FFFF) << 11) | (1 << 30) ; + }else{ + acceptance = inAcceptance ; + } //--- Enter filter - const uint32_t mask = (1 << 30) | inMask ; - const uint32_t acceptance = ((inFormat == kExtended) ? (1 << 30) : 0) | inAcceptance ; Filter * f = new Filter (mask, acceptance, inCallBackRoutine) ; if (mFirstFilter == NULL) { mFirstFilter = f ;