From a54e26ee7fee074363335835094e0ed26423f37d Mon Sep 17 00:00:00 2001 From: Dmitry Nedospasov Date: Sun, 8 Sep 2013 15:04:21 +0200 Subject: [PATCH 1/2] Initial libftdi support * Update Makefile * Add optional libftdi target * Wrap libftdi code in #ifdef LIBFTDI * Define INCS and LIBS on command line * Assume vid: 0x403 pid: 0x6015 (FT230x) --- Makefile | 11 ++-- lpcflash.c | 106 +++++++++++++++++++++--------- serial.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++---- serial.h | 18 +++++- serial_cmd.c | 105 +++++++++++++++--------------- serial_cmd.h | 14 ++-- 6 files changed, 319 insertions(+), 113 deletions(-) diff --git a/Makefile b/Makefile index beb5f97..aee59f5 100644 --- a/Makefile +++ b/Makefile @@ -33,18 +33,21 @@ CMDS=lpcflash OBJS=lpcflash.o serial.o base64.o serial_cmd.o msg.o const.o chksum.o -LIBS= -INCS= -CC=gcc +# LIBS= +# INCS= +CC=cc CFLAGS=-Wall # -ansi -pedantic CFLAGS+=-g -CFLAGS+=${INCS} ${LIBS} +CFLAGS+=${INCS} #CFLAGS+=-DWITH_MAGIC_SLEEP all: lpcflash +libftdi: CFLAGS += -DLIBFTDI +libftdi: all + lpcflash: ${OBJS} ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} diff --git a/lpcflash.c b/lpcflash.c index 726ec62..6dcd47f 100644 --- a/lpcflash.c +++ b/lpcflash.c @@ -53,8 +53,10 @@ #include #include #include - #include +#ifdef LIBFTDI +#include +#endif #include "serial.h" #include "serial_cmd.h" @@ -68,6 +70,14 @@ #define DEFAULT_DEVICE_CCLK 100000UL #define DEFAULT_RAMBUFFER_ADDR 0x10000400UL + +/* Device descriptors */ +int serial_fd = 0; +#ifdef LIBFTDI +struct ftdi_context *ftdi; +int libftdi = 0; +#endif + extern char **lpcisp_status_msg; typedef enum _lpcflash_cmds { @@ -82,12 +92,27 @@ typedef enum _lpcflash_cmds { static unsigned int lpcflash_get_lastsector(unsigned int); static void lpcflash_dumpinfo(mem_info_t *); static void lpcflash_help(void); -static void lpcflash_erase(int, mem_info_t *); +static void lpcflash_erase(mem_info_t *); static int lpcflash_image_dump(int, mem_info_t *, char *); static int lpcflash_image_write(int, mem_info_t *, char *); extern const unsigned long sector_address[][2]; +int lpcflash_cleanup(void) +{ +#ifdef LIBFTDI + if(!libftdi) { + close(serial_fd); + } else { + ftdi_close(); + } +#else + close(serial_fd); +#endif + return(0); + +} + int main(int argc, char **argv) { char *device = NULL; @@ -96,9 +121,8 @@ int main(int argc, char **argv) char c = 0; - int serial_fd = 0; int verbose = 0; - + mem_info_t mem; unsigned int opt_flash_sector_all = 0; @@ -111,6 +135,12 @@ int main(int argc, char **argv) unsigned long baudrate = DEFAULT_BAUDRATE; unsigned int opt_lpcflash_cmd = LPC_NONE; + /* libftdi options */ +#ifdef LIBFTDI + int vid = 0x403; + int pid = 0x6015; +#endif + memset(&mem, 0, sizeof(mem)); mem.ram_buffer_address = DEFAULT_RAMBUFFER_ADDR; @@ -193,24 +223,32 @@ int main(int argc, char **argv) } } - if ( !( - (device) && - (binfile || outfile || opt_lpcflash_cmd) - ) ) { + if ( !(binfile || outfile || opt_lpcflash_cmd) ) { lpcflash_help(); exit(1); } /* open serial port */ - serial_fd = serial_open(device, baudrate); - - if(serial_fd<0) - return(1); + if(device) { + serial_fd = serial_open(device, baudrate); + if(serial_fd<0) + return(1); + } else { +#ifdef LIBFTDI + libftdi = 1; + + if(ftdi_open(baudrate, vid, pid)) + return(1); +#else + lpcflash_help(); + exit(1); +#endif + } - serial_synchronize(serial_fd, mem.cclk); - serial_cmd_read_partid(serial_fd, &mem.cpu.id); - serial_cmd_read_bootcode_version(serial_fd, &mem.cpu.bootcode); - serial_cmd_read_device_serialno(serial_fd, mem.cpu.serial); + serial_synchronize(mem.cclk); + serial_cmd_read_partid(&mem.cpu.id); + serial_cmd_read_bootcode_version(&mem.cpu.bootcode); + serial_cmd_read_device_serialno(mem.cpu.serial); if(opt_flash_sector_from < mem.rom_sector_base) opt_flash_sector_from = mem.rom_sector_base; @@ -227,7 +265,7 @@ int main(int argc, char **argv) mem.rom_address_base = mem.rom_sector_base * 0x1000; - serial_cmd_unlock(serial_fd); + serial_cmd_unlock(); if(opt_flash_sector_all != 0) { mem.img_sector_last = mem.rom_sector_last; @@ -239,19 +277,17 @@ int main(int argc, char **argv) if (opt_lpcflash_cmd == LPC_ERASE) { // erase only - lpcflash_erase(serial_fd, &mem); - close(serial_fd); - return 0; + lpcflash_erase(&mem); + return(lpcflash_cleanup()); } else if(opt_lpcflash_cmd == LPC_INFO) { // dump info only - close(serial_fd); - return 0; + return(lpcflash_cleanup()); } else if(opt_lpcflash_cmd == LPC_WRITEFLASH) { - lpcflash_erase(serial_fd, &mem); + lpcflash_erase(&mem); lpcflash_image_write(serial_fd, &mem, binfile); } else if (opt_lpcflash_cmd == LPC_DUMPFLASH) { @@ -265,18 +301,17 @@ int main(int argc, char **argv) serial_cmd_read_memory(serial_fd, outfile, read_addr, read_size); } - close(serial_fd); - return(0); + return(lpcflash_cleanup()); } -static void lpcflash_erase(int serial_fd, mem_info_t *mem) +static void lpcflash_erase(mem_info_t *mem) { /* erase [entire] (user) flash rom */ printf("[+] erasing sectors %ld - %d", mem->rom_address_base, mem->rom_sector_last); - serial_cmd_prepare_sector(serial_fd, mem->rom_address_base, mem->rom_sector_last); - serial_cmd_erase_sector(serial_fd, mem->rom_address_base, mem->rom_sector_last); + serial_cmd_prepare_sector(mem->rom_address_base, mem->rom_sector_last); + serial_cmd_erase_sector(mem->rom_address_base, mem->rom_sector_last); printf(" - done.\n"); return; @@ -415,8 +450,8 @@ static int lpcflash_image_write(int serial_fd, mem_info_t *mem, char *imgpath) unsigned int j=0; - serial_cmd_prepare_sector(serial_fd, i, i); - serial_cmd_erase_sector(serial_fd, i, i); + serial_cmd_prepare_sector(i, i); + serial_cmd_erase_sector(i, i); for(j=0; j < (0x1000/0x200); j++) { // write in blocksizes of 512 byte @@ -427,7 +462,7 @@ static int lpcflash_image_write(int serial_fd, mem_info_t *mem, char *imgpath) serial_cmd_write_to_ram(serial_fd, mem->ram_buffer_address, nr, outbuf); - serial_cmd_prepare_sector(serial_fd, i, i); + serial_cmd_prepare_sector(i, i); serial_cmd_copy_ram_to_flash(serial_fd, mem->rom_address_base + nwritten, mem->ram_buffer_address, 512); nwritten += nr; @@ -451,7 +486,7 @@ static int lpcflash_image_write(int serial_fd, mem_info_t *mem, char *imgpath) } serial_cmd_write_to_ram(serial_fd, mem->ram_buffer_address, nr, outbuf); - serial_cmd_prepare_sector(serial_fd, i, i); + serial_cmd_prepare_sector(i, i); serial_cmd_copy_ram_to_flash(serial_fd, mem->rom_address_base + nwritten, mem->ram_buffer_address, 512); nwritten += nr; @@ -595,7 +630,9 @@ static void lpcflash_help(void) { // l:b:f:c:o:hviAR:F:T:B:a:s: puts("usage: lpcflash"); +#ifndef LIBFTDI puts("\t -l (8N1 cu device)"); +#endif puts("\t -b (default 115200UL)"); puts("\t -f (.bin file)"); puts("\t -o "); @@ -607,6 +644,11 @@ static void lpcflash_help(void) puts("\t -B "); puts("\t -a (ram/rom memory address in hex)"); puts("\t -s (only for -a: size in hex - word aligned)"); + puts(""); + puts("optional flags:"); +#ifdef LIBFTDI + puts("\t[-l] (8N1 cu device, libftdi if omitted)"); +#endif puts("\t[-v] (be verbose)"); puts("\t[-h] ( _o/ )"); puts("\t[-i] (dump cpu infos)"); diff --git a/serial.c b/serial.c index a8ea925..6d8888b 100644 --- a/serial.c +++ b/serial.c @@ -54,6 +54,9 @@ #include #include #include +#ifdef LIBFTDI +#include +#endif #include "msg.h" #include "serial.h" @@ -75,7 +78,7 @@ static void magic(void) } #endif -int serial_readline(char *buf, int len, int serial_fd) +int serial_readline(char *buf, int len) { char *p = buf; size_t remaining = len; @@ -84,22 +87,41 @@ int serial_readline(char *buf, int len, int serial_fd) memset(buf, 0, remaining); while(remaining>0) { - + // need to read one character at a time to detect '\n' + +#ifdef LIBFTDI + if(!libftdi) + { + nread = read(serial_fd, p, 1); + } else { + nread = ftdi_read_data(ftdi, p, 1); + } +#else nread = read(serial_fd, p, 1); - +#endif + switch (nread) { - + case -1: if (errno == EAGAIN || errno == EINTR) { - WARN("read interrupted"); - continue; - } - err(1, "read(): "); + WARN("read interrupted"); + continue; + } + err(1, "read(): "); break; - - case 0: - errx(1, "unexpected EOF read"); + +#ifdef LIBFTDI + case -666: + errx(1, "USB Unavailable"); + break; + + case 0: + if(!libftdi) errx(1, "unexpected EOF read"); +#else + case 0: + errx(1, "unexpected EOF read"); +#endif break; } @@ -117,7 +139,7 @@ int serial_readline(char *buf, int len, int serial_fd) return p - buf; } -int serial_send(int serial_fd, int len, char *data) +int serial_send(int len, char *data) { ssize_t nwritten; char *p = data; @@ -130,8 +152,17 @@ int serial_send(int serial_fd, int len, char *data) while (remaining > 0) { errno = 0; - + +#ifdef LIBFTDI + if(!libftdi) { + nwritten = write(serial_fd, (unsigned char *)p, remaining); + } else { + nwritten = ftdi_write_data(ftdi, (unsigned char *)p, remaining); + } +#else nwritten = write(serial_fd, (unsigned char *)p, remaining); +#endif + switch (nwritten) { case -1: @@ -141,7 +172,14 @@ int serial_send(int serial_fd, int len, char *data) } err(1,"write(): "); break; - + +#ifdef LIBFTDI + case -666: /* FTDI USB unavailable */ + nwritten = 0; + warn("write(): "); + break; +#endif + case 0: warn("write(): "); break; @@ -348,6 +386,118 @@ int serial_open(char *device, int baudrate) return(fd); } +#ifdef LIBFTDI +void ftdi_close(void) +{ + int f; + + // Looks like the reset doesn't help + /* + f = ftdi_usb_reset(ftdi); + if (f<0) + { + fprintf(stderr, "Unable to reset device: (%s)", + ftdi_get_error_string(ftdi)); + } */ + + f = ftdi_usb_close(ftdi); + if (f<0) + { + fprintf(stderr, "Unable to close device: (%s)", + ftdi_get_error_string(ftdi)); + } + + free(ftdi); +} + + +int ftdi_open(int baudrate, int vid, int pid) +{ + int interface = INTERFACE_ANY; + int f; /* return value */ + + if ((ftdi = ftdi_new()) == 0) + { + fprintf(stderr, "ftdi_new failed\n"); + return EXIT_FAILURE; + } + + if (!vid && !pid && (interface == INTERFACE_ANY)) + { + ftdi_set_interface(ftdi, INTERFACE_ANY); + struct ftdi_device_list *devlist; + int res; + if ((res = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0) + { + fprintf(stderr, "No FTDI with default VID/PID found\n"); + ftdi_close(); + } + if (res == 1) + { + f = ftdi_usb_open_dev(ftdi, devlist[0].dev); + if (f<0) + { + fprintf(stderr, "Unable to open deviced: (%s)", + ftdi_get_error_string(ftdi)); + } + } + ftdi_list_free(&devlist); + if (res > 1) + { + fprintf(stderr, "%d Devices found, please select Device with VID/PID\n", res); + /* TODO: List Devices*/ + ftdi_close(); + } + if (res == 0) + { + fprintf(stderr, "No Devices found with default VID/PID\n"); + ftdi_close(); + } + } + else + { + // Select interface + ftdi_set_interface(ftdi, interface); + + // Open device + f = ftdi_usb_open(ftdi, vid, pid); + } + + if (f < 0) + { + fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi)); + exit(-1); + } + // Set baudrate + f = ftdi_set_baudrate(ftdi, baudrate); + if (f < 0) + { + fprintf(stderr, "unable to set baudrate: %d (%s)\n", f, ftdi_get_error_string(ftdi)); + exit(-1); + } + /* Set line parameters + * + * TODO: Make these parameters settable from the command line + * + * Parameters are choosen that sending a continous stream of 0x55 + * should give a square wave + * + */ + f = ftdi_set_line_property(ftdi, 8, STOP_BIT_1, NONE); + if (f < 0) + { + fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi)); + exit(-1); + } + + return(0); +} + +int ftdi_purge(void) +{ + return ftdi_usb_purge_buffers(ftdi); +} +#endif diff --git a/serial.h b/serial.h index e53794e..cc20324 100644 --- a/serial.h +++ b/serial.h @@ -44,10 +44,22 @@ #define CLR(var,flag) (var) &= ~(flag) #define SET(var,flag) (var) |= (flag) - /* serial i/o routines */ +extern int serial_fd; +#ifdef LIBFTDI +extern struct ftdi_context *ftdi; +extern int libftdi; +#endif + /* serial i/o routines */ int serial_open(char *, int); -int serial_readline(char *, int, int); -int serial_send(int, int, char *); +int serial_readline(char *, int); +int serial_send(int, char *); + + /* ftdi i/o routines */ +#ifdef LIBFTDI +int ftdi_open(int, int, int); +void ftdi_close(void); +int ftdi_purge(void); +#endif #endif diff --git a/serial_cmd.c b/serial_cmd.c index 9886ce5..399dde6 100644 --- a/serial_cmd.c +++ b/serial_cmd.c @@ -96,9 +96,9 @@ int serial_cmd_write_to_ram(int serial_fd, unsigned int ramstart, unsigned int c // TODO check ramaddr word boundary -ths snprintf(cmd, sizeof(cmd), "W %d %d\r\n", ramstart, count); - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); len = 0; @@ -127,14 +127,14 @@ int serial_cmd_write_to_ram(int serial_fd, unsigned int ramstart, unsigned int c memset(&buf,0,sizeof(buf)); snprintf(buf, sizeof(buf), "%s\r\n", uuout); - serial_send(serial_fd, strlen((char *)buf), buf); + serial_send(strlen((char *)buf), buf); } //printf("checksum: %d\n",checksum); snprintf(cmd, sizeof(cmd), "%d\r\n", checksum); - serial_send(serial_fd, strlen(cmd), cmd); - len=serial_readline(buf, sizeof(buf), serial_fd); + serial_send(strlen(cmd), cmd); + len=serial_readline(buf, sizeof(buf)); if(serial_check_ok(buf, len)) ; @@ -168,7 +168,7 @@ int serial_cmd_write_to_ram(int serial_fd, unsigned int ramstart, unsigned int c memset(&buf,0,sizeof(buf)); snprintf(buf, sizeof(buf), "%s\r\n", uuout); - nwritten = serial_send(serial_fd, strlen((char *)buf), buf); + nwritten = serial_send(strlen((char *)buf), buf); memset(&buf,0,sizeof(buf)); } @@ -186,14 +186,14 @@ int serial_cmd_write_to_ram(int serial_fd, unsigned int ramstart, unsigned int c memset(&buf,0,sizeof(buf)); snprintf(buf, sizeof(buf), "%s\r\n", uuout); - serial_send(serial_fd, (unsigned int)strlen((char *)buf), buf); + serial_send((unsigned int)strlen((char *)buf), buf); memset(&buf,0,sizeof(buf)); // send checksum snprintf(cmd, sizeof(cmd), "%d\r\n", checksum); - serial_send(serial_fd, strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + serial_send(strlen(cmd), cmd); + len = serial_readline(buf, sizeof(buf)); if(serial_check_ok(buf, len)) ; @@ -278,8 +278,8 @@ int serial_cmd_read_memory(int serial_fd, char *imgpath, unsigned int start, uns len = 0; snprintf(cmd, sizeof(cmd), "R %d %d\r\n", start, count); - serial_send(serial_fd, strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + serial_send(strlen(cmd), cmd); + len = serial_readline(buf, sizeof(buf)); // printf("\n---\nread mem ret: \n"); // print_hex_ascii_line((unsigned char *)buf, len, 0); @@ -302,7 +302,7 @@ int serial_cmd_read_memory(int serial_fd, char *imgpath, unsigned int start, uns unsigned int binlen=0; unsigned int uulen=0; - len=serial_readline(buf, sizeof(buf), serial_fd); + len=serial_readline(buf, sizeof(buf)); //printf("\n---\nread mem ret: \n"); //print_hex_ascii_line((unsigned char *)buf, len, 0); @@ -329,14 +329,14 @@ int serial_cmd_read_memory(int serial_fd, char *imgpath, unsigned int start, uns int got_chksum = strtol(uuline, NULL, 10); if(got_chksum == checksum) - sent = serial_send(serial_fd, 4, "OK\r\n"); + sent = serial_send(4, "OK\r\n"); else { //XXX implement proper resend request handling! printf("\n[e] (%d > %d ?) sumlen=%d - count=%d - checksum mismatch: %x == %x\n", binlen, uulen, sumlen, count, got_chksum, checksum); - sent = serial_send(serial_fd, 4, "RESEND\r\n"); + sent = serial_send(4, "RESEND\r\n"); } checksum = serial_checksum_init(); @@ -396,8 +396,8 @@ int serial_cmd_copy_ram_to_flash(int serial_fd, unsigned int flash_addr, unsigne memset(&buf,0,sizeof(buf)); len=0; - serial_send(serial_fd, strlen(cmd), cmd); - len=serial_readline(buf, sizeof(buf), serial_fd); + serial_send(strlen(cmd), cmd); + len=serial_readline(buf, sizeof(buf)); //printf("\n---\ncopy ram to flash ret: \n"); //print_hex_ascii_line((unsigned char *)buf, len, 0); @@ -427,8 +427,8 @@ int serial_cmd_go(int serial_fd, unsigned int addr) snprintf(cmd, sizeof(cmd), "G %u T\r\n", addr); - serial_send(serial_fd, strlen(cmd), cmd); - len=serial_readline(buf, sizeof(buf), serial_fd); + serial_send(strlen(cmd), cmd); + len=serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); @@ -471,7 +471,7 @@ int serial_retcode(char *buf, int buflen) } -int serial_cmd_prepare_sector(int serial_fd, unsigned int from_sector, unsigned int to_sector) +int serial_cmd_prepare_sector(unsigned int from_sector, unsigned int to_sector) { char buf[128]; int len=0; @@ -485,9 +485,8 @@ int serial_cmd_prepare_sector(int serial_fd, unsigned int from_sector, unsigned memset(&buf,0,sizeof(buf)); len=0; - serial_send(serial_fd, strlen(cmd), cmd); - - len=serial_readline(buf, sizeof(buf), serial_fd); + serial_send(strlen(cmd), cmd); + len=serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); if(ret != CMD_SUCCESS) @@ -497,7 +496,7 @@ int serial_cmd_prepare_sector(int serial_fd, unsigned int from_sector, unsigned } -int serial_cmd_erase_sector(int serial_fd, unsigned int from_sector, unsigned int to_sector) +int serial_cmd_erase_sector(unsigned int from_sector, unsigned int to_sector) { char buf[128]; int len=0; @@ -509,9 +508,9 @@ int serial_cmd_erase_sector(int serial_fd, unsigned int from_sector, unsigned in memset(&buf,0,sizeof(buf)); len=0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); if(ret != CMD_SUCCESS) @@ -521,7 +520,7 @@ int serial_cmd_erase_sector(int serial_fd, unsigned int from_sector, unsigned in } -int serial_cmd_unlock(int serial_fd) +int serial_cmd_unlock(void) { char buf[128]; int len=0; @@ -531,9 +530,9 @@ int serial_cmd_unlock(int serial_fd) memset(&buf,0,sizeof(buf)); len=0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); if(ret != CMD_SUCCESS) @@ -544,7 +543,7 @@ int serial_cmd_unlock(int serial_fd) } -int serial_cmd_read_device_serialno(int serial_fd, unsigned int *ser) +int serial_cmd_read_device_serialno(unsigned int *ser) { char buf[128]; int len = 0; @@ -555,11 +554,11 @@ int serial_cmd_read_device_serialno(int serial_fd, unsigned int *ser) memset(&buf,0,sizeof(buf)); len = 0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); while(ret != CMD_SUCCESS) { - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); memset(&buf,0,sizeof(buf)); @@ -567,7 +566,7 @@ int serial_cmd_read_device_serialno(int serial_fd, unsigned int *ser) } for(i=0;i<4;i++) { - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ser[i]=(unsigned int)atoi(buf); } @@ -578,7 +577,7 @@ int serial_cmd_read_device_serialno(int serial_fd, unsigned int *ser) } -int serial_cmd_read_bootcode_version(int serial_fd, unsigned int *ver) +int serial_cmd_read_bootcode_version(unsigned int *ver) { char buf[128]; int len=0; @@ -589,17 +588,17 @@ int serial_cmd_read_bootcode_version(int serial_fd, unsigned int *ver) memset(&buf,0,sizeof(buf)); len=0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); while(ret != CMD_SUCCESS) { - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); memset(&buf,0,sizeof(buf)); len = 0; } // read response 0 - partid - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); result = (unsigned int)atoi(buf); @@ -612,7 +611,7 @@ int serial_cmd_read_bootcode_version(int serial_fd, unsigned int *ver) } -int serial_cmd_read_partid(int serial_fd, unsigned int *id) +int serial_cmd_read_partid(unsigned int *id) { char buf[128]; int len=0; @@ -623,17 +622,17 @@ int serial_cmd_read_partid(int serial_fd, unsigned int *id) memset(&buf,0,sizeof(buf)); len=0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); while(ret != CMD_SUCCESS) { - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); memset(&buf,0,sizeof(buf)); len = 0; } // read response 0 - partid - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); result = (unsigned int)atoi(buf); @@ -716,9 +715,9 @@ int serial_cmd_set_baudrate(int serial_fd, unsigned long baudrate, unsigned int memset(&buf,0,sizeof(buf)); len = 0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); if(ret != CMD_SUCCESS) @@ -743,9 +742,9 @@ int serial_cmd_echo(int serial_fd, unsigned int echo) memset(&buf,0,sizeof(buf)); len = 0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); if(ret != CMD_SUCCESS) @@ -773,9 +772,9 @@ int serial_cmd_blankcheck_sector(int serial_fd, unsigned int start_sector, unsig memset(&buf,0,sizeof(buf)); len = 0; - serial_send(serial_fd, strlen(cmd), cmd); + serial_send(strlen(cmd), cmd); - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); ret = serial_retcode(buf, len); if(ret != CMD_SUCCESS) @@ -791,18 +790,18 @@ int serial_check_ok(char *buf, int buflen) return memcmp(&buf[buflen-4], "OK\r\n", 4) == 0; } -int serial_synchronize(int serial_fd, unsigned int freq) +int serial_synchronize(unsigned int freq) { char buf[128]; int len = 0; memset(&buf,0,sizeof(buf)); - serial_send(serial_fd, 1, "?"); - len = serial_readline(buf, sizeof(buf), serial_fd); + serial_send(1, "?"); + len = serial_readline(buf, sizeof(buf)); - serial_send(serial_fd, len, buf); + serial_send(len, buf); memset(&buf,0,sizeof(buf)); - len = serial_readline(buf, sizeof(buf), serial_fd); + len = serial_readline(buf, sizeof(buf)); if(!serial_check_ok(buf, len)) return -1; @@ -811,12 +810,12 @@ int serial_synchronize(int serial_fd, unsigned int freq) len = 0; snprintf(buf, sizeof(buf), "%d\r\n", freq); - serial_send(serial_fd, (int)strlen(buf), buf); + serial_send((int)strlen(buf), buf); memset(&buf,0,sizeof(buf)); len = 0; - len=serial_readline(buf, sizeof(buf), serial_fd); + len=serial_readline(buf, sizeof(buf)); if(!serial_check_ok(buf, len)) return -1; diff --git a/serial_cmd.h b/serial_cmd.h index ae2f5f5..5a076fe 100644 --- a/serial_cmd.h +++ b/serial_cmd.h @@ -50,16 +50,16 @@ int serial_cmd_copy_ram_to_flash(int, unsigned int, unsigned int, unsigned int); int serial_cmd_go(int, unsigned int); // addr int serial_cmd_compare(int, unsigned int, unsigned int, unsigned int); // addr1, addr2, number of bytes -int serial_cmd_read_partid(int, unsigned int *); -int serial_cmd_read_bootcode_version(int, unsigned int *); -int serial_cmd_read_device_serialno(int, unsigned int *); -int serial_cmd_prepare_sector(int, unsigned int, unsigned int); -int serial_cmd_unlock(int); -int serial_cmd_erase_sector(int, unsigned int, unsigned int); +int serial_cmd_read_partid(unsigned int *); +int serial_cmd_read_bootcode_version(unsigned int *); +int serial_cmd_read_device_serialno(unsigned int *); +int serial_cmd_prepare_sector(unsigned int, unsigned int); +int serial_cmd_unlock(void); +int serial_cmd_erase_sector(unsigned int, unsigned int); void serial_cmd_remap_bootvect(int, unsigned long); -int serial_synchronize(int, unsigned int); +int serial_synchronize(unsigned int); int serial_retcode(char *, int); int serial_check_ok(char *, int); From b28df09b4454014bb63546897b58580e20c49093 Mon Sep 17 00:00:00 2001 From: Dmitry Nedospasov Date: Sun, 8 Sep 2013 17:36:29 +0200 Subject: [PATCH 2/2] Update README --- README.txt => README.md | 64 ++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 27 deletions(-) rename README.txt => README.md (88%) diff --git a/README.txt b/README.md similarity index 88% rename from README.txt rename to README.md index 9f9c537..8036030 100644 --- a/README.txt +++ b/README.md @@ -1,20 +1,19 @@ -2011/01/30 - -lpcflash (beta) - an opensource flash utility for NXP LPC17xx ARM CM3 series +# lpcflash (beta) 2013/09/08 +### an opensource flash utility for NXP LPC17xx ARM CM3 series Currently supporting: - boot rom/on-chip serial bootloader. - - all lpc1700 boot rom loader compatible bootloaders, such as the usb cdc secondary bootloader included in - the opensource LPCboot Suite (will be released soon) + - all lpc1700 boot rom loader compatible bootloaders, such as the usb cdc secondary bootloader included in the opensource LPCboot Suite (will be released soon) lpcflash was written by Thorsten Schroeder and is released under the 2-clause BSD license. Even though it is released under a very flexible and free licence, feedback and feature requests are highly appreciated. -PLATFORMS +#### PLATFORMS lpcflash was tested under Mac OSX 10.6.6 and Ubuntu 10.04 LTS. Target platforms are all LPC1700 based ARM Coretex-M3 processors. -BUILD +#### BUILD +``` $ make gcc -Wall -g -c -o lpcflash.o lpcflash.c gcc -Wall -g -c -o serial.o serial.c @@ -23,11 +22,19 @@ gcc -Wall -g -c -o serial_cmd.o serial_cmd.c gcc -Wall -g -c -o msg.o msg.c gcc -Wall -g -c -o const.o const.c gcc -Wall -g -c -o chksum.o chksum.c -gcc -Wall -g -o lpcflash lpcflash.o serial.o base64.o serial_cmd.o msg.o const.o chksum.o +gcc -Wall -g -o lpcflash lpcflash.o serial.o base64.o serial_cmd.o msg.o const.o chksum.o +``` + +#### BUILD w/libftdi support (requires libftdi) + +``` +LIBS="$(libftdi1-config --libs)" INCS="$(libftdi1-config --cflags)" make libftdi +``` -USAGE +#### USAGE +``` $ ./lpcflash usage: lpcflash -l (8N1 cu device) @@ -47,9 +54,9 @@ usage: lpcflash [-i] (dump cpu infos) [-e] (erase only (== erase and exit)) [-] More infos at https://project.dev.io/code/arm/ +``` - -FEATURES +#### FEATURES + Erase all flash ROM sectors + Erase selected flash ROM sectors/ranges @@ -62,8 +69,9 @@ Everything that is specified within the LPC17xx user documentation (ISP/IAP (fla EXAMPLES: -1) Erase all sectors on an LPC1756 using the on-chip bootloader via serial line +#### Erase all sectors on an LPC1756 using the on-chip bootloader via serial line +``` $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -e -A [*] [*] Detected part ID = 0x25011723: @@ -72,9 +80,11 @@ $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -e -A [*] Boot code: 0x1 [*] [+] erasing sectors 0 - 21 - done. +``` -2) Write a firmware image file to flash ROM sector 0, using the LPC1756 on-chip bootloader via serial line +#### Write a firmware image file to flash ROM sector 0, using the LPC1756 on-chip bootloader via serial line +``` $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -f testbinaries/keykerikiv2-blinke-flashplace-0000h.bin [*] [*] Detected part ID = 0x25011723: @@ -96,9 +106,11 @@ $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -f testbinaries/keykerikiv2-blinke-fl [-] current sector: 0x00 - 0x00000C00 of 0x00000E00 bytes written [-] current sector: 0x00 - 0x00000E00 of 0x00000E00 bytes written [*] done. +``` -3) hexdump (to stdout) flash ROM address 0x00000000-0x00001000 of an LPC1756 using the on-chip bootloader via serial line +#### hexdump (to stdout) flash ROM address 0x00000000-0x00001000 of an LPC1756 using the on-chip bootloader via serial line +``` $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -a 0x00000000 -s 0x1000 [*] [*] Detected part ID = 0x25011723: @@ -123,10 +135,11 @@ $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -a 0x00000000 -s 0x1000 000c0 49 02 00 00 4b 02 00 00 4d 02 00 00 2b 49 8d 46 I K M +I F 000d0 2b 49 2c 48 0a 1a 04 d0 81 f3 09 88 02 22 82 f3 +I,H " [...] +``` +#### hexdump (to stdout) 256 bytes of SRAM address 0x10000000 of an LPC1756 using the on-chip bootloader via serial line -4) hexdump (to stdout) 256 bytes of SRAM address 0x10000000 of an LPC1756 using the on-chip bootloader via serial line - +``` $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -a 0x10000000 -s 0x100 [*] [*] Detected part ID = 0x25011723: @@ -152,9 +165,11 @@ $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -a 0x10000000 -s 0x100 100000d0 22 bb 93 b4 db 19 80 82 c8 fb d1 0e 99 98 2f cc " / 100000e0 9b e1 40 0e 5b 54 b2 51 44 ad fb 01 41 96 45 6d @ [T QD A Em 100000f0 fc 5a 84 cf 2d cb fe 28 07 6b 75 a6 f8 c0 64 32 Z - ( ku d2 +``` -5) Dumping all flash ROM sectors of an LPC1756 to file, starting at flash ROM base sector 0 +#### Dumping all flash ROM sectors of an LPC1756 to file, starting at flash ROM base sector 0 +``` $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -A -B 0 -o flashrom.bin [*] [*] Detected part ID = 0x25011723: @@ -170,26 +185,21 @@ $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -A -B 0 -o flashrom.bin [+] remapping boot interrupt vector. [+] reading sector 0 - 21. Starting at address 00000000, reading 262144 bytes [*] read 00040000 of 00040000 Bytes from address 00000000 +``` -Why? +#### Why? The Official FlashMagic Tool for this task, which is recommended and referred to by NXP is available only for Microsoft Windows operating systems. There is no sourcecode available for porting it to different platforms, and the usage scenarios are quite restricted for non-paying customers. The free FlashMagicTool version is quite restrictive. LPCFlash utility is available as source code under the BSD license. It has been tested with Mac OSX and Linux. A complete list of supported platforms is available in the source code. -Where? +#### Where? Please be aware, that this version is a very early beta testing version. Please send wishes, recommendations, bug-reports and comments to me, using email. Every feedback is highly appreciated! -What else? +#### What else? I'm also working on an open-source LPCboot Suite -Support? +#### Support? Hardware and Developer Boards are expensive. Hardware donations are highly appreciated... - - - - - -