stm32_eval_i2c_ee.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32_eval_i2c_ee.c
00004   * @author  MCD Application Team
00005   * @version V4.3.0
00006   * @date    10/15/2010
00007   * @brief   This file provides a set of functions needed to manage the I2C M24CXX 
00008   *          EEPROM memory mounted on STM32xx-EVAL board (refer to stm32_eval.h
00009   *          to know about the boards supporting this memory). 
00010   *          
00011   *          ===================================================================      
00012   *          Note: This driver is intended for STM32F10x families devices only.
00013   *          ===================================================================
00014   *            
00015   *          It implements a high level communication layer for read and write 
00016   *          from/to this memory. The needed STM32 hardware resources (I2C and 
00017   *          GPIO) are defined in stm32xx_eval.h file, and the initialization is 
00018   *          performed in sEE_LowLevel_Init() function declared in stm32xx_eval.c 
00019   *          file.
00020   *          You can easily tailor this driver to any other development board, 
00021   *          by just adapting the defines for hardware resources and 
00022   *          sEE_LowLevel_Init() function. 
00023   *        
00024   *          @note In this driver, basic read and write functions (sEE_ReadBuffer() 
00025   *                and sEE_WritePage()) use the DMA to perform the data transfer 
00026   *                to/from EEPROM memory (except when number of requested data is
00027   *                equal to 1). Thus, after calling these two functions, user 
00028   *                application may perform other tasks while DMA is transferring
00029   *                data. The application should then monitor the variable holding 
00030   *                the number of data in order to determine when the transfer is
00031   *                completed (variable decremented to 0). Stopping transfer tasks
00032   *                are performed into DMA interrupt handlers (which are integrated
00033   *                into this driver).
00034   *            
00035   *     +-----------------------------------------------------------------+
00036   *     |                        Pin assignment                           |                 
00037   *     +---------------------------------------+-----------+-------------+
00038   *     |  STM32 I2C Pins                       |   sEE     |   Pin       |
00039   *     +---------------------------------------+-----------+-------------+
00040   *     | .                                     |   E0(GND) |    1  (0V)  |
00041   *     | .                                     |   E1(GND) |    2  (0V)  |
00042   *     | .                                     |   E2(GND) |    3  (0V)  |
00043   *     | .                                     |   E0(VSS) |    4  (0V)  |
00044   *     | sEE_I2C_SDA_PIN/ SDA                  |   SDA     |    5        |
00045   *     | sEE_I2C_SCL_PIN/ SCL                  |   SCL     |    6        |
00046   *     | .                                     |   /WC(VDD)|    7 (3.3V) |
00047   *     | .                                     |   VDD     |    8 (3.3V) |
00048   *     +---------------------------------------+-----------+-------------+  
00049   ******************************************************************************
00050   * @copy
00051   *
00052   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00053   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00054   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00055   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00056   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00057   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00058   *
00059   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
00060   */ 
00061 
00062 /* Includes ------------------------------------------------------------------*/
00063 #include "stm32_eval_i2c_ee.h"
00064 
00065 /** @addtogroup Utilities
00066   * @{
00067   */
00068   
00069 /** @addtogroup STM32_EVAL
00070   * @{
00071   */ 
00072 
00073 /** @addtogroup Common
00074   * @{
00075   */
00076   
00077 /** @addtogroup STM32_EVAL_I2C_EE
00078   * @brief      This file includes the I2C EEPROM driver of STM32-EVAL boards.
00079   * @{
00080   */ 
00081 
00082 /** @defgroup STM32_EVAL_I2C_EE_Private_Types
00083   * @{
00084   */ 
00085 /**
00086   * @}
00087   */ 
00088 
00089 
00090 /** @defgroup STM32_EVAL_I2C_EE_Private_Defines
00091   * @{
00092   */  
00093 /**
00094   * @}
00095   */ 
00096 
00097 
00098 /** @defgroup STM32_EVAL_I2C_EE_Private_Macros
00099   * @{
00100   */
00101 /**
00102   * @}
00103   */ 
00104   
00105 
00106 /** @defgroup STM32_EVAL_I2C_EE_Private_Variables
00107   * @{
00108   */
00109 __IO uint16_t  sEEAddress = 0;   
00110 __IO uint32_t  sEETimeout = sEE_LONG_TIMEOUT;   
00111 __IO uint16_t* sEEDataReadPointer;   
00112 __IO uint8_t*  sEEDataWritePointer;  
00113 __IO uint8_t   sEEDataNum;
00114 /**
00115   * @}
00116   */ 
00117 
00118 
00119 /** @defgroup STM32_EVAL_I2C_EE_Private_Function_Prototypes
00120   * @{
00121   */ 
00122 /**
00123   * @}
00124   */ 
00125 
00126 
00127 /** @defgroup STM32_EVAL_I2C_EE_Private_Functions
00128   * @{
00129   */ 
00130 
00131 /**
00132   * @brief  DeInitializes peripherals used by the I2C EEPROM driver.
00133   * @param  None
00134   * @retval None
00135   */
00136 void sEE_DeInit(void)
00137 {
00138   sEE_LowLevel_DeInit(); 
00139 }
00140 
00141 /**
00142   * @brief  Initializes peripherals used by the I2C EEPROM driver.
00143   * @param  None
00144   * @retval None
00145   */
00146 void sEE_Init(void)
00147 { 
00148   I2C_InitTypeDef  I2C_InitStructure;
00149   
00150   sEE_LowLevel_Init();
00151   
00152   /*!< I2C configuration */
00153   /* sEE_I2C configuration */
00154   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
00155   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
00156   I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
00157   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
00158   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
00159   I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
00160   
00161   /* sEE_I2C Peripheral Enable */
00162   I2C_Cmd(sEE_I2C, ENABLE);
00163   /* Apply sEE_I2C configuration after enabling it */
00164   I2C_Init(sEE_I2C, &I2C_InitStructure);
00165 
00166   /* Enable the sEE_I2C peripheral DMA requests */
00167   I2C_DMACmd(sEE_I2C, ENABLE);
00168   
00169 #if defined (sEE_M24C64_32)
00170   /*!< Select the EEPROM address according to the state of E0, E1, E2 pins */
00171   sEEAddress = sEE_HW_ADDRESS;  
00172 #elif defined (sEE_M24C08)
00173   /*!< depending on the sEE Address selected in the i2c_ee.h file */
00174  #ifdef sEE_Block0_ADDRESS
00175   /*!< Select the sEE Block0 to write on */
00176   sEEAddress = sEE_Block0_ADDRESS;
00177  #endif
00178   
00179  #ifdef sEE_Block1_ADDRESS
00180   /*!< Select the sEE Block1 to write on */
00181   sEEAddress = sEE_Block1_ADDRESS;
00182  #endif
00183 
00184  #ifdef sEE_Block2_ADDRESS
00185   /*!< Select the sEE Block2 to write on */
00186   sEEAddress = sEE_Block2_ADDRESS;
00187  #endif
00188   
00189  #ifdef sEE_Block3_ADDRESS
00190   /*!< Select the sEE Block3 to write on */
00191   sEEAddress = sEE_Block3_ADDRESS;
00192  #endif 
00193 #endif /*!< sEE_M24C64_32 */    
00194 }
00195 
00196 /**
00197   * @brief  Reads a block of data from the EEPROM.
00198   * @param  pBuffer : pointer to the buffer that receives the data read from 
00199   *         the EEPROM.
00200   * @param  ReadAddr : EEPROM's internal address to start reading from.
00201   * @param  NumByteToRead : pointer to the variable holding number of bytes to 
00202   *         be read from the EEPROM.
00203   * 
00204   *        @note The variable pointed by NumByteToRead is reset to 0 when all the 
00205   *              data are read from the EEPROM. Application should monitor this 
00206   *              variable in order know when the transfer is complete.
00207   * 
00208   * @note When number of data to be read is higher than 1, this function just 
00209   *       configures the communication and enable the DMA channel to transfer data.
00210   *       Meanwhile, the user application may perform other tasks.
00211   *       When number of data to be read is 1, then the DMA is not used. The byte
00212   *       is read in polling mode.
00213   * 
00214   * @retval sEE_OK (0) if operation is correctly performed, else return value 
00215   *         different from sEE_OK (0) or the timeout user callback.
00216   */
00217 uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
00218 {  
00219   /* Set the pointer to the Number of data to be read. This pointer will be used 
00220       by the DMA Transfer Completer interrupt Handler in order to reset the 
00221       variable to 0. User should check on this variable in order to know if the 
00222       DMA transfer has been complete or not. */
00223   sEEDataReadPointer = NumByteToRead;
00224   
00225   /*!< While the bus is busy */
00226   sEETimeout = sEE_LONG_TIMEOUT;
00227   while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
00228   {
00229     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00230   }
00231   
00232   /*!< Send START condition */
00233   I2C_GenerateSTART(sEE_I2C, ENABLE);
00234   
00235   /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
00236   sEETimeout = sEE_FLAG_TIMEOUT;
00237   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
00238   {
00239     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00240   }
00241   
00242   /*!< Send EEPROM address for write */
00243   I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
00244 
00245   /*!< Test on EV6 and clear it */
00246   sEETimeout = sEE_FLAG_TIMEOUT;
00247   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
00248   {
00249     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00250   } 
00251 
00252 #ifdef sEE_M24C08  
00253   
00254   /*!< Send the EEPROM's internal address to read from: Only one byte address */
00255   I2C_SendData(sEE_I2C, ReadAddr);  
00256 
00257 #elif defined (sEE_M24C64_32)
00258 
00259   /*!< Send the EEPROM's internal address to read from: MSB of the address first */
00260   I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));    
00261 
00262   /*!< Test on EV8 and clear it */
00263   sEETimeout = sEE_FLAG_TIMEOUT;
00264   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
00265   {
00266     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00267   }
00268 
00269   /*!< Send the EEPROM's internal address to read from: LSB of the address */
00270   I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));    
00271   
00272 #endif /*!< sEE_M24C08 */
00273 
00274   /*!< Test on EV8 and clear it */
00275   sEETimeout = sEE_FLAG_TIMEOUT;
00276   while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF) == RESET)
00277   {
00278     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00279   }
00280   
00281   /*!< Send STRAT condition a second time */  
00282   I2C_GenerateSTART(sEE_I2C, ENABLE);
00283   
00284   /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
00285   sEETimeout = sEE_FLAG_TIMEOUT;
00286   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
00287   {
00288     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00289   } 
00290   
00291   /*!< Send EEPROM address for read */
00292   I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver);  
00293   
00294   /* If number of data to be read is 1, then DMA couldn't be used */
00295   /* One Byte Master Reception procedure (POLLING) ---------------------------*/
00296   if ((uint16_t)(*NumByteToRead) < 2)
00297   {
00298     /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
00299     sEETimeout = sEE_FLAG_TIMEOUT;
00300     while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_ADDR) == RESET)
00301     {
00302       if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00303     }     
00304     
00305     /*!< Disable Acknowledgement */
00306     I2C_AcknowledgeConfig(sEE_I2C, DISABLE);   
00307 
00308     /* Call User callback for critical section start (should typically disable interrupts) */
00309     sEE_EnterCriticalSection_UserCallback();
00310     
00311     /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
00312     (void)sEE_I2C->SR2;
00313     
00314     /*!< Send STOP Condition */
00315     I2C_GenerateSTOP(sEE_I2C, ENABLE);
00316    
00317     /* Call User callback for critical section end (should typically re-enable interrupts) */
00318     sEE_ExitCriticalSection_UserCallback();
00319     
00320     /* Wait for the byte to be received */
00321     sEETimeout = sEE_FLAG_TIMEOUT;
00322     while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_RXNE) == RESET)
00323     {
00324       if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00325     }
00326     
00327     /*!< Read the byte received from the EEPROM */
00328     *pBuffer = I2C_ReceiveData(sEE_I2C);
00329     
00330     /*!< Decrement the read bytes counter */
00331     (uint16_t)(*NumByteToRead)--;        
00332     
00333     /* Wait to make sure that STOP control bit has been cleared */
00334     sEETimeout = sEE_FLAG_TIMEOUT;
00335     while(sEE_I2C->CR1 & I2C_CR1_STOP)
00336     {
00337       if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00338     }  
00339     
00340     /*!< Re-Enable Acknowledgement to be ready for another reception */
00341     I2C_AcknowledgeConfig(sEE_I2C, ENABLE);    
00342   }
00343   else/* More than one Byte Master Reception procedure (DMA) -----------------*/
00344   {
00345     /*!< Test on EV6 and clear it */
00346     sEETimeout = sEE_FLAG_TIMEOUT;
00347     while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
00348     {
00349       if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00350     }  
00351     
00352     /* Configure the DMA Rx Channel with the buffer address and the buffer size */
00353     sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX);
00354     
00355     /* Inform the DMA that the next End Of Transfer Signal will be the last one */
00356     I2C_DMALastTransferCmd(sEE_I2C, ENABLE); 
00357     
00358     /* Enable the DMA Rx Channel */
00359     DMA_Cmd(sEE_I2C_DMA_CHANNEL_RX, ENABLE);  
00360   }
00361   
00362   /* If all operations OK, return sEE_OK (0) */
00363   return sEE_OK;
00364 }
00365 
00366 /**
00367   * @brief  Writes more than one byte to the EEPROM with a single WRITE cycle.
00368   *
00369   * @note   The number of bytes (combined to write start address) must not 
00370   *         cross the EEPROM page boundary. This function can only write into
00371   *         the boundaries of an EEPROM page.
00372   *         This function doesn't check on boundaries condition (in this driver 
00373   *         the function sEE_WriteBuffer() which calls sEE_WritePage() is 
00374   *         responsible of checking on Page boundaries).
00375   * 
00376   * @param  pBuffer : pointer to the buffer containing the data to be written to 
00377   *         the EEPROM.
00378   * @param  WriteAddr : EEPROM's internal address to write to.
00379   * @param  NumByteToWrite : pointer to the variable holding number of bytes to 
00380   *         be written into the EEPROM. 
00381   * 
00382   *        @note The variable pointed by NumByteToWrite is reset to 0 when all the 
00383   *              data are written to the EEPROM. Application should monitor this 
00384   *              variable in order know when the transfer is complete.
00385   * 
00386   * @note This function just configure the communication and enable the DMA 
00387   *       channel to transfer data. Meanwhile, the user application may perform 
00388   *       other tasks in parallel.
00389   * 
00390   * @retval sEE_OK (0) if operation is correctly performed, else return value 
00391   *         different from sEE_OK (0) or the timeout user callback.
00392   */
00393 uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
00394 { 
00395   /* Set the pointer to the Number of data to be written. This pointer will be used 
00396       by the DMA Transfer Completer interrupt Handler in order to reset the 
00397       variable to 0. User should check on this variable in order to know if the 
00398       DMA transfer has been complete or not. */
00399   sEEDataWritePointer = NumByteToWrite;  
00400   
00401   /*!< While the bus is busy */
00402   sEETimeout = sEE_LONG_TIMEOUT;
00403   while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
00404   {
00405     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00406   }
00407   
00408   /*!< Send START condition */
00409   I2C_GenerateSTART(sEE_I2C, ENABLE);
00410   
00411   /*!< Test on EV5 and clear it */
00412   sEETimeout = sEE_FLAG_TIMEOUT;
00413   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
00414   {
00415     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00416   }
00417   
00418   /*!< Send EEPROM address for write */
00419   sEETimeout = sEE_FLAG_TIMEOUT;
00420   I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
00421 
00422   /*!< Test on EV6 and clear it */
00423   sEETimeout = sEE_FLAG_TIMEOUT;
00424   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
00425   {
00426     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00427   }
00428 
00429 #ifdef sEE_M24C08
00430   
00431   /*!< Send the EEPROM's internal address to write to : only one byte Address */
00432   I2C_SendData(sEE_I2C, WriteAddr);
00433   
00434 #elif defined(sEE_M24C64_32)
00435   
00436   /*!< Send the EEPROM's internal address to write to : MSB of the address first */
00437   I2C_SendData(sEE_I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8));
00438 
00439   /*!< Test on EV8 and clear it */
00440   sEETimeout = sEE_FLAG_TIMEOUT;  
00441   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
00442   {
00443     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00444   }  
00445   
00446   /*!< Send the EEPROM's internal address to write to : LSB of the address */
00447   I2C_SendData(sEE_I2C, (uint8_t)(WriteAddr & 0x00FF));
00448   
00449 #endif /*!< sEE_M24C08 */  
00450   
00451   /*!< Test on EV8 and clear it */
00452   sEETimeout = sEE_FLAG_TIMEOUT; 
00453   while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
00454   {
00455     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00456   }  
00457   
00458   /* Configure the DMA Tx Channel with the buffer address and the buffer size */
00459   sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint8_t)(*NumByteToWrite), sEE_DIRECTION_TX);
00460     
00461   /* Enable the DMA Tx Channel */
00462   DMA_Cmd(sEE_I2C_DMA_CHANNEL_TX, ENABLE);
00463   
00464   /* If all operations OK, return sEE_OK (0) */
00465   return sEE_OK;
00466 }
00467 
00468 /**
00469   * @brief  Writes buffer of data to the I2C EEPROM.
00470   * @param  pBuffer : pointer to the buffer  containing the data to be written 
00471   *         to the EEPROM.
00472   * @param  WriteAddr : EEPROM's internal address to write to.
00473   * @param  NumByteToWrite : number of bytes to write to the EEPROM.
00474   * @retval None
00475   */
00476 void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
00477 {
00478   uint8_t NumOfPage = 0, NumOfSingle = 0, count = 0;
00479   uint16_t Addr = 0;
00480 
00481   Addr = WriteAddr % sEE_PAGESIZE;
00482   count = sEE_PAGESIZE - Addr;
00483   NumOfPage =  NumByteToWrite / sEE_PAGESIZE;
00484   NumOfSingle = NumByteToWrite % sEE_PAGESIZE;
00485  
00486   /*!< If WriteAddr is sEE_PAGESIZE aligned  */
00487   if(Addr == 0) 
00488   {
00489     /*!< If NumByteToWrite < sEE_PAGESIZE */
00490     if(NumOfPage == 0) 
00491     {
00492       /* Store the number of data to be written */
00493       sEEDataNum = NumOfSingle;
00494       /* Start writing data */
00495       sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
00496       /* Wait transfer through DMA to be complete */
00497       sEETimeout = sEE_LONG_TIMEOUT;
00498       while (sEEDataNum > 0)
00499       {
00500         if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00501       }
00502       sEE_WaitEepromStandbyState();
00503     }
00504     /*!< If NumByteToWrite > sEE_PAGESIZE */
00505     else  
00506     {
00507       while(NumOfPage--)
00508       {
00509         /* Store the number of data to be written */
00510         sEEDataNum = sEE_PAGESIZE;        
00511         sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 
00512         /* Wait transfer through DMA to be complete */
00513         sEETimeout = sEE_LONG_TIMEOUT;
00514         while (sEEDataNum > 0)
00515         {
00516           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00517         }      
00518         sEE_WaitEepromStandbyState();
00519         WriteAddr +=  sEE_PAGESIZE;
00520         pBuffer += sEE_PAGESIZE;
00521       }
00522 
00523       if(NumOfSingle!=0)
00524       {
00525         /* Store the number of data to be written */
00526         sEEDataNum = NumOfSingle;          
00527         sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
00528         /* Wait transfer through DMA to be complete */
00529         sEETimeout = sEE_LONG_TIMEOUT;
00530         while (sEEDataNum > 0)
00531         {
00532           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00533         }    
00534         sEE_WaitEepromStandbyState();
00535       }
00536     }
00537   }
00538   /*!< If WriteAddr is not sEE_PAGESIZE aligned  */
00539   else 
00540   {
00541     /*!< If NumByteToWrite < sEE_PAGESIZE */
00542     if(NumOfPage== 0) 
00543     {
00544       /*!< If the number of data to be written is more than the remaining space 
00545       in the current page: */
00546       if (NumByteToWrite > count)
00547       {
00548         /* Store the number of data to be written */
00549         sEEDataNum = count;        
00550         /*!< Write the data conained in same page */
00551         sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
00552         /* Wait transfer through DMA to be complete */
00553         sEETimeout = sEE_LONG_TIMEOUT;
00554         while (sEEDataNum > 0)
00555         {
00556           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00557         }          
00558         sEE_WaitEepromStandbyState();      
00559         
00560         /* Store the number of data to be written */
00561         sEEDataNum = (NumByteToWrite - count);          
00562         /*!< Write the remaining data in the following page */
00563         sEE_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&sEEDataNum));
00564         /* Wait transfer through DMA to be complete */
00565         sEETimeout = sEE_LONG_TIMEOUT;
00566         while (sEEDataNum > 0)
00567         {
00568           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00569         }     
00570         sEE_WaitEepromStandbyState();        
00571       }      
00572       else      
00573       {
00574         /* Store the number of data to be written */
00575         sEEDataNum = NumOfSingle;         
00576         sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
00577         /* Wait transfer through DMA to be complete */
00578         sEETimeout = sEE_LONG_TIMEOUT;
00579         while (sEEDataNum > 0)
00580         {
00581           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00582         }          
00583         sEE_WaitEepromStandbyState();        
00584       }     
00585     }
00586     /*!< If NumByteToWrite > sEE_PAGESIZE */
00587     else
00588     {
00589       NumByteToWrite -= count;
00590       NumOfPage =  NumByteToWrite / sEE_PAGESIZE;
00591       NumOfSingle = NumByteToWrite % sEE_PAGESIZE;
00592       
00593       if(count != 0)
00594       {  
00595         /* Store the number of data to be written */
00596         sEEDataNum = count;         
00597         sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
00598         /* Wait transfer through DMA to be complete */
00599         sEETimeout = sEE_LONG_TIMEOUT;
00600         while (sEEDataNum > 0)
00601         {
00602           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00603         }     
00604         sEE_WaitEepromStandbyState();
00605         WriteAddr += count;
00606         pBuffer += count;
00607       } 
00608       
00609       while(NumOfPage--)
00610       {
00611         /* Store the number of data to be written */
00612         sEEDataNum = sEE_PAGESIZE;          
00613         sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
00614         /* Wait transfer through DMA to be complete */
00615         sEETimeout = sEE_LONG_TIMEOUT;
00616         while (sEEDataNum > 0)
00617         {
00618           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00619         }        
00620         sEE_WaitEepromStandbyState();
00621         WriteAddr +=  sEE_PAGESIZE;
00622         pBuffer += sEE_PAGESIZE;  
00623       }
00624       if(NumOfSingle != 0)
00625       {
00626         /* Store the number of data to be written */
00627         sEEDataNum = NumOfSingle;           
00628         sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 
00629         /* Wait transfer through DMA to be complete */
00630         sEETimeout = sEE_LONG_TIMEOUT;
00631         while (sEEDataNum > 0)
00632         {
00633           if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
00634         }         
00635         sEE_WaitEepromStandbyState();
00636       }
00637     }
00638   }  
00639 }
00640 
00641 /**
00642   * @brief  Wait for EEPROM Standby state.
00643   * 
00644   * @note  This function allows to wait and check that EEPROM has finished the 
00645   *        last Write operation. It is mostly used after Write operation: after 
00646   *        receiving the buffer to be written, the EEPROM may need additional 
00647   *        time to actually perform the write operation. During this time, it 
00648   *        doesn't answer to I2C packets addressed to it. Once the write operation 
00649   *        is complete the EEPROM responds to its address.
00650   *        
00651   * @note  It is not necessary to call this function after sEE_WriteBuffer() 
00652   *        function (sEE_WriteBuffer() already calls this function after each
00653   *        write page operation).    
00654   * 
00655   * @param  None
00656   * @retval sEE_OK (0) if operation is correctly performed, else return value 
00657   *         different from sEE_OK (0) or the timeout user callback.
00658   */
00659 uint32_t sEE_WaitEepromStandbyState(void)      
00660 {
00661   __IO uint16_t tmpSR1 = 0;
00662   __IO uint32_t sEETrials = 0;
00663 
00664   /*!< While the bus is busy */
00665   sEETimeout = sEE_LONG_TIMEOUT;
00666   while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
00667   {
00668     if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00669   }
00670 
00671   /* Keep looping till the slave acknowledge his address or maximum number 
00672      of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define
00673      in stm32_eval_i2c_ee.h file) */
00674   while (1)
00675   {
00676     /*!< Send START condition */
00677     I2C_GenerateSTART(sEE_I2C, ENABLE);
00678 
00679     /*!< Test on EV5 and clear it */
00680     sEETimeout = sEE_FLAG_TIMEOUT;
00681     while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
00682     {
00683       if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00684     }    
00685 
00686     /*!< Send EEPROM address for write */
00687     I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
00688     
00689     /* Wait for ADDR flag to be set (Slave acknowledged his address) */
00690     sEETimeout = sEE_LONG_TIMEOUT;
00691     do
00692     {     
00693       /* Get the current value of the SR1 register */
00694       tmpSR1 = sEE_I2C->SR1;
00695       
00696       /* Update the timeout value and exit if it reach 0 */
00697       if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
00698     }
00699     /* Keep looping till the Address is acknowledged or the AF flag is 
00700        set (address not acknowledged at time) */
00701     while((tmpSR1 & (I2C_SR1_ADDR | I2C_SR1_AF)) == 0);
00702      
00703     /* Check if the ADDR flag has been set */
00704     if (tmpSR1 & I2C_SR1_ADDR)
00705     {
00706       /* Clear ADDR Flag by reading SR1 then SR2 registers (SR1 have already 
00707          been read) */
00708       (void)sEE_I2C->SR2;
00709       
00710       /*!< STOP condition */    
00711       I2C_GenerateSTOP(sEE_I2C, ENABLE);
00712         
00713       /* Exit the function */
00714       return sEE_OK;
00715     }
00716     else
00717     {
00718       /*!< Clear AF flag */
00719       I2C_ClearFlag(sEE_I2C, I2C_FLAG_AF);                  
00720     }
00721     
00722     /* Check if the maximum allowed numbe of trials has bee reached */
00723     if (sEETrials++ == sEE_MAX_TRIALS_NUMBER)
00724     {
00725       /* If the maximum number of trials has been reached, exit the function */
00726       return sEE_TIMEOUT_UserCallback();
00727     }
00728   }
00729 }
00730 
00731 /**
00732   * @}
00733   */
00734 
00735 
00736 /**
00737   * @brief  This function handles the DMA Tx Channel interrupt Handler.
00738   * @param  None
00739   * @retval None
00740   */
00741 void sEE_I2C_DMA_TX_IRQHandler(void)
00742 {
00743   /* Check if the DMA transfer is complete */ 
00744   if(DMA_GetFlagStatus(sEE_I2C_DMA_FLAG_TX_TC) != RESET)
00745   {  
00746     /* Disable the DMA Tx Channel and Clear all its Flags */  
00747     DMA_Cmd(sEE_I2C_DMA_CHANNEL_TX, DISABLE);
00748     DMA_ClearFlag(sEE_I2C_DMA_FLAG_TX_GL);
00749 
00750     /*!< Wait till all data have been physically transferred on the bus */
00751     sEETimeout = sEE_LONG_TIMEOUT;
00752     while(!I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF))
00753     {
00754       if((sEETimeout--) == 0) sEE_TIMEOUT_UserCallback();
00755     }
00756     
00757     /*!< Send STOP condition */
00758     I2C_GenerateSTOP(sEE_I2C, ENABLE);
00759     
00760     /* Perform a read on SR1 and SR2 register to clear eventualaly pending flags */
00761     (void)sEE_I2C->SR1;
00762     (void)sEE_I2C->SR2;
00763     
00764     /* Reset the variable holding the number of data to be written */
00765     *sEEDataWritePointer = 0;  
00766   }
00767 }
00768 
00769 /**
00770   * @brief  This function handles the DMA Rx Channel interrupt Handler.
00771   * @param  None
00772   * @retval None
00773   */
00774 void sEE_I2C_DMA_RX_IRQHandler(void)
00775 {
00776   /* Check if the DMA transfer is complete */
00777   if(DMA_GetFlagStatus(sEE_I2C_DMA_FLAG_RX_TC) != RESET)
00778   {      
00779     /*!< Send STOP Condition */
00780     I2C_GenerateSTOP(sEE_I2C, ENABLE);    
00781     
00782     /* Disable the DMA Rx Channel and Clear all its Flags */  
00783     DMA_Cmd(sEE_I2C_DMA_CHANNEL_RX, DISABLE);
00784     DMA_ClearFlag(sEE_I2C_DMA_FLAG_RX_GL);
00785     
00786     /* Reset the variable holding the number of data to be read */
00787     *sEEDataReadPointer = 0;
00788   }
00789 }
00790 
00791 #ifdef USE_DEFAULT_TIMEOUT_CALLBACK
00792 /**
00793   * @brief  Basic management of the timeout situation.
00794   * @param  None.
00795   * @retval None.
00796   */
00797 uint32_t sEE_TIMEOUT_UserCallback(void)
00798 {
00799   /* Block communication and all processes */
00800   while (1)
00801   {   
00802   }
00803 }
00804 #endif /* USE_DEFAULT_TIMEOUT_CALLBACK */
00805 
00806 #ifdef USE_DEFAULT_CRITICAL_CALLBACK
00807 /**
00808   * @brief  Start critical section: these callbacks should be typically used
00809   *         to disable interrupts when entering a critical section of I2C communication
00810   *         You may use default callbacks provided into this driver by uncommenting the 
00811   *         define USE_DEFAULT_CRITICAL_CALLBACK.
00812   *         Or you can comment that line and implement these callbacks into your 
00813   *         application.
00814   * @param  None.
00815   * @retval None.
00816   */
00817 void sEE_EnterCriticalSection_UserCallback(void)
00818 {
00819   __disable_irq();  
00820 }
00821 
00822 /**
00823   * @brief  Start and End of critical section: these callbacks should be typically used
00824   *         to re-enable interrupts when exiting a critical section of I2C communication
00825   *         You may use default callbacks provided into this driver by uncommenting the 
00826   *         define USE_DEFAULT_CRITICAL_CALLBACK.
00827   *         Or you can comment that line and implement these callbacks into your 
00828   *         application.
00829   * @param  None.
00830   * @retval None.
00831   */
00832 void sEE_ExitCriticalSection_UserCallback(void)
00833 {
00834   __enable_irq();
00835 }
00836 #endif /* USE_DEFAULT_CRITICAL_CALLBACK */
00837 
00838 /**
00839   * @}
00840   */
00841 
00842 
00843 /**
00844   * @}
00845   */
00846 
00847 /**
00848   * @}
00849   */
00850 
00851 /**
00852   * @}
00853   */  
00854 
00855 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
STM32F10x Standard Peripherals Library: Footer

 

 

 

      For complete documentation on STM32(CORTEX M3) 32-bit Microcontrollers platform visit  www.st.com/STM32