NOR: cleanup driver decls
[openocd.git] / src / flash / nor / pic32mx.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2008 by John McCarthy *
9 * jgmcc@magma.ca *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "imp.h"
31 #include "pic32mx.h"
32 #include <target/mips32.h>
33
34
35 static
36 struct pic32mx_devs_s {
37 uint8_t devid;
38 char *name;
39 uint32_t pfm_size;
40 } pic32mx_devs[] = {
41 { 0x78, "460F512L USB", 512 },
42 { 0x74, "460F256L USB", 256 },
43 { 0x6D, "440F128L USB", 128 },
44 { 0x56, "440F512H USB", 512 },
45 { 0x52, "440F256H USB", 256 },
46 { 0x4D, "440F128H USB", 128 },
47 { 0x42, "420F032H USB", 32 },
48 { 0x38, "360F512L", 512 },
49 { 0x34, "360F256L", 256 },
50 { 0x2D, "340F128L", 128 },
51 { 0x2A, "320F128L", 128 },
52 { 0x16, "340F512H", 512 },
53 { 0x12, "340F256H", 256 },
54 { 0x0D, "340F128H", 128 },
55 { 0x0A, "320F128H", 128 },
56 { 0x06, "320F064H", 64 },
57 { 0x02, "320F032H", 32 },
58 { 0x00, NULL, 0 }
59 };
60
61 static int pic32mx_write_row(struct flash_bank *bank, uint32_t address, uint32_t srcaddr);
62 static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word);
63
64 /* flash bank pic32mx <base> <size> 0 0 <target#>
65 */
66 FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
67 {
68 struct pic32mx_flash_bank *pic32mx_info;
69
70 if (CMD_ARGC < 6)
71 {
72 LOG_WARNING("incomplete flash_bank pic32mx configuration");
73 return ERROR_FLASH_BANK_INVALID;
74 }
75
76 pic32mx_info = malloc(sizeof(struct pic32mx_flash_bank));
77 bank->driver_priv = pic32mx_info;
78
79 pic32mx_info->write_algorithm = NULL;
80 pic32mx_info->probed = 0;
81
82 return ERROR_OK;
83 }
84
85 static uint32_t pic32mx_get_flash_status(struct flash_bank *bank)
86 {
87 struct target *target = bank->target;
88 uint32_t status;
89
90 target_read_u32(target, PIC32MX_NVMCON, &status);
91
92 return status;
93 }
94
95 static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)
96 {
97 uint32_t status;
98
99 /* wait for busy to clear */
100 while (((status = pic32mx_get_flash_status(bank)) & NVMCON_NVMWR) && (timeout-- > 0))
101 {
102 LOG_DEBUG("status: 0x%" PRIx32, status);
103 alive_sleep(1);
104 }
105 if (timeout <= 0)
106 LOG_DEBUG("timeout: status: 0x%" PRIx32, status);
107
108 return status;
109 }
110
111 static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)
112 {
113 struct target *target = bank->target;
114 uint32_t status;
115
116 target_write_u32(target, PIC32MX_NVMCON, NVMCON_NVMWREN | op);
117
118 /* unlock flash registers */
119 target_write_u32(target, PIC32MX_NVMKEY, NVMKEY1);
120 target_write_u32(target, PIC32MX_NVMKEY, NVMKEY2);
121
122 /* start operation */
123 target_write_u32(target, PIC32MX_NVMCONSET, NVMCON_NVMWR);
124
125 status = pic32mx_wait_status_busy(bank, timeout);
126
127 /* lock flash registers */
128 target_write_u32(target, PIC32MX_NVMCONCLR, NVMCON_NVMWREN);
129
130 return status;
131 }
132
133 static int pic32mx_protect_check(struct flash_bank *bank)
134 {
135 struct target *target = bank->target;
136
137 uint32_t devcfg0;
138 int s;
139 int num_pages;
140
141 if (target->state != TARGET_HALTED)
142 {
143 LOG_ERROR("Target not halted");
144 return ERROR_TARGET_NOT_HALTED;
145 }
146
147 target_read_u32(target, PIC32MX_DEVCFG0, &devcfg0);
148 if ((devcfg0 & (1 << 28)) == 0) /* code protect bit */
149 num_pages = 0xffff; /* All pages protected */
150 else if (bank->base == PIC32MX_KSEG1_BOOT_FLASH)
151 {
152 if (devcfg0 & (1 << 24))
153 num_pages = 0; /* All pages unprotected */
154 else
155 num_pages = 0xffff; /* All pages protected */
156 }
157 else /* pgm flash */
158 num_pages = (~devcfg0 >> 12) & 0xff;
159 for (s = 0; s < bank->num_sectors && s < num_pages; s++)
160 bank->sectors[s].is_protected = 1;
161 for (; s < bank->num_sectors; s++)
162 bank->sectors[s].is_protected = 0;
163
164 return ERROR_OK;
165 }
166
167 static int pic32mx_erase(struct flash_bank *bank, int first, int last)
168 {
169 struct target *target = bank->target;
170 int i;
171 uint32_t status;
172
173 if (bank->target->state != TARGET_HALTED)
174 {
175 LOG_ERROR("Target not halted");
176 return ERROR_TARGET_NOT_HALTED;
177 }
178
179 if ((first == 0) && (last == (bank->num_sectors - 1)) && (bank->base == PIC32MX_KSEG0_PGM_FLASH || bank->base == PIC32MX_KSEG1_PGM_FLASH))
180 {
181 LOG_DEBUG("Erasing entire program flash");
182 status = pic32mx_nvm_exec(bank, NVMCON_OP_PFM_ERASE, 50);
183 if (status & NVMCON_NVMERR)
184 return ERROR_FLASH_OPERATION_FAILED;
185 if (status & NVMCON_LVDERR)
186 return ERROR_FLASH_OPERATION_FAILED;
187 return ERROR_OK;
188 }
189
190 for (i = first; i <= last; i++)
191 {
192 if (bank->base >= PIC32MX_KSEG1_PGM_FLASH)
193 target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(bank->base + bank->sectors[i].offset));
194 else
195 target_write_u32(target, PIC32MX_NVMADDR, KS0Virt2Phys(bank->base + bank->sectors[i].offset));
196
197 status = pic32mx_nvm_exec(bank, NVMCON_OP_PAGE_ERASE, 10);
198
199 if (status & NVMCON_NVMERR)
200 return ERROR_FLASH_OPERATION_FAILED;
201 if (status & NVMCON_LVDERR)
202 return ERROR_FLASH_OPERATION_FAILED;
203 bank->sectors[i].is_erased = 1;
204 }
205
206 return ERROR_OK;
207 }
208
209 static int pic32mx_protect(struct flash_bank *bank, int set, int first, int last)
210 {
211 struct pic32mx_flash_bank *pic32mx_info = NULL;
212 struct target *target = bank->target;
213 #if 0
214 uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
215 int i, reg, bit;
216 int status;
217 uint32_t protection;
218 #endif
219
220 pic32mx_info = bank->driver_priv;
221
222 if (target->state != TARGET_HALTED)
223 {
224 LOG_ERROR("Target not halted");
225 return ERROR_TARGET_NOT_HALTED;
226 }
227
228 #if 0
229 if ((first && (first % pic32mx_info->ppage_size)) || ((last + 1) && (last + 1) % pic32mx_info->ppage_size))
230 {
231 LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", pic32mx_info->ppage_size);
232 return ERROR_FLASH_SECTOR_INVALID;
233 }
234
235 /* medium density - each bit refers to a 4bank protection
236 * high density - each bit refers to a 2bank protection */
237 target_read_u32(target, PIC32MX_FLASH_WRPR, &protection);
238
239 prot_reg[0] = (uint16_t)protection;
240 prot_reg[1] = (uint16_t)(protection >> 8);
241 prot_reg[2] = (uint16_t)(protection >> 16);
242 prot_reg[3] = (uint16_t)(protection >> 24);
243
244 if (pic32mx_info->ppage_size == 2)
245 {
246 /* high density flash */
247
248 /* bit 7 controls sector 62 - 255 protection */
249 if (last > 61)
250 {
251 if (set)
252 prot_reg[3] &= ~(1 << 7);
253 else
254 prot_reg[3] |= (1 << 7);
255 }
256
257 if (first > 61)
258 first = 62;
259 if (last > 61)
260 last = 61;
261
262 for (i = first; i <= last; i++)
263 {
264 reg = (i / pic32mx_info->ppage_size) / 8;
265 bit = (i / pic32mx_info->ppage_size) - (reg * 8);
266
267 if (set)
268 prot_reg[reg] &= ~(1 << bit);
269 else
270 prot_reg[reg] |= (1 << bit);
271 }
272 }
273 else
274 {
275 /* medium density flash */
276 for (i = first; i <= last; i++)
277 {
278 reg = (i / pic32mx_info->ppage_size) / 8;
279 bit = (i / pic32mx_info->ppage_size) - (reg * 8);
280
281 if (set)
282 prot_reg[reg] &= ~(1 << bit);
283 else
284 prot_reg[reg] |= (1 << bit);
285 }
286 }
287
288 if ((status = pic32mx_erase_options(bank)) != ERROR_OK)
289 return status;
290
291 pic32mx_info->option_bytes.protection[0] = prot_reg[0];
292 pic32mx_info->option_bytes.protection[1] = prot_reg[1];
293 pic32mx_info->option_bytes.protection[2] = prot_reg[2];
294 pic32mx_info->option_bytes.protection[3] = prot_reg[3];
295
296 return pic32mx_write_options(bank);
297 #else
298 return ERROR_OK;
299 #endif
300 }
301
302 static int pic32mx_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
303 {
304 struct target *target = bank->target;
305 uint32_t buffer_size = 512;
306 struct working_area *source;
307 uint32_t address = bank->base + offset;
308 int retval = ERROR_OK;
309 #if 0
310 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
311 struct armv7m_algorithm armv7m_info;
312
313 uint8_t pic32mx_flash_write_code[] = {
314 /* write: */
315 0xDF, 0xF8, 0x24, 0x40, /* ldr r4, PIC32MX_FLASH_CR */
316 0x09, 0x4D, /* ldr r5, PIC32MX_FLASH_SR */
317 0x4F, 0xF0, 0x01, 0x03, /* mov r3, #1 */
318 0x23, 0x60, /* str r3, [r4, #0] */
319 0x30, 0xF8, 0x02, 0x3B, /* ldrh r3, [r0], #2 */
320 0x21, 0xF8, 0x02, 0x3B, /* strh r3, [r1], #2 */
321 /* busy: */
322 0x2B, 0x68, /* ldr r3, [r5, #0] */
323 0x13, 0xF0, 0x01, 0x0F, /* tst r3, #0x01 */
324 0xFB, 0xD0, /* beq busy */
325 0x13, 0xF0, 0x14, 0x0F, /* tst r3, #0x14 */
326 0x01, 0xD1, /* bne exit */
327 0x01, 0x3A, /* subs r2, r2, #1 */
328 0xED, 0xD1, /* bne write */
329 /* exit: */
330 0xFE, 0xE7, /* b exit */
331 0x10, 0x20, 0x02, 0x40, /* PIC32MX_FLASH_CR: .word 0x40022010 */
332 0x0C, 0x20, 0x02, 0x40 /* PIC32MX_FLASH_SR: .word 0x4002200C */
333 };
334
335 /* flash write code */
336 if (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code), &pic32mx_info->write_algorithm) != ERROR_OK)
337 {
338 LOG_WARNING("no working area available, can't do block memory writes");
339 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
340 };
341
342 if ((retval = target_write_buffer(target, pic32mx_info->write_algorithm->address, sizeof(pic32mx_flash_write_code), pic32mx_flash_write_code)) != ERROR_OK)
343 return retval;
344 #endif
345
346 /* memory buffer */
347 if (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
348 {
349 #if 0
350 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
351 if (pic32mx_info->write_algorithm)
352 target_free_working_area(target, pic32mx_info->write_algorithm);
353 #endif
354
355 LOG_WARNING("no large enough working area available, can't do block memory writes");
356 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
357 }
358
359 while (count >= buffer_size/4)
360 {
361 uint32_t status;
362
363 if ((retval = target_write_buffer(target, source->address, buffer_size, buffer)) != ERROR_OK) {
364 LOG_ERROR("Failed to write row buffer (%d words) to RAM", (int)(buffer_size/4));
365 break;
366 }
367
368 #if 0
369 buf_set_u32(reg_params[0].value, 0, 32, source->address);
370 buf_set_u32(reg_params[1].value, 0, 32, address);
371 buf_set_u32(reg_params[2].value, 0, 32, buffer_size/4);
372
373 if ((retval = target_run_algorithm(target, 0, NULL, 4, reg_params, pic32mx_info->write_algorithm->address, \
374 pic32mx_info->write_algorithm->address + (sizeof(pic32mx_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK)
375 {
376 LOG_ERROR("error executing pic32mx flash write algorithm");
377 retval = ERROR_FLASH_OPERATION_FAILED;
378 break;
379 }
380
381 if (buf_get_u32(reg_params[3].value, 0, 32) & 0x14)
382 {
383 retval = ERROR_FLASH_OPERATION_FAILED;
384 break;
385 }
386 #endif
387 status = pic32mx_write_row(bank, address, source->address);
388 if (status & NVMCON_NVMERR) {
389 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
390 retval = ERROR_FLASH_OPERATION_FAILED;
391 break;
392 }
393 if (status & NVMCON_LVDERR) {
394 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
395 retval = ERROR_FLASH_OPERATION_FAILED;
396 break;
397 }
398
399 buffer += buffer_size;
400 address += buffer_size;
401 count -= buffer_size/4;
402 }
403
404 target_free_working_area(target, source);
405
406 while (count > 0)
407 {
408 uint32_t value;
409 memcpy(&value, buffer, sizeof(uint32_t));
410
411 uint32_t status = pic32mx_write_word(bank, address, value);
412 if (status & NVMCON_NVMERR) {
413 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
414 retval = ERROR_FLASH_OPERATION_FAILED;
415 break;
416 }
417 if (status & NVMCON_LVDERR) {
418 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
419 retval = ERROR_FLASH_OPERATION_FAILED;
420 break;
421 }
422
423 buffer += 4;
424 address += 4;
425 count--;
426 }
427
428 return retval;
429 }
430
431 static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)
432 {
433 struct target *target = bank->target;
434
435 if (bank->base >= PIC32MX_KSEG1_PGM_FLASH)
436 target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(address));
437 else
438 target_write_u32(target, PIC32MX_NVMADDR, KS0Virt2Phys(address));
439 target_write_u32(target, PIC32MX_NVMDATA, word);
440
441 return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);
442 }
443
444 /*
445 * Write a 128 word (512 byte) row to flash address from RAM srcaddr.
446 */
447 static int pic32mx_write_row(struct flash_bank *bank, uint32_t address, uint32_t srcaddr)
448 {
449 struct target *target = bank->target;
450
451 LOG_DEBUG("addr: 0x%08" PRIx32 " srcaddr: 0x%08" PRIx32 "", address, srcaddr);
452
453 if (address >= PIC32MX_KSEG1_PGM_FLASH)
454 target_write_u32(target, PIC32MX_NVMADDR, KS1Virt2Phys(address));
455 else
456 target_write_u32(target, PIC32MX_NVMADDR, KS0Virt2Phys(address));
457 if (srcaddr >= PIC32MX_KSEG1_RAM)
458 target_write_u32(target, PIC32MX_NVMSRCADDR, KS1Virt2Phys(srcaddr));
459 else
460 target_write_u32(target, PIC32MX_NVMSRCADDR, KS0Virt2Phys(srcaddr));
461
462 return pic32mx_nvm_exec(bank, NVMCON_OP_ROW_PROG, 100);
463 }
464
465 static int pic32mx_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
466 {
467 uint32_t words_remaining = (count / 4);
468 uint32_t bytes_remaining = (count & 0x00000003);
469 uint32_t address = bank->base + offset;
470 uint32_t bytes_written = 0;
471 uint32_t status;
472 int retval;
473
474 if (bank->target->state != TARGET_HALTED)
475 {
476 LOG_ERROR("Target not halted");
477 return ERROR_TARGET_NOT_HALTED;
478 }
479
480 if (offset & 0x3)
481 {
482 LOG_WARNING("offset 0x%" PRIx32 "breaks required 4-byte alignment", offset);
483 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
484 }
485
486 /* multiple words (4-byte) to be programmed? */
487 if (words_remaining > 0)
488 {
489 /* try using a block write */
490 if ((retval = pic32mx_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
491 {
492 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
493 {
494 /* if block write failed (no sufficient working area),
495 * we use normal (slow) single dword accesses */
496 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
497 }
498 else if (retval == ERROR_FLASH_OPERATION_FAILED)
499 {
500 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
501 return ERROR_FLASH_OPERATION_FAILED;
502 }
503 }
504 else
505 {
506 buffer += words_remaining * 4;
507 address += words_remaining * 4;
508 words_remaining = 0;
509 }
510 }
511
512 while (words_remaining > 0)
513 {
514 uint32_t value;
515 memcpy(&value, buffer + bytes_written, sizeof(uint32_t));
516
517 status = pic32mx_write_word(bank, address, value);
518 if (status & NVMCON_NVMERR)
519 return ERROR_FLASH_OPERATION_FAILED;
520 if (status & NVMCON_LVDERR)
521 return ERROR_FLASH_OPERATION_FAILED;
522
523 bytes_written += 4;
524 words_remaining--;
525 address += 4;
526 }
527
528 if (bytes_remaining)
529 {
530 uint32_t value = 0xffffffff;
531 memcpy(&value, buffer + bytes_written, bytes_remaining);
532
533 status = pic32mx_write_word(bank, address, value);
534 if (status & NVMCON_NVMERR)
535 return ERROR_FLASH_OPERATION_FAILED;
536 if (status & NVMCON_LVDERR)
537 return ERROR_FLASH_OPERATION_FAILED;
538 }
539
540 return ERROR_OK;
541 }
542
543 static int pic32mx_probe(struct flash_bank *bank)
544 {
545 struct target *target = bank->target;
546 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
547 struct mips32_common *mips32 = target->arch_info;
548 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
549 int i;
550 uint16_t num_pages = 0;
551 uint32_t device_id;
552 int page_size;
553
554 pic32mx_info->probed = 0;
555
556 device_id = ejtag_info->idcode;
557 LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%02x, ver 0x%03x)",
558 device_id,
559 (unsigned)((device_id >> 1)&0x7ff),
560 (unsigned)((device_id >> 12)&0xff),
561 (unsigned)((device_id >> 20)&0xfff));
562
563 if (((device_id >> 1)&0x7ff) != PIC32MX_MANUF_ID) {
564 LOG_WARNING("Cannot identify target as a PIC32MX family.");
565 return ERROR_FLASH_OPERATION_FAILED;
566 }
567
568 page_size = 4096;
569 if (bank->base == PIC32MX_KSEG1_BOOT_FLASH || bank->base == 1) {
570 /* 0xBFC00000: Boot flash size fixed at 12k */
571 num_pages = 12;
572 } else {
573 /* 0xBD000000: Program flash size varies with device */
574 for (i = 0; pic32mx_devs[i].name != NULL; i++)
575 if (pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
576 num_pages = pic32mx_devs[i].pfm_size;
577 break;
578 }
579 if (pic32mx_devs[i].name == NULL) {
580 LOG_WARNING("Cannot identify target as a PIC32MX family.");
581 return ERROR_FLASH_OPERATION_FAILED;
582 }
583 }
584
585 #if 0
586 if (bank->target->state != TARGET_HALTED)
587 {
588 LOG_ERROR("Target not halted");
589 return ERROR_TARGET_NOT_HALTED;
590 }
591
592 /* get flash size from target */
593 if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK)
594 {
595 /* failed reading flash size, default to max target family */
596 num_pages = 0xffff;
597 }
598 #endif
599
600 LOG_INFO("flash size = %dkbytes", num_pages);
601
602 /* calculate numbers of pages */
603 num_pages /= (page_size / 1024);
604
605 if (bank->base == 0) bank->base = PIC32MX_KSEG1_PGM_FLASH;
606 if (bank->base == 1) bank->base = PIC32MX_KSEG1_BOOT_FLASH;
607 bank->size = (num_pages * page_size);
608 bank->num_sectors = num_pages;
609 bank->chip_width = 4;
610 bank->bus_width = 4;
611 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
612
613 for (i = 0; i < num_pages; i++)
614 {
615 bank->sectors[i].offset = i * page_size;
616 bank->sectors[i].size = page_size;
617 bank->sectors[i].is_erased = -1;
618 bank->sectors[i].is_protected = 1;
619 }
620
621 pic32mx_info->probed = 1;
622
623 return ERROR_OK;
624 }
625
626 static int pic32mx_auto_probe(struct flash_bank *bank)
627 {
628 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
629 if (pic32mx_info->probed)
630 return ERROR_OK;
631 return pic32mx_probe(bank);
632 }
633
634 #if 0
635 COMMAND_HANDLER(pic32mx_handle_part_id_command)
636 {
637 return ERROR_OK;
638 }
639 #endif
640
641 static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size)
642 {
643 struct target *target = bank->target;
644 struct mips32_common *mips32 = target->arch_info;
645 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
646 uint32_t device_id;
647 int printed = 0, i;
648
649 device_id = ejtag_info->idcode;
650
651 if (((device_id >> 1)&0x7ff) != PIC32MX_MANUF_ID) {
652 snprintf(buf, buf_size,
653 "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n",
654 (unsigned)((device_id >> 1)&0x7ff),
655 PIC32MX_MANUF_ID);
656 return ERROR_FLASH_OPERATION_FAILED;
657 }
658 for (i = 0; pic32mx_devs[i].name != NULL; i++)
659 if (pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
660 printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
661 break;
662 }
663 if (pic32mx_devs[i].name == NULL) {
664 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family\n");
665 return ERROR_FLASH_OPERATION_FAILED;
666 }
667 buf += printed;
668 buf_size -= printed;
669 printed = snprintf(buf, buf_size, " Ver: 0x%03x",
670 (unsigned)((device_id >> 20)&0xfff));
671
672 return ERROR_OK;
673 }
674
675 #if 0
676 COMMAND_HANDLER(pic32mx_handle_lock_command)
677 {
678 struct target *target = NULL;
679 struct pic32mx_flash_bank *pic32mx_info = NULL;
680
681 if (CMD_ARGC < 1)
682 {
683 command_print(CMD_CTX, "pic32mx lock <bank>");
684 return ERROR_OK;
685 }
686
687 struct flash_bank *bank;
688 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
689 if (ERROR_OK != retval)
690 return retval;
691
692 pic32mx_info = bank->driver_priv;
693
694 target = bank->target;
695
696 if (target->state != TARGET_HALTED)
697 {
698 LOG_ERROR("Target not halted");
699 return ERROR_TARGET_NOT_HALTED;
700 }
701
702 if (pic32mx_erase_options(bank) != ERROR_OK)
703 {
704 command_print(CMD_CTX, "pic32mx failed to erase options");
705 return ERROR_OK;
706 }
707
708 /* set readout protection */
709 pic32mx_info->option_bytes.RDP = 0;
710
711 if (pic32mx_write_options(bank) != ERROR_OK)
712 {
713 command_print(CMD_CTX, "pic32mx failed to lock device");
714 return ERROR_OK;
715 }
716
717 command_print(CMD_CTX, "pic32mx locked");
718
719 return ERROR_OK;
720 }
721
722 COMMAND_HANDLER(pic32mx_handle_unlock_command)
723 {
724 struct target *target = NULL;
725 struct pic32mx_flash_bank *pic32mx_info = NULL;
726
727 if (CMD_ARGC < 1)
728 {
729 command_print(CMD_CTX, "pic32mx unlock <bank>");
730 return ERROR_OK;
731 }
732
733 struct flash_bank *bank;
734 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
735 if (ERROR_OK != retval)
736 return retval;
737
738 pic32mx_info = bank->driver_priv;
739
740 target = bank->target;
741
742 if (target->state != TARGET_HALTED)
743 {
744 LOG_ERROR("Target not halted");
745 return ERROR_TARGET_NOT_HALTED;
746 }
747
748 if (pic32mx_erase_options(bank) != ERROR_OK)
749 {
750 command_print(CMD_CTX, "pic32mx failed to unlock device");
751 return ERROR_OK;
752 }
753
754 if (pic32mx_write_options(bank) != ERROR_OK)
755 {
756 command_print(CMD_CTX, "pic32mx failed to lock device");
757 return ERROR_OK;
758 }
759
760 command_print(CMD_CTX, "pic32mx unlocked");
761
762 return ERROR_OK;
763 }
764 #endif
765
766 #if 0
767 static int pic32mx_chip_erase(struct flash_bank *bank)
768 {
769 struct target *target = bank->target;
770 #if 0
771 uint32_t status;
772 #endif
773
774 if (target->state != TARGET_HALTED)
775 {
776 LOG_ERROR("Target not halted");
777 return ERROR_TARGET_NOT_HALTED;
778 }
779
780 LOG_INFO("PIC32MX chip erase called");
781
782 #if 0
783 /* unlock option flash registers */
784 target_write_u32(target, PIC32MX_FLASH_KEYR, KEY1);
785 target_write_u32(target, PIC32MX_FLASH_KEYR, KEY2);
786
787 /* chip erase flash memory */
788 target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER);
789 target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER | FLASH_STRT);
790
791 status = pic32mx_wait_status_busy(bank, 10);
792
793 target_write_u32(target, PIC32MX_FLASH_CR, FLASH_LOCK);
794
795 if (status & FLASH_WRPRTERR)
796 {
797 LOG_ERROR("pic32mx device protected");
798 return ERROR_OK;
799 }
800
801 if (status & FLASH_PGERR)
802 {
803 LOG_ERROR("pic32mx device programming failed");
804 return ERROR_OK;
805 }
806 #endif
807
808 return ERROR_OK;
809 }
810 #endif
811
812 COMMAND_HANDLER(pic32mx_handle_chip_erase_command)
813 {
814 #if 0
815 int i;
816
817 if (CMD_ARGC != 0)
818 {
819 command_print(CMD_CTX, "pic32mx chip_erase");
820 return ERROR_OK;
821 }
822
823 struct flash_bank *bank;
824 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
825 if (ERROR_OK != retval)
826 return retval;
827
828 if (pic32mx_chip_erase(bank) == ERROR_OK)
829 {
830 /* set all sectors as erased */
831 for (i = 0; i < bank->num_sectors; i++)
832 {
833 bank->sectors[i].is_erased = 1;
834 }
835
836 command_print(CMD_CTX, "pic32mx chip erase complete");
837 }
838 else
839 {
840 command_print(CMD_CTX, "pic32mx chip erase failed");
841 }
842 #endif
843
844 return ERROR_OK;
845 }
846
847 COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
848 {
849 uint32_t address, value;
850 int status, res;
851
852 if (CMD_ARGC != 3)
853 {
854 command_print(CMD_CTX, "pic32mx pgm_word <addr> <value> <bank>");
855 return ERROR_OK;
856 }
857
858 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
859 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
860
861 struct flash_bank *bank;
862 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 2, &bank);
863 if (ERROR_OK != retval)
864 return retval;
865
866 if (address < bank->base || address >= (bank->base + bank->size))
867 {
868 command_print(CMD_CTX, "flash address '%s' is out of bounds", CMD_ARGV[0]);
869 return ERROR_OK;
870 }
871
872 res = ERROR_OK;
873 status = pic32mx_write_word(bank, address, value);
874 if (status & NVMCON_NVMERR)
875 res = ERROR_FLASH_OPERATION_FAILED;
876 if (status & NVMCON_LVDERR)
877 res = ERROR_FLASH_OPERATION_FAILED;
878
879 if (res == ERROR_OK)
880 command_print(CMD_CTX, "pic32mx pgm word complete");
881 else
882 command_print(CMD_CTX, "pic32mx pgm word failed (status = 0x%x)", status);
883
884 return ERROR_OK;
885 }
886 static const struct command_registration pic32mx_exec_command_handlers[] = {
887 {
888 .name = "chip_erase",
889 .handler = pic32mx_handle_chip_erase_command,
890 .mode = COMMAND_EXEC,
891 .help = "erase device",
892 },
893 {
894 .name = "pgm_word",
895 .handler = pic32mx_handle_pgm_word_command,
896 .mode = COMMAND_EXEC,
897 .help = "program a word",
898 },
899 COMMAND_REGISTRATION_DONE
900 };
901 static const struct command_registration pic32mx_command_handlers[] = {
902 {
903 .name = "pic32mx",
904 .mode = COMMAND_ANY,
905 .help = "pic32mx flash command group",
906 .chain = pic32mx_exec_command_handlers,
907 },
908 COMMAND_REGISTRATION_DONE
909 };
910
911 struct flash_driver pic32mx_flash = {
912 .name = "pic32mx",
913 .commands = pic32mx_command_handlers,
914 .flash_bank_command = pic32mx_flash_bank_command,
915 .erase = pic32mx_erase,
916 .protect = pic32mx_protect,
917 .write = pic32mx_write,
918 .probe = pic32mx_probe,
919 .auto_probe = pic32mx_auto_probe,
920 .erase_check = default_flash_mem_blank_check,
921 .protect_check = pic32mx_protect_check,
922 .info = pic32mx_info,
923 };

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)