openocd: src/jtag: replace the GPL-2.0-or-later license tag
[openocd.git] / src / jtag / drivers / at91rm9200.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4 * Copyright (C) 2006 by Anders Larsen *
5 * al@alarsen.net *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <jtag/interface.h>
13 #include "bitbang.h"
14
15 #include <sys/mman.h>
16
17 /* AT91RM9200 */
18 #define AT91C_BASE_SYS (0xfffff000)
19
20 /* GPIO assignment */
21 #define PIOA (0 << 7)
22 #define PIOB (1 << 7)
23 #define PIOC (2 << 7)
24 #define PIOD (3 << 7)
25
26 #define PIO_PER (0) /* PIO enable */
27 #define PIO_OER (4) /* output enable */
28 #define PIO_ODR (5) /* output disable */
29 #define PIO_SODR (12) /* set output data */
30 #define PIO_CODR (13) /* clear output data */
31 #define PIO_PDSR (15) /* pin data status */
32 #define PIO_PPUER (25) /* pull-up enable */
33
34 #define NC (0) /* not connected */
35 #define P0 (1 << 0)
36 #define P1 (1 << 1)
37 #define P2 (1 << 2)
38 #define P3 (1 << 3)
39 #define P4 (1 << 4)
40 #define P5 (1 << 5)
41 #define P6 (1 << 6)
42 #define P7 (1 << 7)
43 #define P8 (1 << 8)
44 #define P9 (1 << 9)
45 #define P10 (1 << 10)
46 #define P11 (1 << 11)
47 #define P12 (1 << 12)
48 #define P13 (1 << 13)
49 #define P14 (1 << 14)
50 #define P15 (1 << 15)
51 #define P16 (1 << 16)
52 #define P17 (1 << 17)
53 #define P18 (1 << 18)
54 #define P19 (1 << 19)
55 #define P20 (1 << 20)
56 #define P21 (1 << 21)
57 #define P22 (1 << 22)
58 #define P23 (1 << 23)
59 #define P24 (1 << 24)
60 #define P25 (1 << 25)
61 #define P26 (1 << 26)
62 #define P27 (1 << 27)
63 #define P28 (1 << 28)
64 #define P29 (1 << 29)
65 #define P30 (1 << 30)
66 #define P31 (1 << 31)
67
68 struct device_t {
69 const char *name;
70 int TDO_PIO; /* PIO holding TDO */
71 uint32_t TDO_MASK; /* TDO bitmask */
72 int TRST_PIO; /* PIO holding TRST */
73 uint32_t TRST_MASK; /* TRST bitmask */
74 int TMS_PIO; /* PIO holding TMS */
75 uint32_t TMS_MASK; /* TMS bitmask */
76 int TCK_PIO; /* PIO holding TCK */
77 uint32_t TCK_MASK; /* TCK bitmask */
78 int TDI_PIO; /* PIO holding TDI */
79 uint32_t TDI_MASK; /* TDI bitmask */
80 int SRST_PIO; /* PIO holding SRST */
81 uint32_t SRST_MASK; /* SRST bitmask */
82 };
83
84 static const struct device_t devices[] = {
85 { "rea_ecr", PIOD, P27, PIOA, NC, PIOD, P23, PIOD, P24, PIOD, P26, PIOC, P5 },
86 { .name = NULL },
87 };
88
89 /* configuration */
90 static char *at91rm9200_device;
91
92 /* interface variables
93 */
94 static const struct device_t *device;
95 static int dev_mem_fd;
96 static void *sys_controller;
97 static uint32_t *pio_base;
98
99 /* low level command set
100 */
101 static bb_value_t at91rm9200_read(void);
102 static int at91rm9200_write(int tck, int tms, int tdi);
103
104 static int at91rm9200_init(void);
105 static int at91rm9200_quit(void);
106
107 static struct bitbang_interface at91rm9200_bitbang = {
108 .read = at91rm9200_read,
109 .write = at91rm9200_write,
110 .blink = 0
111 };
112
113 static bb_value_t at91rm9200_read(void)
114 {
115 return (pio_base[device->TDO_PIO + PIO_PDSR] & device->TDO_MASK) ? BB_HIGH : BB_LOW;
116 }
117
118 static int at91rm9200_write(int tck, int tms, int tdi)
119 {
120 if (tck)
121 pio_base[device->TCK_PIO + PIO_SODR] = device->TCK_MASK;
122 else
123 pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;
124
125 if (tms)
126 pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;
127 else
128 pio_base[device->TMS_PIO + PIO_CODR] = device->TMS_MASK;
129
130 if (tdi)
131 pio_base[device->TDI_PIO + PIO_SODR] = device->TDI_MASK;
132 else
133 pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;
134
135 return ERROR_OK;
136 }
137
138 /* (1) assert or (0) deassert reset lines */
139 static int at91rm9200_reset(int trst, int srst)
140 {
141 if (trst == 0)
142 pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;
143 else if (trst == 1)
144 pio_base[device->TRST_PIO + PIO_CODR] = device->TRST_MASK;
145
146 if (srst == 0)
147 pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;
148 else if (srst == 1)
149 pio_base[device->SRST_PIO + PIO_CODR] = device->SRST_MASK;
150
151 return ERROR_OK;
152 }
153
154 COMMAND_HANDLER(at91rm9200_handle_device_command)
155 {
156 if (CMD_ARGC == 0)
157 return ERROR_COMMAND_SYNTAX_ERROR;
158
159 /* only if the device name wasn't overwritten by cmdline */
160 if (at91rm9200_device == 0) {
161 at91rm9200_device = malloc(strlen(CMD_ARGV[0]) + sizeof(char));
162 strcpy(at91rm9200_device, CMD_ARGV[0]);
163 }
164
165 return ERROR_OK;
166 }
167
168 static const struct command_registration at91rm9200_command_handlers[] = {
169 {
170 .name = "at91rm9200_device",
171 .handler = &at91rm9200_handle_device_command,
172 .mode = COMMAND_CONFIG,
173 .help = "Set at91rm9200 device [default \"rea_ecr\"]",
174 .usage = "<device>",
175 },
176 COMMAND_REGISTRATION_DONE
177 };
178
179 static struct jtag_interface at91rm9200_interface = {
180 .execute_queue = bitbang_execute_queue,
181 };
182
183 struct adapter_driver at91rm9200_adapter_driver = {
184 .name = "at91rm9200",
185 .transports = jtag_only,
186 .commands = at91rm9200_command_handlers,
187
188 .init = at91rm9200_init,
189 .quit = at91rm9200_quit,
190 .reset = at91rm9200_reset,
191
192 .jtag_ops = &at91rm9200_interface,
193 };
194
195 static int at91rm9200_init(void)
196 {
197 const struct device_t *cur_device;
198
199 cur_device = devices;
200
201 if (!at91rm9200_device || at91rm9200_device[0] == 0) {
202 at91rm9200_device = "rea_ecr";
203 LOG_WARNING("No at91rm9200 device specified, using default 'rea_ecr'");
204 }
205
206 while (cur_device->name) {
207 if (strcmp(cur_device->name, at91rm9200_device) == 0) {
208 device = cur_device;
209 break;
210 }
211 cur_device++;
212 }
213
214 if (!device) {
215 LOG_ERROR("No matching device found for %s", at91rm9200_device);
216 return ERROR_JTAG_INIT_FAILED;
217 }
218
219 bitbang_interface = &at91rm9200_bitbang;
220
221 dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
222 if (dev_mem_fd < 0) {
223 LOG_ERROR("open: %s", strerror(errno));
224 return ERROR_JTAG_INIT_FAILED;
225 }
226
227 sys_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
228 MAP_SHARED, dev_mem_fd, AT91C_BASE_SYS);
229 if (sys_controller == MAP_FAILED) {
230 LOG_ERROR("mmap: %s", strerror(errno));
231 close(dev_mem_fd);
232 return ERROR_JTAG_INIT_FAILED;
233 }
234 pio_base = (uint32_t *)sys_controller + 0x100;
235
236 /*
237 * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
238 * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
239 */
240 pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;
241 pio_base[device->TDI_PIO + PIO_OER] = device->TDI_MASK;
242 pio_base[device->TDI_PIO + PIO_PER] = device->TDI_MASK;
243 pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;
244 pio_base[device->TCK_PIO + PIO_OER] = device->TCK_MASK;
245 pio_base[device->TCK_PIO + PIO_PER] = device->TCK_MASK;
246 pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;
247 pio_base[device->TMS_PIO + PIO_OER] = device->TMS_MASK;
248 pio_base[device->TMS_PIO + PIO_PER] = device->TMS_MASK;
249 pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;
250 pio_base[device->TRST_PIO + PIO_OER] = device->TRST_MASK;
251 pio_base[device->TRST_PIO + PIO_PER] = device->TRST_MASK;
252 pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;
253 pio_base[device->SRST_PIO + PIO_OER] = device->SRST_MASK;
254 pio_base[device->SRST_PIO + PIO_PER] = device->SRST_MASK;
255 pio_base[device->TDO_PIO + PIO_ODR] = device->TDO_MASK;
256 pio_base[device->TDO_PIO + PIO_PPUER] = device->TDO_MASK;
257 pio_base[device->TDO_PIO + PIO_PER] = device->TDO_MASK;
258
259 return ERROR_OK;
260 }
261
262 static int at91rm9200_quit(void)
263 {
264
265 return ERROR_OK;
266 }

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)