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

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)