/**
******************************************************************************
* @file stm8s_eval_i2c_ee.c
* @author MCD Application Team
* @version V1.1.0
* @date 05-February-2018
* @brief This file provides a set of functions needed to manage the I2C M24CXX
* EEPROM memory mounted on STM8Sxx-EVAL board (refer to stm8s_eval.h
* to know about the boards supporting this memory).
*
* ===================================================================
* Note: This driver is intended for STM8S families devices only.
* ===================================================================
*
* It implements a high level communication layer for read and write
* from/to this memory. The needed STM8S hardware resources (I2C and
* GPIO) are defined in stm8s_eval.h file, and the initialization is
* performed in sEE_LowLevel_Init() function declared in stm8s_eval.c
* file.
* You can easily tailor this driver to any other development board,
* by just adapting the defines for hardware resources and
* sEE_LowLevel_Init() function.
*
* @note In this driver, basic read and write functions (sEE_ReadBuffer()
* and sEE_WritePage()) use the I2C in polling mode to perform
* the data transfer to/from EEPROM memory
* Safe procedure is implemented to handle the read operation,
* ensuring safe data reception in case of 1, 2, 3 or more bytes
* The application should then monitor the variable holding
* the number of data in order to determine when the transfer is
* completed (variable decremented to 0).
* For more details on the use of this driver you can refer to
* the I2C_EEPROM example provided within the STM8SS_StdPeriph_Lib
* package.
*
* +-----------------------------------------------------------------+
* | Pin assignment |
* +---------------------------------------+-----------+-------------+
* | STM8S I2C Pins | sEE | Pin |
* +---------------------------------------+-----------+-------------+
* | . | E0(GND) | 1 (0V) |
* | . | E1(GND) | 2 (0V) |
* | . | E2(GND) | 3 (0V) |
* | . | E0(VSS) | 4 (0V) |
* | sEE_I2C_SDA_PIN/ SDA | SDA | 5 |
* | sEE_I2C_SCL_PIN/ SCL | SCL | 6 |
* | . | /WC(VDD)| 7 (3.3V) |
* | . | VDD | 8 (3.3V) |
* +---------------------------------------+-----------+-------------+
******************************************************************************
* @attention
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm8s_eval_i2c_ee.h"
/** @addtogroup Utilities
* @{
*/
/** @addtogroup STM8S_EVAL
* @{
*/
/** @addtogroup Common
* @{
*/
/** @addtogroup STM8S_EVAL_I2C_EE
* @brief This file includes the I2C EEPROM driver of STM8S-EVAL boards.
* @{
*/
/* Private types -------------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/** @defgroup STM8S_EVAL_I2C_EE_Private_Variables
* @{
*/
__IO uint16_t sEEAddress = 0;
__IO uint32_t sEETimeout = sEE_LONG_TIMEOUT;
__IO uint8_t* sEEDataWritePointer;
__IO uint8_t sEEDataNum;
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup STM8S_EVAL_I2C_EE_Private_Functions
* @{
*/
/**
* @brief DeInitializes peripherals used by the I2C EEPROM driver.
* @param None
* @retval None
*/
void sEE_DeInit(void)
{
sEE_LowLevel_DeInit();
}
/**
* @brief Initializes peripherals used by the I2C EEPROM driver.
* @param None
* @retval None
*/
void sEE_Init(void)
{
sEE_LowLevel_Init();
/* I2C configuration */
/* sEE_I2C Peripheral Enable */
I2C_Cmd( ENABLE);
/* sEE_I2C configuration after enabling it */
I2C_Init(I2C_SPEED, I2C_SLAVE_ADDRESS7, I2C_DUTYCYCLE_2, I2C_ACK_CURR,
I2C_ADDMODE_7BIT, 16);
#if defined (sEE_M24C64_32)
/* Select the EEPROM address according to the state of E0, E1, E2 pins */
sEEAddress = sEE_HW_ADDRESS;
#endif /* sEE_M24C64_32 */
}
/**
* @brief Reads a block of data from the EEPROM.
* @param pBuffer : pointer to the buffer that receives the data read from
* the EEPROM.
* @param ReadAddr : EEPROM's internal address to start reading from.
* @param NumByteToRead : pointer to the variable holding number of bytes to
* be read from the EEPROM.
*
* @note The variable pointed by NumByteToRead is reset to 0 when all the
* data are read from the EEPROM. Application should monitor this
* variable in order to know when the transfer is complete.
*
* @note This function ensures data reading from EEPROM, it assumes that I2C is
* used with polling or its interrupt priority is not the highest in the
* application.
* Method 2 transfer sequence is implemented in this function(refer to RM0016
* for more details). 3 bytes, 2bytes and 1 byte reception cases are handled.
*
* @retval sEE_OK (0) if operation is correctly performed, else return value
* different from sEE_OK (0) or the timeout user callback.
*/
uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{
/* While the bus is busy */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus( I2C_FLAG_BUSBUSY))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Send START condition */
I2C_GenerateSTART(ENABLE);
/* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Send EEPROM address for write */
I2C_Send7bitAddress( (uint8_t)sEEAddress, I2C_DIRECTION_TX);
/* Test on EV6 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent( I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
#ifdef sEE_M24C64_32
/* Send the EEPROM's internal address to read from: MSB of the address first */
I2C_SendData( (uint8_t)((ReadAddr & 0xFF00) >> 8));
/* Test on EV8 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((sE