stm322xg_eval_eeprom.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /**
  2. ******************************************************************************
  3. * @file stm322xg_eval_eeprom.c
  4. * @author MCD Application Team
  5. * @brief This file provides a set of functions needed to manage an I2C M24C64
  6. * EEPROM memory.
  7. *
  8. * ===================================================================
  9. * Notes:
  10. * - This driver is intended for STM32F2xx families devices only.
  11. * - The I2C EEPROM memory (M24C64) is available on STM322xG-EVAL
  12. * - To use this driver you have to connect the eeprom jumper (JP24).
  13. * ===================================================================
  14. *
  15. * It implements a high level communication layer for read and write
  16. * from/to this memory. The needed STM32F2xx hardware resources (I2C and
  17. * GPIO) are defined in stm32f2xg_eval.h file, and the initialization is
  18. * performed in EEPROM_IO_Init() function declared in stm32f2xg_eval.c
  19. * file.
  20. * You can easily tailor this driver to any other development board,
  21. * by just adapting the defines for hardware resources and
  22. * EEPROM_IO_Init() function.
  23. *
  24. * @note In this driver, basic read and write functions (BSP_EEPROM_ReadBuffer()
  25. * and EEPROM_WritePage()) use Polling mode to perform the data transfer
  26. * to/from EEPROM memory.
  27. *
  28. * +-----------------------------------------------------------------+
  29. * | Pin assignment for M24C64 EEPROM |
  30. * +---------------------------------------+-----------+-------------+
  31. * | STM32F2xx I2C Pins | EEPROM | Pin |
  32. * +---------------------------------------+-----------+-------------+
  33. * | . | E0 | 1 (0V) |
  34. * | . | E1 | 2 (0V) |
  35. * | . | E2 | 3 (0V) |
  36. * | . | VSS(GND)| 4 (0V) |
  37. * | SDA | SDA | 5 |
  38. * | SCL | SCL | 6 |
  39. * | JP24 | /WS | 7 |
  40. * | . | VDD | 8 (3.3V) |
  41. * +---------------------------------------+-----------+-------------+
  42. *
  43. ******************************************************************************
  44. * @attention
  45. *
  46. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  47. *
  48. * Redistribution and use in source and binary forms, with or without modification,
  49. * are permitted provided that the following conditions are met:
  50. * 1. Redistributions of source code must retain the above copyright notice,
  51. * this list of conditions and the following disclaimer.
  52. * 2. Redistributions in binary form must reproduce the above copyright notice,
  53. * this list of conditions and the following disclaimer in the documentation
  54. * and/or other materials provided with the distribution.
  55. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  56. * may be used to endorse or promote products derived from this software
  57. * without specific prior written permission.
  58. *
  59. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  60. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  61. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  62. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  63. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  64. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  65. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  66. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  67. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  68. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69. *
  70. ******************************************************************************
  71. */
  72. /* Includes ------------------------------------------------------------------*/
  73. #include "stm322xg_eval_eeprom.h"
  74. /** @addtogroup BSP
  75. * @{
  76. */
  77. /** @addtogroup STM322xG_EVAL
  78. * @{
  79. */
  80. /** @addtogroup STM322xG_EVAL_EEPROM STM322xG EVAL EEPROM
  81. * @brief This file includes the I2C EEPROM driver of STM322xG-EVAL evaluation board.
  82. * @{
  83. */
  84. /** @defgroup STM322xG_EVAL_EEPROM_Private_Variables STM322xG EVAL EEPROM Private Variables
  85. * @{
  86. */
  87. __IO uint32_t EEPROMTimeout = EEPROM_READ_TIMEOUT;
  88. __IO uint16_t EEPROMDataRead;
  89. __IO uint8_t EEPROMDataWrite;
  90. /**
  91. * @}
  92. */
  93. /** @defgroup STM322xG_EVAL_EEPROM_Private_Function_Prototypes STM322xG EVAL EEPROM Private Function Prototypes
  94. * @{
  95. */
  96. static uint32_t EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite);
  97. static uint32_t EEPROM_WaitEepromStandbyState(void);
  98. /**
  99. * @}
  100. */
  101. /** @defgroup STM322xG_EVAL_EEPROM_Private_Functions STM322xG EVAL EEPROM Private Functions
  102. * @{
  103. */
  104. /**
  105. * @brief Initializes peripherals used by the I2C EEPROM driver.
  106. * @retval EEPROM_OK (0) if operation is correctly performed, else return value
  107. * different from EEPROM_OK (0)
  108. */
  109. uint32_t BSP_EEPROM_Init(void)
  110. {
  111. /* I2C Initialization */
  112. EEPROM_IO_Init();
  113. /* Select the EEPROM address and check if OK */
  114. if(EEPROM_IO_IsDeviceReady(EEPROM_I2C_ADDRESS, EEPROM_MAX_TRIALS) != HAL_OK)
  115. {
  116. return EEPROM_FAIL;
  117. }
  118. return EEPROM_OK;
  119. }
  120. /**
  121. * @brief Reads a block of data from the EEPROM.
  122. * @param pBuffer: pointer to the buffer that receives the data read from
  123. * the EEPROM.
  124. * @param ReadAddr: EEPROM's internal address to start reading from.
  125. * @param NumByteToRead: pointer to the variable holding number of bytes to
  126. * be read from the EEPROM.
  127. *
  128. * @note The variable pointed by NumByteToRead is reset to 0 when all the
  129. * data are read from the EEPROM. Application should monitor this
  130. * variable in order know when the transfer is complete.
  131. *
  132. * @retval EEPROM_OK (0) if operation is correctly performed, else return value
  133. * different from EEPROM_OK (0) or the timeout user callback.
  134. */
  135. uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
  136. {
  137. uint32_t buffersize = *NumByteToRead;
  138. /* Set the pointer to the Number of data to be read */
  139. EEPROMDataRead = *NumByteToRead;
  140. if(EEPROM_IO_ReadData(EEPROM_I2C_ADDRESS, ReadAddr, pBuffer, buffersize) != HAL_OK)
  141. {
  142. BSP_EEPROM_TIMEOUT_UserCallback();
  143. return EEPROM_FAIL;
  144. }
  145. /* If all operations OK, return EEPROM_OK (0) */
  146. return EEPROM_OK;
  147. }
  148. /**
  149. * @brief Writes buffer of data to the I2C EEPROM.
  150. * @param pBuffer: pointer to the buffer containing the data to be written
  151. * to the EEPROM.
  152. * @param WriteAddr: EEPROM's internal address to write to.
  153. * @param NumByteToWrite: number of bytes to write to the EEPROM.
  154. * @retval EEPROM_OK (0) if operation is correctly performed, else return value
  155. * different from EEPROM_OK (0) or the timeout user callback.
  156. */
  157. uint32_t BSP_EEPROM_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
  158. {
  159. uint8_t numofpage = 0, numofsingle = 0, count = 0;
  160. uint16_t addr = 0;
  161. uint8_t dataindex = 0;
  162. uint32_t status = EEPROM_OK;
  163. addr = WriteAddr % EEPROM_PAGESIZE;
  164. count = EEPROM_PAGESIZE - addr;
  165. numofpage = NumByteToWrite / EEPROM_PAGESIZE;
  166. numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
  167. /* If WriteAddr is EEPROM_PAGESIZE aligned */
  168. if(addr == 0)
  169. {
  170. /* If NumByteToWrite < EEPROM_PAGESIZE */
  171. if(numofpage == 0)
  172. {
  173. /* Store the number of data to be written */
  174. dataindex = numofsingle;
  175. /* Start writing data */
  176. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  177. if(status != EEPROM_OK)
  178. {
  179. return status;
  180. }
  181. }
  182. /* If NumByteToWrite > EEPROM_PAGESIZE */
  183. else
  184. {
  185. while(numofpage--)
  186. {
  187. /* Store the number of data to be written */
  188. dataindex = EEPROM_PAGESIZE;
  189. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  190. if(status != EEPROM_OK)
  191. {
  192. return status;
  193. }
  194. WriteAddr += EEPROM_PAGESIZE;
  195. pBuffer += EEPROM_PAGESIZE;
  196. }
  197. if(numofsingle!=0)
  198. {
  199. /* Store the number of data to be written */
  200. dataindex = numofsingle;
  201. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  202. if(status != EEPROM_OK)
  203. {
  204. return status;
  205. }
  206. }
  207. }
  208. }
  209. /* If WriteAddr is not EEPROM_PAGESIZE aligned */
  210. else
  211. {
  212. /* If NumByteToWrite < EEPROM_PAGESIZE */
  213. if(numofpage == 0)
  214. {
  215. /* If the number of data to be written is more than the remaining space
  216. in the current page: */
  217. if(NumByteToWrite > count)
  218. {
  219. /* Store the number of data to be written */
  220. dataindex = count;
  221. /* Write the data contained in same page */
  222. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  223. if(status != EEPROM_OK)
  224. {
  225. return status;
  226. }
  227. /* Store the number of data to be written */
  228. dataindex = (NumByteToWrite - count);
  229. /* Write the remaining data in the following page */
  230. status = EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
  231. if(status != EEPROM_OK)
  232. {
  233. return status;
  234. }
  235. }
  236. else
  237. {
  238. /* Store the number of data to be written */
  239. dataindex = numofsingle;
  240. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  241. if(status != EEPROM_OK)
  242. {
  243. return status;
  244. }
  245. }
  246. }
  247. /* If NumByteToWrite > EEPROM_PAGESIZE */
  248. else
  249. {
  250. NumByteToWrite -= count;
  251. numofpage = NumByteToWrite / EEPROM_PAGESIZE;
  252. numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
  253. if(count != 0)
  254. {
  255. /* Store the number of data to be written */
  256. dataindex = count;
  257. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  258. if(status != EEPROM_OK)
  259. {
  260. return status;
  261. }
  262. WriteAddr += count;
  263. pBuffer += count;
  264. }
  265. while(numofpage--)
  266. {
  267. /* Store the number of data to be written */
  268. dataindex = EEPROM_PAGESIZE;
  269. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  270. if(status != EEPROM_OK)
  271. {
  272. return status;
  273. }
  274. WriteAddr += EEPROM_PAGESIZE;
  275. pBuffer += EEPROM_PAGESIZE;
  276. }
  277. if(numofsingle != 0)
  278. {
  279. /* Store the number of data to be written */
  280. dataindex = numofsingle;
  281. status = EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
  282. if(status != EEPROM_OK)
  283. {
  284. return status;
  285. }
  286. }
  287. }
  288. }
  289. /* If all operations OK, return EEPROM_OK (0) */
  290. return EEPROM_OK;
  291. }
  292. /**
  293. * @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
  294. *
  295. * @note The number of bytes (combined to write start address) must not
  296. * cross the EEPROM page boundary. This function can only write into
  297. * the boundaries of an EEPROM page.
  298. * This function doesn't check on boundaries condition (in this driver
  299. * the function BSP_EEPROM_WriteBuffer() which calls EEPROM_WritePage() is
  300. * responsible of checking on Page boundaries).
  301. *
  302. * @param pBuffer: pointer to the buffer containing the data to be written to
  303. * the EEPROM.
  304. * @param WriteAddr: EEPROM's internal address to write to.
  305. * @param NumByteToWrite: pointer to the variable holding number of bytes to
  306. * be written into the EEPROM.
  307. *
  308. * @note The variable pointed by NumByteToWrite is reset to 0 when all the
  309. * data are written to the EEPROM. Application should monitor this
  310. * variable in order know when the transfer is complete.
  311. *
  312. * @retval EEPROM_OK (0) if operation is correctly performed, else return value
  313. * different from EEPROM_OK (0) or the timeout user callback.
  314. */
  315. static uint32_t EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
  316. {
  317. uint32_t buffersize = *NumByteToWrite;
  318. uint32_t status = EEPROM_OK;
  319. /* Set the pointer to the Number of data to be written */
  320. EEPROMDataWrite = *NumByteToWrite;
  321. if(EEPROM_IO_WriteData(EEPROM_I2C_ADDRESS, WriteAddr, pBuffer, buffersize) != HAL_OK)
  322. {
  323. BSP_EEPROM_TIMEOUT_UserCallback();
  324. status = EEPROM_FAIL;
  325. }
  326. while(EEPROM_WaitEepromStandbyState() != EEPROM_OK)
  327. {
  328. return EEPROM_FAIL;
  329. }
  330. /* If all operations OK, return EEPROM_OK (0) */
  331. return status;
  332. }
  333. /**
  334. * @brief Waits for EEPROM Standby state.
  335. *
  336. * @note This function allows to wait and check that EEPROM has finished the
  337. * last operation. It is mostly used after Write operation: after receiving
  338. * the buffer to be written, the EEPROM may need additional time to actually
  339. * perform the write operation. During this time, it doesn't answer to
  340. * I2C packets addressed to it. Once the write operation is complete
  341. * the EEPROM responds to its address.
  342. *
  343. * @retval EEPROM_OK (0) if operation is correctly performed, else return value
  344. * different from EEPROM_OK (0) or the timeout user callback.
  345. */
  346. static uint32_t EEPROM_WaitEepromStandbyState(void)
  347. {
  348. /* Check if the maximum allowed number of trials has bee reached */
  349. if(EEPROM_IO_IsDeviceReady(EEPROM_I2C_ADDRESS, EEPROM_MAX_TRIALS) != HAL_OK)
  350. {
  351. /* If the maximum number of trials has been reached, exit the function */
  352. BSP_EEPROM_TIMEOUT_UserCallback();
  353. return EEPROM_TIMEOUT;
  354. }
  355. return EEPROM_OK;
  356. }
  357. /**
  358. * @brief Basic management of the timeout situation.
  359. */
  360. __weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
  361. {
  362. }
  363. /**
  364. * @}
  365. */
  366. /**
  367. * @}
  368. */
  369. /**
  370. * @}
  371. */
  372. /**
  373. * @}
  374. */
  375. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/