jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / at91samd.c
1 /***************************************************************************
2 * Copyright (C) 2013 by Andrey Yurovsky *
3 * Andrey Yurovsky <yurovsky@gmail.com> *
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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "imp.h"
24 #include "helper/binarybuffer.h"
25
26 #include <jtag/jtag.h>
27 #include <target/cortex_m.h>
28
29 #define SAMD_NUM_PROT_BLOCKS 16
30 #define SAMD_PAGE_SIZE_MAX 1024
31
32 #define SAMD_FLASH ((uint32_t)0x00000000) /* physical Flash memory */
33 #define SAMD_USER_ROW ((uint32_t)0x00804000) /* User Row of Flash */
34 #define SAMD_PAC1 0x41000000 /* Peripheral Access Control 1 */
35 #define SAMD_DSU 0x41002000 /* Device Service Unit */
36 #define SAMD_NVMCTRL 0x41004000 /* Non-volatile memory controller */
37
38 #define SAMD_DSU_STATUSA 1 /* DSU status register */
39 #define SAMD_DSU_DID 0x18 /* Device ID register */
40 #define SAMD_DSU_CTRL_EXT 0x100 /* CTRL register, external access */
41
42 #define SAMD_NVMCTRL_CTRLA 0x00 /* NVM control A register */
43 #define SAMD_NVMCTRL_CTRLB 0x04 /* NVM control B register */
44 #define SAMD_NVMCTRL_PARAM 0x08 /* NVM parameters register */
45 #define SAMD_NVMCTRL_INTFLAG 0x18 /* NVM Interrupt Flag Status & Clear */
46 #define SAMD_NVMCTRL_STATUS 0x18 /* NVM status register */
47 #define SAMD_NVMCTRL_ADDR 0x1C /* NVM address register */
48 #define SAMD_NVMCTRL_LOCK 0x20 /* NVM Lock section register */
49
50 #define SAMD_CMDEX_KEY 0xA5UL
51 #define SAMD_NVM_CMD(n) ((SAMD_CMDEX_KEY << 8) | (n & 0x7F))
52
53 /* NVMCTRL commands. See Table 20-4 in 42129F–SAM–10/2013 */
54 #define SAMD_NVM_CMD_ER 0x02 /* Erase Row */
55 #define SAMD_NVM_CMD_WP 0x04 /* Write Page */
56 #define SAMD_NVM_CMD_EAR 0x05 /* Erase Auxiliary Row */
57 #define SAMD_NVM_CMD_WAP 0x06 /* Write Auxiliary Page */
58 #define SAMD_NVM_CMD_LR 0x40 /* Lock Region */
59 #define SAMD_NVM_CMD_UR 0x41 /* Unlock Region */
60 #define SAMD_NVM_CMD_SPRM 0x42 /* Set Power Reduction Mode */
61 #define SAMD_NVM_CMD_CPRM 0x43 /* Clear Power Reduction Mode */
62 #define SAMD_NVM_CMD_PBC 0x44 /* Page Buffer Clear */
63 #define SAMD_NVM_CMD_SSB 0x45 /* Set Security Bit */
64 #define SAMD_NVM_CMD_INVALL 0x46 /* Invalidate all caches */
65
66 /* NVMCTRL bits */
67 #define SAMD_NVM_CTRLB_MANW 0x80
68
69 /* Known identifiers */
70 #define SAMD_PROCESSOR_M0 0x01
71 #define SAMD_FAMILY_D 0x00
72 #define SAMD_FAMILY_L 0x01
73 #define SAMD_FAMILY_C 0x02
74 #define SAMD_SERIES_20 0x00
75 #define SAMD_SERIES_21 0x01
76 #define SAMD_SERIES_22 0x02
77 #define SAMD_SERIES_10 0x02
78 #define SAMD_SERIES_11 0x03
79 #define SAMD_SERIES_09 0x04
80
81 /* Device ID macros */
82 #define SAMD_GET_PROCESSOR(id) (id >> 28)
83 #define SAMD_GET_FAMILY(id) (((id >> 23) & 0x1F))
84 #define SAMD_GET_SERIES(id) (((id >> 16) & 0x3F))
85 #define SAMD_GET_DEVSEL(id) (id & 0xFF)
86
87 /* Bits to mask out lockbits in user row */
88 #define NVMUSERROW_LOCKBIT_MASK ((uint64_t)0x0000FFFFFFFFFFFF)
89
90 struct samd_part {
91 uint8_t id;
92 const char *name;
93 uint32_t flash_kb;
94 uint32_t ram_kb;
95 };
96
97 /* Known SAMD09 parts. DID reset values missing in RM, see
98 * https://github.com/avrxml/asf/blob/master/sam0/utils/cmsis/samd09/include/ */
99 static const struct samd_part samd09_parts[] = {
100 { 0x0, "SAMD09D14A", 16, 4 },
101 { 0x7, "SAMD09C13A", 8, 4 },
102 };
103
104 /* Known SAMD10 parts */
105 static const struct samd_part samd10_parts[] = {
106 { 0x0, "SAMD10D14AMU", 16, 4 },
107 { 0x1, "SAMD10D13AMU", 8, 4 },
108 { 0x2, "SAMD10D12AMU", 4, 4 },
109 { 0x3, "SAMD10D14ASU", 16, 4 },
110 { 0x4, "SAMD10D13ASU", 8, 4 },
111 { 0x5, "SAMD10D12ASU", 4, 4 },
112 { 0x6, "SAMD10C14A", 16, 4 },
113 { 0x7, "SAMD10C13A", 8, 4 },
114 { 0x8, "SAMD10C12A", 4, 4 },
115 };
116
117 /* Known SAMD11 parts */
118 static const struct samd_part samd11_parts[] = {
119 { 0x0, "SAMD11D14AM", 16, 4 },
120 { 0x1, "SAMD11D13AMU", 8, 4 },
121 { 0x2, "SAMD11D12AMU", 4, 4 },
122 { 0x3, "SAMD11D14ASS", 16, 4 },
123 { 0x4, "SAMD11D13ASU", 8, 4 },
124 { 0x5, "SAMD11D12ASU", 4, 4 },
125 { 0x6, "SAMD11C14A", 16, 4 },
126 { 0x7, "SAMD11C13A", 8, 4 },
127 { 0x8, "SAMD11C12A", 4, 4 },
128 { 0x9, "SAMD11D14AU", 16, 4 },
129 };
130
131 /* Known SAMD20 parts. See Table 12-8 in 42129F–SAM–10/2013 */
132 static const struct samd_part samd20_parts[] = {
133 { 0x0, "SAMD20J18A", 256, 32 },
134 { 0x1, "SAMD20J17A", 128, 16 },
135 { 0x2, "SAMD20J16A", 64, 8 },
136 { 0x3, "SAMD20J15A", 32, 4 },
137 { 0x4, "SAMD20J14A", 16, 2 },
138 { 0x5, "SAMD20G18A", 256, 32 },
139 { 0x6, "SAMD20G17A", 128, 16 },
140 { 0x7, "SAMD20G16A", 64, 8 },
141 { 0x8, "SAMD20G15A", 32, 4 },
142 { 0x9, "SAMD20G14A", 16, 2 },
143 { 0xA, "SAMD20E18A", 256, 32 },
144 { 0xB, "SAMD20E17A", 128, 16 },
145 { 0xC, "SAMD20E16A", 64, 8 },
146 { 0xD, "SAMD20E15A", 32, 4 },
147 { 0xE, "SAMD20E14A", 16, 2 },
148 };
149
150 /* Known SAMD21 parts. */
151 static const struct samd_part samd21_parts[] = {
152 { 0x0, "SAMD21J18A", 256, 32 },
153 { 0x1, "SAMD21J17A", 128, 16 },
154 { 0x2, "SAMD21J16A", 64, 8 },
155 { 0x3, "SAMD21J15A", 32, 4 },
156 { 0x4, "SAMD21J14A", 16, 2 },
157 { 0x5, "SAMD21G18A", 256, 32 },
158 { 0x6, "SAMD21G17A", 128, 16 },
159 { 0x7, "SAMD21G16A", 64, 8 },
160 { 0x8, "SAMD21G15A", 32, 4 },
161 { 0x9, "SAMD21G14A", 16, 2 },
162 { 0xA, "SAMD21E18A", 256, 32 },
163 { 0xB, "SAMD21E17A", 128, 16 },
164 { 0xC, "SAMD21E16A", 64, 8 },
165 { 0xD, "SAMD21E15A", 32, 4 },
166 { 0xE, "SAMD21E14A", 16, 2 },
167
168 /* SAMR21 parts have integrated SAMD21 with a radio */
169 { 0x18, "SAMR21G19A", 256, 32 }, /* with 512k of serial flash */
170 { 0x19, "SAMR21G18A", 256, 32 },
171 { 0x1A, "SAMR21G17A", 128, 32 },
172 { 0x1B, "SAMR21G16A", 64, 16 },
173 { 0x1C, "SAMR21E18A", 256, 32 },
174 { 0x1D, "SAMR21E17A", 128, 32 },
175 { 0x1E, "SAMR21E16A", 64, 16 },
176
177 /* SAMD21 B Variants (Table 3-7 from rev I of datasheet) */
178 { 0x20, "SAMD21J16B", 64, 8 },
179 { 0x21, "SAMD21J15B", 32, 4 },
180 { 0x23, "SAMD21G16B", 64, 8 },
181 { 0x24, "SAMD21G15B", 32, 4 },
182 { 0x26, "SAMD21E16B", 64, 8 },
183 { 0x27, "SAMD21E15B", 32, 4 },
184
185 /* SAMD21 D and L Variants (from Errata)
186 http://ww1.microchip.com/downloads/en/DeviceDoc/
187 SAM-D21-Family-Silicon-Errata-and-DataSheet-Clarification-DS80000760D.pdf */
188 { 0x55, "SAMD21E16BU", 64, 8 },
189 { 0x56, "SAMD21E15BU", 32, 4 },
190 { 0x57, "SAMD21G16L", 64, 8 },
191 { 0x3E, "SAMD21E16L", 64, 8 },
192 { 0x3F, "SAMD21E15L", 32, 4 },
193 { 0x62, "SAMD21E16CU", 64, 8 },
194 { 0x63, "SAMD21E15CU", 32, 4 },
195 { 0x92, "SAMD21J17D", 128, 16 },
196 { 0x93, "SAMD21G17D", 128, 16 },
197 { 0x94, "SAMD21E17D", 128, 16 },
198 { 0x95, "SAMD21E17DU", 128, 16 },
199 { 0x96, "SAMD21G17L", 128, 16 },
200 { 0x97, "SAMD21E17L", 128, 16 },
201
202 /* Known SAMDA1 parts.
203 SAMD-A1 series uses the same series identifier like the SAMD21
204 taken from http://ww1.microchip.com/downloads/en/DeviceDoc/40001895A.pdf (pages 14-17) */
205 { 0x29, "SAMDA1J16A", 64, 8 },
206 { 0x2A, "SAMDA1J15A", 32, 4 },
207 { 0x2B, "SAMDA1J14A", 16, 4 },
208 { 0x2C, "SAMDA1G16A", 64, 8 },
209 { 0x2D, "SAMDA1G15A", 32, 4 },
210 { 0x2E, "SAMDA1G14A", 16, 4 },
211 { 0x2F, "SAMDA1E16A", 64, 8 },
212 { 0x30, "SAMDA1E15A", 32, 4 },
213 { 0x31, "SAMDA1E14A", 16, 4 },
214 { 0x64, "SAMDA1J16B", 64, 8 },
215 { 0x65, "SAMDA1J15B", 32, 4 },
216 { 0x66, "SAMDA1J14B", 16, 4 },
217 { 0x67, "SAMDA1G16B", 64, 8 },
218 { 0x68, "SAMDA1G15B", 32, 4 },
219 { 0x69, "SAMDA1G14B", 16, 4 },
220 { 0x6A, "SAMDA1E16B", 64, 8 },
221 { 0x6B, "SAMDA1E15B", 32, 4 },
222 { 0x6C, "SAMDA1E14B", 16, 4 },
223 };
224
225 /* Known SAML21 parts. */
226 static const struct samd_part saml21_parts[] = {
227 { 0x00, "SAML21J18A", 256, 32 },
228 { 0x01, "SAML21J17A", 128, 16 },
229 { 0x02, "SAML21J16A", 64, 8 },
230 { 0x05, "SAML21G18A", 256, 32 },
231 { 0x06, "SAML21G17A", 128, 16 },
232 { 0x07, "SAML21G16A", 64, 8 },
233 { 0x0A, "SAML21E18A", 256, 32 },
234 { 0x0B, "SAML21E17A", 128, 16 },
235 { 0x0C, "SAML21E16A", 64, 8 },
236 { 0x0D, "SAML21E15A", 32, 4 },
237 { 0x0F, "SAML21J18B", 256, 32 },
238 { 0x10, "SAML21J17B", 128, 16 },
239 { 0x11, "SAML21J16B", 64, 8 },
240 { 0x14, "SAML21G18B", 256, 32 },
241 { 0x15, "SAML21G17B", 128, 16 },
242 { 0x16, "SAML21G16B", 64, 8 },
243 { 0x19, "SAML21E18B", 256, 32 },
244 { 0x1A, "SAML21E17B", 128, 16 },
245 { 0x1B, "SAML21E16B", 64, 8 },
246 { 0x1C, "SAML21E15B", 32, 4 },
247
248 /* SAMR30 parts have integrated SAML21 with a radio */
249 { 0x1E, "SAMR30G18A", 256, 32 },
250 { 0x1F, "SAMR30E18A", 256, 32 },
251
252 /* SAMR34/R35 parts have integrated SAML21 with a lora radio */
253 { 0x28, "SAMR34J18", 256, 32 },
254 { 0x2B, "SAMR35J18", 256, 32 },
255 };
256
257 /* Known SAML22 parts. */
258 static const struct samd_part saml22_parts[] = {
259 { 0x00, "SAML22N18A", 256, 32 },
260 { 0x01, "SAML22N17A", 128, 16 },
261 { 0x02, "SAML22N16A", 64, 8 },
262 { 0x05, "SAML22J18A", 256, 32 },
263 { 0x06, "SAML22J17A", 128, 16 },
264 { 0x07, "SAML22J16A", 64, 8 },
265 { 0x0A, "SAML22G18A", 256, 32 },
266 { 0x0B, "SAML22G17A", 128, 16 },
267 { 0x0C, "SAML22G16A", 64, 8 },
268 };
269
270 /* Known SAMC20 parts. */
271 static const struct samd_part samc20_parts[] = {
272 { 0x00, "SAMC20J18A", 256, 32 },
273 { 0x01, "SAMC20J17A", 128, 16 },
274 { 0x02, "SAMC20J16A", 64, 8 },
275 { 0x03, "SAMC20J15A", 32, 4 },
276 { 0x05, "SAMC20G18A", 256, 32 },
277 { 0x06, "SAMC20G17A", 128, 16 },
278 { 0x07, "SAMC20G16A", 64, 8 },
279 { 0x08, "SAMC20G15A", 32, 4 },
280 { 0x0A, "SAMC20E18A", 256, 32 },
281 { 0x0B, "SAMC20E17A", 128, 16 },
282 { 0x0C, "SAMC20E16A", 64, 8 },
283 { 0x0D, "SAMC20E15A", 32, 4 },
284 { 0x20, "SAMC20N18A", 256, 32 },
285 { 0x21, "SAMC20N17A", 128, 16 },
286 };
287
288 /* Known SAMC21 parts. */
289 static const struct samd_part samc21_parts[] = {
290 { 0x00, "SAMC21J18A", 256, 32 },
291 { 0x01, "SAMC21J17A", 128, 16 },
292 { 0x02, "SAMC21J16A", 64, 8 },
293 { 0x03, "SAMC21J15A", 32, 4 },
294 { 0x05, "SAMC21G18A", 256, 32 },
295 { 0x06, "SAMC21G17A", 128, 16 },
296 { 0x07, "SAMC21G16A", 64, 8 },
297 { 0x08, "SAMC21G15A", 32, 4 },
298 { 0x0A, "SAMC21E18A", 256, 32 },
299 { 0x0B, "SAMC21E17A", 128, 16 },
300 { 0x0C, "SAMC21E16A", 64, 8 },
301 { 0x0D, "SAMC21E15A", 32, 4 },
302 { 0x20, "SAMC21N18A", 256, 32 },
303 { 0x21, "SAMC21N17A", 128, 16 },
304 };
305
306 /* Each family of parts contains a parts table in the DEVSEL field of DID. The
307 * processor ID, family ID, and series ID are used to determine which exact
308 * family this is and then we can use the corresponding table. */
309 struct samd_family {
310 uint8_t processor;
311 uint8_t family;
312 uint8_t series;
313 const struct samd_part *parts;
314 size_t num_parts;
315 uint64_t nvm_userrow_res_mask; /* protect bits which are reserved, 0 -> protect */
316 };
317
318 /* Known SAMD families */
319 static const struct samd_family samd_families[] = {
320 { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_20,
321 samd20_parts, ARRAY_SIZE(samd20_parts),
322 (uint64_t)0xFFFF01FFFE01FF77 },
323 { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_21,
324 samd21_parts, ARRAY_SIZE(samd21_parts),
325 (uint64_t)0xFFFF01FFFE01FF77 },
326 { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_09,
327 samd09_parts, ARRAY_SIZE(samd09_parts),
328 (uint64_t)0xFFFF01FFFE01FF77 },
329 { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_10,
330 samd10_parts, ARRAY_SIZE(samd10_parts),
331 (uint64_t)0xFFFF01FFFE01FF77 },
332 { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_11,
333 samd11_parts, ARRAY_SIZE(samd11_parts),
334 (uint64_t)0xFFFF01FFFE01FF77 },
335 { SAMD_PROCESSOR_M0, SAMD_FAMILY_L, SAMD_SERIES_21,
336 saml21_parts, ARRAY_SIZE(saml21_parts),
337 (uint64_t)0xFFFF03FFFC01FF77 },
338 { SAMD_PROCESSOR_M0, SAMD_FAMILY_L, SAMD_SERIES_22,
339 saml22_parts, ARRAY_SIZE(saml22_parts),
340 (uint64_t)0xFFFF03FFFC01FF77 },
341 { SAMD_PROCESSOR_M0, SAMD_FAMILY_C, SAMD_SERIES_20,
342 samc20_parts, ARRAY_SIZE(samc20_parts),
343 (uint64_t)0xFFFF03FFFC01FF77 },
344 { SAMD_PROCESSOR_M0, SAMD_FAMILY_C, SAMD_SERIES_21,
345 samc21_parts, ARRAY_SIZE(samc21_parts),
346 (uint64_t)0xFFFF03FFFC01FF77 },
347 };
348
349 struct samd_info {
350 uint32_t page_size;
351 int num_pages;
352 int sector_size;
353 int prot_block_size;
354
355 bool probed;
356 struct target *target;
357 };
358
359
360 /**
361 * Gives the family structure to specific device id.
362 * @param id The id of the device.
363 * @return On failure NULL, otherwise a pointer to the structure.
364 */
365 static const struct samd_family *samd_find_family(uint32_t id)
366 {
367 uint8_t processor = SAMD_GET_PROCESSOR(id);
368 uint8_t family = SAMD_GET_FAMILY(id);
369 uint8_t series = SAMD_GET_SERIES(id);
370
371 for (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) {
372 if (samd_families[i].processor == processor &&
373 samd_families[i].series == series &&
374 samd_families[i].family == family)
375 return &samd_families[i];
376 }
377
378 return NULL;
379 }
380
381 /**
382 * Gives the part structure to specific device id.
383 * @param id The id of the device.
384 * @return On failure NULL, otherwise a pointer to the structure.
385 */
386 static const struct samd_part *samd_find_part(uint32_t id)
387 {
388 uint8_t devsel = SAMD_GET_DEVSEL(id);
389 const struct samd_family *family = samd_find_family(id);
390 if (!family)
391 return NULL;
392
393 for (unsigned i = 0; i < family->num_parts; i++) {
394 if (family->parts[i].id == devsel)
395 return &family->parts[i];
396 }
397
398 return NULL;
399 }
400
401 static int samd_protect_check(struct flash_bank *bank)
402 {
403 int res;
404 uint16_t lock;
405
406 res = target_read_u16(bank->target,
407 SAMD_NVMCTRL + SAMD_NVMCTRL_LOCK, &lock);
408 if (res != ERROR_OK)
409 return res;
410
411 /* Lock bits are active-low */
412 for (unsigned int prot_block = 0; prot_block < bank->num_prot_blocks; prot_block++)
413 bank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));
414
415 return ERROR_OK;
416 }
417
418 static int samd_get_flash_page_info(struct target *target,
419 uint32_t *sizep, int *nump)
420 {
421 int res;
422 uint32_t param;
423
424 res = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_PARAM, &param);
425 if (res == ERROR_OK) {
426 /* The PSZ field (bits 18:16) indicate the page size bytes as 2^(3+n)
427 * so 0 is 8KB and 7 is 1024KB. */
428 if (sizep)
429 *sizep = (8 << ((param >> 16) & 0x7));
430 /* The NVMP field (bits 15:0) indicates the total number of pages */
431 if (nump)
432 *nump = param & 0xFFFF;
433 } else {
434 LOG_ERROR("Couldn't read NVM Parameters register");
435 }
436
437 return res;
438 }
439
440 static int samd_probe(struct flash_bank *bank)
441 {
442 uint32_t id;
443 int res;
444 struct samd_info *chip = (struct samd_info *)bank->driver_priv;
445 const struct samd_part *part;
446
447 if (chip->probed)
448 return ERROR_OK;
449
450 res = target_read_u32(bank->target, SAMD_DSU + SAMD_DSU_DID, &id);
451 if (res != ERROR_OK) {
452 LOG_ERROR("Couldn't read Device ID register");
453 return res;
454 }
455
456 part = samd_find_part(id);
457 if (!part) {
458 LOG_ERROR("Couldn't find part corresponding to DID %08" PRIx32, id);
459 return ERROR_FAIL;
460 }
461
462 bank->size = part->flash_kb * 1024;
463
464 res = samd_get_flash_page_info(bank->target, &chip->page_size,
465 &chip->num_pages);
466 if (res != ERROR_OK) {
467 LOG_ERROR("Couldn't determine Flash page size");
468 return res;
469 }
470
471 /* Sanity check: the total flash size in the DSU should match the page size
472 * multiplied by the number of pages. */
473 if (bank->size != chip->num_pages * chip->page_size) {
474 LOG_WARNING("SAMD: bank size doesn't match NVM parameters. "
475 "Identified %" PRIu32 "KB Flash but NVMCTRL reports %u %" PRIu32 "B pages",
476 part->flash_kb, chip->num_pages, chip->page_size);
477 }
478
479 /* Erase granularity = 1 row = 4 pages */
480 chip->sector_size = chip->page_size * 4;
481
482 /* Allocate the sector table */
483 bank->num_sectors = chip->num_pages / 4;
484 bank->sectors = alloc_block_array(0, chip->sector_size, bank->num_sectors);
485 if (!bank->sectors)
486 return ERROR_FAIL;
487
488 /* 16 protection blocks per device */
489 chip->prot_block_size = bank->size / SAMD_NUM_PROT_BLOCKS;
490
491 /* Allocate the table of protection blocks */
492 bank->num_prot_blocks = SAMD_NUM_PROT_BLOCKS;
493 bank->prot_blocks = alloc_block_array(0, chip->prot_block_size, bank->num_prot_blocks);
494 if (!bank->prot_blocks)
495 return ERROR_FAIL;
496
497 samd_protect_check(bank);
498
499 /* Done */
500 chip->probed = true;
501
502 LOG_INFO("SAMD MCU: %s (%" PRIu32 "KB Flash, %" PRIu32 "KB RAM)", part->name,
503 part->flash_kb, part->ram_kb);
504
505 return ERROR_OK;
506 }
507
508 static int samd_check_error(struct target *target)
509 {
510 int ret, ret2;
511 uint16_t status;
512
513 ret = target_read_u16(target,
514 SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, &status);
515 if (ret != ERROR_OK) {
516 LOG_ERROR("Can't read NVM status");
517 return ret;
518 }
519
520 if ((status & 0x001C) == 0)
521 return ERROR_OK;
522
523 if (status & (1 << 4)) { /* NVME */
524 LOG_ERROR("SAMD: NVM Error");
525 ret = ERROR_FLASH_OPERATION_FAILED;
526 }
527
528 if (status & (1 << 3)) { /* LOCKE */
529 LOG_ERROR("SAMD: NVM lock error");
530 ret = ERROR_FLASH_PROTECTED;
531 }
532
533 if (status & (1 << 2)) { /* PROGE */
534 LOG_ERROR("SAMD: NVM programming error");
535 ret = ERROR_FLASH_OPER_UNSUPPORTED;
536 }
537
538 /* Clear the error conditions by writing a one to them */
539 ret2 = target_write_u16(target,
540 SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, status);
541 if (ret2 != ERROR_OK)
542 LOG_ERROR("Can't clear NVM error conditions");
543
544 return ret;
545 }
546
547 static int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd)
548 {
549 int res;
550
551 if (target->state != TARGET_HALTED) {
552 LOG_ERROR("Target not halted");
553 return ERROR_TARGET_NOT_HALTED;
554 }
555
556 /* Issue the NVM command */
557 res = target_write_u16(target,
558 SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLA, SAMD_NVM_CMD(cmd));
559 if (res != ERROR_OK)
560 return res;
561
562 /* Check to see if the NVM command resulted in an error condition. */
563 return samd_check_error(target);
564 }
565
566 /**
567 * Erases a flash-row at the given address.
568 * @param target Pointer to the target structure.
569 * @param address The address of the row.
570 * @return On success ERROR_OK, on failure an errorcode.
571 */
572 static int samd_erase_row(struct target *target, uint32_t address)
573 {
574 int res;
575
576 /* Set an address contained in the row to be erased */
577 res = target_write_u32(target,
578 SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR, address >> 1);
579
580 /* Issue the Erase Row command to erase that row. */
581 if (res == ERROR_OK)
582 res = samd_issue_nvmctrl_command(target,
583 address == SAMD_USER_ROW ? SAMD_NVM_CMD_EAR : SAMD_NVM_CMD_ER);
584
585 if (res != ERROR_OK) {
586 LOG_ERROR("Failed to erase row containing %08" PRIx32, address);
587 return ERROR_FAIL;
588 }
589
590 return ERROR_OK;
591 }
592
593 /**
594 * Returns the bitmask of reserved bits in register.
595 * @param target Pointer to the target structure.
596 * @param mask Bitmask, 0 -> value stays untouched.
597 * @return On success ERROR_OK, on failure an errorcode.
598 */
599 static int samd_get_reservedmask(struct target *target, uint64_t *mask)
600 {
601 int res;
602 /* Get the devicetype */
603 uint32_t id;
604 res = target_read_u32(target, SAMD_DSU + SAMD_DSU_DID, &id);
605 if (res != ERROR_OK) {
606 LOG_ERROR("Couldn't read Device ID register");
607 return res;
608 }
609 const struct samd_family *family;
610 family = samd_find_family(id);
611 if (!family) {
612 LOG_ERROR("Couldn't determine device family");
613 return ERROR_FAIL;
614 }
615 *mask = family->nvm_userrow_res_mask;
616 return ERROR_OK;
617 }
618
619 static int read_userrow(struct target *target, uint64_t *userrow)
620 {
621 int res;
622 uint8_t buffer[8];
623
624 res = target_read_memory(target, SAMD_USER_ROW, 4, 2, buffer);
625 if (res != ERROR_OK)
626 return res;
627
628 *userrow = target_buffer_get_u64(target, buffer);
629 return ERROR_OK;
630 }
631
632 /**
633 * Modify the contents of the User Row in Flash. The User Row itself
634 * has a size of one page and contains a combination of "fuses" and
635 * calibration data. Bits which have a value of zero in the mask will
636 * not be changed. Up to now devices only use the first 64 bits.
637 * @param target Pointer to the target structure.
638 * @param value_input The value to write.
639 * @param value_mask Bitmask, 0 -> value stays untouched.
640 * @return On success ERROR_OK, on failure an errorcode.
641 */
642 static int samd_modify_user_row_masked(struct target *target,
643 uint64_t value_input, uint64_t value_mask)
644 {
645 int res;
646 uint32_t nvm_ctrlb;
647 bool manual_wp = true;
648
649 /* Retrieve the MCU's page size, in bytes. This is also the size of the
650 * entire User Row. */
651 uint32_t page_size;
652 res = samd_get_flash_page_info(target, &page_size, NULL);
653 if (res != ERROR_OK) {
654 LOG_ERROR("Couldn't determine Flash page size");
655 return res;
656 }
657
658 /* Make sure the size is sane. */
659 assert(page_size <= SAMD_PAGE_SIZE_MAX &&
660 page_size >= sizeof(value_input));
661
662 uint8_t buf[SAMD_PAGE_SIZE_MAX];
663 /* Read the user row (comprising one page) by words. */
664 res = target_read_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);
665 if (res != ERROR_OK)
666 return res;
667
668 uint64_t value_device;
669 res = read_userrow(target, &value_device);
670 if (res != ERROR_OK)
671 return res;
672 uint64_t value_new = (value_input & value_mask) | (value_device & ~value_mask);
673
674 /* We will need to erase before writing if the new value needs a '1' in any
675 * position for which the current value had a '0'. Otherwise we can avoid
676 * erasing. */
677 if ((~value_device) & value_new) {
678 res = samd_erase_row(target, SAMD_USER_ROW);
679 if (res != ERROR_OK) {
680 LOG_ERROR("Couldn't erase user row");
681 return res;
682 }
683 }
684
685 /* Modify */
686 target_buffer_set_u64(target, buf, value_new);
687
688 /* Write the page buffer back out to the target. */
689 res = target_write_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);
690 if (res != ERROR_OK)
691 return res;
692
693 /* Check if we need to do manual page write commands */
694 res = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, &nvm_ctrlb);
695 if (res == ERROR_OK)
696 manual_wp = (nvm_ctrlb & SAMD_NVM_CTRLB_MANW) != 0;
697 else {
698 LOG_ERROR("Read of NVM register CTRKB failed.");
699 return ERROR_FAIL;
700 }
701 if (manual_wp) {
702 /* Trigger flash write */
703 res = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_WAP);
704 } else {
705 res = samd_check_error(target);
706 }
707
708 return res;
709 }
710
711 /**
712 * Modifies the user row register to the given value.
713 * @param target Pointer to the target structure.
714 * @param value The value to write.
715 * @param startb The bit-offset by which the given value is shifted.
716 * @param endb The bit-offset of the last bit in value to write.
717 * @return On success ERROR_OK, on failure an errorcode.
718 */
719 static int samd_modify_user_row(struct target *target, uint64_t value,
720 uint8_t startb, uint8_t endb)
721 {
722 uint64_t mask = 0;
723 int i;
724 for (i = startb ; i <= endb ; i++)
725 mask |= ((uint64_t)1) << i;
726
727 return samd_modify_user_row_masked(target, value << startb, mask);
728 }
729
730 static int samd_protect(struct flash_bank *bank, int set,
731 unsigned int first, unsigned int last)
732 {
733 int res = ERROR_OK;
734
735 /* We can issue lock/unlock region commands with the target running but
736 * the settings won't persist unless we're able to modify the LOCK regions
737 * and that requires the target to be halted. */
738 if (bank->target->state != TARGET_HALTED) {
739 LOG_ERROR("Target not halted");
740 return ERROR_TARGET_NOT_HALTED;
741 }
742
743 for (unsigned int prot_block = first; prot_block <= last; prot_block++) {
744 if (set != bank->prot_blocks[prot_block].is_protected) {
745 /* Load an address that is within this protection block (we use offset 0) */
746 res = target_write_u32(bank->target,
747 SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR,
748 bank->prot_blocks[prot_block].offset >> 1);
749 if (res != ERROR_OK)
750 goto exit;
751
752 /* Tell the controller to lock that block */
753 res = samd_issue_nvmctrl_command(bank->target,
754 set ? SAMD_NVM_CMD_LR : SAMD_NVM_CMD_UR);
755 if (res != ERROR_OK)
756 goto exit;
757 }
758 }
759
760 /* We've now applied our changes, however they will be undone by the next
761 * reset unless we also apply them to the LOCK bits in the User Page. The
762 * LOCK bits start at bit 48, corresponding to Sector 0 and end with bit 63,
763 * corresponding to Sector 15. A '1' means unlocked and a '0' means
764 * locked. See Table 9-3 in the SAMD20 datasheet for more details. */
765
766 res = samd_modify_user_row(bank->target,
767 set ? (uint64_t)0 : (uint64_t)UINT64_MAX,
768 48 + first, 48 + last);
769 if (res != ERROR_OK)
770 LOG_WARNING("SAMD: protect settings were not made persistent!");
771
772 res = ERROR_OK;
773
774 exit:
775 samd_protect_check(bank);
776
777 return res;
778 }
779
780 static int samd_erase(struct flash_bank *bank, unsigned int first,
781 unsigned int last)
782 {
783 int res;
784 struct samd_info *chip = (struct samd_info *)bank->driver_priv;
785
786 if (bank->target->state != TARGET_HALTED) {
787 LOG_ERROR("Target not halted");
788
789 return ERROR_TARGET_NOT_HALTED;
790 }
791
792 if (!chip->probed) {
793 if (samd_probe(bank) != ERROR_OK)
794 return ERROR_FLASH_BANK_NOT_PROBED;
795 }
796
797 /* For each sector to be erased */
798 for (unsigned int s = first; s <= last; s++) {
799 res = samd_erase_row(bank->target, bank->sectors[s].offset);
800 if (res != ERROR_OK) {
801 LOG_ERROR("SAMD: failed to erase sector %d at 0x%08" PRIx32, s, bank->sectors[s].offset);
802 return res;
803 }
804 }
805
806 return ERROR_OK;
807 }
808
809
810 static int samd_write(struct flash_bank *bank, const uint8_t *buffer,
811 uint32_t offset, uint32_t count)
812 {
813 int res;
814 uint32_t nvm_ctrlb;
815 uint32_t address;
816 uint32_t pg_offset;
817 uint32_t nb;
818 uint32_t nw;
819 struct samd_info *chip = (struct samd_info *)bank->driver_priv;
820 uint8_t *pb = NULL;
821 bool manual_wp;
822
823 if (bank->target->state != TARGET_HALTED) {
824 LOG_ERROR("Target not halted");
825 return ERROR_TARGET_NOT_HALTED;
826 }
827
828 if (!chip->probed) {
829 if (samd_probe(bank) != ERROR_OK)
830 return ERROR_FLASH_BANK_NOT_PROBED;
831 }
832
833 /* Check if we need to do manual page write commands */
834 res = target_read_u32(bank->target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, &nvm_ctrlb);
835
836 if (res != ERROR_OK)
837 return res;
838
839 if (nvm_ctrlb & SAMD_NVM_CTRLB_MANW)
840 manual_wp = true;
841 else
842 manual_wp = false;
843
844 res = samd_issue_nvmctrl_command(bank->target, SAMD_NVM_CMD_PBC);
845 if (res != ERROR_OK) {
846 LOG_ERROR("%s: %d", __func__, __LINE__);
847 return res;
848 }
849
850 while (count) {
851 nb = chip->page_size - offset % chip->page_size;
852 if (count < nb)
853 nb = count;
854
855 address = bank->base + offset;
856 pg_offset = offset % chip->page_size;
857
858 if (offset % 4 || (offset + nb) % 4) {
859 /* Either start or end of write is not word aligned */
860 if (!pb) {
861 pb = malloc(chip->page_size);
862 if (!pb)
863 return ERROR_FAIL;
864 }
865
866 /* Set temporary page buffer to 0xff and overwrite the relevant part */
867 memset(pb, 0xff, chip->page_size);
868 memcpy(pb + pg_offset, buffer, nb);
869
870 /* Align start address to a word boundary */
871 address -= offset % 4;
872 pg_offset -= offset % 4;
873 assert(pg_offset % 4 == 0);
874
875 /* Extend length to whole words */
876 nw = (nb + offset % 4 + 3) / 4;
877 assert(pg_offset + 4 * nw <= chip->page_size);
878
879 /* Now we have original data extended by 0xff bytes
880 * to the nearest word boundary on both start and end */
881 res = target_write_memory(bank->target, address, 4, nw, pb + pg_offset);
882 } else {
883 assert(nb % 4 == 0);
884 nw = nb / 4;
885 assert(pg_offset + 4 * nw <= chip->page_size);
886
887 /* Word aligned data, use direct write from buffer */
888 res = target_write_memory(bank->target, address, 4, nw, buffer);
889 }
890 if (res != ERROR_OK) {
891 LOG_ERROR("%s: %d", __func__, __LINE__);
892 goto free_pb;
893 }
894
895 /* Devices with errata 13134 have automatic page write enabled by default
896 * For other devices issue a write page CMD to the NVM
897 * If the page has not been written up to the last word
898 * then issue CMD_WP always */
899 if (manual_wp || pg_offset + 4 * nw < chip->page_size) {
900 res = samd_issue_nvmctrl_command(bank->target, SAMD_NVM_CMD_WP);
901 } else {
902 /* Access through AHB is stalled while flash is being programmed */
903 usleep(200);
904
905 res = samd_check_error(bank->target);
906 }
907
908 if (res != ERROR_OK) {
909 LOG_ERROR("%s: write failed at address 0x%08" PRIx32, __func__, address);
910 goto free_pb;
911 }
912
913 /* We're done with the page contents */
914 count -= nb;
915 offset += nb;
916 buffer += nb;
917 }
918
919 free_pb:
920 free(pb);
921 return res;
922 }
923
924 FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command)
925 {
926 if (bank->base != SAMD_FLASH) {
927 LOG_ERROR("Address " TARGET_ADDR_FMT
928 " invalid bank address (try 0x%08" PRIx32
929 "[at91samd series] )",
930 bank->base, SAMD_FLASH);
931 return ERROR_FAIL;
932 }
933
934 struct samd_info *chip;
935 chip = calloc(1, sizeof(*chip));
936 if (!chip) {
937 LOG_ERROR("No memory for flash bank chip info");
938 return ERROR_FAIL;
939 }
940
941 chip->target = bank->target;
942 chip->probed = false;
943
944 bank->driver_priv = chip;
945
946 return ERROR_OK;
947 }
948
949 COMMAND_HANDLER(samd_handle_chip_erase_command)
950 {
951 struct target *target = get_current_target(CMD_CTX);
952 int res = ERROR_FAIL;
953
954 if (target) {
955 /* Enable access to the DSU by disabling the write protect bit */
956 target_write_u32(target, SAMD_PAC1, (1<<1));
957 /* intentionally without error checking - not accessible on secured chip */
958
959 /* Tell the DSU to perform a full chip erase. It takes about 240ms to
960 * perform the erase. */
961 res = target_write_u8(target, SAMD_DSU + SAMD_DSU_CTRL_EXT, (1<<4));
962 if (res == ERROR_OK)
963 command_print(CMD, "chip erase started");
964 else
965 command_print(CMD, "write to DSU CTRL failed");
966 }
967
968 return res;
969 }
970
971 COMMAND_HANDLER(samd_handle_set_security_command)
972 {
973 int res = ERROR_OK;
974 struct target *target = get_current_target(CMD_CTX);
975
976 if (CMD_ARGC < 1 || (CMD_ARGC >= 1 && (strcmp(CMD_ARGV[0], "enable")))) {
977 command_print(CMD, "supply the \"enable\" argument to proceed.");
978 return ERROR_COMMAND_SYNTAX_ERROR;
979 }
980
981 if (target) {
982 if (target->state != TARGET_HALTED) {
983 LOG_ERROR("Target not halted");
984 return ERROR_TARGET_NOT_HALTED;
985 }
986
987 res = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_SSB);
988
989 /* Check (and clear) error conditions */
990 if (res == ERROR_OK)
991 command_print(CMD, "chip secured on next power-cycle");
992 else
993 command_print(CMD, "failed to secure chip");
994 }
995
996 return res;
997 }
998
999 COMMAND_HANDLER(samd_handle_eeprom_command)
1000 {
1001 int res = ERROR_OK;
1002 struct target *target = get_current_target(CMD_CTX);
1003
1004 if (target) {
1005 if (target->state != TARGET_HALTED) {
1006 LOG_ERROR("Target not halted");
1007 return ERROR_TARGET_NOT_HALTED;
1008 }
1009
1010 if (CMD_ARGC >= 1) {
1011 int val = atoi(CMD_ARGV[0]);
1012 uint32_t code;
1013
1014 if (val == 0)
1015 code = 7;
1016 else {
1017 /* Try to match size in bytes with corresponding size code */
1018 for (code = 0; code <= 6; code++) {
1019 if (val == (2 << (13 - code)))
1020 break;
1021 }
1022
1023 if (code > 6) {
1024 command_print(CMD, "Invalid EEPROM size. Please see "
1025 "datasheet for a list valid sizes.");
1026 return ERROR_COMMAND_SYNTAX_ERROR;
1027 }
1028 }
1029
1030 res = samd_modify_user_row(target, code, 4, 6);
1031 } else {
1032 uint16_t val;
1033 res = target_read_u16(target, SAMD_USER_ROW, &val);
1034 if (res == ERROR_OK) {
1035 uint32_t size = ((val >> 4) & 0x7); /* grab size code */
1036
1037 if (size == 0x7)
1038 command_print(CMD, "EEPROM is disabled");
1039 else {
1040 /* Otherwise, 6 is 256B, 0 is 16KB */
1041 command_print(CMD, "EEPROM size is %u bytes",
1042 (2 << (13 - size)));
1043 }
1044 }
1045 }
1046 }
1047
1048 return res;
1049 }
1050
1051 COMMAND_HANDLER(samd_handle_nvmuserrow_command)
1052 {
1053 int res = ERROR_OK;
1054 struct target *target = get_current_target(CMD_CTX);
1055
1056 if (target) {
1057 if (CMD_ARGC > 2) {
1058 command_print(CMD, "Too much Arguments given.");
1059 return ERROR_COMMAND_SYNTAX_ERROR;
1060 }
1061
1062 if (CMD_ARGC > 0) {
1063 if (target->state != TARGET_HALTED) {
1064 LOG_ERROR("Target not halted.");
1065 return ERROR_TARGET_NOT_HALTED;
1066 }
1067
1068 uint64_t mask;
1069 res = samd_get_reservedmask(target, &mask);
1070 if (res != ERROR_OK) {
1071 LOG_ERROR("Couldn't determine the mask for reserved bits.");
1072 return ERROR_FAIL;
1073 }
1074 mask &= NVMUSERROW_LOCKBIT_MASK;
1075
1076 uint64_t value;
1077 COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], value);
1078
1079 if (CMD_ARGC == 2) {
1080 uint64_t mask_temp;
1081 COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], mask_temp);
1082
1083 mask &= mask_temp;
1084 }
1085 res = samd_modify_user_row_masked(target, value, mask);
1086 if (res != ERROR_OK)
1087 return res;
1088 }
1089
1090 /* read register */
1091 uint64_t value;
1092 res = read_userrow(target, &value);
1093 if (res == ERROR_OK)
1094 command_print(CMD, "NVMUSERROW: 0x%016"PRIX64, value);
1095 else
1096 LOG_ERROR("NVMUSERROW could not be read.");
1097 }
1098 return res;
1099 }
1100
1101 COMMAND_HANDLER(samd_handle_bootloader_command)
1102 {
1103 int res = ERROR_OK;
1104 struct target *target = get_current_target(CMD_CTX);
1105
1106 if (target) {
1107 if (target->state != TARGET_HALTED) {
1108 LOG_ERROR("Target not halted");
1109 return ERROR_TARGET_NOT_HALTED;
1110 }
1111
1112 /* Retrieve the MCU's page size, in bytes. */
1113 uint32_t page_size;
1114 res = samd_get_flash_page_info(target, &page_size, NULL);
1115 if (res != ERROR_OK) {
1116 LOG_ERROR("Couldn't determine Flash page size");
1117 return res;
1118 }
1119
1120 if (CMD_ARGC >= 1) {
1121 int val = atoi(CMD_ARGV[0]);
1122 uint32_t code;
1123
1124 if (val == 0)
1125 code = 7;
1126 else {
1127 /* Try to match size in bytes with corresponding size code */
1128 for (code = 0; code <= 6; code++) {
1129 if ((unsigned int)val == (2UL << (8UL - code)) * page_size)
1130 break;
1131 }
1132
1133 if (code > 6) {
1134 command_print(CMD, "Invalid bootloader size. Please "
1135 "see datasheet for a list valid sizes.");
1136 return ERROR_COMMAND_SYNTAX_ERROR;
1137 }
1138
1139 }
1140
1141 res = samd_modify_user_row(target, code, 0, 2);
1142 } else {
1143 uint16_t val;
1144 res = target_read_u16(target, SAMD_USER_ROW, &val);
1145 if (res == ERROR_OK) {
1146 uint32_t size = (val & 0x7); /* grab size code */
1147 uint32_t nb;
1148
1149 if (size == 0x7)
1150 nb = 0;
1151 else
1152 nb = (2 << (8 - size)) * page_size;
1153
1154 /* There are 4 pages per row */
1155 command_print(CMD, "Bootloader size is %" PRIu32 " bytes (%" PRIu32 " rows)",
1156 nb, (uint32_t)(nb / (page_size * 4)));
1157 }
1158 }
1159 }
1160
1161 return res;
1162 }
1163
1164
1165
1166 COMMAND_HANDLER(samd_handle_reset_deassert)
1167 {
1168 struct target *target = get_current_target(CMD_CTX);
1169 int retval = ERROR_OK;
1170 enum reset_types jtag_reset_config = jtag_get_reset_config();
1171
1172 /* If the target has been unresponsive before, try to re-establish
1173 * communication now - CPU is held in reset by DSU, DAP is working */
1174 if (!target_was_examined(target))
1175 target_examine_one(target);
1176 target_poll(target);
1177
1178 /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
1179 * so we just release reset held by DSU
1180 *
1181 * n_RESET (srst) clears the DP, so reenable debug and set vector catch here
1182 *
1183 * After vectreset DSU release is not needed however makes no harm
1184 */
1185 if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
1186 retval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
1187 if (retval == ERROR_OK)
1188 retval = target_write_u32(target, DCB_DEMCR,
1189 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
1190 /* do not return on error here, releasing DSU reset is more important */
1191 }
1192
1193 /* clear CPU Reset Phase Extension bit */
1194 int retval2 = target_write_u8(target, SAMD_DSU + SAMD_DSU_STATUSA, (1<<1));
1195 if (retval2 != ERROR_OK)
1196 return retval2;
1197
1198 return retval;
1199 }
1200
1201 static const struct command_registration at91samd_exec_command_handlers[] = {
1202 {
1203 .name = "dsu_reset_deassert",
1204 .handler = samd_handle_reset_deassert,
1205 .mode = COMMAND_EXEC,
1206 .help = "Deassert internal reset held by DSU.",
1207 .usage = "",
1208 },
1209 {
1210 .name = "chip-erase",
1211 .handler = samd_handle_chip_erase_command,
1212 .mode = COMMAND_EXEC,
1213 .help = "Erase the entire Flash by using the Chip-"
1214 "Erase feature in the Device Service Unit (DSU).",
1215 .usage = "",
1216 },
1217 {
1218 .name = "set-security",
1219 .handler = samd_handle_set_security_command,
1220 .mode = COMMAND_EXEC,
1221 .help = "Secure the chip's Flash by setting the Security Bit. "
1222 "This makes it impossible to read the Flash contents. "
1223 "The only way to undo this is to issue the chip-erase "
1224 "command.",
1225 .usage = "'enable'",
1226 },
1227 {
1228 .name = "eeprom",
1229 .usage = "[size_in_bytes]",
1230 .handler = samd_handle_eeprom_command,
1231 .mode = COMMAND_EXEC,
1232 .help = "Show or set the EEPROM size setting, stored in the User Row. "
1233 "Please see Table 20-3 of the SAMD20 datasheet for allowed values. "
1234 "Changes are stored immediately but take affect after the MCU is "
1235 "reset.",
1236 },
1237 {
1238 .name = "bootloader",
1239 .usage = "[size_in_bytes]",
1240 .handler = samd_handle_bootloader_command,
1241 .mode = COMMAND_EXEC,
1242 .help = "Show or set the bootloader size, stored in the User Row. "
1243 "Please see Table 20-2 of the SAMD20 datasheet for allowed values. "
1244 "Changes are stored immediately but take affect after the MCU is "
1245 "reset.",
1246 },
1247 {
1248 .name = "nvmuserrow",
1249 .usage = "[value] [mask]",
1250 .handler = samd_handle_nvmuserrow_command,
1251 .mode = COMMAND_EXEC,
1252 .help = "Show or set the nvmuserrow register. It is 64 bit wide "
1253 "and located at address 0x804000. Use the optional mask argument "
1254 "to prevent changes at positions where the bitvalue is zero. "
1255 "For security reasons the lock- and reserved-bits are masked out "
1256 "in background and therefore cannot be changed.",
1257 },
1258 COMMAND_REGISTRATION_DONE
1259 };
1260
1261 static const struct command_registration at91samd_command_handlers[] = {
1262 {
1263 .name = "at91samd",
1264 .mode = COMMAND_ANY,
1265 .help = "at91samd flash command group",
1266 .usage = "",
1267 .chain = at91samd_exec_command_handlers,
1268 },
1269 COMMAND_REGISTRATION_DONE
1270 };
1271
1272 const struct flash_driver at91samd_flash = {
1273 .name = "at91samd",
1274 .commands = at91samd_command_handlers,
1275 .flash_bank_command = samd_flash_bank_command,
1276 .erase = samd_erase,
1277 .protect = samd_protect,
1278 .write = samd_write,
1279 .read = default_flash_read,
1280 .probe = samd_probe,
1281 .auto_probe = samd_probe,
1282 .erase_check = default_flash_blank_check,
1283 .protect_check = samd_protect_check,
1284 .free_driver_priv = default_flash_free_driver_priv,
1285 };

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)