STM8S/A Standard Peripherals Firmware Library
|
stm8s_eval_i2c_ee.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm8s_eval_i2c_ee.c 00004 * @author MCD Application Team 00005 * @version V1.0.1 00006 * @date 30-September-2014 00007 * @brief This file provides a set of functions needed to manage the I2C M24CXX 00008 * EEPROM memory mounted on STM8Sxx-EVAL board (refer to stm8s_eval.h 00009 * to know about the boards supporting this memory). 00010 * 00011 * =================================================================== 00012 * Note: This driver is intended for STM8S families devices only. 00013 * =================================================================== 00014 * 00015 * It implements a high level communication layer for read and write 00016 * from/to this memory. The needed STM8S hardware resources (I2C and 00017 * GPIO) are defined in stm8s_eval.h file, and the initialization is 00018 * performed in sEE_LowLevel_Init() function declared in stm8s_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 I2C in polling mode to perform 00026 * the data transfer to/from EEPROM memory 00027 * Safe procedure is implemented to handle the read operation, 00028 * ensuring safe data reception in case of 1, 2, 3 or more bytes 00029 * 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). 00032 * For more details on the use of this driver you can refer to 00033 * the I2C_EEPROM example provided within the STM8SS_StdPeriph_Lib 00034 * package. 00035 * 00036 * +-----------------------------------------------------------------+ 00037 * | Pin assignment | 00038 * +---------------------------------------+-----------+-------------+ 00039 * | STM8S I2C Pins | sEE | Pin | 00040 * +---------------------------------------+-----------+-------------+ 00041 * | . | E0(GND) | 1 (0V) | 00042 * | . | E1(GND) | 2 (0V) | 00043 * | . | E2(GND) | 3 (0V) | 00044 * | . | E0(VSS) | 4 (0V) | 00045 * | sEE_I2C_SDA_PIN/ SDA | SDA | 5 | 00046 * | sEE_I2C_SCL_PIN/ SCL | SCL | 6 | 00047 * | . | /WC(VDD)| 7 (3.3V) | 00048 * | . | VDD | 8 (3.3V) | 00049 * +---------------------------------------+-----------+-------------+ 00050 ****************************************************************************** 00051 * 00052 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00053 * You may not use this file except in compliance with the License. 00054 * You may obtain a copy of the License at: 00055 * 00056 * http://www.st.com/software_license_agreement_liberty_v2 00057 * 00058 * Unless required by applicable law or agreed to in writing, software 00059 * distributed under the License is distributed on an "AS IS" BASIS, 00060 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00061 * See the License for the specific language governing permissions and 00062 * limitations under the License. 00063 * 00064 ****************************************************************************** 00065 */ 00066 00067 /* Includes ------------------------------------------------------------------*/ 00068 #include "stm8s_eval_i2c_ee.h" 00069 00070 /** @addtogroup Utilities 00071 * @{ 00072 */ 00073 00074 /** @addtogroup STM8S_EVAL 00075 * @{ 00076 */ 00077 00078 /** @addtogroup Common 00079 * @{ 00080 */ 00081 00082 /** @addtogroup STM8S_EVAL_I2C_EE 00083 * @brief This file includes the I2C EEPROM driver of STM8S-EVAL boards. 00084 * @{ 00085 */ 00086 00087 /* Private types -------------------------------------------------------------*/ 00088 /* Private define ------------------------------------------------------------*/ 00089 /* Private macro -------------------------------------------------------------*/ 00090 00091 /** @defgroup STM8S_EVAL_I2C_EE_Private_Variables 00092 * @{ 00093 */ 00094 __IO uint16_t sEEAddress = 0; 00095 __IO uint32_t sEETimeout = sEE_LONG_TIMEOUT; 00096 __IO uint8_t* sEEDataWritePointer; 00097 __IO uint8_t sEEDataNum; 00098 /** 00099 * @} 00100 */ 00101 00102 /* Private function prototypes -----------------------------------------------*/ 00103 00104 00105 /** @defgroup STM8S_EVAL_I2C_EE_Private_Functions 00106 * @{ 00107 */ 00108 00109 /** 00110 * @brief DeInitializes peripherals used by the I2C EEPROM driver. 00111 * @param None 00112 * @retval None 00113 */ 00114 void sEE_DeInit(void) 00115 { 00116 sEE_LowLevel_DeInit(); 00117 } 00118 00119 /** 00120 * @brief Initializes peripherals used by the I2C EEPROM driver. 00121 * @param None 00122 * @retval None 00123 */ 00124 void sEE_Init(void) 00125 { 00126 sEE_LowLevel_Init(); 00127 00128 /* I2C configuration */ 00129 /* sEE_I2C Peripheral Enable */ 00130 I2C_Cmd( ENABLE); 00131 /* sEE_I2C configuration after enabling it */ 00132 I2C_Init(I2C_SPEED, I2C_SLAVE_ADDRESS7, I2C_DUTYCYCLE_2, I2C_ACK_CURR, 00133 I2C_ADDMODE_7BIT, 16); 00134 00135 #if defined (sEE_M24C64_32) 00136 /* Select the EEPROM address according to the state of E0, E1, E2 pins */ 00137 sEEAddress = sEE_HW_ADDRESS; 00138 #endif /* sEE_M24C64_32 */ 00139 } 00140 00141 /** 00142 * @brief Reads a block of data from the EEPROM. 00143 * @param pBuffer : pointer to the buffer that receives the data read from 00144 * the EEPROM. 00145 * @param ReadAddr : EEPROM's internal address to start reading from. 00146 * @param NumByteToRead : pointer to the variable holding number of bytes to 00147 * be read from the EEPROM. 00148 * 00149 * @note The variable pointed by NumByteToRead is reset to 0 when all the 00150 * data are read from the EEPROM. Application should monitor this 00151 * variable in order to know when the transfer is complete. 00152 * 00153 * @note This function ensures data reading from EEPROM, it assumes that I2C is 00154 * used with polling or its interrupt priority is not the highest in the 00155 * application. 00156 * Method 2 transfer sequence is implemented in this function(refer to RM0016 00157 * for more details). 3 bytes, 2bytes and 1 byte reception cases are handled. 00158 * 00159 * @retval sEE_OK (0) if operation is correctly performed, else return value 00160 * different from sEE_OK (0) or the timeout user callback. 00161 */ 00162 uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead) 00163 { 00164 00165 /* While the bus is busy */ 00166 sEETimeout = sEE_LONG_TIMEOUT; 00167 while(I2C_GetFlagStatus( I2C_FLAG_BUSBUSY)) 00168 { 00169 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00170 } 00171 00172 /* Send START condition */ 00173 I2C_GenerateSTART(ENABLE); 00174 00175 /* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ 00176 sEETimeout = sEE_FLAG_TIMEOUT; 00177 while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT)) 00178 { 00179 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00180 } 00181 00182 /* Send EEPROM address for write */ 00183 I2C_Send7bitAddress( (uint8_t)sEEAddress, I2C_DIRECTION_TX); 00184 00185 /* Test on EV6 and clear it */ 00186 sEETimeout = sEE_FLAG_TIMEOUT; 00187 while(!I2C_CheckEvent( I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 00188 { 00189 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00190 } 00191 00192 #ifdef sEE_M24C64_32 00193 00194 /* Send the EEPROM's internal address to read from: MSB of the address first */ 00195 I2C_SendData( (uint8_t)((ReadAddr & 0xFF00) >> 8)); 00196 00197 /* Test on EV8 and clear it */ 00198 sEETimeout = sEE_FLAG_TIMEOUT; 00199 while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED)) 00200 { 00201 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00202 } 00203 00204 /* Send the EEPROM's internal address to read from: LSB of the address */ 00205 I2C_SendData( (uint8_t)(ReadAddr & 0x00FF)); 00206 00207 #endif /* sEE_M24C64_32 */ 00208 00209 /* Test on EV8 and clear it */ 00210 sEETimeout = sEE_FLAG_TIMEOUT; 00211 while(I2C_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED) == RESET) 00212 { 00213 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00214 } 00215 00216 /* Send START condition a second time */ 00217 I2C_GenerateSTART( ENABLE); 00218 00219 /* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ 00220 sEETimeout = sEE_FLAG_TIMEOUT; 00221 while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT)) 00222 { 00223 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00224 } 00225 00226 /* Send EEPROM address for read */ 00227 I2C_Send7bitAddress((uint8_t)sEEAddress, I2C_DIRECTION_RX); 00228 00229 /* Read data from first byte until byte N-3 */ 00230 if ((uint16_t)(*NumByteToRead)> 3) 00231 { 00232 /* Poll on BTF */ 00233 sEETimeout = sEE_FLAG_TIMEOUT; 00234 while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET) 00235 { 00236 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00237 } 00238 00239 /* Read a byte from the EEPROM */ 00240 *pBuffer = I2C_ReceiveData(); 00241 00242 /* Point to the next location where the byte read will be saved */ 00243 *pBuffer++; 00244 00245 /* Decrement the read bytes counter */ 00246 (uint16_t)(*NumByteToRead)--; 00247 } 00248 00249 /* Remains three data for read: data N-2, data N-1, Data N */ 00250 /* Three Bytes Master Reception procedure (POLLING) ------------------------*/ 00251 if ((uint16_t)(*NumByteToRead) == 3) 00252 { 00253 /* Data N-2 in DR and data N -1 in shift register */ 00254 /* Poll on BTF */ 00255 sEETimeout = sEE_FLAG_TIMEOUT; 00256 while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET) 00257 { 00258 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00259 } 00260 00261 /* Clear ACK */ 00262 I2C_AcknowledgeConfig(I2C_ACK_NONE); 00263 00264 /* Call User callback for critical section start (should typically disable interrupts) */ 00265 sEE_EnterCriticalSection_UserCallback(); 00266 00267 /* Read Data N-2 */ 00268 *pBuffer = I2C_ReceiveData(); 00269 00270 /* Point to the next location where the byte read will be saved */ 00271 *pBuffer++; 00272 00273 /* Program the STOP */ 00274 I2C_GenerateSTOP(ENABLE); 00275 00276 /* Read DataN-1 */ 00277 *pBuffer = I2C_ReceiveData(); 00278 00279 /* Call User callback for critical section end (should typically re-enable interrupts) */ 00280 sEE_ExitCriticalSection_UserCallback(); 00281 00282 /* Point to the next location where the byte read will be saved */ 00283 *pBuffer++; 00284 00285 /* Poll on RxNE */ 00286 sEETimeout = sEE_FLAG_TIMEOUT; 00287 while (I2C_GetFlagStatus( I2C_FLAG_RXNOTEMPTY) == RESET) 00288 { 00289 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00290 } 00291 /* Read DataN */ 00292 *pBuffer = I2C_ReceiveData(); 00293 00294 /* Reset the number of bytes to be read from the EEPROM */ 00295 NumByteToRead = 0; 00296 00297 } 00298 00299 /* If number of data to be read is 2 */ 00300 /* Tow Bytes Master Reception procedure (POLLING) ---------------------------*/ 00301 if ((uint16_t)(*NumByteToRead) == 2) 00302 { 00303 /* Enable acknowledgement on next byte (set POS and ACK bits)*/ 00304 I2C_AcknowledgeConfig(I2C_ACK_NEXT); 00305 00306 /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ 00307 sEETimeout = sEE_FLAG_TIMEOUT; 00308 while(I2C_GetFlagStatus( I2C_FLAG_ADDRESSSENTMATCHED) == RESET) 00309 { 00310 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00311 } 00312 00313 /* Clear ADDR register by reading SR1 then SR3 register (SR1 has already been read) */ 00314 (void)I2C->SR3; 00315 00316 /* Disable Acknowledgement */ 00317 I2C_AcknowledgeConfig(I2C_ACK_NONE); 00318 00319 /* Wait for BTF flag to be set */ 00320 sEETimeout = sEE_FLAG_TIMEOUT; 00321 while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET) 00322 { 00323 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00324 } 00325 00326 /* Call User callback for critical section start (should typically disable interrupts) */ 00327 sEE_EnterCriticalSection_UserCallback(); 00328 00329 /* Program the STOP */ 00330 I2C_GenerateSTOP(ENABLE); 00331 00332 /* Read Data N-1 */ 00333 *pBuffer = I2C_ReceiveData(); 00334 00335 /* Point to the next location where the byte read will be saved */ 00336 *pBuffer++; 00337 00338 /* Call User callback for critical section end (should typically re-enable interrupts) */ 00339 sEE_ExitCriticalSection_UserCallback(); 00340 00341 /* Read Data N */ 00342 *pBuffer = I2C_ReceiveData(); 00343 00344 /* Reset the number of bytes to be read from the EEPROM */ 00345 NumByteToRead = 0; 00346 } 00347 00348 /* If number of data to be read is 1 */ 00349 /* One Byte Master Reception procedure (POLLING) ---------------------------*/ 00350 if ((uint16_t)(*NumByteToRead) < 2) 00351 { 00352 /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ 00353 sEETimeout = sEE_FLAG_TIMEOUT; 00354 while(I2C_GetFlagStatus( I2C_FLAG_ADDRESSSENTMATCHED) == RESET) 00355 { 00356 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00357 } 00358 00359 /* Disable Acknowledgement */ 00360 I2C_AcknowledgeConfig(I2C_ACK_NONE); 00361 00362 /* Call User callback for critical section start (should typically disable interrupts) */ 00363 sEE_EnterCriticalSection_UserCallback(); 00364 00365 /* Clear ADDR register by reading SR1 then SR3 register (SR1 has already been read) */ 00366 (void)sEE_I2C->SR3; 00367 00368 /* Send STOP Condition */ 00369 I2C_GenerateSTOP( ENABLE); 00370 00371 /* Call User callback for critical section end (should typically re-enable interrupts) */ 00372 sEE_ExitCriticalSection_UserCallback(); 00373 00374 /* Wait for the byte to be received */ 00375 sEETimeout = sEE_FLAG_TIMEOUT; 00376 while(I2C_GetFlagStatus( I2C_FLAG_RXNOTEMPTY) == RESET) 00377 { 00378 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00379 } 00380 00381 /* Read the byte received from the EEPROM */ 00382 *pBuffer = I2C_ReceiveData(); 00383 00384 /* Decrement the read bytes counter */ 00385 (uint16_t)(*NumByteToRead)--; 00386 00387 /* Wait to make sure that STOP control bit has been cleared */ 00388 sEETimeout = sEE_FLAG_TIMEOUT; 00389 while(sEE_I2C->CR2 & I2C_CR2_STOP) 00390 { 00391 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00392 } 00393 00394 /* Re-Enable Acknowledgement to be ready for another reception */ 00395 I2C_AcknowledgeConfig( I2C_ACK_CURR); 00396 } 00397 /* If all operations OK, return sEE_OK (0) */ 00398 return sEE_OK; 00399 } 00400 00401 /** 00402 * @brief Writes buffer of data to the I2C EEPROM. 00403 * @param pBuffer : pointer to the buffer containing the data to be written 00404 * to the EEPROM. 00405 * @param WriteAddr : EEPROM's internal address to write to. 00406 * @param NumByteToWrite : number of bytes to write to the EEPROM. 00407 * @retval None 00408 */ 00409 void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite) 00410 { 00411 uint8_t NumOfPage = 0, NumOfSingle = 0, count = 0; 00412 uint16_t Addr = 0; 00413 00414 Addr = WriteAddr % sEE_PAGESIZE; 00415 count = (uint8_t)(sEE_PAGESIZE - (uint16_t)Addr); 00416 NumOfPage = (uint8_t)(NumByteToWrite / sEE_PAGESIZE); 00417 NumOfSingle = (uint8_t)(NumByteToWrite % sEE_PAGESIZE); 00418 00419 /* If WriteAddr is sEE_PAGESIZE aligned */ 00420 if (Addr == 0) 00421 { 00422 /* If NumByteToWrite < sEE_PAGESIZE */ 00423 if (NumOfPage == 0) 00424 { 00425 /* Store the number of data to be written */ 00426 sEEDataNum = NumOfSingle; 00427 /* Start writing data */ 00428 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00429 /* Wait data transfer to be complete */ 00430 sEETimeout = sEE_LONG_TIMEOUT; 00431 while (sEEDataNum > 0) 00432 { 00433 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00434 } 00435 sEE_WaitEepromStandbyState(); 00436 } 00437 /* If NumByteToWrite > sEE_PAGESIZE */ 00438 else 00439 { 00440 while (NumOfPage--) 00441 { 00442 /* Store the number of data to be written */ 00443 sEEDataNum = sEE_PAGESIZE; 00444 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00445 /* Wait data transfer to be complete */ 00446 sEETimeout = sEE_LONG_TIMEOUT; 00447 while (sEEDataNum > 0) 00448 { 00449 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00450 } 00451 sEE_WaitEepromStandbyState(); 00452 WriteAddr += sEE_PAGESIZE; 00453 pBuffer += sEE_PAGESIZE; 00454 } 00455 00456 if (NumOfSingle != 0) 00457 { 00458 /* Store the number of data to be written */ 00459 sEEDataNum = NumOfSingle; 00460 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00461 /* Wait data transfer to be complete */ 00462 sEETimeout = sEE_LONG_TIMEOUT; 00463 while (sEEDataNum > 0) 00464 { 00465 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00466 } 00467 sEE_WaitEepromStandbyState(); 00468 } 00469 } 00470 } 00471 /* If WriteAddr is not sEE_PAGESIZE aligned */ 00472 else 00473 { 00474 /* If NumByteToWrite < sEE_PAGESIZE */ 00475 if (NumOfPage == 0) 00476 { 00477 /* If the number of data to be written is more than the remaining space 00478 in the current page: */ 00479 if (NumByteToWrite > count) 00480 { 00481 /* Store the number of data to be written */ 00482 sEEDataNum = count; 00483 /* Write the data contained in the same page */ 00484 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00485 /* Wait data transfer to be complete */ 00486 sEETimeout = sEE_LONG_TIMEOUT; 00487 while (sEEDataNum > 0) 00488 { 00489 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00490 } 00491 sEE_WaitEepromStandbyState(); 00492 00493 /* Store the number of data to be written */ 00494 sEEDataNum = (uint8_t)(NumByteToWrite - count); 00495 /* Write the remaining data in the following page */ 00496 sEE_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&sEEDataNum)); 00497 /* Wait data transfer to be complete */ 00498 sEETimeout = sEE_LONG_TIMEOUT; 00499 while (sEEDataNum > 0) 00500 { 00501 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00502 } 00503 sEE_WaitEepromStandbyState(); 00504 } 00505 else 00506 { 00507 /* Store the number of data to be written */ 00508 sEEDataNum = NumOfSingle; 00509 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00510 /* Wait data transfer to be complete */ 00511 sEETimeout = sEE_LONG_TIMEOUT; 00512 while (sEEDataNum > 0) 00513 { 00514 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00515 } 00516 sEE_WaitEepromStandbyState(); 00517 } 00518 } 00519 /* If NumByteToWrite > sEE_PAGESIZE */ 00520 else 00521 { 00522 NumByteToWrite -= count; 00523 NumOfPage = (uint8_t)(NumByteToWrite / sEE_PAGESIZE); 00524 NumOfSingle = (uint8_t)(NumByteToWrite % sEE_PAGESIZE); 00525 00526 if (count != 0) 00527 { 00528 /* Store the number of data to be written */ 00529 sEEDataNum = count; 00530 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00531 /* Wait data transfer to be complete */ 00532 sEETimeout = sEE_LONG_TIMEOUT; 00533 while (sEEDataNum > 0) 00534 { 00535 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00536 } 00537 sEE_WaitEepromStandbyState(); 00538 WriteAddr += count; 00539 pBuffer += count; 00540 } 00541 00542 while (NumOfPage--) 00543 { 00544 /* Store the number of data to be written */ 00545 sEEDataNum = sEE_PAGESIZE; 00546 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00547 /* Wait data transfer to be complete */ 00548 sEETimeout = sEE_LONG_TIMEOUT; 00549 while (sEEDataNum > 0) 00550 { 00551 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00552 } 00553 sEE_WaitEepromStandbyState(); 00554 WriteAddr += sEE_PAGESIZE; 00555 pBuffer += sEE_PAGESIZE; 00556 } 00557 if (NumOfSingle != 0) 00558 { 00559 /* Store the number of data to be written */ 00560 sEEDataNum = NumOfSingle; 00561 sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); 00562 /* Wait data transfer to be complete */ 00563 sEETimeout = sEE_LONG_TIMEOUT; 00564 while (sEEDataNum > 0) 00565 { 00566 if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;}; 00567 } 00568 sEE_WaitEepromStandbyState(); 00569 } 00570 } 00571 } 00572 } 00573 00574 /** 00575 * @brief Writes more than one byte to the EEPROM. 00576 * 00577 * @note The number of bytes (combined to write start address) must not 00578 * cross the EEPROM page boundary. This function can only write into 00579 * the boundaries of an EEPROM page. 00580 * This function doesn't check on boundaries condition (in this driver 00581 * the function sEE_WriteBuffer() which calls sEE_WritePage() is 00582 * responsible of checking on Page boundaries). 00583 * 00584 * @param pBuffer : pointer to the buffer containing the data to be written to 00585 * the EEPROM. 00586 * @param WriteAddr : EEPROM's internal address to write to. 00587 * @param NumByteToWrite : pointer to the variable holding number of bytes to 00588 * be written into the EEPROM. 00589 * 00590 * @note The variable pointed by NumByteToWrite is reset to 0 when all the 00591 * data are written to the EEPROM. Application should monitor this 00592 * variable in order know when the transfer is complete. 00593 * 00594 * @retval sEE_OK (0) if operation is correctly performed, else return value 00595 * different from sEE_OK (0) or the timeout user callback. 00596 */ 00597 uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite) 00598 { 00599 /* Set the pointer to the Number of data to be written. 00600 User should check on this variable in order to know if the 00601 data transfer has been completed or not. */ 00602 sEEDataWritePointer = NumByteToWrite; 00603 00604 /* While the bus is busy */ 00605 sEETimeout = sEE_LONG_TIMEOUT; 00606 while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)) 00607 { 00608 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00609 } 00610 00611 /* Send START condition */ 00612 I2C_GenerateSTART( ENABLE); 00613 00614 /* Test on EV5 and clear it */ 00615 sEETimeout = sEE_FLAG_TIMEOUT; 00616 while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT)) 00617 { 00618 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00619 } 00620 00621 /* Send EEPROM address for write */ 00622 sEETimeout = sEE_FLAG_TIMEOUT; 00623 I2C_Send7bitAddress((uint8_t)sEEAddress, I2C_DIRECTION_TX); 00624 00625 /* Test on EV6 and clear it */ 00626 sEETimeout = sEE_FLAG_TIMEOUT; 00627 while(!I2C_CheckEvent( I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 00628 { 00629 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00630 } 00631 00632 #ifdef sEE_M24C08 00633 00634 /* Send the EEPROM's internal address to write to : only one byte Address */ 00635 I2C_SendData( WriteAddr); 00636 00637 #elif defined(sEE_M24C64_32) 00638 00639 /* Send the EEPROM's internal address to write to : MSB of the address first */ 00640 I2C_SendData( (uint8_t)((WriteAddr & 0xFF00) >> 8)); 00641 00642 /* Test on EV8 and clear it */ 00643 sEETimeout = sEE_FLAG_TIMEOUT; 00644 while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED)) 00645 { 00646 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00647 } 00648 00649 /* Send the EEPROM's internal address to write to : LSB of the address */ 00650 I2C_SendData( (uint8_t)(WriteAddr & 0x00FF)); 00651 00652 #endif /* sEE_M24C08 */ 00653 00654 /* Test on EV8 and clear it */ 00655 sEETimeout = sEE_FLAG_TIMEOUT; 00656 while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED)) 00657 { 00658 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00659 } 00660 00661 /* While there is data to be written */ 00662 while((uint16_t)(*sEEDataWritePointer) > 0) 00663 { 00664 /* Send the byte to be written */ 00665 I2C_SendData( *pBuffer); 00666 00667 /* Test on EV8 and clear it */ 00668 /* Wait till all data have been physically transferred on the bus */ 00669 sEETimeout = sEE_LONG_TIMEOUT; 00670 while(!I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED)) 00671 { 00672 if((sEETimeout--) == 0) sEE_TIMEOUT_UserCallback(); 00673 } 00674 (uint16_t)(*sEEDataWritePointer)--; 00675 } 00676 00677 /* Send STOP condition */ 00678 I2C_GenerateSTOP(ENABLE); 00679 00680 /* Perform a read on SR1 and SR3 register to clear eventually pending flags */ 00681 (void)sEE_I2C->SR1; 00682 (void)sEE_I2C->SR3; 00683 00684 /* If all operations OK, return sEE_OK (0) */ 00685 return sEE_OK; 00686 } 00687 00688 /** 00689 * @brief Wait for EEPROM Standby state. 00690 * 00691 * @note This function allows to wait and check that EEPROM has finished the 00692 * last Write operation. It is mostly used after a Write operation: after 00693 * receiving the buffer to be written, the EEPROM may need additional 00694 * time to actually perform the write operation. During this time, it 00695 * doesn't answer to I2C packets addressed to it. Once the write operation 00696 * is complete the EEPROM responds to its address. 00697 * 00698 * @note It is not necessary to call this function after sEE_WriteBuffer() 00699 * function (sEE_WriteBuffer() already calls this function after each 00700 * write page operation). 00701 * 00702 * @param None 00703 * @retval sEE_OK (0) if operation is correctly performed, else return value 00704 * different from sEE_OK (0) or the timeout user callback. 00705 */ 00706 uint32_t sEE_WaitEepromStandbyState(void) 00707 { 00708 __IO uint8_t tmpSR1 = 0; 00709 __IO uint32_t sEETrials = 0; 00710 00711 /* While the bus is busy */ 00712 sEETimeout = sEE_LONG_TIMEOUT; 00713 while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)) 00714 { 00715 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00716 } 00717 00718 /* Keep looping till the slave acknowledges his address or the maximum number 00719 of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define 00720 in stm8s_eval_i2c_ee.h file) */ 00721 while (1) 00722 { 00723 /* Send START condition */ 00724 I2C_GenerateSTART(ENABLE); 00725 00726 /* Test on EV5 and clear it */ 00727 sEETimeout = sEE_FLAG_TIMEOUT; 00728 while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT)) 00729 { 00730 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00731 } 00732 00733 /* Send EEPROM address for write */ 00734 I2C_Send7bitAddress((uint8_t)sEEAddress, I2C_DIRECTION_TX); 00735 00736 /* Wait for ADDR flag to be set (Slave acknowledged his address) */ 00737 sEETimeout = sEE_LONG_TIMEOUT; 00738 do 00739 { 00740 /* Get the current value of the SR1 register */ 00741 tmpSR1 = sEE_I2C->SR1; 00742 00743 /* Update the timeout value and exit if it reach 0 */ 00744 if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); 00745 } 00746 /* Keep looping till the Address is acknowledged or the AF flag is 00747 set (address not acknowledged at time) */ 00748 while((I2C_GetFlagStatus(I2C_FLAG_ADDRESSSENTMATCHED)== RESET) & 00749 (I2C_GetFlagStatus(I2C_FLAG_ACKNOWLEDGEFAILURE)== RESET)); 00750 tmpSR1 = sEE_I2C->SR1; 00751 /* Check if the ADDR flag has been set */ 00752 if (tmpSR1 & I2C_SR1_ADDR) 00753 { 00754 /* Clear ADDR Flag by reading SR1 then SR3 registers (SR1 have already 00755 been read) */ 00756 (void)sEE_I2C->SR3; 00757 00758 /* STOP condition */ 00759 I2C_GenerateSTOP(ENABLE); 00760 00761 /* Exit the function */ 00762 return sEE_OK; 00763 } 00764 else 00765 { 00766 /* Clear AF flag */ 00767 I2C_ClearFlag(I2C_FLAG_ACKNOWLEDGEFAILURE); 00768 } 00769 00770 /* Check if the maximum allowed number of trials has bee reached */ 00771 if (sEETrials++ == sEE_MAX_TRIALS_NUMBER) 00772 { 00773 /* If the maximum number of trials has been reached, exit the function */ 00774 return sEE_TIMEOUT_UserCallback(); 00775 } 00776 } 00777 } 00778 00779 #ifdef USE_DEFAULT_TIMEOUT_CALLBACK 00780 /** 00781 * @brief Basic management of the timeout situation. 00782 * @param None. 00783 * @retval None. 00784 */ 00785 uint32_t sEE_TIMEOUT_UserCallback(void) 00786 { 00787 /* Block communication and all processes */ 00788 while(1) 00789 { 00790 } 00791 } 00792 #endif /* USE_DEFAULT_TIMEOUT_CALLBACK */ 00793 00794 #ifdef USE_DEFAULT_CRITICAL_CALLBACK 00795 /** 00796 * @brief Start critical section: this callbacks should be typically used 00797 * to disable interrupts when entering a critical section of I2C communication 00798 * You may use default callbacks provided into this driver by uncommenting the 00799 * define USE_DEFAULT_CRITICAL_CALLBACK. 00800 * Or you can comment that line and implement these callbacks into your 00801 * application. 00802 * @param None. 00803 * @retval None. 00804 */ 00805 void sEE_EnterCriticalSection_UserCallback(void) 00806 { 00807 disableInterrupts(); 00808 } 00809 00810 /** 00811 * @brief End of critical section: this callbacks should be typically used 00812 * to re-enable interrupts when exiting a critical section of I2C communication 00813 * You may use default callbacks provided into this driver by uncommenting the 00814 * define USE_DEFAULT_CRITICAL_CALLBACK. 00815 * Or you can comment that line and implement these callbacks into your 00816 * application. 00817 * @param None. 00818 * @retval None. 00819 */ 00820 void sEE_ExitCriticalSection_UserCallback(void) 00821 { 00822 enableInterrupts(); 00823 } 00824 #endif /* USE_DEFAULT_CRITICAL_CALLBACK */ 00825 00826 00827 00828 /** 00829 * @} 00830 */ 00831 00832 /** 00833 * @} 00834 */ 00835 00836 /** 00837 * @} 00838 */ 00839 00840 /** 00841 * @} 00842 */ 00843 00844 /** 00845 * @} 00846 */ 00847 00848 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/