STM32469I-Discovery BSP User Manual: stm32469i_discovery_eeprom.c Source File

STM32469I-Discovery BSP Drivers

stm32469i_discovery_eeprom.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32469i_discovery_eeprom.c
00004   * @author  MCD Application Team
00005   * @version V2.0.0
00006   * @date    31-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 STM32469I-Discovery
00017   *             board.
00018   *             To use this driver you have to connect the ANT7-M24LR-A to CN11
00019   *             connector of STM32469I-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 stm32469i_discovery.h file, and the initialization is
00025   *          performed in EEPROM_IO_Init() function declared in stm32469i_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 "stm32469i_discovery_eeprom.h"
00090 
00091 /** @addtogroup BSP
00092   * @{
00093   */
00094   
00095 /** @addtogroup STM32469I_Discovery
00096   * @{
00097   */ 
00098   
00099 /** @defgroup STM32469I-Discovery_EEPROM STM32469I Discovery EEPROM
00100   * @brief This file includes the I2C EEPROM driver of STM32469I-Discovery board.
00101   * @{
00102   */ 
00103 
00104 /** @defgroup STM32469I-Discovery_EEPROM_Private_Types STM32469I Discovery EEPROM Private Types
00105   * @{
00106   */ 
00107 /**
00108   * @}
00109   */ 
00110 
00111 /** @defgroup STM32469I-Discovery_EEPROM_Private_Defines STM32469I Discovery EEPROM Private Defines
00112   * @{
00113   */  
00114 /**
00115   * @}
00116   */ 
00117 
00118 /** @defgroup STM32469I-Discovery_EEPROM_Private_Macros STM32469I Discovery EEPROM Private Macros
00119   * @{
00120   */
00121 /**
00122   * @}
00123   */ 
00124   
00125 /** @defgroup STM32469I-Discovery_EEPROM_Private_Variables STM32469I 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 /** @defgroup STM32469I-Discovery_EEPROM_Private_Function_Prototypes STM32469I Discovery EEPROM Private Prototypes
00137   * @{
00138   */ 
00139 /**
00140   * @}
00141   */ 
00142 
00143 /** @defgroup STM32469I-Discovery_EEPROM_Private_Functions STM32469I Discovery EEPROM Private Functions
00144   * @{
00145   */ 
00146 
00147 /**
00148   * @brief  Initializes peripherals used by the I2C EEPROM driver.
00149   * 
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  DeInitializes the EEPROM.
00177   * @retval EEPROM state
00178   */
00179 uint8_t BSP_EEPROM_DeInit(void)
00180 { 
00181   /* I2C won't be disabled because common to other functionalities */
00182   return EEPROM_OK;
00183 }
00184 
00185 /**
00186   * @brief  Reads a block of data from the EEPROM.
00187   * @param  pBuffer: pointer to the buffer that receives the data read from 
00188   *         the EEPROM.
00189   * @param  ReadAddr: EEPROM's internal address to start reading from.
00190   * @param  NumByteToRead: pointer to the variable holding number of bytes to 
00191   *         be read from the EEPROM.
00192   * 
00193   *        @note The variable pointed by NumByteToRead is reset to 0 when all the 
00194   *              data are read from the EEPROM. Application should monitor this 
00195   *              variable in order know when the transfer is complete.
00196   * 
00197   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00198   *         different from EEPROM_OK (0) or the timeout user callback.
00199   */
00200 uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
00201 {  
00202   uint32_t buffersize = *NumByteToRead;
00203   
00204   /* Set the pointer to the Number of data to be read. This pointer will be used 
00205      by the DMA Transfer Completer interrupt Handler in order to reset the 
00206      variable to 0. User should check on this variable in order to know if the 
00207      DMA transfer has been complete or not. */
00208   EEPROMDataRead = *NumByteToRead;
00209   
00210   if(EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
00211   {
00212     BSP_EEPROM_TIMEOUT_UserCallback();
00213     return EEPROM_FAIL;
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   
00252   /* Set the pointer to the Number of data to be written. This pointer will be used 
00253       by the DMA Transfer Completer interrupt Handler in order to reset the 
00254       variable to 0. User should check on this variable in order to know if the 
00255       DMA transfer has been complete or not. */
00256   EEPROMDataWrite = *NumByteToWrite;  
00257   
00258   if(EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
00259   {
00260     BSP_EEPROM_TIMEOUT_UserCallback();
00261     status = EEPROM_FAIL;
00262   }
00263   
00264   if(BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK) 
00265   {
00266     return EEPROM_FAIL;
00267   }
00268   
00269   /* If all operations OK, return EEPROM_OK (0) */
00270   return status;
00271 }
00272 
00273 /**
00274   * @brief  Writes buffer of data to the I2C EEPROM.
00275   * @param  pBuffer: pointer to the buffer  containing the data to be written 
00276   *         to the EEPROM.
00277   * @param  WriteAddr: EEPROM's internal address to write to.
00278   * @param  NumByteToWrite: number of bytes to write to the EEPROM.
00279   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00280   *         different from EEPROM_OK (0) or the timeout user callback.
00281   */
00282 uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
00283 {
00284   uint16_t numofpage = 0, numofsingle = 0, count = 0;
00285   uint16_t addr = 0;
00286   uint8_t  dataindex = 0;
00287   uint32_t status = EEPROM_OK;
00288 
00289   addr = WriteAddr % EEPROM_PAGESIZE;
00290   count = EEPROM_PAGESIZE - addr;
00291   numofpage =  NumByteToWrite / EEPROM_PAGESIZE;
00292   numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
00293  
00294   /* If WriteAddr is EEPROM_PAGESIZE aligned */
00295   if(addr == 0) 
00296   {
00297     /* If NumByteToWrite < EEPROM_PAGESIZE */
00298     if(numofpage == 0) 
00299     {
00300       /* Store the number of data to be written */
00301       dataindex = numofsingle;
00302       /* Start writing data */
00303       status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00304       if(status != EEPROM_OK)
00305       {
00306         return status;
00307       }
00308     }
00309     /* If NumByteToWrite > EEPROM_PAGESIZE */
00310     else  
00311     {
00312       while(numofpage--)
00313       {
00314         /* Store the number of data to be written */
00315         dataindex = EEPROM_PAGESIZE;        
00316         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00317         if(status != EEPROM_OK)
00318         {
00319           return status;
00320         }
00321         
00322         WriteAddr +=  EEPROM_PAGESIZE;
00323         pBuffer += EEPROM_PAGESIZE;
00324       }
00325       
00326       if(numofsingle!=0)
00327       {
00328         /* Store the number of data to be written */
00329         dataindex = numofsingle;          
00330         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00331         if(status != EEPROM_OK)
00332         {
00333           return status;
00334         }
00335       }
00336     }
00337   }
00338   /* If WriteAddr is not EEPROM_PAGESIZE aligned */
00339   else 
00340   {
00341     /* If NumByteToWrite < EEPROM_PAGESIZE */
00342     if(numofpage== 0) 
00343     {
00344       /* If the number of data to be written is more than the remaining space 
00345       in the current page: */
00346       if(NumByteToWrite > count)
00347       {
00348         /* Store the number of data to be written */
00349         dataindex = count;        
00350         /* Write the data contained in same page */
00351         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00352         if(status != EEPROM_OK)
00353         {
00354           return status;
00355         }
00356         
00357         /* Store the number of data to be written */
00358         dataindex = (NumByteToWrite - count);          
00359         /* Write the remaining data in the following page */
00360         status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
00361         if(status != EEPROM_OK)
00362         {
00363           return status;
00364         }
00365       }      
00366       else      
00367       {
00368         /* Store the number of data to be written */
00369         dataindex = numofsingle;         
00370         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00371         if(status != EEPROM_OK)
00372         {
00373           return status;
00374         }
00375       }     
00376     }
00377     /* If NumByteToWrite > EEPROM_PAGESIZE */
00378     else
00379     {
00380       NumByteToWrite -= count;
00381       numofpage =  NumByteToWrite / EEPROM_PAGESIZE;
00382       numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
00383       
00384       if(count != 0)
00385       {  
00386         /* Store the number of data to be written */
00387         dataindex = count;         
00388         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00389         if(status != EEPROM_OK)
00390         {
00391           return status;
00392         }
00393         WriteAddr += count;
00394         pBuffer += count;
00395       } 
00396       
00397       while(numofpage--)
00398       {
00399         /* Store the number of data to be written */
00400         dataindex = EEPROM_PAGESIZE;          
00401         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00402         if(status != EEPROM_OK)
00403         {
00404           return status;
00405         }
00406         WriteAddr +=  EEPROM_PAGESIZE;
00407         pBuffer += EEPROM_PAGESIZE;  
00408       }
00409       if(numofsingle != 0)
00410       {
00411         /* Store the number of data to be written */
00412         dataindex = numofsingle;           
00413         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00414         if(status != EEPROM_OK)
00415         {
00416           return status;
00417         }
00418       }
00419     }
00420   }  
00421                                    
00422   /* If all operations OK, return EEPROM_OK (0) */
00423   return EEPROM_OK;
00424 }
00425 
00426 /**
00427   * @brief  Wait for EEPROM Standby state.
00428   * 
00429   * @note  This function allows to wait and check that EEPROM has finished the 
00430   *        last operation. It is mostly used after Write operation: after receiving
00431   *        the buffer to be written, the EEPROM may need additional time to actually
00432   *        perform the write operation. During this time, it doesn't answer to
00433   *        I2C packets addressed to it. Once the write operation is complete
00434   *        the EEPROM responds to its address.
00435   * 
00436   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00437   *         different from EEPROM_OK (0) or the timeout user callback.
00438   */
00439 uint32_t BSP_EEPROM_WaitEepromStandbyState(void)      
00440 {
00441   /* Check if the maximum allowed number of trials has bee reached */
00442   if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
00443   {
00444     /* If the maximum number of trials has been reached, exit the function */
00445     BSP_EEPROM_TIMEOUT_UserCallback();
00446     return EEPROM_TIMEOUT;
00447   }
00448   return EEPROM_OK;
00449 }
00450 
00451 /**
00452   * @brief  Basic management of the timeout situation.
00453   */
00454 __weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
00455 {
00456 }
00457 
00458 /**
00459   * @}
00460   */
00461 
00462 /**
00463   * @}
00464   */
00465 
00466 /**
00467   * @}
00468   */
00469 
00470 /**
00471   * @}
00472   */
00473 
00474 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Jan 13 2017 11:00:15 for STM32469I-Discovery BSP User Manual by   doxygen 1.7.6.1