This is an automated email from Gerrit.

Rick Foos ([email protected]) just uploaded a new patch set to Gerrit, which 
you can find at http://openocd.zylin.com/3513

-- gerrit

commit b3795abc625297c0e9d97ba96f0d72824e1670fc
Author: Rick Foos <[email protected]>
Date:   Fri May 27 20:58:14 2016 -0500

    flash/nor: Add Apollo2 controller.
    
    This driver supports both the Apollo and Apollo2 microcontrollers.
    The Apollo2: doubles the available sizes of flash and sram,
    raises the clock speed, and adds peripherals for more
    complex applications.
    
    The Apollo2 debugger interface essentially the same as Apollo.
    All flash operations are performed by bootloader calls as before.
    
    The bootloader calling procedure is significantly improved
    based on feedback from the initial Apollo patch.
    
    All sram parameter blocks are set by a single routine(setupSram).
    The bootloader target return,  wait sequence and error handling
    are in a single routine for all commands (ambiqmicro_exec_command).
    
    There are several commands unique to Apollo and Apollo2 devices.
    There are also several commands that are the same but with
    some size and address differences.
    
    These differences are handled by an 'enum' like structure called 'name_t'.
    When Apollo or Apollo2 is detected, the structured is set to
    0, and then the appropriate command/address/size set is loaded.
    
    A command that is invalid for a particular chip has a value of 0,
    and this error is detected in 'ambiqmicro_exec_command'.
    All other command execution errors are handled here as well.
    
    Two target specific reset commands are added. These are
    useful for test scripts to clear the environment between tests.
    
    Power On Reset only resets the Cortex-M core.
    Power On Internal resets all peripherals and the core.
    
    When POI is issued, the connection will drop and openocd
    will restart the target. The target is fully functional through
    this reset, and the flash bank info from probe
    is still available.
    
    Change-Id: I79e23c42ce47007e0a251295caebfdb151ebd319
    Signed-off-by: Rick Foos <[email protected]>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index ae92697..41f33fd 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -4963,8 +4963,10 @@ flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME
 @deffn {Flash Driver} ambiqmicro
 @cindex ambiqmicro
 @cindex apollo
-All members of the Apollo microcontroller family from
-Ambiq Micro include internal flash and use ARM's Cortex-M4 core.
+@cindex apollo2
+Apollo Ultra Low Power Microcontrollers from
+Ambiq Micro use ARM's Cortex-M4 core
+running at sub-threshold voltage.
 The host connects over USB to an FTDI interface that communicates
 with the target using SWD.
 
@@ -4972,23 +4974,21 @@ The @var{ambiqmicro} driver reads the Chip Information 
Register detect
 the device class of the MCU.
 The Flash and Sram sizes directly follow device class, and are used
 to set up the flash banks.
-If this fails, the driver will use default values set to the minimum
-sizes of an Apollo chip.
 
-All Apollo chips have two flash banks of the same size.
+All Apollo's have two flash banks of the same size.
 In all cases the first flash bank starts at location 0,
 and the second bank starts after the first.
 
 @example
-# Flash bank 0
-flash bank $_FLASHNAME ambiqmicro 0 0x00040000 0 0 $_TARGETNAME
+# Flash bank 0 - size determined at runtime.
+flash bank $_FLASHNAME ambiqmicro 0x00000000 0x00000000 0 0 $_TARGETNAME
 # Flash bank 1 - same size as bank0, starts after bank 0.
-flash bank $_FLASHNAME ambiqmicro 0x00040000 0x00040000 0 0 $_TARGETNAME
+flash bank $_FLASHNAME ambiqmicro 0x00000000 0x00000000 0 0 $_TARGETNAME
 @end example
 
 Flash is programmed using custom entry points into the bootloader.
-This is the only way to program the flash as no flash control registers
-are available to the user.
+This is the only way to program the flash. There is no way to
+access flash control registers from a user program.
 
 The @var{ambiqmicro} driver adds some additional commands:
 
@@ -4999,10 +4999,34 @@ Erase entire bank.
 Erase device pages.
 @end deffn
 @deffn Command {ambiqmicro program_otp} <bank> <offset> <count>
-Program OTP is a one time operation to create write protected flash.
-The user writes sectors to sram starting at 0x10000010.
-Program OTP will write these sectors from sram to flash, and write protect
+Program OTP is a one time operation to create write protected flash [APOLLO 
ONLY].
+The caller writes sectors to sram starting at 0x10000010.
+Program OTP will write sectors from sram to flash, and write protect
 the flash.
+The flash protection is permanent. There is no way to erase and
+re-program once this command is used.
+@end deffn
+@deffn Command {ambiqmicro poi}
+Send Power on Internal (POI) to target.
+The processor and all peripherals are reset.
+@end deffn
+@deffn Command {ambiqmicro por}
+Send  Power On Reset (POR) to target.
+The processor is reset.
+@end deffn
+@deffn Command {ambiqmicro program_info} <bank> <offset> <count>
+Program INFO will write sectors from sram to flash, and write
+protect the flash [APOLLO2 ONLY]. The sram buffer starts at
+0x10001000.
+@end deffn
+@deffn Command {ambiqmicro recover}
+Recover and erase locked device. [APOLLO2 ONLY]
+@end deffn
+@deffn Command {ambiqmicro erase_info} <bank>
+Erase the info bank [APOLLO2 ONLY].
+@end deffn
+@deffn Command {ambiqmicro erase_info_plus_main} <bank>
+Erase the info plus main bank [APOLLO2 ONLY].
 @end deffn
 @end deffn
 
@@ -5132,6 +5156,55 @@ This command shows/sets the slow clock frequency used in 
the
 @end deffn
 @end deffn
 
+@deffn {Flash Driver} ambiqmicro
+@cindex ambiqmicro
+@cindex apollo
+All members of the Apollo microcontroller family from
+Ambiq Micro include internal flash and use ARM's Cortex-M4 core.
+The host connects over USB to an FTDI interface that communicates
+with the target using SWD.
+
+The @var{ambiqmicro} driver reads the Chip Information Register detect
+the device class of the MCU.
+The Flash and Sram sizes directly follow device class, and are used
+to set up the flash banks.
+If this fails, the driver will use default values set to the minimum
+sizes of an Apollo chip.
+
+All Apollo chips have two flash banks of the same size.
+In all cases the first flash bank starts at location 0,
+and the second bank starts after the first.
+
+@example
+# Flash bank 0
+flash bank $_FLASHNAME ambiqmicro 0 0x00040000 0 0 $_TARGETNAME
+# Flash bank 1 - same size as bank0, starts after bank 0.
+flash bank $_FLASHNAME ambiqmicro 0x00040000 0x00040000 0 0 $_TARGETNAME
+@end example
+
+Flash is programmed using custom entry points into the bootloader.
+This is the only way to program the flash as no flash control registers
+are available to the user.
+
+The @var{ambiqmicro} driver adds some additional commands:
+
+@deffn Command {ambiqmicro mass_erase} <bank>
+Erase entire bank.
+@end deffn
+@deffn Command {ambiqmicro page_erase} <bank> <first> <last>
+Erase device pages.
+@end deffn
+@deffn Command {ambiqmicro program_otp} <bank> <offset> <count>
+Program OTP is a one time operation to create write protected flash.
+The user writes sectors to sram starting at 0x10000010.
+Program OTP will write these sectors from sram to flash, and write protect
+the flash.
+@quotation Warning
+This operation can only be done once for each sector. It CANNOT be undone.
+@end quotation
+@end deffn
+@end deffn
+
 @deffn {Flash Driver} at91sam4
 @cindex at91sam4
 All members of the AT91SAM4 microcontroller family from
diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c
index b2c30e6..7fe7eb9 100644
--- a/src/flash/nor/ambiqmicro.c
+++ b/src/flash/nor/ambiqmicro.c
@@ -7,11 +7,11 @@
  *****************************************************************************/
 
 /******************************************************************************
- * Copyright (c) 2015, David Racine <dracine at ambiqmicro.com>
+ * Copyright (C) 2015, David Racine <dracine at ambiqmicro.com>
  *
- * Copyright (c) 2016, Rick Foos <rfoos at solengtech.com>
+ * Copyright (C) 2016, Rick Foos <rfoos at solengtech.com>
  *
- * Copyright (c) 2015-2016, Ambiq Micro, Inc.
+ * Copyright (C) 2015-2016, Ambiq Micro, Inc.
  *
  * All rights reserved.
  *
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -51,23 +52,121 @@
 #include "target/algorithm.h"
 #include "target/armv7m.h"
 #include "target/cortex_m.h"
+#include "target/register.h"
 
-/** Check error, log error. */
-#define CHECK_STATUS(rc, msg) {        \
-               if (rc != ERROR_OK) { \
-                       LOG_ERROR("status(%d):%s\n", rc, msg); } }
+#if 0
+#define _DEBUG_FLASHCMD_EXECUTION_ 1
+#endif
+
+/* RSTGEN - MCU Reset Generator 0x40000000 */
+
+#define RSTGEN_CFG      (0x40000000)
+#define RSTGEN_POI      (0x40000004)
+#define RSTGEN_POIKEY   (0x0000001B)
+#define RSTGEN_POR      (0x40000008)
+#define RSTGEN_PORKEY   (0x000000D4)
+#define RSTGEN_STAT     (0x4000000C)
+#define RSTGEN_POISTAT  (0x00000010)
+#define RSTGEN_SWRSTAT  (0x00000008)   /* POR or AICR Reset occurred. */
+#define RSTGEN_PORSTAT  (0x00000002)   /* POR Reset occurred. */
+#define RSTGEN_CLRSTAT  (0x40000010)
+#define RSTGEN_CLRKEY   (0x00000001)
+
+/* Address and Key defines. */
 
