210 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			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));
 | 
						|
   }
 | 
						|
 | 
						|
 | 
						|
}
 |