From 06b78d43fac03a12d155aee03385ceb9b8588655 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 13 Oct 2020 06:49:48 +0300 Subject: [PATCH] emurom client program --- .gitignore | 1 + emurom/Makefile | 23 +++ emurom/src/emurom.c | 384 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 408 insertions(+) create mode 100644 emurom/Makefile create mode 100644 emurom/src/emurom.c diff --git a/.gitignore b/.gitignore index 2d76d46..3f1b0a9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ *.net gerber fw/romdev +emurom/emurom diff --git a/emurom/Makefile b/emurom/Makefile new file mode 100644 index 0000000..8a0e82f --- /dev/null +++ b/emurom/Makefile @@ -0,0 +1,23 @@ +PREFIX ?= /usr/local + +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +bin = emurom + +CFLAGS = -pedantic -Wall -g + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) + +.PHONY: install +install: + mkdir $(DESTDIR)$(PREFIX)/bin + cp $(bin) $(DESTDIR)$(PREFIX)/bin/$(bin) + +.PHONY: uninstall +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/$(bin) diff --git a/emurom/src/emurom.c b/emurom/src/emurom.c new file mode 100644 index 0000000..3f83126 --- /dev/null +++ b/emurom/src/emurom.c @@ -0,0 +1,384 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +enum { FMT_BIN, FMT_IHEX, FMT_SREC }; + +int send_bin(FILE *infile, int dev); +int send_ihex(FILE *infile, int dev); +int send_srec(FILE *infile, int dev); +void print_usage(const char *argv0); + +FILE *infile; +int sdev; +int base_addr; + +int main(int argc, char **argv) +{ + int i; + char *endp; + const char *serdev = "/dev/ttyACM0"; + const char *fname = 0; + struct termios term; + int (*send)(FILE*, int) = send_bin; + + for(i=1; i 0) { + if((num = read(fd, buf, bufsz)) <= 0) { + break; + } + + for(i=0; i= 256) { + fprintf(stderr, "cmd_write: invalid byte value: %d\n", val); + return -1; + } + + sprintf(buf, "w %d\n", val); + return cmd(dev, buf); +} + +int send_bin(FILE *infile, int dev) +{ + int c, res = -1; + long count = 0, fsz = -1; + + if(fseek(infile, 0, SEEK_END) != -1) { + fsz = ftell(infile); + rewind(infile); + } + + if(cmd(dev, "p\n") == -1 || cmd_addr(dev, 0) == -1) { + return -1; + } + + while((c = fgetc(infile)) != -1) { + if(cmd_write(dev, c) == -1) { + goto end; + } + + if(fsz > 0) { + printf("\r%ld/%ld ", ++count, fsz); + fflush(stdout); + } + } + res = 0; + +end: + if(fsz > 0) putchar('\n'); + cmd(dev, "b\n"); + return res; +} + +long hexval(const char *s, int digits) +{ + int i; + long val = 0; + + for(i=0; i= 'a') { + val |= *s - 'a' + 10; + } else if(*s >= 'A') { + val |= *s - 'A' + 10; + } else { + val |= *s - '0'; + } + s++; + } + return val; +} + +const char *substr(const char *s, int len) +{ + char *tmp; + static char *buf; + static int buflen; + + if(len > buflen) { + if(!(tmp = malloc(len + 1))) { + perror("failed to allocate substring buffer"); + return 0; + } + free(buf); + buf = tmp; + buflen = len; + } + memcpy(buf, s, len); + buf[len] = 0; + return buf; +} + +enum { + TYPE_DATA = 0, + TYPE_EOF = 1, + TYPE_EXT16 = 2, + TYPE_START16 = 3, + TYPE_EXT32 = 4, + TYPE_START32 = 5 +}; + +int send_ihex(FILE *infile, int dev) +{ + char line[512], *ptr; + int res = -1, count, addr, type, val; + int cur_addr = -1, offs = 0; + + if(cmd(dev, "p\n") == -1) { + return -1; + } + + while(fgets(line, sizeof line, infile)) { + if(line[0] != ':') continue; + + ptr = line + 1; + + if((count = hexval(ptr, 2)) == -1) { + fprintf(stderr, "ihex: invalid count field: %s\n", substr(ptr, 2)); + goto end; + } + ptr += 2; + if((addr = hexval(ptr, 4)) == -1) { + fprintf(stderr, "ihex: invalid address field: %s\n", substr(ptr, 4)); + goto end; + } + ptr += 4; + if((type = hexval(ptr, 2)) == -1 || type > 5) { + fprintf(stderr, "ihex: invalid type field: %s\n", substr(ptr, 2)); + goto end; + } + ptr += 2; + + switch(type) { + case TYPE_DATA: + addr += base_addr + offs; + if(cur_addr != addr) { + cur_addr = addr; + if(cmd_addr(dev, addr) == -1) { + goto end; + } + } + + cur_addr += count; + while(count-- > 0) { + if((val = hexval(ptr, 2)) == -1) { + fprintf(stderr, "ihex: invalid value: %s\n", substr(ptr, 2)); + goto end; + } + if(cmd_write(dev, val) == -1) { + goto end; + } + ptr += 2; + } + break; + + case TYPE_EOF: + res = 0; + goto end; + + case TYPE_EXT16: + if((val = hexval(ptr, 4)) == -1) { + fprintf(stderr, "ihex: invalid extended segment address: %s\n", substr(ptr, 4)); + goto end; + } + offs = val << 4; + ptr += 4; + break; + + case TYPE_EXT32: + if((val = hexval(ptr, 8)) == -1) { + fprintf(stderr, "ihex: invalid extended linear address: %s\n", substr(ptr, 8)); + goto end; + } + offs = val; + ptr += 8; + break; + + default: + break; + } + + } + res = 0; + +end: + cmd(dev, "b\n"); + return res; +} + +int send_srec(FILE *infile, int dev) +{ + fprintf(stderr, "TODO: SREC format not implemented yet\n"); + return -1; +} + +void print_usage(const char *argv0) +{ + printf("Usage: %s [options] [input file]\n", argv0); + printf("If no input file is specified, defaults to reading standard input\n"); + printf("Options:\n"); + printf(" -d devrom board USB serial port (default: /dev/ttyACM0)\n"); + printf(" -f format of the input file [bin/ihex/srec] (default: bin)\n"); + printf(" -a address offset (default: 0)\n"); + printf(" -h print usage and exit\n"); +} -- 1.7.10.4