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. *E June 28, 2016
46 PSoC(R) 4 Registers TRM Spec.
47 Document No. 001-85847 Rev. *A June 25, 2013
49 PSoC 4000 Family PSoC(R) 4 Technical Reference Manual
50 Document No. 001-89309 Rev. *B May 9, 2016
52 PSoC 41XX_BLE/42XX_BLE Family PSoC 4 BLE Architecture TRM
53 Document No. 001-92738 Rev. *C February 12, 2016
55 PSoC 4200L Family PSoC 4 Architecture TRM
56 Document No. 001-97952 Rev. *A December 15, 2015
58 PSoC 4200L Family PSoC 4 Registers TRM
59 Document No. 001-98126 Rev. *A December 16, 2015
61 PSoC 4100M/4200M Family PSoC 4 Architecture TRM
62 Document No. 001-95223 Rev. *B July 29, 2015
64 PSoC 4100S Family PSoC 4 Architecture TRM
65 Document No. 002-10621 Rev. *A July 29, 2016
67 PSoC 4100S Family PSoC 4 Registers TRM
68 Document No. 002-10523 Rev. *A July 20, 2016
70 PSoC Analog Coprocessor Architecture TRM
71 Document No. 002-10404 Rev. ** December 18, 2015
73 CY8C4Axx PSoC Analog Coprocessor Registers TRM
74 Document No. 002-10405 Rev. ** December 18, 2015
76 CY8C41xx, CY8C42xx Programming Specifications
77 Document No. 001-81799 Rev. *C March 4, 2014
79 CYBL10x6x, CY8C4127_BL, CY8C4247_BL Programming Specifications
80 Document No. 001-91508 Rev. *B September 22, 2014
83 /* register locations */
84 #define PSOC4_SFLASH_MACRO0 0x0FFFF000
86 #define PSOC4_CPUSS_SYSREQ_LEGACY 0x40000004
87 #define PSOC4_CPUSS_SYSARG_LEGACY 0x40000008
88 #define PSOC4_SPCIF_GEOMETRY_LEGACY 0x400E0000
90 #define PSOC4_CPUSS_SYSREQ_NEW 0x40100004
91 #define PSOC4_CPUSS_SYSARG_NEW 0x40100008
92 #define PSOC4_SPCIF_GEOMETRY_NEW 0x40110000
94 #define PSOC4_TEST_MODE 0x40030014
96 #define PSOC4_ROMTABLE_PID0 0xF0000FE0
100 #define PSOC4_SFLASH_MACRO_SIZE 0x400
101 #define PSOC4_ROWS_PER_MACRO 512
103 #define PSOC4_SROM_KEY1 0xb6
104 #define PSOC4_SROM_KEY2 0xd3
105 #define PSOC4_SROM_SYSREQ_BIT (1<<31)
106 #define PSOC4_SROM_HMASTER_BIT (1<<30)
107 #define PSOC4_SROM_PRIVILEGED_BIT (1<<28)
108 #define PSOC4_SROM_STATUS_SUCCEEDED 0xa0000000
109 #define PSOC4_SROM_STATUS_FAILED 0xf0000000
110 #define PSOC4_SROM_STATUS_MASK 0xf0000000
112 /* not documented in any TRM */
113 #define PSOC4_SROM_ERR_IMO_NOT_IMPLEM 0xf0000013
115 #define PSOC4_CMD_GET_SILICON_ID 0
116 #define PSOC4_CMD_LOAD_LATCH 4
117 #define PSOC4_CMD_WRITE_ROW 5
118 #define PSOC4_CMD_PROGRAM_ROW 6
119 #define PSOC4_CMD_ERASE_ALL 0xa
120 #define PSOC4_CMD_CHECKSUM 0xb
121 #define PSOC4_CMD_WRITE_PROTECTION 0xd
122 #define PSOC4_CMD_SET_IMO48 0x15
123 #define PSOC4_CMD_WRITE_SFLASH_ROW 0x18
125 #define PSOC4_CHIP_PROT_VIRGIN 0x0
126 #define PSOC4_CHIP_PROT_OPEN 0x1
127 #define PSOC4_CHIP_PROT_PROTECTED 0x2
128 #define PSOC4_CHIP_PROT_KILL 0x4
130 #define PSOC4_ROMTABLE_DESIGNER_CHECK 0xb4
132 #define PSOC4_FAMILY_FLAG_LEGACY 1
134 struct psoc4_chip_family
{
140 const struct psoc4_chip_family psoc4_families
[] = {
141 { 0x93, "PSoC4100/4200", .flags
= PSOC4_FAMILY_FLAG_LEGACY
},
142 { 0x9A, "PSoC4000", .flags
= 0 },
143 { 0x9E, "PSoC/PRoC BLE (119E)", .flags
= 0 },
144 { 0xA0, "PSoC4200L", .flags
= 0 },
145 { 0xA1, "PSoC4100M/4200M", .flags
= 0 },
146 { 0xA3, "PSoC/PRoC BLE (11A3)", .flags
= 0 },
147 { 0xA9, "PSoC4000S", .flags
= 0 },
148 { 0xAA, "PSoC/PRoC BLE (11AA)", .flags
= 0 },
149 { 0xAB, "PSoC4100S", .flags
= 0 },
150 { 0xAC, "PSoC Analog Coprocessor", .flags
= 0 },
151 { 0, "Unknown", .flags
= 0 }
155 struct psoc4_flash_bank
{
157 uint32_t user_bank_size
;
160 uint8_t cmd_program_row
;
163 uint32_t cpuss_sysreq_addr
;
164 uint32_t cpuss_sysarg_addr
;
165 uint32_t spcif_geometry_addr
;
169 static const struct psoc4_chip_family
*psoc4_family_by_id(uint16_t family_id
)
171 const struct psoc4_chip_family
*p
= psoc4_families
;
172 while (p
->id
&& p
->id
!= family_id
)
178 static const char *psoc4_decode_chip_protection(uint8_t protection
)
180 switch (protection
) {
181 case PSOC4_CHIP_PROT_VIRGIN
:
182 return "protection VIRGIN";
183 case PSOC4_CHIP_PROT_OPEN
:
184 return "protection open";
185 case PSOC4_CHIP_PROT_PROTECTED
:
187 case PSOC4_CHIP_PROT_KILL
:
188 return "protection KILL";
190 LOG_WARNING("Unknown protection state 0x%02" PRIx8
"", protection
);
196 /* flash bank <name> psoc <base> <size> 0 0 <target#>
198 FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command
)
200 struct psoc4_flash_bank
*psoc4_info
;
203 return ERROR_COMMAND_SYNTAX_ERROR
;
205 psoc4_info
= calloc(1, sizeof(struct psoc4_flash_bank
));
207 bank
->driver_priv
= psoc4_info
;
208 bank
->default_padded_value
= bank
->erased_value
= 0x00;
209 psoc4_info
->user_bank_size
= bank
->size
;
210 psoc4_info
->cmd_program_row
= PSOC4_CMD_WRITE_ROW
;
216 /* PSoC 4 system ROM request
217 * Setting SROM_SYSREQ_BIT in CPUSS_SYSREQ register runs NMI service
218 * in sysrem ROM. Algorithm just waits for NMI to finish.
219 * When sysreq_params_size == 0 only one parameter is passed in CPUSS_SYSARG register.
220 * Otherwise address of memory parameter block is set in CPUSS_SYSARG
221 * and the first parameter is written to the first word of parameter block
223 static int psoc4_sysreq(struct flash_bank
*bank
, uint8_t cmd
,
225 uint32_t *sysreq_params
, uint32_t sysreq_params_size
,
226 uint32_t *sysarg_out
)
228 struct target
*target
= bank
->target
;
229 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
231 struct working_area
*sysreq_wait_algorithm
;
232 struct working_area
*sysreq_mem
;
234 struct reg_param reg_params
[1];
235 struct armv7m_algorithm armv7m_info
;
237 int retval
= ERROR_OK
;
239 uint32_t param1
= PSOC4_SROM_KEY1
240 | ((PSOC4_SROM_KEY2
+ cmd
) << 8)
243 static uint8_t psoc4_sysreq_wait_code
[] = {
244 /* system request NMI is served immediately after algo run
245 now we are done: break */
246 0x00, 0xbe, /* bkpt 0 */
249 const int code_words
= (sizeof(psoc4_sysreq_wait_code
) + 3) / 4;
250 /* stack must be aligned */
251 const int stack_size
= 256;
252 /* tested stack sizes on PSoC4200:
258 /* allocate area for sysreq wait code and stack */
259 if (target_alloc_working_area(target
, code_words
* 4 + stack_size
,
260 &sysreq_wait_algorithm
) != ERROR_OK
) {
261 LOG_DEBUG("no working area for sysreq code");
262 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
266 retval
= target_write_buffer(target
,
267 sysreq_wait_algorithm
->address
,
268 sizeof(psoc4_sysreq_wait_code
),
269 psoc4_sysreq_wait_code
);
270 if (retval
!= ERROR_OK
) {
271 /* we already allocated the writing code, but failed to get a
272 * buffer, free the algorithm */
276 if (sysreq_params_size
) {
277 LOG_DEBUG("SYSREQ %02" PRIx8
" %04" PRIx16
" %08" PRIx32
" %08" PRIx32
" size %" PRIu32
,
278 cmd
, cmd_param
, param1
, sysreq_params
[0], sysreq_params_size
);
279 /* Allocate memory for sysreq_params */
280 retval
= target_alloc_working_area(target
, sysreq_params_size
, &sysreq_mem
);
281 if (retval
!= ERROR_OK
) {
282 LOG_WARNING("no working area for sysreq parameters");
284 /* we already allocated the writing code, but failed to get a
285 * buffer, free the algorithm */
286 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
290 /* Write sysreq_params */
291 target_buffer_set_u32(target
, (uint8_t *)sysreq_params
, param1
);
292 retval
= target_write_buffer(target
, sysreq_mem
->address
,
293 sysreq_params_size
, (uint8_t *)sysreq_params
);
294 if (retval
!= ERROR_OK
)
297 /* Set address of sysreq parameters block */
298 retval
= target_write_u32(target
, psoc4_info
->cpuss_sysarg_addr
, sysreq_mem
->address
);
299 if (retval
!= ERROR_OK
)
303 /* Sysreq without memory block of parameters */
304 LOG_DEBUG("SYSREQ %02" PRIx8
" %04" PRIx16
" %08" PRIx32
,
305 cmd
, cmd_param
, param1
);
306 /* Set register parameter */
307 retval
= target_write_u32(target
, psoc4_info
->cpuss_sysarg_addr
, param1
);
308 if (retval
!= ERROR_OK
)
312 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
313 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
316 init_reg_param(®_params
[0], "sp", 32, PARAM_OUT
);
317 buf_set_u32(reg_params
[0].value
, 0, 32,
318 sysreq_wait_algorithm
->address
+ sysreq_wait_algorithm
->size
);
320 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
321 if (armv7m
== NULL
) {
322 /* something is very wrong if armv7m is NULL */
323 LOG_ERROR("unable to get armv7m target");
327 /* Set SROM request */
328 retval
= target_write_u32(target
, psoc4_info
->cpuss_sysreq_addr
,
329 PSOC4_SROM_SYSREQ_BIT
| PSOC4_SROM_HMASTER_BIT
| cmd
);
330 if (retval
!= ERROR_OK
)
333 /* Execute wait code */
334 retval
= target_run_algorithm(target
, 0, NULL
,
335 sizeof(reg_params
) / sizeof(*reg_params
), reg_params
,
336 sysreq_wait_algorithm
->address
, 0, 1000, &armv7m_info
);
337 if (retval
!= ERROR_OK
) {
338 LOG_ERROR("sysreq wait code execution failed");
342 uint32_t sysarg_out_tmp
;
343 retval
= target_read_u32(target
, psoc4_info
->cpuss_sysarg_addr
, &sysarg_out_tmp
);
344 if (retval
!= ERROR_OK
)
348 *sysarg_out
= sysarg_out_tmp
;
349 /* If result is an error, do not show now, let caller to decide */
350 } else if ((sysarg_out_tmp
& PSOC4_SROM_STATUS_MASK
) != PSOC4_SROM_STATUS_SUCCEEDED
) {
351 LOG_ERROR("sysreq error 0x%" PRIx32
, sysarg_out_tmp
);
355 destroy_reg_param(®_params
[0]);
358 if (sysreq_params_size
)
359 target_free_working_area(target
, sysreq_mem
);
362 target_free_working_area(target
, sysreq_wait_algorithm
);
368 /* helper routine to get silicon ID from a PSoC 4 chip */
369 static int psoc4_get_silicon_id(struct flash_bank
*bank
, uint32_t *silicon_id
, uint16_t *family_id
, uint8_t *protection
)
371 struct target
*target
= bank
->target
;
372 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
374 uint32_t part0
, part1
;
376 int retval
= psoc4_sysreq(bank
, PSOC4_CMD_GET_SILICON_ID
, 0, NULL
, 0, &part0
);
377 if (retval
!= ERROR_OK
)
380 if ((part0
& PSOC4_SROM_STATUS_MASK
) != PSOC4_SROM_STATUS_SUCCEEDED
) {
381 LOG_ERROR("sysreq error 0x%" PRIx32
, part0
);
385 retval
= target_read_u32(target
, psoc4_info
->cpuss_sysreq_addr
, &part1
);
386 if (retval
!= ERROR_OK
)
389 /* build ID as Cypress sw does:
390 * bit 31..16 silicon ID
391 * bit 15..8 revision ID (so far 0x11 for all devices)
392 * bit 7..0 family ID (lowes 8 bits)
395 *silicon_id
= ((part0
& 0x0000ffff) << 16)
396 | ((part0
& 0x00ff0000) >> 8)
397 | (part1
& 0x000000ff);
400 *family_id
= part1
& 0x0fff;
403 *protection
= (part1
>> 12) & 0x0f;
409 static int psoc4_get_family(struct target
*target
, uint16_t *family_id
)
415 retval
= target_read_memory(target
, PSOC4_ROMTABLE_PID0
, 4, 3, (uint8_t *)pidbf
);
416 if (retval
!= ERROR_OK
)
419 for (i
= 0; i
< 3; i
++) {
420 uint32_t tmp
= target_buffer_get_u32(target
, (uint8_t *)(pidbf
+ i
));
421 if (tmp
& 0xffffff00) {
422 LOG_ERROR("Unexpected data in ROMTABLE");
428 uint16_t family
= pid
[0] | ((pid
[1] & 0xf) << 8);
429 uint32_t designer
= ((pid
[1] & 0xf0) >> 4) | ((pid
[2] & 0xf) << 4);
431 if (designer
!= PSOC4_ROMTABLE_DESIGNER_CHECK
) {
432 LOG_ERROR("ROMTABLE designer is not Cypress");
441 static int psoc4_flash_prepare(struct flash_bank
*bank
)
443 struct target
*target
= bank
->target
;
444 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
446 if (target
->state
!= TARGET_HALTED
) {
447 LOG_ERROR("Target not halted");
448 return ERROR_TARGET_NOT_HALTED
;
454 /* get family ID from SROM call */
455 retval
= psoc4_get_silicon_id(bank
, NULL
, &family_id
, NULL
);
456 if (retval
!= ERROR_OK
)
459 /* and check with family ID from ROMTABLE */
460 if (family_id
!= psoc4_info
->family_id
) {
461 LOG_ERROR("Family mismatch");
465 if (!psoc4_info
->legacy_family
) {
466 uint32_t sysreq_status
;
467 retval
= psoc4_sysreq(bank
, PSOC4_CMD_SET_IMO48
, 0, NULL
, 0, &sysreq_status
);
468 if (retval
!= ERROR_OK
)
471 if ((sysreq_status
& PSOC4_SROM_STATUS_MASK
) != PSOC4_SROM_STATUS_SUCCEEDED
) {
472 /* This undocumented error code is returned probably when
473 * PSOC4_CMD_SET_IMO48 command is not implemented.
474 * Can be safely ignored, programming works.
476 if (sysreq_status
== PSOC4_SROM_ERR_IMO_NOT_IMPLEM
)
477 LOG_INFO("PSOC4_CMD_SET_IMO48 is not implemented on this device.");
479 LOG_ERROR("sysreq error 0x%" PRIx32
, sysreq_status
);
489 static int psoc4_protect_check(struct flash_bank
*bank
)
491 struct target
*target
= bank
->target
;
492 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
494 uint32_t prot_addr
= PSOC4_SFLASH_MACRO0
;
498 uint8_t bf
[PSOC4_ROWS_PER_MACRO
/8];
500 for (m
= 0; m
< psoc4_info
->num_macros
; m
++, prot_addr
+= PSOC4_SFLASH_MACRO_SIZE
) {
501 retval
= target_read_memory(target
, prot_addr
, 4, PSOC4_ROWS_PER_MACRO
/32, bf
);
502 if (retval
!= ERROR_OK
)
505 for (i
= 0; i
< PSOC4_ROWS_PER_MACRO
&& s
< bank
->num_sectors
; i
++, s
++)
506 bank
->sectors
[s
].is_protected
= bf
[i
/8] & (1 << (i
%8)) ? 1 : 0;
513 static int psoc4_mass_erase(struct flash_bank
*bank
)
516 int retval
= psoc4_flash_prepare(bank
);
517 if (retval
!= ERROR_OK
)
520 /* Call "Erase All" system ROM API */
522 retval
= psoc4_sysreq(bank
, PSOC4_CMD_ERASE_ALL
,
524 ¶m
, sizeof(param
), NULL
);
526 if (retval
== ERROR_OK
)
527 /* set all sectors as erased */
528 for (i
= 0; i
< bank
->num_sectors
; i
++)
529 bank
->sectors
[i
].is_erased
= 1;
535 static int psoc4_erase(struct flash_bank
*bank
, int first
, int last
)
537 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
538 if (psoc4_info
->cmd_program_row
== PSOC4_CMD_WRITE_ROW
) {
539 LOG_INFO("Autoerase enabled, erase command ignored");
543 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
544 return psoc4_mass_erase(bank
);
546 LOG_ERROR("Only mass erase available! Consider using 'psoc4 flash_autoerase 0 on'");
552 static int psoc4_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
554 struct target
*target
= bank
->target
;
555 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
557 if (!psoc4_info
->probed
)
560 int retval
= psoc4_flash_prepare(bank
);
561 if (retval
!= ERROR_OK
)
564 uint32_t *sysrq_buffer
= NULL
;
565 const int param_sz
= 8;
566 int chip_prot
= PSOC4_CHIP_PROT_OPEN
;
568 int num_bits
= bank
->num_sectors
;
570 if (num_bits
> PSOC4_ROWS_PER_MACRO
)
571 num_bits
= PSOC4_ROWS_PER_MACRO
;
573 int prot_sz
= num_bits
/ 8;
575 sysrq_buffer
= calloc(1, param_sz
+ prot_sz
);
576 if (sysrq_buffer
== NULL
) {
577 LOG_ERROR("no memory for row buffer");
581 for (i
= first
; i
<= last
&& i
< bank
->num_sectors
; i
++)
582 bank
->sectors
[i
].is_protected
= set
;
584 for (m
= 0; m
< psoc4_info
->num_macros
; m
++) {
585 uint8_t *p
= (uint8_t *)(sysrq_buffer
+ 2);
586 for (i
= 0; i
< num_bits
&& i
< bank
->num_sectors
; i
++) {
587 if (bank
->sectors
[i
].is_protected
)
588 p
[i
/8] |= 1 << (i
%8);
591 /* Call "Load Latch" system ROM API */
592 target_buffer_set_u32(target
, (uint8_t *)(sysrq_buffer
+ 1),
594 retval
= psoc4_sysreq(bank
, PSOC4_CMD_LOAD_LATCH
,
595 0 /* Byte number in latch from what to write */
596 | (m
<< 8), /* flash macro index */
597 sysrq_buffer
, param_sz
+ psoc4_info
->row_size
,
599 if (retval
!= ERROR_OK
)
602 /* Call "Write Protection" system ROM API */
603 retval
= psoc4_sysreq(bank
, PSOC4_CMD_WRITE_PROTECTION
,
604 chip_prot
| (m
<< 8), NULL
, 0, NULL
);
605 if (retval
!= ERROR_OK
)
612 psoc4_protect_check(bank
);
617 COMMAND_HANDLER(psoc4_handle_flash_autoerase_command
)
620 return ERROR_COMMAND_SYNTAX_ERROR
;
622 struct flash_bank
*bank
;
623 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
624 if (ERROR_OK
!= retval
)
627 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
628 bool enable
= psoc4_info
->cmd_program_row
== PSOC4_CMD_WRITE_ROW
;
631 COMMAND_PARSE_ON_OFF(CMD_ARGV
[1], enable
);
634 psoc4_info
->cmd_program_row
= PSOC4_CMD_WRITE_ROW
;
635 LOG_INFO("Flash auto-erase enabled, non mass erase commands will be ignored.");
637 psoc4_info
->cmd_program_row
= PSOC4_CMD_PROGRAM_ROW
;
638 LOG_INFO("Flash auto-erase disabled. Use psoc mass_erase before flash programming.");
645 static int psoc4_write(struct flash_bank
*bank
, const uint8_t *buffer
,
646 uint32_t offset
, uint32_t count
)
648 struct target
*target
= bank
->target
;
649 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
650 uint32_t *sysrq_buffer
= NULL
;
651 const int param_sz
= 8;
653 int retval
= psoc4_flash_prepare(bank
);
654 if (retval
!= ERROR_OK
)
657 sysrq_buffer
= malloc(param_sz
+ psoc4_info
->row_size
);
658 if (sysrq_buffer
== NULL
) {
659 LOG_ERROR("no memory for row buffer");
663 uint8_t *row_buffer
= (uint8_t *)sysrq_buffer
+ param_sz
;
664 uint32_t row_num
= offset
/ psoc4_info
->row_size
;
665 uint32_t row_offset
= offset
- row_num
* psoc4_info
->row_size
;
667 memset(row_buffer
, bank
->default_padded_value
, row_offset
);
669 bool save_poll
= jtag_poll_get_enabled();
670 jtag_poll_set_enabled(false);
673 uint32_t chunk_size
= psoc4_info
->row_size
- row_offset
;
674 if (chunk_size
> count
) {
676 memset(row_buffer
+ chunk_size
, bank
->default_padded_value
, psoc4_info
->row_size
- chunk_size
);
678 memcpy(row_buffer
+ row_offset
, buffer
, chunk_size
);
679 LOG_DEBUG("offset / row: 0x%08" PRIx32
" / %" PRIu32
", size %" PRIu32
"",
680 offset
, row_offset
, chunk_size
);
682 uint32_t macro_idx
= row_num
/ PSOC4_ROWS_PER_MACRO
;
684 /* Call "Load Latch" system ROM API */
685 target_buffer_set_u32(target
, (uint8_t *)(sysrq_buffer
+ 1),
686 psoc4_info
->row_size
- 1);
687 retval
= psoc4_sysreq(bank
, PSOC4_CMD_LOAD_LATCH
,
688 0 /* Byte number in latch from what to write */
690 sysrq_buffer
, param_sz
+ psoc4_info
->row_size
,
692 if (retval
!= ERROR_OK
)
695 /* Call "Program Row" or "Write Row" system ROM API */
696 uint32_t sysrq_param
;
697 retval
= psoc4_sysreq(bank
, psoc4_info
->cmd_program_row
,
699 &sysrq_param
, sizeof(sysrq_param
),
701 if (retval
!= ERROR_OK
)
704 buffer
+= chunk_size
;
711 jtag_poll_set_enabled(save_poll
);
720 static int psoc4_probe(struct flash_bank
*bank
)
722 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
723 struct target
*target
= bank
->target
;
728 psoc4_info
->probed
= false;
730 retval
= psoc4_get_family(target
, &family_id
);
731 if (retval
!= ERROR_OK
)
734 const struct psoc4_chip_family
*family
= psoc4_family_by_id(family_id
);
736 if (family
->id
== 0) {
737 LOG_ERROR("Cannot identify PSoC 4 family.");
741 if (family
->flags
& PSOC4_FAMILY_FLAG_LEGACY
) {
742 LOG_INFO("%s legacy family detected.", family
->name
);
743 psoc4_info
->legacy_family
= true;
744 psoc4_info
->cpuss_sysreq_addr
= PSOC4_CPUSS_SYSREQ_LEGACY
;
745 psoc4_info
->cpuss_sysarg_addr
= PSOC4_CPUSS_SYSARG_LEGACY
;
746 psoc4_info
->spcif_geometry_addr
= PSOC4_SPCIF_GEOMETRY_LEGACY
;
748 LOG_INFO("%s family detected.", family
->name
);
749 psoc4_info
->legacy_family
= false;
750 psoc4_info
->cpuss_sysreq_addr
= PSOC4_CPUSS_SYSREQ_NEW
;
751 psoc4_info
->cpuss_sysarg_addr
= PSOC4_CPUSS_SYSARG_NEW
;
752 psoc4_info
->spcif_geometry_addr
= PSOC4_SPCIF_GEOMETRY_NEW
;
755 uint32_t spcif_geometry
;
756 retval
= target_read_u32(target
, psoc4_info
->spcif_geometry_addr
, &spcif_geometry
);
757 if (retval
!= ERROR_OK
)
760 uint32_t flash_size_in_kb
= spcif_geometry
& 0x3fff;
761 /* TRM of legacy, M and L version describes FLASH field as 16-bit.
762 * S-series and PSoC Analog Coprocessor changes spec to 14-bit only.
763 * Impose PSoC Analog Coprocessor limit to all devices as it
764 * does not make any harm: flash size is safely below 4 MByte limit
766 uint32_t row_size
= (spcif_geometry
>> 22) & 3;
767 uint32_t num_macros
= (spcif_geometry
>> 20) & 3;
769 if (psoc4_info
->legacy_family
) {
770 flash_size_in_kb
= flash_size_in_kb
* 256 / 1024;
773 flash_size_in_kb
= (flash_size_in_kb
+ 1) * 256 / 1024;
774 row_size
= 64 * (row_size
+ 1);
778 LOG_DEBUG("SPCIF geometry: %" PRIu32
" kb flash, row %" PRIu32
" bytes.",
779 flash_size_in_kb
, row_size
);
781 /* if the user sets the size manually then ignore the probed value
782 * this allows us to work around devices that have a invalid flash size register value */
783 if (psoc4_info
->user_bank_size
) {
784 LOG_INFO("ignoring flash probed value, using configured bank size");
785 flash_size_in_kb
= psoc4_info
->user_bank_size
/ 1024;
788 char macros_txt
[20] = "";
790 snprintf(macros_txt
, sizeof(macros_txt
), " in %" PRIu32
" macros", num_macros
);
792 LOG_INFO("flash size = %" PRIu32
" kbytes%s", flash_size_in_kb
, macros_txt
);
794 /* calculate number of pages */
795 uint32_t num_rows
= flash_size_in_kb
* 1024 / row_size
;
797 /* check number of flash macros */
798 if (num_macros
!= (num_rows
+ PSOC4_ROWS_PER_MACRO
- 1) / PSOC4_ROWS_PER_MACRO
)
799 LOG_WARNING("Number of macros does not correspond with flash size!");
805 psoc4_info
->family_id
= family_id
;
806 psoc4_info
->num_macros
= num_macros
;
807 psoc4_info
->row_size
= row_size
;
808 bank
->base
= 0x00000000;
809 bank
->size
= num_rows
* row_size
;
810 bank
->num_sectors
= num_rows
;
811 bank
->sectors
= alloc_block_array(0, row_size
, num_rows
);
812 if (bank
->sectors
== NULL
)
815 LOG_DEBUG("flash bank set %" PRIu32
" rows", num_rows
);
816 psoc4_info
->probed
= true;
821 static int psoc4_auto_probe(struct flash_bank
*bank
)
823 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
824 if (psoc4_info
->probed
)
826 return psoc4_probe(bank
);
830 static int get_psoc4_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
832 struct target
*target
= bank
->target
;
833 struct psoc4_flash_bank
*psoc4_info
= bank
->driver_priv
;
835 if (!psoc4_info
->probed
)
838 const struct psoc4_chip_family
*family
= psoc4_family_by_id(psoc4_info
->family_id
);
839 uint32_t size_in_kb
= bank
->size
/ 1024;
841 if (target
->state
!= TARGET_HALTED
) {
842 snprintf(buf
, buf_size
, "%s, flash %" PRIu32
" kb"
843 " (halt target to see details)", family
->name
, size_in_kb
);
853 retval
= psoc4_get_silicon_id(bank
, &silicon_id
, &family_id
, &protection
);
854 if (retval
!= ERROR_OK
)
857 if (family_id
!= psoc4_info
->family_id
)
858 printed
= snprintf(buf
, buf_size
, "Family id mismatch 0x%02" PRIx16
859 "/0x%02" PRIx16
", silicon id 0x%08" PRIx32
,
860 psoc4_info
->family_id
, family_id
, silicon_id
);
862 printed
= snprintf(buf
, buf_size
, "%s silicon id 0x%08" PRIx32
"",
863 family
->name
, silicon_id
);
869 const char *prot_txt
= psoc4_decode_chip_protection(protection
);
870 snprintf(buf
, buf_size
, ", flash %" PRIu32
" kb %s", size_in_kb
, prot_txt
);
875 COMMAND_HANDLER(psoc4_handle_mass_erase_command
)
878 return ERROR_COMMAND_SYNTAX_ERROR
;
880 struct flash_bank
*bank
;
881 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
882 if (ERROR_OK
!= retval
)
885 retval
= psoc4_mass_erase(bank
);
886 if (retval
== ERROR_OK
)
887 command_print(CMD_CTX
, "psoc mass erase complete");
889 command_print(CMD_CTX
, "psoc mass erase failed");
895 static const struct command_registration psoc4_exec_command_handlers
[] = {
897 .name
= "mass_erase",
898 .handler
= psoc4_handle_mass_erase_command
,
899 .mode
= COMMAND_EXEC
,
901 .help
= "Erase entire flash device.",
904 .name
= "flash_autoerase",
905 .handler
= psoc4_handle_flash_autoerase_command
,
906 .mode
= COMMAND_EXEC
,
907 .usage
= "bank_id on|off",
908 .help
= "Set autoerase mode for flash bank.",
910 COMMAND_REGISTRATION_DONE
913 static const struct command_registration psoc4_command_handlers
[] = {
917 .help
= "PSoC 4 flash command group",
919 .chain
= psoc4_exec_command_handlers
,
921 COMMAND_REGISTRATION_DONE
924 struct flash_driver psoc4_flash
= {
926 .commands
= psoc4_command_handlers
,
927 .flash_bank_command
= psoc4_flash_bank_command
,
928 .erase
= psoc4_erase
,
929 .protect
= psoc4_protect
,
930 .write
= psoc4_write
,
931 .read
= default_flash_read
,
932 .probe
= psoc4_probe
,
933 .auto_probe
= psoc4_auto_probe
,
934 .erase_check
= default_flash_blank_check
,
935 .protect_check
= psoc4_protect_check
,
936 .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)