# HG changeset patch # User Michael Spacefalcon # Date 1367376197 0 # Node ID fea204bc7674844b711a519be2a953f0d9f85ca5 # Parent acaac9162574746b0e2228cda176db9ae89a2f78 fc-sertool compiles diff -r acaac9162574 -r fea204bc7674 .hgignore --- a/.hgignore Tue Apr 30 21:35:14 2013 +0000 +++ b/.hgignore Wed May 01 02:43:17 2013 +0000 @@ -5,6 +5,8 @@ \.bin$ \.srec$ +^loadtools/fc-sertool + ^toolchain/binutils-2.21.1/ ^toolchain/binutils-build/ ^toolchain/gcc-4.5.4/ diff -r acaac9162574 -r fea204bc7674 loadtools/Makefile --- a/loadtools/Makefile Tue Apr 30 21:35:14 2013 +0000 +++ b/loadtools/Makefile Wed May 01 02:43:17 2013 +0000 @@ -1,8 +1,14 @@ CC= gcc CFLAGS= -O2 -OBJS= hexdecode.o sercomm.o srecreader.o ttypassthru.o +PROGS= fc-sertool + +SERTOOL_OBJS= hexdecode.o romload.o sercomm.o sertool.o srecreader.o \ + ttypassthru.o -all: ${OBJS} +all: ${PROGS} + +fc-sertool: ${SERTOOL_OBJS} + ${CC} -o $@ ${SERTOOL_OBJS} clean: - rm -f *.o *.out *errs + rm -f *.o *.out *errs ${PROGS} diff -r acaac9162574 -r fea204bc7674 loadtools/romload.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/romload.c Wed May 01 02:43:17 2013 +0000 @@ -0,0 +1,269 @@ +/* + * This module implements the communication protocol for pushing our + * IRAM-loadable code to the Calypso ROM bootloader. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "srecreader.h" + +extern int errno; + +extern char *target_ttydev; +extern int target_fd; + +struct srecreader iramimage; + +static int beacon_interval = 13; /* in milliseconds */ + +static u_char beacon_cmd[2] = {'<', 'i'}; + +static u_char param_cmd[11] = {'<', 'p', + 0x00, /* baud rate select code (115200) */ + 0x00, /* DPLL setup: leave it off like on power-up, */ + /* OsmocomBB does the same thing */ + 0x00, 0x04, /* chip select timing (WS) settings */ + /* our setting matches both OsmocomBB */ + /* and what the ROM runs with */ + /* before receiving this command */ + 0x22, /* FFFF:F900 register config, low byte */ + /* OsmocomBB sends 0x00 here, but I've chosen */ + /* 0x22 to match the setting of this register */ + /* used by the boot ROM before this command. */ + 0x00, 0x01, 0xD4, 0xC0 /* UART timeout */ + /* I've chosen the same value as what the */ + /* boot ROM runs with before getting this cmd */ +}; + +static u_char write_cmd[10] = {'<', 'w', 0x01, 0x01, 0x00}; +static u_char cksum_cmd[3] = {'<', 'c'}; +static u_char branch_cmd[6] = {'<', 'b'}; + +#define INTERMEDIATE_TIMEOUT 500 /* ms to wait for responses */ +#define SERIAL_FLUSH_DELAY 200 /* also in ms */ + +/* + * The following function should be called by command line option + * parsers upon encountering the -i option. + */ +set_beacon_interval(arg) + char *arg; +{ + int i; + + i = atoi(arg); + if (i < 2 || i > 500) { + fprintf(stderr, "invalid -i argument specified\n"); + exit(1); + } + beacon_interval = i; +} + +static int +expect_response(timeout) +{ + char buf[2]; + fd_set fds; + struct timeval tv; + int pass, cc; + + for (pass = 0; pass < 2; ) { + FD_ZERO(&fds); + FD_SET(target_fd, &fds); + tv.tv_sec = 0; + tv.tv_usec = timeout * 1000; + cc = select(target_fd+1, &fds, NULL, NULL, &tv); + if (cc < 0) { + if (errno == EINTR) + continue; + perror("select"); + exit(1); + } + if (cc < 1) + return(-1); + cc = read(target_fd, buf + pass, 2 - pass); + if (cc <= 0) { + perror("read after successful select"); + exit(1); + } + if (pass == 0 && buf[0] != '>') + continue; + pass += cc; + } + return(buf[1]); +} + +static +send_beacons() +{ + printf("Sending beacons to %s\n", target_ttydev); + do + write(target_fd, beacon_cmd, sizeof beacon_cmd); + while (expect_response(beacon_interval) != 'i'); + return 0; +} + +static uint32_t +compute_block_cksum() +{ + uint32_t sum; + int i, llen; + + sum = iramimage.datalen + 5; + llen = iramimage.datalen + 4; + for (i = 0; i < llen; i++) + sum = iramimage.record[i+1]; + return sum; +} + +perform_romload() +{ + int resp; + uint16_t image_cksum; + unsigned long rec_count; + static int zero = 0; + + if (open_srec_file(&iramimage) < 0) + exit(1); + ioctl(target_fd, FIONBIO, &zero); + send_beacons(); + printf("Got beacon response, attempting download\n"); + + usleep(SERIAL_FLUSH_DELAY * 1000); + tcflush(target_fd, TCIFLUSH); + write(target_fd, param_cmd, sizeof param_cmd); + resp = expect_response(INTERMEDIATE_TIMEOUT); + if (resp != 'p') { + if (resp < 0) + fprintf(stderr, "No response to

