# HG changeset patch # User John Tsiombikas # Date 1489292422 -7200 # Node ID e6d499a8eb1d2835ff35116a7591d763b04e7afd initial commit diff -r 000000000000 -r e6d499a8eb1d Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sun Mar 12 06:20:22 2017 +0200 @@ -0,0 +1,12 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +bin = mdcart + +CFLAGS = -pedantic -Wall -g -O0 + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 000000000000 -r e6d499a8eb1d src/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main.c Sun Mar 12 06:20:22 2017 +0200 @@ -0,0 +1,228 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + OP_NONE, + OP_WRITE, + OP_READ, + OP_RESET +}; + +int op_write(FILE *dev, FILE *fp); +int op_read(FILE *dev, FILE *fp); +int op_reset(FILE *dev); +int parse_args(int argc, char **argv); + +int op, verify = 0; +const char *devname = "/dev/ttyUSB0"; +char *fname = 0; +uint32_t start_addr; +int read_size = 128 * 1024; + +int main(int argc, char **argv) +{ + FILE *fp, *devfp; + int dev; + struct termios term; + + if(parse_args(argc, argv) == -1) { + return 1; + } + + if((dev = open(devname, O_RDWR)) == -1) { + fprintf(stderr, "failed to open device %s: %s\n", devname, strerror(errno)); + return 1; + } + if(tcgetattr(dev, &term) == -1) { + fprintf(stderr, "failed to get terminal attributes for %s: %s\n", devname, strerror(errno)); + return 1; + } + term.c_cflag = CS8 | CLOCAL; + term.c_iflag &= ~(IXON | IXOFF); + term.c_lflag = 0; + + cfsetispeed(&term, B38400); + cfsetospeed(&term, B38400); + + if(tcsetattr(dev, TCSANOW, &term) == -1) { + fprintf(stderr, "failed to set terminal attributes for %s: %s\n", devname, strerror(errno)); + return 1; + } + + if(!(devfp = fdopen(dev, "r+"))) { + perror("failed to attach I/O stream to the device file\n"); + return 1; + } + setvbuf(devfp, 0, _IONBF, 0); + + if(fname && !(fp = fopen(fname, op == OP_READ ? "w" : "r"))) { + fprintf(stderr, "failed to open %s: %s\n", fname, strerror(errno)); + return 1; + } + + switch(op) { + case OP_WRITE: + if(op_write(devfp, fp) == -1) { + fprintf(stderr, "write failed\n"); + return 1; + } + break; + + case OP_READ: + if(op_read(devfp, fp) == -1) { + fprintf(stderr, "read failed\n"); + return 1; + } + break; + + case OP_RESET: + if(op_reset(devfp) == -1) { + fprintf(stderr, "reset failed\n"); + return 1; + } + break; + + default: + break; + } + + fclose(devfp); + close(dev); + if(fp) { + fclose(fp); + } + return 0; +} + +#define RET_IF_FAIL(x) \ + if(!fgets(buf, sizeof buf, dev) || buf[0] != 'O') return x + +int op_write(FILE *dev, FILE *fp) +{ + char buf[128]; + int c; + + fprintf(dev, "p\n"); + RET_IF_FAIL(-1); + fprintf(dev, "a%d\n", start_addr); + RET_IF_FAIL(-1); + + while((c = fgetc(fp)) != -1) { + fprintf(dev, "w%d\n", c); + RET_IF_FAIL(-1); + } + + fprintf(dev, "b\n"); + RET_IF_FAIL(-1); + return 0; +} + +int op_read(FILE *dev, FILE *fp) +{ + char buf[128]; + int i, val; + + fprintf(dev, "p\n"); + RET_IF_FAIL(-1); + fprintf(dev, "a%d\n", start_addr); + RET_IF_FAIL(-1); + + for(i=0; i\n"); + printf(" -r|-read \n"); + printf(" -a|-addr
: start address for read/write operations\n"); + printf(" -R|-reset: reboot machine\n"); + printf(" -v|-verify: do verification after writing\n"); + printf(" -s|-size: read size in bytes\n"); + printf(" -d|-device : serial device (eg /dev/ttyUSB0)\n"); + printf(" -h|-help: print usage and exit\n"); + return 0; + + } else { + fprintf(stderr, "invalid argument: %s\n", argv[i]); + return -1; + } + } + + if(!op) { + fprintf(stderr, "you must specify an operation\n"); + return -1; + } + return 0; +}