STM32F429I-Discovery BSP User Manual: stm32f429i_discovery_eeprom.c Source File

STM32F429I-Discovery BSP Driver

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