STM3210C_EVAL BSP User Manual: stm3210c_eval_eeprom.c Source File

STM3210C EVAL BSP Drivers

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 V6.0.1
00006   * @date    18-December-2015
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) 2015 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 /** @addtogroup 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_Types Private Types
00089   * @{
00090   */
00091 /**
00092   * @}
00093   */ 
00094 
00095 
00096 /** @defgroup STM3210C_EVAL_EEPROM_Private_Defines Private Defines
00097   * @{
00098   */  
00099 /**
00100   * @}
00101   */ 
00102 
00103 
00104 /** @defgroup STM3210C_EVAL_EEPROM_Private_Macros Private Macros
00105   * @{
00106   */
00107 /**
00108   * @}
00109   */ 
00110   
00111 
00112 /** @defgroup STM3210C_EVAL_EEPROM_Private_Variables Private Variables
00113   * @{
00114   */
00115 __IO uint16_t  EEPROMAddress = 0;
00116 __IO uint16_t  EEPROMPageSize = 0;
00117 __IO uint16_t  EEPROMDataRead = 0;
00118 __IO uint8_t   EEPROMDataWrite = 0;
00119 
00120 static EEPROM_DrvTypeDef *EEPROM_SelectedDevice = 0;
00121 /**
00122   * @}
00123   */ 
00124 
00125 
00126 /** @defgroup STM3210C_EVAL_EEPROM_Private_Function_Prototypes Private Function Prototypes
00127   * @{
00128   */ 
00129 static uint32_t EEPROM_I2C_Init(void);
00130 static uint32_t EEPROM_I2C_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint32_t* NumByteToRead);
00131 static uint32_t EEPROM_I2C_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint32_t* NumByteToWrite);
00132 static uint32_t EEPROM_I2C_WaitEepromStandbyState(void);
00133 
00134 /* EEPROM I2C driver typedef */
00135 EEPROM_DrvTypeDef EEPROM_I2C_Drv =
00136 {
00137   EEPROM_I2C_Init,
00138   EEPROM_I2C_ReadBuffer,
00139   EEPROM_I2C_WritePage
00140 };
00141 
00142 /**
00143   * @}
00144   */ 
00145 
00146 /** @defgroup STM3210C_EVAL_EEPROM_Exported_Functions Exported Functions
00147   * @{
00148   */ 
00149 
00150 /**
00151   * @brief  Initializes peripherals used by the EEPROM device selected.
00152   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00153   *         different from EEPROM_OK (0)
00154   */
00155 uint32_t BSP_EEPROM_Init(void)
00156 { 
00157   if(EEPROM_SelectedDevice->Init != 0)
00158   {
00159     return (EEPROM_SelectedDevice->Init());
00160   }
00161   else
00162   {
00163     return EEPROM_FAIL;
00164   }
00165 }
00166 
00167 /**
00168   * @brief  Select the EEPROM device to communicate.
00169   * @param  DeviceID: Specifies the EEPROM device to be selected. 
00170   *   This parameter can be one of following parameters:
00171   *     @arg BSP_EEPROM_M24C64_32
00172   *     @arg BSP_EEPROM_M24C08
00173   * 
00174   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00175   *         different from EEPROM_OK (0)
00176   */
00177 void BSP_EEPROM_SelectDevice(uint8_t DeviceID)
00178 {
00179   switch(DeviceID)
00180   {
00181   case BSP_EEPROM_M24C64_32:
00182   case BSP_EEPROM_M24C08:
00183     EEPROM_SelectedDevice = &EEPROM_I2C_Drv;
00184     break;
00185     
00186   default:
00187     break;
00188   }
00189 }
00190 
00191 /**
00192   * @brief  Reads a block of data from the EEPROM device selected.
00193   * @param  pBuffer : pointer to the buffer that receives the data read from 
00194   *         the EEPROM.
00195   * @param  ReadAddr : EEPROM's internal address to start reading from.
00196   * @param  NumByteToRead : pointer to the variable holding number of bytes to 
00197   *         be read from the EEPROM.
00198   * 
00199   *        @note The variable pointed by NumByteToRead is reset to 0 when all the 
00200   *              data are read from the EEPROM. Application should monitor this 
00201   *              variable in order know when the transfer is complete.
00202   * 
00203   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00204   *         different from EEPROM_OK (0) or the timeout user callback.
00205   */
00206 uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint32_t* NumByteToRead)
00207 {
00208   if(EEPROM_SelectedDevice->ReadBuffer != 0)
00209   {
00210     return (EEPROM_SelectedDevice->ReadBuffer(pBuffer, ReadAddr, NumByteToRead));
00211   }
00212   else
00213   {
00214     return EEPROM_FAIL;
00215   }
00216 }
00217 
00218 /**
00219   * @brief  Writes buffer of data to the EEPROM device selected.
00220   * @param  pBuffer : pointer to the buffer  containing the data to be written 
00221   *         to the EEPROM.
00222   * @param  WriteAddr : EEPROM's internal address to write to.
00223   * @param  NumByteToWrite : number of bytes to write to the EEPROM.
00224   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00225   *         different from EEPROM_OK (0) or the timeout user callback.
00226   */
00227 uint32_t BSP_EEPROM_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint32_t NumByteToWrite)
00228 {
00229   uint16_t numofpage = 0, numofsingle = 0, count = 0;
00230   uint16_t addr = 0;
00231   uint32_t dataindex = 0;
00232   uint32_t status = EEPROM_OK;
00233 
00234   addr = WriteAddr % EEPROMPageSize;
00235   count = EEPROMPageSize - addr;
00236   numofpage =  NumByteToWrite / EEPROMPageSize;
00237   numofsingle = NumByteToWrite % EEPROMPageSize;
00238  
00239   if(EEPROM_SelectedDevice->WritePage == 0)
00240   {
00241     return EEPROM_FAIL;
00242   }
00243   
00244   /*!< If WriteAddr is EEPROM_PAGESIZE aligned  */
00245   if(addr == 0) 
00246   {
00247     /*!< If NumByteToWrite < EEPROM_PAGESIZE */
00248     if(numofpage == 0) 
00249     {
00250       /* Store the number of data to be written */
00251       dataindex = numofsingle;
00252       /* Start writing data */
00253       status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00254       if (status != EEPROM_OK)
00255       {
00256         return status;
00257       }
00258     }
00259     /*!< If NumByteToWrite > EEPROM_PAGESIZE */
00260     else  
00261     {
00262       while(numofpage--)
00263       {
00264         /* Store the number of data to be written */
00265         dataindex = EEPROMPageSize;        
00266         status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00267         if (status != EEPROM_OK)
00268         {
00269           return status;
00270         }
00271         
00272         WriteAddr +=  EEPROMPageSize;
00273         pBuffer += EEPROMPageSize;
00274       }
00275 
00276       if(numofsingle!=0)
00277       {
00278         /* Store the number of data to be written */
00279         dataindex = numofsingle;          
00280         status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00281         if (status != EEPROM_OK)
00282         {
00283           return status;
00284         }
00285           }
00286         }
00287     }
00288   /*!< If WriteAddr is not EEPROM_PAGESIZE aligned  */
00289   else 
00290   {
00291     /*!< If NumByteToWrite < EEPROM_PAGESIZE */
00292     if(numofpage== 0) 
00293     {
00294       /*!< If the number of data to be written is more than the remaining space 
00295       in the current page: */
00296       if (NumByteToWrite > count)
00297       {
00298         /* Store the number of data to be written */
00299         dataindex = count;        
00300         /*!< Write the data contained in same page */
00301         status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00302         if (status != EEPROM_OK)
00303         {
00304           return status;
00305         }
00306         
00307         /* Store the number of data to be written */
00308         dataindex = (NumByteToWrite - count);          
00309         /*!< Write the remaining data in the following page */
00310         status = EEPROM_SelectedDevice->WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint32_t*)(&dataindex));
00311         if (status != EEPROM_OK)
00312         {
00313           return status;
00314         }
00315       }      
00316       else      
00317       {
00318         /* Store the number of data to be written */
00319         dataindex = numofsingle;         
00320         status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00321         if (status != EEPROM_OK)
00322         {
00323           return status;
00324         }
00325         }
00326       }     
00327     /*!< If NumByteToWrite > EEPROM_PAGESIZE */
00328     else
00329     {
00330       NumByteToWrite -= count;
00331       numofpage =  NumByteToWrite / EEPROMPageSize;
00332       numofsingle = NumByteToWrite % EEPROMPageSize;
00333       
00334       if(count != 0)
00335       {  
00336         /* Store the number of data to be written */
00337         dataindex = count;         
00338         status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00339         if (status != EEPROM_OK)
00340         {
00341           return status;
00342         }
00343         WriteAddr += count;
00344         pBuffer += count;
00345       } 
00346       
00347       while(numofpage--)
00348       {
00349         /* Store the number of data to be written */
00350         dataindex = EEPROMPageSize;          
00351         status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00352         if (status != EEPROM_OK)
00353         {
00354           return status;
00355         }
00356         WriteAddr +=  EEPROMPageSize;
00357         pBuffer += EEPROMPageSize;  
00358       }
00359       if(numofsingle != 0)
00360       {
00361         /* Store the number of data to be written */
00362         dataindex = numofsingle;           
00363         status = EEPROM_SelectedDevice->WritePage(pBuffer, WriteAddr, (uint32_t*)(&dataindex));
00364         if (status != EEPROM_OK)
00365         {
00366           return status;
00367         }
00368       }
00369     }
00370   }  
00371   
00372   /* If all operations OK, return EEPROM_OK (0) */
00373   return EEPROM_OK;
00374 }
00375 
00376 /**
00377   * @brief  Basic management of the timeout situation.
00378   * @retval None.
00379   */
00380 __weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
00381 {
00382 }
00383 /**
00384   * @}
00385   */
00386 
00387 /** @addtogroup STM3210C_EVAL_EEPROM_Private_Function_Prototypes
00388   * @{
00389   */ 
00390 
00391 /**
00392   * @brief  Initializes peripherals used by the I2C EEPROM driver.
00393   * @note There are 2 different versions of M24CXX (08 or 32 or 64).
00394   *             Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01) 
00395   *             and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02)
00396   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00397   *         different from EEPROM_OK (0)
00398   */
00399 static uint32_t EEPROM_I2C_Init(void)
00400 {
00401   EEPROM_I2C_IO_Init();
00402 
00403   /*Select the EEPROM address for M24C32 or M24C64 and check if OK*/
00404   EEPROMAddress = EEPROM_ADDRESS_M24C64_32;
00405   EEPROMPageSize = EEPROM_PAGESIZE_M24C64_32;
00406   if (EEPROM_I2C_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 
00407   {
00408     EEPROMPageSize = EEPROM_PAGESIZE_M24C08;
00409     /*Select the EEPROM address for M24C08 (BLOCK0) and check if OK*/
00410     EEPROMAddress = EEPROM_ADDRESS_M24C08_BLOCK0;
00411     if (EEPROM_I2C_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 
00412     {
00413       /*Select the EEPROM address for M24C08 (BLOCK1) and check if OK*/
00414       EEPROMAddress = EEPROM_ADDRESS_M24C08_BLOCK1;
00415       if (EEPROM_I2C_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 
00416       {
00417         /*Select the EEPROM address for M24C08 (BLOCK2) and check if OK*/
00418         EEPROMAddress = EEPROM_ADDRESS_M24C08_BLOCK2;
00419         if (EEPROM_I2C_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 
00420         {
00421           /*Select the EEPROM address for M24C08 (BLOCK3) and check if OK*/
00422           EEPROMAddress = EEPROM_ADDRESS_M24C08_BLOCK3;
00423           if (EEPROM_I2C_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 
00424           {
00425             return EEPROM_FAIL;
00426           }
00427         }
00428       }
00429     }
00430   }
00431 
00432   return EEPROM_OK;
00433 }
00434 
00435 /**
00436   * @brief  Reads a block of data from the I2C EEPROM.
00437   * @param  pBuffer : pointer to the buffer that receives the data read from 
00438   *         the EEPROM.
00439   * @param  ReadAddr : EEPROM's internal address to start reading from.
00440   * @param  NumByteToRead : pointer to the variable holding number of bytes to 
00441   *         be read from the EEPROM.
00442   * 
00443   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00444   *         different from EEPROM_OK (0) or the timeout user callback.
00445   */
00446 static uint32_t EEPROM_I2C_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint32_t* NumByteToRead)
00447 {  
00448   uint32_t buffersize = *NumByteToRead;
00449   
00450   if (EEPROM_I2C_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
00451   {
00452     return EEPROM_FAIL;
00453   }
00454   
00455   /* If all operations OK, return EEPROM_OK (0) */
00456   return EEPROM_OK;
00457 }
00458 
00459 /**
00460   * @brief  Writes more than one byte to the EEPROM with a single WRITE cycle.
00461   *
00462   * @note   The number of bytes (combined to write start address) must not 
00463   *         cross the EEPROM page boundary. This function can only write into
00464   *         the boundaries of an EEPROM page.
00465   *         This function doesn't check on boundaries condition (in this driver 
00466   *         the function BSP_EEPROM_WriteBuffer() which calls EEPROM_WritePage() is 
00467   *         responsible of checking on Page boundaries).
00468   * 
00469   * @param  pBuffer : pointer to the buffer containing the data to be written to 
00470   *         the EEPROM.
00471   * @param  WriteAddr : EEPROM's internal address to write to.
00472   * @param  NumByteToWrite : pointer to the variable holding number of bytes to 
00473   *         be written into the EEPROM. 
00474   * 
00475   *        @note The variable pointed by NumByteToWrite is reset to 0 when all the 
00476   *              data are written to the EEPROM. Application should monitor this 
00477   *              variable in order know when the transfer is complete.
00478   * 
00479   * 
00480   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00481   *         different from EEPROM_OK (0) or the timeout user callback.
00482   */
00483 static uint32_t EEPROM_I2C_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint32_t* NumByteToWrite)
00484 { 
00485   uint32_t buffersize = *NumByteToWrite;
00486 
00487   if (EEPROM_I2C_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
00488   {
00489     return EEPROM_FAIL;
00490   }
00491   
00492   /* Wait for EEPROM Standby state */
00493   if (EEPROM_I2C_WaitEepromStandbyState() != EEPROM_OK) 
00494   {
00495     return EEPROM_FAIL;
00496   }
00497   
00498   return EEPROM_OK;
00499 }
00500 
00501 /**
00502   * @brief  Wait for EEPROM I2C Standby state.
00503   * 
00504   * @note  This function allows to wait and check that EEPROM has finished the 
00505   *        last operation. It is mostly used after Write operation: after receiving
00506   *        the buffer to be written, the EEPROM may need additional time to actually
00507   *        perform the write operation. During this time, it doesn't answer to
00508   *        I2C packets addressed to it. Once the write operation is complete
00509   *        the EEPROM responds to its address.
00510   * 
00511   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00512   *         different from EEPROM_OK (0) or the timeout user callback.
00513   */
00514 static uint32_t EEPROM_I2C_WaitEepromStandbyState(void)  
00515 {
00516     /* Check if the maximum allowed number of trials has bee reached */
00517   if (EEPROM_I2C_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
00518   {
00519     /* If the maximum number of trials has been reached, exit the function */
00520     BSP_EEPROM_TIMEOUT_UserCallback();
00521     return EEPROM_TIMEOUT;
00522   }
00523   return EEPROM_OK;
00524 }
00525 
00526 /**
00527   * @}
00528   */
00529 
00530 /**
00531   * @}
00532   */
00533 
00534 /**
00535   * @}
00536   */
00537 
00538 /**
00539   * @}
00540   */
00541 
00542 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00543 
Generated on Thu Dec 10 2015 17:13:52 for STM3210C_EVAL BSP User Manual by   doxygen 1.7.6.1