Add BCM2835 (as found in Raspberry Pi) interface driver 58/758/11
authorPaul Fertser <fercerpav@gmail.com>
Sun, 22 Jul 2012 13:28:02 +0000 (17:28 +0400)
committerSpencer Oliver <spen@spen-soft.co.uk>
Mon, 10 Jun 2013 09:39:48 +0000 (09:39 +0000)
This adds support for JTAG programming by bitbanging GPIOs exposed on
the RaspberryPi's expansion header.

Tested by connecting directly to an STM32VLDiscovery board, without any
additional circuity. I observed maximum about 4MHz on the TCK pin with an
old analogue 'scope and about 100kHz when setting the speed to 100kHz.
Busyloop waiting is needed because even with a single 0ns nanosleep call
(with FIFO priority) it lowers the TCK speed to ~30kHz which is way too low
to be useful.

The speed testing with adapter_khz 2000 gave the following results:
sudo chrt -f 1 nice -n -19 ./src/openocd \
     -f interface/raspberrypi-native.cfg \
     -c "set WORKAREASIZE 0x2000" \
     -f target/stm32f1x.cfg -c "adapter_khz 2000"

wrote 131072 bytes from file random.bin in 3.973677s (32.212 KiB/s)
dumped 131072 bytes in 1.445699s (88.538 KiB/s)

This is 3.7 times faster for writing and 14.3 times faster for reading
compared to the generic sysfsgpio driver; probably the writing speed is
limited by the target itself here and reading speed might be considerably
higher too with appropriate connection and a capable target.

BCM2835 name is choosen over BCM2708 because the published peripherals
datasheet uses the particular model name and not family name.

Change-Id: Ib78168be27f53c2a3c88c3dd8154d1190c318c78
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Reviewed-on: http://openocd.zylin.com/758
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
configure.ac
doc/openocd.texi
src/jtag/drivers/Makefile.am
src/jtag/drivers/bcm2835gpio.c [new file with mode: 0644]
src/jtag/interfaces.c
tcl/interface/raspberrypi-native.cfg [new file with mode: 0644]

index 68d6301a96147e47c81e5454db5f445dc7fb32d6..4388573c012a87bafd107efb26acaa820cdf6c29 100644 (file)
@@ -422,11 +422,16 @@ case "${host_cpu}" in
     AC_ARG_ENABLE([at91rm9200],
       AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]),
       [build_at91rm9200=$enableval], [build_at91rm9200=no])
     AC_ARG_ENABLE([at91rm9200],
       AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]),
       [build_at91rm9200=$enableval], [build_at91rm9200=no])
+
+    AC_ARG_ENABLE([bcm2835gpio],
+      AS_HELP_STRING([--enable-bcm2835gpio], [Enable building support for bitbanging on BCM2835 (as found in Raspberry Pi)]),
+      [build_bcm2835gpio=$enableval], [build_bcm2835gpio=no])
     ;;
 
   *)
     build_ep93xx=no
     build_at91rm9200=no
     ;;
 
   *)
     build_ep93xx=no
     build_at91rm9200=no
+    build_bcm2835gpio=no
     ;;
 esac
 
     ;;
 esac
 
