STM32412G-Discovery BSP User Manual: stm32412g_discovery_eeprom.c Source File

STM32412G-Discovery BSP Drivers

stm32412g_discovery_eeprom.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32412g_discovery_eeprom.c
00004   * @author  MCD Application Team
00005   * @version V2.0.0
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 STM32412G_DISCOVERY
00017   *             board.
00018   *             To use this driver you have to connect the ANT7-M24LR-A to CN3 
00019   *             connector of STM32412G_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 stm32412g_discovery.h file, and the initialization is
00025   *          performed in EEPROM_IO_Init() function declared in stm32412g_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 "stm32412g_discovery_eeprom.h"
00090 
00091 /** @addtogroup BSP
00092   * @{
00093   */
00094   
00095 /** @addtogroup STM32412G_DISCOVERY
00096   * @{
00097   */ 
00098   
00099 /** @defgroup STM32412G_DISCOVERY_EEPROM STM32412G-DISCOVERY EEPROM
00100   * @brief This file includes the I2C EEPROM driver of STM32412G-DISCOVERY board.
00101   * @{
00102   */ 
00103 
00104 /** @defgroup STM32412G_DISCOVERY_EEPROM_Private_Variables STM32412G Discovery Eeprom Private Variables
00105   * @{
00106   */
00107 __IO uint16_t EEPROMAddress = 0;
00108 __IO uint16_t EEPROMDataRead;
00109 __IO uint8_t  EEPROMDataWrite;
00110 /**
00111   * @}
00112   */ 
00113 
00114 /** @defgroup STM32412G_DISCOVERY_EEPROM_Private_Functions STM32412G Discovery Eeprom Private Functions
00115   * @{
00116   */ 
00117 
00118 /**
00119   * @brief  Initializes peripherals used by the I2C EEPROM driver.
00120   * @note   There are 2 different versions of M24LR64 (A01 & A02).
00121   *             Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01) 
00122   *             and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02)
00123   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00124   *         different from EEPROM_OK (0)
00125   */
00126 uint32_t BSP_EEPROM_Init(void)
00127 { 
00128   /* I2C Initialization */
00129   EEPROM_IO_Init();
00130   
00131   /* Select the EEPROM address for A01 and check if OK */
00132   EEPROMAddress = EEPROM_I2C_ADDRESS_A01;
00133   if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK) 
00134   {
00135     /* Select the EEPROM address for A02 and check if OK */
00136     EEPROMAddress = EEPROM_I2C_ADDRESS_A02;
00137     if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
00138     {
00139       return EEPROM_FAIL;
00140     }
00141   }
00142   return EEPROM_OK;
00143 }
00144 
00145 /**
00146   * @brief  DeInitializes the EEPROM.
00147   * @retval EEPROM state
00148   */
00149 uint8_t BSP_EEPROM_DeInit(void)
00150 { 
00151   /* I2C won't be disabled because common to other functionalities */
00152   return EEPROM_OK;
00153 }
00154 
00155 /**
00156   * @brief  Reads a block of data from the EEPROM.
00157   * @param  pBuffer: pointer to the buffer that receives the data read from 
00158   *         the EEPROM.
00159   * @param  ReadAddr: EEPROM's internal address to start reading from.
00160   * @param  NumByteToRead: pointer to the variable holding number of bytes to 
00161   *         be read from the EEPROM.
00162   * 
00163   * @note   The variable pointed by NumByteToRead is reset to 0 when all the 
00164   *         data are read from the EEPROM. Application should monitor this 
00165   *         variable in order know when the transfer is complete.
00166   * 
00167   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00168   *         different from EEPROM_OK (0) or the timeout user callback.
00169   */
00170 uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
00171 {  
00172   uint32_t buffersize = *NumByteToRead;
00173   
00174   /* Set the pointer to the Number of data to be read. This pointer will be used 
00175      by the DMA Transfer Completer interrupt Handler in order to reset the 
00176      variable to 0. User should check on this variable in order to know if the 
00177      DMA transfer has been complete or not. */
00178   EEPROMDataRead = *NumByteToRead;
00179   
00180   if(EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
00181   {
00182     BSP_EEPROM_TIMEOUT_UserCallback();
00183     return EEPROM_FAIL;
00184   }
00185 
00186   /* If all operations OK, return EEPROM_OK (0) */
00187   return EEPROM_OK;
00188 }
00189 
00190 /**
00191   * @brief  Writes more than one byte to the EEPROM with a single WRITE cycle.
00192   *
00193   * @note   The number of bytes (combined to write start address) must not 
00194   *         cross the EEPROM page boundary. This function can only write into
00195   *         the boundaries of an EEPROM page.
00196   *         This function doesn't check on boundaries condition (in this driver 
00197   *         the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is 
00198   *         responsible of checking on Page boundaries).
00199   * 
00200   * @param  pBuffer: pointer to the buffer containing the data to be written to 
00201   *         the EEPROM.
00202   * @param  WriteAddr: EEPROM's internal address to write to.
00203   * @param  NumByteToWrite: pointer to the variable holding number of bytes to 
00204   *         be written into the EEPROM. 
00205   * 
00206   * @note   The variable pointed by NumByteToWrite is reset to 0 when all the 
00207   *         data are written to the EEPROM. Application should monitor this 
00208   *         variable in order know when the transfer is complete.
00209   * 
00210   * @note   This function just configure the communication and enable the DMA 
00211   *         channel to transfer data. Meanwhile, the user application may perform 
00212   *         other tasks in parallel.
00213   * 
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_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
00218 { 
00219   uint32_t buffersize = *NumByteToWrite;
00220   uint32_t status = EEPROM_OK;
00221   
00222   /* Set the pointer to the Number of data to be written. This pointer will be used 
00223       by the DMA Transfer Completer interrupt Handler in order to reset the 
00224       variable to 0. User should check on this variable in order to know if the 
00225       DMA transfer has been complete or not. */
00226   EEPROMDataWrite = *NumByteToWrite;  
00227   
00228   if(EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
00229   {
00230     BSP_EEPROM_TIMEOUT_UserCallback();
00231     status = EEPROM_FAIL;
00232   }
00233   
00234   if(BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK) 
00235   {
00236     return EEPROM_FAIL;
00237   }
00238   
00239   /* If all operations OK, return EEPROM_OK (0) */
00240   return status;
00241 }
00242 
00243 /**
00244   * @brief  Writes buffer of data to the I2C EEPROM.
00245   * @param  pBuffer: pointer to the buffer  containing the data to be written 
00246   *         to the EEPROM.
00247   * @param  WriteAddr: EEPROM's internal address to write to.
00248   * @param  NumByteToWrite: number of bytes to write to the EEPROM.
00249   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00250   *         different from EEPROM_OK (0) or the timeout user callback.
00251   */
00252 uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
00253 {
00254   uint16_t numofpage = 0, numofsingle = 0, count = 0;
00255   uint16_t addr = 0;
00256   uint8_t  dataindex = 0;
00257   uint32_t status = EEPROM_OK;
00258 
00259   addr = WriteAddr % EEPROM_PAGESIZE;
00260   count = EEPROM_PAGESIZE - addr;
00261   numofpage =  NumByteToWrite / EEPROM_PAGESIZE;
00262   numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
00263  
00264   /* If WriteAddr is EEPROM_PAGESIZE aligned */
00265   if(addr == 0) 
00266   {
00267     /* If NumByteToWrite < EEPROM_PAGESIZE */
00268     if(numofpage == 0) 
00269     {
00270       /* Store the number of data to be written */
00271       dataindex = numofsingle;
00272       /* Start writing data */
00273       status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00274       if(status != EEPROM_OK)
00275       {
00276         return status;
00277       }
00278     }
00279     /* If NumByteToWrite > EEPROM_PAGESIZE */
00280     else  
00281     {
00282       while(numofpage--)
00283       {
00284         /* Store the number of data to be written */
00285         dataindex = EEPROM_PAGESIZE;        
00286         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00287         if(status != EEPROM_OK)
00288         {
00289           return status;
00290         }
00291         
00292         WriteAddr +=  EEPROM_PAGESIZE;
00293         pBuffer += EEPROM_PAGESIZE;
00294       }
00295       
00296       if(numofsingle!=0)
00297       {
00298         /* Store the number of data to be written */
00299         dataindex = numofsingle;          
00300         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00301         if(status != EEPROM_OK)
00302         {
00303           return status;
00304         }
00305       }
00306     }
00307   }
00308   /* If WriteAddr is not EEPROM_PAGESIZE aligned */
00309   else 
00310   {
00311     /* If NumByteToWrite < EEPROM_PAGESIZE */
00312     if(numofpage== 0) 
00313     {
00314       /* If the number of data to be written is more than the remaining space 
00315       in the current page: */
00316       if(NumByteToWrite > count)
00317       {
00318         /* Store the number of data to be written */
00319         dataindex = count;        
00320         /* Write the data contained in same page */
00321         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00322         if(status != EEPROM_OK)
00323         {
00324           return status;
00325         }
00326         
00327         /* Store the number of data to be written */
00328         dataindex = (NumByteToWrite - count);          
00329         /* Write the remaining data in the following page */
00330         status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
00331         if(status != EEPROM_OK)
00332         {
00333           return status;
00334         }
00335       }      
00336       else      
00337       {
00338         /* Store the number of data to be written */
00339         dataindex = numofsingle;         
00340         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00341         if(status != EEPROM_OK)
00342         {
00343           return status;
00344         }
00345       }     
00346     }
00347     /* If NumByteToWrite > EEPROM_PAGESIZE */
00348     else
00349     {
00350       NumByteToWrite -= count;
00351       numofpage =  NumByteToWrite / EEPROM_PAGESIZE;
00352       numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
00353       
00354       if(count != 0)
00355       {  
00356         /* Store the number of data to be written */
00357         dataindex = count;         
00358         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00359         if(status != EEPROM_OK)
00360         {
00361           return status;
00362         }
00363         WriteAddr += count;
00364         pBuffer += count;
00365       } 
00366       
00367       while(numofpage--)
00368       {
00369         /* Store the number of data to be written */
00370         dataindex = EEPROM_PAGESIZE;          
00371         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00372         if(status != EEPROM_OK)
00373         {
00374           return status;
00375         }
00376         WriteAddr +=  EEPROM_PAGESIZE;
00377         pBuffer += EEPROM_PAGESIZE;  
00378       }
00379       if(numofsingle != 0)
00380       {
00381         /* Store the number of data to be written */
00382         dataindex = numofsingle;           
00383         status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
00384         if(status != EEPROM_OK)
00385         {
00386           return status;
00387         }
00388       }
00389     }
00390   }  
00391                                    
00392   /* If all operations OK, return EEPROM_OK (0) */
00393   return EEPROM_OK;
00394 }
00395 
00396 /**
00397   * @brief  Wait for EEPROM Standby state.
00398   * 
00399   * @note  This function allows to wait and check that EEPROM has finished the 
00400   *        last operation. It is mostly used after Write operation: after receiving
00401   *        the buffer to be written, the EEPROM may need additional time to actually
00402   *        perform the write operation. During this time, it doesn't answer to
00403   *        I2C packets addressed to it. Once the write operation is complete
00404   *        the EEPROM responds to its address.
00405   * @retval EEPROM_OK (0) if operation is correctly performed, else return value 
00406   *         different from EEPROM_OK (0) or the timeout user callback.
00407   */
00408 uint32_t BSP_EEPROM_WaitEepromStandbyState(void)      
00409 {
00410   /* Check if the maximum allowed number of trials has bee reached */
00411   if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
00412   {
00413     /* If the maximum number of trials has been reached, exit the function */
00414     BSP_EEPROM_TIMEOUT_UserCallback();
00415     return EEPROM_TIMEOUT;
00416   }
00417   return EEPROM_OK;
00418 }
00419 
00420 /**
00421   * @brief  Basic management of the timeout situation.
00422   */
00423 __weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
00424 {
00425 }
00426 
00427 /**
00428   * @}
00429   */
00430 
00431 /**
00432   * @}
00433   */
00434 
00435 /**
00436   * @}
00437   */
00438 
00439 /**
00440   * @}
00441   */
00442 
00443 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jan 24 2017 11:28:05 for STM32412G-Discovery BSP User Manual by   doxygen 1.7.6.1