LIN_master_portable_Arduino 1.4
Arduino library for Local Interconnect Network master node emulation
Loading...
Searching...
No Matches
LIN_master_HardwareSerial_ESP32.cpp
Go to the documentation of this file.
1
10// assert ESP32 platform
11#if defined(ARDUINO_ARCH_ESP32)
12
13// include files
15
16
23{
24 // if state is wrong, exit immediately
26 {
27 // print debug message
28 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
29
30 // set error state and return immediately
33 this->_disableTransmitter();
34 return this->state;
35 }
36
37 // empty buffers, just in case...
38 this->pSerial->flush();
39 while (this->pSerial->available())
40 this->pSerial->read();
41
42 // set half baudrate for BREAK
43 this->pSerial->updateBaudRate(this->baudrate >> 1);
44
45 // optionally enable transmitter
46 this->_enableTransmitter();
47
48 // send BREAK (>=13 bit low)
49 this->pSerial->write(this->bufTx[0]);
50
51 // store starting time to avoid using Serial.available(), which has >1ms delay
52 this->timeStartBreak = micros();
53
54 // progress state
56
57 // print debug message
58 DEBUG_PRINT(3, " ");
59
60 // return state
61 return this->state;
62
63} // LIN_Master_HardwareSerial_ESP32::_sendBreak()
64
65
66
73{
74 // if state is wrong, exit immediately
76 {
77 // print debug message
78 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
79
80 // set error state and return immediately
83 this->_disableTransmitter();
84 return this->state;
85 }
86
87 // Serial.available() has >1ms delay -> use duration of BREAK instead
88 if ((micros() - this->timeStartBreak) > (this->timePerByte << 1))
89 {
90 // skip reading Rx now (is not yet in buffer)
91
92 // restore nominal baudrate. Apparently this is ok for BREAK
93 this->pSerial->updateBaudRate(this->baudrate);
94
95 // send rest of frame (request frame: SYNC+ID+DATA[]+CHK; response frame: SYNC+ID)
96 this->pSerial->write(this->bufTx+1, this->lenTx-1);
97
98 // progress state
100
101 } // BREAK duration expired
102
103 // print debug message
104 DEBUG_PRINT(2, " ");
105
106 // return state
107 return this->state;
108
109} // LIN_Master_HardwareSerial_ESP32::_sendFrame()
110
111
112
119{
120 // if state is wrong, exit immediately
122 {
123 // print debug message
124 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
125
126 // set error state and return immediately
129 this->_disableTransmitter();
130 return this->state;
131 }
132
133 // optionally disable transmitter for slave response frames. Here, need to read BREAK as well due to delay of Serial.available()
134 if ((this->type == LIN_Master_Base::SLAVE_RESPONSE) && (this->pSerial->available() == 3))
135 this->_disableTransmitter();
136
137 // frame body received. Here, need to read BREAK as well due to delay of Serial.available()
138 if (this->pSerial->available() >= this->lenRx)
139 {
140 // store bytes in Rx
141 this->pSerial->readBytes(this->bufRx, this->lenRx);
142
143 // check frame for errors
144 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) this->_checkFrame());
145
146 // optionally disable transmitter after frame is completed
147 this->_disableTransmitter();
148
149 // progress state
151
152 } // frame body received
153
154 // frame body received not yet received
155 else
156 {
157 // check for timeout
158 if (micros() - this->timeStart > this->timeoutFrame)
159 {
160 // print debug message
161 DEBUG_PRINT(1, "Rx timeout");
162
163 // set error state and return immediately
166 this->_disableTransmitter();
167 return this->state;
168 }
169
170 } // not enough bytes received
171
172 // print debug message
173 DEBUG_PRINT(2, " ");
174
175 // return state
176 return this->state;
177
178} // LIN_Master_HardwareSerial_ESP32::_receiveFrame()
179
180
181
191LIN_Master_HardwareSerial_ESP32::LIN_Master_HardwareSerial_ESP32(HardwareSerial &Interface, uint8_t PinRx, uint8_t PinTx, const char NameLIN[], const int8_t PinTxEN) :
192 LIN_Master_Base::LIN_Master_Base(NameLIN, PinTxEN)
193{
194 // Debug serial initialized in begin() -> no debug output here
195
196 // store pointer to used HW serial
197 this->pSerial = &Interface; // used serial interface
198 this->pinRx = PinRx; // receive pin
199 this->pinTx = PinTx; // transmit pin
200
201 // must not open connection here, else system resets
202
203} // LIN_Master_HardwareSerial_ESP32::LIN_Master_HardwareSerial_ESP32()
204
205
206
213{
214 // call base class method
215 LIN_Master_Base::begin(Baudrate);
216
217 // open serial interface incl. used pins with optional timeout
218 this->pSerial->end();
219 this->pSerial->begin(this->baudrate, SERIAL_8N1, this->pinRx, this->pinTx);
220 #if defined(LIN_MASTER_LIN_PORT_TIMEOUT) && (LIN_MASTER_LIN_PORT_TIMEOUT > 0)
221 uint32_t startMillis = millis();
222 while ((!(*(this->pSerial))) && (millis() - startMillis < LIN_MASTER_LIN_PORT_TIMEOUT));
223 #else
224 while(!(*(this->pSerial)));
225 #endif
226
227 // print debug message
228 DEBUG_PRINT(2, "ok");
229
230} // LIN_Master_HardwareSerial_ESP32::begin()
231
232
233
239{
240 // call base class method
242
243 // close serial interface
244 this->pSerial->end();
245
246 // print debug message
247 DEBUG_PRINT(2, " ");
248
249} // LIN_Master_HardwareSerial_ESP32::end()
250
251#endif // ARDUINO_ARCH_ESP32
252
253/*-----------------------------------------------------------------------------
254 END OF FILE
255-----------------------------------------------------------------------------*/
LIN master emulation library using a HardwareSerial interface of ESP32.
LIN master node base class.
uint8_t lenRx
receive buffer length (max. 12)
virtual void begin(uint16_t Baudrate=19200)
Open serial interface.
uint16_t baudrate
communication baudrate [Baud]
@ SLAVE_RESPONSE
LIN slave response frame.
uint8_t bufTx[12]
send buffer incl. BREAK, SYNC, DATA and CHK (max. 12B)
LIN_Master_Base::error_t _checkFrame(void)
Check received LIN frame.
LIN_Master_Base::error_t error
error state. Is latched until cleared
void _enableTransmitter(void)
Enable RS485 transmitter (DE=high)
uint32_t timeStart
starting time [us] for frame timeout
uint8_t lenTx
send buffer length (max. 12)
LIN_Master_Base::state_t state
status of LIN state machine
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_TIMEOUT
frame timeout error
uint32_t timePerByte
time [us] per byte at specified baudrate
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_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.
uint32_t timeoutFrame
max. frame duration [us]
LIN_Master_HardwareSerial_ESP32(HardwareSerial &Interface, uint8_t PinRx, uint8_t PinTx, const char NameLIN[]="Master", const int8_t PinTxEN=INT8_MIN)
Class constructor.
LIN_Master_Base::state_t _sendFrame(void)
Send LIN bytes (request frame: SYNC+ID+DATA[]+CHK; response frame: SYNC+ID)
uint32_t timeStartBreak
micros() when BREAK was sent
void begin(uint16_t Baudrate=19200)
Open serial interface.
HardwareSerial * pSerial
serial interface used for LIN
LIN_Master_Base::state_t _receiveFrame(void)
Read and check LIN frame.
LIN_Master_Base::state_t _sendBreak(void)
Send LIN break.