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
;
89 static int swdio_dir_gpio
= -1;
90 static int swdio_dir_gpio_mode
;
92 /* Transition delay coefficients */
93 static int speed_coeff
= 113714;
94 static int speed_offset
= 28;
95 static unsigned int jtag_delay
;
97 static bb_value_t
bcm2835gpio_read(void)
99 return (GPIO_LEV
& 1<<tdo_gpio
) ? BB_HIGH
: BB_LOW
;
102 static int bcm2835gpio_write(int tck
, int tms
, int tdi
)
104 uint32_t set
= tck
<<tck_gpio
| tms
<<tms_gpio
| tdi
<<tdi_gpio
;
105 uint32_t clear
= !tck
<<tck_gpio
| !tms
<<tms_gpio
| !tdi
<<tdi_gpio
;
110 for (unsigned int i
= 0; i
< jtag_delay
; i
++)
116 static int bcm2835gpio_swd_write(int swclk
, int swdio
)
118 uint32_t set
= swclk
<< swclk_gpio
| swdio
<< swdio_gpio
;
119 uint32_t clear
= !swclk
<< swclk_gpio
| !swdio
<< swdio_gpio
;
124 for (unsigned int i
= 0; i
< jtag_delay
; i
++)
130 /* (1) assert or (0) deassert reset lines */
131 static int bcm2835gpio_reset(int trst
, int srst
)
137 set
|= !trst
<<trst_gpio
;
138 clear
|= trst
<<trst_gpio
;
142 set
|= !srst
<<srst_gpio
;
143 clear
|= srst
<<srst_gpio
;
152 static void bcm2835_swdio_drive(bool is_output
)
154 if (swdio_dir_gpio
> 0) {
156 GPIO_SET
= 1 << swdio_dir_gpio
;
157 OUT_GPIO(swdio_gpio
);
159 INP_GPIO(swdio_gpio
);
160 GPIO_CLR
= 1 << swdio_dir_gpio
;
164 OUT_GPIO(swdio_gpio
);
166 INP_GPIO(swdio_gpio
);
170 static int bcm2835_swdio_read(void)
172 return !!(GPIO_LEV
& 1 << swdio_gpio
);
175 static int bcm2835gpio_khz(int khz
, int *jtag_speed
)
178 LOG_DEBUG("RCLK not supported");
181 *jtag_speed
= speed_coeff
/khz
- speed_offset
;
187 static int bcm2835gpio_speed_div(int speed
, int *khz
)
189 *khz
= speed_coeff
/(speed
+ speed_offset
);
193 static int bcm2835gpio_speed(int speed
)
199 static int is_gpio_valid(int gpio
)
201 return gpio
>= 0 && gpio
<= 53;
204 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums
)
207 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tck_gpio
);
208 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], tms_gpio
);
209 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[2], tdi_gpio
);
210 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[3], tdo_gpio
);
211 } else if (CMD_ARGC
!= 0) {
212 return ERROR_COMMAND_SYNTAX_ERROR
;
216 "BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
217 tck_gpio
, tms_gpio
, tdi_gpio
, tdo_gpio
);
222 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck
)
225 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tck_gpio
);
227 command_print(CMD
, "BCM2835 GPIO config: tck = %d", tck_gpio
);
231 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms
)
234 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tms_gpio
);
236 command_print(CMD
, "BCM2835 GPIO config: tms = %d", tms_gpio
);
240 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo
)
243 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tdo_gpio
);
245 command_print(CMD
, "BCM2835 GPIO config: tdo = %d", tdo_gpio
);
249 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi
)
252 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], tdi_gpio
);
254 command_print(CMD
, "BCM2835 GPIO config: tdi = %d", tdi_gpio
);
258 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst
)
261 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], srst_gpio
);
263 command_print(CMD
, "BCM2835 GPIO config: srst = %d", srst_gpio
);
267 COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst
)
270 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], trst_gpio
);
272 command_print(CMD
, "BCM2835 GPIO config: trst = %d", trst_gpio
);
276 COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionums
)
279 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], swclk_gpio
);
280 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], swdio_gpio
);
281 } else if (CMD_ARGC
!= 0) {
282 return ERROR_COMMAND_SYNTAX_ERROR
;
286 "BCM2835 GPIO nums: swclk = %d, swdio = %d",
287 swclk_gpio
, swdio_gpio
);
292 COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swclk
)
295 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], swclk_gpio
);
297 command_print(CMD
, "BCM2835 num: swclk = %d", swclk_gpio
);
301 COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio
)
304 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], swdio_gpio
);
306 command_print(CMD
, "BCM2835 num: swdio = %d", swdio_gpio
);
310 COMMAND_HANDLER(bcm2835gpio_handle_swd_dir_gpionum_swdio
)
313 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], swdio_dir_gpio
);
315 command_print(CMD
, "BCM2835 num: swdio_dir = %d", swdio_dir_gpio
);
319 COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs
)
322 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], speed_coeff
);
323 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], speed_offset
);
326 command_print(CMD
, "BCM2835 GPIO: speed_coeffs = %d, speed_offset = %d",
327 speed_coeff
, speed_offset
);
331 COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base
)
334 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], bcm2835_peri_base
);
336 command_print(CMD
, "BCM2835 GPIO: peripheral_base = 0x%08x",
341 static const struct command_registration bcm2835gpio_subcommand_handlers
[] = {
344 .handler
= &bcm2835gpio_handle_jtag_gpionums
,
345 .mode
= COMMAND_CONFIG
,
346 .help
= "gpio numbers for tck, tms, tdi, tdo. (in that order)",
347 .usage
= "[tck tms tdi tdo]",
351 .handler
= &bcm2835gpio_handle_jtag_gpionum_tck
,
352 .mode
= COMMAND_CONFIG
,
353 .help
= "gpio number for tck.",
358 .handler
= &bcm2835gpio_handle_jtag_gpionum_tms
,
359 .mode
= COMMAND_CONFIG
,
360 .help
= "gpio number for tms.",
365 .handler
= &bcm2835gpio_handle_jtag_gpionum_tdo
,
366 .mode
= COMMAND_CONFIG
,
367 .help
= "gpio number for tdo.",
372 .handler
= &bcm2835gpio_handle_jtag_gpionum_tdi
,
373 .mode
= COMMAND_CONFIG
,
374 .help
= "gpio number for tdi.",
379 .handler
= &bcm2835gpio_handle_swd_gpionums
,
380 .mode
= COMMAND_CONFIG
,
381 .help
= "gpio numbers for swclk, swdio. (in that order)",
382 .usage
= "[swclk swdio]",
386 .handler
= &bcm2835gpio_handle_swd_gpionum_swclk
,
387 .mode
= COMMAND_CONFIG
,
388 .help
= "gpio number for swclk.",
393 .handler
= &bcm2835gpio_handle_swd_gpionum_swdio
,
394 .mode
= COMMAND_CONFIG
,
395 .help
= "gpio number for swdio.",
399 .name
= "swdio_dir_num",
400 .handler
= &bcm2835gpio_handle_swd_dir_gpionum_swdio
,
401 .mode
= COMMAND_CONFIG
,
402 .help
= "gpio number for swdio direction control pin (set=output mode, clear=input mode)",
403 .usage
= "[swdio_dir]",
407 .handler
= &bcm2835gpio_handle_jtag_gpionum_srst
,
408 .mode
= COMMAND_CONFIG
,
409 .help
= "gpio number for srst.",
414 .handler
= &bcm2835gpio_handle_jtag_gpionum_trst
,
415 .mode
= COMMAND_CONFIG
,
416 .help
= "gpio number for trst.",
420 .name
= "speed_coeffs",
421 .handler
= &bcm2835gpio_handle_speed_coeffs
,
422 .mode
= COMMAND_CONFIG
,
423 .help
= "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
424 .usage
= "[SPEED_COEFF SPEED_OFFSET]",
427 .name
= "peripheral_base",
428 .handler
= &bcm2835gpio_handle_peripheral_base
,
429 .mode
= COMMAND_CONFIG
,
430 .help
= "peripheral base to access GPIOs (RPi1 0x20000000, RPi2 0x3F000000).",
434 COMMAND_REGISTRATION_DONE
437 static const struct command_registration bcm2835gpio_command_handlers
[] = {
439 .name
= "bcm2835gpio",
441 .help
= "perform bcm2835gpio management",
442 .chain
= bcm2835gpio_subcommand_handlers
,
445 COMMAND_REGISTRATION_DONE
448 static const char * const bcm2835_transports
[] = { "jtag", "swd", NULL
};
450 static struct jtag_interface bcm2835gpio_interface
= {
451 .supported
= DEBUG_CAP_TMS_SEQ
,
452 .execute_queue
= bitbang_execute_queue
,
455 struct adapter_driver bcm2835gpio_adapter_driver
= {
456 .name
= "bcm2835gpio",
457 .transports
= bcm2835_transports
,
458 .commands
= bcm2835gpio_command_handlers
,
460 .init
= bcm2835gpio_init
,
461 .quit
= bcm2835gpio_quit
,
462 .reset
= bcm2835gpio_reset
,
463 .speed
= bcm2835gpio_speed
,
464 .khz
= bcm2835gpio_khz
,
465 .speed_div
= bcm2835gpio_speed_div
,
467 .jtag_ops
= &bcm2835gpio_interface
,
468 .swd_ops
= &bitbang_swd
,
471 static bool bcm2835gpio_jtag_mode_possible(void)
473 if (!is_gpio_valid(tck_gpio
))
475 if (!is_gpio_valid(tms_gpio
))
477 if (!is_gpio_valid(tdi_gpio
))
479 if (!is_gpio_valid(tdo_gpio
))
484 static bool bcm2835gpio_swd_mode_possible(void)
486 if (!is_gpio_valid(swclk_gpio
))
488 if (!is_gpio_valid(swdio_gpio
))
493 static int bcm2835gpio_init(void)
495 bitbang_interface
= &bcm2835gpio_bitbang
;
497 LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver");
499 if (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) {
500 LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
501 return ERROR_JTAG_INIT_FAILED
;
504 if (transport_is_swd() && !bcm2835gpio_swd_mode_possible()) {
505 LOG_ERROR("Require swclk and swdio gpio for SWD mode");
506 return ERROR_JTAG_INIT_FAILED
;
509 dev_mem_fd
= open("/dev/gpiomem", O_RDWR
| O_SYNC
);
510 if (dev_mem_fd
< 0) {
511 LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
512 dev_mem_fd
= open("/dev/mem", O_RDWR
| O_SYNC
);
514 if (dev_mem_fd
< 0) {
515 LOG_ERROR("open: %s", strerror(errno
));
516 return ERROR_JTAG_INIT_FAILED
;
519 pio_base
= mmap(NULL
, sysconf(_SC_PAGE_SIZE
), PROT_READ
| PROT_WRITE
,
520 MAP_SHARED
, dev_mem_fd
, BCM2835_GPIO_BASE
);
522 if (pio_base
== MAP_FAILED
) {
523 LOG_ERROR("mmap: %s", strerror(errno
));
525 return ERROR_JTAG_INIT_FAILED
;
528 static volatile uint32_t *pads_base
;
529 pads_base
= mmap(NULL
, sysconf(_SC_PAGE_SIZE
), PROT_READ
| PROT_WRITE
,
530 MAP_SHARED
, dev_mem_fd
, BCM2835_PADS_GPIO_0_27
);
532 if (pads_base
== MAP_FAILED
) {
533 LOG_ERROR("mmap: %s", strerror(errno
));
535 return ERROR_JTAG_INIT_FAILED
;
538 /* set 4mA drive strength, slew rate limited, hysteresis on */
539 pads_base
[BCM2835_PADS_GPIO_0_27_OFFSET
] = 0x5a000008 + 1;
542 * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
543 * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
545 if (transport_is_jtag()) {
546 tdo_gpio_mode
= MODE_GPIO(tdo_gpio
);
547 tdi_gpio_mode
= MODE_GPIO(tdi_gpio
);
548 tck_gpio_mode
= MODE_GPIO(tck_gpio
);
549 tms_gpio_mode
= MODE_GPIO(tms_gpio
);
553 GPIO_CLR
= 1<<tdi_gpio
| 1<<tck_gpio
;
554 GPIO_SET
= 1<<tms_gpio
;
560 if (trst_gpio
!= -1) {
561 trst_gpio_mode
= MODE_GPIO(trst_gpio
);
562 GPIO_SET
= 1 << trst_gpio
;
567 if (transport_is_swd()) {
568 swclk_gpio_mode
= MODE_GPIO(swclk_gpio
);
569 swdio_gpio_mode
= MODE_GPIO(swdio_gpio
);
571 GPIO_CLR
= 1<<swdio_gpio
| 1<<swclk_gpio
;
573 OUT_GPIO(swclk_gpio
);
574 OUT_GPIO(swdio_gpio
);
577 if (srst_gpio
!= -1) {
578 srst_gpio_mode
= MODE_GPIO(srst_gpio
);
579 GPIO_SET
= 1 << srst_gpio
;
583 if (swdio_dir_gpio
!= -1) {
584 swdio_dir_gpio_mode
= MODE_GPIO(swdio_dir_gpio
);
585 GPIO_SET
= 1 << swdio_dir_gpio
;
586 OUT_GPIO(swdio_dir_gpio
);
589 LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d "
590 "tdo %d trst %d srst %d", tck_gpio_mode
, tms_gpio_mode
,
591 tdi_gpio_mode
, tdo_gpio_mode
, trst_gpio_mode
, srst_gpio_mode
);
596 static int bcm2835gpio_quit(void)
598 if (transport_is_jtag()) {
599 SET_MODE_GPIO(tdo_gpio
, tdo_gpio_mode
);
600 SET_MODE_GPIO(tdi_gpio
, tdi_gpio_mode
);
601 SET_MODE_GPIO(tck_gpio
, tck_gpio_mode
);
602 SET_MODE_GPIO(tms_gpio
, tms_gpio_mode
);
604 SET_MODE_GPIO(trst_gpio
, trst_gpio_mode
);
607 if (transport_is_swd()) {
608 SET_MODE_GPIO(swclk_gpio
, swclk_gpio_mode
);
609 SET_MODE_GPIO(swdio_gpio
, swdio_gpio_mode
);
613 SET_MODE_GPIO(srst_gpio
, srst_gpio_mode
);
615 if (swdio_dir_gpio
!= -1)
616 SET_MODE_GPIO(swdio_dir_gpio
, swdio_dir_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)