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 uint32_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 },
113 { 0x0490, "CYPD1103-35FNXI", "CSP-35", .flash_size_in_kb = 32 },
114 { 0x0489, "CYPD1121-40LQXI", "QFN-40", .flash_size_in_kb = 32 },
115 { 0x048A, "CYPD1122-40LQXI", "QFN-40", .flash_size_in_kb = 32 },
116 { 0x0491, "CYPD1131-35FNXI", "CSP-35", .flash_size_in_kb = 32 },
117 { 0x0498, "CYPD1132-16SXI", "SOIC-16", .flash_size_in_kb = 32 },
118 { 0x0481, "CYPD1134-28PVXI", "SSOP-28", .flash_size_in_kb = 32 },
119 { 0x048B, "CYPD1134-40LQXI", "QFN-40", .flash_size_in_kb = 32 },
123 struct psoc4_flash_bank {
125 uint32_t user_bank_size;
128 uint8_t chip_protection;
129 uint8_t cmd_program_row;
133 static const struct psoc4_chip_details *psoc4_details_by_id(uint32_t silicon_id)
135 const struct psoc4_chip_details *p = psoc4_devices;
137 uint16_t id = silicon_id >> 16; /* ignore die revision */
138 for (i = 0; i < sizeof(psoc4_devices)/sizeof(psoc4_devices[0]); i++, p++) {
142 LOG_DEBUG("Unknown PSoC 4 device silicon id 0x%08" PRIx32 ".", silicon_id);
146 static const char *psoc4_decode_chip_protection(uint8_t protection)
148 switch (protection) {
149 case PSOC4_CHIP_PROT_VIRGIN:
150 return "protection VIRGIN";
151 case PSOC4_CHIP_PROT_OPEN:
152 return "protection open";
153 case PSOC4_CHIP_PROT_PROTECTED:
155 case PSOC4_CHIP_PROT_KILL:
156 return "protection KILL";
158 LOG_WARNING("Unknown protection state 0x%02" PRIx8 "", protection);
164 /* flash bank <name> psoc <base> <size> 0 0 <target#>
166 FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command)
168 struct psoc4_flash_bank *psoc4_info;
171 return ERROR_COMMAND_SYNTAX_ERROR;
173 psoc4_info = calloc(1, sizeof(struct psoc4_flash_bank));
175 bank->driver_priv = psoc4_info;
176 psoc4_info->user_bank_size = bank->size;
182 /* PSoC 4 system ROM request
183 * Setting SROM_SYSREQ_BIT in CPUSS_SYSREQ register runs NMI service
184 * in sysrem ROM. Algorithm just waits for NMI to finish.
185 * When sysreq_params_size == 0 only one parameter is passed in CPUSS_SYSARG register.
186 * Otherwise address of memory parameter block is set in CPUSS_SYSARG
187 * and the first parameter is written to the first word of parameter block
189 static int psoc4_sysreq(struct target *target, uint8_t cmd, uint16_t cmd_param,
190 uint32_t *sysreq_params, uint32_t sysreq_params_size)
192 struct working_area *sysreq_wait_algorithm;
193 struct working_area *sysreq_mem;
195 struct reg_param reg_params[1];
196 struct armv7m_algorithm armv7m_info;
198 int retval = ERROR_OK;
200 uint32_t param1 = PSOC4_SROM_KEY1
201 | ((PSOC4_SROM_KEY2 + cmd) << 8)
204 static uint8_t psoc4_sysreq_wait_code[] = {
205 /* system request NMI is served immediately after algo run
206 now we are done: break */
207 0x00, 0xbe, /* bkpt 0 */
210 const int code_words = (sizeof(psoc4_sysreq_wait_code) + 3) / 4;
211 /* stack must be aligned */
212 const int stack_size = 196;
213 /* tested stack sizes on PSoC 4:
219 /* allocate area for sysreq wait code and stack */
220 if (target_alloc_working_area(target, code_words * 4 + stack_size,
221 &sysreq_wait_algorithm) != ERROR_OK) {
222 LOG_DEBUG("no working area for sysreq code");
223 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
227 retval = target_write_buffer(target,
228 sysreq_wait_algorithm->address,
229 sizeof(psoc4_sysreq_wait_code),
230 psoc4_sysreq_wait_code);
231 if (retval != ERROR_OK) {
232 /* we already allocated the writing code, but failed to get a
233 * buffer, free the algorithm */
237 if (sysreq_params_size) {
238 /* Allocate memory for sysreq_params */
239 retval = target_alloc_working_area(target, sysreq_params_size, &sysreq_mem);
240 if (retval != ERROR_OK) {
241 LOG_WARNING("no working area for sysreq parameters");
243 /* we already allocated the writing code, but failed to get a
244 * buffer, free the algorithm */
245 retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
249 /* Write sysreq_params */
250 sysreq_params[0] = param1;
251 retval = target_write_buffer(target, sysreq_mem->address,
252 sysreq_params_size, (uint8_t *)sysreq_params);
253 if (retval != ERROR_OK)
256 /* Set address of sysreq parameters block */
257 retval = target_write_u32(target, PSOC4_CPUSS_SYSARG, sysreq_mem->address);
258 if (retval != ERROR_OK)
262 /* Sysreq without memory block of parameters */
263 /* Set register parameter */
264 retval = target_write_u32(target, PSOC4_CPUSS_SYSARG, param1);
265 if (retval != ERROR_OK)
269 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
270 armv7m_info.core_mode = ARM_MODE_THREAD;
273 init_reg_param(®_params[0], "sp", 32, PARAM_OUT);
274 buf_set_u32(reg_params[0].value, 0, 32,
275 sysreq_wait_algorithm->address + sysreq_wait_algorithm->size);
277 struct armv7m_common *armv7m = target_to_armv7m(target);
278 if (armv7m == NULL) {
280 /* something is very wrong if armv7m is NULL */
281 LOG_ERROR("unable to get armv7m target");
285 /* Set SROM request */
286 retval = target_write_u32(target, PSOC4_CPUSS_SYSREQ,
287 PSOC4_SROM_SYSREQ_BIT | PSOC4_SROM_HMASTER_BIT | cmd);
288 if (retval != ERROR_OK)
291 /* Execute wait code */
292 retval = target_run_algorithm(target, 0, NULL,
293 sizeof(reg_params) / sizeof(*reg_params), reg_params,
294 sysreq_wait_algorithm->address, 0, 1000, &armv7m_info);
295 if (retval != ERROR_OK)
296 LOG_ERROR("sysreq wait code execution failed");
299 destroy_reg_param(®_params[0]);
302 if (sysreq_params_size)
303 target_free_working_area(target, sysreq_mem);
306 target_free_working_area(target, sysreq_wait_algorithm);
312 /* helper routine to get silicon ID from a PSoC 4 chip */
313 static int psoc4_get_silicon_id(struct target *target, uint32_t *silicon_id, uint8_t *protection)
315 uint32_t params = PSOC4_SROM_KEY1
316 | ((PSOC4_SROM_KEY2 + PSOC4_CMD_GET_SILICON_ID) << 8);
317 uint32_t part0, part1;
319 int retval = psoc4_sysreq(target, PSOC4_CMD_GET_SILICON_ID, 0, NULL, 0);
320 if (retval != ERROR_OK)
323 retval = target_read_u32(target, PSOC4_CPUSS_SYSARG, &part0);
324 if (retval != ERROR_OK)
327 if (part0 == params) {
328 LOG_ERROR("sysreq silicon id request not served");
332 retval = target_read_u32(target, PSOC4_CPUSS_SYSREQ, &part1);
333 if (retval != ERROR_OK)
336 uint32_t silicon = ((part0 & 0xffff) << 16)
337 | (((part0 >> 16) & 0xff) << 8)
339 uint8_t prot = (part1 >> 12) & 0xff;
342 *silicon_id = silicon;
346 LOG_DEBUG("silicon id: 0x%08" PRIx32 "", silicon);
347 LOG_DEBUG("protection: 0x%02" PRIx8 "", prot);
352 static int psoc4_protect_check(struct flash_bank *bank)
354 struct target *target = bank->target;
355 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
357 uint32_t prot_addr = PSOC4_SFLASH_MACRO;
361 int retval = ERROR_OK;
363 num_bits = bank->num_sectors;
365 for (i = 0; i < num_bits; i += 32) {
366 retval = target_read_u32(target, prot_addr, &protection);
367 if (retval != ERROR_OK)
372 for (s = 0; s < 32; s++) {
373 if (i + s >= num_bits)
375 bank->sectors[i + s].is_protected = (protection & (1 << s)) ? 1 : 0;
379 retval = psoc4_get_silicon_id(target, NULL, &(psoc4_info->chip_protection));
384 static int psoc4_mass_erase(struct flash_bank *bank)
386 struct target *target = bank->target;
389 if (bank->target->state != TARGET_HALTED) {
390 LOG_ERROR("Target not halted");
391 return ERROR_TARGET_NOT_HALTED;
394 /* Call "Erase All" system ROM API */
396 int retval = psoc4_sysreq(target, PSOC4_CMD_ERASE_ALL,
398 ¶m, sizeof(param));
400 if (retval == ERROR_OK)
401 /* set all sectors as erased */
402 for (i = 0; i < bank->num_sectors; i++)
403 bank->sectors[i].is_erased = 1;
409 static int psoc4_erase(struct flash_bank *bank, int first, int last)
411 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
412 if (psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW) {
413 LOG_INFO("Autoerase enabled, erase command ignored");
417 if ((first == 0) && (last == (bank->num_sectors - 1)))
418 return psoc4_mass_erase(bank);
420 LOG_ERROR("Only mass erase available");
426 static int psoc4_protect(struct flash_bank *bank, int set, int first, int last)
428 struct target *target = bank->target;
429 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
431 if (psoc4_info->probed == 0)
434 if (target->state != TARGET_HALTED) {
435 LOG_ERROR("Target not halted");
436 return ERROR_TARGET_NOT_HALTED;
439 uint32_t *sysrq_buffer = NULL;
441 int num_bits = bank->num_sectors;
442 const int param_sz = 8;
443 int prot_sz = num_bits / 8;
444 int chip_prot = PSOC4_CHIP_PROT_OPEN;
445 int flash_macro = 0; /* PSoC 42xx has only macro 0 */
448 sysrq_buffer = calloc(1, param_sz + prot_sz);
449 if (sysrq_buffer == NULL) {
450 LOG_ERROR("no memory for row buffer");
454 for (i = first; i < num_bits && i <= last; i++)
455 bank->sectors[i].is_protected = set;
457 uint32_t *p = sysrq_buffer + 2;
458 for (i = 0; i < num_bits; i++) {
459 if (bank->sectors[i].is_protected)
460 p[i / 32] |= 1 << (i % 32);
463 /* Call "Load Latch" system ROM API */
464 sysrq_buffer[1] = prot_sz - 1;
465 retval = psoc4_sysreq(target, PSOC4_CMD_LOAD_LATCH,
466 0, /* Byte number in latch from what to write */
467 sysrq_buffer, param_sz + psoc4_info->row_size);
468 if (retval != ERROR_OK)
471 /* Call "Write Protection" system ROM API */
472 retval = psoc4_sysreq(target, PSOC4_CMD_WRITE_PROTECTION,
473 chip_prot | (flash_macro << 8), NULL, 0);
475 if (retval != ERROR_OK)
476 psoc4_protect_check(bank);
485 COMMAND_HANDLER(psoc4_handle_flash_autoerase_command)
488 return ERROR_COMMAND_SYNTAX_ERROR;
490 struct flash_bank *bank;
491 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
492 if (ERROR_OK != retval)
495 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
496 bool enable = psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW;
499 COMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable);
502 psoc4_info->cmd_program_row = PSOC4_CMD_WRITE_ROW;
503 LOG_INFO("Flash auto-erase enabled, non mass erase commands will be ignored.");
505 psoc4_info->cmd_program_row = PSOC4_CMD_PROGRAM_ROW;
506 LOG_INFO("Flash auto-erase disabled. Use psoc mass_erase before flash programming.");
513 static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer,
514 uint32_t offset, uint32_t count)
516 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
517 struct target *target = bank->target;
518 uint32_t *sysrq_buffer = NULL;
519 int retval = ERROR_OK;
520 const int param_sz = 8;
522 if (bank->target->state != TARGET_HALTED) {
523 LOG_ERROR("Target not halted");
524 return ERROR_TARGET_NOT_HALTED;
528 LOG_ERROR("offset 0x%08" PRIx32 " breaks required 2-byte alignment", offset);
529 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
532 sysrq_buffer = malloc(param_sz + psoc4_info->row_size);
533 if (sysrq_buffer == NULL) {
534 LOG_ERROR("no memory for row buffer");
538 uint8_t *row_buffer = (uint8_t *)sysrq_buffer + param_sz;
539 uint32_t row_num = offset / psoc4_info->row_size;
540 uint32_t row_offset = offset - row_num * psoc4_info->row_size;
542 memset(row_buffer, 0, row_offset);
544 bool save_poll = jtag_poll_get_enabled();
545 jtag_poll_set_enabled(false);
548 uint32_t chunk_size = psoc4_info->row_size - row_offset;
549 if (chunk_size > count) {
551 memset(row_buffer + chunk_size, 0, psoc4_info->row_size - chunk_size);
553 memcpy(row_buffer + row_offset, buffer, chunk_size);
554 LOG_DEBUG("offset / row: 0x%08" PRIx32 " / %" PRIu32 ", size %" PRIu32 "",
555 offset, row_offset, chunk_size);
557 /* Call "Load Latch" system ROM API */
558 sysrq_buffer[1] = psoc4_info->row_size - 1;
559 retval = psoc4_sysreq(target, PSOC4_CMD_LOAD_LATCH,
560 0, /* Byte number in latch from what to write */
561 sysrq_buffer, param_sz + psoc4_info->row_size);
562 if (retval != ERROR_OK)
565 /* Call "Program Row" or "Write Row" system ROM API */
566 uint32_t sysrq_param;
567 retval = psoc4_sysreq(target, psoc4_info->cmd_program_row,
569 &sysrq_param, sizeof(sysrq_param));
570 if (retval != ERROR_OK)
573 buffer += chunk_size;
580 jtag_poll_set_enabled(save_poll);
589 static int psoc4_probe(struct flash_bank *bank)
591 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
592 struct target *target = bank->target;
593 uint32_t flash_size_in_kb = 0;
594 uint32_t max_flash_size_in_kb;
598 uint32_t base_address = 0x00000000;
601 if (target->state != TARGET_HALTED) {
602 LOG_ERROR("Target not halted");
603 return ERROR_TARGET_NOT_HALTED;
606 psoc4_info->probed = 0;
607 psoc4_info->cmd_program_row = PSOC4_CMD_PROGRAM_ROW;
609 /* Get the CPUID from the ARM Core
610 * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/DDI0432C_cortex_m0_r0p0_trm.pdf 4.2.1 */
611 int retval = target_read_u32(target, 0xE000ED00, &cpu_id);
612 if (retval != ERROR_OK)
615 LOG_DEBUG("cpu id = 0x%08" PRIx32 "", cpu_id);
617 /* set page size, protection granularity and max flash size depending on family */
618 switch ((cpu_id >> 4) & 0xFFF) {
619 case 0xc20: /* M0 -> PSoC4 */
621 max_flash_size_in_kb = 32;
624 LOG_WARNING("Cannot identify target as a PSoC 4 family.");
628 uint32_t spcif_geometry;
629 retval = target_read_u32(target, PSOC4_SPCIF_GEOMETRY, &spcif_geometry);
630 if (retval == ERROR_OK) {
631 row_size = 128 * ((spcif_geometry >> 22) & 3);
632 flash_size_in_kb = (spcif_geometry & 0xffff) * 256 / 1024;
633 LOG_INFO("SPCIF geometry: %" PRIu32 " kb flash, row %" PRIu32 " bytes.",
634 flash_size_in_kb, row_size);
637 /* Early revisions of ST-Link v2 have some problem reading PSOC4_SPCIF_GEOMETRY
638 and an error is reported late. Dummy read gets this error. */
640 target_read_u32(target, PSOC4_CPUSS_SYSREQ, &dummy);
642 /* get silicon ID from target. */
643 retval = psoc4_get_silicon_id(target, &silicon_id, &protection);
644 if (retval != ERROR_OK)
647 const struct psoc4_chip_details *details = psoc4_details_by_id(silicon_id);
649 LOG_INFO("%s device detected.", details->type);
650 if (flash_size_in_kb == 0)
651 flash_size_in_kb = details->flash_size_in_kb;
652 else if (flash_size_in_kb != details->flash_size_in_kb)
653 LOG_ERROR("Flash size mismatch");
656 psoc4_info->row_size = row_size;
657 psoc4_info->silicon_id = silicon_id;
658 psoc4_info->chip_protection = protection;
660 /* failed reading flash size or flash size invalid (early silicon),
661 * default to max target family */
662 if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {
663 LOG_WARNING("PSoC 4 flash size failed, probe inaccurate - assuming %" PRIu32 " k flash",
664 max_flash_size_in_kb);
665 flash_size_in_kb = max_flash_size_in_kb;
668 /* if the user sets the size manually then ignore the probed value
669 * this allows us to work around devices that have a invalid flash size register value */
670 if (psoc4_info->user_bank_size) {
671 LOG_INFO("ignoring flash probed value, using configured bank size");
672 flash_size_in_kb = psoc4_info->user_bank_size / 1024;
675 LOG_INFO("flash size = %" PRIu32 " kbytes", flash_size_in_kb);
677 /* did we assign flash size? */
678 assert(flash_size_in_kb != 0xffff);
680 /* calculate numbers of pages */
681 uint32_t num_rows = flash_size_in_kb * 1024 / row_size;
683 /* check that calculation result makes sense */
684 assert(num_rows > 0);
688 bank->sectors = NULL;
691 bank->base = base_address;
692 bank->size = num_rows * row_size;
693 bank->num_sectors = num_rows;
694 bank->sectors = malloc(sizeof(struct flash_sector) * num_rows);
697 for (i = 0; i < num_rows; i++) {
698 bank->sectors[i].offset = i * row_size;
699 bank->sectors[i].size = row_size;
700 bank->sectors[i].is_erased = -1;
701 bank->sectors[i].is_protected = 1;
704 LOG_INFO("flash bank set %" PRIu32 " rows", num_rows);
705 psoc4_info->probed = 1;
710 static int psoc4_auto_probe(struct flash_bank *bank)
712 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
713 if (psoc4_info->probed)
715 return psoc4_probe(bank);
719 static int get_psoc4_info(struct flash_bank *bank, char *buf, int buf_size)
721 struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
724 if (psoc4_info->probed == 0)
727 const struct psoc4_chip_details *details = psoc4_details_by_id(psoc4_info->silicon_id);
730 uint32_t chip_revision = psoc4_info->silicon_id & 0xffff;
731 printed = snprintf(buf, buf_size, "PSoC 4 %s rev 0x%04" PRIx32 " package %s",
732 details->type, chip_revision, details->package);
734 printed = snprintf(buf, buf_size, "PSoC 4 silicon id 0x%08" PRIx32 "",
735 psoc4_info->silicon_id);
740 const char *prot_txt = psoc4_decode_chip_protection(psoc4_info->chip_protection);
741 uint32_t size_in_kb = bank->size / 1024;
742 snprintf(buf, buf_size, " flash %" PRIu32 " kb %s", size_in_kb, prot_txt);
747 COMMAND_HANDLER(psoc4_handle_mass_erase_command)
750 return ERROR_COMMAND_SYNTAX_ERROR;
752 struct flash_bank *bank;
753 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
754 if (ERROR_OK != retval)
757 retval = psoc4_mass_erase(bank);
758 if (retval == ERROR_OK)
759 command_print(CMD_CTX, "psoc mass erase complete");
761 command_print(CMD_CTX, "psoc mass erase failed");
767 static const struct command_registration psoc4_exec_command_handlers[] = {
769 .name = "mass_erase",
770 .handler = psoc4_handle_mass_erase_command,
771 .mode = COMMAND_EXEC,
773 .help = "Erase entire flash device.",
776 .name = "flash_autoerase",
777 .handler = psoc4_handle_flash_autoerase_command,
778 .mode = COMMAND_EXEC,
779 .usage = "bank_id on|off",
780 .help = "Set autoerase mode for flash bank.",
782 COMMAND_REGISTRATION_DONE
785 static const struct command_registration psoc4_command_handlers[] = {
789 .help = "PSoC 4 flash command group",
791 .chain = psoc4_exec_command_handlers,
793 COMMAND_REGISTRATION_DONE
796 struct flash_driver psoc4_flash = {
798 .commands = psoc4_command_handlers,
799 .flash_bank_command = psoc4_flash_bank_command,
800 .erase = psoc4_erase,
801 .protect = psoc4_protect,
802 .write = psoc4_write,
803 .read = default_flash_read,
804 .probe = psoc4_probe,
805 .auto_probe = psoc4_auto_probe,
806 .erase_check = default_flash_blank_check,
807 .protect_check = psoc4_protect_check,
808 .info = get_psoc4_info,