STM32091C_EVAL BSP User Manual: stm32091c_eval_eeprom.c Source File

STM32091C EVAL BSP Drivers

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