1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2008 by John McCarthy *
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. *
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. *
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 ***************************************************************************/
35 struct pic32mx_devs_s
{
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 },
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
);
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
);
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);
81 flash_driver_t pic32mx_flash
=
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
,
96 static int pic32mx_register_commands(struct command_context_s
*cmd_ctx
)
98 command_t
*pic32mx_cmd
= register_command(cmd_ctx
, NULL
, "pic32mx", NULL
, COMMAND_ANY
, "pic32mx flash specific commands");
101 register_command(cmd_ctx
, pic32mx_cmd
, "lock", pic32mx_handle_lock_command
, COMMAND_EXEC
,
103 register_command(cmd_ctx
, pic32mx_cmd
, "unlock", pic32mx_handle_unlock_command
, COMMAND_EXEC
,
104 "unlock protected device");
106 register_command(cmd_ctx
, pic32mx_cmd
, "chip_erase", pic32mx_handle_chip_erase_command
, COMMAND_EXEC
,
108 register_command(cmd_ctx
, pic32mx_cmd
, "pgm_word", pic32mx_handle_pgm_word_command
, COMMAND_EXEC
,
113 /* flash bank pic32mx <base> <size> 0 0 <target#>
115 static int pic32mx_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
117 pic32mx_flash_bank_t
*pic32mx_info
;
121 LOG_WARNING("incomplete flash_bank pic32mx configuration");
122 return ERROR_FLASH_BANK_INVALID
;
125 pic32mx_info
= malloc(sizeof(pic32mx_flash_bank_t
));
126 bank
->driver_priv
= pic32mx_info
;
128 pic32mx_info
->write_algorithm
= NULL
;
129 pic32mx_info
->probed
= 0;
134 static u32
pic32mx_get_flash_status(flash_bank_t
*bank
)
136 target_t
*target
= bank
->target
;
139 target_read_u32(target
, PIC32MX_NVMCON
, &status
);
144 static u32
pic32mx_wait_status_busy(flash_bank_t
*bank
, int timeout
)
148 /* wait for busy to clear */
149 while (((status
= pic32mx_get_flash_status(bank
)) & NVMCON_NVMWR
) && (timeout
-- > 0))
151 LOG_DEBUG("status: 0x%x", status
);
155 LOG_DEBUG("timeout: status: 0x%x", status
);
160 static int pic32mx_nvm_exec(struct flash_bank_s
*bank
, u32 op
, u32 timeout
)
162 target_t
*target
= bank
->target
;
165 target_write_u32(target
, PIC32MX_NVMCON
, NVMCON_NVMWREN
|op
);
167 /* unlock flash registers */
168 target_write_u32(target
, PIC32MX_NVMKEY
, NVMKEY1
);
169 target_write_u32(target
, PIC32MX_NVMKEY
, NVMKEY2
);
171 /* start operation */
172 target_write_u32(target
, PIC32MX_NVMCONSET
, NVMCON_NVMWR
);
174 status
= pic32mx_wait_status_busy(bank
, timeout
);
176 /* lock flash registers */
177 target_write_u32(target
, PIC32MX_NVMCONCLR
, NVMCON_NVMWREN
);
182 static int pic32mx_protect_check(struct flash_bank_s
*bank
)
184 target_t
*target
= bank
->target
;
190 if (target
->state
!= TARGET_HALTED
)
192 LOG_ERROR("Target not halted");
193 return ERROR_TARGET_NOT_HALTED
;
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
)
201 if(devcfg0
& (1<<24))
202 num_pages
= 0; /* All pages unprotected */
204 num_pages
= 0xffff; /* All pages protected */
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;
216 static int pic32mx_erase(struct flash_bank_s
*bank
, int first
, int last
)
218 target_t
*target
= bank
->target
;
222 if (bank
->target
->state
!= TARGET_HALTED
)
224 LOG_ERROR("Target not halted");
225 return ERROR_TARGET_NOT_HALTED
;
228 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)) && (bank
->base
== PIC32MX_KSEG0_PGM_FLASH
|| bank
->base
== PIC32MX_KSEG1_PGM_FLASH
))
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
;
239 for (i
= first
; i
<= last
; i
++)
241 if(bank
->base
>= PIC32MX_KSEG1_PGM_FLASH
)
242 target_write_u32(target
, PIC32MX_NVMADDR
, KS1Virt2Phys(bank
->base
+ bank
->sectors
[i
].offset
));
244 target_write_u32(target
, PIC32MX_NVMADDR
, KS0Virt2Phys(bank
->base
+ bank
->sectors
[i
].offset
));
246 status
= pic32mx_nvm_exec(bank
, NVMCON_OP_PAGE_ERASE
, 10);
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;
258 static int pic32mx_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
260 pic32mx_flash_bank_t
*pic32mx_info
= NULL
;
261 target_t
*target
= bank
->target
;
263 u16 prot_reg
[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
269 pic32mx_info
= bank
->driver_priv
;
271 if (target
->state
!= TARGET_HALTED
)
273 LOG_ERROR("Target not halted");
274 return ERROR_TARGET_NOT_HALTED
;
278 if ((first
&& (first
% pic32mx_info
->ppage_size
)) || ((last
+ 1) && (last
+ 1) % pic32mx_info
->ppage_size
))
280 LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", pic32mx_info
->ppage_size
);
281 return ERROR_FLASH_SECTOR_INVALID
;
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
);
288 prot_reg
[0] = (u16
)protection
;
289 prot_reg
[1] = (u16
)(protection
>> 8);
290 prot_reg
[2] = (u16
)(protection
>> 16);
291 prot_reg
[3] = (u16
)(protection
>> 24);
293 if (pic32mx_info
->ppage_size
== 2)
295 /* high density flash */
297 /* bit 7 controls sector 62 - 255 protection */
301 prot_reg
[3] &= ~(1 << 7);
303 prot_reg
[3] |= (1 << 7);
311 for (i
= first
; i
<= last
; i
++)
313 reg
= (i
/ pic32mx_info
->ppage_size
) / 8;
314 bit
= (i
/ pic32mx_info
->ppage_size
) - (reg
* 8);
317 prot_reg
[reg
] &= ~(1 << bit
);
319 prot_reg
[reg
] |= (1 << bit
);
324 /* medium density flash */
325 for (i
= first
; i
<= last
; i
++)
327 reg
= (i
/ pic32mx_info
->ppage_size
) / 8;
328 bit
= (i
/ pic32mx_info
->ppage_size
) - (reg
* 8);
331 prot_reg
[reg
] &= ~(1 << bit
);
333 prot_reg
[reg
] |= (1 << bit
);
337 if ((status
= pic32mx_erase_options(bank
)) != ERROR_OK
)
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];
345 return pic32mx_write_options(bank
);
351 static int pic32mx_write_block(struct flash_bank_s
*bank
, uint8_t *buffer
, u32 offset
, u32 count
)
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
;
359 pic32mx_flash_bank_t
*pic32mx_info
= bank
->driver_priv
;
360 armv7m_algorithm_t armv7m_info
;
362 uint8_t pic32mx_flash_write_code
[] = {
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 */
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 */
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 */
384 /* flash write code */
385 if (target_alloc_working_area(target
, sizeof(pic32mx_flash_write_code
), &pic32mx_info
->write_algorithm
) != ERROR_OK
)
387 LOG_WARNING("no working area available, can't do block memory writes");
388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
391 if ((retval
=target_write_buffer(target
, pic32mx_info
->write_algorithm
->address
, sizeof(pic32mx_flash_write_code
), pic32mx_flash_write_code
))!=ERROR_OK
)
396 if (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
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
);
404 LOG_WARNING("no large enough working area available, can't do block memory writes");
405 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
408 while (count
>= buffer_size
/4)
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);
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);
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
)
425 LOG_ERROR("error executing pic32mx flash write algorithm");
426 retval
= ERROR_FLASH_OPERATION_FAILED
;
430 if (buf_get_u32(reg_params
[3].value
, 0, 32) & 0x14)
432 retval
= ERROR_FLASH_OPERATION_FAILED
;
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
;
442 if( status
& NVMCON_LVDERR
) {
443 LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status
);
444 retval
= ERROR_FLASH_OPERATION_FAILED
;
448 buffer
+= buffer_size
;
449 address
+= buffer_size
;
450 count
-= buffer_size
/4;
453 target_free_working_area(target
, source
);
458 memcpy(&value
, buffer
, sizeof(u32
));
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
;
466 if( status
& NVMCON_LVDERR
) {
467 LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status
);
468 retval
= ERROR_FLASH_OPERATION_FAILED
;
480 static int pic32mx_write_word(struct flash_bank_s
*bank
, u32 address
, u32 word
)
482 target_t
*target
= bank
->target
;
484 if(bank
->base
>= PIC32MX_KSEG1_PGM_FLASH
)
485 target_write_u32(target
, PIC32MX_NVMADDR
, KS1Virt2Phys(address
));
487 target_write_u32(target
, PIC32MX_NVMADDR
, KS0Virt2Phys(address
));
488 target_write_u32(target
, PIC32MX_NVMDATA
, word
);
490 return pic32mx_nvm_exec(bank
, NVMCON_OP_WORD_PROG
, 5);
494 * Write a 128 word (512 byte) row to flash address from RAM srcaddr.
496 static int pic32mx_write_row(struct flash_bank_s
*bank
, u32 address
, u32 srcaddr
)
498 target_t
*target
= bank
->target
;
500 LOG_DEBUG("addr: 0x%08x srcaddr: 0x%08x", address
, srcaddr
);
502 if(address
>= PIC32MX_KSEG1_PGM_FLASH
)
503 target_write_u32(target
, PIC32MX_NVMADDR
, KS1Virt2Phys(address
));
505 target_write_u32(target
, PIC32MX_NVMADDR
, KS0Virt2Phys(address
));
506 if(srcaddr
>= PIC32MX_KSEG1_RAM
)
507 target_write_u32(target
, PIC32MX_NVMSRCADDR
, KS1Virt2Phys(srcaddr
));
509 target_write_u32(target
, PIC32MX_NVMSRCADDR
, KS0Virt2Phys(srcaddr
));
511 return pic32mx_nvm_exec(bank
, NVMCON_OP_ROW_PROG
, 100);
514 static int pic32mx_write(struct flash_bank_s
*bank
, uint8_t *buffer
, u32 offset
, u32 count
)
516 u32 words_remaining
= (count
/ 4);
517 u32 bytes_remaining
= (count
& 0x00000003);
518 u32 address
= bank
->base
+ offset
;
519 u32 bytes_written
= 0;
523 if (bank
->target
->state
!= TARGET_HALTED
)
525 LOG_ERROR("Target not halted");
526 return ERROR_TARGET_NOT_HALTED
;
531 LOG_WARNING("offset 0x%x breaks required 4-byte alignment", offset
);
532 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
535 /* multiple words (4-byte) to be programmed? */
536 if (words_remaining
> 0)
538 /* try using a block write */
539 if ((retval
= pic32mx_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
541 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
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");
547 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
549 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
550 return ERROR_FLASH_OPERATION_FAILED
;
555 buffer
+= words_remaining
* 4;
556 address
+= words_remaining
* 4;
561 while (words_remaining
> 0)
564 memcpy(&value
, buffer
+ bytes_written
, sizeof(u32
));
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
;
579 u32 value
= 0xffffffff;
580 memcpy(&value
, buffer
+ bytes_written
, bytes_remaining
);
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
;
592 static int pic32mx_probe(struct flash_bank_s
*bank
)
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
;
603 pic32mx_info
->probed
= 0;
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 );
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
;
614 if(bank
->base
== PIC32MX_KSEG1_BOOT_FLASH
|| bank
->base
== 1) {
615 /* 0xBFC00000: Boot flash size fixed at 12k */
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
;
624 if(pic32mx_devs
[i
].name
== NULL
) {
625 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
626 return ERROR_FLASH_OPERATION_FAILED
;
631 if (bank
->target
->state
!= TARGET_HALTED
)
633 LOG_ERROR("Target not halted");
634 return ERROR_TARGET_NOT_HALTED
;
637 /* get flash size from target */
638 if (target_read_u16(target
, 0x1FFFF7E0, &num_pages
) != ERROR_OK
)
640 /* failed reading flash size, default to max target family */
645 LOG_INFO( "flash size = %dkbytes", num_pages
);
647 /* calculate numbers of pages */
648 num_pages
/= (page_size
/ 1024);
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;
656 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_pages
);
658 for (i
= 0; i
< num_pages
; i
++)
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;
666 pic32mx_info
->probed
= 1;
671 static int pic32mx_auto_probe(struct flash_bank_s
*bank
)
673 pic32mx_flash_bank_t
*pic32mx_info
= bank
->driver_priv
;
674 if (pic32mx_info
->probed
)
676 return pic32mx_probe(bank
);
680 static int pic32mx_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
686 static int pic32mx_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
688 target_t
*target
= bank
->target
;
689 mips32_common_t
*mips32
= target
->arch_info
;
690 mips_ejtag_t
*ejtag_info
= &mips32
->ejtag_info
;
694 device_id
= ejtag_info
->idcode
;
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
;
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
);
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
;
711 printed
= snprintf(buf
, buf_size
, " Ver: 0x%03x", (device_id
>>20)&0xfff);
717 int pic32mx_handle_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
720 target_t
*target
= NULL
;
721 pic32mx_flash_bank_t
*pic32mx_info
= NULL
;
725 command_print(cmd_ctx
, "pic32mx lock <bank>");
729 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
732 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
736 pic32mx_info
= bank
->driver_priv
;
738 target
= bank
->target
;
740 if (target
->state
!= TARGET_HALTED
)
742 LOG_ERROR("Target not halted");
743 return ERROR_TARGET_NOT_HALTED
;
746 if (pic32mx_erase_options(bank
) != ERROR_OK
)
748 command_print(cmd_ctx
, "pic32mx failed to erase options");
752 /* set readout protection */
753 pic32mx_info
->option_bytes
.RDP
= 0;
755 if (pic32mx_write_options(bank
) != ERROR_OK
)
757 command_print(cmd_ctx
, "pic32mx failed to lock device");
761 command_print(cmd_ctx
, "pic32mx locked");
766 int pic32mx_handle_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
769 target_t
*target
= NULL
;
770 pic32mx_flash_bank_t
*pic32mx_info
= NULL
;
774 command_print(cmd_ctx
, "pic32mx unlock <bank>");
778 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
781 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
785 pic32mx_info
= bank
->driver_priv
;
787 target
= bank
->target
;
789 if (target
->state
!= TARGET_HALTED
)
791 LOG_ERROR("Target not halted");
792 return ERROR_TARGET_NOT_HALTED
;
795 if (pic32mx_erase_options(bank
) != ERROR_OK
)
797 command_print(cmd_ctx
, "pic32mx failed to unlock device");
801 if (pic32mx_write_options(bank
) != ERROR_OK
)
803 command_print(cmd_ctx
, "pic32mx failed to lock device");
807 command_print(cmd_ctx
, "pic32mx unlocked");
814 static int pic32mx_chip_erase(struct flash_bank_s
*bank
)
816 target_t
*target
= bank
->target
;
821 if (target
->state
!= TARGET_HALTED
)
823 LOG_ERROR("Target not halted");
824 return ERROR_TARGET_NOT_HALTED
;
827 LOG_INFO("PIC32MX chip erase called");
830 /* unlock option flash registers */
831 target_write_u32(target
, PIC32MX_FLASH_KEYR
, KEY1
);
832 target_write_u32(target
, PIC32MX_FLASH_KEYR
, KEY2
);
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
);
838 status
= pic32mx_wait_status_busy(bank
, 10);
840 target_write_u32(target
, PIC32MX_FLASH_CR
, FLASH_LOCK
);
842 if( status
& FLASH_WRPRTERR
)
844 LOG_ERROR("pic32mx device protected");
848 if( status
& FLASH_PGERR
)
850 LOG_ERROR("pic32mx device programming failed");
859 static int pic32mx_handle_chip_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
867 command_print(cmd_ctx
, "pic32mx chip_erase");
871 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
874 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
878 if (pic32mx_chip_erase(bank
) == ERROR_OK
)
880 /* set all sectors as erased */
881 for (i
= 0; i
< bank
->num_sectors
; i
++)
883 bank
->sectors
[i
].is_erased
= 1;
886 command_print(cmd_ctx
, "pic32mx chip erase complete");
890 command_print(cmd_ctx
, "pic32mx chip erase failed");
897 static int pic32mx_handle_pgm_word_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
905 command_print(cmd_ctx
, "pic32mx pgm_word <addr> <value> <bank>");
909 address
= strtoul(args
[0], NULL
, 0);
910 value
= strtoul(args
[1], NULL
, 0);
912 bank
= get_flash_bank_by_num(strtoul(args
[2], NULL
, 0));
915 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[2]);
918 if (address
< bank
->base
|| address
>= (bank
->base
+bank
->size
))
920 command_print(cmd_ctx
, "flash address '%s' is out of bounds", args
[0]);
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
;
932 command_print(cmd_ctx
, "pic32mx pgm word complete");
934 command_print(cmd_ctx
, "pic32mx pgm word failed (status=0x%x)", status
);
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)