Skip to content

Commit

Permalink
2.1.0 : fixed extended frame reception
Browse files Browse the repository at this point in the history
  • Loading branch information
pierremolinaro committed Feb 16, 2022
1 parent 68aa8b8 commit 977c3eb
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@

//——————————————————————————————————————————————————————————————————————————————
// The Pico has two SPI peripherals, SPI and SPI1. Either (or both) can be used.
// The are no default pin assignments to these must be set explicitly.
// At the time of writing (Apr 2021) there is no official Arduino core for the Pico
// The are no default pin assignments so they must be set explicitly.
// Testing was done with Earle Philhower's arduino-pico core:
// https://github.com/earlephilhower/arduino-pico
// There is a small bug in release 1.0.3 so you will require at least 1.0.4
//——————————————————————————————————————————————————————————————————————————————

static const byte MCP2515_SCK = 2 ; // SCK input of MCP2515
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//——————————————————————————————————————————————————————————————————————————————
// ACAN2515 Demo in loopback mode, for the Raspberry Pi Pico
// Demo sketch that uses SPI1
//——————————————————————————————————————————————————————————————————————————————

#ifndef ARDUINO_ARCH_RP2040
#error "Select a Raspberry Pi Pico board"
#endif

//——————————————————————————————————————————————————————————————————————————————

#include <ACAN2515.h>

//——————————————————————————————————————————————————————————————————————————————
// The Pico has two SPI peripherals, SPI and SPI1. Either (or both) can be used.
// The are no default pin assignments so they must be set explicitly.
// Testing was done with Earle Philhower's arduino-pico core:
// https://github.com/earlephilhower/arduino-pico
//——————————————————————————————————————————————————————————————————————————————

static const byte MCP2515_SCK = 14 ; // SCK input of MCP2515 (adapt to your design)
static const byte MCP2515_MOSI = 15 ; // SDI input of MCP2515 (adapt to your design)
static const byte MCP2515_MISO = 12 ; // SDO output of MCP2515 (adapt to your design)

static const byte MCP2515_CS = 13 ; // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 11 ; // INT output of MCP2515 (adapt to your design)

//——————————————————————————————————————————————————————————————————————————————
// MCP2515 Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2515 can (MCP2515_CS, SPI1, MCP2515_INT) ;

//——————————————————————————————————————————————————————————————————————————————
// MCP2515 Quartz: adapt to your design
//——————————————————————————————————————————————————————————————————————————————

static const uint32_t QUARTZ_FREQUENCY = 20UL * 1000UL * 1000UL ; // 20 MHz

//——————————————————————————————————————————————————————————————————————————————
// SETUP
//——————————————————————————————————————————————————————————————————————————————

