| LIN_master_portable_Arduino 1.4 Arduino library for Local Interconnect Network master node emulation

Loading...
Searching...
No Matches
LIN_master_SoftwareSerial.cpp
Go to the documentation of this file.
1
9// assert platform which supports SoftwareSerial. Note: ARDUINO_ARCH_ESP32 requires library ESPSoftwareSerial
10#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
11
12// include files
13#include <LIN_master_SoftwareSerial.h>
14
15
21 LIN_Master_Base::state_t LIN_Master_SoftwareSerial::_sendBreak(void)
22{
23 // if state is wrong, exit immediately
24 if (this->state != LIN_Master_Base::STATE_IDLE)
25 {
26 // print debug message
27 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
28
29 // set error state and return immediately
30 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) LIN_Master_Base::ERROR_STATE);
31 this->state = LIN_Master_Base::STATE_DONE;
32 this->_disableTransmitter();
33 return this->state;
34 }
35
36 // optionally enable transmitter
37 this->_enableTransmitter();
38
39 // generate BREAK directly via GPIO (less overhead)
40 digitalWrite(this->pinTx, LOW);
41 delayMicroseconds(this->durationBreak);
42 digitalWrite(this->pinTx, HIGH);
43 delayMicroseconds(100); // stop bit + 1b delimiter
44
45 // progress state
46 this->state = LIN_Master_Base::STATE_BREAK;
47
48 // print debug message
49 DEBUG_PRINT(3, " ");
50
51 // return state
52 return this->state;
53
54} // LIN_Master_SoftwareSerial::_sendBreak()
55
56
57
63 LIN_Master_Base::state_t LIN_Master_SoftwareSerial::_sendFrame(void)
64{
65 // if state is wrong, exit immediately
66 if (this->state != LIN_Master_Base::STATE_BREAK)
67 {
68 // print debug message
69 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
70
71 // set error state and return immediately
72 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) LIN_Master_Base::ERROR_STATE);
73 this->state = LIN_Master_Base::STATE_DONE;
74 this->_disableTransmitter();
75 return this->state;
76 }
77
78 // restore nominal baudrate not required, use digitalWrite() for BREAK
79
80 // disable reception to skip LIN echo (disturbs SoftwareSerial)
81 this->SWSerial.stopListening();
82
83 // send rest of frame (request frame: SYNC+ID+DATA[]+CHK; response frame: SYNC+ID). Is blocking and receive is disabled!
84 this->SWSerial.write(this->bufTx+1, this->lenTx-1);
85
86 // optionally disable transmitter for slave response frames
87 if (this->type == LIN_Master_Base::SLAVE_RESPONSE)
88 this->_disableTransmitter();
89
90 // re-enable reception (above write is blocking)
91 this->SWSerial.listen();
92
93 // Emulate LIN echo for sent bytes
94 memcpy(this->bufRx, this->bufTx, this->lenTx);
95
96 // progress state
97 this->state = LIN_Master_Base::STATE_BODY;
98
99 // print debug message
100 DEBUG_PRINT(2, " ");
101
102 // return state
103 return this->state;
104
105} // LIN_Master_SoftwareSerial::_sendFrame()
106
107
108
114 LIN_Master_Base::state_t LIN_Master_SoftwareSerial::_receiveFrame(void)
115{
116 // if state is wrong, exit immediately
117 if (this->state != LIN_Master_Base::STATE_BODY)
118 {
119 // print debug message
120 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
121
122 // set error state and return immediately
123 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) LIN_Master_Base::ERROR_STATE);
124 this->state = LIN_Master_Base::STATE_DONE;
125 this->_disableTransmitter();
126 return this->state;
127 }
128
129 // master request frame
130 if (this-> type == LIN_Master_Base::MASTER_REQUEST)
131 {
132 // LIN echo already emulated in _sendFrame()
133
134 // check frame for errors
135 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) this->_checkFrame());
136
137 // optionally disable transmitter after frame is completed
138 this->_disableTransmitter();
139
140 // progress state
141 this->state = LIN_Master_Base::STATE_DONE;
142
143 } // master request frame
144
145 // slave response frame
146 else
147 {
148 // slave response received (-lenTx because header already emulated in _sendFrame())
149 if (this->SWSerial.available() >= this->lenRx - this->lenTx)
150 {
151 // store bytes in Rx
152 this->SWSerial.readBytes(this->bufRx+3, this->lenRx - this->lenTx);
153
154 // check frame for errors
155 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) this->_checkFrame());
156
157 // progress state
158 this->state = LIN_Master_Base::STATE_DONE;
159
160 } // frame body received
161
162 // frame body received not yet received
163 else
164 {
165 // check for timeout
166 if (micros() - this->timeStart > this->timeoutFrame)
167 {
168 // print debug message
169 DEBUG_PRINT(1, "Rx timeout");
170
171 // set error state and return immediately
172 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) LIN_Master_Base::ERROR_TIMEOUT);
173 this->state = LIN_Master_Base::STATE_DONE;
174 this->_disableTransmitter();
175 return this->state;
176 }
177
178 } // not enough bytes received
179
180 } // slave response frame
181
182 // print debug message
183 DEBUG_PRINT(2, " ");
184
185 // return state
186 return this->state;
187
188} // LIN_Master_SoftwareSerial::_receiveFrame()
189
190
191
201 LIN_Master_SoftwareSerial::LIN_Master_SoftwareSerial(uint8_t PinRx, uint8_t PinTx, bool InverseLogic, const char NameLIN[], const int8_t PinTxEN) :
202 LIN_Master_Base::LIN_Master_Base(NameLIN, PinTxEN), SWSerial(PinRx, PinTx, InverseLogic)
203{
204 // Debug serial initialized in begin() -> no debug output here
205
206 // store pins used for SW serial
207 this->pinRx = PinRx;
208 this->pinTx = PinTx;
209 this->inverseLogic = InverseLogic;
210
211 // must not open connection here, else (at least) ESP32 and ESP8266 fail
212
213 // cannot print debug message, as constructor is called before setup()
214
215} // LIN_Master_SoftwareSerial::LIN_Master_SoftwareSerial()
216
217
218
224 void LIN_Master_SoftwareSerial::begin(uint16_t Baudrate)
225{
226 // call base class method
227 LIN_Master_Base::begin(Baudrate);
228
229 // open serial interface. Timeout not required here
230 this->SWSerial.end();
231 this->SWSerial.begin(this->baudrate);
232
233 // calculate duration of BREAK
234 this->durationBreak = this->timePerByte * 13 / 10;
235
236 // print debug message
237 DEBUG_PRINT(2, "ok");
238
239} // LIN_Master_SoftwareSerial::begin()
240
241
242
247 void LIN_Master_SoftwareSerial::end()
248{
249 // call base class method
250 LIN_Master_Base::end();
251
252 // close serial interface
253 this->SWSerial.end();
254
255 // print debug message
256 DEBUG_PRINT(2, " ");
257
258} // LIN_Master_SoftwareSerial::end()
259
260
261#endif // ARDUINO_ARCH_AVR || ARDUINO_ARCH_ESP8266 || ARDUINO_ARCH_ESP32
262
263/*-----------------------------------------------------------------------------
264 END OF FILE
265-----------------------------------------------------------------------------*/
LIN_master_SoftwareSerial.h
LIN master emulation library for SoftwareSerial.
LIN_Master_Base
LIN master node base class.
Definition LIN_master_Base.h:106
LIN_Master_Base::lenRx
uint8_t lenRx
receive buffer length (max. 12)
Definition LIN_master_Base.h:166
LIN_Master_Base::begin
virtual void begin(uint16_t Baudrate=19200)
Open serial interface.
Definition LIN_master_Base.cpp:240
LIN_Master_Base::baudrate
uint16_t baudrate
communication baudrate [Baud]
Definition LIN_master_Base.h:154
LIN_Master_Base::MASTER_REQUEST
@ MASTER_REQUEST
LIN master request frame.
Definition LIN_master_Base.h:121
LIN_Master_Base::SLAVE_RESPONSE
@ SLAVE_RESPONSE
LIN slave response frame.
Definition LIN_master_Base.h:122
LIN_Master_Base::bufTx
uint8_t bufTx[12]
send buffer incl. BREAK, SYNC, DATA and CHK (max. 12B)
Definition LIN_master_Base.h:165
LIN_Master_Base::_checkFrame
LIN_Master_Base::error_t _checkFrame(void)
Check received LIN frame.
Definition LIN_master_Base.cpp:92
LIN_Master_Base::error
LIN_Master_Base::error_t error
error state. Is latched until cleared
Definition LIN_master_Base.h:156
LIN_Master_Base::_enableTransmitter
void _enableTransmitter(void)
Enable RS485 transmitter (DE=high)
Definition LIN_master_Base.h:201
LIN_Master_Base::timeStart
uint32_t timeStart
starting time [us] for frame timeout
Definition LIN_master_Base.h:168
LIN_Master_Base::lenTx
uint8_t lenTx
send buffer length (max. 12)
Definition LIN_master_Base.h:164
LIN_Master_Base::state
LIN_Master_Base::state_t state
status of LIN state machine
Definition LIN_master_Base.h:155
LIN_Master_Base::_disableTransmitter
void _disableTransmitter(void)
Disable RS485 transmitter (DE=low)
Definition LIN_master_Base.h:213
LIN_Master_Base::error_t
error_t
LIN error codes. Use bitmasks, as error is latched. Use same as LIN_slave_portable.
Definition LIN_master_Base.h:139
LIN_Master_Base::ERROR_STATE
@ ERROR_STATE
error in LIN state machine
Definition LIN_master_Base.h:141
LIN_Master_Base::ERROR_TIMEOUT
@ ERROR_TIMEOUT
frame timeout error
Definition LIN_master_Base.h:143
LIN_Master_Base::timePerByte
uint32_t timePerByte
time [us] per byte at specified baudrate
Definition LIN_master_Base.h:157
LIN_Master_Base::state_t
state_t
state of LIN master state machine. Use bitmasks for fast checking multiple states
Definition LIN_master_Base.h:128
LIN_Master_Base::STATE_BODY
@ STATE_BODY
rest of frame is being sent/received
Definition LIN_master_Base.h:132
LIN_Master_Base::STATE_BREAK
@ STATE_BREAK
sync break is being transmitted
Definition LIN_master_Base.h:131
LIN_Master_Base::STATE_IDLE
@ STATE_IDLE
no LIN transmission ongoing
Definition LIN_master_Base.h:130
LIN_Master_Base::STATE_DONE
@ STATE_DONE
frame completed
Definition LIN_master_Base.h:133
LIN_Master_Base::end
virtual void end(void)
Close serial interface.
Definition LIN_master_Base.cpp:279
LIN_Master_Base::bufRx
uint8_t bufRx[12]
receive buffer incl. BREAK, SYNC, DATA and CHK (max. 12B)
Definition LIN_master_Base.h:167
LIN_Master_Base::type
LIN_Master_Base::frame_t type
LIN frame type.
Definition LIN_master_Base.h:162
LIN_Master_Base::timeoutFrame
uint32_t timeoutFrame
max. frame duration [us]
Definition LIN_master_Base.h:158
LIN_Master_SoftwareSerial::begin
void begin(uint16_t Baudrate=19200)
Open serial interface.
Definition LIN_master_SoftwareSerial.cpp:224
LIN_Master_SoftwareSerial::_sendBreak
LIN_Master_Base::state_t _sendBreak(void)
Send LIN break.
Definition LIN_master_SoftwareSerial.cpp:21
LIN_Master_SoftwareSerial::end
void end(void)
Close serial interface.
Definition LIN_master_SoftwareSerial.cpp:247
LIN_Master_SoftwareSerial::LIN_Master_SoftwareSerial
LIN_Master_SoftwareSerial(uint8_t PinRx, uint8_t PinTx, bool InverseLogic=false, const char NameLIN[]="Master", const int8_t PinTxEN=INT8_MIN)
Class constructor.
Definition LIN_master_SoftwareSerial.cpp:201
LIN_Master_SoftwareSerial::_receiveFrame
LIN_Master_Base::state_t _receiveFrame(void)
Read and check LIN frame.
Definition LIN_master_SoftwareSerial.cpp:114
LIN_Master_SoftwareSerial::_sendFrame
LIN_Master_Base::state_t _sendFrame(void)
Send LIN bytes (request frame: SYNC+ID+DATA[]+CHK; response frame: SYNC+ID)
Definition LIN_master_SoftwareSerial.cpp:63