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 FLEXIBITY_USB_RESET high(2)
60 #define FLEXIBITY_USB_VREF2L high(7)
61 #define FLEXIBITY_USB_VREF2H high(6)
62 #define FLEXIBITY_USB_INTERFACE INTERFACE_A
64 #define BOARD REDBEE_USB
67 #define STR2(x) STR(x)
69 #define CAT2(x, y, z) x##y##z
71 #define dir(x) ( CAT(x,_RESET) | CAT(x,_VREF2L) | CAT(x,_VREF2H))
72 #define interface(x) ( CAT(x,_INTERFACE) )
73 #define reset_release(x) ( CAT(x,_RESET) )
74 #define reset_set(x) ( 0 )
75 #define vref2_normal(x) ( CAT(x,_VREF2H) )
76 #define vref2_erase(x) ( CAT(x,_VREF2L) )
84 enum ftdi_interface interface;
86 uint16_t reset_release;
88 uint16_t vref2_normal;
92 int print_and_prompt(
struct ftdi_device_list *devlist );
93 int bb_mpsee(
struct ftdi_context *ftdic, uint16_t dir, uint16_t val);
94 void reset(
struct ftdi_context *ftdic,
const struct layout * l);
95 void erase(
struct ftdi_context *ftdic,
const struct layout * l);
98 #define std_layout(x) \
99 .interface = interface(x), \
101 .reset_release = reset_release(x), \
102 .reset_set = reset_set(x), \
103 .vref2_normal = vref2_normal(x), \
104 .vref2_erase = vref2_erase(x),
106 static struct layout layouts[] =
108 { .name =
"redbee-econotag",
109 .desc =
"Redbee Econotag",
110 std_layout(REDBEE_ECONOTAG)
112 { .name =
"redbee-usb",
113 .desc =
"Redbee USB stick",
114 std_layout(REDBEE_USB)
116 { .name =
"flexibity",
117 .desc =
"Flexibity USB Interface",
118 std_layout(FLEXIBITY_USB)
126 void (*cmd)(
struct ftdi_context *ftdic,
const struct layout * l);
129 static const struct command commands[] =
133 .desc =
"Toggles reset pin",
138 .desc =
"Sets VREF2 erase mode; toggles reset; waits 2 sec.; sets normal; toggles reset again",
144 struct layout * find_layout(
char * str)
148 while(layouts[i].name !=
NULL) {
149 if(strcmp(layouts[i].name, str) == 0) {
return &layouts[i]; }
156 static uint32_t vendid = 0x0403; uint32_t prodid = 0x6010;
158 int main(
int argc,
char **argv)
160 struct ftdi_context ftdic;
161 struct ftdi_device_list *devlist;
162 int dev_index = -1;
int num_devs;
163 char layout_str[BUF_LEN];
164 struct layout layout;
165 struct layout *l =
NULL;
171 int reset_release = -1;
173 int vref2_normal = -1;
174 int vref2_erase = -1;
180 int option_index = 0;
181 static struct option long_options[] = {
182 {
"layout", required_argument, 0,
'l'},
183 {
"index", required_argument, 0,
'i'},
184 {
"vendor", required_argument, 0,
'v'},
185 {
"product", required_argument, 0,
'p'},
186 {
"dir", required_argument, 0, 0 },
187 {
"reset_release", required_argument, 0, 0 },
188 {
"reset_set", required_argument, 0, 0 },
189 {
"vref2_normal", required_argument, 0, 0 },
190 {
"vref2_erase", required_argument, 0, 0 },
191 {
"interface", required_argument, 0, 0 },
192 {
"help", no_argument, 0,
'?'},
196 c = getopt_long (argc, argv,
"i:l:v:p:",
197 long_options, &option_index);
204 if(strcmp(long_options[option_index].name,
"interface") == 0) {
205 sscanf(optarg,
"%i", &interface);
207 if(strcmp(long_options[option_index].name,
"dir") == 0) {
208 sscanf(optarg,
"%i", &dir);
210 if (strcmp(long_options[option_index].name,
"reset_release") == 0) {
211 sscanf(optarg,
"%i", &reset_release);
213 if (strcmp(long_options[option_index].name,
"reset_set") == 0) {
214 sscanf(optarg,
"%i", &reset_set);
216 if (strcmp(long_options[option_index].name,
"vref2_normal") == 0) {
217 sscanf(optarg,
"%i", &vref2_normal);
219 if (strcmp(long_options[option_index].name,
"vref2_erase") == 0) {
220 sscanf(optarg,
"%i", &vref2_erase);
225 strncpy(layout_str, optarg, BUF_LEN);
228 dev_index = atoi(optarg);
231 sscanf(optarg,
"%i", &vendid);
234 sscanf(optarg,
"%i", &prodid);
242 if( !(l = find_layout(layout_str)) &&
243 !((interface >= 0) &&
245 (reset_release >= 0) &&
247 (vref2_normal >= 0) &&
251 printf(
"*** You must specify a layout or a complete set of overrides\n");
256 memcpy(&layout, l,
sizeof(
struct layout));
259 #define override(x) if(x > 0) { layout.x = x; }
262 override(reset_release);
override(reset_set);
263 override(vref2_normal);
override(vref2_erase);
265 if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0)
267 fprintf(stderr,
"ftdi_usb_find_all failed: %d (%s)\n",
269 ftdi_get_error_string(&ftdic));
273 if (ftdi_init(&ftdic) < 0)
275 fprintf(stderr,
"ftdi_init failed\n");
279 if (ftdi_set_interface(&ftdic, layout.interface) < 0) {
280 fprintf(stderr,
"couldn't set interface %d\n", layout.interface);
284 printf(
"Found %d devices with vendor id 0x%04x product id 0x%04x\n",
285 num_devs, vendid, prodid);
287 if(num_devs == 0) {
return EXIT_SUCCESS; }
289 if(num_devs == 1) { dev_index = 0; }
290 while( (dev_index < 0) || (dev_index >= num_devs)){
291 dev_index = print_and_prompt(devlist);
294 if(layout.name !=
NULL) {
295 printf(
"Opening device %d interface %d using layout %s\n",
296 dev_index, layout.interface, layout.name);
298 printf(
"Opening device %d interface %d without a layout.\n",
299 dev_index, layout.interface);
302 if( (ret = ftdi_usb_open_desc_index(
309 fprintf(stderr,
"couldn't open dev_index %d\n", dev_index);
314 for(i = 0; commands[i].name !=
NULL; i++) {
315 if( (argv[optind] !=
NULL) &&
316 (strcmp(commands[i].name, argv[optind]) == 0)) {
break; }
318 if(commands[i].name !=
NULL) {
319 commands[i].cmd(&ftdic, &layout);
321 printf(
"invalid command\n");
323 ftdi_list_free(&devlist);
331 ftdi_list_free(&devlist);
340 printf(
"Usage: bbmc [options|overrides] -l|--layout layout command \n");
341 printf(
"Commands:\n");
342 for(i = 0; commands[i].name !=
NULL; i++) {
343 printf(
" %s: %s\n", commands[i].name, commands[i].desc);
346 printf(
"Required options:\n");
347 printf(
" -l|--layout\t specifiy which board layout to use\n");
348 printf(
" \t layout is not necessary with a full\n");
349 printf(
" \t set of overrides\n");
350 printf(
"\nLayout overrides:\n");
351 printf(
" --interface\t\t FTDI interface to use\n");
352 printf(
" --dir\t\t direction (1 is output)\n");
353 printf(
" --reset_release\t reset release command\n");
354 printf(
" --reset_set\t\t reset set command\n");
355 printf(
" --vref2_normal\t vref2 normal\n");
356 printf(
" --vref2_erase\t vref2 erase\n");
358 printf(
"Layouts:\n");
359 for(i = 0; layouts[i].name !=
NULL; i++) {
360 printf(
"\t%s: %s\n", layouts[i].name, layouts[i].desc);
362 printf(
"\t\tinterface: \t0x%04x\n", layouts[i].interface);
363 printf(
"\t\tdir: \t\t0x%04x\n", layouts[i].dir);
364 printf(
"\t\treset release: \t0x%04x\n", layouts[i].reset_release);
365 printf(
"\t\treset hold: \t0x%04x\n", layouts[i].reset_set);
366 printf(
"\t\tvref2 normal: \t0x%04x\n", layouts[i].vref2_normal);
367 printf(
"\t\tvref2 erase: \t0x%04x\n", layouts[i].vref2_erase);
371 printf(
"Options:\n");
372 printf(
" -i|--index specifiy which device to use (default 0)\n");
373 printf(
" -v|--vendor set vendor id (default 0x0403)\n");
374 printf(
" -p|--product set vendor id (default 0x6010)\n");
377 int print_and_prompt(
struct ftdi_device_list *devlist )
380 struct ftdi_context ftdic;
381 struct ftdi_device_list *curdev;
382 char manufacturer[128], description[128], serial[128];
383 char input[BUF_LEN];
char *s;
389 for (curdev = devlist; curdev !=
NULL; i++)
392 if (0 > (ret = ftdi_usb_get_strings(&ftdic,
398 fprintf(stderr,
"ftdi_usb_get_strings failed: %d (%s)\n",
399 ret, ftdi_get_error_string(&ftdic));
402 printf(
"Manufacturer: %s, Description: %s, Serial %s\n",
403 manufacturer, description, serial);
404 curdev = curdev->next;
407 printf(
"\nUse which device? ");
409 s = fgets(input, BUF_LEN, stdin);
411 size_t last = strlen (input) - 1;
412 if (input[last] ==
'\n') input[last] =
'\0';
415 sscanf(s,
"%i",&sel);
420 void reset(
struct ftdi_context *ftdic,
const struct layout * l)
425 ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
427 printf(
"toggle reset\n");
429 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
430 bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_normal));
431 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
438 void erase(
struct ftdi_context *ftdic,
const struct layout * l)
440 printf(
"setting VREF2 erase\n");
444 ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
446 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
447 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
449 printf(
"toggle reset\n");
451 bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_erase));
452 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
454 printf(
"waiting for erase\n");
458 printf(
"setting VREF2 normal\n");
460 bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
469 int bb_mpsee(
struct ftdi_context *ftdic, uint16_t dir, uint16_t val)
476 buf[1] = (val & 0xff);
479 fprintf(stderr,
"write %x %x %x\n",buf[0],buf[1],buf[2]);
482 if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0)
484 perror(
"ft2232_write error");
485 fprintf(stderr,
"ft2232_write command %x\n", buf[0]);
495 fprintf(stderr,
"write %x %x %x\n",buf[0],buf[1],buf[2]);
498 if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0)
500 perror(
"ft2232_write error");
501 fprintf(stderr,
"ft2232_write command %x\n", buf[0]);
#define NULL
The null pointer.
int main(void)
This is main...