/*************************************************************************** * Copyright (C) 2013 by Paul Fertser, fercerpav@gmail.com * * * * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au * * Based on at91rm9200.c (c) Anders Larsen * * and RPi GPIO examples by Gert van Loo & Dom * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "bitbang.h" #include uint32_t bcm2835_peri_base = 0x20000000; #define BCM2835_GPIO_BASE (bcm2835_peri_base + 0x200000) /* GPIO controller */ #define BCM2835_PADS_GPIO_0_27 (bcm2835_peri_base + 0x100000) #define BCM2835_PADS_GPIO_0_27_OFFSET (0x2c / 4) /* GPIO setup macros */ #define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7) #define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0) #define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \ INP_GPIO(g); \ *(pio_base+((g)/10)) |= ((m)<<(((g)%10)*3)); } while (0) #define OUT_GPIO(g) SET_MODE_GPIO(g, 1) #define GPIO_SET (*(pio_base+7)) /* sets bits which are 1, ignores bits which are 0 */ #define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */ #define GPIO_LEV (*(pio_base+13)) /* current level of the pin */ static int dev_mem_fd; static volatile uint32_t *pio_base; static bb_value_t bcm2835gpio_read(void); 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); static struct bitbang_interface bcm2835gpio_bitbang = { .read = bcm2835gpio_read, .write = bcm2835gpio_write, .swdio_read = bcm2835_swdio_read, .swdio_drive = bcm2835_swdio_drive, .swd_write = bcm2835gpio_swd_write, .blink = NULL }; /* GPIO numbers for each signal. Negative values are invalid */ static int tck_gpio = -1; static int tck_gpio_mode; static int tms_gpio = -1; static int tms_gpio_mode; static int tdi_gpio = -1; static int tdi_gpio_mode; static int tdo_gpio = -1; static int tdo_gpio_mode; static int trst_gpio = -1; static int trst_gpio_mode; static int srst_gpio = -1; static int srst_gpio_mode; 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<