@@ -257,7 +257,18 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait)
257
257
uint32_t baudrate ;
258
258
uint32_t byte_delay_us = 0 ;
259
259
BaseType_t res ;
260
+ portTickType ticks_cur ;
261
+ portTickType ticks_start = xTaskGetTickCount ();
260
262
portTickType ticks_end = xTaskGetTickCount () + ticks_to_wait ;
263
+ /**
264
+ * Considering the overflow of the ticks_end and the ticks_cur (xTaskGetTickCount()),
265
+ * the possible tick timestamp is as follows:
266
+ * (one start tick timestamp, two end tick timestamps, four current tick timestamps)
267
+ *
268
+ * ticks: 0 0xFFFFFFFF
269
+ * |_______._______._______._______._______._______._______._______|
270
+ * cur1 end1 cur2 start cur3 end2 cur4
271
+ */
261
272
262
273
// Take tx_mux
263
274
res = xSemaphoreTake (p_uart_obj [uart_num ]-> tx_mux , (portTickType )ticks_to_wait );
@@ -273,10 +284,22 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait)
273
284
uart_get_baudrate (uart_num , & baudrate );
274
285
byte_delay_us = (uint32_t )(10000000 / baudrate ); // (1/baudrate)*10*1000_000 us
275
286
276
- ticks_to_wait = ticks_end - xTaskGetTickCount ();
287
+ ticks_cur = xTaskGetTickCount ();
288
+ if (ticks_start <= ticks_cur ) {
289
+ ticks_to_wait = ticks_to_wait - (ticks_cur - ticks_start );
290
+ } else {
291
+ ticks_to_wait = ticks_to_wait - (portMAX_DELAY - ticks_start + ticks_cur );
292
+ }
277
293
// wait for tx done sem.
278
294
if (pdTRUE == xSemaphoreTake (p_uart_obj [uart_num ]-> tx_done_sem , ticks_to_wait )) {
279
295
while (1 ) {
296
+ ticks_cur = xTaskGetTickCount ();
297
+ bool end1_timeout = (ticks_end < ticks_start && ticks_cur < ticks_start && ticks_cur > ticks_end );
298
+ bool end2_timeout = (ticks_start < ticks_end && (ticks_cur < ticks_start || ticks_end < ticks_cur ));
299
+ if (end1_timeout || end2_timeout ) {
300
+ xSemaphoreGive (p_uart_obj [uart_num ]-> tx_mux );
301
+ return ESP_ERR_TIMEOUT ;
302
+ }
280
303
if (UART [uart_num ]-> status .txfifo_cnt == 0 ) {
281
304
ets_delay_us (byte_delay_us ); // Delay one byte time to guarantee transmission completion
282
305
break ;
0 commit comments