def writer(self): """\ Loop and copy console->serial until EXITCHARCTER character is found. When MENUCHARACTER is found, interpret the next key locally. """ menu_active = False try: while self.alive: try: b = console.getkey() except KeyboardInterrupt: b = serial.to_bytes([3]) c = character(b) if menu_active: if c == MENUCHARACTER or c == EXITCHARCTER: # Menu character again/exit char -> send itself self.serial.write(b) # send character if self.echo: sys.stdout.write(c) elif c == '\x15': # CTRL+U -> upload file sys.stderr.write('\n--- File to upload: ') sys.stderr.flush() console.cleanup() filename = sys.stdin.readline().rstrip('\r\n') if filename: try: file = open(filename, 'r') sys.stderr.write('--- Sending file %s ---\n' % filename) while True: line = file.readline().rstrip('\r\n') if not line: break self.serial.write(line) self.serial.write('\r\n') # Wait for output buffer to drain. self.serial.flush() sys.stderr.write('.') # Progress indicator. sys.stderr.write('\n--- File %s sent ---\n' % filename) except IOError, e: sys.stderr.write('--- ERROR opening file %s: %s ---\n' % (filename, e)) console.setup() elif c in '\x08hH?': # CTRL+H, h, H, ? -> Show help sys.stderr.write(get_help_text()) elif c == '\x12': # CTRL+R -> Toggle RTS self.rts_state = not self.rts_state self.serial.setRTS(self.rts_state) sys.stderr.write('--- RTS %s ---\n' % (self.rts_state and 'active' or 'inactive')) elif c == '\x04': # CTRL+D -> Toggle DTR self.dtr_state = not self.dtr_state self.serial.setDTR(self.dtr_state) sys.stderr.write('--- DTR %s ---\n' % (self.dtr_state and 'active' or 'inactive')) elif c == '\x02': # CTRL+B -> toggle BREAK condition self.break_state = not self.break_state self.serial.setBreak(self.break_state) sys.stderr.write('--- BREAK %s ---\n' % (self.break_state and 'active' or 'inactive')) elif c == '\x05': # CTRL+E -> toggle local echo self.echo = not self.echo sys.stderr.write('--- local echo %s ---\n' % (self.echo and 'active' or 'inactive')) elif c == '\x09': # CTRL+I -> info self.dump_port_settings() elif c == '\x01': # CTRL+A -> cycle escape mode self.repr_mode += 1 if self.repr_mode > 3: self.repr_mode = 0 sys.stderr.write('--- escape data: %s ---\n' % ( REPR_MODES[self.repr_mode], )) elif c == '\x0c': # CTRL+L -> cycle linefeed mode self.convert_outgoing += 1 if self.convert_outgoing > 2: self.convert_outgoing = 0 self.newline = NEWLINE_CONVERISON_MAP[self.convert_outgoing] sys.stderr.write('--- line feed %s ---\n' % ( LF_MODES[self.convert_outgoing], )) elif c in 'pP': # P -> change port dump_port_list() sys.stderr.write('--- Enter port name: ') sys.stderr.flush() console.cleanup() try: port = sys.stdin.readline().strip() except KeyboardInterrupt: port = None console.setup() if port and port != self.serial.port: # reader thread needs to be shut down self._stop_reader() # save settings settings = self.serial.getSettingsDict() try: try: new_serial = serial.serial_for_url(port, do_not_open=True) except AttributeError: # happens when the installed pyserial is older than 2.5. use the # Serial class directly then. new_serial = serial.Serial() new_serial.port = port # restore settings and open new_serial.applySettingsDict(settings) new_serial.open() new_serial.setRTS(self.rts_state) new_serial.setDTR(self.dtr_state) new_serial.setBreak(self.break_state) except Exception, e: sys.stderr.write('--- ERROR opening new port: %s ---\n' % (e,)) new_serial.close() else: self.serial.close() self.serial = new_serial sys.stderr.write('--- Port changed to: %s ---\n' % (self.serial.port,)) # and restart the reader thread self._start_reader() elif c in 'bB': # B -> change baudrate sys.stderr.write('\n--- Baudrate: ') sys.stderr.flush() console.cleanup() backup = self.serial.baudrate try: self.serial.baudrate = int(sys.stdin.readline().strip()) except ValueError, e: sys.stderr.write('--- ERROR setting baudrate: %s ---\n' % (e,)) self.serial.baudrate = backup else:
def writer(self): """\ Loop and copy console->serial until EXITCHARCTER character is found. When MENUCHARACTER is found, interpret the next key locally. """ menu_active = False try: while self.alive: try: b = console.getkey() except KeyboardInterrupt: b = serial.to_bytes([3]) c = character(b) if menu_active: if c == MENUCHARACTER or c == EXITCHARCTER: # Menu character again/exit char -> send itself self.serial.write(b) # send character if self.echo: sys.stdout.write(c) elif c == '\x15': # CTRL+U -> upload file sys.stderr.write('\n--- File to upload: ') sys.stderr.flush() console.cleanup() filename = sys.stdin.readline().rstrip('\r\n') if filename: try: file = open(filename, 'r') sys.stderr.write('--- Sending file %s ---\n' % filename) while True: line = file.readline().rstrip('\r\n') if not line: break self.serial.write(line) self.serial.write('\r\n') # Wait for output buffer to drain. self.serial.flush() sys.stderr.write( '.') # Progress indicator. sys.stderr.write('\n--- File %s sent ---\n' % filename) except IOError, e: sys.stderr.write( '--- ERROR opening file %s: %s ---\n' % (filename, e)) console.setup() elif c in '\x08hH?': # CTRL+H, h, H, ? -> Show help sys.stderr.write(get_help_text()) elif c == '\x12': # CTRL+R -> Toggle RTS self.rts_state = not self.rts_state self.serial.setRTS(self.rts_state) sys.stderr.write( '--- RTS %s ---\n' % (self.rts_state and 'active' or 'inactive')) elif c == '\x04': # CTRL+D -> Toggle DTR self.dtr_state = not self.dtr_state self.serial.setDTR(self.dtr_state) sys.stderr.write( '--- DTR %s ---\n' % (self.dtr_state and 'active' or 'inactive')) elif c == '\x02': # CTRL+B -> toggle BREAK condition self.break_state = not self.break_state self.serial.setBreak(self.break_state) sys.stderr.write( '--- BREAK %s ---\n' % (self.break_state and 'active' or 'inactive')) elif c == '\x05': # CTRL+E -> toggle local echo self.echo = not self.echo sys.stderr.write( '--- local echo %s ---\n' % (self.echo and 'active' or 'inactive')) elif c == '\x09': # CTRL+I -> info self.dump_port_settings() elif c == '\x01': # CTRL+A -> cycle escape mode self.repr_mode += 1 if self.repr_mode > 3: self.repr_mode = 0 sys.stderr.write('--- escape data: %s ---\n' % (REPR_MODES[self.repr_mode], )) elif c == '\x0c': # CTRL+L -> cycle linefeed mode self.convert_outgoing += 1 if self.convert_outgoing > 2: self.convert_outgoing = 0 self.newline = NEWLINE_CONVERISON_MAP[ self.convert_outgoing] sys.stderr.write('--- line feed %s ---\n' % (LF_MODES[self.convert_outgoing], )) elif c in 'pP': # P -> change port dump_port_list() sys.stderr.write('--- Enter port name: ') sys.stderr.flush() console.cleanup() try: port = sys.stdin.readline().strip() except KeyboardInterrupt: port = None console.setup() if port and port != self.serial.port: # reader thread needs to be shut down self._stop_reader() # save settings settings = self.serial.getSettingsDict() try: try: new_serial = serial.serial_for_url( port, do_not_open=True) except AttributeError: # happens when the installed pyserial is older than 2.5. use the # Serial class directly then. new_serial = serial.Serial() new_serial.port = port # restore settings and open new_serial.applySettingsDict(settings) new_serial.open() new_serial.setRTS(self.rts_state) new_serial.setDTR(self.dtr_state) new_serial.setBreak(self.break_state) except Exception, e: sys.stderr.write( '--- ERROR opening new port: %s ---\n' % (e, )) new_serial.close() else: self.serial.close() self.serial = new_serial sys.stderr.write( '--- Port changed to: %s ---\n' % (self.serial.port, )) # and restart the reader thread self._start_reader() elif c in 'bB': # B -> change baudrate sys.stderr.write('\n--- Baudrate: ') sys.stderr.flush() console.cleanup() backup = self.serial.baudrate try: self.serial.baudrate = int( sys.stdin.readline().strip()) except ValueError, e: sys.stderr.write( '--- ERROR setting baudrate: %s ---\n' % (e, )) self.serial.baudrate = backup else:
# FTDITerm, a terminal for the FTDI direct driver. # (C)2015 Ian Hartwig <ihartwig@github> # Built on top of miniterm.py: # Very simple serial terminal # (C)2002-2011 Chris Liechti <*****@*****.**> # Input characters are sent directly (only LF -> CR/LF/CRLF translation is # done), received characters are displayed as is (or escaped trough pythons # repr, useful for debug purposes) import sys, os, threading import pyserial_glue as serial EXITCHARCTER = serial.to_bytes([0x1d]) # GS/CTRL+] MENUCHARACTER = serial.to_bytes([0x14]) # Menu: CTRL+T DEFAULT_PORT = None DEFAULT_BAUDRATE = 9600 DEFAULT_RTS = None DEFAULT_DTR = None def key_description(character): """generate a readable description for a key""" ascii_code = ord(character) if ascii_code < 32: return 'Ctrl+%c' % (ord('@') + ascii_code) else: return repr(character)