diff --git a/tools/ftditools/bbmc.c b/tools/ftditools/bbmc.c index 96632ef0a..44e497e6b 100644 --- a/tools/ftditools/bbmc.c +++ b/tools/ftditools/bbmc.c @@ -34,12 +34,55 @@ #define vref2_normal(x) ( CAT(x,_VREF2H) ) #define vref2_erase(x) ( CAT(x,_VREF2L) ) +struct layout { + char *name; + enum ftdi_interface interface; + uint16_t dir; + uint16_t reset_release; + uint16_t reset_set; + uint16_t vref2_normal; + uint16_t vref2_erase; +}; + +#define std_layout(x) \ + .interface = interface(x), \ + .dir = dir(x), \ + .reset_release = reset_release(x), \ + .reset_set = reset_set(x), \ + .vref2_normal = vref2_normal(x), \ + .vref2_erase = vref2_erase(x), + +static const struct layout layouts[] = +{ + { .name = "redbee_econotag", + std_layout(REDBEE_ECONOTAG) + }, + { .name = "redbee_usb", + std_layout(REDBEE_USB) + }, + { .name = NULL, /* end of table */ }, +}; + + /* fgets input buffer length: for prompts and such */ #define BUF_LEN 32 -int print_and_prompt( struct ftdi_device_list *devlist, int num_devs); +int print_and_prompt( struct ftdi_device_list *devlist ); int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val); -void toggle_reset(struct ftdi_context *ftdic); +void toggle_reset(struct ftdi_context *ftdic, const struct layout * l); +void usage(void); + +const struct layout * find_layout(char * str) +{ + uint32_t i = 0; + + while(layouts[i].name != NULL) { + if(strcmp(layouts[i].name, str) == 0) { return &layouts[i]; } + i++; + } + + return NULL; +} static uint32_t vendid = 0x0403; uint32_t prodid = 0x6010; @@ -48,39 +91,52 @@ int main(int argc, char **argv) struct ftdi_context ftdic; struct ftdi_device_list *devlist; int dev_index = -1; int num_devs; + char layout_str[BUF_LEN]; + const struct layout *layout; int ret; while (1) { int c; int option_index = 0; static struct option long_options[] = { - {"index", required_argument, 0, 'i'}, - {"help", no_argument, 0, '?'}, + {"layout", required_argument, 0, 'l'}, + {"index", required_argument, 0, 'i'}, + {"help", no_argument, 0, '?'}, {0, 0, 0, 0} }; - c = getopt_long (argc, argv, "i:", + c = getopt_long (argc, argv, "i:l:", long_options, &option_index); if (c == -1) break; switch (c) { /* process long opts */ + case 'l': + strncpy(layout_str, optarg, BUF_LEN); + break; case 'i': dev_index = atoi(optarg); - printf("index %d\n", dev_index); + break; default: - printf("Usage: don't know yet\n"); + usage(); + break; } } + if( !(layout = find_layout(layout_str))) { + usage(); + printf("You must specify a layout\n"); + return EXIT_FAILURE; + } + if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0) { fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", num_devs, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; - } + } if (ftdi_init(&ftdic) < 0) { @@ -88,16 +144,23 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - if (ftdi_set_interface(&ftdic, interface(BOARD)) < 0) { - fprintf(stderr, "couldn't set interface %d\n", interface(BOARD)); + if (ftdi_set_interface(&ftdic, layout->interface) < 0) { + fprintf(stderr, "couldn't set interface %d\n", layout->interface); return EXIT_FAILURE; } + printf("Found %d devices with vendor id 0x%04x product id 0x%04x\n", + num_devs, vendid, prodid); + + if(num_devs == 0) { return EXIT_SUCCESS; } + if(num_devs == 1) { dev_index = 0; } while( (dev_index < 0) || (dev_index >= num_devs)){ - dev_index = print_and_prompt(devlist, num_devs); + dev_index = print_and_prompt(devlist); } + printf("Opening device %d using layout %s\n", dev_index, layout->name); + if( (ret = ftdi_usb_open_desc_index( &ftdic, vendid, @@ -108,7 +171,7 @@ int main(int argc, char **argv) fprintf(stderr, "couldn't open dev_index %d\n", dev_index); return EXIT_FAILURE; } - toggle_reset(&ftdic); + toggle_reset(&ftdic, layout); ftdi_list_free(&devlist); ftdi_deinit(&ftdic); @@ -116,7 +179,12 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } -int print_and_prompt( struct ftdi_device_list *devlist, int num_devs) +void usage(void) +{ + printf("Usage: don't know yet\n"); +} + +int print_and_prompt( struct ftdi_device_list *devlist ) { int i, ret; struct ftdi_context ftdic; @@ -125,9 +193,7 @@ int print_and_prompt( struct ftdi_device_list *devlist, int num_devs) char input[BUF_LEN]; char *s; int sel = -1; - printf("Found %d devices with vendor id 0x%04x product id 0x%04x\n\n", - num_devs, vendid, prodid); - + printf("\n"); i = 0; for (curdev = devlist; curdev != NULL; i++) @@ -161,7 +227,7 @@ int print_and_prompt( struct ftdi_device_list *devlist, int num_devs) return sel; } -void toggle_reset(struct ftdi_context *ftdic) +void toggle_reset(struct ftdi_context *ftdic, const struct layout * l) { printf("toggle reset\n"); @@ -169,9 +235,9 @@ void toggle_reset(struct ftdi_context *ftdic) /* set as inputs for now */ ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE); - bb_mpsee(ftdic, dir(BOARD), (reset_release(BOARD) | vref2_normal(BOARD))); - bb_mpsee(ftdic, dir(BOARD), (reset_set(BOARD) | vref2_normal(BOARD))); - bb_mpsee(ftdic, dir(BOARD), (reset_release(BOARD) | vref2_normal(BOARD))); + bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal)); + bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_normal)); + bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal)); return;