1 /***************************************************************************
2 * Copyright (C) 2013 by Paul Fertser, fercerpav@gmail.com *
4 * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *
5 * Based on at91rm9200.c (c) Anders Larsen *
6 * and RPi GPIO examples by Gert van Loo & Dom *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
20 ***************************************************************************/
26 #include <jtag/interface.h>
27 #include <transport/transport.h>
32 uint32_t bcm2835_peri_base
= 0x20000000;
33 #define BCM2835_GPIO_BASE (bcm2835_peri_base + 0x200000) /* GPIO controller */
35 #define BCM2835_PADS_GPIO_0_27 (bcm2835_peri_base + 0x100000)
36 #define BCM2835_PADS_GPIO_0_27_OFFSET (0x2c / 4)
38 /* GPIO setup macros */
39 #define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7)
40 #define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0)
41 #define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \
43 *(pio_base+((g)/10)) |= ((m)<<(((g)%10)*3)); } while (0)
44 #define OUT_GPIO(g) SET_MODE_GPIO(g, 1)
46 #define GPIO_SET (*(pio_base+7)) /* sets bits which are 1, ignores bits which are 0 */
47 #define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */
48 #define GPIO_LEV (*(pio_base+13)) /* current level of the pin */
50 static int dev_mem_fd
;
51 static volatile uint32_t *pio_base
;
53 static bb_value_t
bcm2835gpio_read(void);
54 static int bcm2835gpio_write(int tck
, int tms
, int tdi
);
56 static int bcm2835_swdio_read(void);
57 static void bcm2835_swdio_drive(bool is_output
);
58 static int bcm2835gpio_swd_write(int swclk
, int swdio
);
60 static int bcm2835gpio_init(void);
61 static int bcm2835gpio_quit(void);
63 static struct bitbang_interface bcm2835gpio_bitbang
= {
64 .read
= bcm2835gpio_read
,
65 .write
= bcm2835gpio_write
,
66 .swdio_read
= bcm2835_swdio_read
,
67 .swdio_drive
= bcm2835_swdio_drive
,
68 .swd_write
= bcm2835gpio_swd_write
,
72 /* GPIO numbers for each signal. Negative values are invalid */
73 static int tck_gpio
= -1;
74 static int tck_gpio_mode
;
75 static int tms_gpio
= -1;
76 static int tms_gpio_mode
;
77 static int tdi_gpio
= -1;
78 static int tdi_gpio_mode
;
79 static int tdo_gpio
= -1;
80 static int tdo_gpio_mode
;
81 static int trst_gpio
= -1;
82 static int trst_gpio_mode
;
83 static int srst_gpio
= -1;
84 static int srst_gpio_mode
;
85 static int swclk_gpio
= -1;
86 static int swclk_gpio_mode
;
87 static int swdio_gpio
= -1;
88 static int swdio_gpio_mode
;
90 /* Transition delay coefficients */
91 static int speed_coeff
= 113714;
92 static int speed_offset
= 28;
93 static unsigned int jtag_delay
;
95 static bb_value_t
bcm2835gpio_read(void)
97 return (GPIO_LEV
& 1<<tdo_gpio
) ? BB_HIGH
: BB_LOW
;
100 static int bcm2835gpio_write(int tck
, int tms
, int tdi
)
102 uint32_t set
= tck
<<tck_gpio
| tms
<<tms_gpio
| tdi
<<tdi_gpio
;
103 uint32_t clear
= !tck
<<tck_gpio
| !tms
<<tms_gpio
| !tdi
<<tdi_gpio
;
108 for (unsigned int i
= 0; i
< jtag_delay
; i
++)
114 static int bcm2835gpio_swd_write(int swclk
, int swdio
)
116 uint32_t set
= swclk
<< swclk_gpio
| swdio
<< swdio_gpio
;
117 uint32_t clear
= !swclk
<< swclk_gpio
| !swdio
<< swdio_gpio
;
122 for (unsigned int i
= 0; i
< jtag_delay
; i
++)
128 /* (1) assert or (0) deassert reset lines */
129 static int bcm2835gpio_reset(int trst
, int srst
)
135 set
|= !trst
<<trst_gpio
;
136 clear
|= trst
<<trst_gpio
;
140 set
|= !srst
<<srst_gpio
;
141 clear
|= srst
<<srst_gpio
;
150 static void bcm2835_swdio_drive(bool is_output
)
153 OUT_GPIO(swdio_gpio
);
155 INP_GPIO(swdio_gpio
);
158 static int bcm2835_swdio_read(void)
160 return !!(GPIO_LEV
& 1 << swdio_gpio
);
163 static int bcm2835gpio_khz(int khz
, int *jtag_speed
)
166 LOG_DEBUG("RCLK not supported");
169 *jtag_speed
= speed_coeff
/khz
- speed_offset
;
175 static int bcm2835gpio_speed_div(int speed
, int *khz
)
177 *khz
= speed_coeff
/(speed
+ speed_offset
);
181 static int bcm2835gpio_speed(int speed
)
187 static int is_gpio_valid(int gpio
)
189 return gpio
>= 0 && gpio
<= 53;
192 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums
)
195 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tck_gpio
);
196 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], tms_gpio
);
197 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[2], tdi_gpio
);
198 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[3], tdo_gpio
);
199 } else if (CMD_ARGC
!= 0) {
200 return ERROR_COMMAND_SYNTAX_ERROR
;
204 "BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
205 tck_gpio
, tms_gpio
, tdi_gpio
, tdo_gpio
);
210 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck
)
213 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tck_gpio
);
215 command_print(CMD
, "BCM2835 GPIO config: tck = %d", tck_gpio
);
219 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms
)
222 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tms_gpio
);
224 command_print(CMD
, "BCM2835 GPIO config: tms = %d", tms_gpio
);
228 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo
)
231 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tdo_gpio
);
233 command_print(CMD
, "BCM2835 GPIO config: tdo = %d", tdo_gpio
);
237 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi
)
240 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tdi_gpio
);
242 command_print(CMD
, "BCM2835 GPIO config: tdi = %d", tdi_gpio
);
246 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst
)
249 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], srst_gpio
);
251 command_print(CMD
, "BCM2835 GPIO config: srst = %d", srst_gpio
);
255 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst
)
258 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], trst_gpio
);
260 command_print(CMD
, "BCM2835 GPIO config: trst = %d", trst_gpio
);
264 COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionums
)
267 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], swclk_gpio
);
268 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], swdio_gpio
);
269 } else if (CMD_ARGC
!= 0) {
270 return ERROR_COMMAND_SYNTAX_ERROR
;
274 "BCM2835 GPIO nums: swclk = %d, swdio = %d",
275 swclk_gpio
, swdio_gpio
);
280 COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swclk
)
283 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], swclk_gpio
);
285 command_print(CMD
, "BCM2835 num: swclk = %d", swclk_gpio
);
289 COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio
)
292 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], swdio_gpio
);
294 command_print(CMD
, "BCM2835 num: swdio = %d", swdio_gpio
);
298 COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs
)
301 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], speed_coeff
);
302 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], speed_offset
);
305 command_print(CMD
, "BCM2835 GPIO: speed_coeffs = %d, speed_offset = %d",
306 speed_coeff
, speed_offset
);
310 COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base
)
313 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], bcm2835_peri_base
);
315 command_print(CMD
, "BCM2835 GPIO: peripheral_base = 0x%08x",
320 static const struct command_registration bcm2835gpio_command_handlers
[] = {
322 .name
= "bcm2835gpio_jtag_nums",
323 .handler
= &bcm2835gpio_handle_jtag_gpionums
,
324 .mode
= COMMAND_CONFIG
,
325 .help
= "gpio numbers for tck, tms, tdi, tdo. (in that order)",
326 .usage
= "[tck tms tdi tdo]",
329 .name
= "bcm2835gpio_tck_num",
330 .handler
= &bcm2835gpio_handle_jtag_gpionum_tck
,
331 .mode
= COMMAND_CONFIG
,
332 .help
= "gpio number for tck.",
336 .name
= "bcm2835gpio_tms_num",
337 .handler
= &bcm2835gpio_handle_jtag_gpionum_tms
,
338 .mode
= COMMAND_CONFIG
,
339 .help
= "gpio number for tms.",
343 .name
= "bcm2835gpio_tdo_num",
344 .handler
= &bcm2835gpio_handle_jtag_gpionum_tdo
,
345 .mode
= COMMAND_CONFIG
,
346 .help
= "gpio number for tdo.",
350 .name
= "bcm2835gpio_tdi_num",
351 .handler
= &bcm2835gpio_handle_jtag_gpionum_tdi
,
352 .mode
= COMMAND_CONFIG
,
353 .help
= "gpio number for tdi.",
357 .name
= "bcm2835gpio_swd_nums",
358 .handler
= &bcm2835gpio_handle_swd_gpionums
,
359 .mode
= COMMAND_CONFIG
,
360 .help
= "gpio numbers for swclk, swdio. (in that order)",
361 .usage
= "[swclk swdio]",
364 .name
= "bcm2835gpio_swclk_num",
365 .handler
= &bcm2835gpio_handle_swd_gpionum_swclk
,
366 .mode
= COMMAND_CONFIG
,
367 .help
= "gpio number for swclk.",
371 .name
= "bcm2835gpio_swdio_num",
372 .handler
= &bcm2835gpio_handle_swd_gpionum_swdio
,
373 .mode
= COMMAND_CONFIG
,
374 .help
= "gpio number for swdio.",
378 .name
= "bcm2835gpio_srst_num",
379 .handler
= &bcm2835gpio_handle_jtag_gpionum_srst
,
380 .mode
= COMMAND_CONFIG
,
381 .help
= "gpio number for srst.",
385 .name
= "bcm2835gpio_trst_num",
386 .handler
= &bcm2835gpio_handle_jtag_gpionum_trst
,
387 .mode
= COMMAND_CONFIG
,
388 .help
= "gpio number for trst.",
392 .name
= "bcm2835gpio_speed_coeffs",
393 .handler
= &bcm2835gpio_handle_speed_coeffs
,
394 .mode
= COMMAND_CONFIG
,
395 .help
= "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
396 .usage
= "[SPEED_COEFF SPEED_OFFSET]",
399 .name
= "bcm2835gpio_peripheral_base",
400 .handler
= &bcm2835gpio_handle_peripheral_base
,
401 .mode
= COMMAND_CONFIG
,
402 .help
= "peripheral base to access GPIOs (RPi1 0x20000000, RPi2 0x3F000000).",
406 COMMAND_REGISTRATION_DONE
409 static const char * const bcm2835_transports
[] = { "jtag", "swd", NULL
};
411 static struct jtag_interface bcm2835gpio_interface
= {
412 .supported
= DEBUG_CAP_TMS_SEQ
,
413 .execute_queue
= bitbang_execute_queue
,
416 struct adapter_driver bcm2835gpio_adapter_driver
= {
417 .name
= "bcm2835gpio",
418 .transports
= bcm2835_transports
,
419 .commands
= bcm2835gpio_command_handlers
,
421 .init
= bcm2835gpio_init
,
422 .quit
= bcm2835gpio_quit
,
423 .reset
= bcm2835gpio_reset
,
424 .speed
= bcm2835gpio_speed
,
425 .khz
= bcm2835gpio_khz
,
426 .speed_div
= bcm2835gpio_speed_div
,
428 .jtag_ops
= &bcm2835gpio_interface
,
429 .swd_ops
= &bitbang_swd
,
432 static bool bcm2835gpio_jtag_mode_possible(void)
434 if (!is_gpio_valid(tck_gpio
))
436 if (!is_gpio_valid(tms_gpio
))
438 if (!is_gpio_valid(tdi_gpio
))
440 if (!is_gpio_valid(tdo_gpio
))
445 static bool bcm2835gpio_swd_mode_possible(void)
447 if (!is_gpio_valid(swclk_gpio
))
449 if (!is_gpio_valid(swdio_gpio
))
454 static int bcm2835gpio_init(void)
456 bitbang_interface
= &bcm2835gpio_bitbang
;
458 LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver");
460 if (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) {
461 LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
462 return ERROR_JTAG_INIT_FAILED
;
465 if (transport_is_swd() && !bcm2835gpio_swd_mode_possible()) {
466 LOG_ERROR("Require swclk and swdio gpio for SWD mode");
467 return ERROR_JTAG_INIT_FAILED
;
470 dev_mem_fd
= open("/dev/gpiomem", O_RDWR
| O_SYNC
);
471 if (dev_mem_fd
< 0) {
472 LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
473 dev_mem_fd
= open("/dev/mem", O_RDWR
| O_SYNC
);
475 if (dev_mem_fd
< 0) {
476 LOG_ERROR("open: %s", strerror(errno
));
477 return ERROR_JTAG_INIT_FAILED
;
480 pio_base
= mmap(NULL
, sysconf(_SC_PAGE_SIZE
), PROT_READ
| PROT_WRITE
,
481 MAP_SHARED
, dev_mem_fd
, BCM2835_GPIO_BASE
);
483 if (pio_base
== MAP_FAILED
) {
484 LOG_ERROR("mmap: %s", strerror(errno
));
486 return ERROR_JTAG_INIT_FAILED
;
489 static volatile uint32_t *pads_base
;
490 pads_base
= mmap(NULL
, sysconf(_SC_PAGE_SIZE
), PROT_READ
| PROT_WRITE
,
491 MAP_SHARED
, dev_mem_fd
, BCM2835_PADS_GPIO_0_27
);
493 if (pads_base
== MAP_FAILED
) {
494 LOG_ERROR("mmap: %s", strerror(errno
));
496 return ERROR_JTAG_INIT_FAILED
;
499 /* set 4mA drive strength, slew rate limited, hysteresis on */
500 pads_base
[BCM2835_PADS_GPIO_0_27_OFFSET
] = 0x5a000008 + 1;
503 * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
504 * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
506 if (transport_is_jtag()) {
507 tdo_gpio_mode
= MODE_GPIO(tdo_gpio
);
508 tdi_gpio_mode
= MODE_GPIO(tdi_gpio
);
509 tck_gpio_mode
= MODE_GPIO(tck_gpio
);
510 tms_gpio_mode
= MODE_GPIO(tms_gpio
);
514 GPIO_CLR
= 1<<tdi_gpio
| 1<<tck_gpio
;
515 GPIO_SET
= 1<<tms_gpio
;
521 if (trst_gpio
!= -1) {
522 trst_gpio_mode
= MODE_GPIO(trst_gpio
);
523 GPIO_SET
= 1 << trst_gpio
;
528 if (transport_is_swd()) {
529 swclk_gpio_mode
= MODE_GPIO(swclk_gpio
);
530 swdio_gpio_mode
= MODE_GPIO(swdio_gpio
);
532 GPIO_CLR
= 1<<swdio_gpio
| 1<<swclk_gpio
;
534 OUT_GPIO(swclk_gpio
);
535 OUT_GPIO(swdio_gpio
);
538 if (srst_gpio
!= -1) {
539 srst_gpio_mode
= MODE_GPIO(srst_gpio
);
540 GPIO_SET
= 1 << srst_gpio
;
544 LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d "
545 "tdo %d trst %d srst %d", tck_gpio_mode
, tms_gpio_mode
,
546 tdi_gpio_mode
, tdo_gpio_mode
, trst_gpio_mode
, srst_gpio_mode
);
551 static int bcm2835gpio_quit(void)
553 if (transport_is_jtag()) {
554 SET_MODE_GPIO(tdo_gpio
, tdo_gpio_mode
);
555 SET_MODE_GPIO(tdi_gpio
, tdi_gpio_mode
);
556 SET_MODE_GPIO(tck_gpio
, tck_gpio_mode
);
557 SET_MODE_GPIO(tms_gpio
, tms_gpio_mode
);
559 SET_MODE_GPIO(trst_gpio
, trst_gpio_mode
);
562 if (transport_is_swd()) {
563 SET_MODE_GPIO(swclk_gpio
, swclk_gpio_mode
);
564 SET_MODE_GPIO(swdio_gpio
, swdio_gpio_mode
);
568 SET_MODE_GPIO(srst_gpio
, srst_gpio_mode
);
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)