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) 2011 by Andreas Fritiofson *
9 * andreas.fritiofson@gmail.com *
11 * Copyright (C) 2014 by Tomas Vanek (PSoC 4 support derived from STM32) *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
26 ***************************************************************************/
33 #include <helper/binarybuffer.h>
34 #include <jtag/jtag.h>
35 #include <target/algorithm.h>
36 #include <target/armv7m.h>
40 PSoC(R) 4: PSoC 4200 Family Datasheet
41 Document Number: 001-87197 Rev. *B Revised August 29, 2013
43 PSoC 4100/4200 Family PSoC(R) 4 Architecture TRM
44 Document No. 001-85634 Rev. *C March 25, 2014
46 PSoC(R) 4 Registers TRM Spec.
47 Document No. 001-85847 Rev. *A June 25, 2013
49 CY8C41xx, CY8C42xx Programming Specifications
50 Document No. 001-81799 Rev. *C March 4, 2014
53 /* register locations */
54 #define PSOC4_CPUSS_SYSREQ 0x40000004
55 #define PSOC4_CPUSS_SYSARG 0x40000008
56 #define PSOC4_TEST_MODE 0x40030014
57 #define PSOC4_SPCIF_GEOMETRY 0x400E0000
59 #define PSOC4_SFLASH_MACRO 0x0ffff000
62 #define PSOC4_SROM_KEY1 0xb6
63 #define PSOC4_SROM_KEY2 0xd3
64 #define PSOC4_SROM_SYSREQ_BIT (1<<31)
65 #define PSOC4_SROM_HMASTER_BIT (1<<30)
66 #define PSOC4_SROM_PRIVILEGED_BIT (1<<28)
67 #define PSOC4_SROM_STATUS_SUCCEEDED 0xa0000000
68 #define PSOC4_SROM_STATUS_FAILED 0xf0000000
70 #define PSOC4_CMD_GET_SILICON_ID 0
71 #define PSOC4_CMD_LOAD_LATCH 4
72 #define PSOC4_CMD_WRITE_ROW 5
73 #define PSOC4_CMD_PROGRAM_ROW 6
74 #define PSOC4_CMD_ERASE_ALL 0xa
75 #define PSOC4_CMD_CHECKSUM 0xb
76 #define PSOC4_CMD_WRITE_PROTECTION 0xd
78 #define PSOC4_CHIP_PROT_VIRGIN 0x0
79 #define PSOC4_CHIP_PROT_OPEN 0x1
80 #define PSOC4_CHIP_PROT_PROTECTED 0x2
81 #define PSOC4_CHIP_PROT_KILL 0x4
84 struct psoc4_chip_details
{
88 uint32_t flash_size_in_kb
;
91 /* list of PSoC 4 chips
92 * flash_size_in_kb is not necessary as it can be decoded from SPCIF_GEOMETRY
94 const struct psoc4_chip_details psoc4_devices
[] = {
96 { 0x04A6, "CY8C4245PVI-482", "SSOP-28", .flash_size_in_kb
= 32 },
97 { 0x04B6, "CY8C4245LQI-483", "QFN-40", .flash_size_in_kb
= 32 },
98 { 0x04C8, "CY8C4245AXI-483", "TQFP-44", .flash_size_in_kb
= 32 },
99 { 0x04FB, "CY8C4245AXI-473", "TQFP-44", .flash_size_in_kb
= 32 },
100 { 0x04F0, "CY8C4244PVI-432", "SSOP-28", .flash_size_in_kb
= 16 },
101 { 0x04F1, "CY8C4244PVI-442", "SSOP-28", .flash_size_in_kb
= 16 },
102 { 0x04F6, "CY8C4244LQI-443", "QFN-40", .flash_size_in_kb
= 16 },
103 { 0x04FA, "CY8C4244AXI-443", "TQFP-44", .flash_size_in_kb
= 16 },
106 { 0x0410, "CY8C4124PVI-432", "SSOP-28", .flash_size_in_kb
= 16 },
107 { 0x0411, "CY8C4124PVI-442", "SSOP-28", .flash_size_in_kb
= 16 },
108 { 0x0416, "CY8C4124LQI-443", "QFN-40", .flash_size_in_kb
= 16 },
109 { 0x041A, "CY8C4124AXI-443", "TQFP-44", .flash_size_in_kb
= 16 },
110 { 0x041B, "CY8C4125AXI-473", "TQFP-44", .flash_size_in_kb
= 32 },
111 { 0x0412, "CY8C4125PVI-482", "SSOP-28", .flash_size_in_kb
= 32 },
112 { 0x0417, "CY8C4125LQI-483", "QFN-40", .flash_size_in_kb
= 32 },
113 { 0x041C, "CY8C4125AXI-483", "TQFP-44", .flash_size_in_kb
= 32 },
116 { 0x0490, "CYPD1103-35FNXI", "CSP-35", .flash_size_in_kb
= 32 },
117 { 0x0489, "CYPD1121-40LQXI", "QFN-40", .flash_size_in_kb
= 32 },
118 { 0x048A, "CYPD1122-40LQXI", "QFN-40", .flash_size_in_kb
= 32 },
119 { 0x0491, "CYPD1131-35FNXI", "CSP-35", .flash_size_in_kb
= 32 },
120 { 0x0498, "CYPD1132-16SXI", "SOIC-16", .flash_size_in_kb
= 32 },
121 { 0x0481, "CYPD1134-28PVXI", "SSOP-28", .flash_size_in_kb
= 32 },
122 { 0x048B, "CYPD1134-40LQXI", "QFN-40", .flash_size_in_kb
= 32 },
126 struct psoc4_flash_bank
{
128 uint32_t user_bank_size
;
131 uint8_t chip_protection
;
132 uint8_t cmd_program_row
;
136 static const struct psoc4_chip_details
*psoc4_details_by_id(uint32_t silicon_id
)
138 const struct psoc4_chip_details
*p
= psoc4_devices
;
140 uint16_t id
= silicon_id
>> 16; /* ignore die revision */
141 for (i
= 0; i
< sizeof(psoc4_devices
)/sizeof(psoc4_devices
[0]); i
++, p
++) {
145 LOG_DEBUG("Unknown PSoC 4 device silicon id 0x%08" PRIx32
".", silicon_id
);
149 static const char *psoc4_decode_chip_protection(uint8_t protection
)
151 switch (protection
) {
152 case PSOC4_CHIP_PROT_VIRGIN
:
153 return "protection VIRGIN";
154 case PSOC4_CHIP_PROT_OPEN
:
155 return "protection open";
156 case PSOC4_CHIP_PROT_PROTECTED
:
158 case PSOC4_CHIP_PROT_KILL
:
159 return "protection KILL";
161 LOG_WARNING("Unknown protection state 0x%02" PRIx8
"", protection
);
167 /* flash bank <name> psoc <base> <size> 0 0 <target#>
169 FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command
)
171 struct psoc4_flash_bank
*psoc4_info
;
174 return ERROR_COMMAND_SYNTAX_ERROR
;
176 psoc4_info
= calloc(1, sizeof(struct psoc4_flash_bank
));
178 bank
->driver_priv
= psoc4_info
;
179 psoc4_info
->user_bank_size
= bank
->size
;
185 /* PSoC 4 system ROM request
186 * Setting SROM_SYSREQ_BIT in CPUSS_SYSREQ register runs NMI service
187 * in sysrem ROM. Algorithm just waits for NMI to finish.
188 * When sysreq_params_size == 0 only one parameter is passed in CPUSS_SYSARG register.
189 * Otherwise address of memory parameter block is set in CPUSS_SYSARG
190 * and the first parameter is written to the first word of parameter block
192 static int psoc4_sysreq(struct target
*target
, uint8_t cmd
, uint16_t cmd_param
,
193 uint32_t *sysreq_params
, uint32_t sysreq_params_size
)
195 struct working_area
*sysreq_wait_algorithm
;
196 struct working_area
*sysreq_mem
;
198 struct reg_param reg_params
[1];
199 struct armv7m_algorithm armv7m_info
;
201 int retval
= ERROR_OK
;
203 uint32_t param1
= PSOC4_SROM_KEY1
204 | ((PSOC4_SROM_KEY2
+ cmd
) << 8)
207 static uint8_t psoc4_sysreq_wait_code
[] = {
208 /* system request NMI is served immediately after algo run
209 now we are done: break */
210 0x00, 0xbe, /* bkpt 0 */
213 const int code_words
= (sizeof(psoc4_sysreq_wait_code
) + 3) / 4;
214 /* stack must be aligned */
215 const int stack_size
= 196;
216 /* tested stack sizes on PSoC 4:
222 /* allocate area for sysreq wait code and stack */
223 if (target_alloc_working_area(target
, code_words
* 4 + stack_size
,
224 &sysreq_wait_algorithm
) != ERROR_OK
) {
225 LOG_DEBUG("no working area for sysreq code");
226 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
230 retval
= target_write_buffer(target
,
231 sysreq_wait_algorithm
->address
,
232 sizeof(psoc4_sysreq_wait_code
),
233 psoc4_sysreq_wait_code
);
234 if (retval
!= ERROR_OK
) {
235 /* we already allocated the writing code, but failed to get a
236 * buffer, free the algorithm */
240 if (sysreq_params_size
) {
241 /* Allocate memory for sysreq_params */
242 retval
= target_alloc_working_area(target
, sysreq_params_size
, &sysreq_mem
);
243 if (retval
!= ERROR_OK
) {
244 LOG_WARNING("no working area for sysreq parameters");
246 /* we already allocated the writing code, but failed to get a
247 * buffer, free the algorithm */
248 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
252 /* Write sysreq_params */
253 sysreq_params
[0] = param1
;
254 retval
= target_write_buffer(target
, sysreq_mem
->address
,
255 sysreq_params_size
, (uint8_t *)sysreq_params
);
256 if (retval
!= ERROR_OK
)
259 /* Set address of sysreq parameters block */
260 retval
= target_write_u32(target
, PSOC4_CPUSS_SYSARG
, sysreq_mem
->address
);
261 if (retval
!= ERROR_OK
)
265 /* Sysreq without memory block of parameters */
266 /* Set register parameter */
267 retval
= target_write_u32(target
, PSOC4_CPUSS_SYSARG
, param1
);
268 if (retval
!= ERROR_OK
)
272 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
273 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
276 init_reg_param(®_params
[0], "sp", 32, PARAM_OUT
);
277 buf_set_u32(reg_params
[0].value
, 0, 32,
278 sysreq_wait_algorithm
->address
+ sysreq_wait_algorithm
->size
);
280 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
281 if (armv7m
== NULL
) {
283 /* something is very wrong if armv7m is NULL */
284 LOG_ERROR("unable to get armv7m target");
288 /* Set SROM request */
289 retval
= target_write_u32(target
, PSOC4_CPUSS_SYSREQ
,
290 PSOC4_SROM_SYSREQ_BIT
| PSOC4_SROM_HMASTER_BIT
| cmd
);
291 if (retval
!= ERROR_OK
)
294 /* Execute wait code */
295 retval
= target_run_algorithm(target
, 0, NULL
,
296 sizeof(reg_params
) / sizeof(*reg_params
), reg_params
,
297 sysreq_wait_algorithm
->address
, 0, 1000, &armv7m_info
);
298 if (retval
!= ERROR_OK
)
299 LOG_ERROR("sysreq wait code execution failed");
302 destroy_reg_param(®_params
[0]);
305 if (sysreq_params_size
)
306 target_free_working_area(target
, sysreq_mem
);
309 target_free_working_area(target
, sysreq_wait_algorithm
);
315 /* helper routine to get silicon ID from a PSoC 4 chip */
316 static int psoc4_get_silicon_id(struct target
*target
, uint32_t *silicon_id
, uint8_t *protection
)
318 uint32_t params
= PSOC4_SROM_KEY1
319 | ((PSOC4_SROM_KEY2
+ PSOC4_CMD_GET_SILICON_ID
) << 8);
320 uint32_t part0
, part1
;
322 int retval
= psoc4_sysreq(target
, PSOC4_CMD_GET_SILICON_ID
, 0, NULL
, 0);
323 if (retval
!= ERROR_OK
)
326 retval
= target_read_u32(target
, PSOC4_CPUSS_SYSARG
, &part0
);
327 if (retval
!= ERROR_OK
)
330 if (part0
== params
) {
331 LOG_ERROR("sysreq silicon id request not served");
335 retval
= target_read_u32(target
, PSOC4_CPUSS_SYSREQ
, &part1
);
336 if (retval
!= ERROR_OK
)
339 uint32_t silicon
= ((part0
& 0xffff) << 16)
340 | (((part0
>> 16) & 0xff) << 8)
342 uint8_t prot
= (part1
>> 12) & 0xff;
345 *silicon_id
= silicon
;
349 LOG_DEBUG("silicon id: 0x%08" PRIx32
"", silicon
);
350 LOG_DEBUG("protection: 0x%02" PRIx8
"", prot
);
355 static int psoc4_protect_check(struct flash_bank
*bank
)
357 struct target
*target
= bank
->target
;
358 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
360 uint32_t prot_addr
= PSOC4_SFLASH_MACRO
;
364 int retval
= ERROR_OK
;
366 num_bits
= bank
->num_sectors
;
368 for (i
= 0; i
< num_bits
; i
+= 32) {
369 retval
= target_read_u32(target
, prot_addr
, &protection
);
370 if (retval
!= ERROR_OK
)
375 for (s
= 0; s
< 32; s
++) {
376 if (i
+ s
>= num_bits
)
378 bank
->sectors
[i
+ s
].is_protected
= (protection
& (1 << s
)) ? 1 : 0;
382 retval
= psoc4_get_silicon_id(target
, NULL
, &(psoc4_info
->chip_protection
));
387 static int psoc4_mass_erase(struct flash_bank
*bank
)
389 struct target
*target
= bank
->target
;
392 if (bank
->target
->state
!= TARGET_HALTED
) {
393 LOG_ERROR("Target not halted");
394 return ERROR_TARGET_NOT_HALTED
;
397 /* Call "Erase All" system ROM API */
399 int retval
= psoc4_sysreq(target
, PSOC4_CMD_ERASE_ALL
,
401 ¶m
, sizeof(param
));
403 if (retval
== ERROR_OK
)
404 /* set all sectors as erased */
405 for (i
= 0; i
< bank
->num_sectors
; i
++)
406 bank
->sectors
[i
].is_erased
= 1;
412 static int psoc4_erase(struct flash_bank
*bank
, int first
, int last
)
414 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
415 if (psoc4_info
->cmd_program_row
== PSOC4_CMD_WRITE_ROW
) {
416 LOG_INFO("Autoerase enabled, erase command ignored");
420 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
421 return psoc4_mass_erase(bank
);
423 LOG_ERROR("Only mass erase available");
429 static int psoc4_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
431 struct target
*target
= bank
->target
;
432 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
434 if (psoc4_info
->probed
== 0)
437 if (target
->state
!= TARGET_HALTED
) {
438 LOG_ERROR("Target not halted");
439 return ERROR_TARGET_NOT_HALTED
;
442 uint32_t *sysrq_buffer
= NULL
;
444 int num_bits
= bank
->num_sectors
;
445 const int param_sz
= 8;
446 int prot_sz
= num_bits
/ 8;
447 int chip_prot
= PSOC4_CHIP_PROT_OPEN
;
448 int flash_macro
= 0; /* PSoC 42xx has only macro 0 */
451 sysrq_buffer
= calloc(1, param_sz
+ prot_sz
);
452 if (sysrq_buffer
== NULL
) {
453 LOG_ERROR("no memory for row buffer");
457 for (i
= first
; i
< num_bits
&& i
<= last
; i
++)
458 bank
->sectors
[i
].is_protected
= set
;
460 uint32_t *p
= sysrq_buffer
+ 2;
461 for (i
= 0; i
< num_bits
; i
++) {
462 if (bank
->sectors
[i
].is_protected
)
463 p
[i
/ 32] |= 1 << (i
% 32);
466 /* Call "Load Latch" system ROM API */
467 sysrq_buffer
[1] = prot_sz
- 1;
468 retval
= psoc4_sysreq(target
, PSOC4_CMD_LOAD_LATCH
,
469 0, /* Byte number in latch from what to write */
470 sysrq_buffer
, param_sz
+ psoc4_info
->row_size
);
471 if (retval
!= ERROR_OK
)
474 /* Call "Write Protection" system ROM API */
475 retval
= psoc4_sysreq(target
, PSOC4_CMD_WRITE_PROTECTION
,
476 chip_prot
| (flash_macro
<< 8), NULL
, 0);
478 if (retval
!= ERROR_OK
)
479 psoc4_protect_check(bank
);
488 COMMAND_HANDLER(psoc4_handle_flash_autoerase_command
)
491 return ERROR_COMMAND_SYNTAX_ERROR
;
493 struct flash_bank
*bank
;
494 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
495 if (ERROR_OK
!= retval
)
498 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
499 bool enable
= psoc4_info
->cmd_program_row
== PSOC4_CMD_WRITE_ROW
;
502 COMMAND_PARSE_ON_OFF(CMD_ARGV
[1], enable
);
505 psoc4_info
->cmd_program_row
= PSOC4_CMD_WRITE_ROW
;
506 LOG_INFO("Flash auto-erase enabled, non mass erase commands will be ignored.");
508 psoc4_info
->cmd_program_row
= PSOC4_CMD_PROGRAM_ROW
;
509 LOG_INFO("Flash auto-erase disabled. Use psoc mass_erase before flash programming.");
516 static int psoc4_write(struct flash_bank
*bank
, const uint8_t *buffer
,
517 uint32_t offset
, uint32_t count
)
519 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
520 struct target
*target
= bank
->target
;
521 uint32_t *sysrq_buffer
= NULL
;
522 int retval
= ERROR_OK
;
523 const int param_sz
= 8;
525 if (bank
->target
->state
!= TARGET_HALTED
) {
526 LOG_ERROR("Target not halted");
527 return ERROR_TARGET_NOT_HALTED
;
531 LOG_ERROR("offset 0x%08" PRIx32
" breaks required 2-byte alignment", offset
);
532 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
535 sysrq_buffer
= malloc(param_sz
+ psoc4_info
->row_size
);
536 if (sysrq_buffer
== NULL
) {
537 LOG_ERROR("no memory for row buffer");
541 uint8_t *row_buffer
= (uint8_t *)sysrq_buffer
+ param_sz
;
542 uint32_t row_num
= offset
/ psoc4_info
->row_size
;
543 uint32_t row_offset
= offset
- row_num
* psoc4_info
->row_size
;
545 memset(row_buffer
, 0, row_offset
);
547 bool save_poll
= jtag_poll_get_enabled();
548 jtag_poll_set_enabled(false);
551 uint32_t chunk_size
= psoc4_info
->row_size
- row_offset
;
552 if (chunk_size
> count
) {
554 memset(row_buffer
+ chunk_size
, 0, psoc4_info
->row_size
- chunk_size
);
556 memcpy(row_buffer
+ row_offset
, buffer
, chunk_size
);
557 LOG_DEBUG("offset / row: 0x%08" PRIx32
" / %" PRIu32
", size %" PRIu32
"",
558 offset
, row_offset
, chunk_size
);
560 /* Call "Load Latch" system ROM API */
561 sysrq_buffer
[1] = psoc4_info
->row_size
- 1;
562 retval
= psoc4_sysreq(target
, PSOC4_CMD_LOAD_LATCH
,
563 0, /* Byte number in latch from what to write */
564 sysrq_buffer
, param_sz
+ psoc4_info
->row_size
);
565 if (retval
!= ERROR_OK
)
568 /* Call "Program Row" or "Write Row" system ROM API */
569 uint32_t sysrq_param
;
570 retval
= psoc4_sysreq(target
, psoc4_info
->cmd_program_row
,
572 &sysrq_param
, sizeof(sysrq_param
));
573 if (retval
!= ERROR_OK
)
576 buffer
+= chunk_size
;
583 jtag_poll_set_enabled(save_poll
);
592 static int psoc4_probe(struct flash_bank
*bank
)
594 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
595 struct target
*target
= bank
->target
;
596 uint32_t flash_size_in_kb
= 0;
597 uint32_t max_flash_size_in_kb
;
601 uint32_t base_address
= 0x00000000;
604 if (target
->state
!= TARGET_HALTED
) {
605 LOG_ERROR("Target not halted");
606 return ERROR_TARGET_NOT_HALTED
;
609 psoc4_info
->probed
= 0;
610 psoc4_info
->cmd_program_row
= PSOC4_CMD_PROGRAM_ROW
;
612 /* Get the CPUID from the ARM Core
613 * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/DDI0432C_cortex_m0_r0p0_trm.pdf 4.2.1 */
614 int retval
= target_read_u32(target
, 0xE000ED00, &cpu_id
);
615 if (retval
!= ERROR_OK
)
618 LOG_DEBUG("cpu id = 0x%08" PRIx32
"", cpu_id
);
620 /* set page size, protection granularity and max flash size depending on family */
621 switch ((cpu_id
>> 4) & 0xFFF) {
622 case 0xc20: /* M0 -> PSoC4 */
624 max_flash_size_in_kb
= 32;
627 LOG_WARNING("Cannot identify target as a PSoC 4 family.");
631 uint32_t spcif_geometry
;
632 retval
= target_read_u32(target
, PSOC4_SPCIF_GEOMETRY
, &spcif_geometry
);
633 if (retval
== ERROR_OK
) {
634 row_size
= 128 * ((spcif_geometry
>> 22) & 3);
635 flash_size_in_kb
= (spcif_geometry
& 0xffff) * 256 / 1024;
636 LOG_INFO("SPCIF geometry: %" PRIu32
" kb flash, row %" PRIu32
" bytes.",
637 flash_size_in_kb
, row_size
);
640 /* Early revisions of ST-Link v2 have some problem reading PSOC4_SPCIF_GEOMETRY
641 and an error is reported late. Dummy read gets this error. */
643 target_read_u32(target
, PSOC4_CPUSS_SYSREQ
, &dummy
);
645 /* get silicon ID from target. */
646 retval
= psoc4_get_silicon_id(target
, &silicon_id
, &protection
);
647 if (retval
!= ERROR_OK
)
650 const struct psoc4_chip_details
*details
= psoc4_details_by_id(silicon_id
);
652 LOG_INFO("%s device detected.", details
->type
);
653 if (flash_size_in_kb
== 0)
654 flash_size_in_kb
= details
->flash_size_in_kb
;
655 else if (flash_size_in_kb
!= details
->flash_size_in_kb
)
656 LOG_ERROR("Flash size mismatch");
659 psoc4_info
->row_size
= row_size
;
660 psoc4_info
->silicon_id
= silicon_id
;
661 psoc4_info
->chip_protection
= protection
;
663 /* failed reading flash size or flash size invalid (early silicon),
664 * default to max target family */
665 if (retval
!= ERROR_OK
|| flash_size_in_kb
== 0xffff || flash_size_in_kb
== 0) {
666 LOG_WARNING("PSoC 4 flash size failed, probe inaccurate - assuming %" PRIu32
" k flash",
667 max_flash_size_in_kb
);
668 flash_size_in_kb
= max_flash_size_in_kb
;
671 /* if the user sets the size manually then ignore the probed value
672 * this allows us to work around devices that have a invalid flash size register value */
673 if (psoc4_info
->user_bank_size
) {
674 LOG_INFO("ignoring flash probed value, using configured bank size");
675 flash_size_in_kb
= psoc4_info
->user_bank_size
/ 1024;
678 LOG_INFO("flash size = %" PRIu32
" kbytes", flash_size_in_kb
);
680 /* did we assign flash size? */
681 assert(flash_size_in_kb
!= 0xffff);
683 /* calculate numbers of pages */
684 uint32_t num_rows
= flash_size_in_kb
* 1024 / row_size
;
686 /* check that calculation result makes sense */
687 assert(num_rows
> 0);
691 bank
->sectors
= NULL
;
694 bank
->base
= base_address
;
695 bank
->size
= num_rows
* row_size
;
696 bank
->num_sectors
= num_rows
;
697 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_rows
);
700 for (i
= 0; i
< num_rows
; i
++) {
701 bank
->sectors
[i
].offset
= i
* row_size
;
702 bank
->sectors
[i
].size
= row_size
;
703 bank
->sectors
[i
].is_erased
= -1;
704 bank
->sectors
[i
].is_protected
= 1;
707 LOG_INFO("flash bank set %" PRIu32
" rows", num_rows
);
708 psoc4_info
->probed
= 1;
713 static int psoc4_auto_probe(struct flash_bank
*bank
)
715 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
716 if (psoc4_info
->probed
)
718 return psoc4_probe(bank
);
722 static int get_psoc4_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
724 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
727 if (psoc4_info
->probed
== 0)
730 const struct psoc4_chip_details
*details
= psoc4_details_by_id(psoc4_info
->silicon_id
);
733 uint32_t chip_revision
= psoc4_info
->silicon_id
& 0xffff;
734 printed
= snprintf(buf
, buf_size
, "PSoC 4 %s rev 0x%04" PRIx32
" package %s",
735 details
->type
, chip_revision
, details
->package
);
737 printed
= snprintf(buf
, buf_size
, "PSoC 4 silicon id 0x%08" PRIx32
"",
738 psoc4_info
->silicon_id
);
743 const char *prot_txt
= psoc4_decode_chip_protection(psoc4_info
->chip_protection
);
744 uint32_t size_in_kb
= bank
->size
/ 1024;
745 snprintf(buf
, buf_size
, " flash %" PRIu32
" kb %s", size_in_kb
, prot_txt
);
750 COMMAND_HANDLER(psoc4_handle_mass_erase_command
)
753 return ERROR_COMMAND_SYNTAX_ERROR
;
755 struct flash_bank
*bank
;
756 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
757 if (ERROR_OK
!= retval
)
760 retval
= psoc4_mass_erase(bank
);
761 if (retval
== ERROR_OK
)
762 command_print(CMD_CTX
, "psoc mass erase complete");
764 command_print(CMD_CTX
, "psoc mass erase failed");
770 static const struct command_registration psoc4_exec_command_handlers
[] = {
772 .name
= "mass_erase",
773 .handler
= psoc4_handle_mass_erase_command
,
774 .mode
= COMMAND_EXEC
,
776 .help
= "Erase entire flash device.",
779 .name
= "flash_autoerase",
780 .handler
= psoc4_handle_flash_autoerase_command
,
781 .mode
= COMMAND_EXEC
,
782 .usage
= "bank_id on|off",
783 .help
= "Set autoerase mode for flash bank.",
785 COMMAND_REGISTRATION_DONE
788 static const struct command_registration psoc4_command_handlers
[] = {
792 .help
= "PSoC 4 flash command group",
794 .chain
= psoc4_exec_command_handlers
,
796 COMMAND_REGISTRATION_DONE
799 struct flash_driver psoc4_flash
= {
801 .commands
= psoc4_command_handlers
,
802 .flash_bank_command
= psoc4_flash_bank_command
,
803 .erase
= psoc4_erase
,
804 .protect
= psoc4_protect
,
805 .write
= psoc4_write
,
806 .read
= default_flash_read
,
807 .probe
= psoc4_probe
,
808 .auto_probe
= psoc4_auto_probe
,
809 .erase_check
= default_flash_blank_check
,
810 .protect_check
= psoc4_protect_check
,
811 .info
= get_psoc4_info
,
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)