flash/nor: Add support for TI CC26xx/CC13xx flash
[openocd.git] / 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;
+       }
+}

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)