STM32F429I-Discovery BSP User Manual
|
stm32f429i_discovery_eeprom.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f429i_discovery_eeprom.c 00004 * @author MCD Application Team 00005 * @version V2.1.5 00006 * @date 27-January-2017 00007 * @brief This file provides a set of functions needed to manage an I2C M24LR64 00008 * EEPROM memory. 00009 * To be able to use this driver, the switch EE_M24LR64 must be defined 00010 * in your toolchain compiler preprocessor 00011 * 00012 * =================================================================== 00013 * Notes: 00014 * - This driver is intended for STM32F4xx families devices only. 00015 * - The I2C EEPROM memory (M24LR64) is available on separate daughter 00016 * board ANT7-M24LR-A, which is not provided with the STM32F429I 00017 * DISCOVERY board. 00018 * To use this driver you have to connect the ANT7-M24LR-A to CN3 00019 * connector of STM32F429I DISCOVERY board. 00020 * =================================================================== 00021 * 00022 * It implements a high level communication layer for read and write 00023 * from/to this memory. The needed STM32F4xx hardware resources (I2C and 00024 * GPIO) are defined in stm32f429i_discovery.h file, and the initialization is 00025 * performed in EEPROM_IO_Init() function declared in stm32f429i_discovery.c 00026 * file. 00027 * You can easily tailor this driver to any other development board, 00028 * by just adapting the defines for hardware resources and 00029 * EEPROM_IO_Init() function. 00030 * 00031 * @note In this driver, basic read and write functions (BSP_EEPROM_ReadBuffer() 00032 * and BSP_EEPROM_WritePage()) use DMA mode to perform the data 00033 * transfer to/from EEPROM memory. 00034 * 00035 * @note Regarding BSP_EEPROM_WritePage(), it is a optimized function to perform 00036 * small write (less than 1 page) BUT The number of bytes (combined to write start address) must not 00037 * cross the EEPROM page boundary. This function can only write into 00038 * the boundaries of an EEPROM page. 00039 * This function doesn't check on boundaries condition (in this driver 00040 * the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is 00041 * responsible of checking on Page boundaries). 00042 * 00043 * 00044 * +-----------------------------------------------------------------+ 00045 * | Pin assignment for M24LR64 EEPROM | 00046 * +---------------------------------------+-----------+-------------+ 00047 * | STM32F4xx I2C Pins | EEPROM | Pin | 00048 * +---------------------------------------+-----------+-------------+ 00049 * | . | E0(GND) | 1 (0V) | 00050 * | . | AC0 | 2 | 00051 * | . | AC1 | 3 | 00052 * | . | VSS | 4 (0V) | 00053 * | SDA | SDA | 5 | 00054 * | SCL | SCL | 6 | 00055 * | . | E1(GND) | 7 (0V) | 00056 * | . | VDD | 8 (3.3V) | 00057 * +---------------------------------------+-----------+-------------+ 00058 * 00059 ****************************************************************************** 00060 * @attention 00061 * 00062 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00063 * 00064 * Redistribution and use in source and binary forms, with or without modification, 00065 * are permitted provided that the following conditions are met: 00066 * 1. Redistributions of source code must retain the above copyright notice, 00067 * this list of conditions and the following disclaimer. 00068 * 2. Redistributions in binary form must reproduce the above copyright notice, 00069 * this list of conditions and the following disclaimer in the documentation 00070 * and/or other materials provided with the distribution. 00071 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00072 * may be used to endorse or promote products derived from this software 00073 * without specific prior written permission. 00074 * 00075 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00076 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00077 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00078 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00079 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00080 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00081 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00082 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00083 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00084 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00085 * 00086 ****************************************************************************** 00087 */ 00088 /* Includes ------------------------------------------------------------------*/ 00089 #include "stm32f429i_discovery_eeprom.h" 00090 00091 #ifdef EE_M24LR64 00092 00093 /** @addtogroup BSP 00094 * @{ 00095 */ 00096 00097 /** @addtogroup STM32F429I_DISCOVERY 00098 * @{ 00099 */ 00100 00101 /** @defgroup STM32F429I_DISCOVERY_EEPROM STM32F429I DISCOVERY EEPROM 00102 * @brief This file includes the I2C EEPROM driver of STM32F429I Discovery Kit. 00103 * @{ 00104 */ 00105 00106 /** @defgroup STM32F429I_DISCOVERY_EEPROM_Private_Types STM32F429I DISCOVERY EEPROM Private Types 00107 * @{ 00108 */ 00109 /** 00110 * @} 00111 */ 00112 00113 /** @defgroup STM32F429I_DISCOVERY_EEPROM_Private_Defines STM32F429I DISCOVERY EEPROM Private Defines 00114 * @{ 00115 */ 00116 /** 00117 * @} 00118 */ 00119 00120 /** @defgroup STM32F429I_DISCOVERY_EEPROM_Private_Macros STM32F429I DISCOVERY EEPROM Private Macros 00121 * @{ 00122 */ 00123 /** 00124 * @} 00125 */ 00126 00127 /** @defgroup STM32F429I_DISCOVERY_EEPROM_Private_Variables STM32F429I DISCOVERY EEPROM Private Variables 00128 * @{ 00129 */ 00130 __IO uint16_t EEPROMAddress = 0; 00131 __IO uint32_t EEPROMTimeout = EEPROM_READ_TIMEOUT; 00132 __IO uint16_t EEPROMDataRead; 00133 __IO uint8_t EEPROMDataWrite; 00134 00135 /** 00136 * @} 00137 */ 00138 00139 /** @defgroup STM32F429I_DISCOVERY_EEPROM_Private_Function_Prototypes STM32F429I DISCOVERY EEPROM Private Function Prototypes 00140 * @{ 00141 */ 00142 /** 00143 * @} 00144 */ 00145 00146 /** @defgroup STM32F429I_DISCOVERY_EEPROM_Private_Functions STM32F429I DISCOVERY EEPROM Private Functions 00147 * @{ 00148 */ 00149 00150 /** 00151 * @brief Initializes peripherals used by the I2C EEPROM driver. 00152 * @note There are 2 different versions of M24LR64 (A01 & A02). 00153 * Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01) 00154 * and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02) 00155 * @retval EEPROM_OK (0) if operation is correctly performed, else return value 00156 * different from EEPROM_OK (0) 00157 */ 00158 uint32_t BSP_EEPROM_Init(void) 00159 { 00160 /* I2C Initialization */ 00161 EEPROM_IO_Init(); 00162 00163 /*Select the EEPROM address for A01 and check if OK*/ 00164 EEPROMAddress = EEPROM_I2C_ADDRESS_A01; 00165 if (EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 00166 { 00167 /*Select the EEPROM address for A02 and check if OK*/ 00168 EEPROMAddress = EEPROM_I2C_ADDRESS_A02; 00169 if (EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 00170 { 00171 return EEPROM_FAIL; 00172 } 00173 } 00174 return EEPROM_OK; 00175 } 00176 00177 /** 00178 * @brief Reads a block of data from the EEPROM. 00179 * @param pBuffer : pointer to the buffer that receives the data read from 00180 * the EEPROM. 00181 * @param ReadAddr : EEPROM's internal address to start reading from. 00182 * @param NumByteToRead : pointer to the variable holding number of bytes to 00183 * be read from the EEPROM. 00184 * 00185 * @note The variable pointed by NumByteToRead is reset to 0 when all the 00186 * data are read from the EEPROM. Application should monitor this 00187 * variable in order know when the transfer is complete. 00188 * 00189 * @retval EEPROM_OK (0) if operation is correctly performed, else return value 00190 * different from EEPROM_OK (0) or the timeout user callback. 00191 */ 00192 uint32_t BSP_EEPROM_ReadBuffer(uint8_t *pBuffer, uint16_t ReadAddr, uint16_t *NumByteToRead) 00193 { 00194 uint32_t buffersize = *NumByteToRead; 00195 00196 /* Set the pointer to the Number of data to be read. This pointer will be used 00197 by the DMA Transfer Completer interrupt Handler in order to reset the 00198 variable to 0. User should check on this variable in order to know if the 00199 DMA transfer has been complete or not. */ 00200 EEPROMDataRead = *NumByteToRead; 00201 00202 if (EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK) 00203 { 00204 return EEPROM_FAIL; 00205 } 00206 00207 /* Wait transfer through DMA to be complete */ 00208 EEPROMTimeout = HAL_GetTick() + EEPROM_READ_TIMEOUT; 00209 while (EEPROMDataRead > 0) 00210 { 00211 if(HAL_GetTick() > EEPROMTimeout) 00212 { 00213 BSP_EEPROM_TIMEOUT_UserCallback(); 00214 return EEPROM_TIMEOUT; 00215 } 00216 } 00217 00218 /* If all operations OK, return EEPROM_OK (0) */ 00219 return EEPROM_OK; 00220 } 00221 00222 /** 00223 * @brief Writes more than one byte to the EEPROM with a single WRITE cycle. 00224 * 00225 * @note The number of bytes (combined to write start address) must not 00226 * cross the EEPROM page boundary. This function can only write into 00227 * the boundaries of an EEPROM page. 00228 * This function doesn't check on boundaries condition (in this driver 00229 * the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is 00230 * responsible of checking on Page boundaries). 00231 * 00232 * @param pBuffer : pointer to the buffer containing the data to be written to 00233 * the EEPROM. 00234 * @param WriteAddr : EEPROM's internal address to write to. 00235 * @param NumByteToWrite : pointer to the variable holding number of bytes to 00236 * be written into the EEPROM. 00237 * 00238 * @note The variable pointed by NumByteToWrite is reset to 0 when all the 00239 * data are written to the EEPROM. Application should monitor this 00240 * variable in order know when the transfer is complete. 00241 * 00242 * @note This function just configure the communication and enable the DMA 00243 * channel to transfer data. Meanwhile, the user application may perform 00244 * other tasks in parallel. 00245 * 00246 * @retval EEPROM_OK (0) if operation is correctly performed, else return value 00247 * different from EEPROM_OK (0) or the timeout user callback. 00248 */ 00249 uint32_t BSP_EEPROM_WritePage(uint8_t *pBuffer, uint16_t WriteAddr, uint8_t *NumByteToWrite) 00250 { 00251 uint32_t buffersize = *NumByteToWrite; 00252 uint32_t status = EEPROM_OK; 00253 /* Set the pointer to the Number of data to be written. This pointer will be used 00254 by the DMA Transfer Completer interrupt Handler in order to reset the 00255 variable to 0. User should check on this variable in order to know if the 00256 DMA transfer has been complete or not. */ 00257 EEPROMDataWrite = *NumByteToWrite; 00258 00259 if (EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK) 00260 { 00261 status = EEPROM_FAIL; 00262 } 00263 00264 /* Wait transfer through DMA to be complete */ 00265 EEPROMTimeout = HAL_GetTick() + EEPROM_WRITE_TIMEOUT; 00266 while (EEPROMDataWrite > 0) 00267 { 00268 if(HAL_GetTick() > EEPROMTimeout) 00269 { 00270 BSP_EEPROM_TIMEOUT_UserCallback(); 00271 return EEPROM_TIMEOUT; 00272 } 00273 } 00274 00275 if (BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK) 00276 { 00277 return EEPROM_FAIL; 00278 } 00279 00280 /* If all operations OK, return EEPROM_OK (0) */ 00281 return status; 00282 } 00283 00284 /** 00285 * @brief Writes buffer of data to the I2C EEPROM. 00286 * @param pBuffer : pointer to the buffer containing the data to be written 00287 * to the EEPROM. 00288 * @param WriteAddr : EEPROM's internal address to write to. 00289 * @param NumByteToWrite : number of bytes to write to the EEPROM. 00290 * @retval EEPROM_OK (0) if operation is correctly performed, else return value 00291 * different from EEPROM_OK (0) or the timeout user callback. 00292 */ 00293 uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite) 00294 { 00295 uint16_t numofpage = 0, numofsingle = 0, count = 0; 00296 uint16_t addr = 0; 00297 uint8_t dataindex = 0; 00298 uint32_t status = EEPROM_OK; 00299 00300 addr = WriteAddr % EEPROM_PAGESIZE; 00301 count = EEPROM_PAGESIZE - addr; 00302 numofpage = NumByteToWrite / EEPROM_PAGESIZE; 00303 numofsingle = NumByteToWrite % EEPROM_PAGESIZE; 00304 00305 /* If WriteAddr is EEPROM_PAGESIZE aligned */ 00306 if(addr == 0) 00307 { 00308 /* If NumByteToWrite < EEPROM_PAGESIZE */ 00309 if(numofpage == 0) 00310 { 00311 /* Store the number of data to be written */ 00312 dataindex = numofsingle; 00313 /* Start writing data */ 00314 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00315 if (status != EEPROM_OK) 00316 { 00317 return status; 00318 } 00319 } 00320 /* If NumByteToWrite > EEPROM_PAGESIZE */ 00321 else 00322 { 00323 while(numofpage--) 00324 { 00325 /* Store the number of data to be written */ 00326 dataindex = EEPROM_PAGESIZE; 00327 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00328 if (status != EEPROM_OK) 00329 { 00330 return status; 00331 } 00332 00333 WriteAddr += EEPROM_PAGESIZE; 00334 pBuffer += EEPROM_PAGESIZE; 00335 } 00336 00337 if(numofsingle!=0) 00338 { 00339 /* Store the number of data to be written */ 00340 dataindex = numofsingle; 00341 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00342 if (status != EEPROM_OK) 00343 { 00344 return status; 00345 } 00346 } 00347 } 00348 } 00349 /* If WriteAddr is not EEPROM_PAGESIZE aligned */ 00350 else 00351 { 00352 /* If NumByteToWrite < EEPROM_PAGESIZE */ 00353 if(numofpage== 0) 00354 { 00355 /* If the number of data to be written is more than the remaining space 00356 in the current page: */ 00357 if (NumByteToWrite > count) 00358 { 00359 /* Store the number of data to be written */ 00360 dataindex = count; 00361 /* Write the data contained in same page */ 00362 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00363 if (status != EEPROM_OK) 00364 { 00365 return status; 00366 } 00367 00368 /* Store the number of data to be written */ 00369 dataindex = (NumByteToWrite - count); 00370 /* Write the remaining data in the following page */ 00371 status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex)); 00372 if (status != EEPROM_OK) 00373 { 00374 return status; 00375 } 00376 } 00377 else 00378 { 00379 /* Store the number of data to be written */ 00380 dataindex = numofsingle; 00381 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00382 if (status != EEPROM_OK) 00383 { 00384 return status; 00385 } 00386 } 00387 } 00388 /* If NumByteToWrite > EEPROM_PAGESIZE */ 00389 else 00390 { 00391 NumByteToWrite -= count; 00392 numofpage = NumByteToWrite / EEPROM_PAGESIZE; 00393 numofsingle = NumByteToWrite % EEPROM_PAGESIZE; 00394 00395 if(count != 0) 00396 { 00397 /* Store the number of data to be written */ 00398 dataindex = count; 00399 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00400 if (status != EEPROM_OK) 00401 { 00402 return status; 00403 } 00404 WriteAddr += count; 00405 pBuffer += count; 00406 } 00407 00408 while(numofpage--) 00409 { 00410 /* Store the number of data to be written */ 00411 dataindex = EEPROM_PAGESIZE; 00412 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00413 if (status != EEPROM_OK) 00414 { 00415 return status; 00416 } 00417 WriteAddr += EEPROM_PAGESIZE; 00418 pBuffer += EEPROM_PAGESIZE; 00419 } 00420 if(numofsingle != 0) 00421 { 00422 /* Store the number of data to be written */ 00423 dataindex = numofsingle; 00424 status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex)); 00425 if (status != EEPROM_OK) 00426 { 00427 return status; 00428 } 00429 } 00430 } 00431 } 00432 00433 /* If all operations OK, return EEPROM_OK (0) */ 00434 return EEPROM_OK; 00435 } 00436 00437 /** 00438 * @brief Wait for EEPROM Standby state. 00439 * 00440 * @note This function allows to wait and check that EEPROM has finished the 00441 * last operation. It is mostly used after Write operation: after receiving 00442 * the buffer to be written, the EEPROM may need additional time to actually 00443 * perform the write operation. During this time, it doesn't answer to 00444 * I2C packets addressed to it. Once the write operation is complete 00445 * the EEPROM responds to its address. 00446 * 00447 * @retval EEPROM_OK (0) if operation is correctly performed, else return value 00448 * different from EEPROM_OK (0) or the timeout user callback. 00449 */ 00450 uint32_t BSP_EEPROM_WaitEepromStandbyState(void) 00451 { 00452 /* Check if the maximum allowed number of trials has bee reached */ 00453 if (EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 00454 { 00455 /* If the maximum number of trials has been reached, exit the function */ 00456 BSP_EEPROM_TIMEOUT_UserCallback(); 00457 return EEPROM_TIMEOUT; 00458 } 00459 return EEPROM_OK; 00460 } 00461 00462 /** 00463 * @brief Memory Tx Transfer completed callbacks. 00464 * @param hi2c: I2C handle 00465 */ 00466 void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) 00467 { 00468 EEPROMDataWrite = 0; 00469 } 00470 00471 /** 00472 * @brief Memory Rx Transfer completed callbacks. 00473 * @param hi2c: I2C handle 00474 */ 00475 void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) 00476 { 00477 EEPROMDataRead = 0; 00478 } 00479 00480 /** 00481 * @brief Basic management of the timeout situation. 00482 */ 00483 __weak void BSP_EEPROM_TIMEOUT_UserCallback(void) 00484 { 00485 } 00486 00487 #endif /* EE_M24LR64 */ 00488 00489 /** 00490 * @} 00491 */ 00492 00493 /** 00494 * @} 00495 */ 00496 00497 /** 00498 * @} 00499 */ 00500 00501 /** 00502 * @} 00503 */ 00504 00505 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Feb 17 2017 12:10:38 for STM32F429I-Discovery BSP User Manual by 1.7.6.1