OpenCores
URL https://opencores.org/ocsvn/gecko3/gecko3/trunk

Subversion Repositories gecko3

[/] [gecko3/] [trunk/] [GECKO3COM/] [gecko3com-fw/] [gecko3-util/] [gecko3-util.c] - Blame information for rev 36

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 nussgipfel
/* GECKO3COM
2
 *
3
 * Copyright (C) 2008 by
4
 *   ___    ____  _   _
5
 *  (  _`\ (  __)( ) ( )
6
 *  | (_) )| (_  | |_| |   Berne University of Applied Sciences
7
 *  |  _ <'|  _) |  _  |   School of Engineering and
8
 *  | (_) )| |   | | | |   Information Technology
9
 *  (____/'(_)   (_) (_)
10
 *
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation, either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
 
25
/*********************************************************************/
26
/** \file     gecko3-util.c
27
 *********************************************************************
28
 * \brief     simple small helper tool for GECKO3COM
29
 *
30
 *            with this tool you can set the serial number, hw revision
31
 *            and FPGA type of a GECKO3COM driven device.
32
 *            mainly this is the GECKO3main but the firmware could be
33
 *            used on other boards. \n
34
 *            Based on existing code of dfu-util and testlibusb
35
 *
36
 * \warning   does only work on little endian machines!
37
 *
38
 * \author    Christoph Zimmermann bfh.ch
39
 * \date      2009-1-23 first version
40
 * \date      2009-8-25 fixed some little bugs. option --device works now,
41
 *                      counts connected GECKO3 boards now correct.
42
 *
43
*/
44
 
45
#include <stdio.h>
46
#include <string.h>
47
#include <getopt.h>
48
#include <usb.h>
49
#include <errno.h>
50
 
51
#include "gecko3-util.h"
52
 
53
#define VERSION               "1.1"
54
 
55
 
56
/* global variables */
57
int debug;
58
static int verbose = 0;
59
 
60
/* type definitions */
61
struct usb_vendprod {
62
        u_int16_t vendor;
63
        u_int16_t product;
64
};
65
 
66
struct gecko3_if {
67
        u_int16_t vendor;
68
        u_int16_t product;
69
        u_int8_t configuration;
70
        u_int8_t interface;
71
        u_int8_t altsetting;
72
        unsigned int flags;
73
        struct usb_device *dev;
74
 
75
        struct usb_dev_handle *dev_handle;
76
};
77
 
78
static struct option opts[] = {
79
        { "help", 0, 0, 'h' },
80
        { "version", 0, 0, 'V' },
81
        { "verbose", 0, 0, 'v' },
82
        { "device", 1, 0, 'd' },
83
        { "transfer-size", 1, 0, 't' },
84
        { "set-serial", 1, 0, 's' },
85
        { "set-hw-rev", 1, 0, 'r' },
86
        { "set-fpga-type", 1, 0, 'f' },
87
        { "set-fpga-idcode", 1, 0, 'i' },
88
};
89
 
90
/*----------------------------------------------------------------------------*/
91
/* start of functions block */
92
 
93
/* define a portable function for reading a 16bit little-endian word */
94
unsigned short get_int16_le(const void *p)
95
{
96
    const unsigned char *cp = p;
97
 
98
    return ( cp[0] ) | ( ((unsigned short)cp[1]) << 8 );
99
}
100
 
101
static int _get_first_cb(struct gecko3_if *dif, void *v)
102
{
103
        struct gecko3_if *v_dif = v;
104
 
105
        memcpy(v_dif, dif, sizeof(*v_dif)-sizeof(struct usb_dev_handle *));
106
 
107
        /* return a value that makes find_gecko3_if return immediately */
108
        return 1;
109
}
110
 
111
 
112
/* Iterate over all matching devices within system */
113
static int iterate_gecko3_devices(struct gecko3_if *dif,
114
    int (*action)(struct usb_device *dev, void *user), void *user)
115
{
116
        struct usb_bus *usb_bus;
117
        struct usb_device *dev;
118
 
119
        /* Walk the tree and find our device. */
120
        for (usb_bus = usb_get_busses(); NULL != usb_bus;
121
             usb_bus = usb_bus->next) {
122
                for (dev = usb_bus->devices; NULL != dev; dev = dev->next) {
123
                        int retval;
124
 
125
                        if (dif && \
126
                            (dev->descriptor.idVendor == dif->vendor && \
127
                             dev->descriptor.idProduct == dif->product)) {
128
                          retval = action(dev, user);
129
                          if (retval)
130
                            return retval;
131
                        }
132
                }
133
        }
134
        return 0;
135
}
136
 
137
 
138
static int found_gecko3_device(struct usb_device *dev, void *user)
139
{
140
        struct gecko3_if *dif = user;
141
 
142
        dif->dev = dev;
143
        return 1;
144
}
145
 
146
 
147
/* Find the first device, save it in gecko3_if->dev */
148
static int get_first_gecko3_device(struct gecko3_if *dif)
149
{
150
        return iterate_gecko3_devices(dif, found_gecko3_device, dif);
151
}
152
 
153
 
