📄 i2c_ee.c
字号:
/******************** (C) COPYRIGHT 2007 STMicroelectronics ********************
* File Name : i2c_ee.c
* Author : MCD Application Team
* Version : V4.0
* Date First Issued : 10/09/2007
* Description : This file provides a set of functions needed to manage the
* communication between I2C peripheral and I2C M24C08 EEPROM.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "i2c_ee.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define I2C0_SCL 0x2000
#define I2C0_SDA 0x4000
#define I2C1_SCL 0x8
#define I2C1_SDA 0x4
#define I2C_Speed 400000
#define I2C_PageSize 16
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u16 EEPROM_ADDRESS=0xA0;
vu16 SR2_Tmp = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : I2C_EEPROM_Config
* Description : Configure the I2Cx interface.
* Input : - I2Cx: I2C peripheral to be configured. It can be:
I2C0 or I2C1
* Output : None.
* Return : None.
*******************************************************************************/
void I2C_EEPROM_Config(I2C_TypeDef *I2Cx)
{
if(I2Cx == I2C1)
{
/* Configure the SDA and the SCL lines to alternate functions Open Drain */
GPIO_Config (GPIO0, I2C1_SCL | I2C1_SDA, GPIO_AF_OD);
}
else
{
/* Configure the SDA and the SCL lines to alternate functions Open Drain */
GPIO_Config (GPIO1, I2C0_SCL | I2C0_SDA, GPIO_AF_OD);
}
/* Initialize the I2Cx peripheral */
I2C_Init (I2Cx);
/* Configure frequency bits */
I2C_FCLKConfig (I2Cx);
/* Enable I2Cx peripheral */
I2C_FlagClear( I2Cx, I2C_ENDAD );
/* Configure I2Cx clock speed */
I2C_SpeedConfig (I2Cx, I2C_Speed);
/* Enable Acknowledge */
I2C_AcknowledgeConfig (I2Cx, ENABLE);
/* depending on the EEPROM Address selected in the i2c_ee.h file */
#ifdef EEPROM_Block0_ADDRESS
/* Select the EEPROM Block0 to write on */
EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;
#endif
#ifdef EEPROM_Block1_ADDRESS
/* Select the EEPROM Block1 to write on */
EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;
#endif
#ifdef EEPROM_Block2_ADDRESS
/* Select the EEPROM Block2 to write on */
EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;
#endif
#ifdef EEPROM_Block3_ADDRESS
/* Select the EEPROM Block3 to write on */
EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;
#endif
}
/*******************************************************************************
* Function Name : EEPROM_WaitForLastTask
* Description : Wait for M24C08 EEPROM to terminate the last task.
Input : - I2Cx: I2C peripheral to be configured. It can be:
I2C0 or I2C1
* Output : None.
* Return : None.
*******************************************************************************/
void EEPROM_WaitForLastTask(I2C_TypeDef *I2Cx)
{
do {
/* Send START condition */
I2C_STARTGenerate( I2Cx, ENABLE );
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));
/* Send EEPROM address for write */
I2C_AddressSend( I2Cx, EEPROM_ADDRESS, I2C_Mode7, I2C_TX );
/* Wait the set of EVF flag */
while(!(I2C_RegisterRead(I2Cx,I2C_SR1) & I2C_EVF));
/* Store the AF flag status */
SR2_Tmp=(I2C_RegisterRead(I2Cx,I2C_SR2)<<8);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECTED));
/* Clear ENDAD bit */
I2C_FlagClear( I2Cx, I2C_ENDAD );
} while(SR2_Tmp & I2C_AF);
}
/*******************************************************************************
* Function Name : EEPROM_Receive
* Description : Read a buffer from the M24C08 EEPROM.
* Input : - I2Cx: the selected I2C peripheral. It can be:
* I2C0 or I2C1
* - PtrToBuffer: a pointer to a buffer where read data are put.
* - InternalAddress: EEPROM internal address from which data
* will be read.
* - NbOfBytes: the buffer size.
* Output : None.
* Return : None.
*******************************************************************************/
void EEPROM_Receive(I2C_TypeDef *I2Cx, char *PtrToBuffer,
u8 InternalAddress, u8 NbOfBytes)
{
/* Generate the START condition */
I2C_STARTGenerate (I2Cx, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));
/* In the case of a single data transfer disable ACK before reading the data */
if(NbOfBytes==1)
{
I2C_AcknowledgeConfig(I2Cx,DISABLE);
}
/* Send the EEPROM address with LSB bit reset */
I2C_AddressSend (I2Cx,EEPROM_ADDRESS,I2C_Mode7, I2C_TX);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECTED));
/* Clear ENDAD bit */
I2C_FlagClear( I2Cx, I2C_ENDAD );
/* Send the EEPROM's internal address to read from */
I2C_ByteSend (I2Cx, InternalAddress);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Generate the RE-START condition */
I2C_STARTGenerate (I2Cx, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* Send the EEPROM address with LSB bit set */
I2C_AddressSend (I2Cx, EEPROM_ADDRESS, I2C_Mode7, I2C_RX);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECTED));
/* Clear ENDAD bit */
I2C_FlagClear( I2Cx, I2C_ENDAD );
/* Read 'NbOfBytes' bytes from the EEPROM starting from address
'InternalAddress' of Block3 and place them in PtrToBuffer[] array */
while(NbOfBytes)
{
/* Wait until the byte is received */
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));
if(NbOfBytes == 2)
{ /* Disable the ACK generation */
I2C_AcknowledgeConfig (I2Cx, DISABLE);
}
if (NbOfBytes == 1)
{
/* Generate STOP condition to close the communication after the
next byte reception */
I2C_STOPGenerate (I2Cx, ENABLE);
}
*PtrToBuffer=I2C_ByteReceive (I2Cx);
PtrToBuffer++;
NbOfBytes--;
}
/* Enable the ACK generation */
I2C_AcknowledgeConfig (I2Cx, ENABLE);
}
/*******************************************************************************
* Function Name : EEPROM_Send_Byte
* Description : Writes one byte to the I2C EEPROM.
* Input : - I2Cx: the selected I2C peripheral. It can be:
* I2C0 or I2C1
* - pBuffer: a pointer to the buffer containing the data to be
* written to the EEPROM.
* - WriteAddr: EEPROM's internal address to write to.
* Output : None.
* Return : None.
*******************************************************************************/
void EEPROM_Send_Byte(I2C_TypeDef *I2Cx, u8* pBuffer, u8 WriteAddr)
{
/* Generate the START condition */
I2C_STARTGenerate (I2Cx, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));
/* Send the EEPROM's address with LSB bit reset */
I2C_AddressSend (I2Cx, EEPROM_ADDRESS, I2C_Mode7, I2C_TX);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECTED));
/* Clear ENDAD bit */
I2C_FlagClear(I2Cx, I2C_ENDAD );
/* Send the EEPROM's internal address to write to */
I2C_ByteSend (I2Cx, WriteAddr);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send the byte to be written */
I2C_ByteSend (I2Cx, *pBuffer);
/* Test on EV8 and clear it */
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Generate the stop condition */
I2C_STOPGenerate (I2Cx, ENABLE);
}
/*******************************************************************************
* Function Name : EEPROM_Send
* Description : Send data to the M24C08 EEPROM.
* Input : - I2Cx: the selected I2C peripheral. It can be:
* I2C0 or I2C1
* - PtrToBuffer: a pointer to the buffer containing data to be
* written in the EEPROM.
* - NbOfBytes: the buffer size.
* - InternalAddress: EEPROM internal address in which data
* will be written.
* Output : None.
* Return : None.
*******************************************************************************/
void EEPROM_Send(I2C_TypeDef *I2Cx, char *PtrToBuffer, u8 NbOfBytes,
u8 InternalAddress)
{
u8 SentBytes = 0;
/* Generate the START condition */
I2C_STARTGenerate (I2Cx, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));
/* Send the EEPROM's address with LSB bit reset */
I2C_AddressSend (I2Cx, EEPROM_ADDRESS, I2C_Mode7, I2C_TX);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECTED));
/* Clear ENDAD bit */
I2C_FlagClear( I2Cx, I2C_ENDAD );
/* Send the EEPROM's internal address to write to */
I2C_ByteSend (I2Cx,InternalAddress);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Write 'PtrToBuffer' buffer contents in the EEPROM starting from address
'InternalAddress' of Block3 */
while (SentBytes < NbOfBytes)
{
I2C_ByteSend (I2Cx, *(PtrToBuffer+SentBytes));
/* Test on EV8 and clear it */
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
SentBytes++;
}
/* Generate the stop condition */
I2C_STOPGenerate (I2Cx, ENABLE);
}
/*******************************************************************************
* Function Name : EEPROM_BufferWrite
* Description : Writes buffer of data to the I2C EEPROM.
* Input : - I2Cx: the selected I2C peripheral. It can be:
* I2C0 or I2C1
* - pBuffer: a pointer to the buffer containing the data to be
* written to the EEPROM.
* - WriteAddr : EEPROM's internal address to write to.
* - NumByteToWrite : number of bytes to write to the EEPROM.
* Output : None.
* Return : None.
*******************************************************************************/
void EEPROM_BufferWrite(I2C_TypeDef *I2Cx, char* pBuffer, u8 WriteAddr,
u16 NumByteToWrite)
{
u8 NumOfPage, NumOfSingle, Addr, count;
Addr = WriteAddr % I2C_PageSize;
count = I2C_PageSize - Addr;
NumOfPage = NumByteToWrite / I2C_PageSize;
NumOfSingle = NumByteToWrite % I2C_PageSize;
/* If WriteAddr is I2C_PageSize aligned */
if(Addr == 0)
{
/* If NumByteToWrite < I2C_PageSize */
if(NumOfPage == 0)
{
EEPROM_Send(I2Cx, pBuffer,NumOfSingle, WriteAddr);
EEPROM_WaitForLastTask(I2Cx);
}
/* If NumByteToWrite > I2C_PageSize */
else
{
while(NumOfPage--)
{
EEPROM_Send(I2Cx, pBuffer,I2C_PageSize, WriteAddr);
EEPROM_WaitForLastTask(I2Cx);
WriteAddr += I2C_PageSize;
pBuffer += I2C_PageSize;
}
if(NumOfSingle!=0)
{
EEPROM_Send(I2Cx, pBuffer,NumOfSingle, WriteAddr);
EEPROM_WaitForLastTask(I2Cx);
}
}
}
/* If WriteAddr is not I2C_PageSize aligned */
else
{
/* If NumByteToWrite < I2C_PageSize */
if(NumOfPage== 0)
{
EEPROM_Send(I2Cx, pBuffer,NumOfSingle, WriteAddr);
EEPROM_WaitForLastTask(I2Cx);
}
/* If NumByteToWrite > I2C_PageSize */
else
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / I2C_PageSize;
NumOfSingle = NumByteToWrite % I2C_PageSize;
if(count != 0)
{
EEPROM_Send(I2Cx, pBuffer,count, WriteAddr);
EEPROM_WaitForLastTask(I2Cx);
WriteAddr += count;
pBuffer += count;
}
while(NumOfPage--)
{
EEPROM_Send(I2Cx, pBuffer,I2C_PageSize, WriteAddr);
EEPROM_WaitForLastTask(I2Cx);
WriteAddr += I2C_PageSize;
pBuffer += I2C_PageSize;
}
if(NumOfSingle != 0)
{
EEPROM_Send(I2Cx, pBuffer,NumOfSingle, WriteAddr);
EEPROM_WaitForLastTask(I2Cx);
}
}
}
}
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -