This is an automated email from Gerrit.
psocprogrammer ([email protected]) just uploaded a new patch set to
Gerrit, which you can find at http://openocd.zylin.com/4065
-- gerrit
commit b18762ba5d6bad248473d000ddb0b05035bd7581
Author: Yuriy Vynnychek <[email protected]>
Date: Wed Mar 15 11:40:38 2017 +0200
Added support for new PSoC 6 device.
Change-Id: Ib8d09789367840b7f9dfd7914df63d99e472abdc
Signed-off-by: Yuriy Vynnychek <[email protected]>
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index 727e4f2..77c980a 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -40,6 +40,7 @@ NOR_DRIVERS = \
%D%/ocl.c \
%D%/pic32mx.c \
%D%/psoc4.c \
+ %D%/psoc6.c \
%D%/sim3x.c \
%D%/spi.c \
%D%/stmsmi.c \
diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c
new file mode 100755
index 0000000..fa272a3
--- /dev/null
+++ b/src/flash/nor/psoc6.c
@@ -0,0 +1,996 @@
+/*******************************************************************************
+ * Copyright (C) 2017 by Yuriy Vynnychek (PSoC 6 support derived from PSoC
4)*
+ * Yuriy.Vynnychek.cypress.com
*
+ *
*
+ * This program is free software; you can redistribute it and/or modify
*
+ * it under the terms of the GNU General Public License as published by
*
+ * the Free Software Foundation; either version 2 of the License, or
*
+ * (at your option) any later version.
*
+ *
*
+ * This program is distributed in the hope that it will be useful,
*
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
*
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
+ * GNU General Public License for more details.
*
+ *
*
+ * You should have received a copy of the GNU General Public License
*
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
+
******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "imp.h"
+#include <helper/binarybuffer.h>
+#include <jtag/jtag.h>
+#include <target/algorithm.h>
+#include <target/armv7m.h>
+
+/* device documets:
+ PSoC(R) 6: PSoC CY8C6XXX Family Datasheet
+ Document Number:
+
+ PSoC CY8C6XXX Family PSoC(R) 6 Architecture TRM
+ Document No. 002-15785 Rev. ** xx/xx/2016
+
+ CY8C6XXX PSOC(R) 6 BLE 2 REGISTERS TECHNICAL REFERENCE MANUAL (TRM)
+ Document No. 002-12544 Rev. ** 05/09/2016
+
+ CY8C6XXX Programming Specifications
+ Document No.*/
+/*--------------------------------------------------------------------------------------------
+ *Base addresses
+
*--------------------------------------------------------------------------------------------
+ */
+/* 256kB System RAM */
+#define MEM_BASE_SRAM0
0x08000000u
+/* 1024kB FLASH Main Region */
+#define MEM_BASE_FLASH
0x10000000u
+/* Peripheral Interconnect */
+#define MEM_BASE_MMIO
0x40000000u
+/* 0x40200000: Core platform peripherals */
+#define MEM_BASE_MMIO2
(MEM_BASE_MMIO + 0x200000u)
+/* 0x40230000: Base address for IPC structs */
+#define MEM_BASE_IPC
(MEM_BASE_MMIO2 + 0x30000u)
+/* 0x40231000: Base address for IPC_INTR struct */
+#define MEM_BASE_IPCINTR
(MEM_BASE_MMIO2 + 0x31000u)
+
+#define PSOC6_CHIP_PROT_UNKNOWN 0x0u
+#define PSOC6_CHIP_PROT_VIRGIN 0x1u
+#define PSOC6_CHIP_PROT_NORMAL 0x2u
+#define PSOC6_CHIP_PROT_SECURE 0x3u
+#define PSOC6_CHIP_PROT_DEAD 0x4u
+
+/* Addresses for IPC_STRUCT and IPC_INTR_STRUCT */
+#define IPC_INTR_STRUCT_SIZE 0x20u
+#define IPC_STRUCT_SIZE
0x20u
+/* 0x40230000: CM0+ IPC_STRUCT absolute address */
+#define IPC_STRUCT0
MEM_BASE_IPC
+/* 0x40230020: CM4 IPC_STRUCT absolute address */
+#define IPC_STRUCT1
(IPC_STRUCT0 + IPC_STRUCT_SIZE)
+/* 0x40230040: DAP IPC_STRUCT absolute address */
+#define IPC_STRUCT2
(IPC_STRUCT1 + IPC_STRUCT_SIZE)
+/* 0x40231000: IPC_INTR struct absolute address */
+#define IPC_INTR_STRUCT
MEM_BASE_IPCINTR
+
+#define FLASH_SECTOR_LENGTH 256u
+#define PSOC6_SPCIF_GEOMETRY
(MEM_BASE_MMIO2+0x5f00cu)
+
+/* Registers offsets in IPC_STRUCT[x]
+ * This register is used to acquire a lock. This register is NOT SW writable.*/
+#define IPC_STRUCT_ACQUIRE_OFFSET 0x00u
+/* This field allows for the generation of notification events to the IPC
interrupt structures. */
+#define IPC_STRUCT_NOTIFY_OFFSET 0x08u
+/* This field holds a 32-bit data element that is associated with the IPC
structure. */
+#define IPC_STRUCT_DATA_OFFSET 0x0Cu
+/* IPC lock status */
+#define IPC_STRUCT_LOCK_STATUS_OFFSET 0x10u
+
+/* Registers offsets in IPC_INTR_STRUCT
+ * IPC interrupt mask */
+#define IPC_INTR_STRUCT_INTR_IPC_MASK_OFFSET 0x08u
+/* Specifies if the lock is successfully acquired or not: '0': Not
successfully acquired, '1': Successfully acquired.*/
+#define IPC_STRUCT_ACQUIRE_SUCCESS_MSK 0x80000000u
+/* Specifies if the lock is acquired. */
+#define IPC_STRUCT_LOCK_STATUS_ACQUIRED_MSK 0x80000000u
+
+/* Misc
+ * Timeout attempts of IPC_STRUCT acuire*/
+#define IPC_STRUCT_ACQUIRE_TIMEOUT_ATTEMPTS 250u
+/* Timeout attempts of IPC_STRUCT data */
+#define IPC_STRUCT_DATA_TIMEOUT_ATTEMPTS 250u
+/* 0x08001000: Address of SRAM where the API�s parameters are stored by SW. */
+#define SRAM_SCRATCH_ADDR
(MEM_BASE_SRAM0 + 0x00001000u)
+#define ROW_SIZE
512u
+/* Timemout 10 ms */
+#define DELAY_10_MS
10000u
+
+/*--------------------------------------------------------------------------------------------
+ *SROM APIs
+
*--------------------------------------------------------------------------------------------
+ *SROM APIs masks
+ *[0]: 1 - arguments are passed in IPC.DATA. 0 - arguments are passed in SRAM*/
+#define MXS40_SROMAPI_DATA_LOCATION_MSK 0x00000001u
+/* Status Code: 4 bits [31:28] of the data register */
+#define MXS40_SROMAPI_STATUS_MSK 0xF0000000u
+/* Status Code = 0xA */
+#define MXS40_SROMAPI_STAT_SUCCESS 0xA0000000u
+
+/* Sys calls IDs (SROM API Op code)
+ * [31:24]: Opcode = 0x00; [0]: 1 - arguments are passed in IPC.DATA*/
+#define MXS40_SROMAPI_SILID_CODE 0x00000001u
+/* [15:8]: ID type */
+#define MXS40_SROMAPI_SILID_TYPE_MSK 0x0000FF00u
+#define MXS40_SROMAPI_SILID_TYPE_ROL 0x08u
+/* [15:8]: Family Id Hi */
+#define MXS40_SROMAPI_SILID_FAMID_HI_MSK 0x0000FF00u
+#define MXS40_SROMAPI_SILID_FAMID_HI_ROR 0x08u
+ /* [7:0]: Family Id Lo */
+#define MXS40_SROMAPI_SILID_FAMID_LO_MSK 0x000000FFu
+#define MXS40_SROMAPI_SILID_FAMID_LO_ROR 0u
+/* [19:16]: Protection state */
+#define MXS40_SROMAPI_SILID_PROT_MSK 0x000F0000u
+#define MXS40_SROMAPI_SILID_PROT_ROR 0x10u
+/* [15:8]: Silicon Id Hi */
+#define MXS40_SROMAPI_SILID_SILID_HI_MSK 0x0000FF00u
+#define MXS40_SROMAPI_SILID_SILID_HI_ROR 0x08u
+/* [15:8]: Silicon Id Lo */
+#define MXS40_SROMAPI_SILID_SILID_LO_MSK 0x000000FFu
+#define MXS40_SROMAPI_SILID_SILID_LO_ROR 0x00u
+/* [31:24]: Opcode = 0x06; [0]: 0 - arguments are passed in SRAM */
+#define MXS40_SROMAPI_PROGRAMROW_CODE 0x06000100u
+/* [31:24]: Opcode = 0x14; [0]: 0 - arguments are passed in SRAM */
+#define MXS40_SROMAPI_ERASESECTOR_CODE 0x14000100u
+/* [31:24]: Opcode = 0x1C; [0]: 0 - arguments are passed in SRAM */
+#define MXS40_SROMAPI_ERASEROW_CODE 0x1C000100u
+#define IPC_ID
2u
+#define LENGHT_SILICON_ID 16u
+#define SIZE_OF_STRING 32u
+
+/*Offset for data location/size and Integrity check*/
+#define DATA_LOCATION_OFFSET 0x04
+
+/*Property for data location/size and Integrity check*/
+#define DATA_LOCATION_PROPERTY 0x106
+
+/*Offset for flash address which will be programed*/
+#define FLASH_ADDRESS_OFFSET 0x08
+
+/*Offset for first data byte in SRAM*/
+#define DATA_OFFSET
0x10
+
+/*Offset for set pointer to the first data byte location*/
+#define POINTER_ON_FIRST_BYTE_LOCATION_OFFSET 0x0C
+
+struct Psoc6ChipDetails {
+ uint32_t id;
+ const char *type;
+ uint32_t flashSizeInKb;
+};
+
+/* list of PSoC 6 chips
+ * flashSizeInKb is not necessary as it can be decoded from SPCIF_GEOMETRY*/
+const struct Psoc6ChipDetails psoc6Devices[] = {
+ /* PSoC 6 BLE II */
+ { 0xE2071100, "CY8C616FMI-BL603", .flashSizeInKb = 512 },
+ { 0xE2081100, "CY8C616FMI-BL673", .flashSizeInKb = 512 },
+ { 0xE2091100, "CY8C616LQI-BL601", .flashSizeInKb = 512 },
+ { 0xE20A1100, "CY8C616LQI-BL671", .flashSizeInKb = 512 },
+ { 0xE20B1100, "CY8C617FMI-BL603", .flashSizeInKb = 1024 },
+ { 0xE20C1100, "CY8C617FMI-BLD73", .flashSizeInKb = 1024 },
+ { 0xE20D1100, "CY8C626FMI-BL603", .flashSizeInKb = 512 },
+ { 0xE20E1100, "CY8C626BZI-BL604", .flashSizeInKb = 512 },
+ { 0xE20F1100, "CY8C626BZI-BL674", .flashSizeInKb = 512 },
+ { 0xE2111100, "CY8C627BZI-BL604", .flashSizeInKb = 1024 },
+ { 0xE2121100, "CY8C627FMI-BLD73", .flashSizeInKb = 1024 },
+ { 0xE2131100, "CY8C627BZI-BLD74", .flashSizeInKb = 1024 },
+ { 0xE2141100, "CY8C636BZI-BL604", .flashSizeInKb = 512 },
+ { 0xE2151100, "CY8C636BZI-BL674", .flashSizeInKb = 512 },
+ { 0xE2161100, "CY8C636FMI-BL603", .flashSizeInKb = 512 },
+ { 0xE2171100, "CY8C636FMI-BL673", .flashSizeInKb = 512 },
+ { 0xE2181100, "CY8C636LQI-BL601", .flashSizeInKb = 512 },
+ { 0xE2191100, "CY8C636LQI-BL671", .flashSizeInKb = 512 },
+ { 0xE21A1100, "CY8C637BZI-BLD04", .flashSizeInKb = 1024 },
+ { 0xE2011100, "CY8C637BZI-BLD74", .flashSizeInKb = 1024 },
+ { 0xE21C1100, "CY8C637FMI-BLD03", .flashSizeInKb = 1024 },
+ { 0xE2021100, "CY8C637FMI-BLD73", .flashSizeInKb = 1024 },
+ { 0xE21E1100, "CY8C637LQI-BLD01", .flashSizeInKb = 1024 },
+ { 0xE2031100, "CY8C637LQI-BLD71", .flashSizeInKb = 1024 },
+ { 0xE2041100, "CY8C68237FM-BLE", .flashSizeInKb = 1024 },
+ { 0xE2051100, "CY8C68237BZ-BLE", .flashSizeInKb = 1024 },
+
+ /* PSoC 6 M */
+ { 0xE2001100, "CY8C637BZI-MD76", .flashSizeInKb = 1024 },
+ { 0xE2201100, "CY8C616BZI-M606", .flashSizeInKb = 512 },
+ { 0xE2211100, "CY8C616BZI-M676", .flashSizeInKb = 512 },
+ { 0xE2221100, "CY8C617BZI-MD76", .flashSizeInKb = 1024 },
+ { 0xE2231100, "CY8C626BZI-M606", .flashSizeInKb = 512 },
+ { 0xE2241100, "CY8C627BZI-MD76", .flashSizeInKb = 1024 },
+ { 0xE2251100, "CY8C636BZI-MD06", .flashSizeInKb = 512 },
+ { 0xE2261100, "CY8C636BZI-MD76", .flashSizeInKb = 512 },
+ { 0xE2271100, "CY8C637BZI-MD06", .flashSizeInKb = 1024 },
+};
+
+struct psoc6FlashBank {
+ uint32_t rowSize;
+ uint32_t userBankSize;
+ int probed;
+ uint32_t siliconId;
+ uint8_t chipProtection;
+ uint32_t flashSizeInKb;
+};
+
+static const struct Psoc6ChipDetails *psoc6_details_by_id(uint32_t siliconId)
+{
+ const struct Psoc6ChipDetails *p = psoc6Devices;
+ const struct Psoc6ChipDetails *chipInfo;
+ uint16_t i;
+ uint16_t id = siliconId >> LENGHT_SILICON_ID; /* ignore die revision */
+ for (i = 0; i < sizeof(psoc6Devices)/sizeof(psoc6Devices[0]); i++) {
+ if (p->id == id)
+ chipInfo = p;
+ p++;
+ }
+ LOG_INFO("Unknown PSoC 6 device silicon id 0x%08" PRIx32 ".",
siliconId);
+ return chipInfo;
+}
+
+static const char *psoc6_decode_chipProtection(uint8_t protection)
+{
+ char *protectType = calloc(SIZE_OF_STRING, sizeof(*protectType));
+ switch (protection) {
+ case PSOC6_CHIP_PROT_UNKNOWN:
+ strcpy(protectType, "protection UNKNOWN");
+ break;
+ case PSOC6_CHIP_PROT_VIRGIN:
+ strcpy(protectType, "protection VIRGIN");
+ break;
+ case PSOC6_CHIP_PROT_NORMAL:
+ strcpy(protectType, "protection NORMAL");
+ break;
+ case PSOC6_CHIP_PROT_SECURE:
+ strcpy(protectType, "protection SECURE");
+ break;
+ case PSOC6_CHIP_PROT_DEAD:
+ strcpy(protectType, "protection DEAD");
+ break;
+ default:
+ LOG_WARNING("Unknown protection state 0x%02" PRIx8 "",
protection);
+ strcpy(protectType, "Not allowed");
+ break;
+ }
+
+ return protectType;
+}
+
+FLASH_BANK_COMMAND_HANDLER(psoc6_flash_bank_command)
+{
+ struct psoc6FlashBank *psoc6_info;
+ int hr = ERROR_OK;
+
+ if (CMD_ARGC < 6) {
+ hr = ERROR_COMMAND_SYNTAX_ERROR;
+ } else {
+ psoc6_info = calloc(1, sizeof(struct psoc6FlashBank));
+ bank->driver_priv = psoc6_info;
+ psoc6_info->userBankSize = bank->size;
+ }
+ return hr;
+}
+
+
+/*------------------------------------------------------------------------------
+ SROM APIs basics
+--------------------------------------------------------------------------------
+******************************************************************************
+* Purpose: Polls lock status of IPC structure
+* Parameter:
+* target - current target device
+* ipcId - Id of IPC structure
+* - 0:
IPC_STRUCT0 (CM0+)
+* - 1:
IPC_STRUCT1 (CM4)
+* - 2:
IPC_STRUCT2 (DAP)
+* lockExpected - true if look state is expected, or false
if look state is not expected
+* timeOutAttempts - timeout
+* Return:
+* ERROR_OK: IPC structure locked successfully
+* ERROR_FAIL: Cannot lock IPC structure
+*******************************************************************************/
+int Ipc_PollLockStatus(struct target *target, uint32_t ipcId, bool
lockExpected, int timeOutAttempts)
+{
+ /* Poll lock status*/
+ int hr = ERROR_OK;
+ int attemptsElapsed = 0x00;
+ bool isExpectedStatus = false;
+ uint32_t readData;
+ uint32_t ipcAddr = IPC_STRUCT0 + IPC_STRUCT_SIZE * ipcId;
+ do {
+ /* Check lock status*/
+ hr = target_read_u32(target, ipcAddr +
IPC_STRUCT_LOCK_STATUS_OFFSET, &readData);
+ if (hr == ERROR_OK) {
+ bool isLocked = (readData &
IPC_STRUCT_LOCK_STATUS_ACQUIRED_MSK) != 0;
+ isExpectedStatus = (lockExpected && isLocked) ||
(!lockExpected && !isLocked);
+ }
+ /* Check for timeout*/
+ if (!isExpectedStatus) {
+ if (attemptsElapsed > timeOutAttempts) {
+ LOG_ERROR("Timeout polling lock status of
IPC_STRUCT");
+ hr = ERROR_FAIL;
+ break;
+ }
+ usleep(DELAY_10_MS);
+ attemptsElapsed++;
+ }
+ } while (!isExpectedStatus);
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Acquires MXS40 IPC structure
+* Parameter:
+* target - current target device
+* ipcId - Id of IPC structure
+* - 0:
IPC_STRUCT0 (CM0+)
+* - 1:
IPC_STRUCT1 (CM4)
+* - 2:
IPC_STRUCT2 (DAP)
+* timeOutAttempts - timeout
+* Return:
+* ERROR_OK: IPC structure acquired successfully
+* ERROR_FAIL: Cannon acquire IPC structure
+*******************************************************************************/
+int Ipc_Acquire(struct target *target, char ipcId, int timeOutAttempts)
+{
+ int hr = ERROR_OK;
+ int attemptsElapsed = 0x00;
+ bool isAcquired = false;
+ uint32_t readData;
+ uint32_t ipcAddr = IPC_STRUCT0 + IPC_STRUCT_SIZE * ipcId;
+
+ do {
+ /* Acquire the lock in DAP IPC struct (IPC_STRUCT.ACQUIRE).*/
+ hr = target_write_u32(target, ipcAddr +
IPC_STRUCT_ACQUIRE_OFFSET, IPC_STRUCT_ACQUIRE_SUCCESS_MSK);
+ if (hr == ERROR_OK) {
+ /* Check if data is writed on first step */
+ hr = target_read_u32(target, ipcAddr +
IPC_STRUCT_ACQUIRE_OFFSET, &readData);
+ if (hr == ERROR_OK)
+ isAcquired = (readData &
IPC_STRUCT_ACQUIRE_SUCCESS_MSK) != 0;
+ }
+ /* Check for timeout */
+ if (!isAcquired) {
+ if (attemptsElapsed > timeOutAttempts) {
+ LOG_ERROR("Timeout acquiring IPC_STRUCT");
+ hr = ERROR_FAIL;
+ break;
+ }
+ usleep(DELAY_10_MS);
+ attemptsElapsed++;
+ }
+ } while (!isAcquired);
+
+ if (isAcquired) {
+ /* If IPC structure is acquired, the lock status should be set
*/
+ hr = Ipc_PollLockStatus(target, ipcId, true, timeOutAttempts);
+ }
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Polls execution status of SROM API
+* Parameter:
+* target - current target device
+* address - Memory address of SROM API status word
+* timeOutAttempts - timeout
+* dataOut - status word
+* Return:
+* ERROR_OK: SROM API returned successful execution status
+* ERROR_FAIL: SROM API execution failed
+*******************************************************************************/
+int PollSromApiStatus(struct target *target, int address, int timeOutAttempts,
uint32_t *dataOut)
+{
+ /* Poll data from SRAM, returned after system call execution */
+ int hr = ERROR_OK;
+ int attemptsElapsed = 0x00;
+ bool isAcquired = false;
+
+ do {
+ /* Poll data */
+ hr = target_read_u32(target, address, dataOut);
+ if (hr == ERROR_OK)
+ isAcquired = (*dataOut & MXS40_SROMAPI_STATUS_MSK) ==
MXS40_SROMAPI_STAT_SUCCESS;
+
+ /* Check for timeout */
+ if (!isAcquired) {
+ if (attemptsElapsed > timeOutAttempts) {
+ LOG_DEBUG("PollSromApiStatus - FAIL status -
0x%08x", (unsigned int)*dataOut);
+ LOG_ERROR("Timeout waiting for SROM API
execution complete");
+ hr = ERROR_FAIL;
+ break;
+ }
+ usleep(DELAY_10_MS);
+ attemptsElapsed ++;
+ }
+ } while (!isAcquired);
+
+ LOG_DEBUG("PollSromApiStatus - OK status - 0x%08x", (unsigned
int)*dataOut);
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose:
+* Calls SROM API
+* SROM APIs are executed by
invoking a system call & providing
+* the corresponding arguments.
+* System calls can be performed
by CM0+, CM4 or DAP.
+* Each of them have a reserved
IPC structure (used as a mailbox) through which
+* they can request CM0+ to
perform a system call.
+* Each one acquires the specific
mailbox, writes the opcode and
+* argument to the data field of
the mailbox and notifies a dedicated
+* IPC interrupt structure. This
results in an NMI interrupt in M0+.
+* Parameter:
+* target - current target device
+* callIdAndParams - OpCode of SROM API and params (in
case all params are in IPC structure)
+* dataOut - status word
+* Return:
+* ERROR_OK: SROM API returned successful execution status
+* ERROR_FAIL: SROM API execution failed
+*******************************************************************************/
+int CallSromApi(struct target *target, uint32_t callIdAndParams, uint32_t
*dataOut)
+{
+ int hr;
+ /* Check where the arguments for this API are located
+ [0]: 1 - arguments are passed in IPC.DATA. 0 - arguments are
passed in SRAM */
+ bool isDataInRam = (callIdAndParams & MXS40_SROMAPI_DATA_LOCATION_MSK)
== 0;
+ unsigned long IPC_STRUC = IPC_STRUCT2;
+ /* Acquire IPC_STRUCT[0] for CM0+ */
+ hr = Ipc_Acquire(target, IPC_ID, IPC_STRUCT_ACQUIRE_TIMEOUT_ATTEMPTS);
+ if (hr == ERROR_OK) {
+ /* Write to IPC_STRUCT0.DATA - Sys call ID and Parameters
+ OR address in SRAM, where they are located */
+ if (isDataInRam) {
+ LOG_DEBUG("CallSromApi: isDataInRam = true: address ->
0x%x, data -> 0x%x", (unsigned int)(IPC_STRUC + IPC_STRUCT_DATA_OFFSET),
SRAM_SCRATCH_ADDR);
+ hr = target_write_u32(target, (unsigned int)(IPC_STRUC
+ IPC_STRUCT_DATA_OFFSET), SRAM_SCRATCH_ADDR);
+ } else {
+ LOG_DEBUG("CallSromApi: isDataInRam = false: address ->
0x%x, data -> 0x%x", (unsigned int)(IPC_STRUC + IPC_STRUCT_DATA_OFFSET),
callIdAndParams);
+ hr = target_write_u32(target, (unsigned int)(IPC_STRUC
+ IPC_STRUCT_DATA_OFFSET), callIdAndParams);
+ }
+ if (hr == ERROR_OK) {
+ /* Enable notification interrupt of
IPC_INTR_STRUCT0(CM0+) for IPC_STRUCT2 */
+ hr = target_write_u32(target, (IPC_INTR_STRUCT +
IPC_INTR_STRUCT_INTR_IPC_MASK_OFFSET), 1 << (16 + IPC_ID));
+ if (hr == ERROR_OK) {
+ /* Notify to IPC_INTR_STRUCT0. IPC_STRUCT2.MASK
<- Notify */
+ hr = target_write_u32(target, IPC_STRUC +
IPC_STRUCT_NOTIFY_OFFSET, 1);
+ if (hr == ERROR_OK) {
+ /* Poll lock status */
+ hr = Ipc_PollLockStatus(target, IPC_ID,
false, IPC_STRUCT_ACQUIRE_TIMEOUT_ATTEMPTS);
+ if (hr == ERROR_OK) {
+ /* Poll Data byte */
+ if (isDataInRam)
+ hr =
PollSromApiStatus(target, SRAM_SCRATCH_ADDR, IPC_STRUCT_DATA_TIMEOUT_ATTEMPTS,
dataOut);
+ else
+ hr =
PollSromApiStatus(target, IPC_STRUC + IPC_STRUCT_DATA_OFFSET,
IPC_STRUCT_DATA_TIMEOUT_ATTEMPTS, dataOut);
+ }
+ }
+ }
+ }
+
+ }
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Get Silicon ID for connected target
+* Parameter:
+* target - current target device
+* siliconId - value for Silicon ID
+* protection - value for protected state
+* Return:
+* ERROR_OK: Resault of get silicon id operation is OK
+* ERROR_FAIL: Resault of get silicon id operation is FAIL
+*******************************************************************************/
+static int Psoc6GetSiliconId(struct target *target, uint32_t *siliconId,
uint8_t *protection)
+{
+ int hr = 0;
+ uint32_t dataOut0, dataOut1;
+ uint32_t params;
+ uint32_t familyIdHi = 0x0;
+ uint32_t familyIdLo = 0x0;
+ uint32_t siliconIdHi = 0x0;
+ uint32_t siliconIdLo = 0x0;
+
+ /* Type 0: Get Family ID & Revision ID
+ SRAM_SCRATCH: OpCode */
+ params = MXS40_SROMAPI_SILID_CODE + (MXS40_SROMAPI_SILID_TYPE_MSK & (0
<< MXS40_SROMAPI_SILID_TYPE_ROL));
+ hr = CallSromApi(target, params, &dataOut0);
+ if (hr == ERROR_OK) {
+ /* Type 1: Get Silicon ID and protection state */
+ params = (MXS40_SROMAPI_SILID_CODE +
(MXS40_SROMAPI_SILID_TYPE_MSK & (1 << MXS40_SROMAPI_SILID_TYPE_ROL)));
+ hr = CallSromApi(target, params, &dataOut1);
+ if (hr == ERROR_OK) {
+ familyIdHi = (dataOut0 &
MXS40_SROMAPI_SILID_FAMID_HI_MSK) >> MXS40_SROMAPI_SILID_FAMID_HI_ROR;
/* Family ID High */
+ familyIdLo = (dataOut0 &
MXS40_SROMAPI_SILID_FAMID_LO_MSK) >> MXS40_SROMAPI_SILID_FAMID_LO_ROR;
/* Family ID Low */
+ siliconIdHi = (dataOut1 &
MXS40_SROMAPI_SILID_SILID_HI_MSK) >> MXS40_SROMAPI_SILID_SILID_HI_ROR; /*
Silicon ID High */
+ siliconIdLo = (dataOut1 &
MXS40_SROMAPI_SILID_SILID_LO_MSK) >> MXS40_SROMAPI_SILID_SILID_LO_ROR; /*
Silicon ID Low */
+ *protection = (dataOut1 &
MXS40_SROMAPI_SILID_PROT_MSK) >> MXS40_SROMAPI_SILID_PROT_ROR;
/* Protection state */
+ } else {
+ LOG_ERROR("Get Silicon ID and protection state has
failed results");
+ }
+ }
+ *siliconId = ((siliconIdHi & 0xFF) << 24) | ((siliconIdLo & 0xFF) <<
16) | ((familyIdHi & 0xFF) << 8) | (familyIdLo & 0xFF);
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Check if bank of flash in protected state
+* Parameter:
+* bank - flash bank
+* Return:
+* ERROR_OK: Resault of check operation is OK
+* ERROR_FAIL: Resault of check operation is FAIL
+*******************************************************************************/
+static int Psoc6ProtectCheck(struct flash_bank *bank)
+{
+ LOG_INFO("Get protection state not work in OpenOCD");
+ return ERROR_OK;
+}
+
+
+/*******************************************************************************
+* Purpose: Set protected state in bank of flash
+* Parameter:
+* bank - flash bank
+* set - protected value
+* first - first address with protected data
+* last - last address with protected data
+* Return:
+* ERROR_OK: Resault of protect operation is OK
+* ERROR_FAIL: Resault of protect operation is FAIL
+*******************************************************************************/
+static int Psoc6Protect(struct flash_bank *bank, int set, int first, int last)
+{
+ LOG_INFO("Protect for PSoC6 is not support in OpenOCD");
+ return ERROR_OK;
+}
+
+
+/*******************************************************************************
+* Purpose: Detect device and get all main parameters
+* Parameter:
+* bank - flash bank
+* Return:
+* ERROR_OK: Resault of probe operation is OK
+* ERROR_FAIL: Resault of probe operation is FAIL
+*******************************************************************************/
+static int Psoc6Probe(struct flash_bank *bank)
+{
+ struct psoc6FlashBank *psoc6Info = bank->driver_priv;
+ struct target *target = bank->target;
+ uint32_t hr;
+ uint32_t flashSizeInKb = 0;
+ uint32_t maxFlashSizeInKb = 0;
+ uint32_t siliconId = 0;
+ uint32_t rowSize = 0;
+ uint8_t protection = 0;
+ uint32_t spcifGeometry = 0;
+
+ uint32_t haltStatus;
+
+ target_read_u32(target, 0xE000EDF0, &haltStatus);
+ LOG_DEBUG("Status HALT - 0x%x", haltStatus);
+ psoc6Info->probed = 0;
+ hr = target_read_u32(target, PSOC6_SPCIF_GEOMETRY, &spcifGeometry);
+ if (hr == ERROR_OK) {
+ rowSize = ROW_SIZE;
+ flashSizeInKb = (FLASH_SECTOR_LENGTH * (((spcifGeometry >> 24)
& 0xFF) + 1));
+ LOG_INFO("SPCIF geometry: %" PRIu32 " kb flash, row %" PRIu32 "
bytes.", flashSizeInKb, rowSize);
+
+ /* Get silicon ID from target. */
+ hr = Psoc6GetSiliconId(target, &siliconId, &protection);
+ if (hr == ERROR_OK) {
+
+ const struct Psoc6ChipDetails *details =
psoc6_details_by_id(siliconId);
+ if (details) {
+ LOG_INFO("%s device detected.", details->type);
+ if (flashSizeInKb == 0) {
+ flashSizeInKb = details->flashSizeInKb;
+ } else {
+ if (flashSizeInKb !=
details->flashSizeInKb)
+ LOG_ERROR("Flash size
mismatch");
+ }
+ }
+
+ psoc6Info->flashSizeInKb = flashSizeInKb;
+ psoc6Info->rowSize = rowSize;
+ psoc6Info->siliconId = siliconId;
+ psoc6Info->chipProtection = protection;
+
+ /* failed reading flash size or flash size invalid
(early silicon),
+ default to max target family */
+ if (hr != ERROR_OK || flashSizeInKb == 0xffff ||
flashSizeInKb == 0) {
+ LOG_WARNING("PSoC 6 flash size failed, probe
inaccurate - assuming %" PRIu32 " k flash",
+ maxFlashSizeInKb);
+ flashSizeInKb = maxFlashSizeInKb;
+ }
+
+ /* if the user sets the size manually then ignore the
probed value
+ this allows us to work around devices that have a
invalid flash size register value */
+ if (psoc6Info->userBankSize) {
+ LOG_INFO("ignoring flash probed value, using
configured bank size");
+ flashSizeInKb = psoc6Info->userBankSize / 1024;
+ }
+
+ /* did we assign flash size? */
+ assert(flashSizeInKb != 0xffff);
+
+ /* calculate numbers of pages */
+ uint32_t num_rows = flashSizeInKb * 1024 / rowSize;
+
+ /* check that calculation result makes sense */
+ assert(num_rows > 0);
+
+ if (bank->sectors) {
+ free(bank->sectors);
+ bank->sectors = NULL;
+ }
+
+ bank->base = MEM_BASE_FLASH;
+ bank->size = num_rows * rowSize;
+ bank->num_sectors = num_rows;
+ bank->sectors = malloc(sizeof(struct flash_sector) *
num_rows);
+ /* This part doesn't follow the typical standard of 0xff
+ being the erased value.*/
+ bank->default_padded_value = bank->erased_value = 0x00;
+
+ uint32_t i;
+ for (i = 0; i < num_rows; i++) {
+ bank->sectors[i].offset = i * rowSize;
+ bank->sectors[i].size = rowSize;
+ bank->sectors[i].is_erased = -1;
+ bank->sectors[i].is_protected = 1;
+ }
+
+ LOG_DEBUG("psoc6Info->flashSizeInKb-> 0x%x",
psoc6Info->flashSizeInKb);
+ LOG_DEBUG("psoc6Info->rowSize-> 0x%x",
psoc6Info->rowSize);
+ LOG_DEBUG("psoc6Info->siliconId -> 0x%x",
psoc6Info->siliconId);
+ LOG_DEBUG("psoc6Info->chipProtection-> 0x%x",
psoc6Info->chipProtection);
+
+ LOG_DEBUG("bank->base -> 0x%x", bank->base);
+ LOG_DEBUG("bank->size -> 0x%x", bank->size);
+ LOG_DEBUG("bank->num_sectors-> 0x%x",
bank->num_sectors);
+
+ psoc6Info->probed = 1;
+ }
+ }
+
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Auto detect device and get all main parameters
+* Parameter:
+* bank - flash bank
+* Return:
+* ERROR_OK: Resault of probe operation is OK
+* ERROR_FAIL: Resault of probe operation is FAIL
+*******************************************************************************/
+static int Psoc6AutoProbe(struct flash_bank *bank)
+{
+ struct psoc6FlashBank *psoc6Info = bank->driver_priv;
+ int hr;
+
+ if (psoc6Info->probed)
+ hr = ERROR_OK;
+ else
+ hr = Psoc6Probe(bank);
+
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Erase sector operation for connected target
+* Parameter:
+* target - current target device
+* first - first address which will be erased
+* last - last sector which will be erased
+* Return:
+* ERROR_OK: Resault of Erase sector operation is OK
+* ERROR_FAIL: Resault of Erase sector operation is FAIL
+*******************************************************************************/
+static int EraseSector(struct target *target, int first, int last)
+{
+ int hr;
+ LOG_DEBUG("first-> 0x%x, last-> 0x%x", first, last);
+
+ for (int i = first; i < last; i++) {
+ int addr = MEM_BASE_FLASH + (i * FLASH_SECTOR_LENGTH *
1024);
+
+ /* Prepare batch request. Skip immediate responses in
batch mode.
+ SRAM_SCRATCH: OpCode */
+ hr = target_write_u32(target, SRAM_SCRATCH_ADDR,
MXS40_SROMAPI_ERASESECTOR_CODE);
+ if (hr != ERROR_OK)
+ break;
+
+ /* SRAM_SCRATCH + 0x04: Flash address to be erased (in
32-bit system address format) */
+ hr = target_write_u32(target, SRAM_SCRATCH_ADDR +
DATA_LOCATION_OFFSET, addr);
+ if (hr != ERROR_OK)
+ break;
+
+ /* Send batch request */
+ uint32_t dataOut;
+ hr = CallSromApi(target,
MXS40_SROMAPI_ERASESECTOR_CODE, &dataOut);
+ if (hr != ERROR_OK) {
+ LOG_ERROR("Sector \"%d\" from \"%d\" sectors
are not erased. Failed result for Erase operation.", i, last);
+ break;
+ }
+
+ LOG_DEBUG("Sector -> 0x%x is Erased", addr);
+ }
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Erase all sectors operation for connected target
+* Parameter:
+* bank - flash bank
+* Return:
+* ERROR_OK: Resault of Erase sector operation is OK
+* ERROR_FAIL: Resault of Erase sector operation is FAIL
+*******************************************************************************/
+static int psoc6_mass_erase(struct flash_bank *bank)
+{
+ int hr;
+ struct target *target = bank->target;
+ struct psoc6FlashBank *psoc6Info = bank->driver_priv;
+ int sectors = psoc6Info->flashSizeInKb / FLASH_SECTOR_LENGTH;
+
+ LOG_INFO("sectors-> 0x%x", sectors);
+
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ hr = ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (hr == ERROR_OK)
+ hr = EraseSector(target, 0, sectors);
+
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Erase sector operation for connected target
+* Parameter:
+* bank - flash bank
+* first - first address which will be erased
+* last - last sector which will be erased
+* Return:
+* ERROR_OK: Resault of Erase sector operation is OK
+* ERROR_FAIL: Resault of Erase sector operation is FAIL
+*******************************************************************************/
+static int Psoc6Erase(struct flash_bank *bank, int first, int last)
+{
+ int hr = ERROR_OK;
+ struct target *target = bank->target;
+ struct psoc6FlashBank *psoc6Info = bank->driver_priv;
+
+ LOG_DEBUG("bank->num_sectors-> 0x%x", bank->num_sectors);
+ LOG_DEBUG("Calc-> 0x%x", (psoc6Info->flashSizeInKb /
FLASH_SECTOR_LENGTH));
+ LOG_DEBUG("first-> 0x%x, last-> 0x%x", first, last - 1);
+
+ if ((unsigned)(last - 1) !=
(psoc6Info->flashSizeInKb/FLASH_SECTOR_LENGTH))
+ LOG_INFO("Count of sector is more then real present");
+ else
+ hr = EraseSector(target, first, last - 1);
+
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Write row operation for connected target
+* Parameter:
+* target - current target device
+* address - start address for write data
+* buffer - buffer with all data which need write
+* count - lenght data
+* Return:
+* ERROR_OK: Resault of write row operation is OK
+* ERROR_FAIL: Resault of write row operation is FAIL
+*******************************************************************************/
+static int WriteRow(struct target *target, int address, const uint8_t *
buffer, int count)
+{
+ int hr = ERROR_OK;
+ uint32_t dataOut;
+ /* 1. Prepare data for SROM API - write it to SRAM ---
+ SRAM_SCRATCH: OpCode*/
+ hr = target_write_u32(target, SRAM_SCRATCH_ADDR,
MXS40_SROMAPI_PROGRAMROW_CODE);
+ if (hr == ERROR_OK) {
+
+ /* SRAM_SCRATCH + 0x04: Data location/size and Integrity check
+ ---
+ Bits[31:24] Bits[23:16] Bits[15:8]
Bits[7:0]
+ xxxxxxxx Verify row Data
location Data size
+ ---
+ Verify row: 0-Data integrity check is not performed
1-Data integrity check is performed
+ Data location : 0 � page latch , 1- SRAM
+ Data size* � 0 � 8b ,1-16b , 2 -32b ,3 � 64b , 4 � 128b
, 5 � 256 b , 6 � 512b , 7)
+ Data size is ignored for S40 SONOS FLASH as the lowest
granularity for program operation equals page size. */
+ hr = target_write_u32(target, SRAM_SCRATCH_ADDR +
DATA_LOCATION_OFFSET, DATA_LOCATION_OFFSET);
+ if (hr == ERROR_OK) {
+ /* SRAM_SCRATCH + 0x08:
+ Flash address to be programmed (in 32-bit system
address format) */
+ hr = target_write_u32(target, SRAM_SCRATCH_ADDR +
FLASH_ADDRESS_OFFSET, address);
+ if (hr == ERROR_OK) {
+ /* SRAM_SCRATCH + 0x10...n: Data word 0..n
(Data provided should be proportional to data size provided, data to be
programmed into LSB�s ) */
+ uint32_t dataRamAddr = SRAM_SCRATCH_ADDR +
DATA_OFFSET;
+
+ /* SRAM_SCRATCH + 0x0C: Pointer to the first
data byte location */
+ hr = target_write_u32(target, SRAM_SCRATCH_ADDR
+ POINTER_ON_FIRST_BYTE_LOCATION_OFFSET, dataRamAddr);
+ if (hr == ERROR_OK) {
+ if (target_write_buffer(target,
dataRamAddr, count, buffer) != ERROR_OK) {
+ LOG_ERROR("Write to flash
buffer failed");
+ hr = ERROR_FAIL;
+ } else {
+ LOG_DEBUG("PSOC6: WRITE_ROW:
ADDRESS->0x%x, PARAMS->0x%x, DATARAMADDR->0x%x, COUNT->0x%x", address,
DATA_LOCATION_OFFSET, dataRamAddr, count);
+ /* 2. Call SROM API --- */
+ hr = CallSromApi(target,
MXS40_SROMAPI_PROGRAMROW_CODE, &dataOut);
+ }
+ }
+ }
+ }
+ }
+ return hr;
+}
+
+
+/*******************************************************************************
+* Purpose: Write operation for connected target
+* Parameter:
+* bank - flash bank
+* buffer - buffer with all data which need write
+* offset - offset of address where need to write data
+* count - lenght data
+* Return:
+* ERROR_OK: Resault of write operation is OK
+* ERROR_FAIL: Resault of write operation is FAIL
+*******************************************************************************/
+static int Psoc6Write(struct flash_bank *bank, const uint8_t *buffer, uint32_t
offset, uint32_t count)
+{
+ int hr = ERROR_OK;
+ struct psoc6FlashBank *psoc6Info = bank->driver_priv;
+ struct target *target = bank->target;
+ uint32_t bytesRemaining = count;
+ uint8_t pageBuffer[psoc6Info->rowSize];
+ uint32_t address, size, sourceOffset, maxAdressSize;
+
+ LOG_DEBUG("PSOC6_WRITE: OFFSET -> 0x%x, COUNT -> 0x%x", offset, count);
+
+ sourceOffset = 0;
+ address = bank->base + offset;
+ maxAdressSize = (address + count);
+ while (address < maxAdressSize) {
+ LOG_DEBUG("PSOC6_WRITE: SOURCE_OFFSET->0x%x, ADDRESS->0x%x,
ADDRESS+COUNT->0x%x, BYTES_REMAINING->0x%x", sourceOffset, address,
maxAdressSize, bytesRemaining);
+ LOG_INFO("Write data in 0x%x address", address);
+ size = psoc6Info->rowSize;
+ if (bytesRemaining < psoc6Info->rowSize) {
+ memset(pageBuffer, 0x00, size);
+ memcpy(pageBuffer, &buffer[sourceOffset],
bytesRemaining);
+ size = bytesRemaining;
+ } else {
+ memcpy(pageBuffer, &buffer[sourceOffset], size);
+ }
+
+ hr = WriteRow(target, address, pageBuffer, size);
+ if (hr != ERROR_OK)
+ break;
+
+ sourceOffset += size;
+ address = address + size;
+ bytesRemaining -= size;
+ }
+
+ return hr;
+}
+
+/*******************************************************************************
+* Purpose: Get information about connected target
+* Parameter:
+* bank - flash bank
+* buf - buffer all information
+* buf_size - size for buffer
+* Return:
+* ERROR_OK: Resault of get info operation operation is OK
+* ERROR_FAIL: Resault of get info operation operation is FAIL
+*******************************************************************************/
+static int GetPsoc6Info(struct flash_bank *bank, char *buf, int buf_size)
+{
+ int hr;
+ struct psoc6FlashBank *psoc6Info = bank->driver_priv;
+ int printed = 0;
+ if (psoc6Info->probed == 0) {
+ hr = ERROR_FAIL;
+ } else {
+ const struct Psoc6ChipDetails *details =
psoc6_details_by_id(psoc6Info->siliconId);
+ if (details) {
+ uint32_t chip_revision = psoc6Info->siliconId &
0xffffffff;
+ printed = snprintf(buf, buf_size, "PSoC 6 %s rev 0x%04"
PRIx32 " ", details->type, chip_revision);
+ } else {
+ printed = snprintf(buf, buf_size, "PSoC 6 silicon id
0x%x", psoc6Info->siliconId);
+ }
+
+ buf += printed;
+ buf_size -= printed;
+
+ const char *prot_txt =
psoc6_decode_chipProtection(psoc6Info->chipProtection);
+ uint32_t size_in_kb = bank->size / 1024;
+ snprintf(buf, buf_size, " flash %" PRIu32 " kb %s", size_in_kb,
prot_txt);
+
+ hr = ERROR_OK;
+ }
+ return hr;
+}
+
+COMMAND_HANDLER(psoc6_handle_mass_erase_command)
+{
+ LOG_INFO("psoc6_handle_mass_erase_command function");
+ int hr;
+ if (CMD_ARGC < 1)
+ hr = ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (hr == ERROR_OK) {
+ struct flash_bank *bank;
+ hr = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (hr == ERROR_OK) {
+ hr = psoc6_mass_erase(bank);
+ if (hr == ERROR_OK)
+ command_print(CMD_CTX, "psoc mass erase
complete");
+ else
+ command_print(CMD_CTX, "psoc mass erase
failed");
+ }
+ }
+ return hr;
+}
+
+static const struct command_registration psoc6_exec_command_handlers[] = {
+ {
+ .name = "mass_erase",
+ .handler = psoc6_handle_mass_erase_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id",
+ .help = "Erase entire flash device.",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration psoc6_command_handlers[] = {
+ {
+ .name = "psoc6",
+ .mode = COMMAND_ANY,
+ .help = "PSoC 6 flash command group",
+ .usage = "",
+ .chain = psoc6_exec_command_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+struct flash_driver psoc6_flash = {
+ .name = "psoc6",
+ .commands = psoc6_command_handlers,
+ .flash_bank_command = psoc6_flash_bank_command,
+ .erase = Psoc6Erase,
+ .protect = Psoc6Protect,
+ .write = Psoc6Write,
+ .read = default_flash_read,
+ .probe = Psoc6Probe,
+ .auto_probe = Psoc6AutoProbe,
+ .erase_check = default_flash_blank_check,
+ .protect_check = Psoc6ProtectCheck,
+ .info = GetPsoc6Info,
+};
diff --git a/tcl/target/psoc6.cfg b/tcl/target/psoc6.cfg
new file mode 100755
index 0000000..c61f1ea
--- /dev/null
+++ b/tcl/target/psoc6.cfg
@@ -0,0 +1,149 @@
+source [find target/swj-dp.tcl]
+
+global CORE_ID
+if { [info exists CORE] } {
+ set CORE_ID $CORE
+} else {
+ set CORE_ID M0
+}
+
+echo [format "CORE in %s" $CORE_ID]
+
+global _CHIPNAME
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME psoc6
+}
+
+# Work-area is a space in RAM used for flash programming
+# By default use 16kB
+global _WORKAREASIZE
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x4000
+}
+
+global _TAPID
+if { [info exists M0_TAPID] } {
+ set _TAPID $M0_TAPID
+} else {
+ set _TAPID 0x6BA02477
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id
$_TAPID
+
+global TARGET
+set TARGET $_CHIPNAME.cpu
+
+if { 0 == [string compare $CORE_ID M4] } {
+target create $TARGET cortex_m -chain-position $TARGET -ap-num 2
+echo [format "CORE_ID in %s" $CORE_ID]
+} else {
+target create $TARGET cortex_m -chain-position $TARGET -ap-num 1
+echo [format "CORE_ID in %s" $CORE_ID]
+}
+
+$TARGET configure -work-area-phys 0x08002000 -work-area-size $_WORKAREASIZE
-work-area-backup 0
+
+$TARGET configure -event gdb-attach {
+echo [format "GDB_ATTACH_BEFORE_CPU in %s" [$TARGET curstate]]
+reset init
+echo [format "GDB_ATTACH_AFTER_CPU in %s" [$TARGET curstate]]
+
+echo [format "APSEL in %s" $TARGET dap apsel]
+
+}
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME psoc6 0x10000000 0 0 0 $TARGET
+
+if {![using_hla]} {
+ cortex_m reset_config sysresetreq
+}
+
+proc mread32 {addr} {
+ set value(0) 0
+ mem2array value 32 $addr 1
+ return $value(0)
+}
+
+proc ocd_process_reset_inner { MODE } {
+ if { 0 != [string compare psoc6.cpu [target names]] } {
+ return -code error "PSoC 6 reset can handle only one psoc6.cpu
target";
+ }
+ set target psoc6.cpu
+
+ echo [format "APSEL - 1 in %s" [$target dap apsel]]
+
+ # If this target must be halted...
+ set halt -1
+ if { 0 == [string compare $MODE halt] } {
+ set halt 1
+ }
+ if { 0 == [string compare $MODE init] } {
+ set halt 1;
+ }
+ if { 0 == [string compare $MODE run ] } {
+ set halt 0;
+ }
+ if { $halt < 0 } {
+ return -code error "Invalid mode: $MODE, must be one of: halt,
init, or run";
+ }
+
+ $target invoke-event reset-assert-pre
+ $target arp_reset assert 0
+ $target invoke-event reset-assert-post
+ $target invoke-event reset-deassert-pre
+ if {![using_hla]} { # workaround ST-Link v2 fails and forcing
reconnect
+ $target arp_reset deassert 0
+ }
+ $target invoke-event reset-deassert-post
+
+ #Pass 2 - if needed "init"
+ if { 0 == [string compare init $MODE] } {
+ set err [catch "$target arp_waitstate halted 5000"]
+ #Did it halt?
+ if { $err == 0 } {
+ $target invoke-event reset-init
+ }
+
+ }
+ $target invoke-event reset-end
+
+ # Pass 1 - Now wait for any halt (requested as part of reset
+ # assert/deassert) to happen. Ideally it takes effect without
+ # first executing any instructions.
+ if { $halt == 1 } {
+
+ echo "Verify the debug enable, cpu halt bits are set"
+ set halted [mread32 0xE000EDF0]
+ echo [format "OCD_PROCESS_RESET_INNER FORMAT HALTED IN 0x%x" $halted]
+ if { 0x00000003 != [expr ($halted & 0x00000003)] } {
+ return
+ }
+
+ echo "Load infinite for loop code in SRAM address"
+ mww 0x08001010 0xE7FEE7FE
+
+ echo "Load PC with address of infinite for loop SRAM address"
+ reg pc 0x08001011
+
+ echo "Load LR with address of infinite for loop SRAM address"
+ reg lr 0x08001010
+
+ echo "Load SP with top of SRAM address"
+ reg sp 0x0801C000
+
+ echo "Read xPSR register, set the thumb bit, and restore modified
value to xPSR register"
+ set xPSR [ocd_reg xPSR]
+ regsub {xPSR[^:]*: } $xPSR "" xPSR
+ set xPSR [expr ($xPSR | 0x01000000)]
+ echo [format "FORMAT xPSR in 0x%x" $xPSR]
+ reg xPSR $xPSR
+
+ resume
+ }
+ echo [format "APSEL - 2 in %s" [$target dap apsel]]
+}
--
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel