LIN_master_portable_Arduino 1.9
Arduino library for Local Interconnect Network master node emulation
Loading...
Searching...
No Matches
LIN_master_HardwareSerial_STM32.cpp
Go to the documentation of this file.
1
10// assert STM32 platform
11#if defined(ARDUINO_ARCH_STM32)
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 // if LIN mode is available clear BREAK detection flag for debugging purposes
43 #if defined(USART_CR2_LINEN)
44 this->huart->Instance->ICR = USART_ICR_LBDCF;
45 #endif
46
47 // optionally enable transmitter
48 this->_enableTransmitter();
49
50 // if LIN mode is available generate LIN BREAK (>=13 bit low)
51 #if defined(USART_CR2_LINEN)
52 this->huart->Instance->RQR |= USART_RQR_SBKRQ;
53
54 // w/o LIN mode send 0x00 at 1/2 baudrate
55 // Note: don't use Serial.begin() or TE=1 due to HW latency, see https://github.com/stm32duino/Arduino_Core_STM32/issues/2907#issuecomment-3816058235
56 #else
57 //this->huart->Instance->CR1 &= ~USART_CR1_UE;
58 this->huart->Instance->BRR = this->brr * 2;
59 //this->huart->Instance->CR1 |= USART_CR1_UE;
60 this->pSerial->write((int) 0x00);
61 #endif
62
63 // progress state
65
66 // print debug message
67 DEBUG_PRINT(3, " ");
68
69 // return state
70 return this->state;
71
72} // LIN_Master_HardwareSerial_STM32::_sendBreak()
73
74
75
82{
83 // if state is wrong, exit immediately
85 {
86 // print debug message
87 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
88
89 // set error state and return immediately
92 this->_disableTransmitter();
93 return this->state;
94 }
95
96 // byte(s) received (likely BREAK echo)
97 if (this->pSerial->available())
98 {
99 // store echo in Rx
100 this->bufRx[0] = this->pSerial->read();
101
102 // if LIN mode is available do nothing. BREAK generated using dedicated LIN mode above
103 #if defined(USART_CR2_LINEN)
104
105 // w/o LIN mode revert baudrate
106 // Note: don't use Serial.begin() or TE=1 due to HW latency, see https://github.com/stm32duino/Arduino_Core_STM32/issues/2907#issuecomment-3816058235
107 #else
108 this->huart->Instance->BRR = this->brr;
109 #endif
110
111 // send rest of frame (request frame: SYNC+ID+DATA[]+CHK; response frame: SYNC+ID)
112 this->pSerial->write(this->bufTx+1, this->lenTx-1);
113
114 // progress state
116
117 } // BREAK echo received
118
119 // no byte(s) received
120 else
121 {
122 // check for timeout
123 if (micros() - this->timeStart > this->timeoutFrame)
124 {
125 // print debug message
126 DEBUG_PRINT(1, "Rx timeout");
127
128 // set error state and return immediately
131 this->_disableTransmitter();
132 return this->state;
133 }
134
135 } // no byte(s) received
136
137 // print debug message
138 DEBUG_PRINT(2, " ");
139
140 // return state
141 return this->state;
142
143} // LIN_Master_HardwareSerial_STM32::_sendFrame()
144
145
146
153{
154 // if state is wrong, exit immediately
156 {
157 // print debug message
158 DEBUG_PRINT(1, "wrong state 0x%02X", this->state);
159
160 // set error state and return immediately
163 this->_disableTransmitter();
164 return this->state;
165 }
166
167 // optionally disable RS485 transmitter for slave response frames. Len==2 because BREAK is handled already handled in _sendFrame()
168 if ((this->type == LIN_Master_Base::SLAVE_RESPONSE) && (this->pSerial->available() == 2))
169 this->_disableTransmitter();
170
171 // frame body received (-1 because BREAK is handled already handled in _sendFrame())
172 if (this->pSerial->available() >= this->lenRx-1)
173 {
174 // store bytes in Rx
175 this->pSerial->readBytes(this->bufRx+1, this->lenRx-1);
176
177 // check frame for errors
178 this->error = (LIN_Master_Base::error_t) ((int) this->error | (int) this->_checkFrame());
179
180 // optionally disable RS485 transmitter after frame is completed
181 this->_disableTransmitter();
182
183 // progress state
185
186 } // frame body received
187
188 // frame body received not yet received
189 else
190 {
191 // check for timeout
192 if (micros() - this->timeStart > this->timeoutFrame)
193 {
194 // print debug message
195 DEBUG_PRINT(1, "Rx timeout");
196
197 // set error state and return immediately
200 this->_disableTransmitter();
201 return this->state;
202 }
203
204 } // not enough bytes received
205
206 // print debug message
207 DEBUG_PRINT(2, " ");
208
209 // return state
210 return this->state;
211
212} // LIN_Master_HardwareSerial_STM32::_receiveFrame()
213
214
215
226 uint32_t PinTx, const char NameLIN[], const int8_t PinTxEN) : LIN_Master_Base::LIN_Master_Base(NameLIN, PinTxEN)
227{
228 // Debug serial initialized in begin() -> no debug output here
229
230 // store pointer to used HW serial
231 this->pSerial = &Interface; // used serial interface
232 this->huart = Interface.getHandle(); // pointer to underlying HAL UART handle
233 this->pinRx = PinRx; // receive pin
234 this->pinTx = PinTx; // transmit pin
235
236} // LIN_Master_HardwareSerial_STM32::LIN_Master_HardwareSerial_STM32()
237
238
239
246{
247 // call base class method
248 LIN_Master_Base::begin(Baudrate);
249
250 // just to be sure
251 this->pSerial->end();
252
253 // remap Rx/Tx pins (before begin()!)
254 this->pSerial->setTx(this->pinTx);
255 this->pSerial->setRx(this->pinRx);
256
257 // open serial interface with optional timeout
258 this->pSerial->begin(this->baudrate);
259 #if defined(LIN_MASTER_LIN_PORT_TIMEOUT) && (LIN_MASTER_LIN_PORT_TIMEOUT > 0)
260 uint32_t startMillis = millis();
261 while ((!(*(this->pSerial))) && (millis() - startMillis < LIN_MASTER_LIN_PORT_TIMEOUT));
262 #else
263 while(!(*(this->pSerial)));
264 #endif
265
266 // if LIN mode is available enable LIN mode -> BREAK 13b & enable BREAK detection
267 #if defined(USART_CR2_LINEN)
268 this->huart->Instance->CR1 &= ~USART_CR1_UE;
269 this->huart->Instance->CR2 |= USART_CR2_LINEN;
270 this->huart->Instance->CR1 |= USART_CR1_UE;
271
272 // w/o LIN mode store BRR value for BRK generation
273 #else
274 this->brr = this->huart->Instance->BRR;
275 #endif
276
277 // print debug message
278 DEBUG_PRINT(2, "ok");
279
280} // LIN_Master_HardwareSerial_STM32::begin()
281
282
283
289{
290 // call base class method
292
293 // close serial interface
294 this->pSerial->end();
295
296 // disable LIN mode
297 this->huart->Instance->CR1 &= ~USART_CR1_UE;
298 this->huart->Instance->CR2 &= ~USART_CR2_LINEN;
299 this->huart->Instance->CR1 |= USART_CR1_UE;
300
301 // print debug message
302 DEBUG_PRINT(2, " ");
303
304} // LIN_Master_HardwareSerial_STM32::end()
305
306#endif // ARDUINO_ARCH_STM32
307
308/*-----------------------------------------------------------------------------
309 END OF FILE
310-----------------------------------------------------------------------------*/
LIN master emulation library using a HardwareSerial interface of STM32.
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
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]
UART_HandleTypeDef * huart
pointer to underlying HAL UART handle
LIN_Master_HardwareSerial_STM32(HardwareSerial &Interface, uint32_t PinRx, uint32_t PinTx, const char NameLIN[]="Master", const int8_t PinTxEN=INT8_MIN)
Class constructor.
LIN_Master_Base::state_t _sendBreak(void)
Send LIN break.
void begin(uint16_t Baudrate=19200)
Open serial interface.
LIN_Master_Base::state_t _receiveFrame(void)
Read and check LIN frame.
LIN_Master_Base::state_t _sendFrame(void)
Send LIN bytes (request frame: SYNC+ID+DATA[]+CHK; response frame: SYNC+ID)
HardwareSerial * pSerial
serial interface used for LIN
uint32_t brr
BRR value if LIN mode is not available.