@@ -676,6 +681,13 @@ else
   AC_DEFINE([BUILD_AT91RM9200], [0], [0 if you don't want at91rm9200.])
 fi
 
   AC_DEFINE([BUILD_AT91RM9200], [0], [0 if you don't want at91rm9200.])
 fi
 
+if test $build_bcm2835gpio = yes; then
+  build_bitbang=yes
+  AC_DEFINE([BUILD_BCM2835GPIO], [1], [1 if you want bcm2835gpio.])
+else
+  AC_DEFINE([BUILD_BCM2835GPIO], [0], [0 if you don't want bcm2835gpio.])
+fi
+
 if test x$parport_use_ppdev = xyes; then
   AC_DEFINE([PARPORT_USE_PPDEV], [1], [1 if you want parport to use ppdev.])
 else
 if test x$parport_use_ppdev = xyes; then
   AC_DEFINE([PARPORT_USE_PPDEV], [1], [1 if you want parport to use ppdev.])
 else
@@ -1208,6 +1220,7 @@ AM_CONDITIONAL([ZY1000], [test $build_zy1000 = yes])
 AM_CONDITIONAL([ZY1000_MASTER], [test $build_zy1000_master = yes])
 AM_CONDITIONAL([IOUTIL], [test $build_ioutil = yes])
 AM_CONDITIONAL([AT91RM9200], [test $build_at91rm9200 = yes])
 AM_CONDITIONAL([ZY1000_MASTER], [test $build_zy1000_master = yes])
 AM_CONDITIONAL([IOUTIL], [test $build_ioutil = yes])
 AM_CONDITIONAL([AT91RM9200], [test $build_at91rm9200 = yes])
+AM_CONDITIONAL([BCM2835GPIO], [test $build_bcm2835gpio = yes])
 AM_CONDITIONAL([BITBANG], [test $build_bitbang = yes])
 AM_CONDITIONAL([FT2232_LIBFTDI], [test $build_ft2232_libftdi = yes])
 AM_CONDITIONAL([FT2232_DRIVER], [test $build_ft2232_ftd2xx = yes -o $build_ft2232_libftdi = yes])
 AM_CONDITIONAL([BITBANG], [test $build_bitbang = yes])
 AM_CONDITIONAL([FT2232_LIBFTDI], [test $build_ft2232_libftdi = yes])
 AM_CONDITIONAL([FT2232_DRIVER], [test $build_ft2232_ftd2xx = yes -o $build_ft2232_libftdi = yes])
index 9ea7edf8310f7de0a5566f7d648e82ea566d1acc..51dab187f14046bb83a51a7368092711a8a6618c 100644 (file)
@@ -574,6 +574,9 @@ produced, PDF schematics are easily found and it is easy to make.
 @item @b{at91rm9200}
 @* Like the EP93xx - but an ATMEL AT91RM9200 based solution using the GPIO pins on the chip.
 
 @item @b{at91rm9200}
 @* Like the EP93xx - but an ATMEL AT91RM9200 based solution using the GPIO pins on the chip.
 
+@item @b{bcm2835gpio}
+@* A BCM2835-based board (e.g. Raspberry Pi) using the GPIO pins of the expansion header.
+
 @end itemize
 
 @node About Jim-Tcl
 @end itemize
 
 @node About Jim-Tcl
@@ -3048,6 +3051,22 @@ Turn power switch to target on/off.
 No arguments: print status.
 @end deffn
 
 No arguments: print status.
 @end deffn
 
+@deffn {Interface Driver} {bcm2835gpio}
+This SoC is present in Raspberry Pi which is a cheap single-board computer
+exposing some GPIOs on its expansion header.
+
+The driver accesses memory-mapped GPIO peripheral registers directly
+for maximum performance, but the only possible race condition is for
+the pins' modes/muxing (which is highly unlikely), so it should be
+able to coexist nicely with both sysfs bitbanging and various
+peripherals' kernel drivers. The driver restores the previous
+configuration on exit.
+
+See @file{interface/raspberrypi-native.cfg} for a sample config and
+pinout.
+
+@end deffn
+
 @section Transport Configuration
 @cindex Transport
 As noted earlier, depending on the version of OpenOCD you use,
 @section Transport Configuration
 @cindex Transport
 As noted earlier, depending on the version of OpenOCD you use,
index 65167ea2758fe50f6482b9be23582746be039cfa..30251be155d794921322d88c09c598fd117b94b8 100644 (file)
@@ -114,6 +114,9 @@ endif
 if SYSFSGPIO
 DRIVERFILES += sysfsgpio.c
 endif
 if SYSFSGPIO
 DRIVERFILES += sysfsgpio.c
 endif
+if BCM2835GPIO
+DRIVERFILES += bcm2835gpio.c
+endif
 
 if OPENJTAG
 DRIVERFILES += openjtag.c
 
 if OPENJTAG
 DRIVERFILES += openjtag.c
diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c
new file mode 100644 (file)
index 0000000..7dfabcb
--- /dev/null
@@ -0,0 +1,368 @@
+/***************************************************************************
+ *   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, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <jtag/interface.h>
+#include "bitbang.h"
+
+#include <sys/mman.h>
+
+#define BCM2835_PERI_BASE      0x20000000
+#define BCM2835_GPIO_BASE      (BCM2835_PERI_BASE + 0x200000) /* GPIO controller */
+
+/* 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 int bcm2835gpio_read(void);
+static void bcm2835gpio_write(int tck, int tms, int tdi);
+static void bcm2835gpio_reset(int trst, int srst);
+
+static int bcm2835gpio_init(void);
+static int bcm2835gpio_quit(void);
+
+static struct bitbang_interface bcm2835gpio_bitbang = {
+       .read = bcm2835gpio_read,
+       .write = bcm2835gpio_write,
+       .reset = bcm2835gpio_reset,
+       .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;
+
+/* Transition delay coefficients */
+static int speed_coeff = 113714;
+static int speed_offset = 28;
+static unsigned int jtag_delay;
+
+static int bcm2835gpio_read(void)
+{
+       return !!(GPIO_LEV & 1<<tdo_gpio);
+}
+
+static void bcm2835gpio_write(int tck, int tms, int tdi)
+{
+       uint32_t set = tck<<tck_gpio | tms<<tms_gpio | tdi<<tdi_gpio;
+       uint32_t clear = !tck<<tck_gpio | !tms<<tms_gpio | !tdi<<tdi_gpio;
+
+       GPIO_SET = set;
+       GPIO_CLR = clear;
+
+       for (unsigned int i = 0; i < jtag_delay; i++)
+               asm volatile ("");
+}
+
+/* (1) assert or (0) deassert reset lines */
+static void bcm2835gpio_reset(int trst, int srst)
+{
+       uint32_t set = 0;
+       uint32_t clear = 0;
+
+       if (trst_gpio > 0) {
+               set |= !trst<<trst_gpio;
+               clear |= trst<<trst_gpio;
+       }
+
+       if (srst_gpio > 0) {
+               set |= !srst<<srst_gpio;
+               clear |= srst<<srst_gpio;
+       }
+
+       GPIO_SET = set;
+       GPIO_CLR = clear;
+}
+
+static int bcm2835gpio_khz(int khz, int *jtag_speed)
+{
+       if (!khz) {
+               LOG_DEBUG("RCLK not supported");
+               return ERROR_FAIL;
+       }
+       *jtag_speed = speed_coeff/khz - speed_offset;
+       if (*jtag_speed < 0)
+               *jtag_speed = 0;
+       return ERROR_OK;
+}
+
+static int bcm2835gpio_speed_div(int speed, int *khz)
+{
+       *khz = speed_coeff/(speed + speed_offset);
+       return ERROR_OK;
+}
+
+static int bcm2835gpio_speed(int speed)
+{
+       jtag_delay = speed;
+       return ERROR_OK;
+}
+
+static int is_gpio_valid(int gpio)
+{
+       return gpio >= 0 && gpio <= 53;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums)
+{
+       if (CMD_ARGC == 4) {
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
+       } else if (CMD_ARGC != 0) {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       command_print(CMD_CTX,
+                       "BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdi = %d",
+                       tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck)
+{
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
+
+       command_print(CMD_CTX, "BCM2835 GPIO config: tck = %d", tck_gpio);
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms)
+{
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
+
+       command_print(CMD_CTX, "BCM2835 GPIO config: tms = %d", tms_gpio);
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo)
+{
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
+
+       command_print(CMD_CTX, "BCM2835 GPIO config: tdo = %d", tdo_gpio);
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi)
+{
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
+
+       command_print(CMD_CTX, "BCM2835 GPIO config: tdi = %d", tdi_gpio);
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst)
+{
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
+
+       command_print(CMD_CTX, "BCM2835 GPIO config: srst = %d", srst_gpio);
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst)
+{
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
+
+       command_print(CMD_CTX, "BCM2835 GPIO config: trst = %d", trst_gpio);
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)
+{
+       if (CMD_ARGC == 2) {
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], speed_coeff);
+               COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], speed_offset);
+       }
+       return ERROR_OK;
+}
+
+static const struct command_registration bcm2835gpio_command_handlers[] = {
+       {
+               .name = "bcm2835gpio_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",
+               .handler = &bcm2835gpio_handle_jtag_gpionum_tck,
+               .mode = COMMAND_CONFIG,
+               .help = "gpio number for tck.",
+       },
+       {
+               .name = "bcm2835gpio_tms_num",
+               .handler = &bcm2835gpio_handle_jtag_gpionum_tms,
+               .mode = COMMAND_CONFIG,
+               .help = "gpio number for tms.",
+       },
+       {
+               .name = "bcm2835gpio_tdo_num",
+               .handler = &bcm2835gpio_handle_jtag_gpionum_tdo,
+               .mode = COMMAND_CONFIG,
+               .help = "gpio number for tdo.",
+       },
+       {
+               .name = "bcm2835gpio_tdi_num",
+               .handler = &bcm2835gpio_handle_jtag_gpionum_tdi,
+               .mode = COMMAND_CONFIG,
+               .help = "gpio number for tdi.",
+       },
+       {
+               .name = "bcm2835gpio_srst_num",
+               .handler = &bcm2835gpio_handle_jtag_gpionum_srst,
+               .mode = COMMAND_CONFIG,
+               .help = "gpio number for srst.",
+       },
+       {
+               .name = "bcm2835gpio_trst_num",
+               .handler = &bcm2835gpio_handle_jtag_gpionum_trst,
+               .mode = COMMAND_CONFIG,
+               .help = "gpio number for trst.",
+       },
+       {
+               .name = "bcm2835gpio_speed_coeffs",
+               .handler = &bcm2835gpio_handle_speed_coeffs,
+               .mode = COMMAND_CONFIG,
+               .help = "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+struct jtag_interface bcm2835gpio_interface = {
+       .name = "bcm2835gpio",
+       .supported = DEBUG_CAP_TMS_SEQ,
+       .execute_queue = bitbang_execute_queue,
+       .transports = jtag_only,
+       .speed = bcm2835gpio_speed,
+       .khz = bcm2835gpio_khz,
+       .speed_div = bcm2835gpio_speed_div,
+       .commands = bcm2835gpio_command_handlers,
+       .init = bcm2835gpio_init,
+       .quit = bcm2835gpio_quit,
+};
+
+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;
+}
+
+static int bcm2835gpio_quit(void)
+{
+       SET_MODE_GPIO(tdo_gpio, tdo_gpio_mode);
+       SET_MODE_GPIO(tdi_gpio, tdi_gpio_mode);
+       SET_MODE_GPIO(tck_gpio, tck_gpio_mode);
+       SET_MODE_GPIO(tms_gpio, tms_gpio_mode);
+       if (trst_gpio != -1)
+               SET_MODE_GPIO(trst_gpio, trst_gpio_mode);
+       if (srst_gpio != -1)
+               SET_MODE_GPIO(srst_gpio, srst_gpio_mode);
+
+       return ERROR_OK;
+}
index b967b7e9964d5adccb886848c2bdd2ef76e4f483..579e9e74ddbf42187b100ccdf7b4d825d976199d 100644 (file)
@@ -122,6 +122,9 @@ extern struct jtag_interface sysfsgpio_interface;
 #if BUILD_AICE == 1
 extern struct jtag_interface aice_interface;
 #endif
 #if BUILD_AICE == 1
 extern struct jtag_interface aice_interface;
 #endif
+#if BUILD_BCM2835GPIO == 1
+extern struct jtag_interface bcm2835gpio_interface;
+#endif
 #endif /* standard drivers */
 
 /**
 #endif /* standard drivers */
 
 /**
@@ -212,6 +215,9 @@ struct jtag_interface *jtag_interfaces[] = {
 #if BUILD_AICE == 1
                &aice_interface,
 #endif
 #if BUILD_AICE == 1
                &aice_interface,
 #endif
+#if BUILD_BCM2835GPIO == 1
+               &bcm2835gpio_interface,
+#endif
 #endif /* standard drivers */
                NULL,
        };
 #endif /* standard drivers */
                NULL,
        };
diff --git a/tcl/interface/raspberrypi-native.cfg b/tcl/interface/raspberrypi-native.cfg
new file mode 100644 (file)
index 0000000..058d80b
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# Config for using Raspberry Pi's expansion header
+#
+# This is best used with a fast enough buffer but also
+# is suitable for direct connection if the target voltage
+# matches RPi's 3.3V and the cable is short enough.
+#
+# Do not forget the GND connection, pin 6 of the expansion header.
+#
+
+interface bcm2835gpio
+
+# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
+# These depend on system clock, calibrated for stock 700MHz
+# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
+bcm2835gpio_speed_coeffs 113714 28
+
+# Each of the JTAG lines need a gpio number set: tck tms tdi tdo
+# Header pin numbers: 23 22 19 21
+bcm2835gpio_jtag_nums 11 25 10 9
+
+# If you define trst or srst, use appropriate reset_config
+# Header pin numbers: TRST - 26, SRST - 18
+
+# bcm2835gpio_trst_num 7
+# reset_config trst_only
+
+# bcm2835gpio_srst_num 24
+# reset_config srst_only srst_push_pull
+
+# or if you have both connected,
+# reset_config trst_and_srst srst_push_pull
+

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)