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