1 /*********************************************************************
2  *
3  *   LPC1114 ISP
4  *
5  *********************************************************************/
8 #include <stdlib.h> /* malloc, free */
9 #include <stdio.h>
10 #include <stdint.h>
12 #include <unistd.h> /* open, getopt, close, usleep */
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
17 #include <errno.h>
18 #include <getopt.h>
20 #include <termios.h> /* for serial config */
21 #include <ctype.h>
23 #include "isp_utils.h"
24 #include "isp_commands.h"
26 #define PROG_NAME "LPC11xx ISP"
27 #define VERSION   "0.01"
29 /* short explanation on exit values:
30  *
31  * 0 is OK
32  * 1 is arg error
33  *
34  */
37 void help(char *prog_name)
38 {
39         fprintf(stderr, "-----------------------------------------------------------------------\n");
40         fprintf(stderr, "Usage: %s [options] device [-s | --synchronize]\n" \
41                 "       %s [options] device command [command arguments]\n" \
42                 "  Default baudrate is B115200\n" \
43                 "  <device> is the (host) serial line used to programm the device\n" \
44                 "  <command> is one of:\n" \
45                 "  \t unlock \n" \
46                 "  \t write-to-ram \n" \
47                 "  \t read-memory \n" \
48                 "  \t prepare-for-write \n" \
49                 "  \t copy-ram-to-flash \n" \
50                 "  \t go \n" \
51                 "  \t erase \n" \
52                 "  \t blank-check \n" \
53                 "  \t read-part-id \n" \
54                 "  \t read-boot-version \n" \
55                 "  \t compare \n" \
56                 "  \t read-uid \n" \
57                 "  Notes:\n" \
58                 "   - Access to the ISP mode is done by calling this utility once with the synchronize\n" \
59                 "     option and no command. This starts a session. No command can be used before starting\n" \
60                 "     a session, and no other synchronize request must be done once the session is started\n" \
61                 "     unless the target is reseted, which closes the session.\n" \
62                 "   - Echo is turned OFF when starting a session and the command is not available.\n" \
63                 "   - The set-baud-rate command is not available. The SAME baudrate MUST be used for the\n" \
64                 "     whole session. It must be specified on each successive call if the default baudrate\n" \
65                 "     is not used.\n" \
66                 "  Available options:\n" \
67                 "  \t -s | --synchronize : Perform synchronization (open session)\n" \
68                 "  \t -b | --baudrate=N : Use this baudrate (does not issue the set-baud-rate command)\n" \
69                 "  \t -t | --trace : turn on trace output of serial communication\n" \
70                 "  \t -h | --help : display this help\n" \
71                 "  \t -v | --version : display version information\n", prog_name, prog_name);
72         fprintf(stderr, "-----------------------------------------------------------------------\n");
73 }
75 #define SERIAL_BAUD  B115200
77 int trace_on = 0;
80 int main(int argc, char** argv)
81 {
82         int baudrate = SERIAL_BAUD;
83         int crystal_freq = 10000;
84         int synchronize = 0;
85         char* isp_serial_device = NULL;
87         /* For "command" handling */
88         char* command = NULL;
89         char** cmd_args = NULL;
90         int nb_cmd_args = 0;
93         /* parameter parsing */
94         while(1) {
95                 int option_index = 0;
96                 int c = 0;
98                 struct option long_options[] = {
99                         {"synchronize", no_argument, 0, 's'},
100                         {"baudrate", required_argument, 0, 'b'},
101                         {"trace", no_argument, 0, 't'},
102                         {"help", no_argument, 0, 'h'},
103                         {"version", no_argument, 0, 'v'},
104                         {0, 0, 0, 0}
105                 };
107                 c = getopt_long(argc, argv, "sb:thv", long_options, &option_index);
109                 /* no more options to parse */
110                 if (c == -1) break;
112                 switch (c) {
113                         /* b, baudrate */
114                         case 'b':
115                                 baudrate = atoi(optarg);
116                                 /* FIXME: validate baudrate */
117                                 break;
119                         /* t, trace */
120                         case 't':
121                                 trace_on = 1;
122                                 break;
124                         /* s, synchronize */
125                         case 's':
126                                 synchronize = 1;
127                                 break;
129                         /* v, version */
130                         case 'v':
131                                 printf("%s Version %s\n", PROG_NAME, VERSION);
132                                 return 0;
133                                 break;
135                         /* h, help */
136                         case 'h':
137                         default:
138                                 help(argv[0]);
139                                 return 0;
140                 }
141         }
143         /* Parse remaining command line arguments (not options). */
145         /* First one should (must) be serial device */
146         if (optind < argc) {
147                 isp_serial_device = argv[optind++];
148                 if (trace_on) {
149                         printf("Serial device : %s\n", isp_serial_device);
150                 }
151         }
152         if (isp_serial_device == NULL) {
153                 printf("No serial device given, exiting\n");
154                 help(argv[0]);
155                 return 0;
156         }
157         if (isp_serial_open(baudrate, isp_serial_device) != 0) {
158                 printf("Serial open failed, unable to initiate serial communication with target.\n");
159                 return -1;
160         }
162         if (synchronize) {
163                 if (optind < argc) {
164                         /* no command can be specified when opening a session */
165                         printf("No command can be specified with -s or --synchronize (Session opening)\n");
166                         printf("NOT SYNCHRONIZED !\n");
167                         return -1;
168                 }
169                 isp_connect(crystal_freq);
170                 isp_serial_close();
171                 return 0;
172         }
174         /* Next one should be "command" (if present) */
175         if (optind < argc) {
176                 command = argv[optind++];
177                 if (trace_on) {
178                         printf("Command : %s\n", command);
179                 }
180         } else {
181                 printf("No command given. use -h or --help for help on available commands.\n");
182                 isp_serial_close();
183                 return -1;
184         }
185         /* And then remaining ones (if any) are command arguments */
186         if (optind < argc) {
187                 nb_cmd_args = argc - optind;
188                 cmd_args = malloc(nb_cmd_args * sizeof(char *));
189                 if (trace_on) {
190                         printf("Command arguments :\n");
191                 }
192                 while (optind < argc) {
193                         static unsigned int idx = 0;
194                         cmd_args[idx++] = argv[optind++];
195                         if (trace_on) {
196                                 printf("%s\n", cmd_args[idx - 1]);
197                         }
198                 }
199         }
201         if (command != NULL)  {
202                 int err = 0;
203                 err = isp_handle_command(command, nb_cmd_args, cmd_args);
204                 if (err >= 0) {
205                         if (trace_on) {
206                                 printf("Command \"%s\" handled OK.\n", command);
207                         }
208                 } else {
209                         printf("Error handling command \"%s\" : %d\n", command, err);
210                 }
211         }
214         if (cmd_args != NULL) {
215                 free(cmd_args);
216         }
217         isp_serial_close();
218         return 0;