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

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)