fsl_eeprom.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_eeprom.h"
  31. /*******************************************************************************
  32. * Definitions
  33. ******************************************************************************/
  34. /*******************************************************************************
  35. * Prototypes
  36. ******************************************************************************/
  37. /*!
  38. * @brief Get the EEPROM instance from peripheral base address.
  39. *
  40. * @param base EEPROM peripheral base address.
  41. * @return EEPROM instance.
  42. */
  43. static uint32_t EEPROM_GetInstance(EEPROM_Type *base);
  44. /*******************************************************************************
  45. * Variables
  46. ******************************************************************************/
  47. /* Array of EEPROM peripheral base address. */
  48. static EEPROM_Type *const s_eepromBases[] = EEPROM_BASE_PTRS;
  49. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  50. /* Array of EEPROM clock name. */
  51. static const clock_ip_name_t s_eepromClock[] = EEPROM_CLOCKS;
  52. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  53. /*******************************************************************************
  54. * Code
  55. ******************************************************************************/
  56. static uint32_t EEPROM_GetInstance(EEPROM_Type *base)
  57. {
  58. uint32_t instance;
  59. /* Find the instance index from base address mappings. */
  60. for (instance = 0; instance < ARRAY_SIZE(s_eepromBases); instance++)
  61. {
  62. if (s_eepromBases[instance] == base)
  63. {
  64. break;
  65. }
  66. }
  67. assert(instance < ARRAY_SIZE(s_eepromBases));
  68. return instance;
  69. }
  70. void EEPROM_GetDefaultConfig(eeprom_config_t *config)
  71. {
  72. config->autoProgram = kEEPROM_AutoProgramWriteWord;
  73. config->writeWaitPhase1 = 0x5U;
  74. config->writeWaitPhase2 = 0x9U;
  75. config->writeWaitPhase3 = 0x3U;
  76. config->readWaitPhase1 = 0xFU;
  77. config->readWaitPhase2 = 0x8U;
  78. config->lockTimingParam = false;
  79. }
  80. void EEPROM_Init(EEPROM_Type *base, const eeprom_config_t *config, uint32_t sourceClock_Hz)
  81. {
  82. assert(config);
  83. uint32_t clockDiv = 0;
  84. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  85. /* Enable the SAI clock */
  86. CLOCK_EnableClock(s_eepromClock[EEPROM_GetInstance(base)]);
  87. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  88. /* Set the clock divider */
  89. clockDiv = sourceClock_Hz / FSL_FEATURE_EEPROM_INTERNAL_FREQ;
  90. if ((sourceClock_Hz % FSL_FEATURE_EEPROM_INTERNAL_FREQ) > (FSL_FEATURE_EEPROM_INTERNAL_FREQ / 2U))
  91. {
  92. clockDiv += 1U;
  93. }
  94. base->CLKDIV = clockDiv - 1U;
  95. /* Set the auto program feature */
  96. EEPROM_SetAutoProgram(base, config->autoProgram);
  97. /* Set time delay parameter */
  98. base->RWSTATE =
  99. EEPROM_RWSTATE_RPHASE1(config->readWaitPhase1 - 1U) | EEPROM_RWSTATE_RPHASE2(config->readWaitPhase2 - 1U);
  100. base->WSTATE = EEPROM_WSTATE_PHASE1(config->writeWaitPhase1 - 1U) |
  101. EEPROM_WSTATE_PHASE2(config->writeWaitPhase2 - 1U) |
  102. EEPROM_WSTATE_PHASE3(config->writeWaitPhase3 - 1U);
  103. base->WSTATE |= EEPROM_WSTATE_LCK_PARWEP(config->lockTimingParam);
  104. /* Clear the remaining write operation */
  105. base->CMD = FSL_FEATURE_EEPROM_PROGRAM_CMD;
  106. while ((EEPROM_GetInterruptStatus(base) & kEEPROM_ProgramFinishInterruptEnable) == 0U)
  107. {}
  108. }
  109. void EEPROM_Deinit(EEPROM_Type *base)
  110. {
  111. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  112. /* Enable the SAI clock */
  113. CLOCK_DisableClock(s_eepromClock[EEPROM_GetInstance(base)]);
  114. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  115. }
  116. status_t EEPROM_WriteWord(EEPROM_Type *base, uint32_t offset, uint32_t data)
  117. {
  118. uint32_t *addr = 0;
  119. if ((offset % 4U) || (offset > FSL_FEATURE_EEPROM_SIZE))
  120. {
  121. return kStatus_InvalidArgument;
  122. }
  123. /* Set auto program settings */
  124. if (base->AUTOPROG != kEEPROM_AutoProgramDisable)
  125. {
  126. EEPROM_SetAutoProgram(base, kEEPROM_AutoProgramWriteWord);
  127. }
  128. EEPROM_ClearInterruptFlag(base, kEEPROM_ProgramFinishInterruptEnable);
  129. /* Compute the page */
  130. addr = (uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS + offset);
  131. *addr = data;
  132. /* Check if need to do program erase manually */
  133. if (base->AUTOPROG != kEEPROM_AutoProgramWriteWord)
  134. {
  135. base->CMD = FSL_FEATURE_EEPROM_PROGRAM_CMD;
  136. }
  137. /* Waiting for operation finished */
  138. while ((EEPROM_GetInterruptStatus(base) & kEEPROM_ProgramFinishInterruptEnable) == 0U)
  139. {}
  140. return kStatus_Success;
  141. }
  142. status_t EEPROM_WritePage(EEPROM_Type *base, uint32_t pageNum, uint32_t *data)
  143. {
  144. uint32_t i = 0;
  145. uint32_t *addr = NULL;
  146. if ((pageNum > FSL_FEATURE_EEPROM_PAGE_COUNT) || (!data))
  147. {
  148. return kStatus_InvalidArgument;
  149. }
  150. /* Set auto program settings */
  151. if (base->AUTOPROG != kEEPROM_AutoProgramDisable)
  152. {
  153. EEPROM_SetAutoProgram(base, kEEPROM_AutoProgramLastWord);
  154. }
  155. EEPROM_ClearInterruptFlag(base, kEEPROM_ProgramFinishInterruptEnable);
  156. addr = (uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS + pageNum * (FSL_FEATURE_EEPROM_SIZE/FSL_FEATURE_EEPROM_PAGE_COUNT));
  157. for (i = 0; i < (FSL_FEATURE_EEPROM_SIZE/FSL_FEATURE_EEPROM_PAGE_COUNT) / 4U; i++)
  158. {
  159. addr[i] = data[i];
  160. }
  161. if (base->AUTOPROG == kEEPROM_AutoProgramDisable)
  162. {
  163. base->CMD = FSL_FEATURE_EEPROM_PROGRAM_CMD;
  164. }
  165. /* Waiting for operation finished */
  166. while ((EEPROM_GetInterruptStatus(base) & kEEPROM_ProgramFinishInterruptEnable) == 0U)
  167. {}
  168. return kStatus_Success;
  169. }