summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/mcux-sdk/drivers/ocotp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.c406
-rw-r--r--bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.h211
2 files changed, 617 insertions, 0 deletions
diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.c b/bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.c
new file mode 100644
index 0000000000..4c15d6974d
--- /dev/null
+++ b/bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2019-2020 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_ocotp.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.ocotp"
+#endif
+
+#if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
+#define OCOTP_STATUS_READ_DED_MASK \
+ (OCOTP_OUT_STATUS0_DED0_MASK | OCOTP_OUT_STATUS0_DED1_MASK | OCOTP_OUT_STATUS0_DED2_MASK | \
+ OCOTP_OUT_STATUS0_DED3_MASK)
+#endif
+
+/* Wait time should be not less than 150ns . */
+#define OCOTP_TIMING_WAIT_NS (uint64_t)150
+/* Relex time should be not less than 100ns . */
+#define OCOTP_TIMING_RELEX_NS (uint64_t)100
+/* Program time should be rang from 9000ns~11000ns. */
+#define OCOTP_TIMING_PROGRAM_NS (uint64_t)10000
+/* Read time should be less than 40ns. */
+#define OCOTP_TIMING_READ_NS (uint64_t)40
+
+/* Unlock key is 0x3E77. */
+#define OCOTP_WRITE_UNLOCK_KEY (0x3E77)
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+/*!
+ * @brief Set read timing configuration.
+ *
+ * @param base OCOTP peripheral base addess.
+ * @param timingConfig configuration of timing.
+ */
+static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
+
+/*!
+ * @brief Set write timing configuration.
+ *
+ * @param base OCOTP peripheral base addess.
+ * @param timingConfig configuration of timing.
+ */
+static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+/* Timing configuration for OCOTP controller. */
+static ocotp_timing_t s_timingConfig;
+#endif
+
+/*******************************************************************************
+ * Code
+ *******************************************************************************/
+/* Reload the shadow register. */
+status_t OCOTP_ReloadShadowRegister(OCOTP_Type *base)
+{
+ assert(NULL != base);
+
+ status_t status = kStatus_Success;
+
+ /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+
+ /* Clear access error status bit. */
+ OCOTP_ClearErrorStatus(base);
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+ /* Set the read timing. */
+ OCOTP_SetReadTiming(base, s_timingConfig);
+
+ /* Wait for the OCOTP controller not busy. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+#endif
+
+#if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
+ /* Clear reload error status. */
+ base->OUT_STATUS0_CLR = OCOTP_OUT_STATUS0_DED_RELOAD_MASK;
+#endif
+
+ /* Set reload bit. */
+ base->CTRL_SET = OCOTP_CTRL_RELOAD_SHADOWS(1);
+
+ /* Wait for the OCOTP controller not busy. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+ /* Wait for shadow register reload complete. this bit will be auto clear by OCOTP once operation is complete. */
+ while (OCOTP_CTRL_RELOAD_SHADOWS_MASK == (base->CTRL & OCOTP_CTRL_RELOAD_SHADOWS_MASK))
+ {
+ }
+
+#if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
+ if ((base->OUT_STATUS0 & OCOTP_OUT_STATUS0_DED_RELOAD_MASK) != 0U)
+ {
+ status = kStatus_OCOTP_ReloadError;
+ }
+#endif
+
+ return status;
+}
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
+{
+ uint32_t timingValue = base->TIMING;
+
+ timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_READ_MASK | OCOTP_TIMING_WAIT_MASK);
+ timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_READ(timingConfig.strobe_read) |
+ OCOTP_TIMING_WAIT(timingConfig.wait);
+ base->TIMING = timingValue;
+}
+
+static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
+{
+ uint32_t timingValue = base->TIMING;
+
+ timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_PROG_MASK | OCOTP_TIMING_WAIT_MASK);
+ timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_PROG(timingConfig.strobe_prog) |
+ OCOTP_TIMING_WAIT(timingConfig.wait);
+
+ base->TIMING = timingValue;
+}
+#endif
+
+/* Initializes OCOTP controller. */
+void OCOTP_Init(OCOTP_Type *base, uint32_t srcClock_Hz)
+{
+ assert(NULL != base);
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+ assert(0UL != srcClock_Hz);
+#endif
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable OCOTP clock */
+ CLOCK_EnableClock(kCLOCK_Ocotp);
+#endif
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+ /* tWait time shoule be higher than OCOTP_TIMING_WAIT_NS. */
+ s_timingConfig.wait = (uint32_t)((OCOTP_TIMING_WAIT_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
+
+ /* tRelax time shoule be higher than OCOTP_TIMING_RELEX_NS. */
+ s_timingConfig.relax = (uint32_t)((OCOTP_TIMING_RELEX_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
+
+ /* tStrobe_prog time should be close to OCOTP_TIMING_PROGRAM_NS, only add half of 1000000000. */
+ s_timingConfig.strobe_prog = (uint32_t)((OCOTP_TIMING_PROGRAM_NS * srcClock_Hz + 500000000U) / 1000000000U) +
+ 2U * (s_timingConfig.relax + 1U) - 1U;
+
+ /* tStrobe_read time should be higher than OCOTP_TIMING_READ_NS. */
+ s_timingConfig.strobe_read = (uint32_t)((OCOTP_TIMING_READ_NS * srcClock_Hz + 1000000000U) / 1000000000U) +
+ 2U * (s_timingConfig.relax + 1U) - 1U;
+#endif
+}
+
+/* De-init OCOTP controller. */
+void OCOTP_Deinit(OCOTP_Type *base)
+{
+ assert(NULL != base);
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+ s_timingConfig.wait = 0UL;
+ s_timingConfig.relax = 0UL;
+ s_timingConfig.strobe_prog = 0UL;
+ s_timingConfig.strobe_read = 0UL;
+#endif
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disable OCOTP clock */
+ CLOCK_DisableClock(kCLOCK_Ocotp);
+#endif
+}
+
+/* Read the fuse shadow register. */
+uint32_t OCOTP_ReadFuseShadowRegister(OCOTP_Type *base, uint32_t address)
+{
+ assert(NULL != base);
+
+ uint32_t data = 0U;
+
+ (void)OCOTP_ReadFuseShadowRegisterExt(base, address, &data, 1);
+
+ return data;
+}
+
+status_t OCOTP_ReadFuseShadowRegisterExt(OCOTP_Type *base, uint32_t address, uint32_t *data, uint8_t fuseWords)
+{
+ assert((fuseWords > 0U) && (fuseWords <= OCOTP_READ_FUSE_DATA_COUNT));
+ assert(NULL != data);
+
+ status_t status = kStatus_Success;
+
+#if (OCOTP_READ_FUSE_DATA_COUNT > 1U)
+ uint32_t i;
+#endif
+
+ /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+
+ /* If ERROR bit was set, clear access error status bit. */
+ if (OCOTP_CheckErrorStatus(base))
+ {
+ OCOTP_ClearErrorStatus(base);
+ }
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+ /* Set the read timing. */
+ OCOTP_SetReadTiming(base, s_timingConfig);
+
+ /* Wait for busy bit is cleared. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+
+ /* Clear access error status bit. */
+ if (OCOTP_CheckErrorStatus(base))
+ {
+ OCOTP_ClearErrorStatus(base);
+ }
+#endif
+
+#if defined(OCOTP_STATUS_READ_DED_MASK)
+ /* Clear error flags. */
+ base->OUT_STATUS0_CLR = OCOTP_STATUS_READ_DED_MASK;
+#endif
+
+ /* Write requested address to register. */
+ base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK;
+ base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address);
+
+ /* Set OCOTP auto read enable. */
+#if defined(OCOTP_READ_CTRL_READ_NUM_MASK)
+ base->READ_CTRL = (base->READ_CTRL & ~(OCOTP_READ_CTRL_READ_NUM_MASK)) |
+ OCOTP_READ_CTRL_READ_NUM((uint32_t)fuseWords - 1U) | OCOTP_READ_CTRL_READ_FUSE_MASK;
+#else
+ base->READ_CTRL |= OCOTP_READ_CTRL_READ_FUSE_MASK;
+#endif
+
+ /* Wait for busy bit is cleared, and no error occurred on controller. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+
+ /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
+ if (OCOTP_CheckErrorStatus(base))
+ {
+ /* Clear access error status bit. */
+ OCOTP_ClearErrorStatus(base);
+
+ status = kStatus_OCOTP_AccessError;
+ }
+
+#if defined(OCOTP_STATUS_READ_DED_MASK)
+ if ((base->OUT_STATUS0 & OCOTP_STATUS_READ_DED_MASK) != 0U)
+ {
+ status = kStatus_Fail;
+ }
+#endif
+
+#if (OCOTP_READ_FUSE_DATA_COUNT == 1U)
+ *data = base->READ_FUSE_DATA;
+#else
+ for (i = 0; i < fuseWords; i++)
+ {
+ data[i] = base->READ_FUSE_DATAS[i].READ_FUSE_DATA;
+ }
+#endif
+
+ return status;
+}
+
+/* Write the fuse shadow register. */
+status_t OCOTP_WriteFuseShadowRegister(OCOTP_Type *base, uint32_t address, uint32_t data)
+{
+ return OCOTP_WriteFuseShadowRegisterWithLock(base, address, data, false);
+}
+
+status_t OCOTP_WriteFuseShadowRegisterWithLock(OCOTP_Type *base, uint32_t address, uint32_t data, bool lock)
+{
+ assert(NULL != base);
+
+ status_t status = kStatus_Success;
+
+#if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
+ uint32_t regStatus;
+#endif
+
+#if !(defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
+ if (lock)
+ {
+ return kStatus_InvalidArgument;
+ }
+#endif
+
+ /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+
+ /* Clear access error status bit. */
+ if (OCOTP_CheckErrorStatus(base))
+ {
+ OCOTP_ClearErrorStatus(base);
+ }
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+ /* Set write timing for OCOTP controller. */
+ OCOTP_SetWriteTiming(base, s_timingConfig);
+
+ /* Wait for busy bit is cleared. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+
+ /* Clear access error status bit. */
+ if (OCOTP_CheckErrorStatus(base))
+ {
+ OCOTP_ClearErrorStatus(base);
+ }
+#endif
+
+#if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
+ /* Clear errors. */
+ base->OUT_STATUS0_CLR = (OCOTP_OUT_STATUS0_PROGFAIL_MASK | OCOTP_OUT_STATUS0_LOCKED_MASK);
+#endif
+
+ /* Write requested address and unlock key to register. */
+#if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
+ base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK | OCOTP_CTRL_WORDLOCK_MASK;
+#else
+ base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK;
+#endif
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
+ if (lock)
+ {
+ base->CTRL_SET =
+ OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY) | OCOTP_CTRL_WORDLOCK_MASK;
+ }
+ else
+#endif
+ {
+ base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY);
+ }
+
+ /* Write data to register. */
+ base->DATA = data;
+
+ /* Wait for busy bit is cleared, and no error occurred on controller. */
+ while (OCOTP_CheckBusyStatus(base))
+ {
+ }
+
+ /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
+ if (OCOTP_CheckErrorStatus(base))
+ {
+ /* Clear access error status bit. */
+ OCOTP_ClearErrorStatus(base);
+
+ status = kStatus_OCOTP_AccessError;
+ }
+
+#if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
+ regStatus = base->OUT_STATUS0;
+
+ if ((regStatus & OCOTP_OUT_STATUS0_PROGFAIL_MASK) != 0U)
+ {
+ status = kStatus_OCOTP_ProgramFail;
+ }
+ else if ((regStatus & OCOTP_OUT_STATUS0_LOCKED_MASK) != 0U)
+ {
+ status = kStatus_OCOTP_Locked;
+ }
+ else
+ {
+ /* For MISRA rules. */
+ }
+#endif
+
+ if (kStatus_Success == status)
+ {
+ /* Reload the fuse register. */
+ status = OCOTP_ReloadShadowRegister(base);
+ }
+
+ return status;
+}
diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.h b/bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.h
new file mode 100644
index 0000000000..73a405a12a
--- /dev/null
+++ b/bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2019-2020 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_OCOTP_H_
+#define _FSL_OCOTP_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup ocotp
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ *******************************************************************************/
+/*! @name Driver version */
+/*@{*/
+/*! @brief OCOTP driver version. */
+#define FSL_OCOTP_DRIVER_VERSION (MAKE_VERSION(2, 1, 3))
+/*@}*/
+
+#ifndef OCOTP_READ_FUSE_DATA_COUNT
+#define OCOTP_READ_FUSE_DATA_COUNT (1U)
+#endif
+
+/*! @brief _ocotp_status Error codes for the OCOTP driver. */
+enum
+{
+ kStatus_OCOTP_AccessError = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 0), /*!< eFuse and shadow register access error. */
+ kStatus_OCOTP_CrcFail = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 1), /*!< CRC check failed. */
+ kStatus_OCOTP_ReloadError =
+ MAKE_STATUS(kStatusGroup_SDK_OCOTP, 2), /*!< Error happens during reload shadow register. */
+ kStatus_OCOTP_ProgramFail = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 3), /*!< Fuse programming failed. */
+ kStatus_OCOTP_Locked = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 4), /*!< Fuse is locked and cannot be programmed. */
+};
+
+#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
+/*! @brief OCOTP timing structure.
+ * Note that, these value are used for calcalating the read/write timings.
+ * And the values should statisfy below rules:
+ *
+ * Tsp_rd=(WAIT+1)/ipg_clk_freq should be >= 150ns;
+ * Tsp_pgm=(RELAX+1)/ipg_clk_freq should be >= 100ns;
+ * Trd = ((STROBE_READ+1)- 2*(RELAX_READ+1)) /ipg_clk_freq,
+ * The Trd is required to be larger than 40 ns.
+ * Tpgm = ((STROBE_PROG+1)- 2*(RELAX_PROG+1)) /ipg_clk_freq;
+ * The Tpgm should be configured within the range of 9000 ns < Tpgm < 11000 ns;
+ */
+typedef struct _ocotp_timing
+{
+ uint32_t wait; /*!< Wait time value to fill in the TIMING register. */
+ uint32_t relax; /*!< Relax time value to fill in the TIMING register. */
+ uint32_t strobe_prog; /*!< Storbe program time value to fill in the TIMING register. */
+ uint32_t strobe_read; /*!< Storbe read time value to fill in the TIMING register. */
+} ocotp_timing_t;
+#endif /* FSL_FEATURE_OCOTP_HAS_TIMING_CTRL */
+
+/*******************************************************************************
+ * API
+ *******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @brief Initializes OCOTP controller.
+ *
+ * @param base OCOTP peripheral base address.
+ * @param srcClock_Hz source clock frequency in unit of Hz. When the macro
+ * FSL_FEATURE_OCOTP_HAS_TIMING_CTRL is defined as 0, this parameter is not used,
+ * application could pass in 0 in this case.
+ */
+void OCOTP_Init(OCOTP_Type *base, uint32_t srcClock_Hz);
+
+/*!
+ * @brief De-initializes OCOTP controller.
+ *
+ * @retval kStatus_Success upon successful execution, error status otherwise.
+ */
+void OCOTP_Deinit(OCOTP_Type *base);
+
+/*!
+ * @brief Checking the BUSY bit in CTRL register.
+ * Checking this BUSY bit will help confirm if the OCOTP controller is ready for access.
+ *
+ * @param base OCOTP peripheral base address.
+ * @retval true for bit set and false for cleared.
+ */
+static inline bool OCOTP_CheckBusyStatus(OCOTP_Type *base)
+{
+ return ((OCOTP_CTRL_BUSY_MASK == (base->CTRL & OCOTP_CTRL_BUSY_MASK)) ? (true) : (false));
+}
+
+/*!
+ * @brief Checking the ERROR bit in CTRL register.
+ *
+ * @param base OCOTP peripheral base address.
+ * @retval true for bit set and false for cleared.
+ */
+static inline bool OCOTP_CheckErrorStatus(OCOTP_Type *base)
+{
+ return ((OCOTP_CTRL_ERROR_MASK == (base->CTRL & OCOTP_CTRL_ERROR_MASK)) ? (true) : (false));
+}
+
+/*!
+ * @brief Clear the error bit if this bit is set.
+ *
+ * @param base OCOTP peripheral base address.
+ */
+static inline void OCOTP_ClearErrorStatus(OCOTP_Type *base)
+{
+ base->CTRL_CLR = OCOTP_CTRL_CLR_ERROR_MASK;
+}
+
+/*!
+ * @brief Reload the shadow register.
+ * This function will help reload the shadow register without reseting the OCOTP module.
+ * Please make sure the OCOTP has been initialized before calling this API.
+ *
+ * @param base OCOTP peripheral base addess.
+ * @retval kStatus_Success Reload success.
+ * @retval kStatus_OCOTP_ReloadError Reload failed.
+ */
+status_t OCOTP_ReloadShadowRegister(OCOTP_Type *base);
+
+/*!
+ * @brief Read the fuse shadow register with the fuse addess.
+ *
+ * @deprecated Use @ref OCOTP_ReadFuseShadowRegisterExt instead of this function.
+ *
+ * @param base OCOTP peripheral base address.
+ * @param address the fuse address to be read from.
+ * @return The read out data.
+ */
+uint32_t OCOTP_ReadFuseShadowRegister(OCOTP_Type *base, uint32_t address);
+
+/*!
+ * @brief Read the fuse shadow register from the fuse addess.
+ *
+ * This function reads fuse from @p address, how many words to read is specified
+ * by the parameter @p fuseWords. This function could read at most
+ * OCOTP_READ_FUSE_DATA_COUNT fuse word one time.
+ *
+ * @param base OCOTP peripheral base address.
+ * @param address the fuse address to be read from.
+ * @param data Data array to save the readout fuse value.
+ * @param fuseWords How many words to read.
+ * @retval kStatus_Success Read success.
+ * @retval kStatus_Fail Error occurs during read.
+ */
+status_t OCOTP_ReadFuseShadowRegisterExt(OCOTP_Type *base, uint32_t address, uint32_t *data, uint8_t fuseWords);
+
+/*!
+ * @brief Write the fuse shadow register with the fuse addess and data.
+ * Please make sure the wrtie address is not locked while calling this API.
+ *
+ * @param base OCOTP peripheral base address.
+ * @param address the fuse address to be written.
+ * @param data the value will be writen to fuse address.
+ * @retval write status, kStatus_Success for success and kStatus_Fail for failed.
+ */
+status_t OCOTP_WriteFuseShadowRegister(OCOTP_Type *base, uint32_t address, uint32_t data);
+
+/*!
+ * @brief Write the fuse shadow register and lock it.
+ *
+ * Please make sure the wrtie address is not locked while calling this API.
+ *
+ * Some OCOTP controller supports ECC mode and redundancy mode (see reference mananual
+ * for more details). OCOTP controller will auto select ECC or redundancy
+ * mode to program the fuse word according to fuse map definition. In ECC mode, the
+ * 32 fuse bits in one word can only be written once. In redundancy mode, the word can
+ * be written more than once as long as they are different fuse bits. Set parameter
+ * @p lock as true to force use ECC mode.
+ *
+ * @param base OCOTP peripheral base address.
+ * @param address The fuse address to be written.
+ * @param data The value will be writen to fuse address.
+ * @param lock Lock or unlock write fuse shadow register operation.
+ * @retval kStatus_Success Program and reload success.
+ * @retval kStatus_OCOTP_Locked The eFuse word is locked and cannot be programmed.
+ * @retval kStatus_OCOTP_ProgramFail eFuse word programming failed.
+ * @retval kStatus_OCOTP_ReloadError eFuse word programming success, but
+ * error happens during reload the values.
+ * @retval kStatus_OCOTP_AccessError Cannot access eFuse word.
+ */
+status_t OCOTP_WriteFuseShadowRegisterWithLock(OCOTP_Type *base, uint32_t address, uint32_t data, bool lock);
+
+/*!
+ * @brief Get the OCOTP controller version from the register.
+ *
+ * @param base OCOTP peripheral base address.
+ * @retval return the version value.
+ */
+static inline uint32_t OCOTP_GetVersion(OCOTP_Type *base)
+{
+ return (base->VERSION);
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_OCOTP_H_ */