/********************************************************************* * (c) SEGGER Microcontroller GmbH & Co. KG * * The Embedded Experts * * www.segger.com * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : AMA3B2KK-KBR.JLinkScript Purpose : Handle reset for AmbiqMicro AMA3B2KK series of MCUs Literature: [1] J-Link User Guide (UM08001_JLink.pdf) Additional information: For more information about public functions that can be implemented in order to customize J-Link actions, please refer to [1] *********************************************************************/ /********************************************************************* * * ResetTarget() * Reset and wait until CPU is halted. *********************************************************************/ void ResetTarget(void) { // Register Address Values int AIRCR_ADDR ; int DHCSR_ADDR ; int DEMCR_ADDR ; int AHBAP_REG_CTRL ; int AHBAP_REG_ADDR ; int AHBAP_REG_DATA ; int DP_REG_SELECT ; int MCUCTRL_SCRATCH0 ; int MCUCTRL_BOOTLDR ; int JDEC_PID ; // Internal Variables int Ctrl; int demcr; int scratch0; int bootldr; int jdecpid; int v; int Tries; int Done; int nonsecure; int timeout; // Initialize the Register Address and Internal vars. AIRCR_ADDR = 0xE000ED0C; DHCSR_ADDR = 0xE000EDF0; DEMCR_ADDR = 0xE000EDFC; MCUCTRL_SCRATCH0 = 0x400401B0; MCUCTRL_BOOTLDR = 0x400401A0; JDEC_PID = 0xF0000FE0; AHBAP_REG_CTRL = 0; AHBAP_REG_ADDR = 1; AHBAP_REG_DATA = 3; DP_REG_SELECT = 2; nonsecure = 1; timeout = 0; // Check global variable to detect whether debugger is using JTAG or SWO and configure JTAG is necessary. if (MAIN_ActiveTIF == JLINK_TIF_JTAG) { JLINK_CORESIGHT_Configure("IRPre=0;DRPre=0;IRPost=0;DRPost=0;IRLenDevice=4"); } else { JLINK_CORESIGHT_Configure(""); // For SWD, no special setup is needed, just output the switching sequence } // Power-up complete DAP Ctrl = 0 | (1 << 30) // System power-up | (1 << 28) // Debug popwer-up | (1 << 5) // Clear STICKYERR ; JLINK_CORESIGHT_WriteDP(1, Ctrl); // Select AHB-AP and configure it JLINK_CORESIGHT_WriteDP(DP_REG_SELECT, (0 << 4) | (0 << 24)); // Select AP[0] (AHB-AP) bank 0 JLINK_CORESIGHT_WriteAP(AHBAP_REG_CTRL, (1 << 4) | (1 << 24) | (1 << 25) | (1 << 29) | (2 << 0)); // Auto-increment, Private access, HMASTER = DEBUG, Access size: word // Enable Debug and Halt the MCU Core. JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DHCSR_ADDR); v = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); v &= 0x3F; // Mask out "debug" bits v |= 0xA05F0000; // Debug key to make a write to the DHCSR a valid one v |= 0x00000002; // Halt the core v |= 0x00000001; // Enable debug functionalities of the core JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DHCSR_ADDR); JLINK_CORESIGHT_WriteAP(AHBAP_REG_DATA, v); // Read the Peripheral ID. JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, JDEC_PID); jdecpid = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); Report1("JDEC PID ", jdecpid); // Is this Apollo3-Blue or Apollo3-Blue-Plus MCU? if ((jdecpid & 0xF0) == 0xC0) { // Apollo3-Blue or Apollo3-Blue-Plus Report("Ambiq Apollo3-Blue ResetTarget"); // Read MCUCTRL_BOOTLDR to determine if it is a secure or non-secure chip JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, MCUCTRL_BOOTLDR); bootldr = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); Report1("Bootldr = ", bootldr); if ((bootldr & 0x0C000000) == 0x04000000) { Report("Secure Part."); nonsecure = 0; } } if (nonsecure == 0) { // Set MCUCTRL Scratch0, indicating that the Bootloader needs to run, then halt when it is finished. Report("Secure Chip. Bootloader needs to run which will then halt when finish."); JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, MCUCTRL_SCRATCH0); scratch0 = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, MCUCTRL_SCRATCH0); JLINK_CORESIGHT_WriteAP(AHBAP_REG_DATA, scratch0 | 0x1); } else { // Set VC_CORERESET in the DEMCR. Report("Non-Secure Chip. Following normal Reset procedure."); JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DEMCR_ADDR); demcr = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DEMCR_ADDR); JLINK_CORESIGHT_WriteAP(AHBAP_REG_DATA, demcr | 0x00000001); } // Set the SYSRESETREQ bit in the AIRCR. // This will request the MCU Core to reset. JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, AIRCR_ADDR); JLINK_CORESIGHT_WriteAP(AHBAP_REG_DATA, 0x05FA0004); // Wait until CPU is halted Tries = 0; Done = 0; do { JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DHCSR_ADDR); v = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); // Check if CPU is halted. If so, we are done if (Tries >= 25) // wait for up to 2.5 seconds. { Report("Apollo3 (connect): Timeout while waiting for CPU to halt after reset. Manually halting CPU."); Done = 1; timeout = 1; } else if ((v != 0xFFFFFFFF) && (v & 0x00020000)) // Bit 17: S_HALT in the DHCSR. { Report1("CPU halted after reset. Num Tries = ", Tries); Done = 1; } Tries = Tries + 1; SYS_Sleep(100); // Go to sleep for 100 msec. } while(Done == 0); // Let's try one more time using regular reset method if ((timeout == 1) && (nonsecure == 0)) { // Set VC_CORERESET Report("Secure Part Reset timed out. Reverting to normal Reset procedure."); JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DEMCR_ADDR); demcr = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DEMCR_ADDR); JLINK_CORESIGHT_WriteAP(AHBAP_REG_DATA, demcr | 0x00000001); // SYSRESETREQ JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, AIRCR_ADDR); JLINK_CORESIGHT_WriteAP(AHBAP_REG_DATA, 0x05FA0004); // // Wait until CPU is halted // Tries = 0; Done = 0; do { JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DHCSR_ADDR); v = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); // Check if CPU is halted. If so, we are done if (Tries >= 25) // wait for up to 2.5 seconds. { Report("Apollo3 (connect): Timeout while waiting for CPU to halt after reset. Manually halting CPU."); Done = 1; timeout = 1; } else if ((v != 0xFFFFFFFF) && (v & 0x00020000)) // Bit 17: S_HALT in the DHCSR. { Report1("CPU halted after reset. Num Tries = ", Tries); Done = 1; } Tries = Tries + 1; SYS_Sleep(100); // Go to sleep for 100 msec. } while(Done == 0); } // If non-secure part,... if (nonsecure == 1) { // Clear VC_CORERESET in the DEMCR. JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DEMCR_ADDR); demcr = JLINK_CORESIGHT_ReadAP(AHBAP_REG_DATA); JLINK_CORESIGHT_WriteAP(AHBAP_REG_ADDR, DEMCR_ADDR); JLINK_CORESIGHT_WriteAP(AHBAP_REG_DATA, (demcr & 0xFFFFFFFE)); } }