Module: Prremote::Commands::SerialHelpers
Constant Summary collapse
- SERIAL_CHUNK_SIZE =
ESP32-C6's native USB Serial/JTAG drops bytes when a large payload is written in a single burst: its 256-byte driver RX ring buffer overflows faster than the firmware drains it byte-by-byte, and the controller does not apply USB backpressure. Writing in <=256-byte chunks with a short gap keeps the device from overrunning. The pacing is negligible on the baud-limited transports (Pico USB-CDC / ESP32 UART bridge), where a 256-byte chunk already takes ~22 ms to clock out at 115200 baud.
256- SERIAL_CHUNK_DELAY =
0.004
Instance Method Summary collapse
- #normalize(str) ⇒ Object
-
#safe_read(serial, size) ⇒ Object
Wraps serial.read so that a device disconnect (e.g. ENXIO on macOS when the Pico resets) surfaces as a human-readable error instead of a bare errno name.
- #wait_for_ready(serial) ⇒ Object
- #write_chunked(serial, data) ⇒ Object
Instance Method Details
#normalize(str) ⇒ Object
33 34 35 |
# File 'lib/prremote/commands/serial_helpers.rb', line 33 def normalize(str) str.gsub("\r\n", "\n").gsub("\r", '') end |
#safe_read(serial, size) ⇒ Object
Wraps serial.read so that a device disconnect (e.g. ENXIO on macOS when the Pico resets) surfaces as a human-readable error instead of a bare errno name.
58 59 60 61 62 |
# File 'lib/prremote/commands/serial_helpers.rb', line 58 def safe_read(serial, size) serial.read(size) || '' rescue RubySerial::Error => e raise "Device disconnected (#{e.}). Run `prremote reset` if the device is unresponsive." end |
#wait_for_ready(serial) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/prremote/commands/serial_helpers.rb', line 4 def wait_for_ready(serial) # On macOS, USB CDC TX buffers can be dropped when the host reopens the port, # leaving the device stuck in getchar() without re-sending READY. # Sending Ctrl+C forces the device to restart its READY loop. # Resent every second: ESP32 boards reset when the port opens (DTR/RTS # auto-reset circuit) and a Ctrl+C sent while they are still booting # is lost. Harmless on Pico — 0x03 while idle just re-prints READY. sleep 0.1 serial.write("\x03") rescue nil buf = +'' deadline = Time.now + 10 next_ctrl = Time.now + 1 loop do buf << normalize(safe_read(serial, 256)) if buf.include?('READY ') warn_if_runtime_outdated(buf) return end raise 'Timeout waiting for device. Run `prremote reset` if a script is running.' if Time.now > deadline if Time.now > next_ctrl serial.write("\x03") rescue nil next_ctrl = Time.now + 1 end sleep 0.05 end end |
#write_chunked(serial, data) ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'lib/prremote/commands/serial_helpers.rb', line 47 def write_chunked(serial, data) i = 0 while i < data.bytesize serial.write(data.byteslice(i, SERIAL_CHUNK_SIZE)) i += SERIAL_CHUNK_SIZE sleep SERIAL_CHUNK_DELAY if i < data.bytesize end end |