From a9b8d553fa870eb9860ef62fe4fdbf3484ff0550 Mon Sep 17 00:00:00 2001 From: Daniel Zanco Date: Fri, 16 Sep 2022 00:13:47 -0300 Subject: [PATCH] add scripts used to upload binaries to the keyboard --- Code/devterm_keyboard/upload/dfumode.py | 59 +++++++ Code/devterm_keyboard/upload/upload-reset.c | 166 ++++++++++++++++++++ Code/devterm_keyboard/upload/upload_bin.sh | 30 ++++ 3 files changed, 255 insertions(+) create mode 100755 Code/devterm_keyboard/upload/dfumode.py create mode 100644 Code/devterm_keyboard/upload/upload-reset.c create mode 100755 Code/devterm_keyboard/upload/upload_bin.sh diff --git a/Code/devterm_keyboard/upload/dfumode.py b/Code/devterm_keyboard/upload/dfumode.py new file mode 100755 index 0000000..a7b8867 --- /dev/null +++ b/Code/devterm_keyboard/upload/dfumode.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +import time +import serial +import serial.tools.list_ports as lports +import argparse + + +def main(args): + + # Find which serial port to use (assumes only the keyboard is connected) + if args.port == '': + port_list = lports.comports() + if len(port_list) != 1: + print('No serial ports detected, quitting...') + quit() + else: + port = port_list[0].device + else: + port = args.port + + # Based on https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/master/tools/linux/src/upload-reset/upload-reset.c + # Send magic sequence of DTR and RTS followed by the magic word "1EAF" + with serial.Serial(port=port, baudrate=args.baudrate) as ser: + + ser.rts = False + ser.dtr = False + ser.dtr = True + + time.sleep(0.05) + + ser.dtr = False + ser.rts = True + ser.dtr = True + + time.sleep(0.05) + + ser.dtr = False + + time.sleep(0.05) + + ser.write(b'1EAF') + + # Wait for the DFU mode reboot + time.sleep(args.sleep * 1e-3) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser(description="Enter DFU mode of DevTerm's keyboard.") + parser.add_argument('-p', '--port', dest='port', type=str, default='', + help='Serial port (default: detect serial ports).') + parser.add_argument('-b', '--baudrate', dest='baudrate', type=int, default=9600, + help='Baudrate (default: 9600bps).') + parser.add_argument('-s', '--sleep', dest='sleep', type=int, default=1500, + help='Wait SLEEP milliseconds (ms) after enabling DFU mode (default: 1500ms).') + args = parser.parse_args() + + main(args) diff --git a/Code/devterm_keyboard/upload/upload-reset.c b/Code/devterm_keyboard/upload/upload-reset.c new file mode 100644 index 0000000..59b6ad7 --- /dev/null +++ b/Code/devterm_keyboard/upload/upload-reset.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2015 Roger Clark + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * + * Utility to send the reset sequence on RTS and DTR and chars + * which resets the libmaple and causes the bootloader to be run + * + * + * + * Terminal control code by Heiko Noordhof (see copyright below) + */ + +/* Copyright (C) 2003 Heiko Noordhof + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function prototypes (belong in a seperate header file) */ +int openserial(char *devicename); +void closeserial(void); +int setDTR(unsigned short level); +int setRTS(unsigned short level); + +/* Two globals for use by this module only */ +static int fd; +static struct termios oldterminfo; + +void closeserial(void) +{ + tcsetattr(fd, TCSANOW, &oldterminfo); + close(fd); +} + +int openserial(char *devicename) +{ + struct termios attr; + + if ((fd = open(devicename, O_RDWR)) == -1) + return 0; /* Error */ + atexit(closeserial); + + if (tcgetattr(fd, &oldterminfo) == -1) + return 0; /* Error */ + attr = oldterminfo; + attr.c_cflag |= CRTSCTS | CLOCAL; + attr.c_oflag = 0; + if (tcflush(fd, TCIOFLUSH) == -1) + return 0; /* Error */ + if (tcsetattr(fd, TCSANOW, &attr) == -1) + return 0; /* Error */ + + /* Set the lines to a known state, and */ + /* finally return non-zero is successful. */ + return setRTS(0) && setDTR(0); +} + +/* For the two functions below: + * level=0 to set line to LOW + * level=1 to set line to HIGH + */ + +int setRTS(unsigned short level) +{ + int status; + + if (ioctl(fd, TIOCMGET, &status) == -1) + { + perror("setRTS(): TIOCMGET"); + return 0; + } + if (level) + status |= TIOCM_RTS; + else + status &= ~TIOCM_RTS; + if (ioctl(fd, TIOCMSET, &status) == -1) + { + perror("setRTS(): TIOCMSET"); + return 0; + } + return 1; +} + +int setDTR(unsigned short level) +{ + int status; + + if (ioctl(fd, TIOCMGET, &status) == -1) + { + perror("setDTR(): TIOCMGET"); + return 0; + } + if (level) + status |= TIOCM_DTR; + else + status &= ~TIOCM_DTR; + if (ioctl(fd, TIOCMSET, &status) == -1) + { + perror("setDTR: TIOCMSET"); + return 0; + } + return 1; +} + +/* This portion of code was written by Roger Clark + * It was informed by various other pieces of code written by Leaflabs to reset their + * Maple and Maple mini boards + */ + +main(int argc, char *argv[]) +{ + + if (argc < 2 || argc > 3) + { + printf("Usage upload-reset \n\r"); + return; + } + + if (openserial(argv[1])) + { + // Send magic sequence of DTR and RTS followed by the magic word "1EAF" + setRTS(false); + setDTR(false); + setDTR(true); + + usleep(50000L); + + setDTR(false); + setRTS(true); + setDTR(true); + + usleep(50000L); + + setDTR(false); + + usleep(50000L); + + write(fd, "1EAF", 4); + + closeserial(); + if (argc == 3) + { + usleep(atol(argv[2]) * 1000L); + } + } + else + { + printf("Failed to open serial device.\n\r"); + } +} diff --git a/Code/devterm_keyboard/upload/upload_bin.sh b/Code/devterm_keyboard/upload/upload_bin.sh new file mode 100755 index 0000000..e6fc882 --- /dev/null +++ b/Code/devterm_keyboard/upload/upload_bin.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +altID="2" +usbID="1EAF:0003" +serial_port="/dev/ttyACM0" + +# Default export location +# binfile="../devterm_keyboard.ino.generic_stm32f103r8.bin" +binfile="devterm_keyboard.ino.bin" + +# Send magic numbers via serial to enter DFU mode. +# This needs pyserial, so it's installed quietly: +# pip install -q pyserial +./dfumode.py -p $serial_port -b 9600 -s 1500 + +# Alternatively you can compile the C program that does the same thing: +# gcc upload-reset.c -o upload-reset +# ./upload-reset $serial_port 1500 + +# Upload binary file +dfu-util -d ${usbID} -a ${altID} -D ${binfile} -R + +echo "Waiting for $serial_port serial..." +COUNTER=0 +while [ ! -c $serial_port ] && ((COUNTER++ < 40)); do + sleep 0.1 +done +echo Done + +