|
|
@@ -0,0 +1,327 @@
|
|
|
+/*********************************************************************
|
|
|
+* (c) 1995 - 2018 SEGGER Microcontroller GmbH *
|
|
|
+* The Embedded Experts *
|
|
|
+* www.segger.com *
|
|
|
+**********************************************************************
|
|
|
+
|
|
|
+-------------------------- END-OF-HEADER -----------------------------
|
|
|
+
|
|
|
+File : CY8C6xxx_CM0p_tm.JLinkScript
|
|
|
+Purpose : J-Link script file for Cypress PSoC 6 series
|
|
|
+Literature:
|
|
|
+ [1] J-Link User Guide
|
|
|
+
|
|
|
+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)
|
|
|
+*
|
|
|
+**********************************************************************
|
|
|
+*/
|
|
|
+
|
|
|
+__constant U32 _ACCESS_DP = 0;
|
|
|
+__constant U32 _ACCESS_AP = 1;
|
|
|
+__constant U32 _DHCSR_ADDR = 0xE000EDF0; // Debug Halting Control and Status Register
|
|
|
+__constant U32 _DEMCR_ADDR = 0xE000EDFC; // Debug Exception and Monitor Control Register
|
|
|
+__constant U32 _DCRDR_ADDR = 0xE000EDF8; // Debug Core Register Data Register
|
|
|
+__constant U32 _DCRSR_ADDR = 0xE000EDF4; // Debug Core Register Selector Register
|
|
|
+__constant U32 _DAP_ACC_32BIT_NO_AUTO_INC = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (2 << 0);
|
|
|
+__constant U32 _CPUSS_CM0_VTBASE = 0x402102B0; // Vector table base address for CM0+ core (CPUSS_CM0_VECTOR_TABLE_BASE reg.)
|
|
|
+__constant U32 _CPUSS_CMX_VTBASE_ERR_MSK = 0xFFFFFF00; // Set by boot code if flash is empty or secure application
|
|
|
+
|
|
|
+/*********************************************************************
|
|
|
+*
|
|
|
+* Static data
|
|
|
+*
|
|
|
+**********************************************************************
|
|
|
+*/
|
|
|
+
|
|
|
+const U8 _aData_SeqSwitchToSWD[] = {
|
|
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Line reset (min. 50 clocks SWDIO == HIGH)
|
|
|
+ 0x9E, 0xE7, // Switching sequence STM32
|
|
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Line reset (min. 50 clocks SWDIO == HIGH)
|
|
|
+ 0x00, 0x00 // Make sure SWD is ready for a start bit (min. 2 clocks with SWDIO == LOW)
|
|
|
+};
|
|
|
+
|
|
|
+const U8 _aDir_SeqSwitchToSWD[] = {
|
|
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
+ 0xFF, 0xFF,
|
|
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
+ 0xFF, 0xFF
|
|
|
+};
|
|
|
+
|
|
|
+U8 _aDataOut[18]; // Needs to be big enough to hold data for longest sequence
|
|
|
+
|
|
|
+/*********************************************************************
|
|
|
+*
|
|
|
+* Local functions
|
|
|
+*
|
|
|
+**********************************************************************
|
|
|
+*/
|
|
|
+
|
|
|
+/*********************************************************************
|
|
|
+*
|
|
|
+* _PerformChipAcquisitionSeq()
|
|
|
+*
|
|
|
+* Function description
|
|
|
+* Performs the Cypress PSoC6-specific chip acquisition sequence.
|
|
|
+*
|
|
|
+* 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 _PerformChipAcquisitionSeq(void) {
|
|
|
+ U32 v;
|
|
|
+ U32 OrgTIFSpeed;
|
|
|
+ int t;
|
|
|
+ int tDelta;
|
|
|
+ //
|
|
|
+ // Perform Cypress PSoC 6 chip acquisition sequence
|
|
|
+ // This is the recommended connection sequence, to make sure that we can gain control over the device again, even if there is bad code running on it
|
|
|
+ // nRESET == LOW
|
|
|
+ // nRESET == HIGH
|
|
|
+ // xx us (Wait for reset release)
|
|
|
+ // xx us (wait for secure boot code to finish)
|
|
|
+ // JTAGToSWDSwitching()
|
|
|
+ // Set TST_CTRL
|
|
|
+ // Device waits for app. 1500 us to receive the switching sequence + set TST_CTRL before it starts the user application
|
|
|
+ //
|
|
|
+ // We do not wait any fixed delay after reset release.
|
|
|
+ // We just output the switching sequence and try to read the SW-DP Id. This is repeated, until successful.
|
|
|
+ // This is done because the whole chip acquisition sequence is very time critical
|
|
|
+ //
|
|
|
+ //
|
|
|
+ // Make sure that J-Link is using a high target interface speed,
|
|
|
+ // so we can meet the timing requirements for "chip acquisition sequence"
|
|
|
+ // 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 = 4000;
|
|
|
+ //
|
|
|
+ // 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
|
|
|
+ //
|
|
|
+ JLINK_CORESIGHT_Configure("RetryOnInvalDAPResp=0;PerformTIFInit=0"); // 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
|
|
|
+ //
|
|
|
+ // Reset device, so it will wait for "device acquisition sequence"
|
|
|
+ //
|
|
|
+ JLINK_JTAG_ResetPin = 0; // nRESET == LOW
|
|
|
+ JLINK_SYS_Sleep(10); // Make sure that device recognizes the reset
|
|
|
+ JLINK_JTAG_ResetPin = 1; // nRESET == HIGH
|
|
|
+ //
|
|
|
+ // Wait until device becomes responsive
|
|
|
+ //
|
|
|
+ t = JLINK_GetTime();
|
|
|
+ do {
|
|
|
+ JLINK_SWD_ReadWriteBits(&_aData_SeqSwitchToSWD[0], &_aDir_SeqSwitchToSWD[0], &_aDataOut[0], 18 * 8);
|
|
|
+ v = 0;
|
|
|
+ JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_DP_REG_IDCODE, 0, &v);
|
|
|
+ v &= 0x0F000FFF;
|
|
|
+ if (v == 0x0B000477) { // DAP is responsive?
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ tDelta = JLINK_GetTime() - t;
|
|
|
+ } while (tDelta < 1000); // Timeout reached?
|
|
|
+ //
|
|
|
+ // Put device into test mode, so it does not start the user application
|
|
|
+ //
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_CTRL_STAT, 0, 0x50000000);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, 0x00000000);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_CTRL, 1, 0x00000002);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, 1, 0x40260100);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, 1, 0x80000000);
|
|
|
+ JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_DP_REG_RDBUF, 0, &v); // Make sure that the last AP write actually happens as SW-DP may buffer/delay it until next DAP access
|
|
|
+ //
|
|
|
+ // Restore CORESIGHT settings (See beginning of this function call for more info)
|
|
|
+ //
|
|
|
+ JLINK_CORESIGHT_Configure("RetryOnInvalDAPResp=1;PerformTIFInit=0"); // 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
|
|
|
+ //
|
|
|
+ // Restore original TIF speed
|
|
|
+ //
|
|
|
+ JLINK_JTAG_Speed = OrgTIFSpeed;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*********************************************************************
|
|
|
+*
|
|
|
+* Global functions
|
|
|
+*
|
|
|
+**********************************************************************
|
|
|
+*/
|
|
|
+
|
|
|
+/*********************************************************************
|
|
|
+*
|
|
|
+* ConfigTargetSettings()
|
|
|
+*
|
|
|
+* Function description
|
|
|
+* Called before InitTarget(). Maninly 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 PSoC6xxx Cortex-M0+");
|
|
|
+
|
|
|
+ //
|
|
|
+ // The PSoC 6 has the following APs:
|
|
|
+ // AP[0] SYS-AP (used for chip acquisition sequence)
|
|
|
+ // AP[1] CM0-AP (used for J-Link communication with Cortex-M0 core)
|
|
|
+ // AP[2] CM4-AP (used for J-Link communication with Cortex-M4 core)
|
|
|
+ //
|
|
|
+ JLINK_CORESIGHT_AddAP(0, CORESIGHT_CUSTOM_AP);
|
|
|
+ JLINK_CORESIGHT_AddAP(1, CORESIGHT_AHB_AP);
|
|
|
+ JLINK_CORESIGHT_AddAP(2, CORESIGHT_AHB_AP);
|
|
|
+ JLINK_CORESIGHT_IndexAHBAPToUse = 1; // AP-Index of AHB-AP to use for communication with core
|
|
|
+ CPU=CORTEX_M0;
|
|
|
+
|
|
|
+// //
|
|
|
+// // Mark a specific memory region as memory type illegal
|
|
|
+// // in order to make sure that the software is not allowed to access these regions
|
|
|
+// // Note: This does not work for J-Flash tool
|
|
|
+// //
|
|
|
+// // Exclude SFLASH regions
|
|
|
+// JLINK_ExecCommand("map region 0x16000000-0x160007FF XI"); // [SFLASH Start - User Data Start]
|
|
|
+// JLINK_ExecCommand("map region 0x16001000-0x160019FF XI"); // [User Data End - NAR Start]
|
|
|
+// JLINK_ExecCommand("map region 0x16001C00-0x160059FF XI"); // [NAR End - Public Key Start]
|
|
|
+// JLINK_ExecCommand("map region 0x16006600-0x16007BFF XI"); // [Public Key End - TOC2 Start]
|
|
|
+// // Exclude Cy Metadata
|
|
|
+// JLINK_ExecCommand("map region 0x90300000-0x903FFFFF XI"); // Cy Checksum
|
|
|
+// JLINK_ExecCommand("map region 0x90500000-0x905FFFFF XI"); // Cy Metadata
|
|
|
+// // Exclude eFuse
|
|
|
+// JLINK_ExecCommand("map region 0x90700000-0x907FFFFF XI");
|
|
|
+
|
|
|
+ Report("*****************************************************************");
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*********************************************************************
|
|
|
+*
|
|
|
+* ResetTarget()
|
|
|
+*
|
|
|
+* Function description
|
|
|
+* Replaces selected reset strategy of J-Link software.
|
|
|
+* No matter what reset type is selected, if this function is present, it will be called instead of the selected reset strategy
|
|
|
+*
|
|
|
+* 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
|
|
|
+*/
|
|
|
+__probe int ResetTarget(void) { // __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)
|
|
|
+ U32 iAPBank;
|
|
|
+ U32 iAP;
|
|
|
+ U32 v;
|
|
|
+ U32 vtBase;
|
|
|
+ U32 resetAddr;
|
|
|
+ //
|
|
|
+ // Perform standard chip acquisition sequence which also includes a reset
|
|
|
+ //
|
|
|
+ _PerformChipAcquisitionSeq(); // Requires __probe attribute for caller
|
|
|
+ //
|
|
|
+ // Make sure that the CPU is halted. See (1)
|
|
|
+ // No rush here, as chip acquisition sequence makes sure that user application is not started
|
|
|
+ //
|
|
|
+ // DAP has already been powered-up etc. by _PerformChipAcquisitionSeq(), so no need to configure CoreSight here again
|
|
|
+ //
|
|
|
+ JLINK_SYS_Sleep(5); // Give BTL some time to enter WFI
|
|
|
+ iAPBank = 0;
|
|
|
+ iAP = 1; // AHB-AP for M0
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, _ACCESS_DP, (iAP << 24) | (iAPBank << 4));
|
|
|
+ //
|
|
|
+ // Reset of PSoC6 also resets debug logic, so we need to restore some registers
|
|
|
+ // Luckily, we need to touch most of these registers anyhow, to halt the core
|
|
|
+ //
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_CTRL, _ACCESS_AP, _DAP_ACC_32BIT_NO_AUTO_INC);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DHCSR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, 0xA05F0003); // Key + C_DEBUGEN + C_HALT
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DEMCR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, (1 << 24)); // TRCENA
|
|
|
+ JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_DP_REG_RDBUF, _ACCESS_DP, &v); // Make sure that the last AP write actually happens as SW-DP may buffer/delay it until next DAP access
|
|
|
+ JLINK_SYS_Sleep(2); // Give CPU some time to handle halt request (should not be necessary, but as user-initiated reset is not really a time critical operation that happens rarely, it does not hurt)
|
|
|
+
|
|
|
+ //
|
|
|
+ // 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.
|
|
|
+ // 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
|
|
|
+ //
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _CPUSS_CM0_VTBASE);
|
|
|
+ JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, &vtBase);
|
|
|
+ vtBase &= _CPUSS_CMX_VTBASE_ERR_MSK;
|
|
|
+
|
|
|
+ if (vtBase != 0 && vtBase != _CPUSS_CMX_VTBASE_ERR_MSK) {
|
|
|
+
|
|
|
+ // Get address at reset vector
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, vtBase + 4);
|
|
|
+ JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, &resetAddr);
|
|
|
+ if (resetAddr != 0) {
|
|
|
+
|
|
|
+ // Set PC with address at reset
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRDR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, resetAddr);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRSR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, 0x0001000F);
|
|
|
+
|
|
|
+ // Get address at vector table & set SP
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, vtBase);
|
|
|
+ JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, &v);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRDR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, v);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRSR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, 0x00010011);
|
|
|
+
|
|
|
+ //Read xPSR register, set the thumb bit, and restore modified value to xPSR register
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRSR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, 0x00000010);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRDR_ADDR);
|
|
|
+ JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, &v);
|
|
|
+ v |= 0x01000000;
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRDR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, v);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, _DCRSR_ADDR);
|
|
|
+ JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, 0x00010010);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*********************************************************************
|
|
|
+*
|
|
|
+* InitTarget()
|
|
|
+*
|
|
|
+* Function description
|
|
|
+* If present, called right before performing generic connect sequence.
|
|
|
+* Usually used for targets which need a special connect sequence.
|
|
|
+* E.g.: TI devices with ICEPick TAP on them where core TAP needs to be enabled via specific ICEPick sequences first
|
|
|
+*
|
|
|
+* Return value
|
|
|
+* >= 0: O.K.
|
|
|
+* < 0: Error
|
|
|
+*
|
|
|
+* Notes
|
|
|
+* (1) Must not use high-level API functions like JLINK_MEM_ etc.
|
|
|
+* (2) For target interface JTAG, this device has to setup the JTAG chain + JTAG TAP Ids.
|
|
|
+* (3) This function is called before J-Link performed any communication with the device
|
|
|
+* (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) { // __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)
|
|
|
+ _PerformChipAcquisitionSeq(); // Requires __probe attribute for caller
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*************************** end of file ****************************/
|