Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:00

0001 /*
0002  * Copyright 2019-2020 NXP
0003  * All rights reserved.
0004  *
0005  * SPDX-License-Identifier: BSD-3-Clause
0006  */
0007 
0008 #include "fsl_ocotp.h"
0009 
0010 /*******************************************************************************
0011  * Definitions
0012  ******************************************************************************/
0013 /* Component ID definition, used by tools. */
0014 #ifndef FSL_COMPONENT_ID
0015 #define FSL_COMPONENT_ID "platform.drivers.ocotp"
0016 #endif
0017 
0018 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
0019 #define OCOTP_STATUS_READ_DED_MASK                                                             \
0020     (OCOTP_OUT_STATUS0_DED0_MASK | OCOTP_OUT_STATUS0_DED1_MASK | OCOTP_OUT_STATUS0_DED2_MASK | \
0021      OCOTP_OUT_STATUS0_DED3_MASK)
0022 #endif
0023 
0024 /* Wait time should be not less than 150ns . */
0025 #define OCOTP_TIMING_WAIT_NS (uint64_t)150
0026 /* Relex time should be not less than 100ns . */
0027 #define OCOTP_TIMING_RELEX_NS (uint64_t)100
0028 /* Program time should be rang from 9000ns~11000ns. */
0029 #define OCOTP_TIMING_PROGRAM_NS (uint64_t)10000
0030 /* Read time should be less than 40ns. */
0031 #define OCOTP_TIMING_READ_NS (uint64_t)40
0032 
0033 /* Unlock key is 0x3E77. */
0034 #define OCOTP_WRITE_UNLOCK_KEY (0x3E77)
0035 /*******************************************************************************
0036  * Prototypes
0037  ******************************************************************************/
0038 
0039 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0040 /*!
0041  * @brief Set read timing configuration.
0042  *
0043  * @param base          OCOTP peripheral base addess.
0044  * @param timingConfig  configuration of timing.
0045  */
0046 static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
0047 
0048 /*!
0049  * @brief Set write timing configuration.
0050  *
0051  * @param base          OCOTP peripheral base addess.
0052  * @param timingConfig  configuration of timing.
0053  */
0054 static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
0055 #endif
0056 
0057 /*******************************************************************************
0058  * Variables
0059  ******************************************************************************/
0060 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0061 /* Timing configuration for OCOTP controller. */
0062 static ocotp_timing_t s_timingConfig;
0063 #endif
0064 
0065 /*******************************************************************************
0066  * Code
0067  *******************************************************************************/
0068 /* Reload the shadow register. */
0069 status_t OCOTP_ReloadShadowRegister(OCOTP_Type *base)
0070 {
0071     assert(NULL != base);
0072 
0073     status_t status = kStatus_Success;
0074 
0075     /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
0076     while (OCOTP_CheckBusyStatus(base))
0077     {
0078     }
0079 
0080     /* Clear access error status bit. */
0081     OCOTP_ClearErrorStatus(base);
0082 
0083 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0084     /* Set the read timing. */
0085     OCOTP_SetReadTiming(base, s_timingConfig);
0086 
0087     /* Wait for the OCOTP controller not busy. */
0088     while (OCOTP_CheckBusyStatus(base))
0089     {
0090     }
0091 #endif
0092 
0093 #if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
0094     /* Clear reload error status. */
0095     base->OUT_STATUS0_CLR = OCOTP_OUT_STATUS0_DED_RELOAD_MASK;
0096 #endif
0097 
0098     /* Set reload bit. */
0099     base->CTRL_SET = OCOTP_CTRL_RELOAD_SHADOWS(1);
0100 
0101     /* Wait for the OCOTP controller not busy. */
0102     while (OCOTP_CheckBusyStatus(base))
0103     {
0104     }
0105     /* Wait for shadow register reload complete. this bit will be auto clear by OCOTP once operation is complete. */
0106     while (OCOTP_CTRL_RELOAD_SHADOWS_MASK == (base->CTRL & OCOTP_CTRL_RELOAD_SHADOWS_MASK))
0107     {
0108     }
0109 
0110 #if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
0111     if ((base->OUT_STATUS0 & OCOTP_OUT_STATUS0_DED_RELOAD_MASK) != 0U)
0112     {
0113         status = kStatus_OCOTP_ReloadError;
0114     }
0115 #endif
0116 
0117     return status;
0118 }
0119 
0120 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0121 static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
0122 {
0123     uint32_t timingValue = base->TIMING;
0124 
0125     timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_READ_MASK | OCOTP_TIMING_WAIT_MASK);
0126     timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_READ(timingConfig.strobe_read) |
0127                    OCOTP_TIMING_WAIT(timingConfig.wait);
0128     base->TIMING = timingValue;
0129 }
0130 
0131 static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
0132 {
0133     uint32_t timingValue = base->TIMING;
0134 
0135     timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_PROG_MASK | OCOTP_TIMING_WAIT_MASK);
0136     timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_PROG(timingConfig.strobe_prog) |
0137                    OCOTP_TIMING_WAIT(timingConfig.wait);
0138 
0139     base->TIMING = timingValue;
0140 }
0141 #endif
0142 
0143 /* Initializes OCOTP controller. */
0144 void OCOTP_Init(OCOTP_Type *base, uint32_t srcClock_Hz)
0145 {
0146     assert(NULL != base);
0147 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0148     assert(0UL != srcClock_Hz);
0149 #endif
0150 
0151 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0152     /* Enable OCOTP clock */
0153     CLOCK_EnableClock(kCLOCK_Ocotp);
0154 #endif
0155 
0156 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0157     /* tWait time shoule be higher than OCOTP_TIMING_WAIT_NS. */
0158     s_timingConfig.wait = (uint32_t)((OCOTP_TIMING_WAIT_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
0159 
0160     /* tRelax time shoule be higher than OCOTP_TIMING_RELEX_NS. */
0161     s_timingConfig.relax = (uint32_t)((OCOTP_TIMING_RELEX_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
0162 
0163     /* tStrobe_prog time should be close to OCOTP_TIMING_PROGRAM_NS, only add half of 1000000000. */
0164     s_timingConfig.strobe_prog = (uint32_t)((OCOTP_TIMING_PROGRAM_NS * srcClock_Hz + 500000000U) / 1000000000U) +
0165                                  2U * (s_timingConfig.relax + 1U) - 1U;
0166 
0167     /* tStrobe_read time should be higher than OCOTP_TIMING_READ_NS. */
0168     s_timingConfig.strobe_read = (uint32_t)((OCOTP_TIMING_READ_NS * srcClock_Hz + 1000000000U) / 1000000000U) +
0169                                  2U * (s_timingConfig.relax + 1U) - 1U;
0170 #endif
0171 }
0172 
0173 /* De-init OCOTP controller. */
0174 void OCOTP_Deinit(OCOTP_Type *base)
0175 {
0176     assert(NULL != base);
0177 
0178 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0179     s_timingConfig.wait        = 0UL;
0180     s_timingConfig.relax       = 0UL;
0181     s_timingConfig.strobe_prog = 0UL;
0182     s_timingConfig.strobe_read = 0UL;
0183 #endif
0184 
0185 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0186     /* Disable OCOTP clock */
0187     CLOCK_DisableClock(kCLOCK_Ocotp);
0188 #endif
0189 }
0190 
0191 /* Read the fuse shadow register. */
0192 uint32_t OCOTP_ReadFuseShadowRegister(OCOTP_Type *base, uint32_t address)
0193 {
0194     assert(NULL != base);
0195 
0196     uint32_t data = 0U;
0197 
0198     (void)OCOTP_ReadFuseShadowRegisterExt(base, address, &data, 1);
0199 
0200     return data;
0201 }
0202 
0203 status_t OCOTP_ReadFuseShadowRegisterExt(OCOTP_Type *base, uint32_t address, uint32_t *data, uint8_t fuseWords)
0204 {
0205     assert((fuseWords > 0U) && (fuseWords <= OCOTP_READ_FUSE_DATA_COUNT));
0206     assert(NULL != data);
0207 
0208     status_t status = kStatus_Success;
0209 
0210 #if (OCOTP_READ_FUSE_DATA_COUNT > 1U)
0211     uint32_t i;
0212 #endif
0213 
0214     /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
0215     while (OCOTP_CheckBusyStatus(base))
0216     {
0217     }
0218 
0219     /* If ERROR bit was set, clear access error status bit. */
0220     if (OCOTP_CheckErrorStatus(base))
0221     {
0222         OCOTP_ClearErrorStatus(base);
0223     }
0224 
0225 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0226     /* Set the read timing. */
0227     OCOTP_SetReadTiming(base, s_timingConfig);
0228 
0229     /* Wait for busy bit is cleared. */
0230     while (OCOTP_CheckBusyStatus(base))
0231     {
0232     }
0233 
0234     /* Clear access error status bit. */
0235     if (OCOTP_CheckErrorStatus(base))
0236     {
0237         OCOTP_ClearErrorStatus(base);
0238     }
0239 #endif
0240 
0241 #if defined(OCOTP_STATUS_READ_DED_MASK)
0242     /* Clear error flags. */
0243     base->OUT_STATUS0_CLR = OCOTP_STATUS_READ_DED_MASK;
0244 #endif
0245 
0246     /* Write requested address to register. */
0247     base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK;
0248     base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address);
0249 
0250     /* Set OCOTP auto read enable. */
0251 #if defined(OCOTP_READ_CTRL_READ_NUM_MASK)
0252     base->READ_CTRL = (base->READ_CTRL & ~(OCOTP_READ_CTRL_READ_NUM_MASK)) |
0253                       OCOTP_READ_CTRL_READ_NUM((uint32_t)fuseWords - 1U) | OCOTP_READ_CTRL_READ_FUSE_MASK;
0254 #else
0255     base->READ_CTRL |= OCOTP_READ_CTRL_READ_FUSE_MASK;
0256 #endif
0257 
0258     /* Wait for busy bit is cleared, and no error occurred on controller. */
0259     while (OCOTP_CheckBusyStatus(base))
0260     {
0261     }
0262 
0263     /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
0264     if (OCOTP_CheckErrorStatus(base))
0265     {
0266         /* Clear access error status bit. */
0267         OCOTP_ClearErrorStatus(base);
0268 
0269         status = kStatus_OCOTP_AccessError;
0270     }
0271 
0272 #if defined(OCOTP_STATUS_READ_DED_MASK)
0273     if ((base->OUT_STATUS0 & OCOTP_STATUS_READ_DED_MASK) != 0U)
0274     {
0275         status = kStatus_Fail;
0276     }
0277 #endif
0278 
0279 #if (OCOTP_READ_FUSE_DATA_COUNT == 1U)
0280     *data = base->READ_FUSE_DATA;
0281 #else
0282     for (i = 0; i < fuseWords; i++)
0283     {
0284         data[i] = base->READ_FUSE_DATAS[i].READ_FUSE_DATA;
0285     }
0286 #endif
0287 
0288     return status;
0289 }
0290 
0291 /* Write the fuse shadow register. */
0292 status_t OCOTP_WriteFuseShadowRegister(OCOTP_Type *base, uint32_t address, uint32_t data)
0293 {
0294     return OCOTP_WriteFuseShadowRegisterWithLock(base, address, data, false);
0295 }
0296 
0297 status_t OCOTP_WriteFuseShadowRegisterWithLock(OCOTP_Type *base, uint32_t address, uint32_t data, bool lock)
0298 {
0299     assert(NULL != base);
0300 
0301     status_t status = kStatus_Success;
0302 
0303 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
0304     uint32_t regStatus;
0305 #endif
0306 
0307 #if !(defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
0308     if (lock)
0309     {
0310         return kStatus_InvalidArgument;
0311     }
0312 #endif
0313 
0314     /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
0315     while (OCOTP_CheckBusyStatus(base))
0316     {
0317     }
0318 
0319     /* Clear access error status bit. */
0320     if (OCOTP_CheckErrorStatus(base))
0321     {
0322         OCOTP_ClearErrorStatus(base);
0323     }
0324 
0325 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
0326     /* Set write timing for OCOTP controller. */
0327     OCOTP_SetWriteTiming(base, s_timingConfig);
0328 
0329     /* Wait for busy bit is cleared. */
0330     while (OCOTP_CheckBusyStatus(base))
0331     {
0332     }
0333 
0334     /* Clear access error status bit. */
0335     if (OCOTP_CheckErrorStatus(base))
0336     {
0337         OCOTP_ClearErrorStatus(base);
0338     }
0339 #endif
0340 
0341 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
0342     /* Clear errors. */
0343     base->OUT_STATUS0_CLR = (OCOTP_OUT_STATUS0_PROGFAIL_MASK | OCOTP_OUT_STATUS0_LOCKED_MASK);
0344 #endif
0345 
0346     /* Write requested address and unlock key to register. */
0347 #if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
0348     base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK | OCOTP_CTRL_WORDLOCK_MASK;
0349 #else
0350     base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK;
0351 #endif
0352 
0353 #if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
0354     if (lock)
0355     {
0356         base->CTRL_SET =
0357             OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY) | OCOTP_CTRL_WORDLOCK_MASK;
0358     }
0359     else
0360 #endif
0361     {
0362         base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY);
0363     }
0364 
0365     /* Write data to register. */
0366     base->DATA = data;
0367 
0368     /* Wait for busy bit is cleared, and no error occurred on controller. */
0369     while (OCOTP_CheckBusyStatus(base))
0370     {
0371     }
0372 
0373     /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
0374     if (OCOTP_CheckErrorStatus(base))
0375     {
0376         /* Clear access error status bit. */
0377         OCOTP_ClearErrorStatus(base);
0378 
0379         status = kStatus_OCOTP_AccessError;
0380     }
0381 
0382 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
0383     regStatus = base->OUT_STATUS0;
0384 
0385     if ((regStatus & OCOTP_OUT_STATUS0_PROGFAIL_MASK) != 0U)
0386     {
0387         status = kStatus_OCOTP_ProgramFail;
0388     }
0389     else if ((regStatus & OCOTP_OUT_STATUS0_LOCKED_MASK) != 0U)
0390     {
0391         status = kStatus_OCOTP_Locked;
0392     }
0393     else
0394     {
0395         /* For MISRA rules. */
0396     }
0397 #endif
0398 
0399     if (kStatus_Success == status)
0400     {
0401         /* Reload the fuse register. */
0402         status = OCOTP_ReloadShadowRegister(base);
0403     }
0404 
0405     return status;
0406 }