root/trunk/libffado/support/firmware/dice-firmware-utility.cpp

Revision 2073, 7.7 kB (checked in by adi, 9 years ago)

DICE: Move firmware utility to support/firmware

Line 
1 /*
2  * Copyright (C) 2012 by Peter Hinkel
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * Implementation of the DICE firmware loader specification based upon
23  * TCAT public available document v3.2.0.0 (2008-06-20)
24  *
25  */
26
27 #include <libraw1394/raw1394.h>
28 #include <libiec61883/iec61883.h>
29
30 #include "debugmodule/debugmodule.h"
31
32 #include "devicemanager.h"
33
34 #include "libieee1394/configrom.h"
35 #include "libieee1394/ieee1394service.h"
36 #include "libutil/Configuration.h"
37
38 #include "libcontrol/MatrixMixer.h"
39 #include "libcontrol/CrossbarRouter.h"
40
41 #include "dice/dice_avdevice.h"
42 #include "dice/dice_firmware_loader.h"
43 #include "dice/dice_eap.h"
44
45 using namespace Dice;
46
47 #include <argp.h>
48 #include <iostream>
49 #include <cstdlib>
50 #include <cstring>
51
52 #include <signal.h>
53 int run;
54
55 static void sighandler(int sig)
56 {
57     run = 0;
58 }
59
60 using namespace std;
61 using namespace Util;
62
63 DECLARE_GLOBAL_DEBUG_MODULE;
64
65 #define MAX_ARGS 1000
66
67 ////////////////////////////////////////////////
68 // arg parsing
69 ////////////////////////////////////////////////
70 const char *argp_program_version = "dice-firmware-utility v1.0";
71 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>";
72 static char doc[] = "dice-firmware-utility -- utility for flashing DICE device firmware\n\n"
73                                         "Part of the FFADO project -- www.ffado.org\n"
74                                         "Version: 1.0\n"
75                                         "(C) 2012, Peter Hinkel\n"
76                                         "This program comes with absolutely no warranty.\n\n"
77                                         "OPERATIONS:\n"
78                                         "test\n"
79                                         "   POKE = 1 (write addr), PEEK = 2 (read addr)\n"
80                                         "verbose\n"
81                                         "   LEVEL = 0..8, 4 (default), disabled (-1)\n\n"
82                                         "example: dice-firmware-utility -p 0 -f firmware.bin";
83
84 static char args_doc[] = "";
85 static struct argp_option options[] = {
86         {"application", 'a', NULL,                      0, "Show dice image application information"},
87         {"delete",              'd', "IMAGENAME",       0, "Delete image by name"},
88         {"dump",                'e', "FILENAME",        0, "Extract DICE flash into file"},
89         {"flash",               'f', "FILENAME",        0, "Write firmware file to DICE device"},
90         {"image-info",  'i', NULL,                      0, "Show detailed information about each image within firmware"},
91         {"flash-info",  'm', NULL,                      0, "Show information about flash memory"},
92         {"dice-info",   's', NULL,                      0, "Show dice image vendor and product information"},
93         {"test",                't', "OPERATION",       0, "Test and Debug operation"},
94         {"node",                'n', "NODE",            0, "Set node"},
95         {"port",                'p', "PORT",            0, "Set port"},
96         {"verbose",             'v', "LEVEL",           0, "Verbosity for DEBUG output"},
97         {0}
98 };
99
100 struct arguments {
101
102         arguments()
103                 : nargs(0)
104                 , application(false)
105                 , del(false)
106                 , dump(false)
107                 , flash(false)
108                 , image_info(false)
109                 , flash_info(false)
110                 , dice_info(false)
111                 , test(0)
112                 , filename(NULL)
113                 , imgname(NULL)
114                 , node(-1)
115                 , port(-1)
116                 , verbose(4/*-1*/)
117
118                 {
119                         args[0] = 0;
120                 }
121
122         char* args[MAX_ARGS];
123         int   nargs;
124         bool  application;
125         bool  del;
126         bool  dump;
127         bool  flash;
128         bool  image_info;
129         bool  flash_info;
130         bool  dice_info;
131         int   test;
132         char* filename;
133         char* imgname;
134         int   node;
135         int   port;
136         int   verbose;
137 } arguments;
138
139 // Parse a single option.
140 static error_t
141 parse_opt( int key, char* arg, struct argp_state* state )
142 {
143         // Get the input argument from `argp_parse', which we
144         // know is a pointer to our arguments structure.
145         struct arguments* arguments = ( struct arguments* ) state->input;
146
147         char* tail;
148         errno = 0;
149         switch (key) {
150         case 'a':
151                 arguments->application = true;
152                 break;
153         case 'd':
154                 arguments->del = true;
155                 arguments->imgname = arg;
156                 break;
157         case 'e':
158                 arguments->dump = true;
159                 arguments->filename = arg;
160                 break;
161         case 'f':
162         arguments->flash = true;
163                 arguments->filename = arg;
164                 break;
165         case 'i':
166                 arguments->image_info = true;
167                 break;
168         case 'm':
169                 arguments->flash_info = true;
170                 break;
171         case 's':
172                 arguments->dice_info = true;
173                 break;
174         case 't':
175                 arguments->test = strtol(arg, &tail, 0);
176                 if (errno) {
177                         perror("argument parsing failed:");
178                         return errno;
179                 }
180                 break;
181         case 'v':
182                 arguments->verbose = strtol(arg, &tail, 0);
183                 break;
184         case 'p':
185                 arguments->port = strtol(arg, &tail, 0);
186                 if (errno) {
187                         perror("argument parsing failed:");
188                         return errno;
189                 }
190                 break;
191         case 'n':
192                 arguments->node = strtol(arg, &tail, 0);
193                 if (errno) {
194                         perror("argument parsing failed:");
195                         return errno;
196                 }
197                 break;
198         case ARGP_KEY_ARG:
199                 if (state->arg_num >= MAX_ARGS) {
200                         // Too many arguments.
201                         argp_usage (state);
202                 }
203                 arguments->args[state->arg_num] = arg;
204                 arguments->nargs++;
205                 break;
206         case ARGP_KEY_END:
207                 if(arguments->nargs<0) {
208                         printf("not enough arguments\n");
209                         return -1;
210                 }
211                 break;
212         default:
213                 return ARGP_ERR_UNKNOWN;
214         }
215         return 0;
216 }
217
218 static struct argp argp = { options, parse_opt, args_doc, doc };
219
220 ///////////////////////////
221 // main
222 //////////////////////////
223 int
224 main(int argc, char **argv)
225 {
226         if (argc<=1) {
227                 cout << "Try `" << argv[0] << " --help' or `" << argv[0] << " --usage' for more information." << endl;
228                 return -1;
229         }
230
231         run=1;
232
233         signal (SIGINT, sighandler);
234         signal (SIGPIPE, sighandler);
235
236         // arg parsing
237         if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
238                 printMessage("Could not parse command line\n" );
239                 exit(-1);
240         }
241         errno = 0;
242
243         DeviceManager *m_deviceManager = new DeviceManager();
244         if ( !m_deviceManager ) {
245                 printMessage("Could not allocate device manager\n" );
246                 return -1;
247         }
248
249         if ( arguments.verbose ) {
250                 m_deviceManager->setVerboseLevel(arguments.verbose);
251         }
252
253         if ( !m_deviceManager->initialize() ) {
254                 printMessage("Could not initialize device manager\n" );
255                 delete m_deviceManager;
256                 return -1;
257         }
258
259         char s[1024];
260         if(arguments.node > -1) {
261                 snprintf(s, 1024, "hw:%d,%d", arguments.port, arguments.node);
262                 if ( !m_deviceManager->addSpecString(s) ) {
263                         printMessage("Could not add spec string %s to device manager\n", s );
264                         delete m_deviceManager;
265                         return -1;
266                 }
267         } else {
268                 snprintf(s, 1024, "hw:%d", arguments.port);
269                 if ( !m_deviceManager->addSpecString(s) ) {
270                         printMessage("Could not add spec string %s to device manager\n", s );
271                         delete m_deviceManager;
272                         return -1;
273                 }
274         }
275
276         if ( !m_deviceManager->discover(false) ) {
277                 printMessage("Could not discover devices\n" );
278                 delete m_deviceManager;
279                 return -1;
280         }
281
282         if(m_deviceManager->getAvDeviceCount() == 0) {
283                 printMessage("No devices found\n");
284                 delete m_deviceManager;
285                 return -1;
286         }
287
288         Dice::Device* avDevice = dynamic_cast<Dice::Device*>(m_deviceManager->getAvDeviceByIndex(0));
289
290         if(avDevice == NULL) {
291                 printMessage("Device is not a DICE device\n" );
292                 delete m_deviceManager;
293                 return -1;
294         }
295
296         if (argc<=5) {
297
298                 if (arguments.application) {
299                         avDevice->showAppInfoFL();
300                 }
301
302                 if (arguments.del) {
303                         avDevice->deleteImgFL(arguments.imgname);
304                 }
305
306                 if (arguments.dump) {
307                         avDevice->dumpFirmwareFL(arguments.filename);
308                 }
309
310                 if (arguments.flash) {
311                         avDevice->flashDiceFL(arguments.filename);
312                 }
313
314                 if (arguments.image_info) {
315                         avDevice->showImgInfoFL();
316                 }
317
318                 if (arguments.flash_info) {
319                         avDevice->showFlashInfoFL();
320                 }
321
322                 if (arguments.dice_info) {
323                         avDevice->showDiceInfoFL();
324                 }
325
326                 if (arguments.test) {
327                         avDevice->testDiceFL(arguments.test);
328                 }
329         } else {
330                 printMessage("Too many arguments...");
331         }
332
333         // cleanup
334         delete m_deviceManager;
335         return 0;
336 }
Note: See TracBrowser for help on using the browser.