Adding file with commands for non-regretion testing.
[lpctools] / isp_main.c
1 /*********************************************************************
2  *
3  *   LPC1114 ISP
4  *
5  *
6  * Written by Nathael Pajani <nathael.pajani@nathael.net>
7  * 
8  * This programm is released under the terms of the GNU GPLv3 licence
9  * as can be found on the GNU website : <http://www.gnu.org/licenses/>
10  *
11  *********************************************************************/
14 #include <stdlib.h> /* malloc, free */
15 #include <stdio.h>
16 #include <stdint.h>
18 #include <unistd.h> /* open, getopt, close, usleep */
19 #include <fcntl.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
23 #include <errno.h>
24 #include <getopt.h>
26 #include <termios.h> /* for serial config */
27 #include <ctype.h>
29 #include "isp_utils.h"
30 #include "isp_commands.h"
32 #define PROG_NAME "LPC11xx ISP"
33 #define VERSION   "0.01"
35 /* short explanation on exit values:
36  *
37  * 0 is OK
38  * 1 is arg error
39  *
40  */
43 void help(char *prog_name)
44 {
45         fprintf(stderr, "-----------------------------------------------------------------------\n");
46         fprintf(stderr, "Usage: %s [options] device [-s | --synchronize]\n" \
47                 "       %s [options] device command [command arguments]\n" \
48                 "  Default baudrate is B115200\n" \
49                 "  <device> is the (host) serial line used to programm the device\n" \
50                 "  <command> is one of:\n" \
51                 "  \t unlock \n" \
52                 "  \t write-to-ram address file : send 'file' to 'address' in ram\n" \
53                 "  \t read-memory address count file : read 'count' bytes from 'address', store then in 'file'\n" \
54                 "  \t prepare-for-write first last : prepare sectors from 'first' to 'last' for write operation\n" \
55                 "  \t copy-ram-to-flash flash_addr ram_addr count : copy count bytes (256, 512, 1024 or 4096)\n" \
56                 "  \t     from 'ram_addr' to 'flash_addr'\n" \
57                 "  \t go address mode : execute programm at 'address' (> 0x200) in 'mode' ('arm' or 'thumb')\n" \
58                 "  \t erase first last : erase flash starting from 'first' sector up to (including) 'last' sector \n" \
59                 "  \t blank-check first last : check flash starting from 'first' sector to 'last' sector is blank\n" \
60                 "  \t read-part-id \n" \
61                 "  \t read-boot-version \n" \
62                 "  \t compare address1 address2 count : compare count bytes between address1 and address2\n" \
63                 "  \t read-uid \n" \
64                 "  Notes:\n" \
65                 "   - Access to the ISP mode is done by calling this utility once with the synchronize\n" \
66                 "     option and no command. This starts a session. No command can be used before starting\n" \
67                 "     a session, and no other synchronize request must be done once the session is started\n" \
68                 "     unless the target is reseted, which closes the session.\n" \
69                 "   - Echo is turned OFF when starting a session and the command is not available.\n" \
70                 "   - The set-baud-rate command is not available. The SAME baudrate MUST be used for the\n" \
71                 "     whole session. It must be specified on each successive call if the default baudrate\n" \
72                 "     is not used.\n" \
73                 "   - User must issue an 'unlock' command before any of 'copy-ram-to-flash', 'erase',\n" \
74                 "     and 'go' commands.\n" \
75                 "  Available options:\n" \
76                 "  \t -s | --synchronize : Perform synchronization (open session)\n" \
77                 "  \t -b | --baudrate=N : Use this baudrate (does not issue the set-baud-rate command)\n" \
78                 "  \t -t | --trace : turn on trace output of serial communication\n" \
79                 "  \t -h | --help : display this help\n" \
80                 "  \t -v | --version : display version information\n", prog_name, prog_name);
81         fprintf(stderr, "-----------------------------------------------------------------------\n");
82 }
84 #define SERIAL_BAUD  B115200
86 int trace_on = 0;
89 int main(int argc, char** argv)
90 {
91         int baudrate = SERIAL_BAUD;
92         int crystal_freq = 10000;
93         int synchronize = 0;
94         char* isp_serial_device = NULL;
96         /* For "command" handling */
97         char* command = NULL;
98         char** cmd_args = NULL;
99         int nb_cmd_args = 0;
102         /* parameter parsing */
103         while(1) {
104                 int option_index = 0;
105                 int c = 0;
107                 struct option long_options[] = {
108                         {"synchronize", no_argument, 0, 's'},
109                         {"baudrate", required_argument, 0, 'b'},
110                         {"trace", no_argument, 0, 't'},
111                         {"help", no_argument, 0, 'h'},
112                         {"version", no_argument, 0, 'v'},
113                         {0, 0, 0, 0}
114                 };
116                 c = getopt_long(argc, argv, "sb:thv", long_options, &option_index);
118                 /* no more options to parse */
119                 if (c == -1) break;
121                 switch (c) {
122                         /* b, baudrate */
123                         case 'b':
124                                 baudrate = atoi(optarg);
125                                 /* FIXME: validate baudrate */
126                                 break;
128                         /* t, trace */
129                         case 't':
130                                 trace_on = 1;
131                                 break;
133                         /* s, synchronize */
134                         case 's':
135                                 synchronize = 1;
136                                 break;
138                         /* v, version */
139                         case 'v':
140                                 printf("%s Version %s\n", PROG_NAME, VERSION);
141                                 return 0;
142                                 break;
144                         /* h, help */
145                         case 'h':
146                         default:
147                                 help(argv[0]);
148                                 return 0;
149                 }
150         }
152         /* Parse remaining command line arguments (not options). */
154         /* First one should (must) be serial device */
155         if (optind < argc) {
156                 isp_serial_device = argv[optind++];
157                 if (trace_on) {
158                         printf("Serial device : %s\n", isp_serial_device);
159                 }
160         }
161         if (isp_serial_device == NULL) {
162                 printf("No serial device given, exiting\n");
163                 help(argv[0]);
164                 return 0;
165         }
166         if (isp_serial_open(baudrate, isp_serial_device) != 0) {
167                 printf("Serial open failed, unable to initiate serial communication with target.\n");
168                 return -1;
169         }
171         if (synchronize) {
172                 if (optind < argc) {
173                         /* no command can be specified when opening a session */
174                         printf("No command can be specified with -s or --synchronize (Session opening)\n");
175                         printf("NOT SYNCHRONIZED !\n");
176                         return -1;
177                 }
178                 isp_connect(crystal_freq);
179                 isp_serial_close();
180                 return 0;
181         }
183         /* Next one should be "command" (if present) */
184         if (optind < argc) {
185                 command = argv[optind++];
186                 if (trace_on) {
187                         printf("Command : %s\n", command);
188                 }
189         } else {
190                 printf("No command given. use -h or --help for help on available commands.\n");
191                 isp_serial_close();
192                 return -1;
193         }
194         /* And then remaining ones (if any) are command arguments */
195         if (optind < argc) {
196                 nb_cmd_args = argc - optind;
197                 cmd_args = malloc(nb_cmd_args * sizeof(char *));
198                 if (trace_on) {
199                         printf("Command arguments :\n");
200                 }
201                 while (optind < argc) {
202                         static unsigned int idx = 0;
203                         cmd_args[idx++] = argv[optind++];
204                         if (trace_on) {
205                                 printf("%s\n", cmd_args[idx - 1]);
206                         }
207                 }
208         }
210         if (command != NULL)  {
211                 int err = 0;
212                 err = isp_handle_command(command, nb_cmd_args, cmd_args);
213                 if (err >= 0) {
214                         if (trace_on) {
215                                 printf("Command \"%s\" handled OK.\n", command);
216                         }
217                 } else {
218                         printf("Error handling command \"%s\" : %d\n", command, err);
219                 }
220         }
223         if (cmd_args != NULL) {
224                 free(cmd_args);
225         }
226         isp_serial_close();
227         return 0;