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