STM32L476G_EVAL BSP User Manual: stm32l476g_eval_eeprom.c Source File

STM32L476G_EVAL BSP

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