Skip to content

Commit cedc78f

Browse files
Added end method (release 2.1.9)
1 parent 6ee34ab commit cedc78f

File tree

7 files changed

+274
-10
lines changed

7 files changed

+274
-10
lines changed

examples/LoopBackIntensiveTestTeensy3x/LoopBackIntensiveTestTeensy3x.ino

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,8 @@ void setup () {
6464
SPI1.begin () ;
6565
//--- Configure ACAN2517FD
6666
Serial.println ("Configure ACAN2517FD") ;
67-
//--- For version >= 2.1.0
67+
//--- Settings
6868
ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, DataBitRateFactor::x1) ;
69-
//--- For version < 2.1.0
70-
// ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, ACAN2517FDSettings::DATA_BITRATE_x1) ;
7169
//--- Select loopback mode
7270
settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack ;
7371
//--- RAM Usage
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
//——————————————————————————————————————————————————————————————————————————————
2+
// ACAN2517FD Demo in loopback mode, using hardware SPI1, with an external interrupt
3+
//——————————————————————————————————————————————————————————————————————————————
4+
// Every 1 000 messages, this sketch calls the end method, deallocates the driver,
5+
// creates a new one, and configures it by calling the begin method.
6+
//——————————————————————————————————————————————————————————————————————————————
7+
8+
#include <ACAN2517FD.h>
9+
10+
//——————————————————————————————————————————————————————————————————————————————
11+
// MCP2517 connections: adapt theses settings to your design
12+
// As hardware SPI is used, you should select pins that support SPI functions.
13+
// This sketch is designed for a Teensy 3.5, using SPI1
14+
// But standard Teensy 3.5 SPI1 pins are not used
15+
// SCK input of MCP2517FD is connected to pin #32
16+
// SDI input of MCP2517FD is connected to pin #0
17+
// SDO output of MCP2517FD is connected to pin #1
18+
// CS input of MCP2517FD should be connected to a digital output port
19+
// INT output of MCP2517FD should be connected to a digital input port, with interrupt capability
20+
//——————————————————————————————————————————————————————————————————————————————
21+
22+
static const byte MCP2517_SCK = 32 ; // SCK input of MCP2517
23+
static const byte MCP2517_SDI = 0 ; // SDI input of MCP2517
24+
static const byte MCP2517_SDO = 1 ; // SDO output of MCP2517
25+
26+
static const byte MCP2517_CS = 31 ; // CS input of MCP2517
27+
static const byte MCP2517_INT = 38 ; // INT output of MCP2517
28+
29+
//——————————————————————————————————————————————————————————————————————————————
30+
// ACAN2517FD Driver object
31+
//——————————————————————————————————————————————————————————————————————————————
32+
33+
ACAN2517FD * can = NULL ;
34+
35+
//——————————————————————————————————————————————————————————————————————————————
36+
// SETUP
37+
//——————————————————————————————————————————————————————————————————————————————
38+
39+
void setup () {
40+
//--- Switch on builtin led
41+
pinMode (LED_BUILTIN, OUTPUT) ;
42+
digitalWrite (LED_BUILTIN, HIGH) ;
43+
//--- Start serial
44+
Serial.begin (38400) ;
45+
//--- Wait for serial (blink led at 10 Hz during waiting)
46+
while (!Serial) {
47+
delay (50) ;
48+
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
49+
}
50+
//--- Define alternate pins for SPI1 (see https://www.pjrc.com/teensy/td_libs_SPI.html)
51+
Serial.print ("Using pin #") ;
52+
Serial.print (MCP2517_SDI) ;
53+
Serial.print (" for MOSI: ") ;
54+
Serial.println (SPI1.pinIsMOSI (MCP2517_SDI) ? "yes" : "NO!!!") ;
55+
Serial.print ("Using pin #") ;
56+
Serial.print (MCP2517_SDO) ;
57+
Serial.print (" for MISO: ") ;
58+
Serial.println (SPI1.pinIsMISO (MCP2517_SDO) ? "yes" : "NO!!!") ;
59+
Serial.print ("Using pin #") ;
60+
Serial.print (MCP2517_SCK) ;
61+
Serial.print (" for SCK: ") ;
62+
Serial.println (SPI1.pinIsSCK (MCP2517_SCK) ? "yes" : "NO!!!") ;
63+
SPI1.setMOSI (MCP2517_SDI) ;
64+
SPI1.setMISO (MCP2517_SDO) ;
65+
SPI1.setSCK (MCP2517_SCK) ;
66+
//----------------------------------- Begin SPI1
67+
SPI1.begin () ;
68+
//--- Configure ACAN2517FD
69+
Serial.println ("Configure ACAN2517FD") ;
70+
//--- Settings
71+
ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, DataBitRateFactor::x1) ;
72+
//--- Select loopback mode
73+
settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack ;
74+
//--- RAM Usage
75+
Serial.print ("MCP2517FD RAM Usage: ") ;
76+
Serial.print (settings.ramUsage ()) ;
77+
Serial.println (" bytes") ;
78+
//--- Begin
79+
can = new ACAN2517FD (MCP2517_CS, SPI1, MCP2517_INT) ;
80+
const uint32_t errorCode = can->begin (settings, [] { can->isr () ; }) ;
81+
if (errorCode == 0) {
82+
Serial.print ("Bit Rate prescaler: ") ;
83+
Serial.println (settings.mBitRatePrescaler) ;
84+
Serial.print ("Arbitration Phase segment 1: ") ;
85+
Serial.println (settings.mArbitrationPhaseSegment1) ;
86+
Serial.print ("Arbitration Phase segment 2: ") ;
87+
Serial.println (settings.mArbitrationPhaseSegment2) ;
88+
Serial.print ("Arbitration SJW:") ;
89+
Serial.println (settings.mArbitrationSJW) ;
90+
Serial.print ("Actual Arbitration Bit Rate: ") ;
91+
Serial.print (settings.actualArbitrationBitRate ()) ;
92+
Serial.println (" bit/s") ;
93+
Serial.print ("Exact Arbitration Bit Rate ? ") ;
94+
Serial.println (settings.exactArbitrationBitRate () ? "yes" : "no") ;
95+
Serial.print ("Arbitration Sample point: ") ;
96+
Serial.print (settings.arbitrationSamplePointFromBitStart ()) ;
97+
Serial.println ("%") ;
98+
Serial.print ("Data Phase segment 1: ") ;
99+
Serial.println (settings.mDataPhaseSegment1) ;
100+
Serial.print ("Data Phase segment 2: ") ;
101+
Serial.println (settings.mDataPhaseSegment2) ;
102+
Serial.print ("Data SJW:") ;
103+
Serial.println (settings.mDataSJW) ;
104+
Serial.print ("Actual Data Bit Rate: ") ;
105+
Serial.print (settings.actualDataBitRate ()) ;
106+
Serial.println (" bit/s") ;
107+
}else{
108+
Serial.print ("Configuration error 0x") ;
109+
Serial.println (errorCode, HEX) ;
110+
}
111+
}
112+
113+
//----------------------------------------------------------------------------------------------------------------------
114+
115+
static uint32_t gBlinkLedDate = 2000 ;
116+
static uint32_t gFrameCount = 0 ;
117+
static uint32_t gDebit = 0 ;
118+
static uint32_t gDebitMax = 0 ;
119+
static CANFDMessage gCurrentFrame ;
120+
static bool gWaitingForReception = false ;
121+
122+
//——————————————————————————————————————————————————————————————————————————————
123+
124+
void loop () {
125+
if (gBlinkLedDate < millis ()) {
126+
gBlinkLedDate += 2000 ;
127+
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
128+
if (gDebitMax < gDebit) {
129+
gDebitMax = gDebit ;
130+
}
131+
Serial.print ("Sent: ") ;
132+
Serial.print (gFrameCount) ;
133+
Serial.print (", ") ;
134+
Serial.print (gDebit) ;
135+
Serial.print (" bytes/s, max ") ;
136+
Serial.print (gDebitMax) ;
137+
Serial.println (" bytes/s") ;
138+
gDebit = 0 ;
139+
}
140+
//--- Send frame ?
141+
if (!gWaitingForReception) {
142+
if ((gFrameCount % 1000) == 0) {
143+
//--- Stop CAN
144+
const bool ok = can->end () ;
145+
delete can ; can = NULL ;
146+
Serial.print ("Reset MCP2517FD, ") ;
147+
Serial.println (ok ? "ok" : "error") ;
148+
//--- Settings
149+
ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, DataBitRateFactor::x1) ;
150+
//--- Select loopback mode
151+
settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack ;
152+
//--- Begin
153+
can = new ACAN2517FD (MCP2517_CS, SPI1, MCP2517_INT) ;
154+
const uint32_t errorCode = can->begin (settings, [] { can->isr () ; }) ;
155+
Serial.print ("Reconfigure MCP2517FD, error ") ;
156+
Serial.println (errorCode) ;
157+
}
158+
gCurrentFrame.ext = (random () & 1) == 0 ;
159+
gCurrentFrame.id = (uint32_t) random () ;
160+
if (gCurrentFrame.ext) {
161+
gCurrentFrame.id &= 0x1FFFFFFF ;
162+
}else{
163+
gCurrentFrame.id &= 0x7FF ;
164+
}
165+
gCurrentFrame.len = (uint8_t) (((uint32_t) random ()) % 65) ;
166+
for (uint8_t i=0 ; i<gCurrentFrame.len ; i++) {
167+
gCurrentFrame.data [i] = (uint8_t) random () ;
168+
}
169+
gCurrentFrame.pad () ;
170+
gDebit += gCurrentFrame.len ;
171+
const bool ok = can->tryToSend (gCurrentFrame) ;
172+
if (ok) {
173+
gFrameCount += 1 ;
174+
gWaitingForReception = true ;
175+
}else{
176+
Serial.println ("Send failure") ;
177+
}
178+
}
179+
//--- Receive message ?
180+
if (gWaitingForReception && can->available ()) {
181+
gWaitingForReception = false ;
182+
CANFDMessage frame ;
183+
can->receive (frame) ;
184+
//--- Check receive frame is identical to sent frame
185+
if (frame.ext != gCurrentFrame.ext) {
186+
Serial.println ("ext error") ;
187+
}
188+
if (frame.id != gCurrentFrame.id) {
189+
Serial.println ("id error") ;
190+
}
191+
if (frame.len != gCurrentFrame.len) {
192+
Serial.println ("length error") ;
193+
}else{
194+
bool ok = true ;
195+
for (uint8_t i=0 ; (i<frame.len) && ok ; i++) {
196+
ok = frame.data [i] == gCurrentFrame.data [i] ;
197+
}
198+
if (!ok) {
199+
Serial.println ("data error") ;
200+
}
201+
}
202+
}
203+
}
204+
205+
//——————————————————————————————————————————————————————————————————————————————

