|
|
@@ -1,1051 +0,0 @@
|
|
|
-/*********************************************************************
|
|
|
-* (c) 1995 - 2018 SEGGER Microcontroller GmbH *
|
|
|
-* The Embedded Experts *
|
|
|
-* www.segger.com *
|
|
|
-**********************************************************************
|
|
|
-
|
|
|
--------------------------- END-OF-HEADER -----------------------------
|
|
|
-
|
|
|
-File : CY8C6xxA_CM0p_tm.JLinkScript
|
|
|
-Purpose : J-Link script file for Cypress PSoC6A-2M/512K devices (CY8C6xxA and CY8C6xx5)
|
|
|
-Literature:
|
|
|
- [1] J-Link User Guide
|
|
|
- [2] PSoC® 6 MCU Programming Specifications (Document Number: 002-15554 http://www.cypress.com/file/385671/download)
|
|
|
-
|
|
|
-Additional information:
|
|
|
- For more information about public functions that can be implemented in order to customize J-Link actions, please refer to [1]
|
|
|
-*/
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Constants (similar to defines)
|
|
|
-*********************************************************************/
|
|
|
-
|
|
|
-/* --- Flags --- */
|
|
|
-__constant U8 _DO_ACQUIRE_TEST_MODE = 1; // Perform or skip Test Mode acquisition sequence
|
|
|
-__constant U8 _DO_ACQUIRE_ALTERNATE = 1; // Perform or skip Alternate acquisition sequence
|
|
|
-
|
|
|
-/* --- Misc. --- */
|
|
|
-__constant int _STATUS_OK = 0; // Function return status: O.K.
|
|
|
-__constant int _STATUS_ERR = -1; // Function return status: Error
|
|
|
-__constant U32 _TIMEOUT_HANDSHAKE = 3000;
|
|
|
-__constant U32 _TIMEOUT_HALT_CPU = 300;
|
|
|
-__constant U32 _TIMEOUT_SLEEP_LISTEN_WINDOW = 200;
|
|
|
-__constant U32 _TEST_MODE_SWD_SPEED = 4000;
|
|
|
-
|
|
|
-/* PSoC® 6 MCU definitions */
|
|
|
-__constant U32 _AP_SYS = 0; // AP[0] SYS-AP (used for chip acquisition sequence)
|
|
|
-__constant U32 _AP_CM0 = 1; // AP[1] CM0-AP (used for J-Link communication with Cortex-M0 core)
|
|
|
-__constant U32 _AP_CM4 = 2; // AP[2] CM4-AP (used for J-Link communication with Cortex-M4 core)
|
|
|
-__constant U32 _AP_MYCORE = 1; // AP[1] CM0+ Core is used as the default for this script
|
|
|
-__constant U32 _DP_IDCODE_MSK = 0xFFF00FFF; // AP[2] CM4-AP (used for J-Link communication with Cortex-M4 core)
|
|
|
-__constant U32 _DP_IDCODE_VAL = 0x6BA00477; // AP[2] 0x6BA02477 for SWD or 0x6BA00477 for JTAG
|
|
|
-__constant U32 _CPUSS_CM0_VTBASE_ADDR = 0x40201120; // Vector table base address for CM0+ core (CPUSS_CM0_VECTOR_TABLE_BASE reg.)
|
|
|
-__constant U32 _CPUSS_CMX_VTBASE_ERR_MSK = 0xFFFF0000; // Set by boot code if flash is empty or secure application
|
|
|
-__constant U32 _SRSS_TST_MODE_ADDR = 0x40260100; // SRSS_TST_MODE: Test Mode Control Register
|
|
|
-__constant U32 _SRSS_TST_MODE_TEST_MODE = (1 << 31); // SRSS_TST_MODE.TEST_MODE (bit[31], 0x80000000): 1 - Indicates the chip is in test mode. 0 - Normal operation mode
|
|
|
-__constant U32 _MEM_BASE_ROM = 0x00000000; // Base address of System ROM
|
|
|
-__constant U32 _MEM_SIZE_ROM = 0x00020000; // Size of System ROM
|
|
|
-__constant U32 _MEM_BASE_SFLASH = 0x16000000; // Base address of supervisory flash
|
|
|
-__constant U32 _MEM_SIZE_SFLASH = 0x00008000; // Size of supervisory flash
|
|
|
-__constant U32 _SRAM_ERROR_ADDR = 0x080002FC; // Address in SRAM for error code
|
|
|
-__constant U32 _SRAM_LOOP_ADDR = 0x08000300; // Address in SRAM for infinite loop
|
|
|
-__constant U32 _SRAM_TOP_ADDR = 0x0800FFF0; // Top of SRAM address for SP set by acquisition sequence. Use minimum SRAM size devices (65 KB)
|
|
|
-
|
|
|
-/* --- AP/DP registers --- */
|
|
|
-__constant U32 _ACC_DP = 0; // APnDP for DP access
|
|
|
-__constant U32 _ACC_AP = 1; // APnDP for AP access
|
|
|
-__constant U32 _AP_ABORT_ORUNERRCLR = (1 << 4); // AP->ABORT.ORUNERRCLR (bit[4], 0x00000010): Clears CTRL/STAT.STICKYORUN
|
|
|
-__constant U32 _AP_ABORT_WDERRCLR = (1 << 3); // AP->ABORT.WDERRCLR (bit[3], 0x00000008): Clears CTRL/STAT.WDATAERR
|
|
|
-__constant U32 _AP_ABORT_STKERRCLR = (1 << 2); // AP->ABORT.STKERRCLR (bit[2], 0x00000004): Clears CTRL/STAT.STICKYERR
|
|
|
-__constant U32 _AP_ABORT_STKCMPCLR = (1 << 1); // AP->ABORT.STKCMPCLR (bit[1], 0x00000002): Clears CTRL/STAT.STICKYERR
|
|
|
- // ( |= 0x0000001E)
|
|
|
-__constant U32 _AP_SELECT_APSEL_RSH = 24; // AP->SELECT.APSEL (bits[31:24], 0xFF000000): Selects an AP
|
|
|
-__constant U32 _DP_CTRL_STAT_CSYSPWRUPREQ = (1 << 30); // DP->CTRL/STAT.CSYSPWRUPREQ (bit[30], 0x40000000): System powerup request
|
|
|
-__constant U32 _DP_CTRL_STAT_CDBGPRWUPREQ = (1 << 28); // DP->CTRL/STAT.CDBGPRWUPREQ (bit[28], 0x10000000): Debug powerup request
|
|
|
-__constant U32 _DP_CTRL_STAT_CDBGRSTREQ = (1 << 26); // DP->CTRL/STAT.CDBGRSTREQ (bit[26], 0x04000000): Debug reset request
|
|
|
-__constant U32 _DP_CTRL_STAT_STICKYERR = (1 << 5); // DP->CTRL/STAT.STICKYERR ( bit[5], 0x00000020): Error in AP transaction
|
|
|
-__constant U32 _DP_CTRL_STAT_STICKYCMP = (1 << 4); // DP->CTRL/STAT.STICKYCMP ( bit[4], 0x00000010): Match on a pushed operations
|
|
|
-__constant U32 _DP_CTRL_STAT_STICKYORUN = (1 << 1); // DP->CTRL/STAT.STICKYORUN ( bit[1], 0x00000002): Overrun detection
|
|
|
- // |= 0x50000032
|
|
|
-__constant U32 _DP_CSW_PROT_VAL = (0x23 << 24); // DP->CSW.Prot (bits[30:24], 0x23000000): Bus access protection control
|
|
|
- // Set to 0x23, otherwise no access to CPU registers via M4 AP
|
|
|
-__constant U32 _DP_CSW_SIZE_WORD = (2 << 0); // DP->CSW.Size ( bits[2:0], 0x00000002): Size of access <- Word (32-bits)
|
|
|
- // |= 0x23000002
|
|
|
-/* --- ARMv6-M & ARMv7-M --- */
|
|
|
-__constant U32 _LOOP_CODE = 0xE7FEE7FE; // Endless loop
|
|
|
-__constant U32 _BP_CTRL_ADDR = 0xE0002000; // BP_CTRL: Breakpoint Control register in ARMv6-M. In ARMv7-M, it is FP_CTRL: FlashPatch Control Register.
|
|
|
-__constant U32 _BP_CTRL_KEY = (1 << 1); // BP_CTRL.KEY (bit[1], 0x00000002): Enables write to the register
|
|
|
-__constant U32 _BP_CTRL_ENABLE = (1 << 0); // BP_CTRL.ENABLE (bit[0], 0x00000001): Enables the BPU
|
|
|
-__constant U32 _BP_COMP0_ADDR = 0xE0002008; // BP_COMP0: Breakpoint Comparator registers
|
|
|
-__constant U32 _BP_COMP_BPMATCH = (3 << 30); // BP_COMP.BP_MATCH (bits[31:30], 0xC0000000): Defines the behavior when the COMP address is matched
|
|
|
-__constant U32 _BP_COMP_COMP_MSK = 0x1FFFFFFC; // BP_COMP.COMP ( bits[28:2], 0x07FFFFFF): Stores bits [28:2] of the comparison address
|
|
|
-__constant U32 _BP_COMP_ENABLE = (1 << 0); // BP_COMP.ENABLE ( bit[0], 0x00000001): Enables the comparator
|
|
|
-__constant U32 _AIRCR_ADDR = 0xE000ED0C; // AIRCR: Application Interrupt and Reset Control Register
|
|
|
-__constant U32 _AIRCR_VECTKEY_VAL = (0x05FA << 16); // AIRCR.VECTKEY (bits[31:16], 0x05FA0000): Vector Key. The value 0x05FA must be written to this register
|
|
|
-__constant U32 _AIRCR_SYSRESETREQ = (1 << 2); // AIRCR.SYSRESETREQ ( bit[2], 0x00000004): System Reset Request
|
|
|
-__constant U32 _DHCSR_ADDR = 0xE000EDF0; // DHCSR: Debug Halting Control and Status Register
|
|
|
-__constant U32 _DHCSR_DBGKEY_VAL = (0xA05F << 16); // DHCSR.DBGKEY (bits[31:16], 0xA05F0000): Must write 0xA05F to DBGKEY to enable write accesses to bits[15:0]
|
|
|
-__constant U32 _DHCSR_S_SLEEP = (1 << 18); // DHCSR.S_SLEEP ( bit[18], 0x00040000): Indicates whether the processor is sleeping
|
|
|
-__constant U32 _DHCSR_S_HALT = (1 << 17); // DHCSR.S_HALT ( bit[17], 0x00020000): Indicates whether the processor is in Debug state
|
|
|
-__constant U32 _DHCSR_C_HALT = (1 << 1); // DHCSR.C_HALT ( bit[1], 0x00000002): Processor halt bit
|
|
|
-__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); // DHCSR.C_DEBUGEN ( bit[0], 0x00000001): Halting debug enable bit
|
|
|
- // (DBGKEY|C_HALT|C_DEBUGEN = 0xA05F0003)
|
|
|
-__constant U32 _DCRSR_ADDR = 0xE000EDF4; // DCRSR: Debug Core Register Selector Register
|
|
|
-__constant U32 _DCRSR_REGWnR = (1 << 16); // DCRSR.REGWnR ( bit[16], 0x00010000): Specifies the access type for the transfer ('0' - Read, '1' - Write)
|
|
|
-__constant U32 _DCRSR_REGSEL_MSK = 0x0000007F; // DCRSR.REGSEL (bits[6:0], 0x0000007F): Specifies the ARM core register, special-purpose register, or Floating-point extension register
|
|
|
-__constant U32 _xPSR_T = (1 << 24); // xPSR.T (bit[24], 0x01000000): Thumb bit
|
|
|
-__constant U32 _REGSEL_xPSR = 0x10; // xPSR
|
|
|
-__constant U32 _REGSEL_MSP = 0x11; // Main stack pointer, MSP
|
|
|
-__constant U32 _REGSEL_PC = 0x0F; // PC / DebugReturnAddress
|
|
|
-__constant U32 _DCRDR_ADDR = 0xE000EDF8; // DCRDR: Debug Core Register Data Register
|
|
|
-__constant U32 _DEMCR_ADDR = 0xE000EDFC; // DEMCR: Debug Exception and Monitor Control Register
|
|
|
-__constant U32 _DEMCR_TRCENA = (1 << 24); // DEMCR.TRCENA (bit[24], 0x01000000): Global enable for all DWT and ITM features
|
|
|
-
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Static data
|
|
|
-*********************************************************************/
|
|
|
-
|
|
|
-// Standard ARM command to switch SWJ-DP from JTAG to SWD operations:
|
|
|
-const U8 _aData_JTAGtoSWD[] = {
|
|
|
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Send at least 50 SWCLKTCK cycles with SWDIOTMS HIGH. This ensures that the current interface is in its reset state.
|
|
|
- // The JTAG interface detects only the 16-bit JTAG-to-SWD sequence starting from the test-logic-reset state.
|
|
|
- 0x9E, 0xE7, // Send the 16-bit JTAG-to-SWD select sequence on SWDIOTMS: 0b0111 1001 1110 0111, most significant bit (MSb) first.
|
|
|
- // This can be represented as 0x79E7, transmitted MSB first or 0xE79E, transmitted least significant bit (LSb) first.
|
|
|
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Send at least 50 SWCLKTCK cycles with SWDIOTMS HIGH. This ensures that if SWJ-DP was already in SWD operation
|
|
|
- // before sending the select sequence, the SWD interface enters line reset state.
|
|
|
- 0x00, 0x00 // Make sure SWD is ready for a start bit (min. 2 clocks with SWDIO == LOW)
|
|
|
-};
|
|
|
-
|
|
|
-// Standard ARM command to switch SWJ-DP from SWD to JTAG operations
|
|
|
-const U8 _aData_SWDtoJTAG[] = {
|
|
|
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Send at least 50 SWCLKTCK cycles with SWDIOTMS HIGH. This ensures that the current interface is in its reset state.
|
|
|
- // The SWD interface detects the 16-bit SWD-to-JTAG sequence only when it is in reset state.
|
|
|
- 0x3C, 0xE7, // Send the 16-bit SWD-to-JTAG select sequence on SWDIOTMS: 0b0011 1100 1110 0111, MSb first.
|
|
|
- // This can be represented as 0x3CE7, transmitted MSb first or 0xE73C, transmitted LSb first.
|
|
|
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Send at least five SWCLKTCK cycles with SWDIOTMS HIGH. This ensures that if SWJ-DP was already in JTAG
|
|
|
- // operation before sending the select sequence, the JTAG TAP enters the test-logic-reset state.
|
|
|
- 0x00, 0x00 // Make sure SWD is ready for a start bit (min. 2 clocks with SWDIO == LOW)
|
|
|
-};
|
|
|
-
|
|
|
-// Direction buffer
|
|
|
-const U8 _aDir_SWJDPSwitch[] = {
|
|
|
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
- 0xFF, 0xFF,
|
|
|
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
- 0xFF, 0xFF
|
|
|
-};
|
|
|
-
|
|
|
-// Buffer for receiving data from target. Needs to be big enough to hold data for above sequences
|
|
|
-U8 _aDataOut[18];
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Local functions
|
|
|
-*********************************************************************/
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Checks function result
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* true O.K.
|
|
|
-* false Error
|
|
|
-*/
|
|
|
-int _CheckStatus(int status) {
|
|
|
- if (status >= _STATUS_OK) {
|
|
|
- return _STATUS_OK;
|
|
|
- } else {
|
|
|
- // Push error code to SWD that is it easier to debug the issues
|
|
|
- JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACC_AP, _SRAM_ERROR_ADDR);
|
|
|
- JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACC_AP, 0xDEADBEEF);
|
|
|
- return _STATUS_ERR;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Writes U32 value to provided memory address.
|
|
|
-* Used instead of JLINK_MEM_ReadU32 to validate transaction status
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _ReadMem(U32 address, U32* value) {
|
|
|
- int status;
|
|
|
-
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACC_AP, address); // AP.TAR <- address
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- status = JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACC_AP, value); // AP.DRW -> value
|
|
|
- }
|
|
|
-
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Writes U32 value to provided memory address.
|
|
|
-* Used instead of JLINK_MEM_WriteU32 to validate transaction status
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _WriteMem(U32 address, U32 value) {
|
|
|
- int status;
|
|
|
-
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACC_AP, address); // AP.TAR <- address
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACC_AP, value); // AP.DRW <- value
|
|
|
- }
|
|
|
-
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Polls for the expected bit-field value in given register
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error/Timeout
|
|
|
-*/
|
|
|
-int _PollMem(U32 regAddr, U32 fieldMsk, U32 rsh, U32 expectedValue, U32 timeout, U32 sleepBetweenPolling) {
|
|
|
- int status;
|
|
|
- int t;
|
|
|
- int tDelta;
|
|
|
- U32 v;
|
|
|
- tDelta = -1;
|
|
|
-
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACC_AP, regAddr); // AP.ADDR <- regAddr
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- status = _STATUS_ERR;
|
|
|
- t = JLINK_GetTime();
|
|
|
- do {
|
|
|
- // Sleep some time between polling: let CPU do its job and avoid too much garbage on SWD
|
|
|
- if ((sleepBetweenPolling > 0) && (tDelta >= 0 /* not first iteration*/)) {
|
|
|
- JLINK_SYS_Sleep(sleepBetweenPolling);
|
|
|
- }
|
|
|
- v = 0;
|
|
|
- status = JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACC_AP, &v);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- break;
|
|
|
- }
|
|
|
- if (((v & fieldMsk) >> rsh) == expectedValue) {
|
|
|
- status = _STATUS_OK;
|
|
|
- break;
|
|
|
- }
|
|
|
- tDelta = JLINK_GetTime() - t;
|
|
|
- } while (tDelta < timeout);
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Reads ARM core register, special-purpose register, or Floating-point extension register
|
|
|
-* CPU must be halted for this operation
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _ReadCoreReg(U32 regsel, U32* value) {
|
|
|
- int status;
|
|
|
-
|
|
|
- status = _WriteMem(_DCRSR_ADDR, (regsel & _DCRSR_REGSEL_MSK)); // DCRSR (0xE000EDF4) <- REGWnR == read) | REGSEL
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- status = _ReadMem(_DCRDR_ADDR, value); // DCRDR (0xE000EDF8) -> value
|
|
|
- }
|
|
|
-
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Writes ARM core register, special-purpose register, or Floating-point extension register
|
|
|
-* CPU must be halted for this operation
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _WriteCoreReg(U32 regsel, U32 value) {
|
|
|
- int status;
|
|
|
-
|
|
|
- status = _WriteMem(_DCRDR_ADDR, value); // DCRDR (0xE000EDF8) <- value
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- status = _WriteMem(_DCRSR_ADDR, (_DCRSR_REGWnR | (regsel & _DCRSR_REGSEL_MSK))); // DCRSR (0xE000EDF4) <- (REGWnR == write) | REGSEL
|
|
|
- }
|
|
|
-
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Handshake: wait for debug interface becomes enabled after device reset (tboot).
|
|
|
-* In worst case, when the boot code performs application HASH verification,
|
|
|
-* tboot is around 600ms and depends on CPU clock used by boot code.
|
|
|
-* For PowerCycle, timeout depends on the design schematic and must be longer.
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) Must not use any high-level functions as it is also called from InitTarget() and uses non-standard APs etc.
|
|
|
-*/
|
|
|
-int _Handshake(void) {
|
|
|
- U32 v;
|
|
|
- int t;
|
|
|
- int tDelta;
|
|
|
- int status;
|
|
|
-
|
|
|
- status = _STATUS_ERR;
|
|
|
- t = JLINK_GetTime();
|
|
|
- do {
|
|
|
- if (JLINK_ActiveTIF == JLINK_TIF_JTAG) {
|
|
|
- JLINK_SWD_ReadWriteBits(&_aData_SWDtoJTAG[0], &_aDir_SWJDPSwitch[0], &_aDataOut[0], 18 * 8);
|
|
|
- } else { // JLINK_ActiveTIF == JLINK_TIF_SWD
|
|
|
- JLINK_SWD_ReadWriteBits(&_aData_JTAGtoSWD[0], &_aDir_SWJDPSwitch[0], &_aDataOut[0], 18 * 8);
|
|
|
- }
|
|
|
- v = 0;
|
|
|
- JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_DP_REG_IDCODE, _ACC_DP, &v);
|
|
|
- if ((v & _DP_IDCODE_MSK) == _DP_IDCODE_VAL) { // DAP is responsive if we can read IDCODE (0x6BA02477 for SWD or 0x6BA00477 for JTAG)
|
|
|
- status = _STATUS_OK;
|
|
|
- break;
|
|
|
- }
|
|
|
- tDelta = JLINK_GetTime() - t;
|
|
|
- } while (tDelta < _TIMEOUT_HANDSHAKE); // Timeout reached?
|
|
|
-
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Clears any sticky errors which could be left from previous sessions.
|
|
|
-* Otherwise only power-down-up cycle helps to restore DAP.
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) Must not use any high-level functions as it is also called from InitTarget() and uses non-standard APs etc.
|
|
|
-*/
|
|
|
-int _ClearStickyErrors() {
|
|
|
- int status;
|
|
|
- U32 abort_reg;
|
|
|
- U32 abort_val;
|
|
|
-
|
|
|
- if (JLINK_ActiveTIF == JLINK_TIF_JTAG) {
|
|
|
- // Power up DAP and clear sticky errors using DP.CTRL/STAT: [30]:CSYSPWRUPREQ, [28]:CDBGPWRUPREQ, [5]:STICKYERR, [4]:STICKYCMP, [1]:STICKYORUN
|
|
|
- // Note: for JTAG, sticky error bits are read-write enabled and writing ‘1’ to these bits clears associated sticky errors.
|
|
|
- // For SWD, these bits are read-only and to clean the sticky errors, you should write to appropriate bits of DP.ABORT register
|
|
|
- abort_reg = JLINK_CORESIGHT_DP_REG_CTRL_STAT;
|
|
|
- abort_val = _DP_CTRL_STAT_CSYSPWRUPREQ | _DP_CTRL_STAT_CDBGPRWUPREQ | _DP_CTRL_STAT_STICKYERR | _DP_CTRL_STAT_STICKYCMP | _DP_CTRL_STAT_STICKYORUN; // 0x50000032
|
|
|
- } else { // JLINK_ActiveTIF == JLINK_TIF_SWD
|
|
|
- abort_reg = JLINK_CORESIGHT_DP_REG_ABORT;
|
|
|
- abort_val = _AP_ABORT_ORUNERRCLR | _AP_ABORT_WDERRCLR | _AP_ABORT_STKERRCLR | _AP_ABORT_STKCMPCLR; // 0x0000001E
|
|
|
- }
|
|
|
-
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(abort_reg, _ACC_DP, abort_val);
|
|
|
-
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Initialize the Debug Port for programing operations.
|
|
|
-* Accepts Access Port number as input: 0 – System AP; 1 – CM0+ AP; 2 – CM4 AP.
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) Must not use any high-level functions as it is also called from InitTarget() and uses non-standard APs etc.
|
|
|
-*/
|
|
|
-int _InitDAP(U8 apNum, U8 doPowerUp) {
|
|
|
- int status;
|
|
|
-
|
|
|
- status = _ClearStickyErrors();
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- if (doPowerUp != 0) {
|
|
|
- // Power up DAP using DP.CTRL/STAT: [30]:CSYSPWRUPREQ, [28]:CDBGPWRUPREQ
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_CTRL_STAT, _ACC_DP, _DP_CTRL_STAT_CSYSPWRUPREQ | _DP_CTRL_STAT_CDBGPRWUPREQ); // 0x50000000
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Select desired Access Port and set bank 0 in APACC space
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, _ACC_DP, (apNum << _AP_SELECT_APSEL_RSH) ); // DP->SELECT.APSEL <- apNum
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // Set CSW (DbgSwEnable=0, Prot=0x23, SPIDEN=0, Mode=0x0, TrInProg=0, DeviceEn=0, AddrInc=Auto-increment off, Size=Word (32 bits))
|
|
|
- // Note: Set Prot bits in DAP CSW register, because of no access to CPU registers via M4 AP without these bits
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_CTRL, _ACC_AP, _DP_CSW_PROT_VAL | _DP_CSW_SIZE_WORD); // 0x23000002
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Performs hardware reset by toggling XRES pin
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) Must not use any high-level functions as it is also called from InitTarget() and uses non-standard APs etc.
|
|
|
-*/
|
|
|
-int _HardReset(void) {
|
|
|
- JLINK_JTAG_ResetPin = 0; // nRESET == LOW
|
|
|
- JLINK_SYS_Sleep(50); // Make sure that device recognizes the reset
|
|
|
- JLINK_JTAG_ResetPin = 1; // nRESET == HIGH
|
|
|
- return _STATUS_OK;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Performs software reset using SYSRESETREQ bit in the AIRCR (Application Interrupt and Reset Control Register)
|
|
|
-* DAP communication must be established before this method call (e.g. use _Handshake + _InitDAP function)
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _SoftReset() {
|
|
|
- int status;
|
|
|
-
|
|
|
- status = JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACC_AP, _AIRCR_ADDR); // AP.TAR <- @AIRCR (0xE000ED0C)
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Note: do not check OK/WAIT/FAULT ACKs for the data write phase since the target immediately reboots
|
|
|
- JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_AP_REG_DATA, (_AIRCR_VECTKEY_VAL | _AIRCR_SYSRESETREQ) ); // AP.DRW <- 0x05FA0004
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Performs either of:
|
|
|
-* a. Hardware reset (XRES)
|
|
|
-* b. Software reset (AIRCR.SYSRESETREQ)
|
|
|
-* c. Software reset (DP->CTRL/STAT.CDBGRSTREQ)
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _PSoC6_Reset(U8 doXRES) {
|
|
|
- int status;
|
|
|
-
|
|
|
- if (doXRES != 0) {
|
|
|
- status = _HardReset();
|
|
|
- } else {
|
|
|
- // Handshake: wait for debug interface becomes enabled after device reset
|
|
|
- status = _Handshake();
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- // Initialize the Debug Port and select CM0+ Access Port (AP[1])
|
|
|
- status = _InitDAP(_AP_MYCORE, 1 /* "1" - do power up request */);
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- status = _SoftReset(); // AIRCR.SYSRESETREQ
|
|
|
- }
|
|
|
-
|
|
|
- // In worst case, if standard software reset via SYSRESETREQ failed, it may mean that the firmware did
|
|
|
- // very bad things disabling the debug pins or AHB_AP access (anything behind the DAP).
|
|
|
- // However, if we still can access DAP registers, the last thing we could try is to reset the target
|
|
|
- // via DP->CTRL/STAT.CDBGRSTREQ. In MXS40, setting the CDBGRSTREQ bit will result in a System wide Debug
|
|
|
- // DeepSleep reset, what resets both (CM0+ and CM4) cores.
|
|
|
- // Note that CDBGRSTREQ will reset the target only at first attempt after the hardware reset (XRES or Power Cycle).
|
|
|
- // You need to do the additional hardware reset manually before the acquisition sequence execution if the target
|
|
|
- // stucked in 'bad' state and you already used the CDBGRSTREQ bit since the previous hardware reset.
|
|
|
- // If such case happens and we managed to reset the target using CDBGRSTREQ,
|
|
|
- // the next thing would be to halt the CPU as quickly as possible to prevent firmware to do the bad things again.
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- status = _Handshake();
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_CTRL_STAT, _DP_CTRL_STAT_CSYSPWRUPREQ | _DP_CTRL_STAT_CDBGPRWUPREQ | _DP_CTRL_STAT_CDBGRSTREQ); // 0x54000000
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Enables debug and halts or resumes the CPU using the DHCSR register
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _HaltResumeCPU(U8 haltNresume) {
|
|
|
- int status;
|
|
|
- U32 v;
|
|
|
- int t;
|
|
|
- int tDelta;
|
|
|
- U32 dhcsrVal;
|
|
|
- U32 shaltExpectedVal;
|
|
|
-
|
|
|
- if (haltNresume == 0) { // Resume
|
|
|
- dhcsrVal = _DHCSR_DBGKEY_VAL | _DHCSR_C_DEBUGEN; // 0xA05F0001
|
|
|
- shaltExpectedVal = 0;
|
|
|
- } else { // Halt
|
|
|
- dhcsrVal = _DHCSR_DBGKEY_VAL | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN; // 0xA05F0003
|
|
|
- shaltExpectedVal = _DHCSR_S_HALT;
|
|
|
- }
|
|
|
-
|
|
|
- // Enable debug, and halt the CPU using the DHCSR register
|
|
|
- status = _WriteMem(_DHCSR_ADDR, dhcsrVal); // _DHCSR_ADDR (0xE000EDF0) <- dhcsrVal
|
|
|
-
|
|
|
- if (_CheckStatus(status) == _STATUS_OK) {
|
|
|
- // Poll for S_HALT bit [17] in DHCSR register (@0xE000EDF0)
|
|
|
- status = _PollMem(_DHCSR_ADDR, _DHCSR_S_HALT, 0, shaltExpectedVal, _TIMEOUT_HALT_CPU, 0);
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Gets Reset Address and Initial SP values from application Vector Table
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _PSoC6_GetVectorTableData(U32* resetAddress, U32* sp) {
|
|
|
- int status;
|
|
|
- U32 v;
|
|
|
- U32 vtBase;
|
|
|
-
|
|
|
- *resetAddress = 0;
|
|
|
- *sp = 0;
|
|
|
-
|
|
|
- // Check CPUSS_CM0_VECTOR_TABLE_BASE. Zero or error code there means that the Flash is empty or TOC is corrupted.
|
|
|
- // In this case boot code jumps to infinite loop in ROM or executes ‘dummy’ application.
|
|
|
- // This case is sufficient condition for programming, but has no sense for debugging.
|
|
|
- // Otherwise, application exist, so need to set correct PC/SP for debugging
|
|
|
-
|
|
|
- status = _ReadMem(_CPUSS_CM0_VTBASE_ADDR, &vtBase);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- vtBase &= _CPUSS_CMX_VTBASE_ERR_MSK;
|
|
|
-
|
|
|
- if ((vtBase != 0) && (vtBase != _CPUSS_CMX_VTBASE_ERR_MSK)) {
|
|
|
-
|
|
|
- // Get Initial SP value from Vector Table
|
|
|
- status = _ReadMem(vtBase, &v);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- *sp = v;
|
|
|
-
|
|
|
- // Get Reset Address from Vector Table
|
|
|
- status = _ReadMem(vtBase + 4, &v);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- *resetAddress = v;
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Sets PC and SP getting the values from Vector Table
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*/
|
|
|
-int _PSoC6_SetPCandSPFromVectorTable(void) {
|
|
|
- int status;
|
|
|
- U32 v;
|
|
|
- U32 pc;
|
|
|
- U32 sp;
|
|
|
-
|
|
|
- // Get PC and SP for the application in flash
|
|
|
- status = _PSoC6_GetVectorTableData(&pc, &sp);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- if ((pc > 0) && (sp > 0)) {
|
|
|
-
|
|
|
- // Set PC
|
|
|
- status = _WriteCoreReg(_REGSEL_PC, pc);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // Set MSP
|
|
|
- status = _WriteCoreReg(_REGSEL_MSP, sp);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- //Read xPSR register, set the thumb bit, and restore modified value to xPSR register
|
|
|
- status = _ReadCoreReg(_REGSEL_xPSR, &v);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- status = _WriteCoreReg(_REGSEL_xPSR, (v | _xPSR_T) );
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Performs PSoC 6 chip acquisition in test mode:
|
|
|
-* 1. Do hardware (XRES) or one of the software (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) reset
|
|
|
-* 2. Handshake + Init DAP
|
|
|
-* 3. Set TEST_MODE bit in TST_MODE SRSS register
|
|
|
-* 4. Check CPU is sleeping (executes WFI)
|
|
|
-* 5. Check PC is in ROM or in SFLASH (CPU must be halted to read PC)
|
|
|
-*
|
|
|
-* Refer PSoC 6 MCU Programming Specifications: 002-15554 http://www.cypress.com/file/385671/download
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) Must not use any high-level functions as it is also called from InitTarget() and uses non-standard APs etc.
|
|
|
-*/
|
|
|
-int _PSoC6_AcquireTestMode(U8 doXRES) {
|
|
|
- int status;
|
|
|
- U32 v;
|
|
|
- U32 OrgTIFSpeed;
|
|
|
-
|
|
|
- // Make sure that J-Link is using a high target interface speed, so we can meet the timing requirements as per programming specifications
|
|
|
- // Might be necessary for some IDEs that select a very slow interface speed by default and do not allow to change this
|
|
|
- OrgTIFSpeed = JLINK_JTAG_Speed;
|
|
|
- JLINK_JTAG_Speed = _TEST_MODE_SWD_SPEED;
|
|
|
-
|
|
|
- // Preconfigure some CoreSight settings as time is not critical at this point
|
|
|
- // E.g. by default, when executing DAP API calls from within the firmware, J-Link will do a retry of the DAP transfer for some interfaces, if we got an invalid response from the DAP.
|
|
|
- // As this costs valuable time here, we temporarily disable this behavior and restore it at the end of the call.
|
|
|
- // Additionally, suppress output of the JTAG/SWD switching sequence init at the end of the CORESIGHT_Configure() call, as we do not need it and it only costs time
|
|
|
- JLINK_CORESIGHT_Configure("RetryOnInvalDAPResp=0;PerformTIFInit=0");
|
|
|
-
|
|
|
- // - 1 ----------------------------------------------------------------------
|
|
|
- // Do hardware (XRES) of software (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) pre-reset
|
|
|
- // It is critical for Test Mode acquisition, so stop and in case of failure
|
|
|
- status = _PSoC6_Reset(doXRES);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 2 ----------------------------------------------------------------------
|
|
|
- // Handshake: wait for debug interface becomes enabled after device reset
|
|
|
- status = _Handshake();
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Initialize the Debug Port and select CM0-AP (AP[1])
|
|
|
- status = _InitDAP(_AP_CM0, 1 /* "1" - do power up request */);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 3 ----------------------------------------------------------------------
|
|
|
- // Enter CPU into Test Mode, so it does not start the user application
|
|
|
- JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACC_AP, _SRSS_TST_MODE_ADDR); // Set TEST_MODE bit in TST_MODE SRSS register
|
|
|
- JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACC_AP, _SRSS_TST_MODE_TEST_MODE);
|
|
|
- // Read RDBUFF to make sure that the last AP write actually happens as SW-DP may buffer/delay it until next DAP access
|
|
|
- JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_DP_REG_RDBUF, _ACC_DP, &v);
|
|
|
-
|
|
|
- // The steps above are time critical and must be executed without delays immediately after reset.
|
|
|
- // No hurry for further steps - target already acquired in Test Mode
|
|
|
-
|
|
|
- // Restore CORESIGHT settings (See beginning of this function call for more info) and restore original TIF speed
|
|
|
- JLINK_CORESIGHT_Configure("RetryOnInvalDAPResp=1;PerformTIFInit=0");
|
|
|
- JLINK_JTAG_Speed = OrgTIFSpeed;
|
|
|
-
|
|
|
- // - 4 ----------------------------------------------------------------------
|
|
|
- // Wait for the boot code to finish with Listen window and jump to WFI instruction
|
|
|
- // Polls for S_SLEEP bit [18] in DHCSR register (@0xE000EDF0) what will indicate that the Listen window ended and CPU executes WFI instruction
|
|
|
- status = _PollMem(_DHCSR_ADDR, _DHCSR_S_SLEEP, 0, _DHCSR_S_SLEEP, _TIMEOUT_SLEEP_LISTEN_WINDOW, 1);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 5 ----------------------------------------------------------------------
|
|
|
- // However, the WFI instruction may be executed by user application as well,
|
|
|
- // so additional verification is to check PC is in ROM or in SFLASH.
|
|
|
- // CPU must be halted to read the PC
|
|
|
- status = _HaltResumeCPU(1 /* "1" - halt */);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Read PC and check it points to address in ROM or in SFLASH
|
|
|
- _ReadCoreReg(_REGSEL_PC, &v);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- if (((v >= _MEM_BASE_ROM) && (v < (_MEM_BASE_ROM + _MEM_SIZE_ROM))) || ((v >= _MEM_BASE_SFLASH) && (v < (_MEM_BASE_SFLASH + _MEM_SIZE_SFLASH)))) {
|
|
|
- status = _STATUS_OK;
|
|
|
- } else {
|
|
|
- status = _STATUS_ERR;
|
|
|
- }
|
|
|
-
|
|
|
- // If S_SLEEP is set and PC points to the address in SROM or in SFLASH, it means either of:
|
|
|
- // a. Test Mode acquisition succeeded and we fit timings
|
|
|
- // b. flash is empty or TOC2 is corrupted, so the boot code jumped to WFI or dummy application in ROM/SFLASH
|
|
|
- // Either of this case is sufficient for programming
|
|
|
-
|
|
|
- // Clear TEST_MODE bit in TST_MODE SRSS register
|
|
|
- JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACC_AP, _SRSS_TST_MODE_ADDR);
|
|
|
- JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACC_AP, 0);
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Performs PSoC 6 chip acquisition using alternate sequence:
|
|
|
-* 1. Do hardware (XRES) or one of the software (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) reset
|
|
|
-* 2. Handshake + Init DAP
|
|
|
-* 3. Halt CPU, enable debug
|
|
|
-* 4. Get Reset Address and Initial SP value from the vector table
|
|
|
-* 5. Enable Breakpoint unit and set the breakpoint at Reset Address
|
|
|
-* 6. Issue software reset using the SYSRESETREQ bit in AIRCR register
|
|
|
-* 7. Handshake + Init DAP
|
|
|
-* 8. Verify CPU is halted at breakpoint being set at Reset Address
|
|
|
-* 9. Load infinite loop into SRAM and set PC to this address
|
|
|
-* 10. Load SP with top of SRAM address, set thumb bit in xPSR
|
|
|
-* 11. Disable breakpoint unit and resume the CPU
|
|
|
-*
|
|
|
-* Refer PSoC 6 MCU Programming Specifications: 002-15554 http://www.cypress.com/file/385671/download
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) Must not use any high-level functions as it is also called from InitTarget() and uses non-standard APs etc.
|
|
|
-*/
|
|
|
-int _PSoC6_AcquireAlternate(U8 doXRES) {
|
|
|
- int status;
|
|
|
- U32 v;
|
|
|
- U32 resetAddress;
|
|
|
- U32 sp;
|
|
|
-
|
|
|
- // - 1 ----------------------------------------------------------------------
|
|
|
- // Do hardware (XRES) of software (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) pre-reset.
|
|
|
- // It is good to do even for the alternate method
|
|
|
- status = _PSoC6_Reset(doXRES);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- // Stop and return failure status if initial reset failed because it is critical for Test Mode acquisition
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 2 ----------------------------------------------------------------------
|
|
|
- // Handshake: wait for debug interface becomes enabled after device reset
|
|
|
- status = _Handshake();
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Initialize the Debug Port and select CM0+ Access Port (AP[1])
|
|
|
- status = _InitDAP(_AP_MYCORE, 1 /* "1" - do power up request */);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 3 ----------------------------------------------------------------------
|
|
|
- // Enable debug and halt CPU as quickly as possible right after Reset+Handshake+InitDAP
|
|
|
- // It is not absolutely mandatory to do this quickly, but there is a good chance to stop in Listen window or at least prevent user application from doing too much "bad" stuff
|
|
|
- status = _HaltResumeCPU(1 /* "1" - halt */);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 4 ----------------------------------------------------------------------
|
|
|
- // Get Reset Address and Initial SP values for the current application from the vector table
|
|
|
- status = _PSoC6_GetVectorTableData(&resetAddress, &sp);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Zero or error code means that the Flash is empty or TOC2 is corrupted
|
|
|
- // In this case boot code jumps to infinite loop in ROM or executes ‘dummy’ application, what is sufficient condition for programming.
|
|
|
- // Otherwise, user application exists, so need to do clean-up.
|
|
|
- if ((resetAddress == 0) || sp == 0) {
|
|
|
- // Note that CPU is halted at this point and resume is required for system calls used during programming
|
|
|
- return _STATUS_OK;
|
|
|
- }
|
|
|
-
|
|
|
- // - 5 ----------------------------------------------------------------------
|
|
|
- // Enable Breakpoint unit
|
|
|
- status = _WriteMem(_BP_CTRL_ADDR, _BP_CTRL_KEY | _BP_CTRL_ENABLE); // BP_CTRL (0xE0002000) <- 0x00000003
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Map the address bits to the breakpoint compare register bit-map, set the ENABLE and BPMATCH bits
|
|
|
- v = (resetAddress & _BP_COMP_COMP_MSK) | _BP_COMP_BPMATCH | _BP_COMP_ENABLE; //(resetAddress & 0x1FFFFFFC) | 0xC0000001
|
|
|
- // Update the breakpoint compare register
|
|
|
- status = _WriteMem(_BP_COMP0_ADDR, v);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 6 ----------------------------------------------------------------------
|
|
|
- // Issue software reset using SYSRESETREQ bit in the AIRCR (Application Interrupt and Reset Control Register)
|
|
|
- _SoftReset();
|
|
|
-
|
|
|
- // - 7 ----------------------------------------------------------------------
|
|
|
- // Handshake: wait for debug interface becomes enabled after device reset
|
|
|
- status = _Handshake();
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Initialize the Debug Port and select CM0+ Access Port (AP[1])
|
|
|
- status = _InitDAP(_AP_MYCORE, 1 /* "1" - do power up request */);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 8 ----------------------------------------------------------------------
|
|
|
- // Verify CPU is halted at breakpoint being set at Reset Address
|
|
|
- // S_HALT (bit[17]) and C_DEBUGE (bit[0]) in DHCSR register (@0xE000EDF0) must be set
|
|
|
- // Polling is required in order to wait till boot code finished execution (Listen window closed) and CPU halted at the user application entry
|
|
|
- v = _DHCSR_S_HALT | _DHCSR_C_DEBUGEN;
|
|
|
- status = _PollMem(_DHCSR_ADDR, v, 0, v, _TIMEOUT_SLEEP_LISTEN_WINDOW, 1);
|
|
|
-
|
|
|
- // - 9 ----------------------------------------------------------------------
|
|
|
- // Load infinite loop code into SRAM (0x08000300 <- 0xE7FEE7FE)
|
|
|
- status = _WriteMem(_SRAM_LOOP_ADDR, _LOOP_CODE);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Load PC with address of infinite for loop SRAM address with thumb bit (bit [0]) set
|
|
|
- status = _WriteCoreReg(_REGSEL_PC, (_SRAM_LOOP_ADDR | 1));
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // - 10 ---------------------------------------------------------------------
|
|
|
- // Load SP with top of SRAM address – Set for minimum SRAM size devices (65 KB size)
|
|
|
- status = _WriteCoreReg(_REGSEL_MSP, _SRAM_TOP_ADDR); // SP <- 0x0800FFF0
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- // Read xPSR register, set the thumb bit, and restore modified value to xPSR register
|
|
|
- status = _ReadCoreReg(_REGSEL_xPSR, &v);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
- status = _WriteCoreReg(_REGSEL_xPSR, (v | _xPSR_T));
|
|
|
-
|
|
|
- // - 11 ---------------------------------------------------------------------
|
|
|
- // Disable Breakpoint unit so CPU will jump to endless loop execution in SRAM
|
|
|
- status = _WriteMem(_BP_CTRL_ADDR, _BP_CTRL_KEY); // BP_CTRL (0xE0002000) <- 0x00000002 (ENABLE == "0")
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Performs variety of PSoC 6 chip acquisition attempts:
|
|
|
-* 1. Acquire in Test Mode so the boot code will not start the application
|
|
|
-* 1.a. Using hardware pre-reset (XRES).
|
|
|
-* This is recommended and the only 100% reliable method.
|
|
|
-* But it will not work if XRES pin is not connected or debugger cannot meet timing requirements.
|
|
|
-* 1.b. Using software pre-reset (AIRCR.SYSRESETREQ).
|
|
|
-* Do it in case XRES pin is not connected.
|
|
|
-* 1.c. Acquire in Test Mode using software pre-reset (DP->CTRL/STAT.CDBGRSTREQ)
|
|
|
-* Do it in case firmware disabled anything behind the DAP so we can't use SYSRESETREQ.
|
|
|
-*
|
|
|
-* If all above steps failed, Test Mode acquisition is not possible because of
|
|
|
-* Listen window is turned off or the debugger cannot meet timing requirements.
|
|
|
-* In this case, use one following Alternate acquisition methods with same as above pre-reset strategies:
|
|
|
-*
|
|
|
-* 2. Acquire with "Alternate Method" based on setting the breakpoint at reset address
|
|
|
-* 2.a. Using hardware pre-reset (XRES).
|
|
|
-* 2.b. Using software pre-reset (AIRCR.SYSRESETREQ)
|
|
|
-* 2.c. Using software pre-reset (DP->CTRL/STAT.CDBGRSTREQ)
|
|
|
-*
|
|
|
-* ! Note that XRES connection is strongly required for the hardware reset.
|
|
|
-* Otherwise, neither of above methods will work if the firmware does really "bad" things such as:
|
|
|
-* - Repurposes the debug pins (intentionally or unintentionally)
|
|
|
-* - Disables/Protects access ports and the Listen window is turned off or too short
|
|
|
-* - Intentionally or unintentionally corrupts values in MMIO registers and the Listen window is turned off or too short
|
|
|
-* In this case, there is no way for debugger to establish even basic communication with target
|
|
|
-*
|
|
|
-* Refer PSoC 6 MCU Programming Specifications: 002-15554 http://www.cypress.com/file/385671/download
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) Must not use any high-level functions as it is also called from InitTarget() and uses non-standard APs etc.
|
|
|
-*/
|
|
|
-
|
|
|
-int _PSoC6_Acquire(U32 resumeCPU) {
|
|
|
- int status;
|
|
|
- status = _STATUS_ERR;
|
|
|
-
|
|
|
- if (_DO_ACQUIRE_TEST_MODE != 0) {
|
|
|
- // 1. Acquire PSoC 6 in Test Mode:
|
|
|
- // 1.1. Do hardware (XRES) or one of the software (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) reset
|
|
|
- // 1.2. Handshake + Init DAP
|
|
|
- // 1.3. Set TEST_MODE bit in TST_MODE SRSS register
|
|
|
- // 1.4. Check CPU is sleeping (executes WFI)
|
|
|
- // 1.5. Check PC is in ROM or in SFLASH (CPU must be halted to read PC)
|
|
|
- // Items 1.1 to 1.3 are time critical, so entire function executed in J-Link firmware and requires __probe attribute for caller
|
|
|
- status = _PSoC6_AcquireTestMode(1 /* "1" - do hardware pre-reset (XRES) */);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- // If acquisition failed for some reason (e.g. XRES is not connected), try to acquire in test mode using software reset
|
|
|
- // This should work if the Listen window is wide enough and the application did not disable the debug pins
|
|
|
- status = _PSoC6_AcquireTestMode(0 /* "0" - do software pre-reset (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) */);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ((status != _STATUS_OK) && (_DO_ACQUIRE_ALTERNATE != 0) ) {
|
|
|
- // 2. Performs PSoC 6 acquisition using alternate sequence:
|
|
|
- // 2.1. Do hardware (XRES) or one of the software (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) reset
|
|
|
- // 2.2. Handshake + Init DAP
|
|
|
- // 2.3. Halt CPU, enable debug
|
|
|
- // 2.4. Get Reset Address and Initial SP value from the vector table
|
|
|
- // 2.5. Enable Breakpoint unit and set the breakpoint at Reset Address
|
|
|
- // 2.6. Issue software reset using the SYSRESETREQ bit in AIRCR register
|
|
|
- // 2.7. Handshake + Init DAP
|
|
|
- // 2.8. Verify CPU is halted at breakpoint being set at Reset Address
|
|
|
- // 2.9. Load infinite loop into SRAM and set PC to this address
|
|
|
- // 2.10. Load SP with top of SRAM address, set thumb bit in xPSR
|
|
|
- // 2.11. Disable breakpoint unit and resume the CPU
|
|
|
- status = _PSoC6_AcquireAlternate(1 /* "1" - do hardware pre-reset (XRES) */);
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- // Last chance is to acquire using alternate method and software pre-reset
|
|
|
- status = _PSoC6_AcquireAlternate(0 /* "0" - do software pre-reset (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) */);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Sets PC and SP for further debugging
|
|
|
- status = _PSoC6_SetPCandSPFromVectorTable();
|
|
|
-
|
|
|
- // Resume CPU that was halted above if it is required for caller
|
|
|
- if ((_CheckStatus(status) == _STATUS_OK) && (resumeCPU != 0)) {
|
|
|
- status = _HaltResumeCPU(0 /* "0" - resume */);
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-/*********************************************************************
|
|
|
-* Global functions
|
|
|
-*********************************************************************/
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Called before InitTarget(). Mainly used to set some global DLL variables to customize the normal connect procedure.
|
|
|
-* For ARM CoreSight devices this may be specifying the base address of some CoreSight components (ETM, ...)
|
|
|
-* that cannot be automatically detected by J-Link due to erroneous ROM tables etc.
|
|
|
-* May also be used to specify the device name in case debugger does not pass it to the DLL.
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) May not, under absolutely NO circumstances, call any API functions that perform target communication.
|
|
|
-* (2) Should only set some global DLL variables
|
|
|
-*/
|
|
|
-int ConfigTargetSettings(void) {
|
|
|
- Report("*****************************************************************");
|
|
|
- Report("JLinkScript: Start 'ConfigTargetSettings' for Cortex-M0+ of CY8C6xx5/CY8C6xxA");
|
|
|
-
|
|
|
- JLINK_CORESIGHT_AddAP(_AP_SYS, CORESIGHT_CUSTOM_AP); // AP[0] SYS-AP (used for chip acquisition sequence)
|
|
|
- JLINK_CORESIGHT_AddAP(_AP_CM0, CORESIGHT_AHB_AP); // AP[1] CM0-AP (used for J-Link communication with Cortex-M0 core)
|
|
|
- JLINK_CORESIGHT_AddAP(_AP_CM4, CORESIGHT_AHB_AP); // AP[2] CM4-AP (used for J-Link communication with Cortex-M4 core)
|
|
|
- JLINK_CORESIGHT_IndexAHBAPToUse = _AP_MYCORE; // AP-Index of AHB-AP to use for communication with core
|
|
|
- CPU=CORTEX_M0;
|
|
|
-
|
|
|
- Report("*****************************************************************");
|
|
|
- return _STATUS_OK;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Replaces reset strategies of DLL.
|
|
|
-* No matter what reset type is selected in the DLL, if this function is present, it will be called instead of the DLL internal reset.
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0 O.K.
|
|
|
-* < 0 Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) DLL expects target CPU to be halted / in debug mode, when leaving this function
|
|
|
-* (2) May use MEM_ API functions
|
|
|
-* (3) __probe attribute specifies that this function is executed in the J-Link firmware rather than on the PC side,
|
|
|
-* so changes to global variables may only be temporarily valid inside this function (not guaranteed to be valid later)
|
|
|
-*/
|
|
|
-__probe int ResetTarget(void) {
|
|
|
- int status;
|
|
|
-
|
|
|
- // Acquire PSoC 6 in Test Mode or using Alternate Method
|
|
|
- // Note: Test Mode acquisition is time critical, so entire function executed in J-Link firmware and requires __probe attribute for caller
|
|
|
- status = _PSoC6_Acquire(0); // "0" - Do not resume CPU that is halted during acquisition since DLL expects target CPU to be halted / in debug mode, when leaving ResetTarget function
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- // Enable DWT, ITM, TPIU, and ETM units by setting TRCENA bit in DEMCR register
|
|
|
- status = _WriteMem(_DEMCR_ADDR, _DEMCR_TRCENA); // DEMCR (0xE000EDFC) <- TRCENA
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- return _CheckStatus(status);
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Replaces the target-CPU-auto-find procedure of the J-Link DLL.
|
|
|
-* Useful for target CPUs that are not accessible by default and need some special steps
|
|
|
-* to be executed before the normal debug probe connect procedure can be executed successfully.
|
|
|
-*
|
|
|
-* Return value
|
|
|
-* >= 0: O.K.
|
|
|
-* < 0: Error
|
|
|
-*
|
|
|
-* Notes
|
|
|
-* (1) If target interface JTAG is used: JTAG chain has to be specified manually before leaving this function
|
|
|
-* (meaning all devices and their TAP IDs have to be specified by the user).
|
|
|
-* Also appropriate JTAG TAP number to communicate with during the debug session has to be manually specified in this function.
|
|
|
-* (2) MUST NOT use any MEM_ API functions
|
|
|
-* (3) Global DLL variable “CPU” MUST be set when implementing this function, so the DLL knows which CPU module to use internally.
|
|
|
-* (4) __probe attribute specifies that this function is executed in the J-Link firmware rather than on the PC side,
|
|
|
-* so changes to global variables may only be temporarily valid inside this function (not guaranteed to be valid later)
|
|
|
-*/
|
|
|
-__probe int InitTarget(void) {
|
|
|
- int status;
|
|
|
-
|
|
|
- // Acquire PSoC 6 in Test Mode (a. ToggleXRES; b. Handshake; c. Init DAP; d. Set TEST_MODE bit in TST_MODE SRSS register)
|
|
|
- // Sequence is time critical, so executed in J-Link firmware and requires __probe attribute for caller
|
|
|
- status = _PSoC6_Acquire(1); // "1" - Resume CPU that was halted during acquisition
|
|
|
- if (_CheckStatus(status) != _STATUS_OK) {
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- JLINK_ExecCommand("SetETBIsPresent = 1"); // ETB is available
|
|
|
-
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*********************************************************************
|
|
|
-* Called right after flash programming Usually used to restore initialized peripherals
|
|
|
-* which have been used during the flash download like for example clocks or port pins
|
|
|
-* (e.g. QSPI alternate function)
|
|
|
-*
|
|
|
-* Notes / Limitations
|
|
|
-* (1) DLL expects target CPU to be halted / in debug mode, when leaving this function
|
|
|
-* (2) May use MEM_ API functions
|
|
|
-*/
|
|
|
-int HandleAfterFlashProg(void) {
|
|
|
- int status;
|
|
|
-
|
|
|
- // Do hardware (XRES) of software (AIRCR.SYSRESETREQ or DP->CTRL/STAT.CDBGRSTREQ) reset.
|
|
|
- // Otherwise, device remains acquired because the reset command sent by IDE after programming,
|
|
|
- // calls ResetTarget function, which will acquire target again.
|
|
|
- // This is required to start the application for normal execution and for "Attach" actions after programming.
|
|
|
- status = _PSoC6_Reset(1); // "1" do XRES
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-/*************************** end of file ****************************/
|