fsl_ocotp.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Copyright 2019-2020 NXP
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include "fsl_ocotp.h"
  8. /*******************************************************************************
  9. * Definitions
  10. ******************************************************************************/
  11. /* Component ID definition, used by tools. */
  12. #ifndef FSL_COMPONENT_ID
  13. #define FSL_COMPONENT_ID "platform.drivers.ocotp"
  14. #endif
  15. #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
  16. #define OCOTP_STATUS_READ_DED_MASK \
  17. (OCOTP_OUT_STATUS0_DED0_MASK | OCOTP_OUT_STATUS0_DED1_MASK | OCOTP_OUT_STATUS0_DED2_MASK | \
  18. OCOTP_OUT_STATUS0_DED3_MASK)
  19. #endif
  20. /* Wait time should be not less than 150ns . */
  21. #define OCOTP_TIMING_WAIT_NS (uint64_t)150
  22. /* Relex time should be not less than 100ns . */
  23. #define OCOTP_TIMING_RELEX_NS (uint64_t)100
  24. /* Program time should be rang from 9000ns~11000ns. */
  25. #define OCOTP_TIMING_PROGRAM_NS (uint64_t)10000
  26. /* Read time should be less than 40ns. */
  27. #define OCOTP_TIMING_READ_NS (uint64_t)40
  28. /* Unlock key is 0x3E77. */
  29. #define OCOTP_WRITE_UNLOCK_KEY (0x3E77)
  30. /*******************************************************************************
  31. * Prototypes
  32. ******************************************************************************/
  33. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  34. /*!
  35. * @brief Set read timing configuration.
  36. *
  37. * @param base OCOTP peripheral base addess.
  38. * @param timingConfig configuration of timing.
  39. */
  40. static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
  41. /*!
  42. * @brief Set write timing configuration.
  43. *
  44. * @param base OCOTP peripheral base addess.
  45. * @param timingConfig configuration of timing.
  46. */
  47. static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
  48. #endif
  49. /*******************************************************************************
  50. * Variables
  51. ******************************************************************************/
  52. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  53. /* Timing configuration for OCOTP controller. */
  54. static ocotp_timing_t s_timingConfig;
  55. #endif
  56. /*******************************************************************************
  57. * Code
  58. *******************************************************************************/
  59. /* Reload the shadow register. */
  60. status_t OCOTP_ReloadShadowRegister(OCOTP_Type *base)
  61. {
  62. assert(NULL != base);
  63. status_t status = kStatus_Success;
  64. /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
  65. while (OCOTP_CheckBusyStatus(base))
  66. {
  67. }
  68. /* Clear access error status bit. */
  69. OCOTP_ClearErrorStatus(base);
  70. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  71. /* Set the read timing. */
  72. OCOTP_SetReadTiming(base, s_timingConfig);
  73. /* Wait for the OCOTP controller not busy. */
  74. while (OCOTP_CheckBusyStatus(base))
  75. {
  76. }
  77. #endif
  78. #if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
  79. /* Clear reload error status. */
  80. base->OUT_STATUS0_CLR = OCOTP_OUT_STATUS0_DED_RELOAD_MASK;
  81. #endif
  82. /* Set reload bit. */
  83. base->CTRL_SET = OCOTP_CTRL_RELOAD_SHADOWS(1);
  84. /* Wait for the OCOTP controller not busy. */
  85. while (OCOTP_CheckBusyStatus(base))
  86. {
  87. }
  88. /* Wait for shadow register reload complete. this bit will be auto clear by OCOTP once operation is complete. */
  89. while (OCOTP_CTRL_RELOAD_SHADOWS_MASK == (base->CTRL & OCOTP_CTRL_RELOAD_SHADOWS_MASK))
  90. {
  91. }
  92. #if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
  93. if ((base->OUT_STATUS0 & OCOTP_OUT_STATUS0_DED_RELOAD_MASK) != 0U)
  94. {
  95. status = kStatus_OCOTP_ReloadError;
  96. }
  97. #endif
  98. return status;
  99. }
  100. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  101. static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
  102. {
  103. uint32_t timingValue = base->TIMING;
  104. timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_READ_MASK | OCOTP_TIMING_WAIT_MASK);
  105. timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_READ(timingConfig.strobe_read) |
  106. OCOTP_TIMING_WAIT(timingConfig.wait);
  107. base->TIMING = timingValue;
  108. }
  109. static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
  110. {
  111. uint32_t timingValue = base->TIMING;
  112. timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_PROG_MASK | OCOTP_TIMING_WAIT_MASK);
  113. timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_PROG(timingConfig.strobe_prog) |
  114. OCOTP_TIMING_WAIT(timingConfig.wait);
  115. base->TIMING = timingValue;
  116. }
  117. #endif
  118. /* Initializes OCOTP controller. */
  119. void OCOTP_Init(OCOTP_Type *base, uint32_t srcClock_Hz)
  120. {
  121. assert(NULL != base);
  122. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  123. assert(0UL != srcClock_Hz);
  124. #endif
  125. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  126. /* Enable OCOTP clock */
  127. CLOCK_EnableClock(kCLOCK_Ocotp);
  128. #endif
  129. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  130. /* tWait time shoule be higher than OCOTP_TIMING_WAIT_NS. */
  131. s_timingConfig.wait = (uint32_t)((OCOTP_TIMING_WAIT_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
  132. /* tRelax time shoule be higher than OCOTP_TIMING_RELEX_NS. */
  133. s_timingConfig.relax = (uint32_t)((OCOTP_TIMING_RELEX_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
  134. /* tStrobe_prog time should be close to OCOTP_TIMING_PROGRAM_NS, only add half of 1000000000. */
  135. s_timingConfig.strobe_prog = (uint32_t)((OCOTP_TIMING_PROGRAM_NS * srcClock_Hz + 500000000U) / 1000000000U) +
  136. 2U * (s_timingConfig.relax + 1U) - 1U;
  137. /* tStrobe_read time should be higher than OCOTP_TIMING_READ_NS. */
  138. s_timingConfig.strobe_read = (uint32_t)((OCOTP_TIMING_READ_NS * srcClock_Hz + 1000000000U) / 1000000000U) +
  139. 2U * (s_timingConfig.relax + 1U) - 1U;
  140. #endif
  141. }
  142. /* De-init OCOTP controller. */
  143. void OCOTP_Deinit(OCOTP_Type *base)
  144. {
  145. assert(NULL != base);
  146. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  147. s_timingConfig.wait = 0UL;
  148. s_timingConfig.relax = 0UL;
  149. s_timingConfig.strobe_prog = 0UL;
  150. s_timingConfig.strobe_read = 0UL;
  151. #endif
  152. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  153. /* Disable OCOTP clock */
  154. CLOCK_DisableClock(kCLOCK_Ocotp);
  155. #endif
  156. }
  157. /* Read the fuse shadow register. */
  158. uint32_t OCOTP_ReadFuseShadowRegister(OCOTP_Type *base, uint32_t address)
  159. {
  160. assert(NULL != base);
  161. uint32_t data = 0U;
  162. (void)OCOTP_ReadFuseShadowRegisterExt(base, address, &data, 1);
  163. return data;
  164. }
  165. status_t OCOTP_ReadFuseShadowRegisterExt(OCOTP_Type *base, uint32_t address, uint32_t *data, uint8_t fuseWords)
  166. {
  167. assert((fuseWords > 0U) && (fuseWords <= OCOTP_READ_FUSE_DATA_COUNT));
  168. assert(NULL != data);
  169. status_t status = kStatus_Success;
  170. #if (OCOTP_READ_FUSE_DATA_COUNT > 1U)
  171. uint32_t i;
  172. #endif
  173. /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
  174. while (OCOTP_CheckBusyStatus(base))
  175. {
  176. }
  177. /* If ERROR bit was set, clear access error status bit. */
  178. if (OCOTP_CheckErrorStatus(base))
  179. {
  180. OCOTP_ClearErrorStatus(base);
  181. }
  182. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  183. /* Set the read timing. */
  184. OCOTP_SetReadTiming(base, s_timingConfig);
  185. /* Wait for busy bit is cleared. */
  186. while (OCOTP_CheckBusyStatus(base))
  187. {
  188. }
  189. /* Clear access error status bit. */
  190. if (OCOTP_CheckErrorStatus(base))
  191. {
  192. OCOTP_ClearErrorStatus(base);
  193. }
  194. #endif
  195. #if defined(OCOTP_STATUS_READ_DED_MASK)
  196. /* Clear error flags. */
  197. base->OUT_STATUS0_CLR = OCOTP_STATUS_READ_DED_MASK;
  198. #endif
  199. /* Write requested address to register. */
  200. base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK;
  201. base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address);
  202. /* Set OCOTP auto read enable. */
  203. #if defined(OCOTP_READ_CTRL_READ_NUM_MASK)
  204. base->READ_CTRL = (base->READ_CTRL & ~(OCOTP_READ_CTRL_READ_NUM_MASK)) |
  205. OCOTP_READ_CTRL_READ_NUM((uint32_t)fuseWords - 1U) | OCOTP_READ_CTRL_READ_FUSE_MASK;
  206. #else
  207. base->READ_CTRL |= OCOTP_READ_CTRL_READ_FUSE_MASK;
  208. #endif
  209. /* Wait for busy bit is cleared, and no error occurred on controller. */
  210. while (OCOTP_CheckBusyStatus(base))
  211. {
  212. }
  213. /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
  214. if (OCOTP_CheckErrorStatus(base))
  215. {
  216. /* Clear access error status bit. */
  217. OCOTP_ClearErrorStatus(base);
  218. status = kStatus_OCOTP_AccessError;
  219. }
  220. #if defined(OCOTP_STATUS_READ_DED_MASK)
  221. if ((base->OUT_STATUS0 & OCOTP_STATUS_READ_DED_MASK) != 0U)
  222. {
  223. status = kStatus_Fail;
  224. }
  225. #endif
  226. #if (OCOTP_READ_FUSE_DATA_COUNT == 1U)
  227. *data = base->READ_FUSE_DATA;
  228. #else
  229. for (i = 0; i < fuseWords; i++)
  230. {
  231. data[i] = base->READ_FUSE_DATAS[i].READ_FUSE_DATA;
  232. }
  233. #endif
  234. return status;
  235. }
  236. /* Write the fuse shadow register. */
  237. status_t OCOTP_WriteFuseShadowRegister(OCOTP_Type *base, uint32_t address, uint32_t data)
  238. {
  239. return OCOTP_WriteFuseShadowRegisterWithLock(base, address, data, false);
  240. }
  241. status_t OCOTP_WriteFuseShadowRegisterWithLock(OCOTP_Type *base, uint32_t address, uint32_t data, bool lock)
  242. {
  243. assert(NULL != base);
  244. status_t status = kStatus_Success;
  245. #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
  246. uint32_t regStatus;
  247. #endif
  248. #if !(defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
  249. if (lock)
  250. {
  251. return kStatus_InvalidArgument;
  252. }
  253. #endif
  254. /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
  255. while (OCOTP_CheckBusyStatus(base))
  256. {
  257. }
  258. /* Clear access error status bit. */
  259. if (OCOTP_CheckErrorStatus(base))
  260. {
  261. OCOTP_ClearErrorStatus(base);
  262. }
  263. #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
  264. /* Set write timing for OCOTP controller. */
  265. OCOTP_SetWriteTiming(base, s_timingConfig);
  266. /* Wait for busy bit is cleared. */
  267. while (OCOTP_CheckBusyStatus(base))
  268. {
  269. }
  270. /* Clear access error status bit. */
  271. if (OCOTP_CheckErrorStatus(base))
  272. {
  273. OCOTP_ClearErrorStatus(base);
  274. }
  275. #endif
  276. #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
  277. /* Clear errors. */
  278. base->OUT_STATUS0_CLR = (OCOTP_OUT_STATUS0_PROGFAIL_MASK | OCOTP_OUT_STATUS0_LOCKED_MASK);
  279. #endif
  280. /* Write requested address and unlock key to register. */
  281. #if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
  282. base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK | OCOTP_CTRL_WORDLOCK_MASK;
  283. #else
  284. base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK;
  285. #endif
  286. #if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
  287. if (lock)
  288. {
  289. base->CTRL_SET =
  290. OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY) | OCOTP_CTRL_WORDLOCK_MASK;
  291. }
  292. else
  293. #endif
  294. {
  295. base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY);
  296. }
  297. /* Write data to register. */
  298. base->DATA = data;
  299. /* Wait for busy bit is cleared, and no error occurred on controller. */
  300. while (OCOTP_CheckBusyStatus(base))
  301. {
  302. }
  303. /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
  304. if (OCOTP_CheckErrorStatus(base))
  305. {
  306. /* Clear access error status bit. */
  307. OCOTP_ClearErrorStatus(base);
  308. status = kStatus_OCOTP_AccessError;
  309. }
  310. #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
  311. regStatus = base->OUT_STATUS0;
  312. if ((regStatus & OCOTP_OUT_STATUS0_PROGFAIL_MASK) != 0U)
  313. {
  314. status = kStatus_OCOTP_ProgramFail;
  315. }
  316. else if ((regStatus & OCOTP_OUT_STATUS0_LOCKED_MASK) != 0U)
  317. {
  318. status = kStatus_OCOTP_Locked;
  319. }
  320. else
  321. {
  322. /* For MISRA rules. */
  323. }
  324. #endif
  325. if (kStatus_Success == status)
  326. {
  327. /* Reload the fuse register. */
  328. status = OCOTP_ReloadShadowRegister(base);
  329. }
  330. return status;
  331. }