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. *
23 ***************************************************************************/
30 #include <helper/binarybuffer.h>
31 #include <jtag/jtag.h>
32 #include <target/algorithm.h>
33 #include <target/armv7m.h>
37 PSoC(R) 4: PSoC 4200 Family Datasheet
38 Document Number: 001-87197 Rev. *B Revised August 29, 2013
40 PSoC 4100/4200 Family PSoC(R) 4 Architecture TRM
41 Document No. 001-85634 Rev. *C March 25, 2014
43 PSoC(R) 4 Registers TRM Spec.
44 Document No. 001-85847 Rev. *A June 25, 2013
46 CY8C41xx, CY8C42xx Programming Specifications
47 Document No. 001-81799 Rev. *C March 4, 2014
50 /* register locations */
51 #define PSOC4_CPUSS_SYSREQ 0x40000004
52 #define PSOC4_CPUSS_SYSARG 0x40000008
53 #define PSOC4_TEST_MODE 0x40030014
54 #define PSOC4_SPCIF_GEOMETRY 0x400E0000
56 #define PSOC4_SFLASH_MACRO 0x0ffff000
59 #define PSOC4_SROM_KEY1 0xb6
60 #define PSOC4_SROM_KEY2 0xd3
61 #define PSOC4_SROM_SYSREQ_BIT (1<<31)
62 #define PSOC4_SROM_HMASTER_BIT (1<<30)
63 #define PSOC4_SROM_PRIVILEGED_BIT (1<<28)
64 #define PSOC4_SROM_STATUS_SUCCEEDED 0xa0000000
65 #define PSOC4_SROM_STATUS_FAILED 0xf0000000
67 #define PSOC4_CMD_GET_SILICON_ID 0
68 #define PSOC4_CMD_LOAD_LATCH 4
69 #define PSOC4_CMD_WRITE_ROW 5
70 #define PSOC4_CMD_PROGRAM_ROW 6
71 #define PSOC4_CMD_ERASE_ALL 0xa
72 #define PSOC4_CMD_CHECKSUM 0xb
73 #define PSOC4_CMD_WRITE_PROTECTION 0xd
75 #define PSOC4_CHIP_PROT_VIRGIN 0x0
76 #define PSOC4_CHIP_PROT_OPEN 0x1
77 #define PSOC4_CHIP_PROT_PROTECTED 0x2
78 #define PSOC4_CHIP_PROT_KILL 0x4
81 struct psoc4_chip_details
{
85 uint16_t flash_size_in_kb
;
88 /* list of PSoC 4 chips
89 * flash_size_in_kb is not necessary as it can be decoded from SPCIF_GEOMETRY
91 const struct psoc4_chip_details psoc4_devices
[] = {
93 { 0x04A6, "CY8C4245PVI-482", "SSOP-28", .flash_size_in_kb
= 32 },
94 { 0x04B6, "CY8C4245LQI-483", "QFN-40", .flash_size_in_kb
= 32 },
95 { 0x04C8, "CY8C4245AXI-483", "TQFP-44", .flash_size_in_kb
= 32 },
96 { 0x04FB, "CY8C4245AXI-473", "TQFP-44", .flash_size_in_kb
= 32 },
97 { 0x04F0, "CY8C4244PVI-432", "SSOP-28", .flash_size_in_kb
= 16 },
98 { 0x04F1, "CY8C4244PVI-442", "SSOP-28", .flash_size_in_kb
= 16 },
99 { 0x04F6, "CY8C4244LQI-443", "QFN-40", .flash_size_in_kb
= 16 },
100 { 0x04FA, "CY8C4244AXI-443", "TQFP-44", .flash_size_in_kb
= 16 },
103 { 0x0410, "CY8C4124PVI-432", "SSOP-28", .flash_size_in_kb
= 16 },
104 { 0x0411, "CY8C4124PVI-442", "SSOP-28", .flash_size_in_kb
= 16 },
105 { 0x0416, "CY8C4124LQI-443", "QFN-40", .flash_size_in_kb
= 16 },
106 { 0x041A, "CY8C4124AXI-443", "TQFP-44", .flash_size_in_kb
= 16 },
107 { 0x041B, "CY8C4125AXI-473", "TQFP-44", .flash_size_in_kb
= 32 },
108 { 0x0412, "CY8C4125PVI-482", "SSOP-28", .flash_size_in_kb
= 32 },
109 { 0x0417, "CY8C4125LQI-483", "QFN-40", .flash_size_in_kb
= 32 },
110 { 0x041C, "CY8C4125AXI-483", "TQFP-44", .flash_size_in_kb
= 32 },
114 struct psoc4_flash_bank
{
116 uint32_t user_bank_size
;
119 uint8_t chip_protection
;
120 uint16_t cmd_program_row
;
124 static const struct psoc4_chip_details
*psoc4_details_by_id(uint32_t silicon_id
)
126 const struct psoc4_chip_details
*p
= psoc4_devices
;
128 uint16_t id
= silicon_id
>> 16; /* ignore die revision */
129 for (i
= 0; i
< sizeof(psoc4_devices
)/sizeof(psoc4_devices
[0]); i
++, p
++) {
133 LOG_DEBUG("Unknown PSoC 4 device silicon id 0x%08" PRIx32
".", silicon_id
);
137 static const char *psoc4_decode_chip_protection(uint8_t protection
)
139 switch (protection
) {
140 case PSOC4_CHIP_PROT_VIRGIN
:
141 return "protection VIRGIN";
142 case PSOC4_CHIP_PROT_OPEN
:
143 return "protection open";
144 case PSOC4_CHIP_PROT_PROTECTED
:
146 case PSOC4_CHIP_PROT_KILL
:
147 return "protection KILL";
149 LOG_WARNING("Unknown protection state 0x%02" PRIx8
"", protection
);
155 /* flash bank <name> psoc <base> <size> 0 0 <target#>
157 FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command
)
159 struct psoc4_flash_bank
*psoc4_info
;
162 return ERROR_COMMAND_SYNTAX_ERROR
;
164 psoc4_info
= calloc(1, sizeof(struct psoc4_flash_bank
));
166 bank
->driver_priv
= psoc4_info
;
167 psoc4_info
->user_bank_size
= bank
->size
;
173 /* PSoC 4 system ROM request
174 * Setting SROM_SYSREQ_BIT in CPUSS_SYSREQ register runs NMI service
175 * in sysrem ROM. Algorithm just waits for NMI to finish.
176 * When sysreq_params_size == 0 only one parameter is passed in CPUSS_SYSARG register.
177 * Otherwise address of memory parameter block is set in CPUSS_SYSARG
178 * and the first parameter is written to the first word of parameter block
180 static int psoc4_sysreq(struct target
*target
, uint8_t cmd
, uint16_t cmd_param
,
181 uint32_t *sysreq_params
, uint32_t sysreq_params_size
)
183 struct working_area
*sysreq_wait_algorithm
;
184 struct working_area
*sysreq_mem
;
186 struct reg_param reg_params
[1];
187 struct armv7m_algorithm armv7m_info
;
189 int retval
= ERROR_OK
;
191 uint32_t param1
= PSOC4_SROM_KEY1
192 | ((PSOC4_SROM_KEY2
+ cmd
) << 8)
195 static uint8_t psoc4_sysreq_wait_code
[] = {
196 /* system request NMI is served immediately after algo run
197 now we are done: break */
198 0x00, 0xbe, /* bkpt 0 */
201 const int code_words
= (sizeof(psoc4_sysreq_wait_code
) + 3) / 4;
202 /* stack must be aligned */
203 const int stack_size
= 196;
204 /* tested stack sizes on PSoC 4:
210 /* allocate area for sysreq wait code and stack */
211 if (target_alloc_working_area(target
, code_words
* 4 + stack_size
,
212 &sysreq_wait_algorithm
) != ERROR_OK
) {
213 LOG_DEBUG("no working area for sysreq code");
214 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
218 retval
= target_write_buffer(target
,
219 sysreq_wait_algorithm
->address
,
220 sizeof(psoc4_sysreq_wait_code
),
221 psoc4_sysreq_wait_code
);
222 if (retval
!= ERROR_OK
) {
223 /* we already allocated the writing code, but failed to get a
224 * buffer, free the algorithm */
228 if (sysreq_params_size
) {
229 /* Allocate memory for sysreq_params */
230 retval
= target_alloc_working_area(target
, sysreq_params_size
, &sysreq_mem
);
231 if (retval
!= ERROR_OK
) {
232 LOG_WARNING("no working area for sysreq parameters");
234 /* we already allocated the writing code, but failed to get a
235 * buffer, free the algorithm */
236 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
240 /* Write sysreq_params */
241 sysreq_params
[0] = param1
;
242 retval
= target_write_buffer(target
, sysreq_mem
->address
,
243 sysreq_params_size
, (uint8_t *)sysreq_params
);
244 if (retval
!= ERROR_OK
)
247 /* Set address of sysreq parameters block */
248 retval
= target_write_u32(target
, PSOC4_CPUSS_SYSARG
, sysreq_mem
->address
);
249 if (retval
!= ERROR_OK
)
253 /* Sysreq without memory block of parameters */
254 /* Set register parameter */
255 retval
= target_write_u32(target
, PSOC4_CPUSS_SYSARG
, param1
);
256 if (retval
!= ERROR_OK
)
260 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
261 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
264 init_reg_param(®_params
[0], "sp", 32, PARAM_OUT
);
265 buf_set_u32(reg_params
[0].value
, 0, 32,
266 sysreq_wait_algorithm
->address
+ sysreq_wait_algorithm
->size
);
268 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
269 if (armv7m
== NULL
) {
271 /* something is very wrong if armv7m is NULL */
272 LOG_ERROR("unable to get armv7m target");
276 /* Set SROM request */
277 retval
= target_write_u32(target
, PSOC4_CPUSS_SYSREQ
,
278 PSOC4_SROM_SYSREQ_BIT
| PSOC4_SROM_HMASTER_BIT
| cmd
);
279 if (retval
!= ERROR_OK
)
282 /* Execute wait code */
283 retval
= target_run_algorithm(target
, 0, NULL
,
284 sizeof(reg_params
) / sizeof(*reg_params
), reg_params
,
285 sysreq_wait_algorithm
->address
, 0, 1000, &armv7m_info
);
286 if (retval
!= ERROR_OK
)
287 LOG_ERROR("sysreq wait code execution failed");
290 destroy_reg_param(®_params
[0]);
293 if (sysreq_params_size
)
294 target_free_working_area(target
, sysreq_mem
);
297 target_free_working_area(target
, sysreq_wait_algorithm
);
303 /* helper routine to get silicon ID from a PSoC 4 chip */
304 static int psoc4_get_silicon_id(struct target
*target
, uint32_t *silicon_id
, uint8_t *protection
)
306 uint32_t params
= PSOC4_SROM_KEY1
307 | ((PSOC4_SROM_KEY2
+ PSOC4_CMD_GET_SILICON_ID
) << 8);
308 uint32_t part0
, part1
;
310 int retval
= psoc4_sysreq(target
, PSOC4_CMD_GET_SILICON_ID
, 0, NULL
, 0);
311 if (retval
!= ERROR_OK
)
314 retval
= target_read_u32(target
, PSOC4_CPUSS_SYSARG
, &part0
);
315 if (retval
!= ERROR_OK
)
318 if (part0
== params
) {
319 LOG_ERROR("sysreq silicon id request not served");
323 retval
= target_read_u32(target
, PSOC4_CPUSS_SYSREQ
, &part1
);
324 if (retval
!= ERROR_OK
)
327 uint32_t silicon
= ((part0
& 0xffff) << 16)
328 | (((part0
>> 16) & 0xff) << 8)
330 uint8_t prot
= (part1
>> 12) & 0xff;
333 *silicon_id
= silicon
;
337 LOG_DEBUG("silicon id: 0x%" PRIx32
"", silicon
);
338 LOG_DEBUG("protection: 0x%" PRIx8
"", prot
);
343 static int psoc4_protect_check(struct flash_bank
*bank
)
345 struct target
*target
= bank
->target
;
346 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
348 uint32_t prot_addr
= PSOC4_SFLASH_MACRO
;
352 int retval
= ERROR_OK
;
354 num_bits
= bank
->num_sectors
;
356 for (i
= 0; i
< num_bits
; i
+= 32) {
357 retval
= target_read_u32(target
, prot_addr
, &protection
);
358 if (retval
!= ERROR_OK
)
363 for (s
= 0; s
< 32; s
++) {
364 if (i
+ s
>= num_bits
)
366 bank
->sectors
[i
+ s
].is_protected
= (protection
& (1 << s
)) ? 1 : 0;
370 retval
= psoc4_get_silicon_id(target
, NULL
, &(psoc4_info
->chip_protection
));
375 static int psoc4_mass_erase(struct flash_bank
*bank
)
377 struct target
*target
= bank
->target
;
380 if (bank
->target
->state
!= TARGET_HALTED
) {
381 LOG_ERROR("Target not halted");
382 return ERROR_TARGET_NOT_HALTED
;
385 /* Call "Erase All" system ROM API */
387 int retval
= psoc4_sysreq(target
, PSOC4_CMD_ERASE_ALL
,
389 ¶m
, sizeof(param
));
391 if (retval
== ERROR_OK
)
392 /* set all sectors as erased */
393 for (i
= 0; i
< bank
->num_sectors
; i
++)
394 bank
->sectors
[i
].is_erased
= 1;
400 static int psoc4_erase(struct flash_bank
*bank
, int first
, int last
)
402 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
403 if (psoc4_info
->cmd_program_row
== PSOC4_CMD_WRITE_ROW
) {
404 LOG_INFO("Autoerase enabled, erase command ignored");
408 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
409 return psoc4_mass_erase(bank
);
411 LOG_ERROR("Only mass erase available");
417 static int psoc4_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
419 struct target
*target
= bank
->target
;
420 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
422 if (psoc4_info
->probed
== 0)
425 if (target
->state
!= TARGET_HALTED
) {
426 LOG_ERROR("Target not halted");
427 return ERROR_TARGET_NOT_HALTED
;
430 uint32_t *sysrq_buffer
= NULL
;
432 int num_bits
= bank
->num_sectors
;
433 const int param_sz
= 8;
434 int prot_sz
= num_bits
/ 8;
435 int chip_prot
= PSOC4_CHIP_PROT_OPEN
;
436 int flash_macro
= 0; /* PSoC 42xx has only macro 0 */
439 sysrq_buffer
= calloc(1, param_sz
+ prot_sz
);
440 if (sysrq_buffer
== NULL
) {
441 LOG_ERROR("no memory for row buffer");
445 for (i
= first
; i
< num_bits
&& i
<= last
; i
++)
446 bank
->sectors
[i
].is_protected
= set
;
448 uint32_t *p
= sysrq_buffer
+ 2;
449 for (i
= 0; i
< num_bits
; i
++) {
450 if (bank
->sectors
[i
].is_protected
)
451 p
[i
/ 32] |= 1 << (i
% 32);
454 /* Call "Load Latch" system ROM API */
455 sysrq_buffer
[1] = prot_sz
- 1;
456 retval
= psoc4_sysreq(target
, PSOC4_CMD_LOAD_LATCH
,
457 0, /* Byte number in latch from what to write */
458 sysrq_buffer
, param_sz
+ psoc4_info
->row_size
);
459 if (retval
!= ERROR_OK
)
462 /* Call "Write Protection" system ROM API */
463 retval
= psoc4_sysreq(target
, PSOC4_CMD_WRITE_PROTECTION
,
464 chip_prot
| (flash_macro
<< 8), NULL
, 0);
466 if (retval
!= ERROR_OK
)
467 psoc4_protect_check(bank
);
476 COMMAND_HANDLER(psoc4_handle_flash_autoerase_command
)
479 return ERROR_COMMAND_SYNTAX_ERROR
;
481 struct flash_bank
*bank
;
482 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
483 if (ERROR_OK
!= retval
)
486 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
487 bool enable
= psoc4_info
->cmd_program_row
== PSOC4_CMD_WRITE_ROW
;
490 COMMAND_PARSE_ON_OFF(CMD_ARGV
[1], enable
);
493 psoc4_info
->cmd_program_row
= PSOC4_CMD_WRITE_ROW
;
494 LOG_INFO("Flash auto-erase enabled, non mass erase commands will be ignored.");
496 psoc4_info
->cmd_program_row
= PSOC4_CMD_PROGRAM_ROW
;
497 LOG_INFO("Flash auto-erase disabled. Use psoc mass_erase before flash programming.");
504 static int psoc4_write(struct flash_bank
*bank
, const uint8_t *buffer
,
505 uint32_t offset
, uint32_t count
)
507 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
508 struct target
*target
= bank
->target
;
509 uint32_t *sysrq_buffer
= NULL
;
510 int retval
= ERROR_OK
;
511 const int param_sz
= 8;
513 if (bank
->target
->state
!= TARGET_HALTED
) {
514 LOG_ERROR("Target not halted");
515 return ERROR_TARGET_NOT_HALTED
;
519 LOG_ERROR("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
520 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
523 sysrq_buffer
= malloc(param_sz
+ psoc4_info
->row_size
);
524 if (sysrq_buffer
== NULL
) {
525 LOG_ERROR("no memory for row buffer");
529 uint8_t *row_buffer
= (uint8_t *)sysrq_buffer
+ param_sz
;
530 uint32_t row_num
= offset
/ psoc4_info
->row_size
;
531 uint32_t row_offset
= offset
- row_num
* psoc4_info
->row_size
;
533 memset(row_buffer
, 0, row_offset
);
535 bool save_poll
= jtag_poll_get_enabled();
536 jtag_poll_set_enabled(false);
539 uint32_t chunk_size
= psoc4_info
->row_size
- row_offset
;
540 if (chunk_size
> count
) {
542 memset(row_buffer
+ chunk_size
, 0, psoc4_info
->row_size
- chunk_size
);
544 memcpy(row_buffer
+ row_offset
, buffer
, chunk_size
);
545 LOG_DEBUG("offset / row: 0x%" PRIx32
" / %d size %d",
546 offset
, row_offset
, chunk_size
);
548 /* Call "Load Latch" system ROM API */
549 sysrq_buffer
[1] = psoc4_info
->row_size
- 1;
550 retval
= psoc4_sysreq(target
, PSOC4_CMD_LOAD_LATCH
,
551 0, /* Byte number in latch from what to write */
552 sysrq_buffer
, param_sz
+ psoc4_info
->row_size
);
553 if (retval
!= ERROR_OK
)
556 /* Call "Program Row" or "Write Row" system ROM API */
557 uint32_t sysrq_param
;
558 retval
= psoc4_sysreq(target
, psoc4_info
->cmd_program_row
,
560 &sysrq_param
, sizeof(sysrq_param
));
561 if (retval
!= ERROR_OK
)
564 buffer
+= chunk_size
;
571 jtag_poll_set_enabled(save_poll
);
580 static int psoc4_probe(struct flash_bank
*bank
)
582 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
583 struct target
*target
= bank
->target
;
585 uint16_t flash_size_in_kb
= 0;
586 uint16_t max_flash_size_in_kb
;
590 uint32_t base_address
= 0x00000000;
593 if (target
->state
!= TARGET_HALTED
) {
594 LOG_ERROR("Target not halted");
595 return ERROR_TARGET_NOT_HALTED
;
598 psoc4_info
->probed
= 0;
599 psoc4_info
->cmd_program_row
= PSOC4_CMD_PROGRAM_ROW
;
601 /* Get the CPUID from the ARM Core
602 * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/DDI0432C_cortex_m0_r0p0_trm.pdf 4.2.1 */
603 int retval
= target_read_u32(target
, 0xE000ED00, &cpu_id
);
604 if (retval
!= ERROR_OK
)
607 LOG_DEBUG("cpu id = 0x%08" PRIx32
"", cpu_id
);
609 /* set page size, protection granularity and max flash size depending on family */
610 switch ((cpu_id
>> 4) & 0xFFF) {
611 case 0xc20: /* M0 -> PSoC4 */
613 max_flash_size_in_kb
= 32;
616 LOG_WARNING("Cannot identify target as a PSoC 4 family.");
620 uint32_t spcif_geometry
;
621 retval
= target_read_u32(target
, PSOC4_SPCIF_GEOMETRY
, &spcif_geometry
);
622 if (retval
== ERROR_OK
) {
623 row_size
= 128 * ((spcif_geometry
>> 22) & 3);
624 flash_size_in_kb
= (spcif_geometry
& 0xffff) * 256 / 1024;
625 LOG_INFO("SPCIF geometry: %d kb flash, row %d bytes.", flash_size_in_kb
, row_size
);
628 /* ST-Link v2 has some problem reading PSOC4_SPCIF_GEOMETRY
629 and an error is reported late. Dummy read gets this error. */
631 target_read_u32(target
, PSOC4_CPUSS_SYSREQ
, &dummy
);
633 /* get silicon ID from target. */
634 retval
= psoc4_get_silicon_id(target
, &silicon_id
, &protection
);
635 if (retval
!= ERROR_OK
)
638 const struct psoc4_chip_details
*details
= psoc4_details_by_id(silicon_id
);
640 LOG_INFO("%s device detected.", details
->type
);
641 if (flash_size_in_kb
== 0)
642 flash_size_in_kb
= details
->flash_size_in_kb
;
643 else if (flash_size_in_kb
!= details
->flash_size_in_kb
)
644 LOG_ERROR("Flash size mismatch");
647 psoc4_info
->row_size
= row_size
;
648 psoc4_info
->silicon_id
= silicon_id
;
649 psoc4_info
->chip_protection
= protection
;
651 /* failed reading flash size or flash size invalid (early silicon),
652 * default to max target family */
653 if (retval
!= ERROR_OK
|| flash_size_in_kb
== 0xffff || flash_size_in_kb
== 0) {
654 LOG_WARNING("PSoC 4 flash size failed, probe inaccurate - assuming %dk flash",
655 max_flash_size_in_kb
);
656 flash_size_in_kb
= max_flash_size_in_kb
;
659 /* if the user sets the size manually then ignore the probed value
660 * this allows us to work around devices that have a invalid flash size register value */
661 if (psoc4_info
->user_bank_size
) {
662 LOG_INFO("ignoring flash probed value, using configured bank size");
663 flash_size_in_kb
= psoc4_info
->user_bank_size
/ 1024;
666 LOG_INFO("flash size = %d kbytes", flash_size_in_kb
);
668 /* did we assign flash size? */
669 assert(flash_size_in_kb
!= 0xffff);
671 /* calculate numbers of pages */
672 int num_rows
= flash_size_in_kb
* 1024 / row_size
;
674 /* check that calculation result makes sense */
675 assert(num_rows
> 0);
679 bank
->sectors
= NULL
;
682 bank
->base
= base_address
;
683 bank
->size
= (num_rows
* row_size
);
684 bank
->num_sectors
= num_rows
;
685 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_rows
);
687 for (i
= 0; i
< num_rows
; i
++) {
688 bank
->sectors
[i
].offset
= i
* row_size
;
689 bank
->sectors
[i
].size
= row_size
;
690 bank
->sectors
[i
].is_erased
= -1;
691 bank
->sectors
[i
].is_protected
= 1;
694 LOG_INFO("flash bank set %d rows", num_rows
);
695 psoc4_info
->probed
= 1;
700 static int psoc4_auto_probe(struct flash_bank
*bank
)
702 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
703 if (psoc4_info
->probed
)
705 return psoc4_probe(bank
);
709 static int get_psoc4_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
711 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
714 if (psoc4_info
->probed
== 0)
717 const struct psoc4_chip_details
*details
= psoc4_details_by_id(psoc4_info
->silicon_id
);
720 printed
= snprintf(buf
, buf_size
, "PSoC 4 %s rev 0x%04" PRIx16
" package %s",
721 details
->type
, psoc4_info
->silicon_id
& 0xffff, details
->package
);
723 printed
= snprintf(buf
, buf_size
, "PSoC 4 silicon id 0x%08" PRIx32
"",
724 psoc4_info
->silicon_id
);
729 const char *prot_txt
= psoc4_decode_chip_protection(psoc4_info
->chip_protection
);
730 snprintf(buf
, buf_size
, " flash %d kb %s", bank
->size
/ 1024, prot_txt
);
735 COMMAND_HANDLER(psoc4_handle_mass_erase_command
)
738 return ERROR_COMMAND_SYNTAX_ERROR
;
740 struct flash_bank
*bank
;
741 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
742 if (ERROR_OK
!= retval
)
745 retval
= psoc4_mass_erase(bank
);
746 if (retval
== ERROR_OK
)
747 command_print(CMD_CTX
, "psoc mass erase complete");
749 command_print(CMD_CTX
, "psoc mass erase failed");
755 static const struct command_registration psoc4_exec_command_handlers
[] = {
757 .name
= "mass_erase",
758 .handler
= psoc4_handle_mass_erase_command
,
759 .mode
= COMMAND_EXEC
,
761 .help
= "Erase entire flash device.",
764 .name
= "flash_autoerase",
765 .handler
= psoc4_handle_flash_autoerase_command
,
766 .mode
= COMMAND_EXEC
,
767 .usage
= "bank_id on|off",
768 .help
= "Set autoerase mode for flash bank.",
770 COMMAND_REGISTRATION_DONE
773 static const struct command_registration psoc4_command_handlers
[] = {
777 .help
= "PSoC 4 flash command group",
779 .chain
= psoc4_exec_command_handlers
,
781 COMMAND_REGISTRATION_DONE
784 struct flash_driver psoc4_flash
= {
786 .commands
= psoc4_command_handlers
,
787 .flash_bank_command
= psoc4_flash_bank_command
,
788 .erase
= psoc4_erase
,
789 .protect
= psoc4_protect
,
790 .write
= psoc4_write
,
791 .read
= default_flash_read
,
792 .probe
= psoc4_probe
,
793 .auto_probe
= psoc4_auto_probe
,
794 .erase_check
= default_flash_blank_check
,
795 .protect_check
= psoc4_protect_check
,
796 .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)