]> git.sur5r.net Git - openocd/blobdiff - contrib/loaders/flash/cc26xx/flash.c
flash/nor: Add support for TI CC26xx/CC13xx flash
[openocd] / contrib / loaders / flash / cc26xx / flash.c
diff --git a/contrib/loaders/flash/cc26xx/flash.c b/contrib/loaders/flash/cc26xx/flash.c
new file mode 100644 (file)
index 0000000..c19cb73
--- /dev/null
@@ -0,0 +1,977 @@
+/******************************************************************************
+*
+* Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*  Redistributions of source code must retain the above copyright
+*  notice, this list of conditions and the following disclaimer.
+*
+*  Redistributions in binary form must reproduce the above copyright
+*  notice, this list of conditions and the following disclaimer in the
+*  documentation and/or other materials provided with the
+*  distribution.
+*
+*  Neither the name of Texas Instruments Incorporated nor the names of
+*  its contributors may be used to endorse or promote products derived
+*  from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "flash.h"
+
+/******************************************************************************
+*
+* Defines for accesses to the security control in the customer configuration
+* area in flash top sector.
+*
+******************************************************************************/
+#define CCFG_OFFSET_SECURITY CCFG_O_BL_CONFIG
+#define CCFG_SIZE_SECURITY   0x00000014
+
+/******************************************************************************
+*
+* Default values for security control in customer configuration area in flash
+* top sector.
+*
+******************************************************************************/
+const uint8_t g_ccfg_default_sec[] = {
+       0xFF, 0xFF, 0xFF, 0xC5,
+       0xFF, 0xFF, 0xFF, 0xFF,
+       0xC5, 0xFF, 0xFF, 0xFF,
+       0xC5, 0xC5, 0xC5, 0xFF,
+       0xC5, 0xC5, 0xC5, 0xFF
+};
+
+typedef uint32_t (*flash_prg_pntr_t) (uint8_t *, uint32_t, uint32_t);
+typedef uint32_t (*flash_sector_erase_pntr_t) (uint32_t);
+
+/******************************************************************************
+*
+* Function prototypes for static functions
+*
+******************************************************************************/
+static void issue_fsm_command(flash_state_command_t command);
+static void enable_sectors_for_write(void);
+static uint32_t scale_cycle_values(uint32_t specified_timing,
+       uint32_t scale_value);
+static void set_write_mode(void);
+static void trim_for_write(void);
+static void set_read_mode(void);
+
+/******************************************************************************
+*
+* Erase a flash sector
+*
+******************************************************************************/
+uint32_t flash_sector_erase(uint32_t sector_address)
+{
+       uint32_t error_return;
+       flash_sector_erase_pntr_t func_pntr;
+
+       /* Call ROM function */
+       func_pntr = (uint32_t (*)(uint32_t))(ROM_API_FLASH_TABLE[5]);
+       error_return = func_pntr(sector_address);
+
+       /* Enable standby because ROM function might have disabled it */
+       HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;
+
+       /* Return status of operation. */
+       return error_return;
+}
+
+/******************************************************************************
+*
+* Erase all unprotected sectors in the flash main bank
+*
+******************************************************************************/
+uint32_t flash_bank_erase(bool force_precondition)
+{
+       uint32_t error_return;
+       uint32_t sector_address;
+       uint32_t reg_val;
+
+       /* Enable all sectors for erase. */
+       enable_sectors_for_write();
+
+       /* Clear the Status register. */
+       issue_fsm_command(FAPI_CLEAR_STATUS);
+
+       /* Enable erase of all sectors and enable precondition if required. */
+       reg_val = HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE);
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
+       HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0x00000000;
+       HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0x00000000;
+       if (force_precondition)
+               HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
+                       FLASH_FSM_ST_MACHINE_DO_PRECOND;
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
+
+       /* Issue the bank erase command to the FSM. */
+       issue_fsm_command(FAPI_ERASE_BANK);
+
+       /* Wait for erase to finish. */
+       while (flash_check_fsm_for_ready() == FAPI_STATUS_FSM_BUSY)
+               ;
+
+       /* Update status. */
+       error_return = flash_check_fsm_for_error();
+
+       /* Disable sectors for erase. */
+       flash_disable_sectors_for_write();
+
+       /* Set configured precondition mode since it may have been forced on. */
+       if (!(reg_val & FLASH_FSM_ST_MACHINE_DO_PRECOND)) {
+               HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
+               HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &=
+                       ~FLASH_FSM_ST_MACHINE_DO_PRECOND;
+               HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
+       }
+
+       /* Program security data to default values in the customer configuration */
+       /* area within the flash top sector if erase was successful. */
+       if (error_return == FAPI_STATUS_SUCCESS) {
+               sector_address = FLASHMEM_BASE + flash_size_get() -
+                                                       flash_sector_size_get();
+               error_return = flash_program((uint8_t *)g_ccfg_default_sec,
+                                                       (sector_address + CCFG_OFFSET_SECURITY),
+                                                       CCFG_SIZE_SECURITY);
+       }
+
+       /* Return status of operation. */
+       return error_return;
+}
+
+/******************************************************************************
+*
+* Programs unprotected main bank flash sectors
+*
+******************************************************************************/
+uint32_t flash_program(uint8_t *data_buffer, uint32_t address, uint32_t count)
+{
+       uint32_t error_return;
+       flash_prg_pntr_t func_pntr;
+
+       /* Call ROM function */
+       func_pntr = (uint32_t (*)(uint8_t *, uint32_t, uint32_t))
+                                       (ROM_API_FLASH_TABLE[6]);
+       error_return = func_pntr(data_buffer, address, count);
+
+       /* Enable standby because ROM function might have disabled it */
+       HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;
+
+       /* Return status of operation. */
+       return error_return;
+}
+
+/******************************************************************************
+*
+* Disables all sectors for erase and programming on the active bank
+*
+******************************************************************************/
+void flash_disable_sectors_for_write(void)
+{
+       /* Configure flash back to read mode */
+       set_read_mode();
+
+       /* Disable Level 1 Protection. */
+       HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
+
+       /* Disable all sectors for erase and programming. */
+       HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
+
+       /* Enable Level 1 Protection. */
+       HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
+
+       /* Protect sectors from sector erase. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
+       HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
+       HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
+}
+
+/******************************************************************************
+*
+* Issues a command to the Flash State Machine.
+*
+******************************************************************************/
+static void issue_fsm_command(flash_state_command_t command)
+{
+       /* Enable write to FSM register. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
+
+       /* Issue FSM command. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_CMD) = command;
+
+       /* Start command execute. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_EXECUTE) = FLASH_CMD_EXEC;
+
+       /* Disable write to FSM register. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
+}
+
+/******************************************************************************
+*
+* Enables all sectors for erase and programming on the active bank.
+*
+* This function disables the idle reading power reduction mode, selects the
+* flash bank and enables all sectors for erase and programming on the active
+* bank.
+* Sectors may be protected from programming depending on the value of the
+* FLASH_O_FSM_BSLPx registers.
+* Sectors may be protected from erase depending on the value of the
+* FLASH_O_FSM_BSLEx registers. Additional sector erase protection is set by
+* the FLASH_O_FSM_SECTOR1 register.
+*
+******************************************************************************/
+static void enable_sectors_for_write(void)
+{
+       /* Trim flash module for program/erase operation. */
+       trim_for_write();
+
+       /* Configure flash to write mode */
+       set_write_mode();
+
+       /* Select flash bank. */
+       HWREG(FLASH_BASE + FLASH_O_FMAC) = 0x00;
+
+       /* Disable Level 1 Protection. */
+       HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
+
+       /* Enable all sectors for erase and programming. */
+       HWREG(FLASH_BASE + FLASH_O_FBSE) = 0xFFFF;
+
+       /* Enable Level 1 Protection */
+       HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
+}
+
+/******************************************************************************
+*
+* Trims the Flash Bank and Flash Pump for program/erase functionality
+*
+* This trimming will make it possible to perform erase and program operations
+* of the flash. Trim values are loaded from factory configuration area
+* (referred to as FCGF1). The trimming done by this function is valid until
+* reset of the flash module.
+*
+* Some registers shall be written with a value that is a number of FCLK
+* cycles. The trim values controlling these registers have a value of
+* number of half us. FCLK = SysClk / ((RWAIT+1) x 2).
+*
+******************************************************************************/
+static void trim_for_write(void)
+{
+       uint32_t value;
+       uint32_t temp_val;
+       uint32_t fclk_scale;
+       uint32_t rwait;
+
+       /* Return if flash is already trimmed for program/erase operations. */
+       if (HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_WRT_TRIMMED)
+               return;
+
+       /* Configure the FSM registers */
+
+       /* Enable access to the FSM registers. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
+
+       /* Determine the scaling value to be used on timing related trim values. */
+       /* The value is based on the flash module clock frequency and RWAIT */
+       rwait = (HWREG(FLASH_BASE + FLASH_O_FRDCTL) &
+                               FLASH_FRDCTL_RWAIT_M) >> FLASH_FRDCTL_RWAIT_S;
+       fclk_scale = (16 * FLASH_MODULE_CLK_FREQ) / (rwait + 1);
+
+       /* Configure Program pulse width bits 15:0. */
+       /* (FCFG1 offset 0x188 bits 15:0). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &
+                               FCFG1_FLASH_PROG_EP_PROGRAM_PW_M) >>
+                               FCFG1_FLASH_PROG_EP_PROGRAM_PW_S;
+
+       value = scale_cycle_values(value, fclk_scale);
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) &
+               ~FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M) |
+               ((value << FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_S) &
+               FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M);
+
+       /* Configure Erase pulse width bits 31:0. */
+       /* (FCFG1 offset 0x18C bits 31:0). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_ERA_PW) &
+                               FCFG1_FLASH_ERA_PW_ERASE_PW_M) >>
+                               FCFG1_FLASH_ERA_PW_ERASE_PW_S;
+
+       value = scale_cycle_values(value, fclk_scale);
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) &
+               ~FLASH_FSM_ERA_PW_FSM_ERA_PW_M) |
+               ((value << FLASH_FSM_ERA_PW_FSM_ERA_PW_S) &
+               FLASH_FSM_ERA_PW_FSM_ERA_PW_M);
+
+       /* Configure no of flash clock cycles from EXECUTEZ going low to the the
+          verify data can be read in the program verify mode bits 7:0. */
+       /* (FCFG1 offset 0x174 bits 23:16). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
+                               FCFG1_FLASH_C_E_P_R_PV_ACCESS_M) >>
+                               FCFG1_FLASH_C_E_P_R_PV_ACCESS_S;
+
+       value = scale_cycle_values(value, fclk_scale);
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
+               ~FLASH_FSM_EX_VAL_EXE_VALD_M) |
+               ((value << FLASH_FSM_EX_VAL_EXE_VALD_S) &
+               FLASH_FSM_EX_VAL_EXE_VALD_M);
+
+       /* Configure the number of flash clocks from the start of the Read mode at
+          the end of the operations until the FSM clears the BUSY bit in FMSTAT. */
+       /* (FCFG1 offset 0x178 bits 23:16). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
+                               FCFG1_FLASH_P_R_PV_RH_M) >>
+                               FCFG1_FLASH_P_R_PV_RH_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) &
+               ~FLASH_FSM_RD_H_RD_H_M) |
+               ((value << FLASH_FSM_RD_H_RD_H_S) &
+               FLASH_FSM_RD_H_RD_H_M);
+
+       /* Configure Program hold time */
+       /* (FCFG1 offset 0x178 bits 31:24). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
+                               FCFG1_FLASH_P_R_PV_PH_M) >>
+                               FCFG1_FLASH_P_R_PV_PH_S;
+
+       value = scale_cycle_values(value, fclk_scale);
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) &
+               ~FLASH_FSM_P_OH_PGM_OH_M) |
+               ((value << FLASH_FSM_P_OH_PGM_OH_S) &
+               FLASH_FSM_P_OH_PGM_OH_M);
+
+       /* Configure Erase hold time */
+       /* (FCFG1 offset 0x17C bits 31:24). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &
+                               FCFG1_FLASH_EH_SEQ_EH_M) >>
+                               FCFG1_FLASH_EH_SEQ_EH_S;
+
+       value = scale_cycle_values(value, fclk_scale);
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) &
+               ~FLASH_FSM_ERA_OH_ERA_OH_M) |
+               ((value << FLASH_FSM_ERA_OH_ERA_OH_S) &
+               FLASH_FSM_ERA_OH_ERA_OH_M);
+
+       /* Configure Program verify row switch time */
+       /* (FCFG1 offset0x178 bits 15:8). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
+                               FCFG1_FLASH_P_R_PV_PVH_M) >>
+                               FCFG1_FLASH_P_R_PV_PVH_S;
+
+       value = scale_cycle_values(value, fclk_scale);
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) &
+               ~FLASH_FSM_PE_VH_PGM_VH_M) |
+               ((value << FLASH_FSM_PE_VH_PGM_VH_S) &
+               FLASH_FSM_PE_VH_PGM_VH_M);
+
+       /* Configure Program Operation Setup time */
+       /* (FCFG1 offset 0x170 bits 31:24). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
+                               FCFG1_FLASH_E_P_PSU_M) >>
+                               FCFG1_FLASH_E_P_PSU_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
+               ~FLASH_FSM_PE_OSU_PGM_OSU_M) |
+               ((value << FLASH_FSM_PE_OSU_PGM_OSU_S) &
+               FLASH_FSM_PE_OSU_PGM_OSU_M);
+
+       /* Configure Erase Operation Setup time */
+       /* (FCGF1 offset 0x170 bits 23:16). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
+                               FCFG1_FLASH_E_P_ESU_M) >>
+                               FCFG1_FLASH_E_P_ESU_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
+               ~FLASH_FSM_PE_OSU_ERA_OSU_M) |
+               ((value << FLASH_FSM_PE_OSU_ERA_OSU_S) &
+               FLASH_FSM_PE_OSU_ERA_OSU_M);
+
+       /* Confgure Program Verify Setup time */
+       /* (FCFG1 offset 0x170 bits 15:8). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
+                               FCFG1_FLASH_E_P_PVSU_M) >>
+                               FCFG1_FLASH_E_P_PVSU_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
+               ~FLASH_FSM_PE_VSU_PGM_VSU_M) |
+               ((value << FLASH_FSM_PE_VSU_PGM_VSU_S) &
+               FLASH_FSM_PE_VSU_PGM_VSU_M);
+
+       /* Configure Erase Verify Setup time */
+       /* (FCFG1 offset 0x170 bits 7:0). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
+                               FCFG1_FLASH_E_P_EVSU_M) >>
+                               FCFG1_FLASH_E_P_EVSU_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
+               ~FLASH_FSM_PE_VSU_ERA_VSU_M) |
+               ((value << FLASH_FSM_PE_VSU_ERA_VSU_S) &
+               FLASH_FSM_PE_VSU_ERA_VSU_M);
+
+       /* Configure Addr to EXECUTEZ low setup time */
+       /* (FCFG1 offset 0x174 bits 15:12). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
+                               FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_M) >>
+                               FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) &
+               ~FLASH_FSM_CMP_VSU_ADD_EXZ_M) |
+               ((value << FLASH_FSM_CMP_VSU_ADD_EXZ_S) &
+               FLASH_FSM_CMP_VSU_ADD_EXZ_M);
+
+       /* Configure Voltage Status Count */
+       /* (FCFG1 offset 0x17C bits 15:12). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &
+                               FCFG1_FLASH_EH_SEQ_VSTAT_M) >>
+                               FCFG1_FLASH_EH_SEQ_VSTAT_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) &
+               ~FLASH_FSM_VSTAT_VSTAT_CNT_M) |
+               ((value << FLASH_FSM_VSTAT_VSTAT_CNT_S) &
+               FLASH_FSM_VSTAT_VSTAT_CNT_M);
+
+       /* Configure Repeat Verify action setup */
+       /* (FCFG1 offset 0x174 bits 31:24). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
+                               FCFG1_FLASH_C_E_P_R_RVSU_M) >>
+                               FCFG1_FLASH_C_E_P_R_RVSU_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
+               ~FLASH_FSM_EX_VAL_REP_VSU_M) |
+               ((value << FLASH_FSM_EX_VAL_REP_VSU_S) &
+               FLASH_FSM_EX_VAL_REP_VSU_M);
+
+       /* Configure Maximum Programming Pulses */
+       /* (FCFG1 offset 0x184 bits 15:0). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PP) &
+                               FCFG1_FLASH_PP_MAX_PP_M) >>
+                               FCFG1_FLASH_PP_MAX_PP_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
+               ~FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M) |
+               ((value << FLASH_FSM_PRG_PUL_MAX_PRG_PUL_S) &
+               FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M);
+
+       /* Configure Beginning level for VHVCT used during erase modes */
+       /* (FCFG1 offset 0x180 bits 31:16). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &
+                               FCFG1_FLASH_VHV_E_VHV_E_START_M) >>
+                               FCFG1_FLASH_VHV_E_VHV_E_START_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
+               ~FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M) |
+               ((value << FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_S) &
+               FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M);
+
+       /* Configure Maximum EC Level */
+       /* (FCFG1 offset 0x2B0 bits 21:18). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
+                               FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_M) >>
+                               FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
+               ~FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M) |
+               ((value << FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_S) &
+               FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M);
+
+       /* Configure Maximum Erase Pulses */
+       /* (FCFG1 offset 0x188 bits 31:16). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &
+                               FCFG1_FLASH_PROG_EP_MAX_EP_M) >>
+                               FCFG1_FLASH_PROG_EP_MAX_EP_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
+               ~FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M) |
+               ((value << FLASH_FSM_ERA_PUL_MAX_ERA_PUL_S) &
+               FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M);
+
+       /* Configure the VHVCT Step Size. This is the number of erase pulses that
+          must be completed for each level before the FSM increments the
+          CUR_EC_LEVEL to the next higher level. Actual erase pulses per level
+          equals (EC_STEP_SIZE +1). The stepping is only needed for the VHVCT
+          voltage. */
+       /* (FCFG1 offset 0x2B0 bits 31:23). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
+                               FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_M) >>
+                               FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) &
+               ~FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M) |
+               ((value << FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_S) &
+               FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M);
+
+       /* Configure the hight of each EC step. This is the number of counts that
+          the CUR_EC_LEVEL will increment when going to a new level. Actual count
+          size equals (EC_STEP_HEIGHT + 1). The stepping applies only to the VHVCT
+          voltage.
+          The read trim value is decremented by 1 before written to the register
+          since actual counts equals (register value + 1). */
+       /* (FCFG1 offset 0x180 bits 15:0). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &
+                               FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_M) >>
+                               FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_EC_STEP_HEIGHT) = ((value - 1) &
+               FLASH_FSM_EC_STEP_HEIGHT_EC_STEP_HEIGHT_M);
+
+       /* Configure Precondition used in erase operations */
+       /* (FCFG1 offset 0x2B0 bit 22). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
+                               FCFG1_FLASH_OTP_DATA3_DO_PRECOND_M) >>
+                               FCFG1_FLASH_OTP_DATA3_DO_PRECOND_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) =
+               (HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &
+               ~FLASH_FSM_ST_MACHINE_DO_PRECOND_M) |
+               ((value << FLASH_FSM_ST_MACHINE_DO_PRECOND_S) &
+               FLASH_FSM_ST_MACHINE_DO_PRECOND_M);
+
+       /* Enable the recommended Good Time function. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
+               FLASH_FSM_ST_MACHINE_ONE_TIME_GOOD;
+
+       /* Disable write access to FSM registers. */
+       HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
+
+       /* Configure the voltage registers */
+
+       /* Unlock voltage registers (0x2080 - 0x2098). */
+       HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
+
+       /* Configure voltage level for the specified pump voltage of high
+          voltage supply input during erase operation VHVCT_E and TRIM13_E */
+       /* (FCFG1 offset 0x190 bits[3:0] and bits[11:8]). */
+       temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);
+
+       value = ((temp_val & FCFG1_FLASH_VHV_TRIM13_E_M)>>
+                               FCFG1_FLASH_VHV_TRIM13_E_S) << FLASH_FVHVCT1_TRIM13_E_S;
+       value |= ((temp_val & FCFG1_FLASH_VHV_VHV_E_M)>>
+                               FCFG1_FLASH_VHV_VHV_E_S) << FLASH_FVHVCT1_VHVCT_E_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
+               ~(FLASH_FVHVCT1_TRIM13_E_M | FLASH_FVHVCT1_VHVCT_E_M)) | value;
+
+       /* Configure voltage level for the specified pump voltage of high voltage
+          supply input during program verify operation VHVCT_PV and TRIM13_PV */
+       /* (OTP offset 0x194 bits[19:16] and bits[27:24]). */
+       temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV);
+
+       value = ((temp_val & FCFG1_FLASH_VHV_PV_TRIM13_PV_M) >>
+                               FCFG1_FLASH_VHV_PV_TRIM13_PV_S) << FLASH_FVHVCT1_TRIM13_PV_S;
+       value |= ((temp_val & FCFG1_FLASH_VHV_PV_VHV_PV_M) >>
+                               FCFG1_FLASH_VHV_PV_VHV_PV_S) << FLASH_FVHVCT1_VHVCT_PV_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
+               ~(FLASH_FVHVCT1_TRIM13_PV_M | FLASH_FVHVCT1_VHVCT_PV_M)) | value;
+
+       /* Configure voltage level for the specified pump voltage of high voltage
+          supply input during program operation VHVCT_P and TRIM13_P */
+       /* (FCFG1 offset 0x190 bits[19:16] and bits[27:24]). */
+       temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);
+
+       value = ((temp_val & FCFG1_FLASH_VHV_TRIM13_P_M) >>
+                               FCFG1_FLASH_VHV_TRIM13_P_S) << FLASH_FVHVCT2_TRIM13_P_S;
+       value |= ((temp_val & FCFG1_FLASH_VHV_VHV_P_M) >>
+                               FCFG1_FLASH_VHV_VHV_P_S) << FLASH_FVHVCT2_VHVCT_P_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FVHVCT2) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT2) &
+               ~(FLASH_FVHVCT2_TRIM13_P_M | FLASH_FVHVCT2_VHVCT_P_M)) | value;
+
+       /* Configure voltage level for the specified pump voltage of wordline power
+          supply for read mode */
+       /* (FCFG1 offset 0x198 Bits 15:8). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
+                               FCFG1_FLASH_V_V_READ_M) >> FCFG1_FLASH_V_V_READ_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FVREADCT) =
+               (HWREG(FLASH_BASE + FLASH_O_FVREADCT) &
+               ~FLASH_FVREADCT_VREADCT_M) |
+               ((value << FLASH_FVREADCT_VREADCT_S) &
+               FLASH_FVREADCT_VREADCT_M);
+
+       /* Configure the voltage level for the VCG 2.5 CT pump voltage */
+       /* (FCFG1 offset 0x194 bits 15:8). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV) &
+                               FCFG1_FLASH_VHV_PV_VCG2P5_M) >>
+                               FCFG1_FLASH_VHV_PV_VCG2P5_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FVNVCT) =
+               (HWREG(FLASH_BASE + FLASH_O_FVNVCT) &
+               ~FLASH_FVNVCT_VCG2P5CT_M) |
+               ((value << FLASH_FVNVCT_VCG2P5CT_S) &
+               FLASH_FVNVCT_VCG2P5CT_M);
+
+       /* Configure the voltage level for the specified pump voltage of high
+          current power input during program operation */
+       /* (FCFG1 offset 0x198 bits 31:24). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
+                               FCFG1_FLASH_V_VSL_P_M) >>
+                               FCFG1_FLASH_V_VSL_P_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FVSLP) =
+               (HWREG(FLASH_BASE + FLASH_O_FVSLP) &
+               ~FLASH_FVSLP_VSL_P_M) |
+               ((value << FLASH_FVSLP_VSL_P_S) &
+               FLASH_FVSLP_VSL_P_M);
+
+       /* Configure the voltage level for the specified pump voltage of wordline
+          power supply during programming operations */
+       /* (OTP offset 0x198 bits 23:16). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
+                               FCFG1_FLASH_V_VWL_P_M) >>
+                               FCFG1_FLASH_V_VWL_P_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FVWLCT) =
+               (HWREG(FLASH_BASE + FLASH_O_FVWLCT) &
+               ~FLASH_FVWLCT_VWLCT_P_M) |
+               ((value << FLASH_FVWLCT_VWLCT_P_S) &
+               FLASH_FVWLCT_VWLCT_P_M);
+
+       /* Configure the pump's TRIM_1P7 port pins. */
+       /* (FCFG1 offset 0x2B0 bits 17:16). */
+       value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
+                               FCFG1_FLASH_OTP_DATA3_TRIM_1P7_M) >>
+                               FCFG1_FLASH_OTP_DATA3_TRIM_1P7_S;
+
+       HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
+               (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
+               ~FLASH_FSEQPMP_TRIM_1P7_M) |
+               ((value << FLASH_FSEQPMP_TRIM_1P7_S) &
+               FLASH_FSEQPMP_TRIM_1P7_M);
+
+       /* Lock the voltage registers. */
+       HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
+
+       /* Set trimmed flag. */
+       HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
+       HWREG(FLASH_BASE + FLASH_O_FWFLAG) |= FW_WRT_TRIMMED;
+       HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
+}
+
+/******************************************************************************
+*
+* Used to scale the TI OTP values based on the FClk scaling value.
+*
+******************************************************************************/
+static uint32_t scale_cycle_values(uint32_t specified_timing,
+       uint32_t scale_value)
+{
+       uint32_t scaled_value = (specified_timing * scale_value) >> 6;
+       return scaled_value;
+}
+
+/******************************************************************************
+*
+* Used to set flash in read mode.
+*
+* Flash is configured with values loaded from OTP dependent on the current
+* regulator mode.
+*
+******************************************************************************/
+static void set_read_mode(void)
+{
+       uint32_t trim_value;
+       uint32_t value;
+
+       /* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
+          VIN_AT_X and VIN_BY_PASS for read mode */
+       if (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
+               AON_PMCTL_PWRCTL_EXT_REG_MODE) {
+
+               /* Select trim values for external regulator mode:
+                  Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
+                  Configure STANDBY_PW_SEL   (OTP offset 0x308 bit 6:5)
+                  Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
+               HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
+
+               trim_value =
+                       HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
+
+               value = ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
+                                       FLASH_CFG_STANDBY_MODE_SEL_S;
+
+               value |= ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
+                                       FLASH_CFG_STANDBY_PW_SEL_S;
+
+               /* Configure DIS_STANDBY (OTP offset 0x308 bit 4).
+                  Configure DIS_IDLE    (OTP offset 0x308 bit 3). */
+               value |= ((trim_value &
+                                       (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
+                                       FLASH_CFG_DIS_IDLE_S;
+
+               HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
+                       ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
+                       FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
+
+               /* Check if sample and hold functionality is disabled. */
+               if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
+                       /* Wait for disabled sample and hold functionality to be stable. */
+                       while (!(HWREG(FLASH_BASE+FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
+                               ;
+               }
+
+               /* Configure VIN_AT_X (OTP offset 0x308 bits 2:0) */
+               value = ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
+                                       FLASH_FSEQPMP_VIN_AT_X_S;
+
+               /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
+                  If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
+                  VIN_BY_PASS should be 1 */
+               if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
+                       FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
+                       value |= FLASH_FSEQPMP_VIN_BY_PASS;
+
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
+               HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
+                       (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
+                       ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
+                       FLASH_FSEQPMP_VIN_AT_X_M)) | value;
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
+       } else {
+
+               /* Select trim values for internal regulator mode:
+                  Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
+                  COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 14:13)
+                  Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
+               HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
+
+               trim_value =
+                       HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
+
+               value = ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
+                                       FLASH_CFG_STANDBY_MODE_SEL_S;
+
+               value |= ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
+                                       FLASH_CFG_STANDBY_PW_SEL_S;
+
+               /* Configure DIS_STANDBY (OTP offset 0x308 bit 12).
+                  Configure DIS_IDLE    (OTP offset 0x308 bit 11). */
+               value |= ((trim_value &
+                                       (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
+                                       FLASH_CFG_DIS_IDLE_S;
+
+               HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
+                       ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
+                       FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
+
+               /* Check if sample and hold functionality is disabled. */
+               if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
+                       /* Wait for disabled sample and hold functionality to be stable. */
+                       while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
+                               ;
+               }
+
+               /* Configure VIN_AT_X (OTP offset 0x308 bits 10:8) */
+               value = (((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
+                                       FLASH_FSEQPMP_VIN_AT_X_S);
+
+               /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
+                  If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
+                  VIN_BY_PASS should be 1 */
+               if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
+                       FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
+                       value |= FLASH_FSEQPMP_VIN_BY_PASS;
+
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
+               HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
+                       (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
+                       ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
+                       FLASH_FSEQPMP_VIN_AT_X_M)) | value;
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
+       }
+}
+
+/******************************************************************************
+*
+* Used to set flash in write mode.
+*
+* Flash is configured with values loaded from OTP dependent on the current
+* regulator mode.
+*
+******************************************************************************/
+static void set_write_mode(void)
+{
+       uint32_t trim_value;
+       uint32_t value;
+
+       /* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
+          VIN_AT_X and VIN_BY_PASS for program/erase mode */
+       if (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
+               AON_PMCTL_PWRCTL_EXT_REG_MODE) {
+
+               /* Select trim values for external regulator mode:
+                  Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 23)
+                  Configure STANDBY_PW_SEL   (OTP offset 0x308 bit 22:21)
+                  Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
+               HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
+
+               trim_value =
+                       HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
+
+               value = ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_S) <<
+                                       FLASH_CFG_STANDBY_MODE_SEL_S;
+
+               value |= ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_S) <<
+                                       FLASH_CFG_STANDBY_PW_SEL_S;
+
+               /* Configure DIS_STANDBY (OTP offset 0x308 bit 20).
+                  Configure DIS_IDLE    (OTP offset 0x308 bit 19). */
+               value |= ((trim_value &
+                                       (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_WRT_M |
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_M)) >>
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_S) <<
+                                       FLASH_CFG_DIS_IDLE_S;
+
+               HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
+                       ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
+                       FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
+
+               /* Check if sample and hold functionality is disabled. */
+               if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
+                       /* Wait for disabled sample and hold functionality to be stable. */
+                       while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
+                               ;
+               }
+
+               /* Configure VIN_AT_X (OTP offset 0x308 bits 18:16) */
+               value = ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_S) <<
+                                       FLASH_FSEQPMP_VIN_AT_X_S;
+
+               /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
+                  If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
+                  VIN_BY_PASS should be 1 */
+               if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
+                       FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
+                       value |= FLASH_FSEQPMP_VIN_BY_PASS;
+
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
+               HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
+                       (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
+                       ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
+                       FLASH_FSEQPMP_VIN_AT_X_M)) | value;
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
+       } else {
+               /* Select trim values for internal regulator mode:
+                  Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 31)
+                  COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 30:29)
+                  Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
+               HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
+
+               trim_value =
+                       HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
+
+               value = ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_S) <<
+                                       FLASH_CFG_STANDBY_MODE_SEL_S;
+
+               value |= ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_S) <<
+                                       FLASH_CFG_STANDBY_PW_SEL_S;
+
+               /* Configure DIS_STANDBY (OTP offset 0x308 bit 28).
+                  Configure DIS_IDLE    (OTP offset 0x308 bit 27). */
+               value |= ((trim_value &
+                                       (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_WRT_M |
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_M)) >>
+                                       FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_S) <<
+                                       FLASH_CFG_DIS_IDLE_S;
+
+               HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
+                       ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
+                       FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
+
+               /* Check if sample and hold functionality is disabled. */
+               if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
+                       /* Wait for disabled sample and hold functionality to be stable. */
+                       while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
+                               ;
+               }
+
+               /* Configure VIN_AT_X (OTP offset 0x308 bits 26:24) */
+               value = ((trim_value &
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_M) >>
+                                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_S) <<
+                                       FLASH_FSEQPMP_VIN_AT_X_S;
+
+               /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
+                  If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
+                  VIN_BY_PASS should be 1 */
+               if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
+                       FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
+                       value |= FLASH_FSEQPMP_VIN_BY_PASS;
+
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
+               HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
+                       (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
+                       ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
+                       FLASH_FSEQPMP_VIN_AT_X_M)) | value;
+               HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
+       }
+}