-/*
- * Address and Key defines.
- */
 #define PROGRAM_KEY      (0x12344321)
 #define OTP_PROGRAM_KEY  (0x87655678)
 
-#define FLASH_PROGRAM_MAIN_FROM_SRAM                0x0800005d
-#define FLASH_PROGRAM_OTP_FROM_SRAM                 0x08000061
-#define FLASH_ERASE_LIST_MAIN_PAGES_FROM_SRAM       0x08000065
-#define FLASH_MASS_ERASE_MAIN_PAGES_FROM_SRAM       0x08000069
+/** Key to program info0 flash. */
+#define CUSTOMER_PROGRAM_KEY    (0x87655678)
+#define INFO0_ERASE_KEY         (0x56295141)
+#define BRICK_KEY               (0xA35C9B6D)
+
+
+/** Bootloader visible at 0x00000000 (0x1). */
+#define REG_CONTROL_BOOTLOADERLOW   (0x400201a0)
+/** Part number (class) and sram/flash size. */
+#define REG_CONTROL_CHIPPN          (0x40020000)
+/** Readable on Apollo2 only, fails on Apollo. */
+#define REG_APOLLO2_ID              (0x50011000)
+
+/** Apollo info0 base address. */
+#define APOLLO_INFO0_BASE_ADDRESS   (0x50020400)
+#define APOLLO_INFO0_WRITE_PROTECT0 (0x50020404)
+#define APOLLO_INFO0_COPY_PROTECT0  (0x50020408)
+/** Apollo2 info0 base address. */
+#define APOLLO2_INFO0_BASE_ADDRESS   (0x50020000)
+#define APOLLO2_INFO0_WRITE_PROTECT0 (0x50020020)
+#define APOLLO2_INFO0_COPY_PROTECT0  (0x50020030)
+
+/** Breakpoint for Bootloader to start, and location for return code. */
+#define BREAKPOINT                  (0xfffffffe)
+
+/* Bootloader Commands. */
+
+/** @note The following commands are the same in Apollo and Apollo2. */
+
+/** Bootloader program main flash, parameters in SRAM. */
+#define FLASH_PROGRAM_MAIN_FROM_SRAM                (0x0800005d)
+/** Apollo only (no instance parameter) */
+#define FLASH_PROGRAM_OTP_FROM_SRAM                 (0x08000061)
+/** Apollo2 only. */
+#define FLASH_PROGRAM_INFO_FROM_SRAM                (0x08000061)
+/** Both. */
+#define FLASH_ERASE_MAIN_PAGES_FROM_SRAM            (0x08000065)
+#define FLASH_MASS_ERASE_FROM_SRAM                  (0x08000069)
 
