13#ifndef _LIN_MASTER_BASE_H_
14#define _LIN_MASTER_BASE_H_
22#define LIN_MASTER_BUFLEN_NAME 30
23#define LIN_MASTER_LIN_PORT_TIMEOUT 3000
26#if defined(INCLUDE_NEOHWSERIAL)
27 #include <NeoHWSerial.h>
31#if !defined(LIN_MASTER_DEBUG_SERIAL)
37#if !defined(LIN_MASTER_DEBUG_LEVEL)
38 #define LIN_MASTER_DEBUG_LEVEL 2
40#if !defined(LIN_MASTER_DEBUG_PORT_TIMEOUT)
41 #define LIN_MASTER_DEBUG_PORT_TIMEOUT 3000
43#if !defined(LIN_MASTER_DEBUG_BUFSIZE)
44 #define LIN_MASTER_DEBUG_BUFSIZE 128
49#if defined(LIN_MASTER_DEBUG_SERIAL)
52 #define DEBUG_PRINT(level, fmt, ...) \
54 if (LIN_MASTER_DEBUG_LEVEL >= level) { \
55 LIN_MASTER_DEBUG_SERIAL.print(this->nameLIN); \
56 LIN_MASTER_DEBUG_SERIAL.print(F(": ")); \
57 LIN_MASTER_DEBUG_SERIAL.print(__PRETTY_FUNCTION__); \
58 LIN_MASTER_DEBUG_SERIAL.print(F(": ")); \
59 char debug_buf[LIN_MASTER_DEBUG_BUFSIZE]; \
60 snprintf(debug_buf, sizeof(debug_buf), (fmt), ##__VA_ARGS__); \
61 LIN_MASTER_DEBUG_SERIAL.println(debug_buf); \
66 #define DEBUG_PRINT_STATIC(level, fmt, ...) \
68 if (LIN_MASTER_DEBUG_LEVEL >= level) { \
69 LIN_MASTER_DEBUG_SERIAL.print(__PRETTY_FUNCTION__); \
70 LIN_MASTER_DEBUG_SERIAL.print(F(": ")); \
71 char debug_buf[LIN_MASTER_DEBUG_BUFSIZE]; \
72 snprintf(debug_buf, sizeof(debug_buf), (fmt), ##__VA_ARGS__); \
73 LIN_MASTER_DEBUG_SERIAL.println(debug_buf); \
82 #define DEBUG_PRINT(level, fmt, ...) do {} while (0)
83 #define DEBUG_PRINT_STATIC(level, fmt, ...) do {} while (0)
111 typedef enum : uint8_t
119 typedef enum : uint8_t
127 typedef enum : uint8_t
138 typedef enum : uint8_t
207 if (this->pinTxEN >= 0)
208 digitalWrite(this->pinTxEN, HIGH);
219 if (this->pinTxEN >= 0)
220 digitalWrite(this->pinTxEN, LOW);
229 LIN_Master_Base(
const char NameLIN[] =
"Master",
const int8_t PinTxEN = INT8_MIN);
236 virtual void begin(uint16_t Baudrate = 19200);
239 virtual void end(
void);
297 NumData = this->lenRx - 4;
298 memcpy(Data, this->bufRx+3, NumData);
306 uint8_t Id = 0x00, uint8_t NumData = 0, uint8_t Data[] = NULL);
310 uint8_t Id = 0x00, uint8_t NumData = 0, uint8_t Data[] = NULL);
314 uint8_t Id = 0x00, uint8_t NumData = 0);
318 uint8_t Id = 0x00, uint8_t NumData = 0, uint8_t *Data = NULL);
LIN master node base class.
uint8_t lenRx
receive buffer length (max. 12)
void resetStateMachine(void)
Reset LIN state machine.
virtual void begin(uint16_t Baudrate=19200)
Open serial interface.
uint16_t baudrate
communication baudrate [Baud]
@ MASTER_REQUEST
LIN master request frame.
@ SLAVE_RESPONSE
LIN slave response frame.
void getFrame(LIN_Master_Base::frame_t &Type, uint8_t &Id, uint8_t &NumData, uint8_t Data[])
Getter for LIN frame.
virtual ~LIN_Master_Base(void)
LIN master node destructor, here dummy. Any class with virtual functions should have virtual destruct...
uint8_t bufTx[12]
send buffer incl. BREAK, SYNC, DATA and CHK (max. 12B)
LIN_Master_Base::state_t receiveSlaveResponse(LIN_Master_Base::version_t Version=LIN_Master_Base::LIN_V2, uint8_t Id=0x00, uint8_t NumData=0)
Start sending a LIN slave response frame in background (if supported)
version_t
LIN protocol version.
@ LIN_V2
LIN protocol version 2.x.
@ LIN_V1
LIN protocol version 1.x.
uint8_t _calculatePID(void)
Calculate protected frame ID.
LIN_Master_Base::error_t _checkFrame(void)
Check received LIN frame.
LIN_Master_Base::error_t error
error state. Is latched until cleared
char nameLIN[LIN_MASTER_BUFLEN_NAME]
LIN node name, e.g. for debug.
void _enableTransmitter(void)
Enable RS485 transmitter (DE=high)
LIN_Master_Base::state_t getState(void)
Getter for LIN state machine state.
LIN_Master_Base::error_t receiveSlaveResponseBlocking(LIN_Master_Base::version_t Version=LIN_Master_Base::LIN_V2, uint8_t Id=0x00, uint8_t NumData=0, uint8_t *Data=NULL)
Send a blocking LIN slave response frame (no background operation)
uint32_t timeStart
starting time [us] for frame timeout
int8_t pinTxEN
optional Tx direction pin, e.g. for LIN via RS485
uint8_t lenTx
send buffer length (max. 12)
LIN_Master_Base::state_t handler(void)
Handle LIN background operation (call until STATE_DONE is returned)
uint8_t _calculateChecksum(uint8_t NumData, uint8_t Data[])
Calculate LIN frame checksum.
LIN_Master_Base::error_t getError(void)
Getter for LIN state machine error.
LIN_Master_Base::state_t state
status of LIN state machine
void resetError(void)
Clear error of LIN state machine.
virtual LIN_Master_Base::state_t _sendFrame(void)
Send LIN frame body.
void _disableTransmitter(void)
Disable RS485 transmitter (DE=low)
error_t
LIN error codes. Use bitmasks, as error is latched. Use same as LIN_slave_portable.
@ ERROR_STATE
error in LIN state machine
@ ERROR_CHK
LIN checksum error.
@ ERROR_TIMEOUT
frame timeout error
@ ERROR_ECHO
error reading response echo
@ ERROR_MISC
misc error, should not occur
virtual LIN_Master_Base::state_t _receiveFrame(void)
Receive LIN frame.
uint32_t timePerByte
time [us] per byte at specified baudrate
LIN_Master_Base::state_t sendMasterRequest(LIN_Master_Base::version_t Version=LIN_Master_Base::LIN_V2, uint8_t Id=0x00, uint8_t NumData=0, uint8_t Data[]=NULL)
Start sending a LIN master request frame in background (if supported)
LIN_Master_Base::version_t version
LIN protocol version.
state_t
state of LIN master state machine. Use bitmasks for fast checking multiple states
@ STATE_BODY
rest of frame is being sent/received
@ STATE_OFF
LIN interface closed.
@ STATE_BREAK
sync break is being transmitted
@ STATE_IDLE
no LIN transmission ongoing
@ STATE_DONE
frame completed
virtual void end(void)
Close serial interface.
uint8_t bufRx[12]
receive buffer incl. BREAK, SYNC, DATA and CHK (max. 12B)
LIN_Master_Base::frame_t type
LIN frame type.
virtual LIN_Master_Base::state_t _sendBreak(void)
Send LIN break.
uint8_t id
LIN frame identifier (protected or unprotected)
LIN_Master_Base::error_t sendMasterRequestBlocking(LIN_Master_Base::version_t Version=LIN_Master_Base::LIN_V2, uint8_t Id=0x00, uint8_t NumData=0, uint8_t Data[]=NULL)
Send a blocking LIN master request frame (no background operation)
uint32_t timeoutFrame
max. frame duration [us]