@@ -162,28 +162,6 @@ static stream_ret_t stream_write(Stream *self, const void *buf, size_t size) {
162
162
}
163
163
164
164
165
- static stream_ret_t stream_read (Stream * self , void * buf , size_t size , size_t * read ) {
166
- if (u_assert (self != NULL ) ||
167
- u_assert (buf != NULL ) ||
168
- u_assert (size > 0 )) {
169
- return STREAM_RET_FAILED ;
170
- }
171
- Stm32Uart * stm32_uart = (Stm32Uart * )self -> parent ;
172
-
173
- size_t r = xStreamBufferReceive (stm32_uart -> rxbuf , buf , size , portMAX_DELAY );
174
- if (r == 0 ) {
175
- return STREAM_RET_EOF ;
176
- } else if (r > 0 ) {
177
- if (read != NULL ) {
178
- * read = r ;
179
- }
180
- return STREAM_RET_OK ;
181
- }
182
-
183
- return STREAM_RET_FAILED ;
184
- }
185
-
186
-
187
165
static stream_ret_t stream_write_timeout (Stream * self , const void * buf , size_t size , size_t * written , uint32_t timeout_ms ) {
188
166
if (u_assert (self != NULL ) ||
189
167
u_assert (buf != NULL ) ||
@@ -231,17 +209,54 @@ static stream_ret_t stream_read_timeout(Stream *self, void *buf, size_t size, si
231
209
}
232
210
Stm32Uart * stm32_uart = (Stm32Uart * )self -> parent ;
233
211
234
- size_t r = xStreamBufferReceive (stm32_uart -> rxbuf , buf , size , pdMS_TO_TICKS (timeout_ms ));
235
- if (r == 0 ) {
236
- return STREAM_RET_TIMEOUT ;
237
- } else if (r > 0 ) {
238
- if (read != NULL ) {
239
- * read = r ;
212
+ /* Allow using constant for the max delay, see @p stream_read below. */
213
+ if (timeout_ms != portMAX_DELAY ) {
214
+ timeout_ms = pdMS_TO_TICKS (timeout_ms );
215
+ }
216
+
217
+ for (size_t i = 0 ; i < size ; i ++ ) {
218
+ uint8_t c ;
219
+ /* Waiting with timeout for the first byte only. */
220
+ size_t r = xStreamBufferReceive (stm32_uart -> rxbuf , & c , sizeof (c ), i ? 0 : timeout_ms );
221
+
222
+ if (r == 0 ) {
223
+ if (read != NULL ) {
224
+ * read = i ;
225
+ }
226
+ return i ? STREAM_RET_OK : STREAM_RET_TIMEOUT ;
227
+ } else {
228
+ if (c == 0x1b ) {
229
+ /* Do not handle timeout. We are sure there is another byte ready
230
+ * when ESC is received. Read the next byte after the ESC. */
231
+ r = xStreamBufferReceive (stm32_uart -> rxbuf , & c , sizeof (c ), timeout_ms );
232
+ ((uint8_t * )buf )[i ] = c ;
233
+ } else if (c == 0x17 ) {
234
+ /* Handle end of block (signalled by RTO interrupt). */
235
+ if (read != NULL ) {
236
+ * read = i ;
237
+ }
238
+ return STREAM_RET_EOT ;
239
+ } else {
240
+ ((uint8_t * )buf )[i ] = c ;
241
+ }
240
242
}
241
- return STREAM_RET_OK ;
243
+ }
244
+ if (read != NULL ) {
245
+ * read = size ;
242
246
}
243
247
244
- return STREAM_RET_FAILED ;
248
+ return STREAM_RET_OK ;
249
+ }
250
+
251
+
252
+ static stream_ret_t stream_read (Stream * self , void * buf , size_t size , size_t * read ) {
253
+ if (u_assert (self != NULL ) ||
254
+ u_assert (buf != NULL ) ||
255
+ u_assert (size > 0 )) {
256
+ return STREAM_RET_FAILED ;
257
+ }
258
+
259
+ return stream_read_timeout (self , buf , size , read , portMAX_DELAY );
245
260
}
246
261
247
262
@@ -351,12 +366,26 @@ stm32_uart_ret_t stm32_uart_interrupt_handler(Stm32Uart *self) {
351
366
uint8_t b = usart_recv (self -> port );
352
367
353
368
BaseType_t woken = pdFALSE ;
369
+ /* For any character < 0x20, prepend ESC */
370
+ if (b < 0x20 ) {
371
+ const uint8_t esc = 0x1b ;
372
+ xStreamBufferSendFromISR (self -> rxbuf , & esc , sizeof (esc ), & woken );
373
+ }
354
374
/* Do not check the return value. If there was not enough space to save
355
375
* the received byte, we have nothing else to do. */
356
376
xStreamBufferSendFromISR (self -> rxbuf , & b , sizeof (b ), & woken );
357
377
portYIELD_FROM_ISR (woken );
358
378
}
359
379
380
+ if (USART_ISR (self -> port ) & USART_ISR_RTOF ) {
381
+ USART_ICR (self -> port ) |= USART_ICR_RTOCF ;
382
+
383
+ BaseType_t woken = pdFALSE ;
384
+ const uint8_t etb = 0x17 ;
385
+ xStreamBufferSendFromISR (self -> rxbuf , & etb , sizeof (etb ), & woken );
386
+ portYIELD_FROM_ISR (woken );
387
+ }
388
+
360
389
/* Enabling the RXNE interrupt also enables ORE. We must handle it properly. */
361
390
if ((USART_ISR (self -> port ) & USART_ISR_ORE )) {
362
391
USART_ICR (self -> port ) |= USART_ICR_ORECF ;
@@ -372,3 +401,21 @@ stm32_uart_ret_t stm32_uart_set_de(Stm32Uart *self, uint32_t de_port, uint32_t d
372
401
373
402
return STM32_UART_RET_OK ;
374
403
}
404
+
405
+
406
+ stm32_uart_ret_t stm32_uart_set_rto (Stm32Uart * self , bool rto ) {
407
+ self -> enable_rto = rto ;
408
+ if (rto ) {
409
+ /* Set receiver timeout enable. 3 character time. */
410
+ USART_CR2 (self -> port ) |= USART_CR2_RTOEN ;
411
+ USART_RTOR (self -> port ) = 20L ;
412
+
413
+ /* Enable timeout interrupt. */
414
+ USART_CR1 (self -> port ) |= USART_CR1_RTOIE ;
415
+ } else {
416
+ USART_CR2 (self -> port ) &= ~USART_CR2_RTOEN ;
417
+ USART_CR1 (self -> port ) &= ~USART_CR1_RTOIE ;
418
+ }
419
+
420
+ return STM32_UART_RET_OK ;
421
+ }
0 commit comments