From 38c5ae5b60eae9562b97da42f47af3861847f8e5 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 8 May 2022 15:51:35 -0700 Subject: *Proper* serial port for memory downloads. 115200 8O2 RS232 with CRTRTS. --- tool/con.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tool/connect | 13 ++++--- tool/download.tcl | 33 +++++++++++++++++ tool/p8bin2uart.c | 2 +- 4 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 tool/con.c create mode 100755 tool/download.tcl (limited to 'tool') diff --git a/tool/con.c b/tool/con.c new file mode 100644 index 0000000..8522786 --- /dev/null +++ b/tool/con.c @@ -0,0 +1,106 @@ +/* con device */ + +#include +#include +#include +#include +#include +#include +#include + +struct termios save; + +void +host(int fd) +{ + int cc; + char buf[128]; + + for (;;) { + cc = read(fd, buf, sizeof buf); +#ifdef HEX + if (cc < 0) + break; + for (int i = 0; i < cc; ++i) { + char hex[3]; + sprintf(hex, "%02X", (unsigned char) buf[i]); + write(1, hex, 2); + } +#else + if (cc > 0) + write(1, buf, cc); + else if (cc < 0) + break; +#endif + } +} + +void +hup(int signo) +{ + write(1, "HUP\n", 4); + tcsetattr(0, TCSADRAIN, &save); + _exit(0); +} + +void +user(int fd) +{ + char c, last = '\r'; + + signal(SIGHUP, hup); + for (;;) + while (read(0, &c, 1) > 0) { + if (c == '~' && (last == '\n' || last == '\r' + || last == 4)) { + read(0, &c, 1); + if (c == '.') + return; + } + write(fd, &c, 1); + last = c; + } +} + +int +main(int argc, char *argv[]) +{ + int fd; + pid_t pid; + struct termios t; + + if (argc != 2) + exit(1); + + fd = open(argv[1], O_RDWR | O_NDELAY); + if (fd < 0) + exit(2); + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY); + tcgetattr(fd, &t); + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + tcsetattr(fd, TCSADRAIN, &t); + + tcgetattr(0, &t); + save = t; + t.c_iflag = 0; + t.c_oflag = 0; + t.c_lflag = 0; + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + tcsetattr(0, TCSADRAIN, &t); + + if ((pid = fork()) > 0) { + user(fd); + } else if (pid == 0) { + host(fd); + } else { + perror("fork"); + _exit(EXIT_FAILURE); + } + + tcsetattr(0, TCSADRAIN, &save); + kill(pid, SIGKILL); + close(fd); + _exit(EXIT_SUCCESS); +} diff --git a/tool/connect b/tool/connect index 536db5b..f900e0c 100755 --- a/tool/connect +++ b/tool/connect @@ -1,21 +1,24 @@ #!/bin/bash -set -eux +set -eu -OLD_SETTINGS="$(stty -F /dev/ttyUSB0 -g)" +OLD_SETTINGS="$(stty -g -F /dev/ttyUSB0)" stty -F /dev/ttyUSB0 \ 115200 \ -drain \ -clocal \ cread \ - -crtscts \ + crtscts \ cs8 \ cstopb \ -hup \ parenb \ - -parodd \ + parodd \ + -cmspar \ -igncr \ + ignpar \ + -parmrk \ inpck \ -istrip \ -ixany \ @@ -26,4 +29,4 @@ stty -F /dev/ttyUSB0 \ con /dev/ttyUSB0 || true -stty -F "$OLD_SETTINGS" +stty -drain "$OLD_SETTINGS" -F /dev/ttyUSB0 2> /dev/null diff --git a/tool/download.tcl b/tool/download.tcl new file mode 100755 index 0000000..c0dca55 --- /dev/null +++ b/tool/download.tcl @@ -0,0 +1,33 @@ +#!/usr/bin/env expect + +set timeout 3600 + +set core 0 +set wordsperline 1 + +if {$::argc > 1} { + set core [lindex $::argv 0] + set wordsperline [lindex $::argv 1] +} elseif {$::argc > 0} { + set core [lindex $::argv 0] +} + +spawn tool/connect + +send "@[format %x [expr $core * 32768 / $wordsperline]]\n" + +while {[gets stdin line] >= 0} { + send "$line\n" + expect -ex "$line\n" +} + +# It's likely we ended with a very large zero-memory operation. We want to see +# two command bytes echoed back to us in order to guarantee that the zero +# operation has completely flushed to memory. +send "?" +expect -ex "?" +send "?" +expect -ex "?" + +send "\n~." +wait diff --git a/tool/p8bin2uart.c b/tool/p8bin2uart.c index de5a328..88c19cd 100644 --- a/tool/p8bin2uart.c +++ b/tool/p8bin2uart.c @@ -131,7 +131,7 @@ load(FILE *fp) return v; } -#define MAX_LINE_SIZE 63 +#define MAX_LINE_SIZE 127 char buf[MAX_LINE_SIZE * 2] = {0}; -- cgit v1.2.3