Skip to content

Commit 5338ea0

Browse files
committed
fix: Fix buffering issues with CP2102 converter causing connection failures
Some CP2102 drivers on Windows don't properly flush buffers after unsupported commands, leaving stale data that breaks subsequent communication. Add active buffer draining to read and discard any lingering data before continuing. Closes espressif#1106
1 parent 524825e commit 5338ea0

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

esptool/loader.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,10 +502,35 @@ def command(
502502
if op is None or op_ret == op:
503503
return val, data
504504
if byte(data, 0) != 0 and byte(data, 1) == self.ROM_INVALID_RECV_MSG:
505-
# Unsupported read_reg can result in
505+
506+
def drain_input_buffer(buffering_time=0.2):
507+
"""
508+
Actively drain the input buffer by reading data
509+
for a specified time. Simple approach for some
510+
drivers that have issues with the buffer flushing.
511+
512+
Args:
513+
buffering_time: Time in seconds to wait for
514+
the buffer to fill.
515+
"""
516+
time.sleep(buffering_time)
517+
original_timeout = self._port.timeout
518+
# Set a very short timeout for draining
519+
self._port.timeout = 0.001
520+
521+
# Unsupported command response is sent 8 times and has
522+
# 14 bytes length including delimiter 0xC0 bytes.
523+
# At least part of it is read as a command response,
524+
# but to be safe, read it all.
525+
self._port.read(14 * 8)
526+
527+
# Restore original timeout
528+
self._port.timeout = original_timeout
529+
self.flush_input()
530+
531+
# Unsupported command can result in
506532
# more than one error response for some reason
507-
time.sleep(0.2) # Wait for input buffer to fill
508-
self.flush_input() # Flush input buffer of hanging response
533+
drain_input_buffer(0.2)
509534
raise UnsupportedCommandError(self, op)
510535

511536
finally:

0 commit comments

Comments
 (0)