+/** @note Apollo2 only commands. */
+
+#define APOLLO2_FLASH_INFO_ERASE_FROM_SRAM           (0x08000085)
+#define APOLLO2_FLASH_INFO_PLUS_MAIN_ERASE_FROM_SRAM (0x0800008D)
+#define APOLLO2_FLASH_RECOVERY_FROM_SRAM             (0x08000099)
+
+
+/** Apollo: Info space size. */
+#define APOLLO_INFO_SPACE_SIZE      (256)
+/** Apollo2: Info space size. */
+#define APOLLO2_INFO_SPACE_SIZE     (2048)
+
+/** Apollo Bootloader Write Buffer Start. */
+#define APOLLO_WRITE_BUFFER_START    (0x10000010)
+/** Apollo2 Bootloader Write Buffer Start. */
+#define APOLLO2_WRITE_BUFFER_START   (0x10001000)
+/** Apollo Bootloader Write Buffer Size. Max size 6k. */
+#define APOLLO_WRITE_BUFFER_SIZE     (0x00001800)
+/** Apollo2 Bootloader Write Buffer Size. */
+#define APOLLO2_WRITE_BUFFER_SIZE     (0x00001800)
+
+
+/******************************************************************************
+ *
+ * Define some INFO protection values and macros.
+ *
+ 
******************************************************************************/
+#define AM_HAL_INFO_DBGR_O           0
+#define AM_HAL_INFO_WRITPROT_O       4
+#define AM_HAL_INFO_COPYPROT_O       8
+/** Protection bit chunksize for both Apollo and Apollo2. */
+#define AM_HAL_INFO_CHUNKSIZE        (16*1024)
+
+#define AM_HAL_INFO0_ADDR             0x50020000
+#define AM_HAL_INFO1_ADDR             0x50020400
+#define AM_HAL_INFO0_DBGRPROT_ADDR    (AM_HAL_INFO0_ADDR + AM_HAL_INFO_DBGR_O)
+#define AM_HAL_INFO0_WRITPROT_ADDR    (AM_HAL_INFO0_ADDR + 
AM_HAL_INFO_WRITPROT_O)
+#define AM_HAL_INFO0_COPYPROT_ADDR    (AM_HAL_INFO0_ADDR + 
AM_HAL_INFO_COPYPROT_O)
+#define AM_HAL_INFO1_DBGRPROT_ADDR    (AM_HAL_INFO1_ADDR + AM_HAL_INFO_DBGR_O)
+#define AM_HAL_INFO1_WRITPROT_ADDR    (AM_HAL_INFO1_ADDR + 
AM_HAL_INFO_WRITPROT_O)
+#define AM_HAL_INFO1_COPYPROT_ADDR    (AM_HAL_INFO1_ADDR + 
AM_HAL_INFO_COPYPROT_O)
+
+/** Check for error, then log the error. */
+#define CHECK_STATUS(rc, msg) {        \
+               if (rc != ERROR_OK) \
+                       LOG_ERROR("status(%d):%s\n", rc, msg); }
+
+/** Bootloader SRAM parameter block start. */
+#define SRAM_PARAM_START    ((uint32_t *)0x10000000ul)
+/** Autoincrementing Sram pointer, increment determined by pSram type. */
+#define pSRAM               ((uintptr_t)pSram++)
 
 static const uint32_t apollo_flash_size[] = {
        1 << 15,
@@ -96,19 +195,24 @@ struct ambiqmicro_flash_bank {
 
        const char *target_name;
        uint8_t target_class;
+       uint8_t target_revision;
+       uint8_t target_package;
 
        uint32_t sramsiz;
        uint32_t flshsiz;
 
        /* flash geometry */
+
        uint32_t num_pages;
        uint32_t pagesize;
        uint32_t pages_in_lockregion;
 
-       /* nv memory bits */
+       /* nonvolatile memory bits */
+
        uint16_t num_lockbits;
 
        /* main clock status */
+
        uint32_t rcc;
        uint32_t rcc2;
        uint8_t mck_valid;
@@ -123,25 +227,125 @@ static struct {
        uint8_t class;
        uint8_t partno;
        const char *partname;
-} ambiqmicroParts[6] = {
-       {0xFF, 0x00, "Unknown"},
+} ambiqmicroParts[] = {
+       {0x00, 0x00, "Unknown"},
        {0x01, 0x00, "Apollo"},
-       {0x02, 0x00, "Apollo2"},
-       {0x03, 0x00, "Unknown"},
-       {0x04, 0x00, "Unknown"},
-       {0x05, 0x00, "Apollo"},
+       {0x02, 0x00, "Reserved"},
+       {0x03, 0x00, "Apollo2"},
+       {0x04, 0x00, "Apollo3"},
+       {0x05, 0x00, "ApolloSBL"},
 };
 
-static char *ambiqmicroClassname[6] = {
-       "Unknown", "Apollo", "Apollo2", "Unknown", "Unknown", "Apollo"
+/** Chip names used by flash info command. */
+static char *ambiqmicroClassname[] = {
+       "Unknown",
+       "Apollo",
+       "Reserved",
+       "Apollo2",
+       "Apollo3",
+       "ApolloSBL"
+};
+
+/** Package names used by flash info command. */
+static char *ambiqmicroPackagename[] = {
+       "SIP",
+       "QFN",
+       "BGA",
+       "CSP"
 };
 
 /***************************************************************************
-*      openocd command interface                                              *
+*      Enumerated types for common Apollo commands, and addresses.
 ***************************************************************************/
 
-/* flash_bank ambiqmicro <base> <size> 0 0 <target#>
- */
+typedef uint32_t MyEnum;
+
+/** Bootloader commands and addresses for current chip. */
+struct {
+       MyEnum write_buffer_start;
+       MyEnum write_buffer_size;
+       MyEnum info_space_size;
+       MyEnum info0_flash_write_protect;
+       MyEnum flash_program_main_from_sram;
+       MyEnum flash_program_info_from_sram;
+       MyEnum flash_erase_main_pages_from_sram;
+       MyEnum flash_mass_erase_from_sram;
+       /* Apollo only command. */
+       MyEnum flash_program_otp_from_sram;
+       /* Apollo2 only commands. */
+       MyEnum flash_info_erase_from_sram;
+       MyEnum flash_info_plus_main_erase_from_sram;
+       MyEnum flash_recovery_from_sram;
+} name_t;
+
+static void zeroEnums(void)
+{
+       int count = sizeof(name_t)/sizeof(MyEnum);
+       MyEnum *values = (MyEnum *) &name_t;
+       for (int i = 0; i < count; i++)
+               values[i] = 0;
+}
+
+#if _DEBUG_FLASHCMD_EXECUTION_ == 2
+#define DUMP(varname) LOG_INFO("%s = 0x%x", # varname, name_t.varname)
+static void dumpEnums(void)
+{
+       DUMP(write_buffer_start);
+       DUMP(write_buffer_size);
+       DUMP(info_space_size);
+       DUMP(info0_flash_write_protect);
+       DUMP(flash_program_main_from_sram);
+       DUMP(flash_program_info_from_sram);
+       DUMP(flash_program_otp_from_sram);
+       DUMP(flash_erase_main_pages_from_sram);
+       DUMP(flash_mass_erase_from_sram);
+       /* Apollo2 only commands. */
+       DUMP(flash_info_erase_from_sram);
+       DUMP(flash_info_plus_main_erase_from_sram);
+       DUMP(flash_recovery_from_sram);
+
+}
+#endif
+
+/** Apollo2 specific bootloader commands, offsets, and sizes. */
+static void initApollo2Enum(void)
+{
+       zeroEnums();
+       name_t.write_buffer_start = APOLLO2_WRITE_BUFFER_START;
+       name_t.write_buffer_size = APOLLO2_WRITE_BUFFER_SIZE;
+       name_t.info_space_size = APOLLO2_INFO_SPACE_SIZE;
+       name_t.info0_flash_write_protect = APOLLO2_INFO0_WRITE_PROTECT0;
+/* Apollo and Apollo2 the same */
+       name_t.flash_program_main_from_sram = FLASH_PROGRAM_MAIN_FROM_SRAM;
+       name_t.flash_program_info_from_sram = FLASH_PROGRAM_INFO_FROM_SRAM;
+       name_t.flash_erase_main_pages_from_sram = 
FLASH_ERASE_MAIN_PAGES_FROM_SRAM;
+       name_t.flash_mass_erase_from_sram = FLASH_MASS_ERASE_FROM_SRAM;
+/* Apollo2 only. */
+       name_t.flash_info_erase_from_sram = APOLLO2_FLASH_INFO_ERASE_FROM_SRAM;
+       name_t.flash_info_plus_main_erase_from_sram = 
APOLLO2_FLASH_INFO_PLUS_MAIN_ERASE_FROM_SRAM;
+       name_t.flash_recovery_from_sram = APOLLO2_FLASH_RECOVERY_FROM_SRAM;
+};
+
+static void initApolloEnum(void)
+{
+       zeroEnums();
+       name_t.write_buffer_start = APOLLO_WRITE_BUFFER_START;
+       name_t.write_buffer_size = APOLLO_WRITE_BUFFER_SIZE;
+       /** Size of info0 space on device. */
+       name_t.info_space_size = APOLLO_INFO_SPACE_SIZE;
+       /** Flash write protect INFO0. */
+       name_t.info0_flash_write_protect = APOLLO_INFO0_WRITE_PROTECT0;
+       name_t.flash_program_main_from_sram = FLASH_PROGRAM_MAIN_FROM_SRAM;
+       name_t.flash_program_otp_from_sram = FLASH_PROGRAM_OTP_FROM_SRAM;
+       name_t.flash_erase_main_pages_from_sram = 
FLASH_ERASE_MAIN_PAGES_FROM_SRAM;
+       name_t.flash_mass_erase_from_sram = FLASH_MASS_ERASE_FROM_SRAM;
+}
+
+/***************************************************************************
+*      openocd command interface
+***************************************************************************/
+
+/** flash_bank ambiqmicro <base> <size> 0 0 <target#> */
 FLASH_BANK_COMMAND_HANDLER(ambiqmicro_flash_bank_command)
 {
        struct ambiqmicro_flash_bank *ambiqmicro_info;
@@ -181,10 +385,13 @@ static int get_ambiqmicro_info(struct flash_bank *bank, 
char *buf, int buf_size)
        printed = snprintf(buf,
                buf_size,
                "\nAmbiq Micro information: Chip is "
-               "class %d (%s) %s\n",
+               "class %i (%s) %s%s Rev %i.%i\n",
                ambiqmicro_info->target_class,
                classname,
-               ambiqmicro_info->target_name);
+               ambiqmicro_info->target_name,
+               ambiqmicroPackagename[ambiqmicro_info->target_package],
+               ambiqmicro_info->target_revision >> 4,
+               ambiqmicro_info->target_revision & 0xF);
 
        if ((printed < 0))
                return ERROR_BUF_TOO_SMALL;
@@ -192,10 +399,10 @@ static int get_ambiqmicro_info(struct flash_bank *bank, 
char *buf, int buf_size)
 }
 
 /***************************************************************************
-*      chip identification and status                                         *
+*      chip identification and status
 ***************************************************************************/
 
-/* Fill in driver info structure */
+/** Fill in driver info structure */
 static int ambiqmicro_read_part_info(struct flash_bank *bank)
 {
        struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;
@@ -205,54 +412,93 @@ static int ambiqmicro_read_part_info(struct flash_bank 
*bank)
 
        /*
         * Read Part Number.
+        * <class><flashsize><sramsize><revision><package>
         */
-       retval = target_read_u32(target, 0x40020000, &PartNum);
+       retval = target_read_u32(target, REG_CONTROL_CHIPPN, &PartNum);
+#if _DEBUG_FLASHCMD_EXECUTION_ == 1
+       LOG_INFO("pReg[0x%X] 0x%X", REG_CONTROL_CHIPPN, PartNum);
+#endif
        if (retval != ERROR_OK) {
-               LOG_ERROR("status(0x%x):Could not read PartNum.\n", retval);
+               LOG_ERROR("status(0x%x): Could not read PartNum.", retval);
                /* Set PartNum to default device */
                PartNum = 0;
        }
+
+       /* guess minimum config(fpga) 2 64k flash banks, 256k sram. */
+       if (PartNum == 0) {
+               uint32_t class;
+               retval = target_read_u32(target, REG_APOLLO2_ID, &class);
+#if _DEBUG_FLASHCMD_EXECUTION_ == 1
+               LOG_INFO("pReg[0x%X] 0x%X", REG_APOLLO2_ID, class);
+#endif
+               if (retval == ERROR_OK)
+                       class = 3;
+               else {
+                       /* Cannot disable failure message from target_read_u32. 
*/
+                       LOG_INFO(
+                               "Apollo detected. (please ignore 'Failed to 
read memory' message).");
+                       class = 1;
+               }
+               PartNum = (
+                       (class << 24) | /* Class Apollo2 */ \
+                       (1 << 8)  |     /* Revision 0.1 */ \
+                       (2 << 20) |     /* Flash Size 128k */ \
+                       (3 << 16)       /* SRAM Size 256k */ \
+                       );
+       }
+
        LOG_DEBUG("Part number: 0x%x", PartNum);
 
        /*
-        * Determine device class.
+        * Determine device class, and revision.
         */
        ambiqmicro_info->target_class = (PartNum & 0xFF000000) >> 24;
+       ambiqmicro_info->target_revision = (PartNum & 0x0000FF00) >> 8;
+       ambiqmicro_info->target_package = (PartNum & 0x000000C0) >> 6;
 
        switch (ambiqmicro_info->target_class) {
                case 1:         /* 1 - Apollo */
-               case 5:         /* 5 - Apollo Bootloader */
-                       bank->base = bank->bank_number * 0x40000;
+               case 5:         /* 5 - Apollo Secure Bootloader */
                        ambiqmicro_info->pagesize = 2048;
-                       ambiqmicro_info->flshsiz =
-                       apollo_flash_size[(PartNum & 0x00F00000) >> 20];
-                       ambiqmicro_info->sramsiz =
-                       apollo_sram_size[(PartNum & 0x000F0000) >> 16];
-                       ambiqmicro_info->num_pages = ambiqmicro_info->flshsiz /
-                       ambiqmicro_info->pagesize;
-                       if (ambiqmicro_info->num_pages > 128) {
-                               ambiqmicro_info->num_pages = 128;
-                               ambiqmicro_info->flshsiz = 1024 * 256;
-                       }
+                       initApolloEnum();
                        break;
 
-               default:
-                       LOG_INFO("Unknown Class. Using Apollo-64 as default.");
+               case 3:         /* 3 - Apollo2 */
+                       ambiqmicro_info->pagesize = 8192;
+                       initApollo2Enum();
+                       break;
 
-                       bank->base = bank->bank_number * 0x40000;
+               default:
+                       LOG_WARNING("Unknown Class %d. Using Apollo64 default.",
+                       ambiqmicro_info->target_class);
                        ambiqmicro_info->pagesize = 2048;
-                       ambiqmicro_info->flshsiz = apollo_flash_size[1];
-                       ambiqmicro_info->sramsiz = apollo_sram_size[0];
-                       ambiqmicro_info->num_pages = ambiqmicro_info->flshsiz /
-                       ambiqmicro_info->pagesize;
-                       if (ambiqmicro_info->num_pages > 128) {
-                               ambiqmicro_info->num_pages = 128;
-                               ambiqmicro_info->flshsiz = 1024 * 256;
+                       initApolloEnum();
+                       if (PartNum == 0) {
+                               PartNum &= 0x0000FFFF;
+                               PartNum |= 0x00100000;  /* class = 00, flash = 
1, sram = 0 */
                        }
                        break;
 
        }
 
+#if _DEBUG_FLASHCMD_EXECUTION_ == 2
+       dumpEnums();
+#endif
+
+       /* Calculate flash/sram size. */
+       ambiqmicro_info->flshsiz = apollo_flash_size[(PartNum & 0x00F00000) >> 
20];
+       bank->base = bank->bank_number * ambiqmicro_info->flshsiz;
+       ambiqmicro_info->sramsiz = apollo_sram_size[(PartNum & 0x000F0000) >> 
16];
+
+       /* Maximum pages 128. */
+       ambiqmicro_info->num_pages = ambiqmicro_info->flshsiz / 
ambiqmicro_info->pagesize;
+       if (ambiqmicro_info->num_pages > 128) {
+               ambiqmicro_info->num_pages = 128;
+               ambiqmicro_info->flshsiz = 1024 * 256;
+               bank->base = bank->bank_number * ambiqmicro_info->flshsiz;
+       }
+
+       /* Target Name */
        if (ambiqmicro_info->target_class <
                (sizeof(ambiqmicroParts)/sizeof(ambiqmicroParts[0])))
                ambiqmicro_info->target_name =
@@ -261,42 +507,94 @@ static int ambiqmicro_read_part_info(struct flash_bank 
*bank)
                ambiqmicro_info->target_name =
                        ambiqmicroParts[0].partname;
 
-       LOG_DEBUG("num_pages: %d, pagesize: %d, flash: %d, sram: %d",
+       LOG_INFO("target name: %s, num_pages: %d, pagesize: %d, flash: %d KB, 
sram: %d KB",
+               ambiqmicro_info->target_name,
                ambiqmicro_info->num_pages,
                ambiqmicro_info->pagesize,
-               ambiqmicro_info->flshsiz,
-               ambiqmicro_info->sramsiz);
+               ambiqmicro_info->flshsiz/1024,
+               ambiqmicro_info->sramsiz/1024);
 
        return ERROR_OK;
 }
 
 /***************************************************************************
-*      flash operations                                                       *
+*      flash operations
 ***************************************************************************/
 
-static int ambiqmicro_protect_check(struct flash_bank *bank)
+/** Target must be halted and probed before bootloader commands are executed. 
*/
+static int target_ready_for_command(struct flash_bank *bank)
 {
-       struct ambiqmicro_flash_bank *ambiqmicro = bank->driver_priv;
-       int status = ERROR_OK;
-       uint32_t i;
+       struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;
 
+       if (bank->target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
 
-       if (ambiqmicro->probed == 0) {
+       if (ambiqmicro_info->probed == 0) {
                LOG_ERROR("Target not probed");
                return ERROR_FLASH_BANK_NOT_PROBED;
        }
 
-       for (i = 0; i < (unsigned) bank->num_sectors; i++)
-               bank->sectors[i].is_protected = -1;
+       return ERROR_OK;
+}
 
-       return status;
+/** write the is_erased flag to sector map. */
+static int write_is_erased(struct flash_bank *bank, int first, int last, int 
flag)
+{
+       if ((first > bank->num_sectors) || (last > bank->num_sectors))
+               return ERROR_FAIL;
+
+       for (int i = first; i < last; i++)
+               bank->sectors[i].is_erased = flag;
+       return ERROR_OK;
+}
+
+/** Clear sram parameter space.
+Sram pointer is incremented+4 beyond the last write to sram.*/
+static int clear_sram_parameters(struct target *target, uint32_t *pSram, 
uint32_t *pStart)
+{
+       if (pSram < pStart) {
+               LOG_DEBUG("sram pointer %p less than start address %p",
+                       pSram, pStart);
+               return 1;
+       }
+       while (pSram > pStart)
+               target_write_u32(target, (uintptr_t)-- pSram, 0);
+       return 0;
+}
+
+/** Load bootloader arguments into SRAM. */
+static uint32_t *setupSram(struct target *target, int width, uint32_t 
arr[width])
+{
+       uint32_t *pSramRetval = NULL, *pSram = SRAM_PARAM_START;
+       int retval;
+
+       for (int i = 0; i < width; i++) {
+#if _DEBUG_FLASHCMD_EXECUTION_ == 1
+               LOG_INFO("pSram[0x%X] 0x%X", (uint32_t)(uintptr_t)pSram, 
arr[i]);
+#endif
+               if (arr[i] == BREAKPOINT)
+                       pSramRetval = pSram;
+               retval = target_write_u32(target, pSRAM, arr[i]);
+               CHECK_STATUS(retval, "error writing bootloader SRAM 
parameters.");
+               if (retval != ERROR_OK) {
+                       pSramRetval = 0;
+                       break;
+               }
+       }
+#if _DEBUG_FLASHCMD_EXECUTION_ == 1
+       LOG_INFO("pSram[pSramRetval] 0x%X", (uint32_t)(uintptr_t)pSramRetval);
+#endif
+       return pSramRetval;
 }
+
 /** Read flash status from bootloader. */
-static int check_flash_status(struct target *target, uint32_t address)
+static int check_flash_status(struct target *target, uint32_t *address)
 {
        uint32_t retflash;
        int rc;
-       rc = target_read_u32(target, address, &retflash);
+       rc = target_read_u32(target, (uintptr_t)address, &retflash);
        /* target connection failed. */
        if (rc != ERROR_OK) {
                LOG_DEBUG("%s:%d:%s(): status(0x%x)\n",
@@ -311,12 +609,24 @@ static int check_flash_status(struct target *target, 
uint32_t address)
        return ERROR_OK;
 }
 
+/** Execute bootloader command with SRAM parameters. */
 static int ambiqmicro_exec_command(struct target *target,
        uint32_t command,
-       uint32_t flash_return_address)
+       uint32_t *flash_return_address)
 {
        int retval, retflash;
 
+#if _DEBUG_FLASHCMD_EXECUTION_ == 1
+       LOG_INFO("pROM[Bootloader] 0x%X", command);
+#endif
+
+       /* Commands invalid for this chip will come across as 0. */
+       if (!command) {
+               LOG_ERROR("Invalid command for this target.");
+               return ERROR_FAIL;
+       }
+
+       /* Call bootloader */
        retval = target_resume(
                target,
                false,
@@ -327,6 +637,11 @@ static int ambiqmicro_exec_command(struct target *target,
        CHECK_STATUS(retval, "error executing ambiqmicro command");
 
        /*
+        * Clear Sram Parameters before first return.
+        */
+       clear_sram_parameters(target, flash_return_address, SRAM_PARAM_START);
+
+       /*
         * Wait for halt.
         */
        for (;; ) {
@@ -353,152 +668,234 @@ static int ambiqmicro_exec_command(struct target 
*target,
        retflash = check_flash_status(target, flash_return_address);
        if (retflash != ERROR_OK)
                retval = retflash;
+#if _DEBUG_FLASHCMD_EXECUTION_ == 1
+       LOG_INFO("pSram[0x%X] 0x%X", (uint32_t)(uintptr_t)flash_return_address, 
retflash);
+#endif
 
        /* Return code from target_resume OR flash. */
        return retval;
 }
 
-static int ambiqmicro_mass_erase(struct flash_bank *bank)
+static int ambiqmicro_exec_sram_command(struct flash_bank *bank, uint32_t 
command,
+       int width, uint32_t arr[])
 {
-       struct target *target = NULL;
-       struct ambiqmicro_flash_bank *ambiqmicro_info = NULL;
-       int retval = ERROR_OK;
+       uint32_t *bootloader_return_address;
+       int retval;
 
-       ambiqmicro_info = bank->driver_priv;
-       target = bank->target;
+       retval = target_ready_for_command(bank);
+       if (retval != ERROR_OK)
+               return retval;
 
-       if (target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
+       /*
+        * Load SRAM parameters.
+        */
+       bootloader_return_address = setupSram(bank->target, width, arr);
 
-       if (ambiqmicro_info->probed == 0) {
-               LOG_ERROR("Target not probed");
-               return ERROR_FLASH_BANK_NOT_PROBED;
-       }
+       /*
+        * Execute Bootloader command.
+        */
+       retval = ambiqmicro_exec_command(bank->target, command, 
bootloader_return_address);
+       return retval;
+}
+
+static int ambiqmicro_exec_main_command(struct flash_bank *bank, uint32_t 
command,
+       int width, uint32_t arr[])
+{
+       int retval, retval1;
+
+       retval = target_ready_for_command(bank);
+       if (retval != ERROR_OK)
+               return retval;
 
        /*
         * Clear Bootloader bit.
         */
-       retval = target_write_u32(target, 0x400201a0, 0x0);
+       retval = target_write_u32(bank->target, REG_CONTROL_BOOTLOADERLOW, 0x0);
        CHECK_STATUS(retval, "error clearing bootloader bit.");
 
        /*
-        * Set up the SRAM.
+        * Execute the command.
         */
+       retval = ambiqmicro_exec_sram_command(bank, command, width, arr);
 
        /*
-        * Bank.
+        * Set Bootloader bit, regardless of command execution.
         */
-       retval = target_write_u32(target, 0x10000000, bank->bank_number);
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
+       retval1 = target_write_u32(bank->target, REG_CONTROL_BOOTLOADERLOW, 
0x1);
+       CHECK_STATUS(retval1, "error setting bootloader bit.");
+
+       return retval;
+}
+
+/** Power On Internal (POI). */
+static int ambiqmicro_poi(struct flash_bank *bank)
+{
+       struct target *target = bank->target;
+       struct cortex_m_common *cortex_m = target_to_cm(target);
+       int retval;
 
        /*
-        * Write Key.
+        * Clear Reset Status.
         */
-       retval = target_write_u32(target, 0x10000004, PROGRAM_KEY);
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
+       retval = target_write_u32(target, RSTGEN_CLRSTAT, RSTGEN_CLRKEY);
+       CHECK_STATUS(retval, "error clearing rstgen status.");
 
        /*
-        * Breakpoint.
+        * POI
         */
-       retval = target_write_u32(target, 0x10000008, 0xfffffffe);
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
+       retval = target_write_u32(target, RSTGEN_POI, RSTGEN_POIKEY);
+       CHECK_STATUS(retval, "error writing POI register.");
+       LOG_INFO("Power On Internal issued.");
+
+       target->state = TARGET_RESET;
+
+       /* registers are now invalid */
+       register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
+
+       return retval;
+}
+
+/** Power On Reset (POR). */
+static int ambiqmicro_por(struct flash_bank *bank)
+{
+       struct target *target = bank->target;
+       struct cortex_m_common *cortex_m = target_to_cm(target);
+       uint32_t rstgen_stat = 0;
+       int retval, timeout = 0;
 
        /*
-        * Erase the main array.
+        * Clear Reset Status.
         */
-       LOG_INFO("Mass erase on bank %d.", bank->bank_number);
+       retval = target_write_u32(target, RSTGEN_CLRSTAT, RSTGEN_CLRKEY);
+       CHECK_STATUS(retval, "error clearing rstgen status.");
 
        /*
-        * passed pc, addr = ROM function, handle breakpoints, not debugging.
+        * POR
         */
-       retval = ambiqmicro_exec_command(target, 
FLASH_MASS_ERASE_MAIN_PAGES_FROM_SRAM, 0x10000008);
-       CHECK_STATUS(retval, "error executing ambiqmicro flash mass erase.");
-       if (retval != ERROR_OK)
-               return retval;
+       retval = target_write_u32(target, RSTGEN_POR, RSTGEN_PORKEY);
+       CHECK_STATUS(retval, "error writing POR register.");
+       LOG_INFO("Power On Reset issued.");
+
+       target->state = TARGET_RESET;
+
+       /* registers are now invalid */
+       register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
 
        /*
-        * Set Bootloader bit, regardless of command execution.
+        * Check if POR occurred (delay is needed.)
         */
-       retval = target_write_u32(target, 0x400201a0, 0x1);
-       CHECK_STATUS(retval, "error setting bootloader bit.");
-
+       while (timeout < 20) {
+               retval = target_read_u32(target, RSTGEN_STAT, &rstgen_stat);
+               CHECK_STATUS(retval, "error reading reset status.");
+               alive_sleep(100);
+               rstgen_stat &= (RSTGEN_PORSTAT + RSTGEN_SWRSTAT);
+               if ((retval == ERROR_OK) && rstgen_stat) {
+                       retval = ERROR_OK;
+                       break;
+               } else
+                       retval = ERROR_TARGET_FAILURE;
+               timeout++;
+       }
+       LOG_DEBUG("RSTGEN_STAT %d", rstgen_stat);
        return retval;
 }
 
-
-static int ambiqmicro_erase(struct flash_bank *bank, int first, int last)
+static int ambiqmicro_protect_check(struct flash_bank *bank)
 {
-       struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;
-       struct target *target = bank->target;
-       uint32_t retval = ERROR_OK;
-
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
+       struct ambiqmicro_flash_bank *ambiqmicro = bank->driver_priv;
+       int i, status = ERROR_OK;
 
-       if (ambiqmicro_info->probed == 0) {
+       if (ambiqmicro->probed == 0) {
                LOG_ERROR("Target not probed");
                return ERROR_FLASH_BANK_NOT_PROBED;
        }
 
-       /*
-        * Check pages.
-        * Fix num_pages for the device.
-        */
-       if ((first < 0) || (last < first) || (last >= 
(int)ambiqmicro_info->num_pages))
-               return ERROR_FLASH_SECTOR_INVALID;
+       for (i = 0; i < bank->num_sectors; i++)
+               bank->sectors[i].is_protected = -1;
 
-       /*
-        * Just Mass Erase if all pages are given.
-        * TODO: Fix num_pages for the device
-        */
-       if ((first == 0) && (last == ((int)ambiqmicro_info->num_pages-1)))
-               return ambiqmicro_mass_erase(bank);
+       return status;
+}
+
+/** Erase flash bank. */
+static int ambiqmicro_mass_erase(struct flash_bank *bank)
+{
+       int retval;
 
-       /*
-        * Clear Bootloader bit.
-        */
-       retval = target_write_u32(target, 0x400201a0, 0x0);
-       CHECK_STATUS(retval, "error clearing bootloader bit.");
 
        /*
         * Set up the SRAM.
+        *          0x10000000    pointer in to flash instance #
+        *          0x10000004    customer value to pass to flash helper routine
+        *          0x10000008    return code debugger sets this to -1 all RCs 
are >= 0
         */
+       uint32_t sramargs[] = {
+               bank->bank_number,
+               PROGRAM_KEY,
+               BREAKPOINT,
+       };
 
        /*
-        * Bank.
+        * Erase the main array.
         */
-       retval = target_write_u32(target, 0x10000000, bank->bank_number);
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
+       LOG_INFO("Mass erase on bank %d.", bank->bank_number);
 
        /*
-        * Number of pages to erase.
+        * passed pc, addr = ROM function, handle breakpoints, not debugging.
         */
-       retval = target_write_u32(target, 0x10000004, 1 + (last-first));
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
+       retval = ambiqmicro_exec_main_command(bank, 
name_t.flash_mass_erase_from_sram,
+               (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
+
+
+       /* if successful, set all sectors as erased */
+       if (retval == ERROR_OK)
+               write_is_erased(bank, 0, bank->num_sectors, 1);
+
+       return retval;
+}
+
+/** Erase flash pages (Apollo and Apollo2).
+@param bank Flash bank to use.
+@param first Start page.
+@param last Ending page.
+*/
+static int ambiqmicro_page_erase(struct flash_bank *bank, int first, int last)
+{
+       struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;
+       int retval;
 
        /*
-        * Write Key.
+        * Check pages.
+        * Fix num_pages for the device.
         */
-       retval = target_write_u32(target, 0x10000008, PROGRAM_KEY);
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
+       if ((first < 0) || (last < first) || (last >= 
(int)ambiqmicro_info->num_pages))
+               return ERROR_FLASH_SECTOR_INVALID;
 
        /*
-        * Breakpoint.
+        * Just Mass Erase if all pages are given.
+        * TODO: Fix num_pages for the device
         */
-       retval = target_write_u32(target, 0x1000000c, 0xfffffffe);
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
+       if ((first == 0) && (last == ((int)ambiqmicro_info->num_pages-1)))
+               return ambiqmicro_mass_erase(bank);
 
        /*
-        * Pointer to flash address.
+        * Set up the SRAM.
+        * Calling this function looks up page erase information from offset 
0x0 in SRAM
+        *          0x10000000  instance number
+        *          0x10000004  number of main block pages to erase  must be 
between 1 and 128 inclusive
+        *                      0 < number < 129
+        *          0x10000008  PROGRAM key to pass to flash helper routine
+        *          0x1000000C  return code debugger sets this to -1 all RCs 
are >= 0
+        *          0x10000010  PageNumber of the first flash page to erase.
+        *                      NOTE: these *HAVE* to be sequential range 0 <= 
PageNumber <= 127
         */
-       retval = target_write_u32(target, 0x10000010, first);
-       CHECK_STATUS(retval, "error writing target SRAM parameters.");
-       if (retval != ERROR_OK)
-               return retval;
+
+       uint32_t sramargs[] = {
+               bank->bank_number,
+               (1 + (last-first)),     /* Number of pages to erase. */
+               PROGRAM_KEY,
+               BREAKPOINT,
+               first,
+       };
 
        /*
         * Erase the pages.
@@ -506,28 +903,37 @@ static int ambiqmicro_erase(struct flash_bank *bank, int 
first, int last)
        LOG_INFO("Erasing pages %d to %d on bank %d", first, last, 
bank->bank_number);
 
        /*
+        * Clear Bootloader bit.
+        */
+       retval = target_write_u32(bank->target, REG_CONTROL_BOOTLOADERLOW, 0x0);
+       CHECK_STATUS(retval, "error clearing bootloader bit.");
+
+       /*
         * passed pc, addr = ROM function, handle breakpoints, not debugging.
         */
-       retval = ambiqmicro_exec_command(target, 
FLASH_ERASE_LIST_MAIN_PAGES_FROM_SRAM, 0x1000000C);
+       retval = ambiqmicro_exec_sram_command(bank,
+               name_t.flash_erase_main_pages_from_sram,
+               (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
        CHECK_STATUS(retval, "error executing flash page erase");
-       if (retval != ERROR_OK)
-               return retval;
-
-       LOG_INFO("%d pages erased!", 1+(last-first));
 
+       /* If we erased the interrupt area, provide the bootloader interrupt 
table. */
        if (first == 0) {
                /*
                 * Set Bootloader bit.
                 */
-               retval = target_write_u32(target, 0x400201a0, 0x1);
-               CHECK_STATUS(retval, "error setting bootloader bit.");
-               if (retval != ERROR_OK)
-                       return retval;
+               int retval1 = target_write_u32(bank->target, 
REG_CONTROL_BOOTLOADERLOW, 0x1);
+               CHECK_STATUS(retval1, "error setting bootloader bit.");
+       }
+
+       if (retval == ERROR_OK) {
+               LOG_INFO("%d pages erased!", 1+(last-first));
+               write_is_erased(bank, first, last, 1);
        }
 
        return retval;
 }
 
+/** Write protect sectors of flash. */
 static int ambiqmicro_protect(struct flash_bank *bank, int set, int first, int 
last)
 {
        /* struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;
@@ -536,39 +942,37 @@ static int ambiqmicro_protect(struct flash_bank *bank, 
int set, int first, int l
        /*
         * TODO
         */
-       LOG_INFO("Not yet implemented");
+       LOG_WARNING("Not yet implemented");
 
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
+
+       if (!set) {
+               LOG_ERROR("Hardware doesn't support page-level unprotect. "
+                       "Try the 'recover' command.");
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
+
        return ERROR_OK;
 }
 
+/** Flash write to main. Apollo and Apollo2. */
 static int ambiqmicro_write_block(struct flash_bank *bank,
        const uint8_t *buffer, uint32_t offset, uint32_t count)
 {
        /* struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; */
        struct target *target = bank->target;
        uint32_t address = bank->base + offset;
-       uint32_t buffer_pointer = 0x10000010;
-       uint32_t maxbuffer;
+       uint32_t buffer_pointer = name_t.write_buffer_start;
+       uint32_t maxbuffer = name_t.write_buffer_size;
        uint32_t thisrun_count;
-       int retval = ERROR_OK;
+       int retval;
 
        if (((count%4) != 0) || ((offset%4) != 0)) {
                LOG_ERROR("write block must be multiple of 4 bytes in offset & 
length");
                return ERROR_FAIL;
        }
 
-       /*
-        * Max buffer size for this device.
-        * Hard code 6kB for the buffer.
-        */
-       maxbuffer = 0x1800;
-
-       LOG_INFO("Flashing main array");
+       LOG_INFO("Flashing main array 0x%x", buffer_pointer);
 
        while (count > 0) {
                if (count > maxbuffer)
@@ -578,45 +982,37 @@ static int ambiqmicro_write_block(struct flash_bank *bank,
 
                /*
                 * Set up the SRAM.
+                * Calling this function looks up programming information from 
offset 0x0 in SRAM
+                *          0x10000000  pointer in to flash
+                *          0x10000004  number of 32-bit words to program
+                *          0x10000008  customer program key to pass to flash 
helper routine
+                *          0x1000000C  return code debugger sets this to -1 
all RCs are >= 0
+                *
+                *          0x10000010  Apollo  first 32-bit word of data 
buffer.
+                *          0x10001000  Apollo2 first 32-bit word of data 
buffer (WRITE_BUFFER_START)
                 */
 
-               /*
-                * Pointer to flash.
-                */
-               retval = target_write_u32(target, 0x10000000, address);
-               CHECK_STATUS(retval, "error writing target SRAM parameters.");
-
-               /*
-                * Number of 32-bit words to program.
-                */
-               retval = target_write_u32(target, 0x10000004, thisrun_count/4);
-               CHECK_STATUS(retval, "error writing target SRAM parameters.");
-
-               /*
-                * Write Key.
-                */
-               retval = target_write_u32(target, 0x10000008, PROGRAM_KEY);
-               CHECK_STATUS(retval, "error writing target SRAM parameters.");
-
-               /*
-                * Breakpoint.
-                */
-               retval = target_write_u32(target, 0x1000000c, 0xfffffffe);
-               CHECK_STATUS(retval, "error writing target SRAM parameters.");
+               uint32_t sramargs[] = {
+                       address,
+                       thisrun_count/4,
+                       PROGRAM_KEY,
+                       BREAKPOINT,
+               };
 
                /*
                 * Write Buffer.
                 */
                retval = target_write_buffer(target, buffer_pointer, 
thisrun_count, buffer);
-
                if (retval != ERROR_OK) {
-                       CHECK_STATUS(retval, "error writing target SRAM 
parameters.");
+                       CHECK_STATUS(retval, "error writing target SRAM write 
buffer.");
                        break;
                }
 
                LOG_DEBUG("address = 0x%08x", address);
 
-               retval = ambiqmicro_exec_command(target, 
FLASH_PROGRAM_MAIN_FROM_SRAM, 0x1000000c);
+               retval = ambiqmicro_exec_sram_command(bank,
+                       name_t.flash_program_main_from_sram,
+                       (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
                CHECK_STATUS(retval, "error executing ambiqmicro flash write 
algorithm");
                if (retval != ERROR_OK)
                        break;
@@ -625,41 +1021,42 @@ static int ambiqmicro_write_block(struct flash_bank 
*bank,
                count -= thisrun_count;
        }
 
-
        LOG_INFO("Main array flashed");
 
        /*
         * Clear Bootloader bit.
         */
-       retval = target_write_u32(target, 0x400201a0, 0x0);
-       CHECK_STATUS(retval, "error clearing bootloader bit");
+       int retval1 = target_write_u32(target, REG_CONTROL_BOOTLOADERLOW, 0x0);
+       CHECK_STATUS(retval1, "error clearing bootloader bit");
 
        return retval;
 }
 
+/** Flash write bytes, address count. */
 static int ambiqmicro_write(struct flash_bank *bank, const uint8_t *buffer,
        uint32_t offset, uint32_t count)
 {
-       uint32_t retval;
+       int retval;
 
        /* try using a block write */
        retval = ambiqmicro_write_block(bank, buffer, offset, count);
        if (retval != ERROR_OK)
-               LOG_ERROR("write failed");
+               LOG_ERROR("write block failed.");
 
        return retval;
 }
 
+/** Probe part info and flash banks. */
 static int ambiqmicro_probe(struct flash_bank *bank)
 {
        struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;
-       uint32_t retval;
+       int retval;
 
        /* If this is a ambiqmicro chip, it has flash; probe() is just
         * to figure out how much is present.  Only do it once.
         */
        if (ambiqmicro_info->probed == 1) {
-               LOG_INFO("Target already probed");
+               LOG_INFO("Target already probed.");
                return ERROR_OK;
        }
 
@@ -679,12 +1076,17 @@ static int ambiqmicro_probe(struct flash_bank *bank)
        /* provide this for the benefit of the NOR flash framework */
        bank->size = ambiqmicro_info->pagesize * ambiqmicro_info->num_pages;
        bank->num_sectors = ambiqmicro_info->num_pages;
-       bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
+       bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
        for (int i = 0; i < bank->num_sectors; i++) {
                bank->sectors[i].offset = i * ambiqmicro_info->pagesize;
                bank->sectors[i].size = ambiqmicro_info->pagesize;
                bank->sectors[i].is_erased = -1;
                bank->sectors[i].is_protected = -1;
+               LOG_DEBUG("bank->sectors[%d], offset 0x%x, size %d.",
+                       i,
+                       bank->sectors[i].offset,
+                       bank->sectors[i].size);
+
        }
 
        /*
@@ -695,89 +1097,258 @@ static int ambiqmicro_probe(struct flash_bank *bank)
        return retval;
 }
 
-static int ambiqmicro_otp_program(struct flash_bank *bank,
+/** Flash write to info space [APOLLO2].
+@param flash_bank bank.
+@param uint offset.
+@param uint count.
+@param uint instance.
+ */
+static int ambiqmicro_program_info(struct flash_bank *bank,
        uint32_t offset, uint32_t count)
 {
-       struct target *target = NULL;
-       struct ambiqmicro_flash_bank *ambiqmicro_info = NULL;
-       uint32_t retval = ERROR_OK;
-
-       ambiqmicro_info = bank->driver_priv;
-       target = bank->target;
+       int retval;
 
-       if (target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
+       /* Apollo=2048/4 = 512, Apollo2=8192/4 = 2048 */
+       if (count > name_t.info_space_size) {
+               LOG_ERROR("Count must be < %d", name_t.info_space_size);
+               return ERROR_FAIL;
        }
 
-       if (ambiqmicro_info->probed == 0) {
-               LOG_ERROR("Target not probed");
-               return ERROR_FLASH_BANK_NOT_PROBED;
-       }
+       /*
+        * Set up the SRAM.
+        * Calling this function looks up programming information from offset 
0x0 in SRAM
+        *          0x10000000  Word offset in to FLASH INFO block
+        *                      0 <= Offset < 2048
+        *          0x10000004  Instance
+        *          0x10000008  number of 32-bit words to program
+        *          0x1000000C  customer program key to pass to flash helper 
routine
+        *          0x10000010  return code debugger sets this to -1 all RCs 
are >= 0
+        *
+        *          0x10001000  first 32-bit word of data buffer to be 
programmed (WRITE_BUFFER_START)
+        */
+       uint32_t sramargs[] = {
+               offset,
+               bank->bank_number,
+               count,
+               PROGRAM_KEY,
+               BREAKPOINT,
+       };
 
-       if (count > 256) {
-               LOG_ERROR("Count must be < 256");
+       /*
+        * Program Info.
+        */
+       LOG_INFO("Programming Info\n\toffset=0x%08x\n\tinstance=0x%08x",
+               offset,
+               bank->bank_number);
+
+       /*
+        * passed pc, addr = ROM function, handle breakpoints, not debugging.
+        */
+       retval = ambiqmicro_exec_sram_command(bank, 
name_t.flash_program_info_from_sram,
+               (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
+       CHECK_STATUS(retval, "error programming info.");
+
+       LOG_INFO("Programming Info finished.");
+
+       return retval;
+}
+
+/** Flash write to Apollo OTP space.
+@param flash_bank bank.
+@param uint offset.
+@param uint count.
+ */
+static int ambiqmicro_otp_program(struct flash_bank *bank,
+       uint32_t offset, uint32_t count)
+{
+       int retval;
+
+       if (count > name_t.info_space_size) {
+               LOG_ERROR("Count must be < %d words.", name_t.info_space_size);
                return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
        }
 
        /*
-        * Clear Bootloader bit.
+        * Set up the SRAM.
+        * Calling this function looks up programming information from offset 
0x0 in SRAM
+        *          0x10000000   Offset in to FLASH INFO block (customer 
version limited to second half)
+        *                       0 <= Offset < 256
+        *                       256 added to offset before programming
+        *          0x10000004   number of 32-bit words to program
+        *          0x10000008   OTP program key to pass to flash helper routine
+        *          0x1000000C   return code debugger sets this to -1 all RCs 
are >= 0
+        *
+        *          0x10000010   first 32-bit word of data buffer to be 
programmed
         */
-       retval = target_write_u32(target, 0x400201a0, 0x0);
-       CHECK_STATUS(retval, "error clearing bootloader bit.");
+       uint32_t sramargs[] = {
+               offset,
+               count,
+               OTP_PROGRAM_KEY,
+               BREAKPOINT,
+       };
 
        /*
-        * Set up the SRAM.
+        * Program OTP INFO.
         */
+       LOG_INFO("Programming OTP offset 0x%08x", offset);
+
+       /*
+        * passed pc, addr = ROM function, handle breakpoints, not debugging.
+        */
+       retval = ambiqmicro_exec_sram_command(bank, 
name_t.flash_program_otp_from_sram,
+               (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
+       CHECK_STATUS(retval, "error executing ambiqmicro otp program 
algorithm");
+
+       LOG_INFO("Programming OTP finished.");
+
+       return retval;
+}
+
+/** Extended recover and erase for bricked devices [APOLLO2]. */
+static int ambiqmicro_recover(struct flash_bank *bank)
+{
+       int retval;
 
        /*
-        * Bank.
+        * Set up the SRAM.
+        * Calling this function looks up programming information from offset 
0x0 in SRAM
+        *          0x10000000   key value to enable recovery
+        *          0x10000004   return code
         */
-       retval = target_write_u32(target, 0x10000000, offset);
-       CHECK_STATUS(retval, "error setting target SRAM parameters.");
+       uint32_t sramargs[] = {
+               BRICK_KEY,
+               BREAKPOINT,
+       };
 
        /*
-        * Num of words to program.
+        * Erase the main array.
         */
-       retval = target_write_u32(target, 0x10000004, count);
-       CHECK_STATUS(retval, "error setting target SRAM parameters.");
+       LOG_INFO("Recovering Device started.");
 
        /*
-        * Write Key.
+        * passed pc, addr = ROM function, handle breakpoints, not debugging.
         */
-       retval = target_write_u32(target, 0x10000008, OTP_PROGRAM_KEY);
-       CHECK_STATUS(retval, "error setting target SRAM parameters.");
+       retval = ambiqmicro_exec_sram_command(bank, 
name_t.flash_recovery_from_sram,
+               (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
+       CHECK_STATUS(retval, "error executing ambiqmicro recovery");
+
+       LOG_INFO("Recovering Device finished.");
+
+       return retval;
+}
+
+/** Erase info space. [APOLLO2] */
+static int ambiqmicro_info_erase(struct flash_bank *bank)
+{
+       int retval;
 
        /*
-        * Breakpoint.
+        * Set up the SRAM.
+        * Calling this function looks up programming information from offset 
0x0 in SRAM
+        *          0x10000000  Flash Instance
+        *          0x10000004  CUSTOMER KEY value to pass to flash helper 
routine
+        *          0x10000008  return code debugger sets this to -1 all RCs 
are >= 0
         */
-       retval = target_write_u32(target, 0x1000000c, 0xfffffffe);
-       CHECK_STATUS(retval, "error setting target SRAM parameters.");
-       if (retval != ERROR_OK)
-               return retval;
+       uint32_t sramargs[] = {
+               bank->bank_number,
+               CUSTOMER_PROGRAM_KEY,
+               BREAKPOINT,
+       };
 
        /*
-        * Program OTP.
+        * Erase the main array.
         */
-       LOG_INFO("Programming OTP offset 0x%08x", offset);
+       LOG_INFO("Erasing Info started.");
 
        /*
         * passed pc, addr = ROM function, handle breakpoints, not debugging.
         */
-       retval = ambiqmicro_exec_command(target, FLASH_PROGRAM_OTP_FROM_SRAM, 
0x1000000C);
-       CHECK_STATUS(retval, "error executing ambiqmicro otp program 
algorithm");
+       retval = ambiqmicro_exec_sram_command(bank,
+               name_t.flash_info_erase_from_sram,
+               (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
+       CHECK_STATUS(retval, "error flash info erase from sram.");
 
-       LOG_INFO("Programming OTP finished.");
+       LOG_INFO("Erasing Info complete.");
 
        return retval;
 }
 
+/** Erase info space + main. [APOLLO2] */
+static int ambiqmicro_info_plus_main_erase(struct flash_bank *bank)
+{
+       int retval;
 
+       /*
+        * Set up the SRAM.
+        * Calling this function looks up programming information from offset 
0x0 in SRAM
+        *          0x10000000  Flash Instance
+        *          0x10000004  Customer KEY value to pass to flash helper 
routine
+        *          0x10000008  return code debugger sets this to -1 all RCs 
are >= 0
+        */
+       uint32_t sramargs[] = {
+               bank->bank_number,
+               PROGRAM_KEY,
+               BREAKPOINT,
+       };
 
-COMMAND_HANDLER(ambiqmicro_handle_mass_erase_command)
+       /*
+        * Erase the main plus info array.
+        */
+       LOG_INFO("Erasing Info plus Main started.");
+       retval = ambiqmicro_exec_main_command(bank, 
name_t.flash_info_plus_main_erase_from_sram,
+               (sizeof(sramargs)/sizeof(sramargs[0])), sramargs);
+       CHECK_STATUS(retval, "error flash info plus main erase from sram.");
+
+       /* if successful, set all sectors as erased. */
+       if (retval == ERROR_OK)
+               write_is_erased(bank, 0, bank->num_sectors, 1);
+
+       LOG_INFO("Erasing Info plus Main complete.");
+
+       return retval;
+}
+
+
+COMMAND_HANDLER(ambiqmicro_handle_poi_command)
 {
-       int i;
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct flash_bank *bank = get_flash_bank_by_num_noprobe(0);
+       if (!bank)
+               return ERROR_FAIL;
+       int retval = ambiqmicro_poi(bank);
+       if (retval == ERROR_OK)
+               command_print(CMD_CTX, "ambiqmicro power on internal complete");
+       else {
+               command_print(CMD_CTX, "ambiqmicro power on internal failed");
+               LOG_DEBUG("ambiqmicro_poi: %d", retval);
+       }
+
+       return ERROR_OK;
+}
 
+COMMAND_HANDLER(ambiqmicro_handle_por_command)
+{
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct flash_bank *bank = get_flash_bank_by_num_noprobe(0);
+       if (!bank)
+               return ERROR_FAIL;
+       int retval = ambiqmicro_por(bank);
+       if (retval == ERROR_OK)
+               command_print(CMD_CTX, "ambiqmicro power on reset complete");
+       else {
+               command_print(CMD_CTX, "ambiqmicro power on reset failed");
+               LOG_DEBUG("ambiqmicro_por: %d", retval);
+       }
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(ambiqmicro_handle_mass_erase_command)
+{
        if (CMD_ARGC < 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
@@ -786,13 +1357,9 @@ COMMAND_HANDLER(ambiqmicro_handle_mass_erase_command)
        if (ERROR_OK != retval)
                return retval;
 
-       if (ambiqmicro_mass_erase(bank) == ERROR_OK) {
-               /* set all sectors as erased */
-               for (i = 0; i < bank->num_sectors; i++)
-                       bank->sectors[i].is_erased = 1;
-
+       if (ambiqmicro_mass_erase(bank) == ERROR_OK)
                command_print(CMD_CTX, "ambiqmicro mass erase complete");
-       } else
+       else
                command_print(CMD_CTX, "ambiqmicro mass erase failed");
 
        return ERROR_OK;
@@ -814,7 +1381,7 @@ COMMAND_HANDLER(ambiqmicro_handle_page_erase_command)
        if (ERROR_OK != retval)
                return retval;
 
-       if (ambiqmicro_erase(bank, first, last) == ERROR_OK)
+       if (ambiqmicro_page_erase(bank, first, last) == ERROR_OK)
                command_print(CMD_CTX, "ambiqmicro page erase complete");
        else
                command_print(CMD_CTX, "ambiqmicro page erase failed");
@@ -822,10 +1389,7 @@ COMMAND_HANDLER(ambiqmicro_handle_page_erase_command)
        return ERROR_OK;
 }
 
-
-/**
- * Program the otp block.
- */
+/** Program the otp block. */
 COMMAND_HANDLER(ambiqmicro_handle_program_otp_command)
 {
        struct flash_bank *bank;
@@ -849,11 +1413,95 @@ COMMAND_HANDLER(ambiqmicro_handle_program_otp_command)
 
        return ERROR_OK;
 }
+/** Program the Apollo2 info block. */
+COMMAND_HANDLER(ambiqmicro_handle_program_info_command)
+{
+       struct flash_bank *bank;
+       uint32_t offset, count;
+
+       if (CMD_ARGC < 3)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], offset);
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
+
+       command_print(CMD_CTX, "offset=0x%08x count=%d", offset, count);
+
+       CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+
+       ambiqmicro_program_info(bank, offset, count);
+
+       return ERROR_OK;
+}
+/**
+ * Perform the APOLLO2 Recovering a Locked Device procedure.
+ * This performs a mass erase and then restores all nonvolatile registers
+ * (including flash lock bits) to their defaults.
+ * Accordingly, flash can be reprogrammed, and SWD can be used.
+ */
+COMMAND_HANDLER(ambiqmicro_handle_recover_command)
+{
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct flash_bank *bank = get_flash_bank_by_num_noprobe(0);
+       if (!bank)
+               return ERROR_FAIL;
+
+       ambiqmicro_recover(bank);
+
+       return ERROR_OK;
+}
+
+/** Erase the info block. [APOLLO2] */
+COMMAND_HANDLER(ambiqmicro_handle_erase_info_command)
+{
+       if (CMD_ARGC < 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
+       struct flash_bank *bank;
+       uint32_t retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, 
&bank);
+       if (ERROR_OK != retval)
+               return retval;
+
+       ambiqmicro_info_erase(bank);
+
+       return ERROR_OK;
+}
+
+/** Erase the info plus main block. [APOLLO2] */
+COMMAND_HANDLER(ambiqmicro_handle_erase_info_plus_main_command)
+{
+       if (CMD_ARGC < 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct flash_bank *bank;
+       uint32_t retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, 
&bank);
+       if (ERROR_OK != retval)
+               return retval;
+
+       ambiqmicro_info_plus_main_erase(bank);
+
+       return ERROR_OK;
+}
 
 
 static const struct command_registration ambiqmicro_exec_command_handlers[] = {
        {
+               .name = "poi",
+               .usage = "Power On Internal.",
+               .handler = ambiqmicro_handle_poi_command,
+               .mode = COMMAND_EXEC,
+               .help = "Send POI to target.",
+       },
+       {
+               .name = "por",
+               .usage = "Power On Reset.",
+               .handler = ambiqmicro_handle_por_command,
+               .mode = COMMAND_EXEC,
+               .help = "Send POR to target.",
+       },
+       {
                .name = "mass_erase",
                .usage = "<bank>",
                .handler = ambiqmicro_handle_mass_erase_command,
@@ -865,7 +1513,7 @@ static const struct command_registration 
ambiqmicro_exec_command_handlers[] = {
                .usage = "<bank> <first> <last>",
                .handler = ambiqmicro_handle_page_erase_command,
                .mode = COMMAND_EXEC,
-               .help = "Erase device pages",
+               .help = "Erase flash pages.",
        },
        {
                .name = "program_otp",
@@ -873,16 +1521,53 @@ static const struct command_registration 
ambiqmicro_exec_command_handlers[] = {
                .mode = COMMAND_EXEC,
                .usage = "<bank> <offset> <count>",
                .help =
-                       "Program OTP (assumes you have already written array 
starting at 0x10000010)",
+                       "Program OTP is a one time operation to create write 
protected flash [APOLLO ONLY]. "
+                       "The caller writes sectors to sram starting at 
0x10000010. "
+                       "Program OTP will write sectors from sram to flash, "
+                       "and write protect the flash. "
+                       "The flash protection is permanent. "
+                       "There is no way to erase and re-program once this 
command is used.",
+       },
+       {
+               .name = "program_info",
+               .handler = ambiqmicro_handle_program_info_command,
+               .mode = COMMAND_EXEC,
+               .usage = "<bank> <offset> <count>",
+               .help =
+                       "Program INFO will write sectors from sram to flash, "
+                       "and write protect the flash. [APOLLO2 ONLY]. "
+                       "The sram buffer starts at 0x10001000.",
+       },
+       {
+               .name = "recover",
+               .handler = ambiqmicro_handle_recover_command,
+               .mode = COMMAND_EXEC,
+               .usage = "",
+               .help = "recover and erase locked device [APOLLO2 ONLY]",
+       },
+       {
+               .name = "erase_info",
+               .handler = ambiqmicro_handle_erase_info_command,
+               .mode = COMMAND_EXEC,
+               .usage = "<bank>>",
+               .help = "erase info block [APOLLO2 ONLY]",
+       },
+       {
+               .name = "erase_info_plus_main",
+               .handler = ambiqmicro_handle_erase_info_plus_main_command,
+               .mode = COMMAND_EXEC,
+               .usage = "<bank>",
+               .help = "erase info plus main block [APOLLO2 ONLY]",
        },
        COMMAND_REGISTRATION_DONE
 };
+
 static const struct command_registration ambiqmicro_command_handlers[] = {
        {
                .name = "ambiqmicro",
                .mode = COMMAND_EXEC,
                .help = "ambiqmicro flash command group",
-               .usage = "Support for Ambiq Micro parts.",
+               .usage = "Support for Apollo Ultra Low Power parts.",
                .chain = ambiqmicro_exec_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
@@ -892,13 +1577,13 @@ struct flash_driver ambiqmicro_flash = {
        .name = "ambiqmicro",
        .commands = ambiqmicro_command_handlers,
        .flash_bank_command = ambiqmicro_flash_bank_command,
-       .erase = ambiqmicro_erase,
-       .protect = ambiqmicro_protect,
+       .erase = ambiqmicro_page_erase,
        .write = ambiqmicro_write,
        .read = default_flash_read,
        .probe = ambiqmicro_probe,
        .auto_probe = ambiqmicro_probe,
        .erase_check = default_flash_blank_check,
-       .protect_check = ambiqmicro_protect_check,
        .info = get_ambiqmicro_info,
+       .protect_check = ambiqmicro_protect_check,
+       .protect = ambiqmicro_protect,
 };

-- 

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity 
planning reports. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to