Transform 'u16' to 'uint16_t'
[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 u32 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, u32 offset, u32 count);
65 static int pic32mx_write_row(struct flash_bank_s *bank, u32 address, u32 srcaddr);
66 static int pic32mx_write_word(struct flash_bank_s *bank, u32 address, u32 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 u32 pic32mx_get_flash_status(flash_bank_t *bank)
135 {
136 target_t *target = bank->target;
137 u32 status;
138
139 target_read_u32(target, PIC32MX_NVMCON, &status);
140
141 return status;
142 }
143
144 static u32 pic32mx_wait_status_busy(flash_bank_t *bank, int timeout)
145 {
146 u32 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%x", status);
152 alive_sleep(1);
153 }
154 if(timeout <= 0)
155 LOG_DEBUG("timeout: status: 0x%x", status);
156
157 return status;
158 }
159
160 static int pic32mx_nvm_exec(struct flash_bank_s *bank, u32 op, u32 timeout)
161 {
162 target_t *target = bank->target;
163 u32 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 u32 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 u32 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 u32 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, u32 offset, u32 count)
352 {
353 target_t *target = bank->target;
354 u32 buffer_size = 512;
355 working_area_t *source;
356 u32 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 u32 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", 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%08x)", status);
439 retval = ERROR_FLASH_OPERATION_FAILED;
440 break;
441 }
442 if( status & NVMCON_LVDERR ) {
443 LOG_ERROR("Flash write error LVDERR (status=0x%08x)", 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 u32 value;
458 memcpy(&value, buffer, sizeof(u32));
459
460 u32 status = pic32mx_write_word(bank, address, value);
461 if( status & NVMCON_NVMERR ) {
462 LOG_ERROR("Flash write error NVMERR (status=0x%08x)", status);
463 retval = ERROR_FLASH_OPERATION_FAILED;
464 break;
465 }
466 if( status & NVMCON_LVDERR ) {
467 LOG_ERROR("Flash write error LVDERR (status=0x%08x)", 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, u32 address, u32 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, u32 address, u32 srcaddr)
497 {
498 target_t *target = bank->target;
499
500 LOG_DEBUG("addr: 0x%08x srcaddr: 0x%08x", 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, u32 offset, u32 count)
515 {
516 u32 words_remaining = (count / 4);
517 u32 bytes_remaining = (count & 0x00000003);
518 u32 address = bank->base + offset;
519 u32 bytes_written = 0;
520 u32 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%x 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 u32 value;
564 memcpy(&value, buffer + bytes_written, sizeof(u32));
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 u32 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 u32 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%08x (manuf 0x%03x dev 0x%02x, ver 0x%03x)", device_id, (device_id>>1)&0x7ff, (device_id>>12)&0xff, (device_id>>20)&0xfff );
607
608 if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
609 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
610 return ERROR_FLASH_OPERATION_FAILED;
611 }
612
613 page_size = 4096;
614 if(bank->base == PIC32MX_KSEG1_BOOT_FLASH || bank->base == 1) {
615 /* 0xBFC00000: Boot flash size fixed at 12k */
616 num_pages = 12;
617 } else {
618 /* 0xBD000000: Program flash size varies with device */
619 for(i=0; pic32mx_devs[i].name != NULL; i++)
620 if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
621 num_pages = pic32mx_devs[i].pfm_size;
622 break;
623 }
624 if(pic32mx_devs[i].name == NULL) {
625 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
626 return ERROR_FLASH_OPERATION_FAILED;
627 }
628 }
629
630 #if 0
631 if (bank->target->state != TARGET_HALTED)
632 {
633 LOG_ERROR("Target not halted");
634 return ERROR_TARGET_NOT_HALTED;
635 }
636
637 /* get flash size from target */
638 if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK)
639 {
640 /* failed reading flash size, default to max target family */
641 num_pages = 0xffff;
642 }
643 #endif
644
645 LOG_INFO( "flash size = %dkbytes", num_pages );
646
647 /* calculate numbers of pages */
648 num_pages /= (page_size / 1024);
649
650 if(bank->base == 0) bank->base = PIC32MX_KSEG1_PGM_FLASH;
651 if(bank->base == 1) bank->base = PIC32MX_KSEG1_BOOT_FLASH;
652 bank->size = (num_pages * page_size);
653 bank->num_sectors = num_pages;
654 bank->chip_width = 4;
655 bank->bus_width = 4;
656 bank->sectors = malloc(sizeof(flash_sector_t) * num_pages);
657
658 for (i = 0; i < num_pages; i++)
659 {
660 bank->sectors[i].offset = i * page_size;
661 bank->sectors[i].size = page_size;
662 bank->sectors[i].is_erased = -1;
663 bank->sectors[i].is_protected = 1;
664 }
665
666 pic32mx_info->probed = 1;
667
668 return ERROR_OK;
669 }
670
671 static int pic32mx_auto_probe(struct flash_bank_s *bank)
672 {
673 pic32mx_flash_bank_t *pic32mx_info = bank->driver_priv;
674 if (pic32mx_info->probed)
675 return ERROR_OK;
676 return pic32mx_probe(bank);
677 }
678
679 #if 0
680 static int pic32mx_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
681 {
682 return ERROR_OK;
683 }
684 #endif
685
686 static int pic32mx_info(struct flash_bank_s *bank, char *buf, int buf_size)
687 {
688 target_t *target = bank->target;
689 mips32_common_t *mips32 = target->arch_info;
690 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
691 u32 device_id;
692 int printed = 0, i;
693
694 device_id = ejtag_info->idcode;
695
696 if(((device_id>>1)&0x7ff) != PIC32MX_MANUF_ID) {
697 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n", (device_id>>1)&0x7ff, PIC32MX_MANUF_ID);
698 return ERROR_FLASH_OPERATION_FAILED;
699 }
700 for(i=0; pic32mx_devs[i].name != NULL; i++)
701 if(pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
702 printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
703 break;
704 }
705 if(pic32mx_devs[i].name == NULL) {
706 snprintf(buf, buf_size, "Cannot identify target as a PIC32MX family\n");
707 return ERROR_FLASH_OPERATION_FAILED;
708 }
709 buf += printed;
710 buf_size -= printed;
711 printed = snprintf(buf, buf_size, " Ver: 0x%03x", (device_id>>20)&0xfff);
712
713 return ERROR_OK;
714 }
715
716 #if 0
717 int pic32mx_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
718 {
719 flash_bank_t *bank;
720 target_t *target = NULL;
721 pic32mx_flash_bank_t *pic32mx_info = NULL;
722
723 if (argc < 1)
724 {
725 command_print(cmd_ctx, "pic32mx lock <bank>");
726 return ERROR_OK;
727 }
728
729 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
730 if (!bank)
731 {
732 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
733 return ERROR_OK;
734 }
735
736 pic32mx_info = bank->driver_priv;
737
738 target = bank->target;
739
740 if (target->state != TARGET_HALTED)
741 {
742 LOG_ERROR("Target not halted");
743 return ERROR_TARGET_NOT_HALTED;
744 }
745
746 if (pic32mx_erase_options(bank) != ERROR_OK)
747 {
748 command_print(cmd_ctx, "pic32mx failed to erase options");
749 return ERROR_OK;
750 }
751
752 /* set readout protection */
753 pic32mx_info->option_bytes.RDP = 0;
754
755 if (pic32mx_write_options(bank) != ERROR_OK)
756 {
757 command_print(cmd_ctx, "pic32mx failed to lock device");
758 return ERROR_OK;
759 }
760
761 command_print(cmd_ctx, "pic32mx locked");
762
763 return ERROR_OK;
764 }
765
766 int pic32mx_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
767 {
768 flash_bank_t *bank;
769 target_t *target = NULL;
770 pic32mx_flash_bank_t *pic32mx_info = NULL;
771
772 if (argc < 1)
773 {
774 command_print(cmd_ctx, "pic32mx unlock <bank>");
775 return ERROR_OK;
776 }
777
778 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
779 if (!bank)
780 {
781 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
782 return ERROR_OK;
783 }
784
785 pic32mx_info = bank->driver_priv;
786
787 target = bank->target;
788
789 if (target->state != TARGET_HALTED)
790 {
791 LOG_ERROR("Target not halted");
792 return ERROR_TARGET_NOT_HALTED;
793 }
794
795 if (pic32mx_erase_options(bank) != ERROR_OK)
796 {
797 command_print(cmd_ctx, "pic32mx failed to unlock device");
798 return ERROR_OK;
799 }
800
801 if (pic32mx_write_options(bank) != ERROR_OK)
802 {
803 command_print(cmd_ctx, "pic32mx failed to lock device");
804 return ERROR_OK;
805 }
806
807 command_print(cmd_ctx, "pic32mx unlocked");
808
809 return ERROR_OK;
810 }
811 #endif
812
813 #if 0
814 static int pic32mx_chip_erase(struct flash_bank_s *bank)
815 {
816 target_t *target = bank->target;
817 #if 0
818 u32 status;
819 #endif
820
821 if (target->state != TARGET_HALTED)
822 {
823 LOG_ERROR("Target not halted");
824 return ERROR_TARGET_NOT_HALTED;
825 }
826
827 LOG_INFO("PIC32MX chip erase called");
828
829 #if 0
830 /* unlock option flash registers */
831 target_write_u32(target, PIC32MX_FLASH_KEYR, KEY1);
832 target_write_u32(target, PIC32MX_FLASH_KEYR, KEY2);
833
834 /* chip erase flash memory */
835 target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER);
836 target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER|FLASH_STRT);
837
838 status = pic32mx_wait_status_busy(bank, 10);
839
840 target_write_u32(target, PIC32MX_FLASH_CR, FLASH_LOCK);
841
842 if( status & FLASH_WRPRTERR )
843 {
844 LOG_ERROR("pic32mx device protected");
845 return ERROR_OK;
846 }
847
848 if( status & FLASH_PGERR )
849 {
850 LOG_ERROR("pic32mx device programming failed");
851 return ERROR_OK;
852 }
853 #endif
854
855 return ERROR_OK;
856 }
857 #endif
858
859 static int pic32mx_handle_chip_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
860 {
861 #if 0
862 flash_bank_t *bank;
863 int i;
864
865 if (argc != 0)
866 {
867 command_print(cmd_ctx, "pic32mx chip_erase");
868 return ERROR_OK;
869 }
870
871 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
872 if (!bank)
873 {
874 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
875 return ERROR_OK;
876 }
877
878 if (pic32mx_chip_erase(bank) == ERROR_OK)
879 {
880 /* set all sectors as erased */
881 for (i = 0; i < bank->num_sectors; i++)
882 {
883 bank->sectors[i].is_erased = 1;
884 }
885
886 command_print(cmd_ctx, "pic32mx chip erase complete");
887 }
888 else
889 {
890 command_print(cmd_ctx, "pic32mx chip erase failed");
891 }
892 #endif
893
894 return ERROR_OK;
895 }
896
897 static int pic32mx_handle_pgm_word_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
898 {
899 flash_bank_t *bank;
900 u32 address, value;
901 int status, res;
902
903 if (argc != 3)
904 {
905 command_print(cmd_ctx, "pic32mx pgm_word <addr> <value> <bank>");
906 return ERROR_OK;
907 }
908
909 address = strtoul(args[0], NULL, 0);
910 value = strtoul(args[1], NULL, 0);
911
912 bank = get_flash_bank_by_num(strtoul(args[2], NULL, 0));
913 if (!bank)
914 {
915 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[2]);
916 return ERROR_OK;
917 }
918 if (address < bank->base || address >= (bank->base+bank->size))
919 {
920 command_print(cmd_ctx, "flash address '%s' is out of bounds", args[0]);
921 return ERROR_OK;
922 }
923
924 res = ERROR_OK;
925 status = pic32mx_write_word(bank, address, value);
926 if( status & NVMCON_NVMERR )
927 res = ERROR_FLASH_OPERATION_FAILED;
928 if( status & NVMCON_LVDERR )
929 res = ERROR_FLASH_OPERATION_FAILED;
930
931 if (res == ERROR_OK)
932 command_print(cmd_ctx, "pic32mx pgm word complete");
933 else
934 command_print(cmd_ctx, "pic32mx pgm word failed (status=0x%x)", status);
935
936 return ERROR_OK;
937 }

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)