STM32446E_EVAL BSP User Manual: stm32446e_eval_eeprom.c Source File

STM32446E EVAL BSP Drivers

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