46 #define low(x) (1 << x)
47 #define high(x) (1 << (x + 8))
49 #define REDBEE_ECONOTAG_RESET high(2)
50 #define REDBEE_ECONOTAG_VREF2L high(7)
51 #define REDBEE_ECONOTAG_VREF2H high(6)
52 #define REDBEE_ECONOTAG_INTERFACE INTERFACE_A
54 #define REDBEE_USB_RESET high(2)
55 #define REDBEE_USB_VREF2L low(5)
56 #define REDBEE_USB_VREF2H low(6)
57 #define REDBEE_USB_INTERFACE INTERFACE_B
59 #define BOARD REDBEE_USB
62 #define STR2(x) STR(x)
64 #define CAT2(x, y, z) x##y##z
66 #define dir(x) ( CAT(x,_RESET) | CAT(x,_VREF2L) | CAT(x,_VREF2H))
67 #define interface(x) ( CAT(x,_INTERFACE) )
68 #define reset_release(x) ( CAT(x,_RESET) )
69 #define reset_set(x) ( 0 )
70 #define vref2_normal(x) ( CAT(x,_VREF2H) )
71 #define vref2_erase(x) ( CAT(x,_VREF2L) )
79 enum ftdi_interface interface;
81 uint16_t reset_release;
83 uint16_t vref2_normal;
87 int print_and_prompt(
struct ftdi_device_list *devlist );
88 int bb_mpsee(
struct ftdi_context *ftdic, uint16_t dir, uint16_t val);
89 void reset(
struct ftdi_context *ftdic,
const struct layout * l);
90 void erase(
struct ftdi_context *ftdic,
const struct layout * l);
93 #define std_layout(x) \
94 .interface = interface(x), \
96 .reset_release = reset_release(x), \
97 .reset_set = reset_set(x), \
98 .vref2_normal = vref2_normal(x), \
99 .vref2_erase = vref2_erase(x),
101 static struct layout layouts[] =
103 { .name =
"redbee-econotag",
104 .desc =
"Redbee Econotag",
105 std_layout(REDBEE_ECONOTAG)
107 { .name =
"redbee-usb",
108 .desc =
"Redbee USB stick",
109 std_layout(REDBEE_USB)
117 void (*cmd)(
struct ftdi_context *ftdic,
const struct layout * l);
120 static const struct command commands[] =
124 .desc =
"Toggles reset pin",
129 .desc =
"Sets VREF2 erase mode; toggles reset; waits 2 sec.; sets normal; toggles reset again",
135 struct layout * find_layout(
char * str)
139 while(layouts[i].name !=
NULL) {
140 if(strcmp(layouts[i].name, str) == 0) {
return &layouts[i]; }
147 static uint32_t vendid = 0x0403; uint32_t prodid = 0x6010;
149 int main(
int argc,
char **argv)
151 struct ftdi_context ftdic;
152 struct ftdi_device_list *devlist;
153 int dev_index = -1;
int num_devs;
154 char layout_str[BUF_LEN];
155 struct layout layout;
156 struct layout *l =
NULL;
162 int reset_release = -1;
164 int vref2_normal = -1;
165 int vref2_erase = -1;
171 int option_index = 0;
172 static struct option long_options[] = {
173 {
"layout", required_argument, 0,
'l'},
174 {
"index", required_argument, 0,
'i'},
175 {
"vendor", required_argument, 0,
'v'},
176 {
"product", required_argument, 0,
'p'},
177 {
"dir", required_argument, 0, 0 },
178 {
"reset_release", required_argument, 0, 0 },
179 {
"reset_set", required_argument, 0, 0 },
180 {
"vref2_normal", required_argument, 0, 0 },
181 {
"vref2_erase", required_argument, 0, 0 },
182 {
"interface", required_argument, 0, 0 },
183 {
"help", no_argument, 0,
'?'},
187 c = getopt_long (argc, argv,
"i:l:v:p:",
188 long_options, &option_index);
195 if(strcmp(long_options[option_index].name,
"interface") == 0) {
196 sscanf(optarg,
"%i", &interface);
198 if(strcmp(long_options[option_index].name,
"dir") == 0) {
199 sscanf(optarg,
"%i", &dir);
201 if (strcmp(long_options[option_index].name,
"reset_release") == 0) {
202 sscanf(optarg,
"%i", &reset_release);
204 if (strcmp(long_options[option_index].name,
"reset_set") == 0) {
205 sscanf(optarg,
"%i", &reset_set);
207 if (strcmp(long_options[option_index].name,
"vref2_normal") == 0) {
208 sscanf(optarg,
"%i", &vref2_normal);
210 if (strcmp(long_options[option_index].name,
"vref2_erase") == 0) {
211 sscanf(optarg,
"%i", &vref2_erase);
216 strncpy(layout_str, optarg, BUF_LEN);
219 dev_index = atoi(optarg);
222 sscanf(optarg,
"%i", &vendid);
225 sscanf(optarg,
"%i", &prodid);
233 if( !(l = find_layout(layout_str)) &&
234 !((interface >= 0) &&
236 (reset_release >= 0) &&
238 (vref2_normal >= 0) &&
242 printf(
"*** You must specify a layout or a complete set of overrides\n");
247 memcpy(&layout, l,
sizeof(
struct layout));
250 #define override(x) if(x > 0) { layout.x = x; }
253 override(reset_release);
override(reset_set);
254 override(vref2_normal);
override(vref2_erase);
256 if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0)
258 fprintf(stderr,
"ftdi_usb_find_all failed: %d (%s)\n",
260 ftdi_get_error_string(&ftdic));
264 if (ftdi_init(&ftdic) < 0)
266 fprintf(stderr,
"ftdi_init failed\n");
270 if (ftdi_set_interface(&ftdic, layout.interface) < 0) {
271 fprintf(stderr,
"couldn't set interface %d\n", layout.interface);
275 printf(
"Found %d devices with vendor id 0x%04x product id 0x%04x\n",
276 num_devs, vendid, prodid);
278 if(num_devs == 0) {
return EXIT_SUCCESS; }
280 if(num_devs == 1) { dev_index = 0; }
281 while( (dev_index < 0) || (dev_index >= num_devs)){
282 dev_index = print_and_prompt(devlist);
285 if(layout.name !=
NULL) {
286 printf(
"Opening device %d interface %d using layout %s\n",
287 dev_index, layout.interface, layout.name);
289 printf(
"Opening device %d interface %d without a layout.\n",
290 dev_index, layout.interface);
293 if( (ret = ftdi_usb_open_desc_index(
300 fprintf(stderr,
"couldn't open dev_index %d\n", dev_index);
305 for(i = 0; commands[i].name !=
NULL; i++) {
306 if( (argv[optind] !=
NULL) &&
307 (strcmp(commands[i].name, argv[optind]) == 0)) {
break; }
309 if(commands[i].name !=
NULL) {
310 commands[i].cmd(&ftdic, &layout);
312 printf(
"invalid command\n");
314 ftdi_list_free(&devlist);
322 ftdi_list_free(&devlist);
331 printf(
"Usage: bbmc [options|overrides] -l|--layout layout command \n");
332 printf(
"Commands:\n");
333 for(i = 0; commands[i].name !=
NULL; i++) {
334 printf(
" %s: %s\n", commands[i].name, commands[i].desc);
337 printf(
"Required options:\n");
338 printf(
" -l|--layout\t specifiy which board layout to use\n");
339 printf(
" \t layout is not necessary with a full\n");
340 printf(
" \t set of overrides\n");
341 printf(
"\nLayout overrides:\n");
342 printf(
" --interface\t\t FTDI interface to use\n");
343 printf(
" --dir\t\t direction (1 is output)\n");
344 printf(
" --reset_release\t reset release command\n");
345 printf(
" --reset_set\t\t reset set command\n");
346 printf(
" --vref2_normal\t vref2 normal\n");
347 printf(
" --vref2_erase\t vref2 erase\n");
349 printf(
"Layouts:\n");
350 for(i = 0; layouts[i].name !=
NULL; i++) {
351 printf(
"\t%s: %s\n", layouts[i].name, layouts[i].desc);
353 printf(
"\t\tinterface: \t0x%04x\n", layouts[i].interface);
354 printf(
"\t\tdir: \t\t0x%04x\n", layouts[i].dir);
355 printf(
"\t\treset release: \t0x%04x\n", layouts[i].reset_release);
356 printf(
"\t\treset hold: \t0x%04x\n", layouts[i].reset_set);
357 printf(
"\t\tvref2 normal: \t0x%04x\n", layouts[i].vref2_normal);
358 printf(
"\t\tvref2 erase: \t0x%04x\n", layouts[i].vref2_erase);
362 printf(
"Options:\n");
363 printf(
" -i|--index specifiy which device to use (default 0)\n");
364 printf(
" -v|--vendor set vendor id (default 0x0403)\n");
365 printf(
" -p|--product set vendor id (default 0x6010)\n");
368 int print_and_prompt(
struct ftdi_device_list *devlist )
371 struct ftdi_context ftdic;
372 struct ftdi_device_list *curdev;
373 char manufacturer[128], description[128], serial[128];
374 char input[BUF_LEN];
char *s;
380 for (curdev = devlist; curdev !=
NULL; i++)
383 if (0 > (ret = ftdi_usb_get_strings(&ftdic,
389 fprintf(stderr,
"ftdi_usb_get_strings failed: %d (%s)\n",
390 ret, ftdi_get_error_string(&ftdic));
393 printf(
"Manufacturer: %s, Description: %s, Serial %s\n",
394 manufacturer, description, serial);
395 curdev = curdev->next;
398 printf(
"\nUse which device? ");
400 s = fgets(input, BUF_LEN, stdin);
402 size_t last = strlen (input) - 1;
403 if (input[last] ==
'\n') input[last] =
'\0';
406 sscanf(s,
"%i",&sel);
411 void reset(
struct ftdi_context *ftdic,
const struct layout * l)
416 ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
418 printf(
"toggle reset\n");
420 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
421 bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_normal));
422 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
429 void erase(
struct ftdi_context *ftdic,
const struct layout * l)
431 printf(
"setting VREF2 erase\n");
435 ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
437 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
438 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
440 printf(
"toggle reset\n");
442 bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_erase));
443 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
445 printf(
"waiting for erase\n");
449 printf(
"setting VREF2 normal\n");
451 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
460 int bb_mpsee(
struct ftdi_context *ftdic, uint16_t dir, uint16_t val)
467 buf[1] = (val & 0xff);
470 fprintf(stderr,
"write %x %x %x\n",buf[0],buf[1],buf[2]);
473 if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0)
475 perror(
"ft2232_write error");
476 fprintf(stderr,
"ft2232_write command %x\n", buf[0]);
486 fprintf(stderr,
"write %x %x %x\n",buf[0],buf[1],buf[2]);
489 if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0)
491 perror(
"ft2232_write error");
492 fprintf(stderr,
"ft2232_write command %x\n", buf[0]);