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

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)