lpc_eeprom.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**********************************************************************
  2. * $Id$ lpc_eeprom.c 2011-06-02
  3. *//**
  4. * @file lpc_eeprom.c
  5. * @brief Contains all functions support for EEPROM firmware library on
  6. * LPC
  7. * @version 1.0
  8. * @date 02. June. 2011
  9. * @author NXP MCU SW Application Team
  10. *
  11. * Copyright(C) 2011, NXP Semiconductor
  12. * All rights reserved.
  13. *
  14. ***********************************************************************
  15. * Software that is described herein is for illustrative purposes only
  16. * which provides customers with programming information regarding the
  17. * products. This software is supplied "AS IS" without any warranties.
  18. * NXP Semiconductors assumes no responsibility or liability for the
  19. * use of the software, conveys no license or title under any patent,
  20. * copyright, or mask work right to the product. NXP Semiconductors
  21. * reserves the right to make changes in the software without
  22. * notification. NXP Semiconductors also make no representation or
  23. * warranty that such application will be suitable for the specified
  24. * use without further testing or modification.
  25. * Permission to use, copy, modify, and distribute this software and its
  26. * documentation is hereby granted, under NXP Semiconductors'
  27. * relevant copyright in the software, without fee, provided that it
  28. * is used in conjunction with NXP Semiconductors microcontrollers. This
  29. * copyright, permission, and disclaimer notice must appear in all copies of
  30. * this code.
  31. **********************************************************************/
  32. /* Peripheral group ----------------------------------------------------------- */
  33. /** @addtogroup EEPROM
  34. * @{
  35. */
  36. #ifdef __BUILD_WITH_EXAMPLE__
  37. #include "lpc_libcfg.h"
  38. #else
  39. #include "lpc_libcfg_default.h"
  40. #endif /* __BUILD_WITH_EXAMPLE__ */
  41. #ifdef _EEPROM
  42. /* Includes ------------------------------------------------------------------- */
  43. #include "lpc_eeprom.h"
  44. #include "lpc_clkpwr.h"
  45. /* Public Functions ----------------------------------------------------------- */
  46. /*********************************************************************//**
  47. * @brief Initial EEPROM
  48. * @param[in] None
  49. * @return None
  50. **********************************************************************/
  51. void EEPROM_Init(void)
  52. {
  53. uint32_t val, cclk;
  54. LPC_EEPROM->PWRDWN = 0x0;
  55. /* EEPROM is automate turn on after reset */
  56. /* Setting clock:
  57. * EEPROM required a 375kHz. This clock is generated by dividing the
  58. * system bus clock.
  59. */
  60. cclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU);
  61. val = (cclk/375000)-1;
  62. LPC_EEPROM->CLKDIV = val;
  63. /* Setting wait state */
  64. val = ((((cclk / 1000000) * 15) / 1000) + 1);
  65. val |= (((((cclk / 1000000) * 55) / 1000) + 1) << 8);
  66. val |= (((((cclk / 1000000) * 35) / 1000) + 1) << 16);
  67. LPC_EEPROM->WSTATE = val;
  68. }
  69. /*********************************************************************//**
  70. * @brief Write data to EEPROM at specific address
  71. * @param[in] page_offset offset of data in page register(0 - 63)
  72. * page_address page address (0-62)
  73. * mode Write mode, should be:
  74. * - MODE_8_BIT : write 8 bit mode
  75. * - MODE_16_BIT : write 16 bit mode
  76. * - MODE_32_BIT : write 32 bit mode
  77. * data buffer that contain data that will be written to buffer
  78. * count number written data
  79. * @return None
  80. * @note This function actually write data into EEPROM memory and automatically
  81. * write into next page if current page is overflowed
  82. **********************************************************************/
  83. void EEPROM_Write(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t count)
  84. {
  85. uint32_t i;
  86. uint8_t *tmp8 = (uint8_t *)data;
  87. uint16_t *tmp16 = (uint16_t *)data;
  88. uint32_t *tmp32 = (uint32_t *)data;
  89. LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG));
  90. //check page_offset
  91. if(mode == MODE_16_BIT){
  92. if((page_offset & 0x01)!=0) while(1);
  93. }
  94. else if(mode == MODE_32_BIT){
  95. if((page_offset & 0x03)!=0) while(1);
  96. }
  97. LPC_EEPROM->ADDR = EEPROM_PAGE_OFFSET(page_offset);
  98. for(i=0;i<count;i++)
  99. {
  100. //update data to page register
  101. if(mode == MODE_8_BIT){
  102. LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_WRITE;
  103. LPC_EEPROM -> WDATA = *tmp8;
  104. tmp8++;
  105. page_offset +=1;
  106. }
  107. else if(mode == MODE_16_BIT){
  108. LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_WRITE;
  109. LPC_EEPROM -> WDATA = *tmp16;
  110. tmp16++;
  111. page_offset +=2;
  112. }
  113. else{
  114. LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_WRITE;
  115. LPC_EEPROM -> WDATA = *tmp32;
  116. tmp32++;
  117. page_offset +=4;
  118. }
  119. while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_RW)&0x01));
  120. LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_RW);
  121. if((page_offset >= EEPROM_PAGE_SIZE)|(i==count-1)){
  122. //update to EEPROM memory
  123. LPC_EEPROM->INT_CLR_STATUS = (0x1 << EEPROM_ENDOF_PROG);
  124. LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address);
  125. LPC_EEPROM->CMD = EEPROM_CMD_ERASE_PRG_PAGE;
  126. while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_PROG)&0x01));
  127. LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_PROG);
  128. }
  129. if(page_offset >= EEPROM_PAGE_SIZE)
  130. {
  131. page_offset = 0;
  132. page_address +=1;
  133. LPC_EEPROM->ADDR =0;
  134. if(page_address > EEPROM_PAGE_NUM - 1) page_address = 0;
  135. }
  136. }
  137. }
  138. /*********************************************************************//**
  139. * @brief Read data to EEPROM at specific address
  140. * @param[in]
  141. * data buffer that contain data that will be written to buffer
  142. * mode Read mode, should be:
  143. * - MODE_8_BIT : read 8 bit mode
  144. * - MODE_16_BIT : read 16 bit mode
  145. * - MODE_32_BIT : read 32 bit mode
  146. * count number read data (bytes)
  147. * @return data buffer that contain data that will be read to buffer
  148. **********************************************************************/
  149. void EEPROM_Read(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t count)
  150. {
  151. uint32_t i;
  152. uint8_t *tmp8 = (uint8_t *)data;
  153. uint16_t *tmp16 = (uint16_t *)data;
  154. uint32_t *tmp32 = (uint32_t *)data;
  155. LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG));
  156. LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address)|EEPROM_PAGE_OFFSET(page_offset);
  157. if(mode == MODE_8_BIT)
  158. LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_READ|EEPROM_CMD_RDPREFETCH;
  159. else if(mode == MODE_16_BIT){
  160. LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_READ|EEPROM_CMD_RDPREFETCH;
  161. //check page_offset
  162. if((page_offset &0x01)!=0)
  163. return;
  164. }
  165. else{
  166. LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_READ|EEPROM_CMD_RDPREFETCH;
  167. //page_offset must be a multiple of 0x04
  168. if((page_offset & 0x03)!=0)
  169. return;
  170. }
  171. //read and store data in buffer
  172. for(i=0;i<count;i++){
  173. if(mode == MODE_8_BIT){
  174. *tmp8 = (uint8_t)(LPC_EEPROM -> RDATA);
  175. tmp8++;
  176. page_offset +=1;
  177. }
  178. else if (mode == MODE_16_BIT)
  179. {
  180. *tmp16 = (uint16_t)(LPC_EEPROM -> RDATA);
  181. tmp16++;
  182. page_offset +=2;
  183. }
  184. else{
  185. *tmp32 = (uint32_t)(LPC_EEPROM ->RDATA);
  186. tmp32++;
  187. page_offset +=4;
  188. }
  189. while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_RW)&0x01));
  190. LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_RW);
  191. if((page_offset >= EEPROM_PAGE_SIZE) && (i < count - 1)) {
  192. page_offset = 0;
  193. page_address++;
  194. LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address)|EEPROM_PAGE_OFFSET(page_offset);
  195. if(mode == MODE_8_BIT)
  196. LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_READ|EEPROM_CMD_RDPREFETCH;
  197. else if(mode == MODE_16_BIT)
  198. LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_READ|EEPROM_CMD_RDPREFETCH;
  199. else
  200. LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_READ|EEPROM_CMD_RDPREFETCH;
  201. }
  202. }
  203. }
  204. /*********************************************************************//**
  205. * @brief Erase a page at the specific address
  206. * @param[in] address EEPROM page address (0-62)
  207. * @return data buffer that contain data that will be read to buffer
  208. **********************************************************************/
  209. void EEPROM_Erase(uint16_t page_address)
  210. {
  211. uint32_t i;
  212. uint32_t count = EEPROM_PAGE_SIZE/4;
  213. LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG));
  214. //clear page register
  215. LPC_EEPROM->ADDR = EEPROM_PAGE_OFFSET(0);
  216. LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_WRITE;
  217. for(i=0;i<count;i++)
  218. {
  219. LPC_EEPROM->WDATA = 0;
  220. while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_RW)&0x01));
  221. LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_RW);
  222. }
  223. LPC_EEPROM->INT_CLR_STATUS = (0x1 << EEPROM_ENDOF_PROG);
  224. LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address);
  225. LPC_EEPROM->CMD = EEPROM_CMD_ERASE_PRG_PAGE;
  226. while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_PROG)&0x01));
  227. LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_PROG);
  228. }
  229. /*********************************************************************//**
  230. * @brief Enable/Disable EEPROM power down mdoe
  231. * @param[in] NewState PowerDown mode state, should be:
  232. * - ENABLE: Enable power down mode
  233. * - DISABLE: Disable power down mode
  234. * @return None
  235. **********************************************************************/
  236. void EEPROM_PowerDown(FunctionalState NewState)
  237. {
  238. if(NewState == ENABLE)
  239. LPC_EEPROM->PWRDWN = 0x1;
  240. else
  241. LPC_EEPROM->PWRDWN = 0x0;
  242. }
  243. #endif /*_EEPROM*/
  244. /**
  245. * @}
  246. */
  247. /* --------------------------------- End Of File ------------------------------ */