From: Nathael Pajani Date: Fri, 1 Mar 2013 13:46:32 +0000 (+0100) Subject: Changing binary names X-Git-Tag: v1.0~4 X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=767f21ee80ad3f7919e53b3ca78d7154a90888e5;p=soft%2Ftools%2Flpctools Changing binary names --- diff --git a/Makefile b/Makefile index ddbe91f..702b0d6 100644 --- a/Makefile +++ b/Makefile @@ -4,15 +4,15 @@ CC = $(CROSS_COMPILE)gcc CFLAGS += -Wall -Wextra -O2 -all: isp prog +all: lpcisp lpcprog -isp: isp_main.o isp_utils.o isp_commands.o isp_wrapper.o +lpcisp: lpcisp.o isp_utils.o isp_commands.o isp_wrapper.o -prog: lpc_prog.o isp_utils.o isp_commands.o prog_commands.o parts.o +lpcprog: lpcprog.o isp_utils.o isp_commands.o prog_commands.o parts.o -isp_main.o: isp_utils.h isp_commands.h +lpcisp.o: isp_utils.h isp_commands.h isp_utils.o: @@ -20,7 +20,7 @@ isp_commands.o: isp_utils.h isp_wrapper.o: isp_utils.h isp_commands.h -lpc_prog.o: isp_utils.h isp_commands.h prog_commands.h parts.h +lpcprog.o: isp_utils.h isp_commands.h prog_commands.h parts.h prog_commands.o: isp_utils.h isp_commands.h parts.h diff --git a/isp_main.c b/isp_main.c deleted file mode 100644 index 4a27b23..0000000 --- a/isp_main.c +++ /dev/null @@ -1,319 +0,0 @@ -/********************************************************************* - * - * LPC1114 ISP - * - * - * Written by Nathael Pajani - * - * This programm is released under the terms of the GNU GPLv3 licence - * as can be found on the GNU website : - * - *********************************************************************/ - - -#include /* malloc, free */ -#include -#include - -#include /* open, getopt, close, usleep */ -#include -#include -#include - -#include -#include - -#include /* for serial config */ -#include - -#include /* strncmp, strlen */ - -#include "isp_utils.h" -#include "isp_commands.h" - -#define PROG_NAME "LPC11xx ISP" -#define VERSION "1.0" - -/* short explanation on exit values: - * - * 0 is OK - * 1 is arg error - * - */ - - -void help(char *prog_name) -{ - fprintf(stderr, "-----------------------------------------------------------------------\n"); - fprintf(stderr, "Usage: %s [options] device [-s | --synchronize]\n" \ - " %s [options] device command [command arguments]\n" \ - " Default baudrate is B115200\n" \ - " is the (host) serial line used to programm the device\n" \ - " is one of:\n" \ - " \t unlock, write-to-ram, read-memory, prepare-for-write, copy-ram-to-flash, go, erase,\n" \ - " \t blank-check, read-part-id, read-boot-version, compare, and read-uid.\n" \ - " command specific arguments are as follow:\n" \ - " \t unlock \n" \ - " \t write-to-ram address file : send 'file' to 'address' in ram\n" \ - " \t read-memory address count file : read 'count' bytes from 'address', store then in 'file'\n" \ - " \t prepare-for-write first last : prepare sectors from 'first' to 'last' for write operation\n" \ - " \t copy-ram-to-flash flash_addr ram_addr count : copy count bytes (256, 512, 1024 or 4096)\n" \ - " \t from 'ram_addr' to 'flash_addr'\n" \ - " \t go address mode : execute programm at 'address' (> 0x200) in 'mode' ('arm' or 'thumb')\n" \ - " \t erase first last : erase flash starting from 'first' sector up to (including) 'last' sector \n" \ - " \t blank-check first last : check flash starting from 'first' sector to 'last' sector is blank\n" \ - " \t read-part-id \n" \ - " \t read-boot-version \n" \ - " \t compare address1 address2 count : compare count bytes between address1 and address2\n" \ - " \t read-uid \n" \ - " Notes:\n" \ - " - Access to the ISP mode is done by calling this utility once with the synchronize\n" \ - " option and no command. This starts a session. No command can be used before starting\n" \ - " a session, and no other synchronize request must be done once the session is started\n" \ - " unless the target is reseted, which closes the session.\n" \ - " - Echo is turned OFF when starting a session and the command is not available.\n" \ - " - The set-baud-rate command is not available. The SAME baudrate MUST be used for the\n" \ - " whole session. It must be specified on each successive call if the default baudrate\n" \ - " is not used.\n" \ - " - User must issue an 'unlock' command before any of 'copy-ram-to-flash', 'erase',\n" \ - " and 'go' commands.\n" \ - " Available options:\n" \ - " \t -s | --synchronize : Perform synchronization (open session)\n" \ - " \t -b | --baudrate=N : Use this baudrate (does not issue the set-baud-rate command)\n" \ - " \t -t | --trace : turn on trace output of serial communication\n" \ - " \t -h | --help : display this help\n" \ - " \t -v | --version : display version information\n", prog_name, prog_name); - fprintf(stderr, "-----------------------------------------------------------------------\n"); -} - -#define SERIAL_BAUD B115200 - -int trace_on = 0; - -int isp_handle_command(char* cmd, int arg_count, char** args); - -int main(int argc, char** argv) -{ - int baudrate = SERIAL_BAUD; - int crystal_freq = 10000; - int synchronize = 0; - char* isp_serial_device = NULL; - - /* For "command" handling */ - char* command = NULL; - char** cmd_args = NULL; - int nb_cmd_args = 0; - - - /* parameter parsing */ - while(1) { - int option_index = 0; - int c = 0; - - struct option long_options[] = { - {"synchronize", no_argument, 0, 's'}, - {"baudrate", required_argument, 0, 'b'}, - {"trace", no_argument, 0, 't'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "sb:thv", long_options, &option_index); - - /* no more options to parse */ - if (c == -1) break; - - switch (c) { - /* b, baudrate */ - case 'b': - baudrate = atoi(optarg); - /* FIXME: validate baudrate */ - break; - - /* t, trace */ - case 't': - trace_on = 1; - break; - - /* s, synchronize */ - case 's': - synchronize = 1; - break; - - /* v, version */ - case 'v': - printf("%s Version %s\n", PROG_NAME, VERSION); - return 0; - break; - - /* h, help */ - case 'h': - default: - help(argv[0]); - return 0; - } - } - - /* Parse remaining command line arguments (not options). */ - - /* First one should (must) be serial device */ - if (optind < argc) { - isp_serial_device = argv[optind++]; - if (trace_on) { - printf("Serial device : %s\n", isp_serial_device); - } - } - if (isp_serial_device == NULL) { - printf("No serial device given, exiting\n"); - help(argv[0]); - return 0; - } - if (isp_serial_open(baudrate, isp_serial_device) != 0) { - printf("Serial open failed, unable to initiate serial communication with target.\n"); - return -1; - } - - if (synchronize) { - if (optind < argc) { - /* no command can be specified when opening a session */ - printf("No command can be specified with -s or --synchronize (Session opening)\n"); - printf("NOT SYNCHRONIZED !\n"); - return -1; - } - isp_connect(crystal_freq, 0); - isp_serial_close(); - return 0; - } - - /* Next one should be "command" (if present) */ - if (optind < argc) { - command = argv[optind++]; - if (trace_on) { - printf("Command : %s\n", command); - } - } else { - printf("No command given. use -h or --help for help on available commands.\n"); - isp_serial_close(); - return -1; - } - /* And then remaining ones (if any) are command arguments */ - if (optind < argc) { - nb_cmd_args = argc - optind; - cmd_args = malloc(nb_cmd_args * sizeof(char *)); - if (trace_on) { - printf("Command arguments :\n"); - } - while (optind < argc) { - static unsigned int idx = 0; - cmd_args[idx++] = argv[optind++]; - if (trace_on) { - printf("%s\n", cmd_args[idx - 1]); - } - } - } - - if (command != NULL) { - int err = 0; - err = isp_handle_command(command, nb_cmd_args, cmd_args); - if (err >= 0) { - if (trace_on) { - printf("Command \"%s\" handled OK.\n", command); - } - } else { - printf("Error handling command \"%s\" : %d\n", command, err); - } - } - - - if (cmd_args != NULL) { - free(cmd_args); - } - isp_serial_close(); - return 0; -} - -struct isp_command { - int cmd_num; - char* name; - int nb_args; - int (*handler)(int arg_count, char** args); -}; - - -static struct isp_command isp_cmds_list[] = { - {0, "unlock", 0, NULL}, - {1, "write-to-ram", 2, isp_cmd_write_to_ram}, - {2, "read-memory", 3, isp_cmd_read_memory}, - {3, "prepare-for-write", 2, isp_cmd_prepare_for_write}, - {4, "copy-ram-to-flash", 3, isp_cmd_copy_ram_to_flash}, - {5, "go", 2, isp_cmd_go}, - {6, "erase", 2, isp_cmd_erase}, - {7, "blank-check", 2, isp_cmd_blank_check}, - {8, "read-part-id", 0, NULL}, - {9, "read-boot-version", 0, NULL}, - {10, "compare", 3, isp_cmd_compare}, - {11, "read-uid", 0, NULL}, - {-1, NULL, 0, NULL} -}; - -void isp_warn_args(int cmd_num, int arg_count, char** args) -{ - int i = 0; - printf("command \"%s\" needs %d args, got %d.\n", - isp_cmds_list[cmd_num].name, - isp_cmds_list[cmd_num].nb_args, arg_count); - for (i=0; i - * - * This programm is released under the terms of the GNU GPLv3 licence - * as can be found on the GNU website : - * - *********************************************************************/ - - -#include /* malloc, free */ -#include -#include - -#include /* open, getopt, close, usleep */ -#include -#include -#include - -#include -#include - -#include /* for serial config */ -#include - -#include /* strncmp, strlen */ - -#include "isp_utils.h" -#include "isp_commands.h" -#include "prog_commands.h" -#include "parts.h" - -#define PROG_NAME "LPC11xx ISP Prog tool" -#define VERSION "0.01" - - -void help(char *prog_name) -{ - fprintf(stderr, "---------------- "PROG_NAME" --------------------------------\n"); - fprintf(stderr, "Usage: %s [options] serial_device command [command arguments]\n" \ - " Default baudrate is B115200\n" \ - " Default oscilator frequency used is 10000 KHz\n" \ - " is the (host) serial line used to programm the device\n" \ - " is one of:\n" \ - " \t dump, flash, id, blank, go\n" \ - " command specific arguments are:\n" \ - " \t dump file : dump flash content to 'file'\n" \ - " \t flash file : put 'file' to flash, erasing requiered sectors\n" \ - " \t blank : erase whole flash\n" \ - " \t id : get all id information\n" \ - " \t go : execute programm from reset handler in thumb mode and open terminal\n" \ - " Available options:\n" \ - " \t -b | --baudrate=N : Use this baudrate (Same baudrate must be used across whole session)\n" \ - " \t -t | --trace : turn on trace output of serial communication\n" \ - " \t -f | --freq=N : Oscilator frequency of target device\n" \ - " \t -u | --user-code : compute a valid user code for exception vector 7\n" \ - " \t -h | --help : display this help\n" \ - " \t -v | --version : display version information\n", prog_name); - fprintf(stderr, "-----------------------------------------------------------------------\n"); -} - -#define SERIAL_BAUD B115200 - -int trace_on = 0; -int quiet = 0; -static int calc_user_code = 0; - -static int prog_connect_and_id(int freq); -static int prog_handle_command(char* cmd, int dev_id, int arg_count, char** args); - -int main(int argc, char** argv) -{ - int baudrate = SERIAL_BAUD; - int crystal_freq = 10000; - char* isp_serial_device = NULL; - int dev_id = 0; - - /* For "command" handling */ - char* command = NULL; - char** cmd_args = NULL; - int nb_cmd_args = 0; - - - /* parameter parsing */ - while(1) { - int option_index = 0; - int c = 0; - - struct option long_options[] = { - {"synchronized", no_argument, 0, 's'}, - {"baudrate", required_argument, 0, 'b'}, - {"trace", no_argument, 0, 't'}, - {"freq", required_argument, 0, 'f'}, - {"user-code", no_argument, 0, 'u'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "sb:tfuhv", long_options, &option_index); - - /* no more options to parse */ - if (c == -1) break; - - switch (c) { - /* b, baudrate */ - case 'b': - baudrate = atoi(optarg); - /* FIXME: validate baudrate */ - break; - - /* t, trace */ - case 't': - trace_on = 1; - break; - - /* f, freq */ - case 'f': - crystal_freq = atoi(optarg); - break; - - /* u, user-code */ - case 'u': - calc_user_code = 1; - break; - - /* v, version */ - case 'v': - printf("%s Version %s\n", PROG_NAME, VERSION); - return 0; - break; - - /* h, help */ - case 'h': - default: - help(argv[0]); - return 0; - } - } - - /* Parse remaining command line arguments (not options). */ - - /* First one should (must) be serial device */ - if (optind < argc) { - isp_serial_device = argv[optind++]; - if (trace_on) { - printf("Serial device : %s\n", isp_serial_device); - } - } - if (isp_serial_device == NULL) { - printf("No serial device given, exiting\n"); - help(argv[0]); - return 0; - } - if (isp_serial_open(baudrate, isp_serial_device) != 0) { - printf("Serial open failed, unable to initiate serial communication with target.\n"); - return -1; - } - - /* Next one should be "command" (if present) */ - if (optind < argc) { - command = argv[optind++]; - if (trace_on) { - printf("Command : %s\n", command); - } - } else { - printf("No command given. use -h or --help for help on available commands.\n"); - isp_serial_close(); - return -1; - } - - /* And then remaining ones (if any) are command arguments */ - if (optind < argc) { - nb_cmd_args = argc - optind; - cmd_args = malloc(nb_cmd_args * sizeof(char *)); - if (trace_on) { - printf("Command arguments :\n"); - } - while (optind < argc) { - static unsigned int idx = 0; - cmd_args[idx++] = argv[optind++]; - if (trace_on) { - printf("%s\n", cmd_args[idx - 1]); - } - } - } - - /* Frist : sync with device */ - dev_id = prog_connect_and_id(crystal_freq); - if (dev_id < 0) { - printf("Unable to connect to target, consider hard reset of target or link\n"); - return -1; - } - - if (command != NULL) { - int err = 0; - err = prog_handle_command(command, dev_id, nb_cmd_args, cmd_args); - if (err >= 0) { - if (trace_on) { - printf("Command \"%s\" handled OK.\n", command); - } - } else { - printf("Error handling command \"%s\" : %d\n", command, err); - } - } - - - if (cmd_args != NULL) { - free(cmd_args); - } - isp_serial_close(); - return 0; -} - -struct prog_command { - int cmd_num; - char* name; -}; - -static struct prog_command prog_cmds_list[] = { - {0, "dump"}, - {1, "flash"}, - {2, "id"}, - {3, "blank"}, - {4, "go"}, - {5, NULL} -}; - -/* - * Try to connect to the target and identify the device. - * First try sync, and if it fails, try to read id twice. if both fail, then we are not connected - */ -static int prog_connect_and_id(int freq) -{ - int sync_ret = 0; - - /* Try to connect */ - sync_ret = isp_connect(freq, 1); - /* Synchro failed or already synchronised ? */ - if (sync_ret < 0) { - /* If already synchronized, then sync command and the next command fail. - Sync failed, maybe we are already sync'ed, then send one command for nothing */ - isp_cmd_part_id(1); - } - - return isp_cmd_part_id(1); -} - -static int prog_handle_command(char* cmd, int dev_id, int arg_count, char** args) -{ - int cmd_found = -1; - int ret = 0; - int index = 0; - struct part_desc* part = NULL; - - if (cmd == NULL) { - printf("prog_handle_command called with no command !\n"); - return -1; - } - - part = find_part(dev_id); - if (part == NULL) { - printf("Unknown part number : 0x%08x.\n", dev_id); - return -2; - } - - while ((cmd_found == -1) && (prog_cmds_list[index].name != NULL)) { - if (strncmp(prog_cmds_list[index].name, cmd, strlen(prog_cmds_list[index].name)) == 0) { - cmd_found = index; - break; - } - index++; - } - if (cmd_found == -1) { - printf("Unknown command \"%s\", use -h or --help for a list.\n", cmd); - return -3; - } - - switch (prog_cmds_list[cmd_found].cmd_num) { - case 0: /* dump, need one arg : filename */ - if (arg_count != 1) { - printf("command dump needs one arg (filename), got %d.\n", arg_count); - return -4; - } - ret = dump_to_file(part, args[0]); - break; - - case 1: /* flash, need one arg : filename */ - if (arg_count != 1) { - printf("command flash needs one arg (filename), got %d.\n", arg_count); - return -4; - } - ret = flash_target(part, args[0], calc_user_code); - break; - - case 2: /* id : no args */ - ret = get_ids(); - break; - - case 3: /* blank : no args */ - ret = erase_flash(part); - break; - - case 4: /* go : no args */ - ret = start_prog(part); - break; - } - - return ret; -} - diff --git a/lpcisp.c b/lpcisp.c new file mode 100644 index 0000000..4a27b23 --- /dev/null +++ b/lpcisp.c @@ -0,0 +1,319 @@ +/********************************************************************* + * + * LPC1114 ISP + * + * + * Written by Nathael Pajani + * + * This programm is released under the terms of the GNU GPLv3 licence + * as can be found on the GNU website : + * + *********************************************************************/ + + +#include /* malloc, free */ +#include +#include + +#include /* open, getopt, close, usleep */ +#include +#include +#include + +#include +#include + +#include /* for serial config */ +#include + +#include /* strncmp, strlen */ + +#include "isp_utils.h" +#include "isp_commands.h" + +#define PROG_NAME "LPC11xx ISP" +#define VERSION "1.0" + +/* short explanation on exit values: + * + * 0 is OK + * 1 is arg error + * + */ + + +void help(char *prog_name) +{ + fprintf(stderr, "-----------------------------------------------------------------------\n"); + fprintf(stderr, "Usage: %s [options] device [-s | --synchronize]\n" \ + " %s [options] device command [command arguments]\n" \ + " Default baudrate is B115200\n" \ + " is the (host) serial line used to programm the device\n" \ + " is one of:\n" \ + " \t unlock, write-to-ram, read-memory, prepare-for-write, copy-ram-to-flash, go, erase,\n" \ + " \t blank-check, read-part-id, read-boot-version, compare, and read-uid.\n" \ + " command specific arguments are as follow:\n" \ + " \t unlock \n" \ + " \t write-to-ram address file : send 'file' to 'address' in ram\n" \ + " \t read-memory address count file : read 'count' bytes from 'address', store then in 'file'\n" \ + " \t prepare-for-write first last : prepare sectors from 'first' to 'last' for write operation\n" \ + " \t copy-ram-to-flash flash_addr ram_addr count : copy count bytes (256, 512, 1024 or 4096)\n" \ + " \t from 'ram_addr' to 'flash_addr'\n" \ + " \t go address mode : execute programm at 'address' (> 0x200) in 'mode' ('arm' or 'thumb')\n" \ + " \t erase first last : erase flash starting from 'first' sector up to (including) 'last' sector \n" \ + " \t blank-check first last : check flash starting from 'first' sector to 'last' sector is blank\n" \ + " \t read-part-id \n" \ + " \t read-boot-version \n" \ + " \t compare address1 address2 count : compare count bytes between address1 and address2\n" \ + " \t read-uid \n" \ + " Notes:\n" \ + " - Access to the ISP mode is done by calling this utility once with the synchronize\n" \ + " option and no command. This starts a session. No command can be used before starting\n" \ + " a session, and no other synchronize request must be done once the session is started\n" \ + " unless the target is reseted, which closes the session.\n" \ + " - Echo is turned OFF when starting a session and the command is not available.\n" \ + " - The set-baud-rate command is not available. The SAME baudrate MUST be used for the\n" \ + " whole session. It must be specified on each successive call if the default baudrate\n" \ + " is not used.\n" \ + " - User must issue an 'unlock' command before any of 'copy-ram-to-flash', 'erase',\n" \ + " and 'go' commands.\n" \ + " Available options:\n" \ + " \t -s | --synchronize : Perform synchronization (open session)\n" \ + " \t -b | --baudrate=N : Use this baudrate (does not issue the set-baud-rate command)\n" \ + " \t -t | --trace : turn on trace output of serial communication\n" \ + " \t -h | --help : display this help\n" \ + " \t -v | --version : display version information\n", prog_name, prog_name); + fprintf(stderr, "-----------------------------------------------------------------------\n"); +} + +#define SERIAL_BAUD B115200 + +int trace_on = 0; + +int isp_handle_command(char* cmd, int arg_count, char** args); + +int main(int argc, char** argv) +{ + int baudrate = SERIAL_BAUD; + int crystal_freq = 10000; + int synchronize = 0; + char* isp_serial_device = NULL; + + /* For "command" handling */ + char* command = NULL; + char** cmd_args = NULL; + int nb_cmd_args = 0; + + + /* parameter parsing */ + while(1) { + int option_index = 0; + int c = 0; + + struct option long_options[] = { + {"synchronize", no_argument, 0, 's'}, + {"baudrate", required_argument, 0, 'b'}, + {"trace", no_argument, 0, 't'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "sb:thv", long_options, &option_index); + + /* no more options to parse */ + if (c == -1) break; + + switch (c) { + /* b, baudrate */ + case 'b': + baudrate = atoi(optarg); + /* FIXME: validate baudrate */ + break; + + /* t, trace */ + case 't': + trace_on = 1; + break; + + /* s, synchronize */ + case 's': + synchronize = 1; + break; + + /* v, version */ + case 'v': + printf("%s Version %s\n", PROG_NAME, VERSION); + return 0; + break; + + /* h, help */ + case 'h': + default: + help(argv[0]); + return 0; + } + } + + /* Parse remaining command line arguments (not options). */ + + /* First one should (must) be serial device */ + if (optind < argc) { + isp_serial_device = argv[optind++]; + if (trace_on) { + printf("Serial device : %s\n", isp_serial_device); + } + } + if (isp_serial_device == NULL) { + printf("No serial device given, exiting\n"); + help(argv[0]); + return 0; + } + if (isp_serial_open(baudrate, isp_serial_device) != 0) { + printf("Serial open failed, unable to initiate serial communication with target.\n"); + return -1; + } + + if (synchronize) { + if (optind < argc) { + /* no command can be specified when opening a session */ + printf("No command can be specified with -s or --synchronize (Session opening)\n"); + printf("NOT SYNCHRONIZED !\n"); + return -1; + } + isp_connect(crystal_freq, 0); + isp_serial_close(); + return 0; + } + + /* Next one should be "command" (if present) */ + if (optind < argc) { + command = argv[optind++]; + if (trace_on) { + printf("Command : %s\n", command); + } + } else { + printf("No command given. use -h or --help for help on available commands.\n"); + isp_serial_close(); + return -1; + } + /* And then remaining ones (if any) are command arguments */ + if (optind < argc) { + nb_cmd_args = argc - optind; + cmd_args = malloc(nb_cmd_args * sizeof(char *)); + if (trace_on) { + printf("Command arguments :\n"); + } + while (optind < argc) { + static unsigned int idx = 0; + cmd_args[idx++] = argv[optind++]; + if (trace_on) { + printf("%s\n", cmd_args[idx - 1]); + } + } + } + + if (command != NULL) { + int err = 0; + err = isp_handle_command(command, nb_cmd_args, cmd_args); + if (err >= 0) { + if (trace_on) { + printf("Command \"%s\" handled OK.\n", command); + } + } else { + printf("Error handling command \"%s\" : %d\n", command, err); + } + } + + + if (cmd_args != NULL) { + free(cmd_args); + } + isp_serial_close(); + return 0; +} + +struct isp_command { + int cmd_num; + char* name; + int nb_args; + int (*handler)(int arg_count, char** args); +}; + + +static struct isp_command isp_cmds_list[] = { + {0, "unlock", 0, NULL}, + {1, "write-to-ram", 2, isp_cmd_write_to_ram}, + {2, "read-memory", 3, isp_cmd_read_memory}, + {3, "prepare-for-write", 2, isp_cmd_prepare_for_write}, + {4, "copy-ram-to-flash", 3, isp_cmd_copy_ram_to_flash}, + {5, "go", 2, isp_cmd_go}, + {6, "erase", 2, isp_cmd_erase}, + {7, "blank-check", 2, isp_cmd_blank_check}, + {8, "read-part-id", 0, NULL}, + {9, "read-boot-version", 0, NULL}, + {10, "compare", 3, isp_cmd_compare}, + {11, "read-uid", 0, NULL}, + {-1, NULL, 0, NULL} +}; + +void isp_warn_args(int cmd_num, int arg_count, char** args) +{ + int i = 0; + printf("command \"%s\" needs %d args, got %d.\n", + isp_cmds_list[cmd_num].name, + isp_cmds_list[cmd_num].nb_args, arg_count); + for (i=0; i + * + * This programm is released under the terms of the GNU GPLv3 licence + * as can be found on the GNU website : + * + *********************************************************************/ + + +#include /* malloc, free */ +#include +#include + +#include /* open, getopt, close, usleep */ +#include +#include +#include + +#include +#include + +#include /* for serial config */ +#include + +#include /* strncmp, strlen */ + +#include "isp_utils.h" +#include "isp_commands.h" +#include "prog_commands.h" +#include "parts.h" + +#define PROG_NAME "LPC11xx ISP Prog tool" +#define VERSION "0.01" + + +void help(char *prog_name) +{ + fprintf(stderr, "---------------- "PROG_NAME" --------------------------------\n"); + fprintf(stderr, "Usage: %s [options] serial_device command [command arguments]\n" \ + " Default baudrate is B115200\n" \ + " Default oscilator frequency used is 10000 KHz\n" \ + " is the (host) serial line used to programm the device\n" \ + " is one of:\n" \ + " \t dump, flash, id, blank, go\n" \ + " command specific arguments are:\n" \ + " \t dump file : dump flash content to 'file'\n" \ + " \t flash file : put 'file' to flash, erasing requiered sectors\n" \ + " \t blank : erase whole flash\n" \ + " \t id : get all id information\n" \ + " \t go : execute programm from reset handler in thumb mode and open terminal\n" \ + " Available options:\n" \ + " \t -b | --baudrate=N : Use this baudrate (Same baudrate must be used across whole session)\n" \ + " \t -t | --trace : turn on trace output of serial communication\n" \ + " \t -f | --freq=N : Oscilator frequency of target device\n" \ + " \t -u | --user-code : compute a valid user code for exception vector 7\n" \ + " \t -h | --help : display this help\n" \ + " \t -v | --version : display version information\n", prog_name); + fprintf(stderr, "-----------------------------------------------------------------------\n"); +} + +#define SERIAL_BAUD B115200 + +int trace_on = 0; +int quiet = 0; +static int calc_user_code = 0; + +static int prog_connect_and_id(int freq); +static int prog_handle_command(char* cmd, int dev_id, int arg_count, char** args); + +int main(int argc, char** argv) +{ + int baudrate = SERIAL_BAUD; + int crystal_freq = 10000; + char* isp_serial_device = NULL; + int dev_id = 0; + + /* For "command" handling */ + char* command = NULL; + char** cmd_args = NULL; + int nb_cmd_args = 0; + + + /* parameter parsing */ + while(1) { + int option_index = 0; + int c = 0; + + struct option long_options[] = { + {"synchronized", no_argument, 0, 's'}, + {"baudrate", required_argument, 0, 'b'}, + {"trace", no_argument, 0, 't'}, + {"freq", required_argument, 0, 'f'}, + {"user-code", no_argument, 0, 'u'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "sb:tfuhv", long_options, &option_index); + + /* no more options to parse */ + if (c == -1) break; + + switch (c) { + /* b, baudrate */ + case 'b': + baudrate = atoi(optarg); + /* FIXME: validate baudrate */ + break; + + /* t, trace */ + case 't': + trace_on = 1; + break; + + /* f, freq */ + case 'f': + crystal_freq = atoi(optarg); + break; + + /* u, user-code */ + case 'u': + calc_user_code = 1; + break; + + /* v, version */ + case 'v': + printf("%s Version %s\n", PROG_NAME, VERSION); + return 0; + break; + + /* h, help */ + case 'h': + default: + help(argv[0]); + return 0; + } + } + + /* Parse remaining command line arguments (not options). */ + + /* First one should (must) be serial device */ + if (optind < argc) { + isp_serial_device = argv[optind++]; + if (trace_on) { + printf("Serial device : %s\n", isp_serial_device); + } + } + if (isp_serial_device == NULL) { + printf("No serial device given, exiting\n"); + help(argv[0]); + return 0; + } + if (isp_serial_open(baudrate, isp_serial_device) != 0) { + printf("Serial open failed, unable to initiate serial communication with target.\n"); + return -1; + } + + /* Next one should be "command" (if present) */ + if (optind < argc) { + command = argv[optind++]; + if (trace_on) { + printf("Command : %s\n", command); + } + } else { + printf("No command given. use -h or --help for help on available commands.\n"); + isp_serial_close(); + return -1; + } + + /* And then remaining ones (if any) are command arguments */ + if (optind < argc) { + nb_cmd_args = argc - optind; + cmd_args = malloc(nb_cmd_args * sizeof(char *)); + if (trace_on) { + printf("Command arguments :\n"); + } + while (optind < argc) { + static unsigned int idx = 0; + cmd_args[idx++] = argv[optind++]; + if (trace_on) { + printf("%s\n", cmd_args[idx - 1]); + } + } + } + + /* Frist : sync with device */ + dev_id = prog_connect_and_id(crystal_freq); + if (dev_id < 0) { + printf("Unable to connect to target, consider hard reset of target or link\n"); + return -1; + } + + if (command != NULL) { + int err = 0; + err = prog_handle_command(command, dev_id, nb_cmd_args, cmd_args); + if (err >= 0) { + if (trace_on) { + printf("Command \"%s\" handled OK.\n", command); + } + } else { + printf("Error handling command \"%s\" : %d\n", command, err); + } + } + + + if (cmd_args != NULL) { + free(cmd_args); + } + isp_serial_close(); + return 0; +} + +struct prog_command { + int cmd_num; + char* name; +}; + +static struct prog_command prog_cmds_list[] = { + {0, "dump"}, + {1, "flash"}, + {2, "id"}, + {3, "blank"}, + {4, "go"}, + {5, NULL} +}; + +/* + * Try to connect to the target and identify the device. + * First try sync, and if it fails, try to read id twice. if both fail, then we are not connected + */ +static int prog_connect_and_id(int freq) +{ + int sync_ret = 0; + + /* Try to connect */ + sync_ret = isp_connect(freq, 1); + /* Synchro failed or already synchronised ? */ + if (sync_ret < 0) { + /* If already synchronized, then sync command and the next command fail. + Sync failed, maybe we are already sync'ed, then send one command for nothing */ + isp_cmd_part_id(1); + } + + return isp_cmd_part_id(1); +} + +static int prog_handle_command(char* cmd, int dev_id, int arg_count, char** args) +{ + int cmd_found = -1; + int ret = 0; + int index = 0; + struct part_desc* part = NULL; + + if (cmd == NULL) { + printf("prog_handle_command called with no command !\n"); + return -1; + } + + part = find_part(dev_id); + if (part == NULL) { + printf("Unknown part number : 0x%08x.\n", dev_id); + return -2; + } + + while ((cmd_found == -1) && (prog_cmds_list[index].name != NULL)) { + if (strncmp(prog_cmds_list[index].name, cmd, strlen(prog_cmds_list[index].name)) == 0) { + cmd_found = index; + break; + } + index++; + } + if (cmd_found == -1) { + printf("Unknown command \"%s\", use -h or --help for a list.\n", cmd); + return -3; + } + + switch (prog_cmds_list[cmd_found].cmd_num) { + case 0: /* dump, need one arg : filename */ + if (arg_count != 1) { + printf("command dump needs one arg (filename), got %d.\n", arg_count); + return -4; + } + ret = dump_to_file(part, args[0]); + break; + + case 1: /* flash, need one arg : filename */ + if (arg_count != 1) { + printf("command flash needs one arg (filename), got %d.\n", arg_count); + return -4; + } + ret = flash_target(part, args[0], calc_user_code); + break; + + case 2: /* id : no args */ + ret = get_ids(); + break; + + case 3: /* blank : no args */ + ret = erase_flash(part); + break; + + case 4: /* go : no args */ + ret = start_prog(part); + break; + } + + return ret; +} +