154
static int count_one_gecko3_device(struct usb_device *dev, void *user)
155
{
156
        int *num = user;
157
 
158
        (*num)++;
159
        return 0;
160
}
161
 
162
 
163
/* Count matching devices within system */
164
static int count_gecko3_devices(struct gecko3_if *dif)
165
{
166
        int num_found = 0;
167
 
168
        iterate_gecko3_devices(dif, count_one_gecko3_device, &num_found);
169
        return num_found;
170
}
171
 
172
static int parse_vendprod(struct usb_vendprod *vp, const char *str)
173
{
174
        unsigned long vend, prod;
175
        const char *colon;
176
 
177
        colon = strchr(str, ':');
178
        if (!colon || strlen(colon) < 2)
179
                return -EINVAL;
180
 
181
        vend = strtoul(str, NULL, 16);
182
        prod = strtoul(colon+1, NULL, 16);
183
 
184
        if (vend > 0xffff || prod > 0xffff)
185
                return -EINVAL;
186
 
187
        vp->vendor = vend;
188
        vp->product = prod;
189
 
190
        return 0;
191
}
192
 
193
static void help(void)
194
{
195
        printf("Usage: gecko3-util [options] ...\n"
196
                "  -h --help\t\t\tPrint this help message\n"
197
                "  -V --version\t\t\tPrint the version number\n"
198
                "  -v --verbose\n"
199
                "  -d --device vendor:product\tSpecify Vendor/Product ID of GECKO3COM device\n"
200
                "  -t --transfer-size\t\tSpecify the number of bytes per USB Transfer\n"
201
                "  -s --set-serial\t\tWrite the Serial Number. Expects a String as argument\n"
202
                "  -r --set-hw-rev\t\tWrite the Hardware Revision. Only one digit\n"
203
                "  -f --set-fpga-type\t\tWrite the FPGA type. Formated as ASCII String\n"
204
                "  -i --set-fpga-idcode\t\tWrite the FPGA JTAG IDCODE. This is a 32bit Integer value\n"
205
                );
206
}
207
 
208
static void print_version(void)
209
{
210
        printf("gecko3-util version %s\n", VERSION);
211
}
212
 
213
/*----------------------------------------------------------------------------*/
214
 
