0098b6589c8e9294e9bbda642d13bc20b03809af
[fw/altos] / ao-tools / ao-rawload / ao-rawload.c
1 /*
2  * Copyright © 2008 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <unistd.h>
20 #include <getopt.h>
21 #include "ccdbg.h"
22 #include "cc.h"
23
24 static const struct option options[] = {
25         { .name = "tty", .has_arg = 1, .val = 'T' },
26         { .name = "device", .has_arg = 1, .val = 'D' },
27         { .name = "run", .has_arg = 0, .val = 'r' },
28         { 0, 0, 0, 0},
29 };
30
31 static void usage(char *program)
32 {
33         fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--run] file.ihx\n", program);
34         exit(1);
35 }
36
37 int
38 main (int argc, char **argv)
39 {
40         struct ccdbg    *dbg;
41         uint8_t         status;
42         uint16_t        pc;
43         struct hex_file *hex;
44         struct hex_image *image;
45         char            *filename;
46         FILE            *file;
47         char            *tty = NULL;
48         char            *device = NULL;
49         int             c;
50         int             run = 0;
51
52         while ((c = getopt_long(argc, argv, "T:D:", options, NULL)) != -1) {
53                 switch (c) {
54                 case 'T':
55                         tty = optarg;
56                         break;
57                 case 'D':
58                         device = optarg;
59                         break;
60                 case 'r':
61                         run = 1;
62                         break;
63                 default:
64                         usage(argv[0]);
65                         break;
66                 }
67         }
68         filename = argv[optind];
69         if (filename == NULL) {
70                 fprintf(stderr, "usage: %s <filename.ihx>\n", argv[0]);
71                 exit(1);
72         }
73         file = fopen(filename, "r");
74         if (!file) {
75                 perror(filename);
76                 exit(1);
77         }
78         hex = ccdbg_hex_file_read(file, filename);
79         fclose(file);
80         if (!hex)
81                 exit (1);
82         image = ccdbg_hex_image_create(hex);
83         if (!image) {
84                 fprintf(stderr, "image create failed\n");
85                 exit (1);
86         }
87
88         ccdbg_hex_file_free(hex);
89         if (!tty)
90                 tty = cc_usbdevs_find_by_arg(device, "TIDongle");
91         dbg = ccdbg_open(tty);
92         if (!dbg)
93                 exit (1);
94
95         ccdbg_add_debug(CC_DEBUG_FLASH);
96
97         ccdbg_debug_mode(dbg);
98         ccdbg_halt(dbg);
99         if (image->address == 0xf000) {
100                 printf("Loading %d bytes to execute from RAM\n",
101                        image->length);
102                 ccdbg_write_hex_image(dbg, image, 0);
103         } else if (image->address == 0x0000) {
104                 printf("Loading %d bytes to execute from FLASH\n",
105                        image->length);
106                 ccdbg_flash_hex_image(dbg, image);
107         } else {
108                 printf("Cannot load code to 0x%04x\n",
109                        image->address);
110                 ccdbg_hex_image_free(image);
111                 ccdbg_close(dbg);
112                 exit(1);
113         }
114         if (run) {
115                 ccdbg_set_pc(dbg, image->address);
116                 ccdbg_resume(dbg);
117         }
118         ccdbg_close(dbg);
119         exit (0);
120 }