void setup () {
//--- Switch on builtin led
pinMode (LED_BUILTIN, OUTPUT) ;
digitalWrite (LED_BUILTIN, HIGH) ;
//--- Start serial
Serial.begin (115200) ;
//--- Wait for serial (blink led at 10 Hz during waiting)
while (!Serial) {
delay (50) ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
}
//--- There are no default SPI1 pins so they must be explicitly assigned
SPI1.setSCK (MCP2515_SCK);
SPI1.setTX (MCP2515_MOSI);
SPI1.setRX (MCP2515_MISO);
SPI1.setCS (MCP2515_CS);
//--- Begin SPI1
SPI1.begin () ;
//--- Configure ACAN2515
Serial.println ("Configure ACAN2515") ;
ACAN2515Settings settings (QUARTZ_FREQUENCY, 125UL * 1000UL) ; // CAN bit rate 125 kb/s
settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; // Select loopback mode
const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
if (errorCode == 0) {
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Propagation Segment: ") ;
Serial.println (settings.mPropagationSegment) ;
Serial.print ("Phase segment 1: ") ;
Serial.println (settings.mPhaseSegment1) ;
Serial.print ("Phase segment 2: ") ;
Serial.println (settings.mPhaseSegment2) ;
Serial.print ("SJW: ") ;
Serial.println (settings.mSJW) ;
Serial.print ("Triple Sampling: ") ;
Serial.println (settings.mTripleSampling ? "yes" : "no") ;
Serial.print ("Actual bit rate: ") ;
Serial.print (settings.actualBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact bit rate ? ") ;
Serial.println (settings.exactBitRate () ? "yes" : "no") ;
Serial.print ("Sample point: ") ;
Serial.print (settings.samplePointFromBitStart ()) ;
Serial.println ("%") ;
}else{
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;
}
}

//----------------------------------------------------------------------------------------------------------------------

static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;

//——————————————————————————————————————————————————————————————————————————————

void loop () {
CANMessage frame ;
if (gBlinkLedDate < millis ()) {
gBlinkLedDate += 2000 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
frame.ext = true ;
frame.id = 0x1FFFFFFF ;
frame.len = 8 ;
frame.data [0] = 0x11 ;
frame.data [1] = 0x22 ;
frame.data [2] = 0x33 ;
frame.data [3] = 0x44 ;
frame.data [4] = 0x55 ;
frame.data [5] = 0x66 ;
frame.data [6] = 0x77 ;
frame.data [7] = 0x88 ;
const bool ok = can.tryToSend (frame) ;
if (ok) {
gSentFrameCount += 1 ;
Serial.print ("Sent: ") ;
Serial.println (gSentFrameCount) ;
}else{
Serial.println ("Send failure") ;
}
}
if (can.receive (frame)) {
gReceivedFrameCount ++ ;
Serial.print (" id: ");Serial.println (frame.id,HEX);
Serial.print (" ext: ");Serial.println (frame.ext);
Serial.print (" rtr: ");Serial.println (frame.rtr);
Serial.print (" len: ");Serial.println (frame.len);
Serial.print (" data: ");
for(int x=0;x<frame.len;x++) {
Serial.print (frame.data[x],HEX); Serial.print(":");
}
Serial.println ("");
Serial.print ("Received: ") ;
Serial.println (gReceivedFrameCount) ;
}
}


//——————————————————————————————————————————————————————————————————————————————
Binary file modified extras/acan2515.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ACAN2515
version=2.0.9
version=2.1.0
author=Pierre Molinaro
maintainer=Pierre Molinaro <[email protected]>
sentence=Driver for MCP2515 CAN Controller
Expand Down
22 changes: 17 additions & 5 deletions src/ACAN2515.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ mSPI (inSPI),
mSPISettings (10UL * 1000UL * 1000UL, MSBFIRST, SPI_MODE0), // 10 MHz, UL suffix is required for Arduino Uno
mCS (inCS),
mINT (inINT),
mRolloverEnable (false),
#ifdef ARDUINO_ARCH_ESP32
mISRSemaphore (xSemaphoreCreateCounting (10, 0)),
#endif
Expand Down Expand Up @@ -365,8 +366,10 @@ uint16_t ACAN2515::internalBeginOperation (const ACAN2515Settings & inSettings,
//----------------------------------- Set TXnRTS as inputs
write2515Register (TXRTSCTRL_REGISTER, 0);
//----------------------------------- RXBnCTRL
write2515Register (RXB0CTRL_REGISTER, ((uint8_t) inSettings.mRolloverEnable) << 2) ;
write2515Register (RXB1CTRL_REGISTER, 0x00) ;
mRolloverEnable = inSettings.mRolloverEnable ;
const uint8_t acceptAll = (inAcceptanceFilterCount == 0) ? 0x60 : 0x00 ;
write2515Register (RXB0CTRL_REGISTER, acceptAll | (uint8_t (inSettings.mRolloverEnable) << 2)) ;
write2515Register (RXB1CTRL_REGISTER, acceptAll) ;
//----------------------------------- Setup mask registers
setupMaskRegister (inRXM0, RXM0SIDH_REGISTER) ;
setupMaskRegister (inRXM1, RXM1SIDH_REGISTER) ;
Expand All @@ -382,6 +385,10 @@ uint16_t ACAN2515::internalBeginOperation (const ACAN2515Settings & inSettings,
mCallBackFunctionArray [idx] = inAcceptanceFilters [inAcceptanceFilterCount-1].mCallBack ;
idx += 1 ;
}
// }else{
// for (int i=0 ; i<6 ; i++) {
// setupMaskRegister (ACAN2515Mask (), RXFSIDH_REGISTER [i]) ;
// }
}
//----------------------------------- Set TXBi priorities
write2515Register (TXB0CTRL_REGISTER, inSettings.mTXBPriority & 3) ;
Expand Down Expand Up @@ -521,6 +528,9 @@ uint16_t ACAN2515::internalSetFiltersOnTheFly (const ACAN2515Mask inRXM0,
uint16_t errorCode = setRequestedMode (configurationMode) ;
//--- Setup mask registers
if (errorCode == 0) {
const uint8_t acceptAll = (inAcceptanceFilterCount == 0) ? 0x60 : 0x00 ;
write2515Register (RXB0CTRL_REGISTER, acceptAll | (uint8_t (mRolloverEnable) << 2)) ;
write2515Register (RXB1CTRL_REGISTER, acceptAll) ;
setupMaskRegister (inRXM0, RXM0SIDH_REGISTER) ;
setupMaskRegister (inRXM1, RXM1SIDH_REGISTER) ;
if (inAcceptanceFilterCount > 0) {
Expand Down Expand Up @@ -656,8 +666,8 @@ void ACAN2515::handleRXBInterrupt (void) {
if (received) { // Message in RXB0 and / or RXB1
const bool accessRXB0 = (rxStatus & 0x40) != 0 ;
CANMessage message ;
message.rtr = (rxStatus & 0x08) != 0 ; // Thanks to Arjan-Woltjer for having fixed this bug
message.ext = (rxStatus & 0x10) != 0 ; // Thanks to Arjan-Woltjer for having fixed this bug
// message.rtr = (rxStatus & 0x08) != 0 ; // Thanks to Arjan-Woltjer for having fixed this bug
// message.ext = (rxStatus & 0x10) != 0 ; // Thanks to Arjan-Woltjer for having fixed this bug
//--- Set idx field to matching receive filter
message.idx = rxStatus & 0x07 ;
if (message.idx > 5) {
Expand All @@ -668,10 +678,12 @@ void ACAN2515::handleRXBInterrupt (void) {
mSPI.transfer (accessRXB0 ? READ_FROM_RXB0SIDH_COMMAND : READ_FROM_RXB1SIDH_COMMAND) ;
//--- SIDH
message.id = mSPI.transfer (0) ;
message.id <<= 3 ;
//--- SIDL
const uint32_t sidl = mSPI.transfer (0) ;
message.id <<= 3 ;
message.id |= sidl >> 5 ;
message.rtr = (sidl & 0x10) != 0 ;
message.ext = (sidl & 0x08) != 0 ;
//--- EID8
const uint32_t eid8 = mSPI.transfer (0) ;
if (message.ext) {
Expand Down
7 changes: 4 additions & 3 deletions src/ACAN2515.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

//··································································································

#include <ACANBuffer16.h>
#include <ACAN2515_Buffer16.h>
#include <ACAN2515Settings.h>
#include <MCP2515ReceiveFilters.h>
#include <SPI.h>
Expand Down Expand Up @@ -127,6 +127,7 @@ class ACAN2515 {
private: const SPISettings mSPISettings ;
private: const uint8_t mCS ;
private: const uint8_t mINT ;
private: bool mRolloverEnable ;
#ifdef ARDUINO_ARCH_ESP32
public: SemaphoreHandle_t mISRSemaphore ;
#endif
Expand All @@ -136,7 +137,7 @@ class ACAN2515 {
// Receive buffer
//··································································································

private: ACANBuffer16 mReceiveBuffer ;
private: ACAN2515_Buffer16 mReceiveBuffer ;


//··································································································
Expand Down Expand Up @@ -184,7 +185,7 @@ class ACAN2515 {
// Driver transmit buffer
//··································································································

private: ACANBuffer16 mTransmitBuffer [3] ;
private: ACAN2515_Buffer16 mTransmitBuffer [3] ;
private: bool mTXBIsFree [3] ;

public: inline uint16_t transmitBufferSize (const uint8_t inIndex) const {
Expand Down
Loading

0 comments on commit 977c3eb

Please sign in to comment.