STM3210C_EVAL BSP User Manual: stm3210c_eval_eeprom.c Source File

STM3210C_EVAL BSP

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