⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_ee.c

📁 意法半导体ARM7 STR710+DM9000A的TCP/IP实现
💻 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 + -