%c in response to

p\n", + resp); + else + fprintf(stderr, + "Got > %02X in response to

p\n", + resp); + exit(1); + } + printf("

%c in response to w\n", + resp); + else + fprintf(stderr, + "Got > %02X in response to w\n", + resp); + exit(1); + } + /* on to the next record! */ + } + /* got S7 */ + fclose(iramimage.openfile); + if (!rec_count) { + fprintf(stderr, + "%s line %d: S7 without any preceding S3 data records\n", + iramimage.filename, iramimage.lineno); + exit(1); + } + + /* send %c in response to c\n", + resp); + else + fprintf(stderr, + "Got > %02X in response to c\n", + resp); + exit(1); + } + printf("%c in response to b\n", + resp); + else + fprintf(stderr, + "Got > %02X in response to b\n", + resp); + exit(1); + } + printf(" +#include +#include +#include +#include +#include "srecreader.h" + +extern char *target_ttydev; +extern struct srecreader iramimage; + +main(argc, argv) + char **argv; +{ + extern char *optarg; + extern int optind; + int c; + + while ((c = getopt(argc, argv, "i:")) != EOF) + switch (c) { + case 'i': + set_beacon_interval(optarg); + continue; + case '?': + default: +usage: fprintf(stderr, + "usage: fc-sertool [-i beacon-interval] ttyport iramimage.srec\n"); + exit(1); + } + if (argc - optind != 2) + goto usage; + target_ttydev = argv[optind]; + iramimage.filename = argv[optind+1]; + + open_target_serial(); + perform_romload(); + tty_passthru(); + exit(0); +} diff -r acaac9162574 -r fea204bc7674 loadtools/srecreader.c --- a/loadtools/srecreader.c Tue Apr 30 21:35:14 2013 +0000 +++ b/loadtools/srecreader.c Wed May 01 02:43:17 2013 +0000 @@ -88,3 +88,19 @@ return(-1); return srec_cksum(sr); } + +s3s7_get_addr_data(sr) + struct srecreader *sr; +{ + if (sr->record[0] < 5) { + fprintf(stderr, "%s line %d: S%c record is too short\n", + sr->filename, sr->lineno, sr->record_type); + return(-1); + } + sr->datalen = sr->record[0] - 5; + sr->addr = ((uint32_t)sr->record[1] << 24) | + ((uint32_t)sr->record[2] << 16) | + ((uint32_t)sr->record[3] << 8) | + (uint32_t)sr->record[4]; + return(0); +}