215
int main(int argc, char **argv)
216
{
217
        struct usb_vendprod vendprod;
218
        struct gecko3_if _rt_dif, _dif, *dif = &_dif;
219
        char serial_num[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
220
        unsigned int hw_rev;
221
        char fpga_type[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
222
        char fpga_idcode[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
223
        int num_devs;
224
        unsigned int transfer_size = 0;
225
        const char *little_endian_data;
226
        int ret;
227
 
228
        printf("gecko3-util - (C) 2009 by Berne University of Applied Science\n"
229
               "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");
230
 
231
        memset(dif, 0, sizeof(*dif));
232
        dif->vendor = GECKO3COM_VID;
233
        dif->product = GECKO3COM_PID;
234
        dif->flags = 0;
235
 
236
        usb_init();
237
        //usb_set_debug(255);
238
        usb_find_busses();
239
        usb_find_devices();
240
 
241
        while (1) {
242
                int c, option_index = 0;
243
                c = getopt_long(argc, argv, "hVvd:t:s:r:i:f:", opts,
244
                                &option_index);
245
                if (c == -1)
246
                        break;
247
 
248
                switch (c) {
249
                case 'h':
250
                        help();
251
                        exit(0);
252
                        break;
253
                case 'V':
254
                        print_version();
255
                        exit(0);
256
                        break;
257
                case 'v':
258
                        verbose = 1;
259
                        break;
260
                case 'd':
261
                        /* Parse device */
262
                        if (parse_vendprod(&vendprod, optarg) < 0) {
263
                                fprintf(stderr, "unable to parse `%s'\n", optarg);
264
                                exit(2);
265
                        }
266
                        dif->vendor = vendprod.vendor;
267
                        dif->product = vendprod.product;
268
                        break;
269
                case 't':
270
                        transfer_size = atoi(optarg);
271
                        break;
272
                case 's':
273
                        dif->flags |= FL_SET_SERIAL;
274
                        strcpy(serial_num, optarg);
275
                        break;
276
                case 'i':
277
                        dif->flags |= FL_SET_FPGA_IDCODE;
278
                        strcpy(fpga_idcode, optarg);
279
                        break;
280
                case 'r':
281
                        dif->flags |= FL_SET_HW_REV;
282
                        hw_rev = atoi(optarg);
283
                        break;
284
                case 'f':
285
                        dif->flags |= FL_SET_FPGA_TYPE;
286
                        strcpy(fpga_type, optarg);
287
                        break;
288
                default:
289
                        help();
290
                        exit(2);
291
                }
292
        }
293
 
294
 
295
        if (dif->flags == 0) {
296
                fprintf(stderr, "You need to specify one of -s, -r, -f or -i\n\n");
297
                help();
298
                exit(2);
299
        }
300
 
301
        num_devs = count_gecko3_devices(dif);
302
        if (num_devs == 0) {
303
                fprintf(stderr, "No GECKO3COM USB device found\n");
304
                exit(1);
305
        } else if (num_devs > 1) {
306
                /* We do not support more than one GECKO3COM device */
307
                fprintf(stderr, "More than one GECKO3COM USB device found. "
308
                       "We can handle only one device at the same time. "
309
                       "Please disconnect all but one device\n");
310
                exit(3);
311
        }
312
        if (!get_first_gecko3_device(dif))
313
                exit(3);
314
 
315
        /* We have exactly one device. It's usb_device is now in dif->dev */
316
 
317
        printf("Opening USB Device 0x%04x:0x%04x...\n", dif->vendor, dif->product);
318
        dif->dev_handle = usb_open(dif->dev);
319
        if (!dif->dev_handle) {
320
                fprintf(stderr, "Cannot open device: %s\n", usb_strerror());
321
                exit(1);
322
        }
323
 
324
        printf("Claiming USB Interface...\n");
325
        if (usb_claim_interface(dif->dev_handle,GECKO3COM_IF) < 0) {
326
                fprintf(stderr, "Cannot claim interface: %s\n",
327
                        usb_strerror());
328
                exit(1);
329
        }
330
 
331
        /* write Serial Number to the device */
332
        if (dif->flags & FL_SET_SERIAL) {
333
               printf("Write Serial Number...\n");
334
               ret = usb_control_msg(dif->dev_handle,
335
                                     bmRT_TYPE_VENDOR | bmRT_DIR_OUT,  /* bmRequestType */
336
                                     VRQ_SET_SERIAL,                   /* bRequest      */
337
                                     0,                                /* wValue        */
338
                                     0,                                /* wIndex        */
339
                                     serial_num,                       /* Data          */
340
                                     SERIAL_NO_LEN,                    /* wLength       */
341
                                     TIMEOUT);
342
               if (ret < 0) {
343
                       fprintf(stderr, "Cannot write Serial Number: %s\n",
344
                               usb_strerror());
345
                       exit(1);
346
               }
347
        }
348
 
349
        /* write Hardware Revision to the device */
350
        if (dif->flags & FL_SET_HW_REV) {
351
               printf("Write Hardware Revision...\n");
352
               ret = usb_control_msg(dif->dev_handle,
353
                                     bmRT_TYPE_VENDOR | bmRT_DIR_OUT,  /* bmRequestType */
354
                                     VRQ_SET_HW_REV,                   /* bRequest      */
355
                                     0,                                /* wValue        */
356
                                     0,                                /* wIndex        */
357
                                     (char*)(&hw_rev),                 /* Data          */
358
                                     1,                                /* wLength       */
359
                                     TIMEOUT);
360
               if (ret < 0) {
361
                       fprintf(stderr, "Cannot write Hardware Revision: %s\n",
362
                               usb_strerror());
363
                       exit(1);
364
               }
365
        }
366
 
367
        /* write FPGA Type to the device */
368
        if (dif->flags & FL_SET_FPGA_TYPE) {
369
               printf("Write FPGA Type...\n");
370
               ret = usb_control_msg(dif->dev_handle,
371
                                     bmRT_TYPE_VENDOR | bmRT_DIR_OUT,  /* bmRequestType */
372
                                     VRQ_SET_FPGA_TYPE,                /* bRequest      */
373
                                     0,                                /* wValue        */
374
                                     0,                                /* wIndex        */
375
                                     fpga_type,                        /* Data          */
376
                                     FPGA_TYPE_LEN,                    /* wLength       */
377
                                     TIMEOUT);
378
               if (ret < 0) {
379
                       fprintf(stderr, "Cannot write FPGA Type: %s\n",
380
                               usb_strerror());
381
                       exit(1);
382
               }
383
        }
384
 
385
        /* write FPGA IDCODE to the device */
386
        if (dif->flags & FL_SET_FPGA_IDCODE) {
387
               printf("Write FPGA IDCODE...\n");
388
               ret = usb_control_msg(dif->dev_handle,
389
                                     bmRT_TYPE_VENDOR | bmRT_DIR_OUT,  /* bmRequestType */
390
                                     VRQ_SET_FPGA_IDCODE,              /* bRequest      */
391
                                     0,                                /* wValue        */
392
                                     0,                                /* wIndex        */
393
                                     fpga_idcode,                      /* Data          */
394
                                     FPGA_IDCODE_LEN,                  /* wLength       */
395
                                     TIMEOUT);
396
               if (ret < 0) {
397
                       fprintf(stderr, "Cannot write FPGA IDCODE: %s\n",
398
                               usb_strerror());
399
                       exit(1);
400
               }
401
        }
402
 
403
        printf("We're done. Cleaning up...\n");
404
        if (usb_release_interface(dif->dev_handle, GECKO3COM_IF) < 0) {
405
                fprintf(stderr, "Cannot release interface: %s\n",
406
                        usb_strerror());
407
                exit(1);
408
        }
409
        if (usb_close(dif->dev_handle) < 0) {
410
                fprintf(stderr, "Cannot close USB device: %s\n",
411
                        usb_strerror());
412
                exit(1);
413
        }
414
        printf("Finished\n");
415
        exit(0);
416
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.