| LIN_slave_portable_Arduino 1.4 Arduino library for Local Interconnect Network slave node emulation

Loading...
Searching...
No Matches
LIN_slave_Base.h
Go to the documentation of this file.
1
10/*-----------------------------------------------------------------------------
11 MODULE DEFINITION FOR MULTIPLE INCLUSION
12-----------------------------------------------------------------------------*/
13#ifndef _LIN_SLAVE_BASE_H_
14#define _LIN_SLAVE_BASE_H_
15
16
17/*-----------------------------------------------------------------------------
18 GLOBAL DEFINES
19-----------------------------------------------------------------------------*/
20
21// misc parameters
22#define LIN_SLAVE_BUFLEN_NAME 30
23#define LIN_SLAVE_LIN_PORT_TIMEOUT 3000
24
25// required for CI test environment. Call arduino-cli with "-DINCLUDE_NEOHWSERIAL"
26#if defined(INCLUDE_NEOHWSERIAL)
27 #include <NeoHWSerial.h>
28#endif
29
30// optional LIN debug output @ 115.2kBaud. Comment out for none. When using together with NeoHWSerial on AVR must use NeoSerialx to avoid linker conflict
31#if !defined(LIN_SLAVE_DEBUG_SERIAL)
32 //#define LIN_SLAVE_DEBUG_SERIAL Serial //!< serial interface used for debug output
33 //#define LIN_SLAVE_DEBUG_SERIAL NeoSerial //!< serial interface used for debug output (optional on AVR, not together with HardwareSerial!)
34 //#include <NeoHWSerial.h> // comment in/out together with previous line
35 //#define LIN_SLAVE_DEBUG_SERIAL SerialUSB //!< serial interface used for debug output (optional on Due)
36#endif
37#if !defined(LIN_SLAVE_DEBUG_LEVEL)
38 #define LIN_SLAVE_DEBUG_LEVEL 2
39#endif
40#if !defined(LIN_SLAVE_DEBUG_PORT_TIMEOUT)
41 #define LIN_SLAVE_DEBUG_PORT_TIMEOUT 3000
42#endif
43#if !defined(LIN_SLAVE_DEBUG_BUFSIZE)
44 #define LIN_SLAVE_DEBUG_BUFSIZE 128
45#endif
46
47// define logging macros for optional debug output.
48// Use with printf() format like: DEBUG_PRINT(2, "Text=%s, Value=%d", text, value);
49#if defined(LIN_SLAVE_DEBUG_SERIAL)
50
51 // debug output macro for normal class methods
52 #define DEBUG_PRINT(level, fmt, ...) \
53 do { \
54 if (LIN_SLAVE_DEBUG_LEVEL >= level) { \
55 LIN_SLAVE_DEBUG_SERIAL.print(this->nameLIN); \
56 LIN_SLAVE_DEBUG_SERIAL.print(F(": ")); \
57 LIN_SLAVE_DEBUG_SERIAL.print(__PRETTY_FUNCTION__); \
58 LIN_SLAVE_DEBUG_SERIAL.print(F(": ")); \
59 char debug_buf[LIN_SLAVE_DEBUG_BUFSIZE]; \
60 snprintf(debug_buf, sizeof(debug_buf), (fmt), ##__VA_ARGS__); \
61 LIN_SLAVE_DEBUG_SERIAL.println(debug_buf); \
62 } \
63 } while(0)
64
65 // debug output macro for static class methods and functions
66 #define DEBUG_PRINT_STATIC(level, fmt, ...) \
67 do { \
68 if (LIN_SLAVE_DEBUG_LEVEL >= level) { \
69 LIN_SLAVE_DEBUG_SERIAL.print(__PRETTY_FUNCTION__); \
70 LIN_SLAVE_DEBUG_SERIAL.print(F(": ")); \
71 char debug_buf[LIN_SLAVE_DEBUG_BUFSIZE]; \
72 snprintf(debug_buf, sizeof(debug_buf), (fmt), ##__VA_ARGS__); \
73 LIN_SLAVE_DEBUG_SERIAL.println(debug_buf); \
74 } \
75 } while(0)
76
77
78// no debug output -> omit logging macro
79#else
80
81 // do nothing. Use safe empty macros
82 #define DEBUG_PRINT(level, fmt, ...) do {} while (0)
83 #define DEBUG_PRINT_STATIC(level, fmt, ...) do {} while (0)
84
85#endif // LIN_SLAVE_DEBUG_SERIAL
86
87
88/*-----------------------------------------------------------------------------
89 INCLUDE FILES
90-----------------------------------------------------------------------------*/
91
92// generic Arduino functions
93#include <Arduino.h>
94
95
96/*-----------------------------------------------------------------------------
97 GLOBAL CLASS
98-----------------------------------------------------------------------------*/
99
105 class LIN_Slave_Base
106{
107 // PUBLIC TYPEDEFS
108 public:
109
111 typedef enum : uint8_t
112 {
113 LIN_V1 = 1,
114 LIN_V2 = 2
115 } version_t;
116
117
119 typedef enum : uint8_t
120 {
121 MASTER_REQUEST = 0x10,
122 SLAVE_RESPONSE = 0x20
123 } frame_t;
124
125
127 typedef enum : uint8_t
128 {
129 STATE_OFF = 0x01,
130 STATE_WAIT_FOR_BREAK = 0x02,
131 STATE_WAIT_FOR_SYNC = 0x04,
132 STATE_WAIT_FOR_PID = 0x08,
133 STATE_RECEIVING_DATA = 0x10,
134 STATE_RECEIVING_ECHO = 0x20,
135 STATE_WAIT_FOR_CHK = 0x40,
136 STATE_DONE = 0x80
137 } state_t;
138
139
141 typedef enum : uint8_t
142 {
143 NO_ERROR = 0x00,
144 ERROR_STATE = 0x01,
145 ERROR_ECHO = 0x02,
146 ERROR_TIMEOUT = 0x04,
147 ERROR_CHK = 0x08,
148 ERROR_SYNC = 0x10,
149 ERROR_PID = 0x20,
150 ERROR_MISC = 0x80
151 } error_t;
152
153
154 // PROTECTED TYPEDEFS
155 protected:
156
158 typedef void (*LinMessageCallback)(uint8_t numData, uint8_t* data);
159
161 typedef struct
162 {
163 uint8_t type_numData;
164 LinMessageCallback fct;
165 } callback_t;
166
167
168 // PROTECTED VARIABLES
169 protected:
170
171 // node properties
172 int8_t pinTxEN;
173 uint16_t baudrate;
174 LIN_Slave_Base::version_t version;
175 LIN_Slave_Base::state_t state;
176 LIN_Slave_Base::error_t error;
177 bool flagBreak;
178 LIN_Slave_Base::callback_t callback[64];
179
180 // latest frame properties
181 uint8_t pid;
182 uint8_t id;
183 LIN_Slave_Base::frame_t type;
184 uint8_t numData;
185 uint8_t bufData[9];
186 uint8_t idxData;
187 uint32_t timeoutRx;
188 uint32_t timeLastRx;
189
190
191 // PUBLIC VARIABLES
192 public:
193
194 char nameLIN[LIN_SLAVE_BUFLEN_NAME];
195
196
197 // PROTECTED METHODS
198 protected:
199
201 uint8_t _calculatePID(uint8_t ID);
202
204 uint8_t _calculateChecksum(uint8_t NumData, uint8_t Data[]);
205
207 virtual bool _getBreakFlag(void);
208
210 virtual void _resetBreakFlag(void);
211
212
214 virtual inline uint8_t _serialPeek(void) { return 0x00; }
215
217 virtual inline uint8_t _serialRead(void) { return 0x00; }
218
220 virtual inline void _serialWrite(uint8_t buf[], uint8_t num) { (void) buf; (void) num; }
221
222
224 inline void _enableTransmitter(void)
225 {
226 // print debug message
227 DEBUG_PRINT(3, " ");
228
229 // enable tranmitter
230 if (this->pinTxEN >= 0)
231 digitalWrite(this->pinTxEN, HIGH);
232
233 } // _enableTransmitter()
234
236 inline void _disableTransmitter(void)
237 {
238 // print debug message
239 DEBUG_PRINT(3, " ");
240
241 // disable tranmitter
242 if (this->pinTxEN >= 0)
243 digitalWrite(this->pinTxEN, LOW);
244
245 } // _disableTransmitter()
246
247
248 // PUBLIC METHODS
249 public:
250
252 LIN_Slave_Base(LIN_Slave_Base::version_t Version = LIN_Slave_Base::LIN_V2, const char NameLIN[] = "Slave",
253 uint32_t TimeoutRx = 1500L, const int8_t PinTxEN = INT8_MIN);
254
256 virtual ~LIN_Slave_Base(void) {};
257
258
260 virtual void begin(uint16_t Baudrate = 19200);
261
263 virtual void end(void);
264
266 virtual inline bool available(void) { return false; }
267
268
270 inline void resetStateMachine(void)
271 {
272 // print debug message
273 DEBUG_PRINT(3, " ");
274
275 // reset state
276 this->state = LIN_Slave_Base::STATE_WAIT_FOR_BREAK;
277
278 } // resetStateMachine()
279
281 inline LIN_Slave_Base::state_t getState(void)
282 {
283 // print debug message
284 DEBUG_PRINT(3, " ");
285
286 // return state
287 return this->state;
288
289 } // getState()
290
291
293 inline void resetError(void)
294 {
295 // print debug message
296 DEBUG_PRINT(3, " ");
297
298 // reset error
299 this->error = LIN_Slave_Base::NO_ERROR;
300
301 } // resetError()
302
304 inline LIN_Slave_Base::error_t getError(void)
305 {
306 // print debug message
307 DEBUG_PRINT(3, " ");
308
309 // return error
310 return this->error;
311
312 } // getError()
313
314
316 inline void getFrame(LIN_Slave_Base::frame_t &Type, uint8_t &Id, uint8_t &NumData, uint8_t Data[])
317 {
318 // print debug message
319 DEBUG_PRINT(3, " ");
320
321 noInterrupts(); // for data consistency temporarily disable ISRs
322 Type = this->type; // frame type
323 Id = this->id; // received frame ID
324 NumData = this->numData; // number of data bytes (excl. BREAK, SYNC, ID, CHK)
325 memcpy(Data, this->bufData, NumData); // copy data bytes w/o checksum
326 interrupts(); // re-enable ISRs
327
328 } // getFrame()
329
330
332 void registerMasterRequestHandler(uint8_t ID, LIN_Slave_Base::LinMessageCallback Fct, uint8_t NumData);
333
335 void registerSlaveResponseHandler(uint8_t ID, LIN_Slave_Base::LinMessageCallback Fct, uint8_t NumData);
336
337
339 virtual void handler(void);
340
341}; // class LIN_Slave_Base
342
343/*-----------------------------------------------------------------------------
344 END OF MODULE DEFINITION FOR MULTIPLE INLUSION
345-----------------------------------------------------------------------------*/
346#endif // _LIN_SLAVE_BASE_H_
347
348/*-----------------------------------------------------------------------------
349 END OF FILE
350-----------------------------------------------------------------------------*/
LIN_Slave_Base
LIN slave node base class.
Definition LIN_slave_Base.h:106
LIN_Slave_Base::timeLastRx
uint32_t timeLastRx
time [us] of last received byte in frame
Definition LIN_slave_Base.h:188
LIN_Slave_Base::idxData
uint8_t idxData
current index in bufData
Definition LIN_slave_Base.h:186
LIN_Slave_Base::flagBreak
bool flagBreak
flag for BREAK detected. Needs to be set in Rx-ISR
Definition LIN_slave_Base.h:177
LIN_Slave_Base::error
LIN_Slave_Base::error_t error
error state. Is latched until cleared
Definition LIN_slave_Base.h:176
LIN_Slave_Base::registerSlaveResponseHandler
void registerSlaveResponseHandler(uint8_t ID, LIN_Slave_Base::LinMessageCallback Fct, uint8_t NumData)
Attach user callback function for slave response frame.
Definition LIN_slave_Base.cpp:247
LIN_Slave_Base::getFrame
void getFrame(LIN_Slave_Base::frame_t &Type, uint8_t &Id, uint8_t &NumData, uint8_t Data[])
Getter for LIN frame.
Definition LIN_slave_Base.h:316
LIN_Slave_Base::baudrate
uint16_t baudrate
communication baudrate [Baud]
Definition LIN_slave_Base.h:173
LIN_Slave_Base::resetStateMachine
void resetStateMachine(void)
Reset LIN state machine.
Definition LIN_slave_Base.h:270
LIN_Slave_Base::_serialWrite
virtual void _serialWrite(uint8_t buf[], uint8_t num)
write bytes to Tx buffer. Here dummy
Definition LIN_slave_Base.h:220
LIN_Slave_Base::pinTxEN
int8_t pinTxEN
optional Tx direction pin, e.g. for LIN via RS485
Definition LIN_slave_Base.h:172
LIN_Slave_Base::~LIN_Slave_Base
virtual ~LIN_Slave_Base(void)
LIN slave node destructor, here dummy. Any class with virtual functions should have virtual destructo...
Definition LIN_slave_Base.h:256
LIN_Slave_Base::frame_t
frame_t
LIN frame type. Use high nibble for type, low nibble for number of data bytes -> minimize callback[] ...
Definition LIN_slave_Base.h:120
LIN_Slave_Base::SLAVE_RESPONSE
@ SLAVE_RESPONSE
LIN slave response frame.
Definition LIN_slave_Base.h:122
LIN_Slave_Base::MASTER_REQUEST
@ MASTER_REQUEST
LIN master request frame.
Definition LIN_slave_Base.h:121
LIN_Slave_Base::_serialPeek
virtual uint8_t _serialPeek(void)
peek next byte from Rx buffer. Here dummy
Definition LIN_slave_Base.h:214
LIN_Slave_Base::bufData
uint8_t bufData[9]
buffer for data bytes (max. 8B) + checksum
Definition LIN_slave_Base.h:185
LIN_Slave_Base::timeoutRx
uint32_t timeoutRx
timeout [us] for bytes in frame
Definition LIN_slave_Base.h:187
LIN_Slave_Base::_getBreakFlag
virtual bool _getBreakFlag(void)
Get break detection flag. Is hardware dependent.
Definition LIN_slave_Base.cpp:93
LIN_Slave_Base::numData
uint8_t numData
number of data bytes in frame
Definition LIN_slave_Base.h:184
LIN_Slave_Base::type
LIN_Slave_Base::frame_t type
frame type (master request or slave response)
Definition LIN_slave_Base.h:183
LIN_Slave_Base::state_t
state_t
LIN state machine states. Use bitmasks for fast checking multiple states.
Definition LIN_slave_Base.h:128
LIN_Slave_Base::STATE_DONE
@ STATE_DONE
frame is completed
Definition LIN_slave_Base.h:136
LIN_Slave_Base::STATE_WAIT_FOR_PID
@ STATE_WAIT_FOR_PID
SYNC received, wait for frame PID.
Definition LIN_slave_Base.h:132
LIN_Slave_Base::STATE_OFF
@ STATE_OFF
LIN interface closed.
Definition LIN_slave_Base.h:129
LIN_Slave_Base::STATE_WAIT_FOR_BREAK
@ STATE_WAIT_FOR_BREAK
no LIN transmission ongoing, wait for BRK
Definition LIN_slave_Base.h:130
LIN_Slave_Base::STATE_WAIT_FOR_SYNC
@ STATE_WAIT_FOR_SYNC
BRK received, wait for SYNC.
Definition LIN_slave_Base.h:131
LIN_Slave_Base::STATE_RECEIVING_ECHO
@ STATE_RECEIVING_ECHO
receiving slave response echo
Definition LIN_slave_Base.h:134
LIN_Slave_Base::STATE_RECEIVING_DATA
@ STATE_RECEIVING_DATA
receiving master request data
Definition LIN_slave_Base.h:133
LIN_Slave_Base::STATE_WAIT_FOR_CHK
@ STATE_WAIT_FOR_CHK
waiting for checksum
Definition LIN_slave_Base.h:135
LIN_Slave_Base::version
LIN_Slave_Base::version_t version
LIN protocol version.
Definition LIN_slave_Base.h:174
LIN_Slave_Base::id
uint8_t id
unprotected frame identifier (0..63)
Definition LIN_slave_Base.h:182
LIN_Slave_Base::_disableTransmitter
void _disableTransmitter(void)
Disable RS485 transmitter (DE=low)
Definition LIN_slave_Base.h:236
LIN_Slave_Base::begin
virtual void begin(uint16_t Baudrate=19200)
Open serial interface.
Definition LIN_slave_Base.cpp:163
LIN_Slave_Base::registerMasterRequestHandler
void registerMasterRequestHandler(uint8_t ID, LIN_Slave_Base::LinMessageCallback Fct, uint8_t NumData)
Attach user callback function for master request frame.
Definition LIN_slave_Base.cpp:224
LIN_Slave_Base::getState
LIN_Slave_Base::state_t getState(void)
Getter for LIN state machine state.
Definition LIN_slave_Base.h:281
LIN_Slave_Base::error_t
error_t
LIN error codes. Use bitmasks, as error is latched. Use same as LIN_master_portable.
Definition LIN_slave_Base.h:142
LIN_Slave_Base::ERROR_SYNC
@ ERROR_SYNC
error in SYNC (not 0x55)
Definition LIN_slave_Base.h:148
LIN_Slave_Base::ERROR_TIMEOUT
@ ERROR_TIMEOUT
frame timeout error
Definition LIN_slave_Base.h:146
LIN_Slave_Base::ERROR_ECHO
@ ERROR_ECHO
error reading response echo
Definition LIN_slave_Base.h:145
LIN_Slave_Base::ERROR_STATE
@ ERROR_STATE
error in LIN state machine
Definition LIN_slave_Base.h:144
LIN_Slave_Base::ERROR_PID
@ ERROR_PID
ID parity error.
Definition LIN_slave_Base.h:149
LIN_Slave_Base::ERROR_MISC
@ ERROR_MISC
misc error, should not occur
Definition LIN_slave_Base.h:150
LIN_Slave_Base::ERROR_CHK
@ ERROR_CHK
LIN checksum error.
Definition LIN_slave_Base.h:147
LIN_Slave_Base::NO_ERROR
@ NO_ERROR
no error
Definition LIN_slave_Base.h:143
LIN_Slave_Base::_serialRead
virtual uint8_t _serialRead(void)
read next byte from Rx buffer. Here dummy
Definition LIN_slave_Base.h:217
LIN_Slave_Base::_calculateChecksum
uint8_t _calculateChecksum(uint8_t NumData, uint8_t Data[])
Calculate LIN frame checksum.
Definition LIN_slave_Base.cpp:59
LIN_Slave_Base::nameLIN
char nameLIN[LIN_SLAVE_BUFLEN_NAME]
LIN node name, e.g. for debug.
Definition LIN_slave_Base.h:194
LIN_Slave_Base::LinMessageCallback
void(* LinMessageCallback)(uint8_t numData, uint8_t *data)
Type for frame callback function.
Definition LIN_slave_Base.h:158
LIN_Slave_Base::_calculatePID
uint8_t _calculatePID(uint8_t ID)
Calculate protected frame ID.
Definition LIN_slave_Base.cpp:30
LIN_Slave_Base::_resetBreakFlag
virtual void _resetBreakFlag(void)
Clear break detection flag. Is hardware dependent.
Definition LIN_slave_Base.cpp:106
LIN_Slave_Base::version_t
version_t
LIN protocol version.
Definition LIN_slave_Base.h:112
LIN_Slave_Base::LIN_V1
@ LIN_V1
LIN protocol version 1.x.
Definition LIN_slave_Base.h:113
LIN_Slave_Base::LIN_V2
@ LIN_V2
LIN protocol version 2.x.
Definition LIN_slave_Base.h:114
LIN_Slave_Base::resetError
void resetError(void)
Clear error of LIN state machine.
Definition LIN_slave_Base.h:293
LIN_Slave_Base::pid
uint8_t pid
protected frame identifier (0..255)
Definition LIN_slave_Base.h:181
LIN_Slave_Base::getError
LIN_Slave_Base::error_t getError(void)
Getter for LIN state machine error.
Definition LIN_slave_Base.h:304
LIN_Slave_Base::state
LIN_Slave_Base::state_t state
status of LIN state machine
Definition LIN_slave_Base.h:175
LIN_Slave_Base::_enableTransmitter
void _enableTransmitter(void)
Enable RS485 transmitter (DE=high)
Definition LIN_slave_Base.h:224
LIN_Slave_Base::end
virtual void end(void)
Close serial interface.
Definition LIN_slave_Base.cpp:201
LIN_Slave_Base::available
virtual bool available(void)
check if a byte is available in Rx buffer. Here dummy
Definition LIN_slave_Base.h:266
LIN_Slave_Base::callback
LIN_Slave_Base::callback_t callback[64]
array of user callback functions for IDs 0x00..0x3F
Definition LIN_slave_Base.h:178
LIN_Slave_Base::handler
virtual void handler(void)
Handle LIN protocol and call user-defined frame callbacks.
Definition LIN_slave_Base.cpp:267
LIN_Slave_Base::callback_t
User-defined callback function with data length.
Definition LIN_slave_Base.h:162
LIN_Slave_Base::callback_t::type_numData
uint8_t type_numData
frame type (high nibble) and number of data bytes (low nibble)
Definition LIN_slave_Base.h:163
LIN_Slave_Base::callback_t::fct
LinMessageCallback fct
frame callback function
Definition LIN_slave_Base.h:164