vos/ambiq-hal-sys/ambiq-sparkfun-sdk/tools/apollo3_scripts/AMA3B2KK-KBR.JLinkScript
2022-10-23 23:45:43 -07:00

210 lines
7.2 KiB
Plaintext

/*********************************************************************
* (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));
}
}