16 #define HAS_GETOPT_LONG 1
19 struct tolpc_env Tolpc =
21 .sdev = "/dev/ttyS0", .crystal = 10000, .baud = 9600, .waitrep = 100000
24 struct tolpc_env *env = &Tolpc;
26 void error(const char *fmt, ...)
32 vsnprintf(message, 100, fmt, ap);
35 fprintf(stderr, "tolpc error: %s\n", message);
39 static void usage(void)
42 printf(" high level: tolpc [<global parameters>] -L [mode] -f <object file>\n");
43 printf(" low level: tolpc [<global parameters>] [command [,...]]\n");
44 printf("Command has the form: [command [, param1 [,param2, ...]]\n");
46 printf("Global Parameters:\n");
47 printf(" -d, --sdev <name> name of RS232 device [%s]\n", env->sdev);
48 printf(" -q, --crystal <kHz> crystal frequency in kHz [%d]\n", env->crystal);
49 printf(" -b, --baud <num> RS232 baudrate [%d]\n", env->baud);
50 printf(" -w, --wait <num> timeout in miliseconds [%ld]\n", env->waitrep/1000);
51 printf(" -v, --verbose increase verbosity (can be used more times)\n");
52 printf("Commands:\n");
53 printf(" -L, --load [A|T] Load binary file and execute (loads all BFD sections,\n");
54 printf(" jumps to start address) [only RAM in this version].\n");
55 printf(" -U, --unlock\n");
56 printf(" -A, --echo <setting> Echo (use -A0 when uploading data using W)\n");
57 printf(" -G, --go [<mode>] Mode is A or T [A]\n");
58 printf(" -C, --copy <flash_addr> Copy RAM to Flash\n");
59 printf(" -c, --cmd <command> Execute other command (letters from LPC user manual)\n");
60 printf("Parameters:\n");
61 printf(" -s, --start <addr> start address of transfer\n");
62 printf(" -l, --length <num> length of upload block\n");
63 printf(" -f, --file <filename> file to read or write\n");
64 printf(" -o, --offset <num> offset in a file\n");
66 printf(" -k, --break send communication break character\n");
67 printf(" -V, --version show version\n");
68 printf(" -h, --help this usage screen\n");
84 int load_file(struct cmd_params *p)
91 error("No file (-f) for %c command", p->cmd);
93 ret = stat(p->fname, &st);
99 if (p->length == 0) p->length = st.st_size - p->offset;
101 f = fopen(p->fname, "r");
107 fseek(f, p->offset, SEEK_SET);
109 p->data = malloc(p->length);
111 fread(p->data, p->length, 1, f);
120 int ram_write_cb(bfd_vma lma, bfd_size_type size, void *data) {
121 return tolpc_write_ram(env, lma, size, data);
125 * load bfd file to target (only RAM at this moment) and jump
126 * to its start address
129 int load_exec(struct cmd_params *p) {
134 error("No file (-f) for %c command", p->cmd);
136 ret = tolpc_echo(env, '0');
139 ret = tolpc_unlock(env);
142 ret = load_bfd(p->fname, /*default target*/NULL, ram_write_cb, &start, tolpc_verbose_level);
145 tolpc_verbose(1, "Running the program\n");
146 ret = tolpc_go(env, start, p->iarg == 'A');
151 void not_implemented(char c)
153 error("Not implemented: %c", c);
156 void clear_cmd(struct cmd_params *p)
158 if (p->data) free(p->data);
159 memset(p, 0, sizeof(*p));
163 void run_cmd(struct cmd_params *p)
169 ret = tolpc_unlock(env);
172 ret = tolpc_echo(env, p->iarg);
175 if (p->iarg != 'A' && p->iarg != 'T')
176 error("Go mode can only be A or T.");
178 error("No start address is given for Go command");
179 ret = tolpc_go(env, p->start, p->iarg == 'A');
184 error("No start addres is given for Write command");
185 ret = tolpc_write_ram(env, p->start, p->length, p->data);
190 ret = tolpc_partid(env, partid, 99);
192 tolpc_verbose(1, "Part ID:");
200 tolpc_bootver(env, ver, 99);
202 tolpc_verbose(1, "Boot code version:");
211 not_implemented(p->cmd);
214 if (ret) error("Command %c", p->cmd);
217 void new_command(struct cmd_params *p, char cmd)
226 int main(int argc, char **argv)
233 static struct option long_opts[] = {
234 { "sdev", 1, 0, 'd'},
235 { "crystal", 1, 0, 'q' },
236 { "baud", 1, 0, 'b' },
237 { "wait", 1, 0, 'w' },
238 { "verbose", 0, 0, 'v' },
240 { "unlock", 0, 0, 'U' },
241 { "echo", 1, 0, 'A' },
243 { "copy", 1, 0, 'C' },
244 { "cmd", 1, 0, 'c' },
245 { "load", 2, 0, 'L' }, // has optional argument
247 { "start", 1, 0, 's' },
248 { "length", 1, 0, 'l' },
249 { "file", 1, 0, 'f' },
250 { "offset", 1, 0, 'o' },
252 { "break", 0, 0, 'k' },
253 { "version", 0, 0, 'V' },
254 { "help", 0, 0, 'h' },
258 // Initial clear of of parameters structure (clear_cmd produces segfault here)
259 memset(&p, 0, sizeof(p));
262 memset(short_ops, 0, sizeof(short_ops));
264 for (opt = 0; long_opts[opt].name != NULL || i > 100 - 3; opt++) {
265 short_ops[i++] = long_opts[opt].val;
266 if (long_opts[opt].has_arg) short_ops[i++] = ':';
267 if (long_opts[opt].has_arg == 2) short_ops[i++] = ':';
271 #ifndef HAS_GETOPT_LONG
272 while ((opt = getopt(argc, argv, short_ops)) != EOF)
274 while ((opt = getopt_long(argc, argv, short_ops,
275 &long_opts[0], NULL)) != EOF)
282 env->baud = strtol(optarg, NULL, 0);
285 env->crystal = strtol(optarg, NULL, 0);
288 env->waitrep = 1000*strtol(optarg, NULL, 0);
291 tolpc_verbose_level++;
294 new_command(&p, opt);
297 new_command(&p, opt);
302 new_command(&p, opt);
303 p.iarg = 'A'; // ARM mode is default
304 if (optarg) p.iarg = optarg[0];
308 new_command(&p, opt);
312 char cmd = optarg[0];
317 new_command(&p, cmd);
320 error("Unknown command %c", cmd);
326 new_command(&p, opt);
327 p.iarg = 'A'; // ARM mode is default
328 if (optarg) p.iarg = optarg[0];
331 p.start = strtol(optarg, NULL, 0);
334 p.length = strtol(optarg, NULL, 0);
340 p.offset = strtol(optarg, NULL, 0);
343 fputs("tolpc pre alpha\n", stdout);
348 exit(opt == 'h' ? 0 : 1);
350 new_command(&p, 0); // run the last command