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 ***************************************************************************/
30 #include "replacements.h"
37 #include "algorithm.h"
38 #include "binarybuffer.h"
44 struct pic32mx_devs_s
{
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 },
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
);
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
);
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);
90 flash_driver_t pic32mx_flash
=
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
,
105 static int pic32mx_register_commands(struct command_context_s
*cmd_ctx
)
107 command_t
*pic32mx_cmd
= register_command(cmd_ctx
, NULL
, "pic32mx", NULL
, COMMAND_ANY
, "pic32mx flash specific commands");
110 register_command(cmd_ctx
, pic32mx_cmd
, "lock", pic32mx_handle_lock_command
, COMMAND_EXEC
,
112 register_command(cmd_ctx
, pic32mx_cmd
, "unlock", pic32mx_handle_unlock_command
, COMMAND_EXEC
,
113 "unlock protected device");
115 register_command(cmd_ctx
, pic32mx_cmd
, "chip_erase", pic32mx_handle_chip_erase_command
, COMMAND_EXEC
,
117 register_command(cmd_ctx
, pic32mx_cmd
, "pgm_word", pic32mx_handle_pgm_word_command
, COMMAND_EXEC
,
122 /* flash bank pic32mx <base> <size> 0 0 <target#>
124 static int pic32mx_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
126 pic32mx_flash_bank_t
*pic32mx_info
;
130 LOG_WARNING("incomplete flash_bank pic32mx configuration");
131 return ERROR_FLASH_BANK_INVALID
;
134 pic32mx_info
= malloc(sizeof(pic32mx_flash_bank_t
));
135 bank
->driver_priv
= pic32mx_info
;
137 pic32mx_info
->write_algorithm
= NULL
;
138 pic32mx_info
->probed
= 0;
143 static u32
pic32mx_get_flash_status(flash_bank_t
*bank
)
145 target_t
*target
= bank
->target
;
148 target_read_u32(target
, PIC32MX_NVMCON
, &status
);
153 static u32
pic32mx_wait_status_busy(flash_bank_t
*bank
, int timeout
)
157 /* wait for busy to clear */
158 while (((status
= pic32mx_get_flash_status(bank
)) & NVMCON_NVMWR
) && (timeout
-- > 0))
160 LOG_DEBUG("status: 0x%x", status
);
164 LOG_DEBUG("timeout: status: 0x%x", status
);
169 static int pic32mx_nvm_exec(struct flash_bank_s
*bank
, u32 op
, u32 timeout
)
171 target_t
*target
= bank
->target
;
174 target_write_u32(target
, PIC32MX_NVMCON
, NVMCON_NVMWREN
|op
);
176 /* unlock flash registers */
177 target_write_u32(target
, PIC32MX_NVMKEY
, NVMKEY1
);
178 target_write_u32(target
, PIC32MX_NVMKEY
, NVMKEY2
);
180 /* start operation */
181 target_write_u32(target
, PIC32MX_NVMCONSET
, NVMCON_NVMWR
);
183 status
= pic32mx_wait_status_busy(bank
, timeout
);
185 /* lock flash registers */
186 target_write_u32(target
, PIC32MX_NVMCONCLR
, NVMCON_NVMWREN
);
191 static int pic32mx_protect_check(struct flash_bank_s
*bank
)
193 target_t
*target
= bank
->target
;
199 if (target
->state
!= TARGET_HALTED
)
201 LOG_ERROR("Target not halted");
202 return ERROR_TARGET_NOT_HALTED
;
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
)
210 if(devcfg0
& (1<<24))
211 num_pages
= 0; /* All pages unprotected */
213 num_pages
= 0xffff; /* All pages protected */
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;
225 static int pic32mx_erase(struct flash_bank_s
*bank
, int first
, int last
)
227 target_t
*target
= bank
->target
;
231 if (bank
->target
->state
!= TARGET_HALTED
)
233 LOG_ERROR("Target not halted");
234 return ERROR_TARGET_NOT_HALTED
;
237 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)) && (bank
->base
== PIC32MX_KSEG0_PGM_FLASH
|| bank
->base
== PIC32MX_KSEG1_PGM_FLASH
))
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
;
248 for (i
= first
; i
<= last
; i
++)
250 if(bank
->base
>= PIC32MX_KSEG1_PGM_FLASH
)
251 target_write_u32(target
, PIC32MX_NVMADDR
, KS1Virt2Phys(bank
->base
+ bank
->sectors
[i
].offset
));
253 target_write_u32(target
, PIC32MX_NVMADDR
, KS0Virt2Phys(bank
->base
+ bank
->sectors
[i
].offset
));
255 status
= pic32mx_nvm_exec(bank
, NVMCON_OP_PAGE_ERASE
, 10);
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;
267 static int pic32mx_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
269 pic32mx_flash_bank_t
*pic32mx_info
= NULL
;
270 target_t
*target
= bank
->target
;
272 u16 prot_reg
[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
278 pic32mx_info
= bank
->driver_priv
;
280 if (target
->state
!= TARGET_HALTED
)
282 LOG_ERROR("Target not halted");
283 return ERROR_TARGET_NOT_HALTED
;
287 if ((first
&& (first
% pic32mx_info
->ppage_size
)) || ((last
+ 1) && (last
+ 1) % pic32mx_info
->ppage_size
))
289 LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", pic32mx_info
->ppage_size
);
290 return ERROR_FLASH_SECTOR_INVALID
;
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
);
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);
302 if (pic32mx_info
->ppage_size
== 2)
304 /* high density flash */
306 /* bit 7 controls sector 62 - 255 protection */
310 prot_reg
[3] &= ~(1 << 7);
312 prot_reg
[3] |= (1 << 7);
320 for (i
= first
; i
<= last
; i
++)
322 reg
= (i
/ pic32mx_info
->ppage_size
) / 8;
323 bit
= (i
/ pic32mx_info
->ppage_size
) - (reg
* 8);
326 prot_reg
[reg
] &= ~(1 << bit
);
328 prot_reg
[reg
] |= (1 << bit
);
333 /* medium density flash */
334 for (i
= first
; i
<= last
; i
++)
336 reg
= (i
/ pic32mx_info
->ppage_size
) / 8;
337 bit
= (i
/ pic32mx_info
->ppage_size
) - (reg
* 8);
340 prot_reg
[reg
] &= ~(1 << bit
);
342 prot_reg
[reg
] |= (1 << bit
);
346 if ((status
= pic32mx_erase_options(bank
)) != ERROR_OK
)
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];
354 return pic32mx_write_options(bank
);
360 static int pic32mx_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
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
;
368 pic32mx_flash_bank_t
*pic32mx_info
= bank
->driver_priv
;
369 armv7m_algorithm_t armv7m_info
;
371 u8 pic32mx_flash_write_code
[] = {
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 */
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 */
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 */
393 /* flash write code */
394 if (target_alloc_working_area(target
, sizeof(pic32mx_flash_write_code
), &pic32mx_info
->write_algorithm
) != ERROR_OK
)
396 LOG_WARNING("no working area available, can't do block memory writes");
397 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
400 if ((retval
=target_write_buffer(target
, pic32mx_info
->write_algorithm
->address
, sizeof(pic32mx_flash_write_code
), pic32mx_flash_write_code
))!=ERROR_OK
)
405 if (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
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
);
413 LOG_WARNING("no large enough working area available, can't do block memory writes");
414 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
417 while (count
>= buffer_size
/4)
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);
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);
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
)
434 LOG_ERROR("error executing pic32mx flash write algorithm");
435 retval
= ERROR_FLASH_OPERATION_FAILED
;
439 if (buf_get_u32(reg_params
[3].value
, 0, 32) & 0x14)
441 retval
= ERROR_FLASH_OPERATION_FAILED
;
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
;
451 if( status
& NVMCON_LVDERR
) {
452 LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status
);
453 retval
= ERROR_FLASH_OPERATION_FAILED
;
457 buffer
+= buffer_size
;
458 address
+= buffer_size
;
459 count
-= buffer_size
/4;
462 target_free_working_area(target
, source
);
467 memcpy(&value
, buffer
, sizeof(u32
));
469 u32 status
= pic32mx_write_word(bank
, address
, value
);
470 if( status
& NVMCON_NVMERR
) {
471 LOG_ERROR("Flash write error NVMERR (status=0x%08x)", status
);
472 retval
= ERROR_FLASH_OPERATION_FAILED
;
475 if( status
& NVMCON_LVDERR
) {
476 LOG_ERROR("Flash write error LVDERR (status=0x%08x)", status
);
477 retval
= ERROR_FLASH_OPERATION_FAILED
;
489 static int pic32mx_write_word(struct flash_bank_s
*bank
, u32 address
, u32 word
)
491 target_t
*target
= bank
->target
;
493 if(bank
->base
>= PIC32MX_KSEG1_PGM_FLASH
)
494 target_write_u32(target
, PIC32MX_NVMADDR
, KS1Virt2Phys(address
));
496 target_write_u32(target
, PIC32MX_NVMADDR
, KS0Virt2Phys(address
));
497 target_write_u32(target
, PIC32MX_NVMDATA
, word
);
499 return pic32mx_nvm_exec(bank
, NVMCON_OP_WORD_PROG
, 5);
503 * Write a 128 word (512 byte) row to flash address from RAM srcaddr.
505 static int pic32mx_write_row(struct flash_bank_s
*bank
, u32 address
, u32 srcaddr
)
507 target_t
*target
= bank
->target
;
509 LOG_DEBUG("addr: 0x%08x srcaddr: 0x%08x", address
, srcaddr
);
511 if(address
>= PIC32MX_KSEG1_PGM_FLASH
)
512 target_write_u32(target
, PIC32MX_NVMADDR
, KS1Virt2Phys(address
));
514 target_write_u32(target
, PIC32MX_NVMADDR
, KS0Virt2Phys(address
));
515 if(srcaddr
>= PIC32MX_KSEG1_RAM
)
516 target_write_u32(target
, PIC32MX_NVMSRCADDR
, KS1Virt2Phys(srcaddr
));
518 target_write_u32(target
, PIC32MX_NVMSRCADDR
, KS0Virt2Phys(srcaddr
));
520 return pic32mx_nvm_exec(bank
, NVMCON_OP_ROW_PROG
, 100);
523 static int pic32mx_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
525 u32 words_remaining
= (count
/ 4);
526 u32 bytes_remaining
= (count
& 0x00000003);
527 u32 address
= bank
->base
+ offset
;
528 u32 bytes_written
= 0;
532 if (bank
->target
->state
!= TARGET_HALTED
)
534 LOG_ERROR("Target not halted");
535 return ERROR_TARGET_NOT_HALTED
;
540 LOG_WARNING("offset 0x%x breaks required 4-byte alignment", offset
);
541 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
544 /* multiple words (4-byte) to be programmed? */
545 if (words_remaining
> 0)
547 /* try using a block write */
548 if ((retval
= pic32mx_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
550 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
552 /* if block write failed (no sufficient working area),
553 * we use normal (slow) single dword accesses */
554 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
556 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
558 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
559 return ERROR_FLASH_OPERATION_FAILED
;
564 buffer
+= words_remaining
* 4;
565 address
+= words_remaining
* 4;
570 while (words_remaining
> 0)
573 memcpy(&value
, buffer
+ bytes_written
, sizeof(u32
));
575 status
= pic32mx_write_word(bank
, address
, value
);
576 if( status
& NVMCON_NVMERR
)
577 return ERROR_FLASH_OPERATION_FAILED
;
578 if( status
& NVMCON_LVDERR
)
579 return ERROR_FLASH_OPERATION_FAILED
;
588 u32 value
= 0xffffffff;
589 memcpy(&value
, buffer
+ bytes_written
, bytes_remaining
);
591 status
= pic32mx_write_word(bank
, address
, value
);
592 if( status
& NVMCON_NVMERR
)
593 return ERROR_FLASH_OPERATION_FAILED
;
594 if( status
& NVMCON_LVDERR
)
595 return ERROR_FLASH_OPERATION_FAILED
;
601 static int pic32mx_probe(struct flash_bank_s
*bank
)
603 target_t
*target
= bank
->target
;
604 pic32mx_flash_bank_t
*pic32mx_info
= bank
->driver_priv
;
605 mips32_common_t
*mips32
= target
->arch_info
;
606 mips_ejtag_t
*ejtag_info
= &mips32
->ejtag_info
;
612 pic32mx_info
->probed
= 0;
614 device_id
= ejtag_info
->idcode
;
615 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 );
617 if(((device_id
>>1)&0x7ff) != PIC32MX_MANUF_ID
) {
618 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
619 return ERROR_FLASH_OPERATION_FAILED
;
623 if(bank
->base
== PIC32MX_KSEG1_BOOT_FLASH
|| bank
->base
== 1) {
624 /* 0xBFC00000: Boot flash size fixed at 12k */
627 /* 0xBD000000: Program flash size varies with device */
628 for(i
=0; pic32mx_devs
[i
].name
!= NULL
; i
++)
629 if(pic32mx_devs
[i
].devid
== ((device_id
>> 12) & 0xff)) {
630 num_pages
= pic32mx_devs
[i
].pfm_size
;
633 if(pic32mx_devs
[i
].name
== NULL
) {
634 LOG_WARNING( "Cannot identify target as a PIC32MX family." );
635 return ERROR_FLASH_OPERATION_FAILED
;
640 if (bank
->target
->state
!= TARGET_HALTED
)
642 LOG_ERROR("Target not halted");
643 return ERROR_TARGET_NOT_HALTED
;
646 /* get flash size from target */
647 if (target_read_u16(target
, 0x1FFFF7E0, &num_pages
) != ERROR_OK
)
649 /* failed reading flash size, default to max target family */
654 LOG_INFO( "flash size = %dkbytes", num_pages
);
656 /* calculate numbers of pages */
657 num_pages
/= (page_size
/ 1024);
659 if(bank
->base
== 0) bank
->base
= PIC32MX_KSEG1_PGM_FLASH
;
660 if(bank
->base
== 1) bank
->base
= PIC32MX_KSEG1_BOOT_FLASH
;
661 bank
->size
= (num_pages
* page_size
);
662 bank
->num_sectors
= num_pages
;
663 bank
->chip_width
= 4;
665 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_pages
);
667 for (i
= 0; i
< num_pages
; i
++)
669 bank
->sectors
[i
].offset
= i
* page_size
;
670 bank
->sectors
[i
].size
= page_size
;
671 bank
->sectors
[i
].is_erased
= -1;
672 bank
->sectors
[i
].is_protected
= 1;
675 pic32mx_info
->probed
= 1;
680 static int pic32mx_auto_probe(struct flash_bank_s
*bank
)
682 pic32mx_flash_bank_t
*pic32mx_info
= bank
->driver_priv
;
683 if (pic32mx_info
->probed
)
685 return pic32mx_probe(bank
);
689 static int pic32mx_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
695 static int pic32mx_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
697 target_t
*target
= bank
->target
;
698 mips32_common_t
*mips32
= target
->arch_info
;
699 mips_ejtag_t
*ejtag_info
= &mips32
->ejtag_info
;
703 device_id
= ejtag_info
->idcode
;
705 if(((device_id
>>1)&0x7ff) != PIC32MX_MANUF_ID
) {
706 snprintf(buf
, buf_size
, "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n", (device_id
>>1)&0x7ff, PIC32MX_MANUF_ID
);
707 return ERROR_FLASH_OPERATION_FAILED
;
709 for(i
=0; pic32mx_devs
[i
].name
!= NULL
; i
++)
710 if(pic32mx_devs
[i
].devid
== ((device_id
>> 12) & 0xff)) {
711 printed
= snprintf(buf
, buf_size
, "PIC32MX%s", pic32mx_devs
[i
].name
);
714 if(pic32mx_devs
[i
].name
== NULL
) {
715 snprintf(buf
, buf_size
, "Cannot identify target as a PIC32MX family\n");
716 return ERROR_FLASH_OPERATION_FAILED
;
720 printed
= snprintf(buf
, buf_size
, " Ver: 0x%03x", (device_id
>>20)&0xfff);
726 int pic32mx_handle_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
729 target_t
*target
= NULL
;
730 pic32mx_flash_bank_t
*pic32mx_info
= NULL
;
734 command_print(cmd_ctx
, "pic32mx lock <bank>");
738 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
741 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
745 pic32mx_info
= bank
->driver_priv
;
747 target
= bank
->target
;
749 if (target
->state
!= TARGET_HALTED
)
751 LOG_ERROR("Target not halted");
752 return ERROR_TARGET_NOT_HALTED
;
755 if (pic32mx_erase_options(bank
) != ERROR_OK
)
757 command_print(cmd_ctx
, "pic32mx failed to erase options");
761 /* set readout protection */
762 pic32mx_info
->option_bytes
.RDP
= 0;
764 if (pic32mx_write_options(bank
) != ERROR_OK
)
766 command_print(cmd_ctx
, "pic32mx failed to lock device");
770 command_print(cmd_ctx
, "pic32mx locked");
775 int pic32mx_handle_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
778 target_t
*target
= NULL
;
779 pic32mx_flash_bank_t
*pic32mx_info
= NULL
;
783 command_print(cmd_ctx
, "pic32mx unlock <bank>");
787 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
790 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
794 pic32mx_info
= bank
->driver_priv
;
796 target
= bank
->target
;
798 if (target
->state
!= TARGET_HALTED
)
800 LOG_ERROR("Target not halted");
801 return ERROR_TARGET_NOT_HALTED
;
804 if (pic32mx_erase_options(bank
) != ERROR_OK
)
806 command_print(cmd_ctx
, "pic32mx failed to unlock device");
810 if (pic32mx_write_options(bank
) != ERROR_OK
)
812 command_print(cmd_ctx
, "pic32mx failed to lock device");
816 command_print(cmd_ctx
, "pic32mx unlocked");
823 static int pic32mx_chip_erase(struct flash_bank_s
*bank
)
825 target_t
*target
= bank
->target
;
830 if (target
->state
!= TARGET_HALTED
)
832 LOG_ERROR("Target not halted");
833 return ERROR_TARGET_NOT_HALTED
;
836 LOG_INFO("PIC32MX chip erase called");
839 /* unlock option flash registers */
840 target_write_u32(target
, PIC32MX_FLASH_KEYR
, KEY1
);
841 target_write_u32(target
, PIC32MX_FLASH_KEYR
, KEY2
);
843 /* chip erase flash memory */
844 target_write_u32(target
, PIC32MX_FLASH_CR
, FLASH_MER
);
845 target_write_u32(target
, PIC32MX_FLASH_CR
, FLASH_MER
|FLASH_STRT
);
847 status
= pic32mx_wait_status_busy(bank
, 10);
849 target_write_u32(target
, PIC32MX_FLASH_CR
, FLASH_LOCK
);
851 if( status
& FLASH_WRPRTERR
)
853 LOG_ERROR("pic32mx device protected");
857 if( status
& FLASH_PGERR
)
859 LOG_ERROR("pic32mx device programming failed");
868 static int pic32mx_handle_chip_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
876 command_print(cmd_ctx
, "pic32mx chip_erase");
880 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
883 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
887 if (pic32mx_chip_erase(bank
) == ERROR_OK
)
889 /* set all sectors as erased */
890 for (i
= 0; i
< bank
->num_sectors
; i
++)
892 bank
->sectors
[i
].is_erased
= 1;
895 command_print(cmd_ctx
, "pic32mx chip erase complete");
899 command_print(cmd_ctx
, "pic32mx chip erase failed");
906 static int pic32mx_handle_pgm_word_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
914 command_print(cmd_ctx
, "pic32mx pgm_word <addr> <value> <bank>");
918 address
= strtoul(args
[0], NULL
, 0);
919 value
= strtoul(args
[1], NULL
, 0);
921 bank
= get_flash_bank_by_num(strtoul(args
[2], NULL
, 0));
924 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[2]);
927 if (address
< bank
->base
|| address
>= (bank
->base
+bank
->size
))
929 command_print(cmd_ctx
, "flash address '%s' is out of bounds", args
[0]);
934 status
= pic32mx_write_word(bank
, address
, value
);
935 if( status
& NVMCON_NVMERR
)
936 res
= ERROR_FLASH_OPERATION_FAILED
;
937 if( status
& NVMCON_LVDERR
)
938 res
= ERROR_FLASH_OPERATION_FAILED
;
941 command_print(cmd_ctx
, "pic32mx pgm word complete");
943 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)