xpp_fxloader: rename variable: default_law -> law
[dahdi/tools.git] / xpp / astribank_hexload.c
1 /*
2  * Written by Oron Peled <oron@actcom.co.il>
3  * Copyright (C) 2008, Xorcom
4  *
5  * All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <arpa/inet.h>
31 #include <debug.h>
32 #include "hexfile.h"
33 #include "mpptalk.h"
34 #include "pic_loader.h"
35 #include "echo_loader.h"
36 #include "astribank_usb.h"
37 #include "../autoconfig.h"
38
39 #define DBG_MASK        0x80
40 #define MAX_HEX_LINES   64000
41 #define HAVE_OCTASIC    1
42
43 static char     *progname;
44
45 static void usage()
46 {
47         fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}/<bus>/<dev> hexfile...\n", progname);
48         fprintf(stderr, "\tOptions: {-F|-p}\n");
49         fprintf(stderr, "\t\t[-E]               # Burn to EEPROM\n");
50 #if HAVE_OCTASIC
51         fprintf(stderr, "\t\t[-O]               # Load Octasic firmware\n");
52         fprintf(stderr, "\t\t[-o]               # Show Octasic version\n");
53         fprintf(stderr, "\t\t[-S <pri-spec>]    # Set PRI type specification string\n");
54 #endif
55         fprintf(stderr, "\t\t[-F]               # Load FPGA firmware\n");
56         fprintf(stderr, "\t\t[-p]               # Load PIC firmware\n");
57         fprintf(stderr, "\t\t[-v]               # Increase verbosity\n");
58         fprintf(stderr, "\t\t[-A]               # Set A-Law for 1st module\n");
59         fprintf(stderr, "\t\t[-d mask]          # Debug mask (0xFF for everything)\n");
60         exit(1);
61 }
62
63 int handle_hexline(struct astribank_device *astribank, struct hexline *hexline)
64 {
65         uint16_t        len;
66         uint16_t        offset_dummy;
67         uint8_t         *data;
68         int             ret;
69
70         assert(hexline);
71         assert(astribank);
72         if(hexline->d.content.header.tt != TT_DATA) {
73                 DBG("Non data record type = %d\n", hexline->d.content.header.tt);
74                 return 0;
75         }
76         len = hexline->d.content.header.ll;
77         offset_dummy = hexline->d.content.header.offset;
78         data = hexline->d.content.tt_data.data;
79         if((ret = mpp_send_seg(astribank, data, offset_dummy, len)) < 0) {
80                 ERR("Failed hexfile send line: %d\n", ret);
81                 return -EINVAL;
82         }
83         return 0;
84 }
85
86 void print_parse_errors(int level, const char *msg, ...)
87 {
88         va_list ap;
89
90         if (verbose > level) {
91                 va_start (ap, msg);
92                 vfprintf (stderr, msg, ap);
93                 va_end (ap);
94         }
95 }
96
97 static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest)
98 {
99         struct hexdata          *hexdata = NULL;
100         int                     finished = 0;
101         int                     ret;
102         unsigned                i;
103         char                    star[] = "+\\+|+/+-";
104         const char              *devstr;
105
106         parse_hexfile_set_reporting(print_parse_errors);
107         if((hexdata  = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) {
108                 perror(hexfile);
109                 return -errno;
110         }
111         devstr = xusb_devpath(astribank->xusb);
112         INFO("%s [%s]: Loading %s Firmware: %s (version %s)\n",
113                 devstr,
114                 xusb_serial(astribank->xusb),
115                 dev_dest2str(dest),
116                 hexdata->fname, hexdata->version_info);
117         if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) {
118                 ERR("%s: Failed hexfile send start: %d\n", devstr, ret);
119                 return ret;
120         }
121         for(i = 0; i < hexdata->maxlines; i++) {
122                 struct hexline  *hexline = hexdata->lines[i];
123
124                 if(!hexline)
125                         break;
126                 if(verbose > LOG_INFO) {
127                         printf("Sending: %4d%%    %c\r", (100 * i) / hexdata->last_line, star[i % sizeof(star)]);
128                         fflush(stdout);
129                 }
130                 if(finished) {
131                         ERR("%s: Extra data after End Of Data Record (line %d)\n", devstr, i);
132                         return 0;
133                 }
134                 if(hexline->d.content.header.tt == TT_EOF) {
135                         DBG("End of data\n");
136                         finished = 1;
137                         continue;
138                 }
139                 if((ret = handle_hexline(astribank, hexline)) < 0) {
140                         ERR("%s: Failed hexfile sending in lineno %d (ret=%d)\n", devstr, i, ret);;
141                         return ret;
142                 }
143         }
144         if(verbose > LOG_INFO) {
145                 putchar('\n');
146                 fflush(stdout);
147         }
148         if((ret = mpp_send_end(astribank)) < 0) {
149                 ERR("%s: Failed hexfile send end: %d\n", devstr, ret);
150                 return ret;
151         }
152 #if 0
153         fclose(fp);
154 #endif
155         free_hexdata(hexdata);
156         DBG("hexfile loaded successfully\n");
157         return 0;
158 }
159
160 int main(int argc, char *argv[])
161 {
162         char                    *devpath = NULL;
163         int                     opt_pic = 0;
164         int                     opt_echo = 0;
165         int                     opt_ecver = 0;
166 #if HAVE_OCTASIC
167         int                     opt_alaw = 0;
168         const char              *span_spec = NULL;
169 #endif
170         int                     opt_dest = 0;
171         int                     opt_sum = 0;
172         enum dev_dest           dest = DEST_NONE;
173         const char              options[] = "vd:D:EFOopAS:";
174         int                     iface_num;
175         int                     ret;
176
177         progname = argv[0];
178         while (1) {
179                 int     c;
180
181                 c = getopt (argc, argv, options);
182                 if (c == -1)
183                         break;
184
185                 switch (c) {
186                         case 'D':
187                                 devpath = optarg;
188                                 break;
189                         case 'E':
190                                 if(dest != DEST_NONE) {
191                                         ERR("The -F and -E options are mutually exclusive.\n");
192                                         usage();
193                                 }
194                                 opt_dest++;
195                                 dest = DEST_EEPROM;
196                                 break;
197                         case 'F':
198                                 if(dest != DEST_NONE) {
199                                         ERR("The -F and -E options are mutually exclusive.\n");
200                                         usage();
201                                 }
202                                 opt_dest++;
203                                 dest = DEST_FPGA;
204                                 break;
205 #if HAVE_OCTASIC
206                         case 'O':
207                                 opt_echo = 1;
208                                 break;
209                         case 'o':
210                                 opt_ecver = 1;
211                                 break;
212                         case 'A':
213                                 opt_alaw = 1;
214                                 break;
215                         case 'S':
216                                 span_spec = optarg;
217                                 break;
218 #endif
219                         case 'p':
220                                 opt_pic = 1;
221                                 break;
222                         case 'v':
223                                 verbose++;
224                                 break;
225                         case 'd':
226                                 debug_mask = strtoul(optarg, NULL, 0);
227                                 break;
228                         case 'h':
229                         default:
230                                 ERR("Unknown option '%c'\n", c);
231                                 usage();
232                 }
233         }
234         opt_sum = opt_dest + opt_pic + opt_echo;
235         if(opt_sum > 1 || (opt_sum == 0 && opt_ecver == 0)) {
236                 ERR("The -F, -E"
237 #if HAVE_OCTASIC
238                         ", -O"
239 #endif
240                         " and -p options are mutually exclusive, if neither is used then -o should present\n");
241                 usage();
242         }
243         iface_num = (opt_dest) ? 1 : 0;
244         if(!opt_pic && !opt_ecver) {
245                 if(optind != argc - 1) {
246                         ERR("Got %d hexfile names (Need exactly one hexfile)\n",
247                                 argc - 1 - optind);
248                         usage();
249                 }
250         }
251         if(!devpath) {
252                 ERR("Missing device path.\n");
253                 usage();
254         }
255         if(opt_dest) {
256                 /*
257                  * MPP Interface
258                  */
259                 struct astribank_device *astribank;
260
261                 if((astribank = mpp_init(devpath, iface_num)) == NULL) {
262                         ERR("%s: Opening astribank failed\n", devpath);
263                         return 1;
264                 }
265                 //show_astribank_info(astribank);
266                 if(load_hexfile(astribank, argv[optind], dest) < 0) {
267                         ERR("%s: Loading firmware to %s failed\n", devpath, dev_dest2str(dest));
268                         return 1;
269                 }
270                 astribank_close(astribank, 0);
271         } else if(opt_pic || opt_echo || opt_ecver) {
272                 /*
273                  * XPP Interface
274                  */
275                 struct astribank_device *astribank;
276
277                 if((astribank = astribank_open(devpath, iface_num)) == NULL) {
278                         ERR("%s: Opening astribank failed\n", devpath);
279                         return 1;
280                 }
281                 //show_astribank_info(astribank);
282 #if HAVE_OCTASIC
283                 if (opt_ecver) {
284                         if((ret = echo_ver(astribank)) < 0) {
285                                 ERR("%s: Get Octasic version failed (Is Echo canceller card connected?)\n", devpath);
286                                 return 1;
287                         } else 
288                                 INFO("Octasic version: 0x%0X\n", ret);
289                 }
290 #endif
291                 if (opt_pic) {
292                         if ((ret = load_pic(astribank, argc - optind, argv + optind)) < 0) {
293                                 ERR("%s: Loading PIC's failed\n", devpath);
294                                 return 1;
295                         }
296 #if HAVE_OCTASIC
297                 } else if (opt_echo) {
298                         if((ret = load_echo(astribank, argv[optind], opt_alaw, span_spec)) < 0) {
299                                 ERR("%s: Loading ECHO's failed\n", devpath);
300                                 return 1;
301                         }
302 #endif
303                 }
304                 astribank_close(astribank, 0);
305         }
306         return 0;
307 }