X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fbcm2835gpio.c;h=22d237f22081d6a04edeedca2cb87920e5164cee;hb=bd4bd54b60b3297b746d3d5379f25d54846ce517;hp=bbc87d3dd373c1cf67310d986e2f3084a79cbb1c;hpb=efd1d642220a4f6d3b9a9607c186452b265400d2;p=fw%2Fopenocd diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index bbc87d3dd..22d237f22 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -24,6 +24,7 @@ #endif #include +#include #include "bitbang.h" #include @@ -54,6 +55,7 @@ static int bcm2835gpio_write(int tck, int tms, int tdi); static int bcm2835_swdio_read(void); static void bcm2835_swdio_drive(bool is_output); +static int bcm2835gpio_swd_write(int swclk, int swdio); static int bcm2835gpio_init(void); static int bcm2835gpio_quit(void); @@ -63,6 +65,7 @@ static struct bitbang_interface bcm2835gpio_bitbang = { .write = bcm2835gpio_write, .swdio_read = bcm2835_swdio_read, .swdio_drive = bcm2835_swdio_drive, + .swd_write = bcm2835gpio_swd_write, .blink = NULL }; @@ -83,12 +86,19 @@ static int swclk_gpio = -1; static int swclk_gpio_mode; static int swdio_gpio = -1; static int swdio_gpio_mode; +static int swdio_dir_gpio = -1; +static int swdio_dir_gpio_mode; /* Transition delay coefficients */ static int speed_coeff = 113714; static int speed_offset = 28; static unsigned int jtag_delay; +static int is_gpio_valid(int gpio) +{ + return gpio >= 0 && gpio <= 31; +} + static bb_value_t bcm2835gpio_read(void) { return (GPIO_LEV & 1< 0) { + if (is_gpio_valid(trst_gpio)) { set |= !trst< 0) { + if (is_gpio_valid(srst_gpio)) { set |= !srst<= 0 && gpio <= 53; -} - COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums) { if (CMD_ARGC == 4) { @@ -292,6 +307,15 @@ COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio) return ERROR_OK; } +COMMAND_HANDLER(bcm2835gpio_handle_swd_dir_gpionum_swdio) +{ + if (CMD_ARGC == 1) + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_dir_gpio); + + command_print(CMD, "BCM2835 num: swdio_dir = %d", swdio_dir_gpio); + return ERROR_OK; +} + COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs) { if (CMD_ARGC == 2) { @@ -314,86 +338,93 @@ COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base) return ERROR_OK; } -static const struct command_registration bcm2835gpio_command_handlers[] = { +static const struct command_registration bcm2835gpio_subcommand_handlers[] = { { - .name = "bcm2835gpio_jtag_nums", + .name = "jtag_nums", .handler = &bcm2835gpio_handle_jtag_gpionums, .mode = COMMAND_CONFIG, .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)", .usage = "[tck tms tdi tdo]", }, { - .name = "bcm2835gpio_tck_num", + .name = "tck_num", .handler = &bcm2835gpio_handle_jtag_gpionum_tck, .mode = COMMAND_CONFIG, .help = "gpio number for tck.", .usage = "[tck]", }, { - .name = "bcm2835gpio_tms_num", + .name = "tms_num", .handler = &bcm2835gpio_handle_jtag_gpionum_tms, .mode = COMMAND_CONFIG, .help = "gpio number for tms.", .usage = "[tms]", }, { - .name = "bcm2835gpio_tdo_num", + .name = "tdo_num", .handler = &bcm2835gpio_handle_jtag_gpionum_tdo, .mode = COMMAND_CONFIG, .help = "gpio number for tdo.", .usage = "[tdo]", }, { - .name = "bcm2835gpio_tdi_num", + .name = "tdi_num", .handler = &bcm2835gpio_handle_jtag_gpionum_tdi, .mode = COMMAND_CONFIG, .help = "gpio number for tdi.", .usage = "[tdi]", }, { - .name = "bcm2835gpio_swd_nums", + .name = "swd_nums", .handler = &bcm2835gpio_handle_swd_gpionums, .mode = COMMAND_CONFIG, .help = "gpio numbers for swclk, swdio. (in that order)", .usage = "[swclk swdio]", }, { - .name = "bcm2835gpio_swclk_num", + .name = "swclk_num", .handler = &bcm2835gpio_handle_swd_gpionum_swclk, .mode = COMMAND_CONFIG, .help = "gpio number for swclk.", .usage = "[swclk]", }, { - .name = "bcm2835gpio_swdio_num", + .name = "swdio_num", .handler = &bcm2835gpio_handle_swd_gpionum_swdio, .mode = COMMAND_CONFIG, .help = "gpio number for swdio.", .usage = "[swdio]", }, { - .name = "bcm2835gpio_srst_num", + .name = "swdio_dir_num", + .handler = &bcm2835gpio_handle_swd_dir_gpionum_swdio, + .mode = COMMAND_CONFIG, + .help = "gpio number for swdio direction control pin (set=output mode, clear=input mode)", + .usage = "[swdio_dir]", + }, + { + .name = "srst_num", .handler = &bcm2835gpio_handle_jtag_gpionum_srst, .mode = COMMAND_CONFIG, .help = "gpio number for srst.", .usage = "[srst]", }, { - .name = "bcm2835gpio_trst_num", + .name = "trst_num", .handler = &bcm2835gpio_handle_jtag_gpionum_trst, .mode = COMMAND_CONFIG, .help = "gpio number for trst.", .usage = "[trst]", }, { - .name = "bcm2835gpio_speed_coeffs", + .name = "speed_coeffs", .handler = &bcm2835gpio_handle_speed_coeffs, .mode = COMMAND_CONFIG, .help = "SPEED_COEFF and SPEED_OFFSET for delay calculations.", .usage = "[SPEED_COEFF SPEED_OFFSET]", }, { - .name = "bcm2835gpio_peripheral_base", + .name = "peripheral_base", .handler = &bcm2835gpio_handle_peripheral_base, .mode = COMMAND_CONFIG, .help = "peripheral base to access GPIOs (RPi1 0x20000000, RPi2 0x3F000000).", @@ -403,6 +434,17 @@ static const struct command_registration bcm2835gpio_command_handlers[] = { COMMAND_REGISTRATION_DONE }; +static const struct command_registration bcm2835gpio_command_handlers[] = { + { + .name = "bcm2835gpio", + .mode = COMMAND_ANY, + .help = "perform bcm2835gpio management", + .chain = bcm2835gpio_subcommand_handlers, + .usage = "", + }, + COMMAND_REGISTRATION_DONE +}; + static const char * const bcm2835_transports[] = { "jtag", "swd", NULL }; static struct jtag_interface bcm2835gpio_interface = { @@ -454,21 +496,23 @@ static int bcm2835gpio_init(void) LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver"); - if (bcm2835gpio_jtag_mode_possible()) { - if (bcm2835gpio_swd_mode_possible()) - LOG_INFO("JTAG and SWD modes enabled"); - else - LOG_INFO("JTAG only mode enabled (specify swclk and swdio gpio to add SWD mode)"); - } else if (bcm2835gpio_swd_mode_possible()) { - LOG_INFO("SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)"); - } else { - LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode and/or swclk and swdio gpio for SWD mode"); + if (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) { + LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode"); + return ERROR_JTAG_INIT_FAILED; + } + + if (transport_is_swd() && !bcm2835gpio_swd_mode_possible()) { + LOG_ERROR("Require swclk and swdio gpio for SWD mode"); return ERROR_JTAG_INIT_FAILED; } - dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); + dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC); + if (dev_mem_fd < 0) { + LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem"); + dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); + } if (dev_mem_fd < 0) { - perror("open"); + LOG_ERROR("open: %s", strerror(errno)); return ERROR_JTAG_INIT_FAILED; } @@ -476,7 +520,7 @@ static int bcm2835gpio_init(void) MAP_SHARED, dev_mem_fd, BCM2835_GPIO_BASE); if (pio_base == MAP_FAILED) { - perror("mmap"); + LOG_ERROR("mmap: %s", strerror(errno)); close(dev_mem_fd); return ERROR_JTAG_INIT_FAILED; } @@ -486,7 +530,7 @@ static int bcm2835gpio_init(void) MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27); if (pads_base == MAP_FAILED) { - perror("mmap"); + LOG_ERROR("mmap: %s", strerror(errno)); close(dev_mem_fd); return ERROR_JTAG_INIT_FAILED; } @@ -494,32 +538,50 @@ static int bcm2835gpio_init(void) /* set 4mA drive strength, slew rate limited, hysteresis on */ pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1; - tdo_gpio_mode = MODE_GPIO(tdo_gpio); - tdi_gpio_mode = MODE_GPIO(tdi_gpio); - tck_gpio_mode = MODE_GPIO(tck_gpio); - tms_gpio_mode = MODE_GPIO(tms_gpio); - swclk_gpio_mode = MODE_GPIO(swclk_gpio); - swdio_gpio_mode = MODE_GPIO(swdio_gpio); /* * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. */ - INP_GPIO(tdo_gpio); - - GPIO_CLR = 1<