-
Notifications
You must be signed in to change notification settings - Fork 10
/
ACAN2517.h
217 lines (162 loc) · 10 KB
/
ACAN2517.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
//----------------------------------------------------------------------------------------
// A CAN driver for MCP2517FD, CAN 2.0B mode
// by Pierre Molinaro
// https://github.com/pierremolinaro/acan2517
//
//----------------------------------------------------------------------------------------
#pragma once
//----------------------------------------------------------------------------------------
#include <ACAN2517Settings.h>
#include <ACAN2517_ACANBuffer.h>
#include <ACAN2517Filters.h>
#include <SPI.h>
//----------------------------------------------------------------------------------------
// ACAN2517 class
//----------------------------------------------------------------------------------------
class ACAN2517 {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// CONSTRUCTOR
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: ACAN2517 (const uint8_t inCS, // CS input of MCP2517FD
SPIClass & inSPI, // Hardware SPI object
const uint8_t inINT) ; // INT output of MCP2517FD
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// begin method (returns 0 if no error)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: uint32_t begin (const ACAN2517Settings & inSettings,
void (* inInterruptServiceRoutine) (void)) ;
public: uint32_t begin (const ACAN2517Settings & inSettings,
void (* inInterruptServiceRoutine) (void),
const ACAN2517Filters & inFilters) ;
//--- Error code returned by begin
public: static const uint32_t kRequestedConfigurationModeTimeOut = uint32_t (1) << 0 ;
public: static const uint32_t kReadBackErrorWith1MHzSPIClock = uint32_t (1) << 1 ;
public: static const uint32_t kTooFarFromDesiredBitRate = uint32_t (1) << 2 ;
public: static const uint32_t kInconsistentBitRateSettings = uint32_t (1) << 3 ;
public: static const uint32_t kINTPinIsNotAnInterrupt = uint32_t (1) << 4 ;
public: static const uint32_t kISRIsNull = uint32_t (1) << 5 ;
public: static const uint32_t kFilterDefinitionError = uint32_t (1) << 6 ;
public: static const uint32_t kMoreThan32Filters = uint32_t (1) << 7 ;
public: static const uint32_t kControllerReceiveFIFOSizeIsZero = uint32_t (1) << 8 ;
public: static const uint32_t kControllerReceiveFIFOSizeGreaterThan32 = uint32_t (1) << 9 ;
public: static const uint32_t kControllerTransmitFIFOSizeIsZero = uint32_t (1) << 10 ;
public: static const uint32_t kControllerTransmitFIFOSizeGreaterThan32 = uint32_t (1) << 11 ;
public: static const uint32_t kControllerRamUsageGreaterThan2048 = uint32_t (1) << 12 ;
public: static const uint32_t kControllerTXQPriorityGreaterThan31 = uint32_t (1) << 13 ;
public: static const uint32_t kControllerTransmitFIFOPriorityGreaterThan31 = uint32_t (1) << 14 ;
public: static const uint32_t kControllerTXQSizeGreaterThan32 = uint32_t (1) << 15 ;
public: static const uint32_t kRequestedModeTimeOut = uint32_t (1) << 16 ;
public: static const uint32_t kX10PLLNotReadyWithin1MS = uint32_t (1) << 17 ;
public: static const uint32_t kReadBackErrorWithFullSpeedSPIClock = uint32_t (1) << 18 ;
public: static const uint32_t kISRNotNullAndNoIntPin = uint32_t (1) << 19 ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send a message
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: bool tryToSend (const CANMessage & inMessage) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Receive a message
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: bool receive (CANMessage & outMessage) ;
public: bool available (void) ;
public: typedef void (*tFilterMatchCallBack) (const uint32_t inFilterIndex) ;
public: bool dispatchReceivedMessage (const tFilterMatchCallBack inFilterMatchCallBack = NULL) ;
//--- Call back function array
private: ACANCallBackRoutine * mCallBackFunctionArray = NULL ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Private properties
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private: SPISettings mSPISettings ;
private: SPIClass & mSPI ;
private: uint8_t mCS ;
private: uint8_t mINT ;
private: bool mUsesTXQ ;
private: bool mHardwareTxFIFOFull ;
private: uint8_t mRequestedMode ;
private: uint8_t mHardwareReceiveBufferOverflowCount ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Receive buffer
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private: ACANBuffer mDriverReceiveBuffer ;
public: uint32_t driverReceiveBufferPeakCount (void) const { return mDriverReceiveBuffer.peakCount () ; }
public: uint8_t hardwareReceiveBufferOverflowCount (void) const { return mHardwareReceiveBufferOverflowCount ; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Transmit buffer
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private: ACANBuffer mDriverTransmitBuffer ;
public: uint32_t driverTransmitBufferSize (void) const { return mDriverTransmitBuffer.size () ; }
public: uint32_t driverTransmitBufferCount (void) const { return mDriverTransmitBuffer.count () ; }
public: uint32_t driverTransmitBufferPeakCount (void) const { return mDriverTransmitBuffer.peakCount () ; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get error counters
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: uint32_t errorCounters (void) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Current MCP2517FD Operation Mode
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: typedef enum : uint8_t {
NormalFD = 0,
Sleep = 1,
InternalLoopBack = 2,
ListenOnly = 3,
Configuration = 4,
ExternalLoopBack = 5,
Normal20B = 6,
RestrictedOperation = 7
} OperationMode ;
public: OperationMode currentOperationMode (void) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Recovery from Restricted Operation Mode
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: bool recoverFromRestrictedOperationMode (void) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Private methods
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private: void writeRegister32Assume_SPI_transaction (const uint16_t inRegisterAddress, const uint32_t inValue) ;
private: uint32_t readRegister32Assume_SPI_transaction (const uint16_t inRegisterAddress) ;
private: void writeRegister8Assume_SPI_transaction (const uint16_t inRegisterAddress, const uint8_t inValue) ;
private: uint8_t readRegister8Assume_SPI_transaction (const uint16_t inRegisterAddress) ;
private: void assertCS (void) ;
private: void deassertCS (void) ;
private: void reset2517FD (void) ;
private: void writeRegister32 (const uint16_t inAddress, const uint32_t inValue) ;
private: uint32_t readRegister32 (const uint16_t inAddress) ;
private: void writeRegister8 (const uint16_t inRegisterAddress, const uint8_t inValue) ;
private: uint8_t readRegister8 (const uint16_t inAddress) ;
private: bool sendViaTXQ (const CANMessage & inMessage) ;
private: bool enterInTransmitBuffer (const CANMessage & inMessage) ;
private: void appendInControllerTxFIFO (const CANMessage & inMessage) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Polling
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: void poll (void) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get diagnostic information (thanks to Flole998 and turmary)
// inIndex == 0 returns BDIAG0_REGISTER
// inIndex != 0 returns BDIAG1_REGISTER
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: uint32_t diagInfos (const int inIndex = 1) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Interrupt service routine
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: void isr (void) ;
public: bool isr_core (void) ;
private: void receiveInterrupt (void) ;
private: void transmitInterrupt (void) ;
#ifdef ARDUINO_ARCH_ESP32
public: SemaphoreHandle_t mISRSemaphore ;
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// GPIO
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public: void gpioSetMode (const uint8_t inPin, const uint8_t inMode) ;
public: void gpioWrite (const uint8_t inPin, const uint8_t inLevel) ;
public: bool gpioRead (const uint8_t inPin) ;
public: void configureGPIO0AsXSTBY (void) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// No copy
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private: ACAN2517 (const ACAN2517 &) = delete ;
private: ACAN2517 & operator = (const ACAN2517 &) = delete ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
} ;
//----------------------------------------------------------------------------------------