From 97f3b885820a12ce63101f2a95d1f4bdc7bf1f28 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sun, 14 Mar 2010 17:42:52 -0400 Subject: [PATCH 1/6] add ftditools and Bit-Bang-MC. Right now bbmc can toggle reset on the econotag. --- tools/ftditools/Makefile | 10 ++ tools/ftditools/bbmc.c | 242 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 tools/ftditools/Makefile create mode 100644 tools/ftditools/bbmc.c diff --git a/tools/ftditools/Makefile b/tools/ftditools/Makefile new file mode 100644 index 000000000..d52b445e1 --- /dev/null +++ b/tools/ftditools/Makefile @@ -0,0 +1,10 @@ +LDFLAGS = -lftdi + +TARGETS = bbmc + +CFLAGS = -Wall -Wextra #-Werror + +all: $(TARGETS) + +clean: + rm $(TARGETS) diff --git a/tools/ftditools/bbmc.c b/tools/ftditools/bbmc.c new file mode 100644 index 000000000..675a6d27b --- /dev/null +++ b/tools/ftditools/bbmc.c @@ -0,0 +1,242 @@ +/* control reset and VREF2 lines */ + +#include +#include +#include + +#define low(x) (1 << x) +#define high(x) (1 << (x + 8)) + +#define REDBEE_ECONOTAG_RESET high(2) +#define REDBEE_ECONOTAG_VREF2L high(7) +#define REDBEE_ECONOTAG_VREF2H high(6) +#define REDBEE_ECONOTAG_INTERFACE INTERFACE_A + +#define REDBEE_USB_RESET high(2) +#define REDBEE_USB_VREF2L low(5) +#define REDBEE_USB_VREF2H low(6) +#define REDBEE_USB_INTERFACE INTERFACE_B + +#define BOARD REDBEE_ECONOTAG + +#define STR(x) #x +#define STR2(x) STR(x) +#define CAT(x,y) x##y +#define CAT2(x, y, z) x##y##z + +#define dir(x) ( CAT(x,_RESET) | CAT(x,_VREF2L) | CAT(x,_VREF2H)) +#define interface(x) ( CAT(x,_INTERFACE) ) +#define reset_release(x) ( CAT(x,_RESET) ) +#define reset_set(x) ( 0 ) +#define vref2_normal(x) ( CAT(x,_VREF2H) ) +#define vref2_erase(x) ( CAT(x,_VREF2L) ) + +int print_and_prompt(struct ftdi_device_list *devlist); +void toggle_reset(struct ftdi_context *ftdic); + +int main(int argc, char **argv) +{ + int ret; + struct ftdi_context ftdic; + struct ftdi_device_list *devlist; + uint32_t vendid = 0x0403; uint32_t prodid = 0x6010; + int devindex = 0; + + while (1) { + int c; + int option_index = 0; + static struct option long_options[] = { + {"index", required_argument, 0, 'i'}, + {"help", no_argument, 0, '?'}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "i:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + /* process long opts */ + case 'i': + devindex = atoi(optarg); + printf("index %d\n", devindex); + default: + printf("Usage: don't know yet\n"); + } + } + + if ((ret = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0) + { + fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); + return EXIT_FAILURE; + } + + printf("Number of FTDI devices found: %d\n", ret); + + if (ftdi_init(&ftdic) < 0) + { + fprintf(stderr, "ftdi_init failed\n"); + return EXIT_FAILURE; + } + + if (ftdi_set_interface(&ftdic, interface(BOARD)) < 0) { + fprintf(stderr, "couldn't set interface %d\n", interface(BOARD)); + return EXIT_FAILURE; + } + + if( (ret == 1) /*|| device number passed on cmdline */ ) { + if( (ret = ftdi_usb_open_desc_index( + &ftdic, + vendid, + prodid, + NULL, + NULL, + devindex)) < 0) { + fprintf(stderr, "couldn't open devindex %d\n", devindex); + return EXIT_FAILURE; + } + toggle_reset(&ftdic); + } else { + print_and_prompt(devlist); + } + + ftdi_list_free(&devlist); + ftdi_deinit(&ftdic); + + return EXIT_SUCCESS; +} + +int print_and_prompt( struct ftdi_device_list *devlist ) +{ + int i, ret; + struct ftdi_context ftdic; + struct ftdi_device_list *curdev; + char manufacturer[128], description[128]; + + i = 0; + for (curdev = devlist; curdev != NULL; i++) + { + printf("Checking device: %d\n", i); + if (0 > (ret = ftdi_usb_get_strings(&ftdic, + curdev->dev, + manufacturer, 128, + description, 128, + NULL, 0))) + { + fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n", + ret, ftdi_get_error_string(&ftdic)); + return EXIT_FAILURE; + } + printf("Manufacturer: %s, Description: %s\n\n", manufacturer, description); + curdev = curdev->next; + } + + return EXIT_SUCCESS; +} + +void toggle_reset(struct ftdi_context *ftdic) +{ + uint8_t buf[3], size; + int ret; + + printf("toggle reset\n"); + + /* using MPSSE since it give access to high GPIO*/ + /* set as inputs for now */ + ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE); + + size = 3; + + /* RESET RELEASE */ + + /* initialize low byte */ + /* command "set data bits low byte" */ + buf[0] = 0x80; + buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) & 0xff); + buf[2] = dir(BOARD) & 0xff; + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); + + + if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return; + } + + + /* command "set data bits high byte" */ + buf[0] = 0x82; + buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) >> 8); + buf[2] = dir(BOARD) >> 8; + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); + + if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return; + } + + /* RESET HOLD */ + + /* initialize low byte */ + /* command "set data bits low byte" */ + buf[0] = 0x80; + buf[1] = ((reset_set(BOARD) | vref2_normal(BOARD)) & 0xff); + buf[2] = dir(BOARD) & 0xff; + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); + + if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return; + } + + /* command "set data bits high byte" */ + buf[0] = 0x82; + buf[1] = ((reset_set(BOARD) | vref2_normal(BOARD)) >> 8); + buf[2] = dir(BOARD) >> 8; + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); + + if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return; + } + + /* RESET RELEASE */ + + /* initialize low byte */ + /* command "set data bits low byte" */ + buf[0] = 0x80; + buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) & 0xff); + buf[2] = dir(BOARD) & 0xff; + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); + + if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return; + } + + /* command "set data bits high byte" */ + buf[0] = 0x82; + buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) >> 8); + buf[2] = dir(BOARD) >> 8; + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); + + if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return; + } + + return; + +} From 537ceafe2fd433782dff9b4a4c66984fd6d11420 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sun, 14 Mar 2010 18:08:13 -0400 Subject: [PATCH 2/6] update usage for flow control switch --- tools/mc1322x-load.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/mc1322x-load.pl b/tools/mc1322x-load.pl index 2c2517dec..c56aef892 100755 --- a/tools/mc1322x-load.pl +++ b/tools/mc1322x-load.pl @@ -31,8 +31,9 @@ if($filename eq '') { print " -s optional: secondary binary file to send\n"; print " -t default: /dev/ttyUSB0\n"; print " -b default: 115200\n"; - print " anything on the command line is sent serial device\n"; - print " after all of the files have been sent\n"; + print " -r [none|rts] flow control default: rts\n"; + print " anything on the command line is sent\n"; + print " after all of the files.\n"; exit; } From 8a7b50176ebe2170f2c71a4ee131597b04c6545e Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sun, 14 Mar 2010 19:09:33 -0400 Subject: [PATCH 3/6] finish up print and prompt device selection. --- tools/ftditools/bbmc.c | 227 ++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 125 deletions(-) diff --git a/tools/ftditools/bbmc.c b/tools/ftditools/bbmc.c index 675a6d27b..96632ef0a 100644 --- a/tools/ftditools/bbmc.c +++ b/tools/ftditools/bbmc.c @@ -1,9 +1,12 @@ /* control reset and VREF2 lines */ #include +#include #include #include +#define DEBUG 0 + #define low(x) (1 << x) #define high(x) (1 << (x + 8)) @@ -17,7 +20,7 @@ #define REDBEE_USB_VREF2H low(6) #define REDBEE_USB_INTERFACE INTERFACE_B -#define BOARD REDBEE_ECONOTAG +#define BOARD REDBEE_USB #define STR(x) #x #define STR2(x) STR(x) @@ -31,16 +34,21 @@ #define vref2_normal(x) ( CAT(x,_VREF2H) ) #define vref2_erase(x) ( CAT(x,_VREF2L) ) -int print_and_prompt(struct ftdi_device_list *devlist); +/* 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 bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val); void toggle_reset(struct ftdi_context *ftdic); +static uint32_t vendid = 0x0403; uint32_t prodid = 0x6010; + int main(int argc, char **argv) { - int ret; struct ftdi_context ftdic; struct ftdi_device_list *devlist; - uint32_t vendid = 0x0403; uint32_t prodid = 0x6010; - int devindex = 0; + int dev_index = -1; int num_devs; + int ret; while (1) { int c; @@ -59,21 +67,21 @@ int main(int argc, char **argv) switch (c) { /* process long opts */ case 'i': - devindex = atoi(optarg); - printf("index %d\n", devindex); + dev_index = atoi(optarg); + printf("index %d\n", dev_index); default: printf("Usage: don't know yet\n"); } } - if ((ret = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0) + if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0) { - fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); + fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", + num_devs, + ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } - printf("Number of FTDI devices found: %d\n", ret); - if (ftdi_init(&ftdic) < 0) { fprintf(stderr, "ftdi_init failed\n"); @@ -84,159 +92,128 @@ int main(int argc, char **argv) fprintf(stderr, "couldn't set interface %d\n", interface(BOARD)); return EXIT_FAILURE; } - - if( (ret == 1) /*|| device number passed on cmdline */ ) { - if( (ret = ftdi_usb_open_desc_index( - &ftdic, - vendid, - prodid, - NULL, - NULL, - devindex)) < 0) { - fprintf(stderr, "couldn't open devindex %d\n", devindex); - return EXIT_FAILURE; - } - toggle_reset(&ftdic); - } else { - print_and_prompt(devlist); + + if(num_devs == 1) { dev_index = 0; } + while( (dev_index < 0) || (dev_index >= num_devs)){ + dev_index = print_and_prompt(devlist, num_devs); } + if( (ret = ftdi_usb_open_desc_index( + &ftdic, + vendid, + prodid, + NULL, + NULL, + dev_index)) < 0) { + fprintf(stderr, "couldn't open dev_index %d\n", dev_index); + return EXIT_FAILURE; + } + toggle_reset(&ftdic); + ftdi_list_free(&devlist); ftdi_deinit(&ftdic); return EXIT_SUCCESS; } -int print_and_prompt( struct ftdi_device_list *devlist ) +int print_and_prompt( struct ftdi_device_list *devlist, int num_devs) { int i, ret; struct ftdi_context ftdic; struct ftdi_device_list *curdev; - char manufacturer[128], description[128]; + char manufacturer[128], description[128], serial[128]; + 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); + i = 0; for (curdev = devlist; curdev != NULL; i++) { - printf("Checking device: %d\n", i); + printf(" [%d] ", i); if (0 > (ret = ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, - NULL, 0))) + serial, 128))) { fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } - printf("Manufacturer: %s, Description: %s\n\n", manufacturer, description); + printf("Manufacturer: %s, Description: %s, Serial %s\n", + manufacturer, description, serial); curdev = curdev->next; } - return EXIT_SUCCESS; + printf("\nUse which device? "); + + s = fgets(input, BUF_LEN, stdin); + if (s != NULL) { + size_t last = strlen (input) - 1; + if (input[last] == '\n') input[last] = '\0'; + } + + sscanf(s, "%i",&sel); + + return sel; } void toggle_reset(struct ftdi_context *ftdic) { - uint8_t buf[3], size; - int ret; - printf("toggle reset\n"); /* using MPSSE since it give access to high GPIO*/ /* set as inputs for now */ ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE); - size = 3; - - /* RESET RELEASE */ - - /* initialize low byte */ - /* command "set data bits low byte" */ - buf[0] = 0x80; - buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) & 0xff); - buf[2] = dir(BOARD) & 0xff; - fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); - - - if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) - { - perror("ft2232_write error"); - fprintf(stderr, "ft2232_write command %x\n", buf[0]); - return; - } - - - /* command "set data bits high byte" */ - buf[0] = 0x82; - buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) >> 8); - buf[2] = dir(BOARD) >> 8; - fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); - - if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) - { - perror("ft2232_write error"); - fprintf(stderr, "ft2232_write command %x\n", buf[0]); - return; - } - - /* RESET HOLD */ - - /* initialize low byte */ - /* command "set data bits low byte" */ - buf[0] = 0x80; - buf[1] = ((reset_set(BOARD) | vref2_normal(BOARD)) & 0xff); - buf[2] = dir(BOARD) & 0xff; - fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); - - if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) - { - perror("ft2232_write error"); - fprintf(stderr, "ft2232_write command %x\n", buf[0]); - return; - } - - /* command "set data bits high byte" */ - buf[0] = 0x82; - buf[1] = ((reset_set(BOARD) | vref2_normal(BOARD)) >> 8); - buf[2] = dir(BOARD) >> 8; - fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); - - if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) - { - perror("ft2232_write error"); - fprintf(stderr, "ft2232_write command %x\n", buf[0]); - return; - } - - /* RESET RELEASE */ - - /* initialize low byte */ - /* command "set data bits low byte" */ - buf[0] = 0x80; - buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) & 0xff); - buf[2] = dir(BOARD) & 0xff; - fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); - - if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) - { - perror("ft2232_write error"); - fprintf(stderr, "ft2232_write command %x\n", buf[0]); - return; - } - - /* command "set data bits high byte" */ - buf[0] = 0x82; - buf[1] = ((reset_release(BOARD) | vref2_normal(BOARD)) >> 8); - buf[2] = dir(BOARD) >> 8; - fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); - - if ((ret = (ftdi_write_data(ftdic, buf, size))) < 0) - { - perror("ft2232_write error"); - fprintf(stderr, "ft2232_write command %x\n", buf[0]); - return; - } + 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))); return; } + + +int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val) +{ + uint8_t buf[3]; + int ret; + + /* command "set data bits low byte" */ + buf[0] = 0x80; + buf[1] = (val & 0xff); + buf[2] = dir & 0xff; +#if DEBUG + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); +#endif + + if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return EXIT_FAILURE; + } + + + /* command "set data bits high byte" */ + buf[0] = 0x82; + buf[1] = (val >> 8); + buf[2] = dir >> 8; +#if DEBUG + fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]); +#endif + + if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0) + { + perror("ft2232_write error"); + fprintf(stderr, "ft2232_write command %x\n", buf[0]); + return EXIT_FAILURE; + } + + return 0; + +} From 5751beb9357315b8920ed6be72b54ee0ca510b4c Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 15 Mar 2010 19:01:07 -0400 Subject: [PATCH 4/6] add a way to switch layouts --- tools/ftditools/bbmc.c | 106 +++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 20 deletions(-) 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; From 64e643bd0bba68effd38a2c80148b6d292ebc016 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Tue, 16 Mar 2010 16:35:39 -0400 Subject: [PATCH 5/6] add erase and reset commands --- tools/ftditools/bbmc.c | 88 +++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 13 deletions(-) diff --git a/tools/ftditools/bbmc.c b/tools/ftditools/bbmc.c index 44e497e6b..3708aab8d 100644 --- a/tools/ftditools/bbmc.c +++ b/tools/ftditools/bbmc.c @@ -34,6 +34,9 @@ #define vref2_normal(x) ( CAT(x,_VREF2H) ) #define vref2_erase(x) ( CAT(x,_VREF2L) ) +/* fgets input buffer length: for prompts and such */ +#define BUF_LEN 32 + struct layout { char *name; enum ftdi_interface interface; @@ -44,6 +47,12 @@ struct layout { uint16_t vref2_erase; }; +int print_and_prompt( struct ftdi_device_list *devlist ); +int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val); +void reset(struct ftdi_context *ftdic, const struct layout * l); +void erase(struct ftdi_context *ftdic, const struct layout * l); +void usage(void); + #define std_layout(x) \ .interface = interface(x), \ .dir = dir(x), \ @@ -62,15 +71,24 @@ static const struct layout layouts[] = }, { .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 bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val); -void toggle_reset(struct ftdi_context *ftdic, const struct layout * l); -void usage(void); +struct command { + char *name; + void (*cmd)(struct ftdi_context *ftdic, const struct layout * l); +}; + +static const struct command commands[] = +{ + { + .name = "reset", + .cmd = reset, + }, + { + .name = "erase", + .cmd = erase, + }, + { .name = NULL, /* end of table */ }, +}; const struct layout * find_layout(char * str) { @@ -93,7 +111,7 @@ int main(int argc, char **argv) int dev_index = -1; int num_devs; char layout_str[BUF_LEN]; const struct layout *layout; - int ret; + int i, ret; while (1) { int c; @@ -123,7 +141,7 @@ int main(int argc, char **argv) break; } } - + if( !(layout = find_layout(layout_str))) { usage(); printf("You must specify a layout\n"); @@ -171,7 +189,19 @@ int main(int argc, char **argv) fprintf(stderr, "couldn't open dev_index %d\n", dev_index); return EXIT_FAILURE; } - toggle_reset(&ftdic, layout); + + i = 0; + while(commands[i].name != NULL) { + if(strcmp(commands[i].name, argv[optind]) == 0) { break; } + i++; + } + if(commands[i].name != NULL) { + commands[i].cmd(&ftdic, layout); + } else { + printf("invalid command\n"); + } + + printf("done.\n"); ftdi_list_free(&devlist); ftdi_deinit(&ftdic); @@ -227,18 +257,50 @@ int print_and_prompt( struct ftdi_device_list *devlist ) return sel; } -void toggle_reset(struct ftdi_context *ftdic, const struct layout * l) +void reset(struct ftdi_context *ftdic, const struct layout * l) { + + /* using MPSSE since it give access to high GPIO*/ + /* set as inputs for now */ + ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE); + printf("toggle reset\n"); + + 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; + +} + + +void erase(struct ftdi_context *ftdic, const struct layout * l) +{ + printf("setting VREF2 erase\n"); /* using MPSSE since it give access to high GPIO*/ /* set as inputs for now */ ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE); 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_erase)); + + printf("toggle reset\n"); + + bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_erase)); + bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase)); + + printf("waiting for erase\n"); + + sleep(1); + + printf("setting VREF2 normal\n"); + bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal)); + reset(ftdic, l); + return; } From d1a4d5334a27359a6537cc55d75ed98054cf0fb4 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Tue, 16 Mar 2010 18:44:46 -0400 Subject: [PATCH 6/6] finished bbmc for now. complete with respectable command line options and full usage. --- tools/ftditools/bbmc.c | 155 +++++++++++++++++++++++++++++++++++------ 1 file changed, 135 insertions(+), 20 deletions(-) diff --git a/tools/ftditools/bbmc.c b/tools/ftditools/bbmc.c index 3708aab8d..4388b2a66 100644 --- a/tools/ftditools/bbmc.c +++ b/tools/ftditools/bbmc.c @@ -39,6 +39,7 @@ struct layout { char *name; + char *desc; enum ftdi_interface interface; uint16_t dir; uint16_t reset_release; @@ -61,12 +62,14 @@ void usage(void); .vref2_normal = vref2_normal(x), \ .vref2_erase = vref2_erase(x), -static const struct layout layouts[] = +static struct layout layouts[] = { { .name = "redbee_econotag", + .desc = "Redbee Econotag", std_layout(REDBEE_ECONOTAG) }, { .name = "redbee_usb", + .desc = "Redbee USB stick", std_layout(REDBEE_USB) }, { .name = NULL, /* end of table */ }, @@ -74,6 +77,7 @@ static const struct layout layouts[] = struct command { char *name; + char *desc; void (*cmd)(struct ftdi_context *ftdic, const struct layout * l); }; @@ -81,16 +85,18 @@ static const struct command commands[] = { { .name = "reset", + .desc = "Toggles reset pin", .cmd = reset, }, { .name = "erase", + .desc = "Sets VREF2 erase mode; toggles reset; waits 2 sec.; sets normal; toggles reset again", .cmd = erase, }, { .name = NULL, /* end of table */ }, }; -const struct layout * find_layout(char * str) +struct layout * find_layout(char * str) { uint32_t i = 0; @@ -110,44 +116,107 @@ int main(int argc, char **argv) struct ftdi_device_list *devlist; int dev_index = -1; int num_devs; char layout_str[BUF_LEN]; - const struct layout *layout; + struct layout layout; + struct layout *l = NULL; int i, ret; + /* overrides for layout parameters */ + int interface = -1; + int dir = -1; + int reset_release = -1; + int reset_set = -1; + int vref2_normal = -1; + int vref2_erase = -1; + + layout.name = NULL; + while (1) { int c; int option_index = 0; static struct option long_options[] = { - {"layout", required_argument, 0, 'l'}, - {"index", required_argument, 0, 'i'}, - {"help", no_argument, 0, '?'}, + {"layout", required_argument, 0, 'l'}, + {"index", required_argument, 0, 'i'}, + {"vendor", required_argument, 0, 'v'}, + {"product", required_argument, 0, 'p'}, + {"dir", required_argument, 0, 0 }, + {"reset_release", required_argument, 0, 0 }, + {"reset_set", required_argument, 0, 0 }, + {"vref2_normal", required_argument, 0, 0 }, + {"vref2_erase", required_argument, 0, 0 }, + {"interface", required_argument, 0, 0 }, + {"help", no_argument, 0, '?'}, {0, 0, 0, 0} }; - - c = getopt_long (argc, argv, "i:l:", + + c = getopt_long (argc, argv, "i:l:v:p:", long_options, &option_index); if (c == -1) break; switch (c) { /* process long opts */ + case 0: + if(strcmp(long_options[option_index].name, "interface") == 0) { + sscanf(optarg, "%i", &interface); + } + if(strcmp(long_options[option_index].name, "dir") == 0) { + sscanf(optarg, "%i", &dir); + } + if (strcmp(long_options[option_index].name, "reset_release") == 0) { + sscanf(optarg, "%i", &reset_release); + } + if (strcmp(long_options[option_index].name, "reset_set") == 0) { + sscanf(optarg, "%i", &reset_set); + } + if (strcmp(long_options[option_index].name, "vref2_normal") == 0) { + sscanf(optarg, "%i", &vref2_normal); + } + if (strcmp(long_options[option_index].name, "vref2_erase") == 0) { + sscanf(optarg, "%i", &vref2_erase); + } + break; + case 'l': strncpy(layout_str, optarg, BUF_LEN); break; case 'i': dev_index = atoi(optarg); break; + case 'v': + sscanf(optarg, "%i", &vendid); + break; + case 'p': + sscanf(optarg, "%i", &prodid); + break; default: usage(); break; } } - if( !(layout = find_layout(layout_str))) { - usage(); - printf("You must specify a layout\n"); + if( !(l = find_layout(layout_str)) && + !((interface >= 0) && + (dir >= 0) && + (reset_release >= 0) && + (reset_set >= 0) && + (vref2_normal >= 0) && + (vref2_erase >= 0)) + ) { + + printf("*** You must specify a layout or a complete set of overrides\n"); return EXIT_FAILURE; } + + if(l) { + memcpy(&layout, l, sizeof(struct layout)); + } +#define override(x) if(x > 0) { layout.x = x; } + override(interface); + override(dir); + override(reset_release); override(reset_set); + override(vref2_normal); override(vref2_erase); + if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0) { fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", @@ -162,8 +231,8 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - if (ftdi_set_interface(&ftdic, layout->interface) < 0) { - fprintf(stderr, "couldn't set interface %d\n", layout->interface); + if (ftdi_set_interface(&ftdic, layout.interface) < 0) { + fprintf(stderr, "couldn't set interface %d\n", layout.interface); return EXIT_FAILURE; } @@ -177,7 +246,13 @@ int main(int argc, char **argv) dev_index = print_and_prompt(devlist); } - printf("Opening device %d using layout %s\n", dev_index, layout->name); + if(layout.name != NULL) { + printf("Opening device %d interface %d using layout %s\n", + dev_index, layout.interface, layout.name); + } else { + printf("Opening device %d interface %d without a layout.\n", + dev_index, layout.interface); + } if( (ret = ftdi_usb_open_desc_index( &ftdic, @@ -190,15 +265,20 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - i = 0; - while(commands[i].name != NULL) { - if(strcmp(commands[i].name, argv[optind]) == 0) { break; } - i++; + + for(i = 0; commands[i].name != NULL; i++) { + if( (argv[optind] != NULL) && + (strcmp(commands[i].name, argv[optind]) == 0)) { break; } } if(commands[i].name != NULL) { - commands[i].cmd(&ftdic, layout); + commands[i].cmd(&ftdic, &layout); } else { printf("invalid command\n"); + + ftdi_list_free(&devlist); + ftdi_deinit(&ftdic); + + return EXIT_FAILURE; } printf("done.\n"); @@ -211,7 +291,42 @@ int main(int argc, char **argv) void usage(void) { - printf("Usage: don't know yet\n"); + int i; + printf( "Usage: bbmc [options|overrides] -l|--layout layout command \n"); + printf( "Commands:\n"); + for(i = 0; commands[i].name != NULL; i++) { + printf( " %s: %s\n", commands[i].name, commands[i].desc); + } + printf("\n"); + printf( "Required options:\n"); + printf( " -l|--layout\t specifiy which board layout to use\n"); + printf( " \t layout is not necessary with a full\n"); + printf( " \t set of overrides\n"); + printf( "\nLayout overrides:\n"); + printf( " --interface\t\t FTDI interface to use\n"); + printf( " --dir\t\t direction (1 is output)\n"); + printf( " --reset_release\t reset release command\n"); + printf( " --reset_set\t\t reset set command\n"); + printf( " --vref2_normal\t vref2 normal\n"); + printf( " --vref2_erase\t vref2 erase\n"); + printf("\n"); + printf( "Layouts:\n"); + for(i = 0; layouts[i].name != NULL; i++) { + printf( "\t%s: %s\n", layouts[i].name, layouts[i].desc); + printf("\n"); + printf( "\t\tinterface: \t0x%04x\n", layouts[i].interface); + printf( "\t\tdir: \t\t0x%04x\n", layouts[i].dir); + printf( "\t\treset release: \t0x%04x\n", layouts[i].reset_release); + printf( "\t\treset hold: \t0x%04x\n", layouts[i].reset_set); + printf( "\t\tvref2 normal: \t0x%04x\n", layouts[i].vref2_normal); + printf( "\t\tvref2 erase: \t0x%04x\n", layouts[i].vref2_erase); + printf("\n"); + } + printf("\n"); + printf( "Options:\n"); + printf( " -i|--index specifiy which device to use (default 0)\n"); + printf( " -v|--vendor set vendor id (default 0x0403)\n"); + printf( " -p|--prodcut set vendor id (default 0x6010)\n"); } int print_and_prompt( struct ftdi_device_list *devlist )