summaryrefslogtreecommitdiff
path: root/tools/reset_leonardo.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/reset_leonardo.py')
-rw-r--r--tools/reset_leonardo.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/tools/reset_leonardo.py b/tools/reset_leonardo.py
new file mode 100644
index 0000000..be53aa1
--- /dev/null
+++ b/tools/reset_leonardo.py
@@ -0,0 +1,109 @@
+"""Tool used to reset a Arduino Leonardo board."""
+from os import O_NDELAY, O_NOCTTY, O_RDWR, open as os_open, close as os_close
+import sys
+from termios import (
+ B1200,
+ TCSANOW,
+ TIOCM_DTR,
+ TIOCM_RTS,
+ TIOCMBIC,
+ TIOCMBIS,
+ tcgetattr,
+ tcsetattr
+)
+from fcntl import ioctl
+from argparse import ArgumentParser
+from dataclasses import dataclass
+from pathlib import Path
+from struct import pack
+from time import sleep
+
+
+@dataclass
+class ParsedArguments:
+ """Parsed command-line arguments."""
+ serial_port: Path
+
+
+class TTYAttributes:
+ """TTY attributes."""
+
+ def __init__(self, tty_fd: int):
+ """Initializes the TTY attributes."""
+ self.__tty_fd = tty_fd
+ self.__attrs = tcgetattr(tty_fd)
+
+ @property
+ def ispeed(self):
+ """The ispeed."""
+ return self.__attrs[4]
+
+ @ispeed.setter
+ def ispeed(self, ispeed: int):
+ self.__attrs[4] = ispeed
+
+ @property
+ def ospeed(self):
+ """The ospeed."""
+ return self.__attrs[5]
+
+ @ospeed.setter
+ def ospeed(self, ospeed: int):
+ self.__attrs[5] = ospeed
+
+ def set(self):
+ """Sets the TTY attributes."""
+ tcsetattr(self.__tty_fd, TCSANOW, self.__attrs)
+
+
+RESET_BAUD_RATE = B1200
+
+DESCRIPTION = "Tool used to reset a Arduino Leonardo board."
+
+
+def main():
+ """Main."""
+ parser = ArgumentParser(allow_abbrev=False, description=DESCRIPTION)
+
+ parser.add_argument(
+ "serial_port",
+ type=Path,
+ help="The serial port for a Arduino Leonardo board"
+ )
+
+ arguments = parser.parse_args(namespace=ParsedArguments)
+
+ is_serial_port_char_device = arguments.serial_port.is_char_device()
+
+ # Verify that the serial port exists
+ if not arguments.serial_port.is_file() and not is_serial_port_char_device:
+ print("Error: The serial port file doesn't exist")
+ sys.exit(1)
+
+ # Verify that the serial port is a character device
+ if not is_serial_port_char_device:
+ print("Error: The serial port file is not a character device")
+ sys.exit(1)
+
+ serial_port_fd = os_open(
+ str(arguments.serial_port),
+ O_RDWR | O_NOCTTY | O_NDELAY
+ )
+
+ tty_attributes = TTYAttributes(serial_port_fd)
+
+ tty_attributes.ispeed = RESET_BAUD_RATE
+ tty_attributes.ospeed = RESET_BAUD_RATE
+
+ tty_attributes.set()
+
+ ioctl(serial_port_fd, TIOCMBIS, pack("I", TIOCM_RTS))
+ ioctl(serial_port_fd, TIOCMBIC, pack("I", TIOCM_DTR))
+
+ os_close(serial_port_fd)
+
+ sleep(1.98)
+
+
+if __name__ == "__main__":
+ main()