static bool sysfsgpio_swd_mode_possible(void) { if (!is_gpio_valid(swclk_gpio)) return 0; if (!is_gpio_valid(swdio_gpio)) return 0; return 1; }
static bool sysfsgpio_jtag_mode_possible(void) { if (!is_gpio_valid(tck_gpio)) return 0; if (!is_gpio_valid(tms_gpio)) return 0; if (!is_gpio_valid(tdi_gpio)) return 0; if (!is_gpio_valid(tdo_gpio)) return 0; return 1; }
/* * Helper func to unexport gpio from sysfs */ static void unexport_sysfs_gpio(int gpio) { char gpiostr[4]; if (!is_gpio_valid(gpio)) return; snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); if (open_write_close("/sys/class/gpio/unexport", gpiostr) < 0) LOG_ERROR("Couldn't unexport gpio %d", gpio); return; }
static int bcm2835gpio_init(void) { bitbang_interface = &bcm2835gpio_bitbang; if (!is_gpio_valid(tdo_gpio) || !is_gpio_valid(tdi_gpio) || !is_gpio_valid(tck_gpio) || !is_gpio_valid(tms_gpio) || (trst_gpio != -1 && !is_gpio_valid(trst_gpio)) || (srst_gpio != -1 && !is_gpio_valid(srst_gpio))) return ERROR_JTAG_INIT_FAILED; dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); if (dev_mem_fd < 0) { perror("open"); return ERROR_JTAG_INIT_FAILED; } pio_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_SHARED, dev_mem_fd, BCM2835_GPIO_BASE); if (pio_base == MAP_FAILED) { perror("mmap"); close(dev_mem_fd); return ERROR_JTAG_INIT_FAILED; } 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); /* * 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<<tdi_gpio | 1<<tck_gpio; GPIO_SET = 1<<tms_gpio; OUT_GPIO(tdi_gpio); OUT_GPIO(tck_gpio); OUT_GPIO(tms_gpio); if (trst_gpio != -1) { trst_gpio_mode = MODE_GPIO(trst_gpio); GPIO_SET = 1 << trst_gpio; OUT_GPIO(trst_gpio); } if (srst_gpio != -1) { srst_gpio_mode = MODE_GPIO(srst_gpio); GPIO_SET = 1 << srst_gpio; OUT_GPIO(srst_gpio); } LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d " "tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode, tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode); return ERROR_OK; }
/* * Exports and sets up direction for gpio. * If the gpio is an output, it is initialized according to init_high, * otherwise it is ignored. * * If the gpio is already exported we just show a warning and continue; if * openocd happened to crash (or was killed by user) then the gpios will not * have been cleaned up. */ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) { char buf[40]; char gpiostr[4]; int ret; if (!is_gpio_valid(gpio)) return ERROR_OK; snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); ret = open_write_close("/sys/class/gpio/export", gpiostr); if (ret < 0) { if (errno == EBUSY) { LOG_WARNING("gpio %d is already exported", gpio); } else { LOG_ERROR("Couldn't export gpio %d", gpio); perror("sysfsgpio: "); return ERROR_FAIL; } } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); if (ret < 0) { LOG_ERROR("Couldn't set direction for gpio %d", gpio); perror("sysfsgpio: "); unexport_sysfs_gpio(gpio); return ERROR_FAIL; } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); if (ret < 0) { LOG_ERROR("Couldn't open value for gpio %d", gpio); perror("sysfsgpio: "); unexport_sysfs_gpio(gpio); } return ret; }
static int sysfsgpio_init(void) { bitbang_interface = &sysfsgpio_bitbang; LOG_INFO("SysfsGPIO JTAG bitbang driver"); if (!(is_gpio_valid(tck_gpio) && is_gpio_valid(tms_gpio) && is_gpio_valid(tdi_gpio) && is_gpio_valid(tdo_gpio))) { if (!is_gpio_valid(tck_gpio)) LOG_ERROR("gpio num for tck is invalid"); if (!is_gpio_valid(tms_gpio)) LOG_ERROR("gpio num for tms is invalid"); if (!is_gpio_valid(tdo_gpio)) LOG_ERROR("gpio num for tdo is invalid"); if (!is_gpio_valid(tdi_gpio)) LOG_ERROR("gpio num for tdi is invalid"); LOG_ERROR("Require tck, tms, tdi and tdo gpios to all be specified"); return ERROR_JTAG_INIT_FAILED; } if (!is_gpio_valid(trst_gpio) && !is_gpio_valid(srst_gpio)) { LOG_ERROR("Require at least one of trst or srst gpios to be specified"); return ERROR_JTAG_INIT_FAILED; } /* * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. */ tck_ld = ld(tck_gpio); tck_fd = setup_sysfs_gpio(tck_gpio, 1, 0); if (tck_fd < 0) goto out_error; tms_ld = ld(tms_gpio); tms_fd = setup_sysfs_gpio(tms_gpio, 1, 1); if (tms_fd < 0) goto out_error; tdi_ld = ld(tdi_gpio); tdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0); if (tdi_fd < 0) goto out_error; tdo_ld = ld(tdo_gpio); tdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0); if (tdo_fd < 0) goto out_error; trst_ld = ld(trst_gpio); /* assume active low*/ if (trst_gpio > 0) { trst_fd = setup_sysfs_gpio(trst_gpio, 1, 1); if (trst_fd < 0) goto out_error; } srst_ld = ld(srst_gpio); /* assume active low*/ if (srst_gpio > 0) { srst_fd = setup_sysfs_gpio(srst_gpio, 1, 1); if (srst_fd < 0) goto out_error; } return ERROR_OK; out_error: cleanup_all_fds(); return ERROR_JTAG_INIT_FAILED; }
/* * Exports and sets up direction for gpio. * If the gpio is an output, it is initialized according to init_high, * otherwise it is ignored. * * If the gpio is already exported we just show a warning and continue; if * openocd happened to crash (or was killed by user) then the gpios will not * have been cleaned up. */ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) { char buf[40]; char gpiostr[4]; int ret; int mem_fd; if(pointer==0){ if ((mem_fd = open("/dev/mem", O_RDWR | O_RSYNC | O_SYNC)) < 0) { printf("can't open /dev/mem \n"); exit(-1); } //printf("vor mmap \n"); mymem = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, IOCONFIG); if (mymem == MAP_FAILED) { printf("mmap error %d\n", errno); exit(-1); } else { //printf("mymem = 0x%x\n", (unsigned int)mymem); } pointer=1; } if (!is_gpio_valid(gpio)) return ERROR_OK; snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); ret = open_write_close("/sys/class/gpio/export", gpiostr); if (ret < 0) { if (errno == EBUSY) { LOG_WARNING("gpio %d is already exported", gpio); } else { LOG_ERROR("Couldn't export gpio %d", gpio); perror("sysfsgpio: "); return ERROR_FAIL; } } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); if (ret < 0) { LOG_ERROR("Couldn't set direction for gpio %d", gpio); perror("sysfsgpio: "); unexport_sysfs_gpio(gpio); return ERROR_FAIL; } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); if (is_output) ret = open(buf, O_WRONLY | O_NONBLOCK | O_SYNC); else ret = open(buf, O_RDONLY | O_NONBLOCK | O_SYNC); if (ret < 0) unexport_sysfs_gpio(gpio); return ret; }