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

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)