ff9f7a4126046863c2747b391a9321b2db6431e9
[openocd.git] / src / jtag / drivers / at91rm9200.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Anders Larsen *
3 * al@alarsen.net *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "interface.h"
25 #include "bitbang.h"
26
27 #include <sys/mman.h>
28
29
30 /* AT91RM9200 */
31 #define AT91C_BASE_SYS (0xfffff000)
32
33 /* GPIO assignment */
34 #define PIOA (0 << 7)
35 #define PIOB (1 << 7)
36 #define PIOC (2 << 7)
37 #define PIOD (3 << 7)
38
39 #define PIO_PER (0) /* PIO enable */
40 #define PIO_OER (4) /* output enable */
41 #define PIO_ODR (5) /* output disable */
42 #define PIO_SODR (12) /* set output data */
43 #define PIO_CODR (13) /* clear output data */
44 #define PIO_PDSR (15) /* pin data status */
45 #define PIO_PPUER (25) /* pull-up enable */
46
47 #define NC (0) /* not connected */
48 #define P0 (1 << 0)
49 #define P1 (1 << 1)
50 #define P2 (1 << 2)
51 #define P3 (1 << 3)
52 #define P4 (1 << 4)
53 #define P5 (1 << 5)
54 #define P6 (1 << 6)
55 #define P7 (1 << 7)
56 #define P8 (1 << 8)
57 #define P9 (1 << 9)
58 #define P10 (1 << 10)
59 #define P11 (1 << 11)
60 #define P12 (1 << 12)
61 #define P13 (1 << 13)
62 #define P14 (1 << 14)
63 #define P15 (1 << 15)
64 #define P16 (1 << 16)
65 #define P17 (1 << 17)
66 #define P18 (1 << 18)
67 #define P19 (1 << 19)
68 #define P20 (1 << 20)
69 #define P21 (1 << 21)
70 #define P22 (1 << 22)
71 #define P23 (1 << 23)
72 #define P24 (1 << 24)
73 #define P25 (1 << 25)
74 #define P26 (1 << 26)
75 #define P27 (1 << 27)
76 #define P28 (1 << 28)
77 #define P29 (1 << 29)
78 #define P30 (1 << 30)
79 #define P31 (1 << 31)
80
81 struct device_t
82 {
83 char* name;
84 int TDO_PIO; /* PIO holding TDO */
85 uint32_t TDO_MASK; /* TDO bitmask */
86 int TRST_PIO; /* PIO holding TRST */
87 uint32_t TRST_MASK; /* TRST bitmask */
88 int TMS_PIO; /* PIO holding TMS */
89 uint32_t TMS_MASK; /* TMS bitmask */
90 int TCK_PIO; /* PIO holding TCK */
91 uint32_t TCK_MASK; /* TCK bitmask */
92 int TDI_PIO; /* PIO holding TDI */
93 uint32_t TDI_MASK; /* TDI bitmask */
94 int SRST_PIO; /* PIO holding SRST */
95 uint32_t SRST_MASK; /* SRST bitmask */
96 };
97
98 static struct device_t devices[] =
99 {
100 { "rea_ecr", PIOD, P27, PIOA, NC, PIOD, P23, PIOD, P24, PIOD, P26, PIOC, P5 },
101 { .name = NULL },
102 };
103
104 /* configuration */
105 static char* at91rm9200_device;
106
107 /* interface variables
108 */
109 static struct device_t* device;
110 static int dev_mem_fd;
111 static void *sys_controller;
112 static uint32_t* pio_base;
113
114 /* low level command set
115 */
116 static int at91rm9200_read(void);
117 static void at91rm9200_write(int tck, int tms, int tdi);
118 static void at91rm9200_reset(int trst, int srst);
119
120 static int at91rm9200_speed(int speed);
121 static int at91rm9200_register_commands(struct command_context *cmd_ctx);
122 static int at91rm9200_init(void);
123 static int at91rm9200_quit(void);
124
125 struct jtag_interface at91rm9200_interface =
126 {
127 .name = "at91rm9200",
128
129 .execute_queue = bitbang_execute_queue,
130
131 .speed = at91rm9200_speed,
132 .register_commands = at91rm9200_register_commands,
133 .init = at91rm9200_init,
134 .quit = at91rm9200_quit,
135 };
136
137 static struct bitbang_interface at91rm9200_bitbang =
138 {
139 .read = at91rm9200_read,
140 .write = at91rm9200_write,
141 .reset = at91rm9200_reset,
142 .blink = 0
143 };
144
145 static int at91rm9200_read(void)
146 {
147 return (pio_base[device->TDO_PIO + PIO_PDSR] & device->TDO_MASK) != 0;
148 }
149
150 static void at91rm9200_write(int tck, int tms, int tdi)
151 {
152 if (tck)
153 pio_base[device->TCK_PIO + PIO_SODR] = device->TCK_MASK;
154 else
155 pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;
156
157 if (tms)
158 pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;
159 else
160 pio_base[device->TMS_PIO + PIO_CODR] = device->TMS_MASK;
161
162 if (tdi)
163 pio_base[device->TDI_PIO + PIO_SODR] = device->TDI_MASK;
164 else
165 pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;
166 }
167
168 /* (1) assert or (0) deassert reset lines */
169 static void at91rm9200_reset(int trst, int srst)
170 {
171 if (trst == 0)
172 pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;
173 else if (trst == 1)
174 pio_base[device->TRST_PIO + PIO_CODR] = device->TRST_MASK;
175
176 if (srst == 0)
177 pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;
178 else if (srst == 1)
179 pio_base[device->SRST_PIO + PIO_CODR] = device->SRST_MASK;
180 }
181
182 static int at91rm9200_speed(int speed)
183 {
184
185 return ERROR_OK;
186 }
187
188 static int at91rm9200_handle_device_command(struct command_context *cmd_ctx, char *cmd, char **CMD_ARGV, int argc)
189 {
190 if (CMD_ARGC == 0)
191 return ERROR_OK;
192
193 /* only if the device name wasn't overwritten by cmdline */
194 if (at91rm9200_device == 0)
195 {
196 at91rm9200_device = malloc(strlen(CMD_ARGV[0]) + sizeof(char));
197 strcpy(at91rm9200_device, CMD_ARGV[0]);
198 }
199
200 return ERROR_OK;
201 }
202
203 static const struct command_registration at91rm9200_command_handlers[] = {
204 {
205 .name = "at91rm9200_device",
206 .handler = &at91rm9200_handle_device_command,
207 .mode = COMMAND_CONFIG,
208 .help = "query armjtagew info",
209 },
210 };
211
212 static int at91rm9200_register_commands(struct command_context *cmd_ctx)
213 {
214 return register_commands(cmd_ctx, NULL, at91rm9200_command_handlers);
215 }
216
217 static int at91rm9200_init(void)
218 {
219 struct device_t *cur_device;
220
221 cur_device = devices;
222
223 if (at91rm9200_device == NULL || at91rm9200_device[0] == 0)
224 {
225 at91rm9200_device = "rea_ecr";
226 LOG_WARNING("No at91rm9200 device specified, using default 'rea_ecr'");
227 }
228
229 while (cur_device->name)
230 {
231 if (strcmp(cur_device->name, at91rm9200_device) == 0)
232 {
233 device = cur_device;
234 break;
235 }
236 cur_device++;
237 }
238
239 if (!device)
240 {
241 LOG_ERROR("No matching device found for %s", at91rm9200_device);
242 return ERROR_JTAG_INIT_FAILED;
243 }
244
245 bitbang_interface = &at91rm9200_bitbang;
246
247 dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
248 if (dev_mem_fd < 0) {
249 perror("open");
250 return ERROR_JTAG_INIT_FAILED;
251 }
252
253 sys_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
254 MAP_SHARED, dev_mem_fd, AT91C_BASE_SYS);
255 if (sys_controller == MAP_FAILED) {
256 perror("mmap");
257 close(dev_mem_fd);
258 return ERROR_JTAG_INIT_FAILED;
259 }
260 pio_base = (uint32_t*)sys_controller + 0x100;
261
262 /*
263 * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
264 * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
265 */
266 pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;
267 pio_base[device->TDI_PIO + PIO_OER] = device->TDI_MASK;
268 pio_base[device->TDI_PIO + PIO_PER] = device->TDI_MASK;
269 pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;
270 pio_base[device->TCK_PIO + PIO_OER] = device->TCK_MASK;
271 pio_base[device->TCK_PIO + PIO_PER] = device->TCK_MASK;
272 pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;
273 pio_base[device->TMS_PIO + PIO_OER] = device->TMS_MASK;
274 pio_base[device->TMS_PIO + PIO_PER] = device->TMS_MASK;
275 pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;
276 pio_base[device->TRST_PIO + PIO_OER] = device->TRST_MASK;
277 pio_base[device->TRST_PIO + PIO_PER] = device->TRST_MASK;
278 pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;
279 pio_base[device->SRST_PIO + PIO_OER] = device->SRST_MASK;
280 pio_base[device->SRST_PIO + PIO_PER] = device->SRST_MASK;
281 pio_base[device->TDO_PIO + PIO_ODR] = device->TDO_MASK;
282 pio_base[device->TDO_PIO + PIO_PPUER] = device->TDO_MASK;
283 pio_base[device->TDO_PIO + PIO_PER] = device->TDO_MASK;
284
285 return ERROR_OK;
286 }
287
288 static int at91rm9200_quit(void)
289 {
290
291 return ERROR_OK;
292 }

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)