STM32F429ZI Discovery board drivers

Dependents:   2a 2b 2c 2d1 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f429i_discovery_eeprom.c Source File

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