scripts/microrepl.py (74 lines of code) (raw):
# Copyright 2015 The Python Software Foundation (http://python.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
A simple shim around PySerial that detects the correct port to which the
MicroPython device is connected and attempts to make a serial connection to it
in order to bring up the Python REPL.
Based on https://github.com/ntoll/microrepl by Nicholas H.Tollervey and the
contributors.
"""
import errno
import sys
from time import sleep
import traceback
import serial
import serial.tools.miniterm
from serial.tools.miniterm import Miniterm, key_description
BAUDRATE = 115200
PARITY = 'N'
if sys.version_info >= (3, 0):
def character(b):
return b.decode('latin1')
else:
def character(b):
return b
def connect_miniterm(port):
try:
ser = serial.Serial(port, BAUDRATE, parity=PARITY, rtscts=False,
xonxoff=False)
return Miniterm(ser, echo=False)
except serial.SerialException as e:
if e.errno == errno.ENOENT:
sys.stderr.write(
"Device %r not found. Check your "
"MicroPython device path settings.\n" % port)
elif e.errno == errno.EBUSY:
# Device is busy. Explain what to do.
sys.stderr.write(
"Found the device, but it is busy. "
"Wait up to 20 seconds, or "
"press the reset button on the "
"back of the device next to the yellow light; "
"then try again.\n"
)
elif e.errno == errno.EACCES:
sys.stderr.write("Found the device, but could not connect.\n".format(port))
sys.stderr.write('%s\n' % (str(e),))
sys.stderr.write('On linux, try adding yourself to the "dialout" group:\n')
sys.stderr.write('sudo usermod -a -G dialout <your-username>\n')
else:
# Try to be as helpful as possible.
sys.stderr.write("Found the device, but could not connect via" +
" port %r: %s\n" % (port, e))
sys.stderr.write("I'm not sure what to suggest. :-(\n")
input("Press ENTER to continue")
sys.exit(1)
def main():
"""
The function that actually runs the REPL.
"""
if len(sys.argv) not in range(2, 3):
print("Usage: microrepl.py /path/to/device [--nointerrupt]")
port = sys.argv[1]
print('Device path', port)
serial.tools.miniterm.EXITCHARCTER = character(b'\x1d')
miniterm = connect_miniterm(port)
# Emit some helpful information about the program and MicroPython.
shortcut_message = 'Quit: {} | Stop program: Ctrl+C | Reset: Ctrl+D\n'
help_message = 'Type \'help()\' (without the quotes) then press ENTER.\n'
exit_char = key_description(serial.tools.miniterm.EXITCHARCTER)
sys.stderr.write(shortcut_message.format(exit_char))
sys.stderr.write(help_message)
# Start everything.
miniterm.set_rx_encoding('utf-8')
miniterm.set_tx_encoding('utf-8')
miniterm.start()
sleep(0.5)
if len(sys.argv) != 3 or sys.argv[2] != '--nointerrupt':
miniterm.serial.write(b'\x03') # Connecting stops the running program.
try:
miniterm.join(True)
except KeyboardInterrupt:
pass
sys.stderr.write('\nEXIT - see you soon... :-)\n')
if __name__ == '__main__':
try:
main()
except Exception:
sys.stderr.write(traceback.format_exc())
input("Press ENTER to continue")
sys.exit(1)