extras/acan2517FD.pdf

3.35 KB
Binary file not shown.

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ACAN2517FD
2-
version=2.1.8
2+
version=2.1.9
33
author=Pierre Molinaro
44
maintainer=Pierre Molinaro <Pierre.Molinaro@pcmolinaro.name>
55
sentence=Driver for MCP2517FD and MCP2518FD CAN Controller (CAN FD mode)

src/ACAN2517FD.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
502502
}
503503
}
504504
#ifdef ARDUINO_ARCH_ESP32
505-
xTaskCreate (myESP32Task, "ACAN2517Handler", 1024, this, 256, NULL) ;
505+
xTaskCreate (myESP32Task, "ACAN2517Handler", 1024, this, 256, &mESP32TaskHandle) ;
506506
#endif
507507
if (mINT != 255) { // 255 means interrupt is not used
508508
#ifdef ARDUINO_ARCH_ESP32
@@ -521,6 +521,61 @@ uint32_t ACAN2517FD::begin (const ACAN2517FDSettings & inSettings,
521521
return errorCode ;
522522
}
523523

524+
//······················································································································
525+
// end method (resets the MCP2517FD, deallocate buffers, and detach interrupt pin)
526+
//······················································································································
527+
528+
bool ACAN2517FD::end (void) {
529+
mSPI.beginTransaction (mSPISettings) ;
530+
#ifdef ARDUINO_ARCH_ESP32
531+
taskDISABLE_INTERRUPTS () ;
532+
#else
533+
noInterrupts () ;
534+
#endif
535+
//--- Detach interrupt pin
536+
if (mINT != 255) { // 255 means interrupt is not used
537+
const int8_t itPin = digitalPinToInterrupt (mINT) ;
538+
detachInterrupt (itPin) ; // Available for ESP32 and Arduino
539+
}
540+
//--- Request configuration mode
541+
bool wait = true ;
542+
bool ok = false ;
543+
const uint32_t deadline = millis () + 2 ; // Wait (2 ms max) until the configuration mode is reached
544+
while (wait) {
545+
writeRegister8Assume_SPI_transaction (CON_REGISTER + 3, 0x04 | (1 << 3)) ; // Request configuration mode, abort all transmissions
546+
const uint8_t actualMode = (readRegister8Assume_SPI_transaction (CON_REGISTER + 2) >> 5) & 0x07 ;
547+
ok = actualMode == 0x04 ;
548+
wait = !ok ;
549+
if (wait && (millis () >= deadline)) {
550+
wait = false ;
551+
}
552+
}
553+
//--- Reset MCP2517FD
554+
assertCS () ;
555+
mSPI.transfer16 (0x00) ; // Reset instruction: 0x0000
556+
deassertCS () ;
557+
//--- ESP32: delete associated task
558+
#ifdef ARDUINO_ARCH_ESP32
559+
if (mESP32TaskHandle != nullptr) {
560+
vTaskDelete (mESP32TaskHandle) ;
561+
mESP32TaskHandle = nullptr ;
562+
}
563+
#endif
564+
//--- Deallocate buffers
565+
delete [] mCallBackFunctionArray ; mCallBackFunctionArray = nullptr ;
566+
mDriverReceiveBuffer.initWithSize (0) ;
567+
mDriverTransmitBuffer.initWithSize (0) ;
568+
//---
569+
#ifdef ARDUINO_ARCH_ESP32
570+
taskENABLE_INTERRUPTS () ;
571+
#else
572+
interrupts () ;
573+
#endif
574+
mSPI.endTransaction () ;
575+
//---
576+
return ok ;
577+
}
578+
524579
//----------------------------------------------------------------------------------------------------------------------
525580
// SEND FRAME
526581
//----------------------------------------------------------------------------------------------------------------------

src/ACAN2517FD.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ class ACAN2517FD {
6363
public: static const uint32_t kISRNotNullAndNoIntPin = uint32_t (1) << 19 ;
6464
public: static const uint32_t kInvalidTDCO = uint32_t (1) << 20 ;
6565

66+
//······················································································································
67+
// end method (resets the MCP2517FD, deallocate buffers, and detach interrupt pin)
68+
// Return true if end method succeeds, and false otherwise
69+
//······················································································································
70+
71+
public: bool end (void) ;
72+
6673
//······················································································································
6774
// Send a message
6875
//······················································································································
@@ -122,6 +129,9 @@ class ACAN2517FD {
122129
// Private properties
123130
//······················································································································
124131

132+
#ifdef ARDUINO_ARCH_ESP32
133+
private: TaskHandle_t mESP32TaskHandle = nullptr ;
134+
#endif
125135
private: SPISettings mSPISettings ;
126136
private: SPIClass & mSPI ;
127137
private: const uint8_t mCS ;

src/ACANFDBuffer.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class ACANFDBuffer {
6060
//······················································································································
6161

6262
public: void initWithSize (const uint32_t inSize) {
63-
mBuffer = new CANFDMessage [inSize] ;
63+
delete [] mBuffer ; mBuffer = new CANFDMessage [inSize] ;
6464
mSize = inSize ;
6565
mReadIndex = 0 ;
6666
mCount = 0 ;
@@ -79,10 +79,6 @@ class ACANFDBuffer {
7979
writeIndex -= mSize ;
8080
}
8181
mBuffer [writeIndex] = inMessage ;
82-
// mWriteIndex += 1 ;
83-
// if (mWriteIndex == mSize) {
84-
// mWriteIndex = 0 ;
85-
// }
8682
mCount += 1 ;
8783
if (mPeakCount < mCount) {
8884
mPeakCount = mCount ;

0 commit comments

Comments
 (0)