📄 at24c.c
字号:
/*-----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support - ROUSSET -
*------------------------------------------------------------------------------
* The software is delivered "AS IS" without warranty or condition of any
* kind, either express, implied or statutory. This includes without
* limitation any warranty or condition with respect to merchantability or
* fitness for any particular purpose, or against the infringements of
* intellectual property rights of others.
*------------------------------------------------------------------------------
* File Name : at24c.c
* Object : ATMEL AT24C Two-wire Serial EEPROM low level functions
*
* Version | mm | dd | yy | author :
* 1.0 12 14 06 PFi : Creation
* 1.1 12 04 07 PFi : Update of Multiple read/write function
* according to the new TWI doc.
* 1.11 14 08 07 PFi : Cleanup.
* : AT91F_AT24C_MemoryReset Corrected to match
* : reset sequence from ATMEL AT24C datasheet
*------------------------------------------------------------------------------
* 1)Description:
*
* A set of standalone read or write functions are provided.
*
* AT91F_AT24C_WriteByte
* AT91F_AT24C_WritePage
* AT91F_AT24C_ReadByte
* AT91F_AT24C_ReadPage
* AT91F_AT24C_SequentialRead
*
* TO DO: Add NACK management, due to AT91SAM7S TWI errata, for functions
* which are not using the TWI Lib functions.
*----------------------------------------------------------------------------*/
/*---------------------------- Include files --------------------------------*/
#include "at24c.h"
#include "board.h"
#include "..\common\init.h"
#include "..\common\lib_twi.h"
/*--------------------------- Constants definition -------------------------*/
/* value of the PIT value to have 333ns @ 48 MHz
668 -1 since real time out = PIV + 1 */
#define PIT_PIV_MILI_SECOND_VALUE 0x667
/* value of the PIT value to have 333ns @ 48 MHz
3 -1 since real time out = PIV + 1 */
#define PIT_PIV_MICRO_SECOND_VALUE 0x2
/*----------------------------- Global Variables ----------------------------*/
/*----------------------------- External Functions --------------------------*/
/*-----------------------------------------------------------------------------
* Wait function with the Periodic Interval Timer (PIT)
* The wait time is from 1ms to 999ms.
-----------------------------------------------------------------------------*/
void AT91F_AT24C_WaitMiliSecond (unsigned int MiliSeconds)
{
unsigned int PitStatus = 0; /* Status register of the PIT */
unsigned int PitLoop = 0; /* Store the number of PIT Loop */
AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN|PIT_PIV_MILI_SECOND_VALUE;
for( PitLoop=0; PitLoop <(MiliSeconds*3);) /* One PIT loop equals 333ms */
{
/* Wait for the PIT counter overflow occurs */
while ((AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS)==0);
/* Read the PIT Interval Value Reg. to clear it for the next overflow */
PitStatus = AT91C_BASE_PITC->PITC_PIVR ;
/* dummy access to avoid IAR warning */
PitStatus = PitStatus ;
PitLoop++;
}
}
/*-----------------------------------------------------------------------------
* Wait function with the Periodic Interval Timer (PIT)
* The wait time is from 1us to 999us.
-----------------------------------------------------------------------------*/
void AT91F_AT24C_WaitMicroSecond (unsigned int MicroSecond)
{
unsigned int PitStatus = 0; /* Status register of the PIT */
unsigned int PitLoop = 0; /* Store the number of PIT Loop */
AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN|PIT_PIV_MICRO_SECOND_VALUE;
for( PitLoop=0; PitLoop <(MicroSecond);) /* One PIT loop equals 333ns */
{
/* Wait for the PIT counter overflow occurs */
while ((AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS)==0);
/* Read the PIT Interval Value Reg. to clear it for the next overflow */
PitStatus = AT91C_BASE_PITC->PITC_PIVR ;
/* dummy access to avoid IAR warning */
PitStatus = PitStatus ;
PitLoop++;
}
}
/*-----------------------------------------------------------------------------
Function: AT91F_AT24C_WriteByte(..;..;..)
Arguments:
- <struct at24c *ptAt24c> : Structure of an AT24C Two-wire Eeprom
- <char Data2Write>: The data to write into the eeprom
- <unsigned int Address>: Address where to write
Comments:
This function uses a two bytes internal address (IADR) in relation of the
Eeprom's Internal "Word Address".
Return Value: None. No write error checking is done.
-----------------------------------------------------------------------------*/
void AT91F_AT24C_WriteByte (struct at24c *ptAt24c,
char Data2Write,
unsigned int Address)
{
unsigned int WordAddress;
unsigned int SlaveAddress;
/* 17th bit of the word address. Applicable to the AT24C1024 only */
unsigned char p0=0;
if (ptAt24c->EepromName == AT24C1024)
{
if ( Address > 0xFFFF) {
p0 = 1;
/* Mask the 17th bit to get the 16th LSB */
WordAddress = Address & 0xFFFF ;
SlaveAddress = ptAt24c->SlaveAddress + (p0<<16) ;
}
else {
SlaveAddress = ptAt24c->SlaveAddress ;
WordAddress = Address ;
}
}
AT91F_TWI_WriteSingleIadr(AT91C_BASE_TWI,
SlaveAddress,
WordAddress,
AT91C_TWI_IADRSZ_2_BYTE,
&Data2Write);
/* Wait 10ms before sending another start.
See Twr time spec. in the datasheet */
AT91F_AT24C_WaitMiliSecond (10);
}
/*-----------------------------------------------------------------------------
Function: AT91F_AT24C_WritePage(..;..;..)
Arguments:
- <struct at24c *ptAt24c> : Structure of an AT24C Two-wire Eeprom
- <char *Buffer>: The data (*buffer) to write into the eeprom
- <NumOfBytes>: Size of the buffer
- <unsigned int AddressOffSet>: Address offset form the page address
Comments:
This function uses a two bytes internal address (IADR) in relation of the
Eeprom's Internal "Word Address". NACK error not handled
Return Value: None. No write error checking is done.
-----------------------------------------------------------------------------*/
void AT91F_AT24C_WritePage (struct at24c *ptAt24c,
char *Buffer,
unsigned int NumOfBytes,
unsigned int PageNumber,
unsigned int AddressOffSet)
{
unsigned int WordAddress;
unsigned int SlaveAddress;
unsigned int Count ;
unsigned int status;
/* 17th bit of the word address. Applicable to the AT24C1024 only */
unsigned char p0=0;
if (ptAt24c->EepromName == AT24C1024)
{
if ( ( (PageNumber*ptAt24c->PageSize) + AddressOffSet ) > 0xFFFF) {
p0 = 1;
/* Mask the 17th bit to get the 16th LSB */
WordAddress = ( (PageNumber*ptAt24c->PageSize) + AddressOffSet ) & 0xFFFF ;
SlaveAddress = ptAt24c->SlaveAddress + (p0<<16) ;
}
else
{
SlaveAddress = ptAt24c->SlaveAddress ;
WordAddress = (PageNumber*ptAt24c->PageSize) + AddressOffSet ;
}
}
/****************************************************************************/
/* Speed improvement w/ large buffer, TWI is accessed without calling TWI */
/* functions. */
/****************************************************************************/
/* Enable Master Mode of the TWI */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN ;
/* Set the TWI Master Mode Register */
AT91C_BASE_TWI->TWI_MMR = SlaveAddress & ~AT91C_TWI_MREAD | AT91C_TWI_IADRSZ_2_BYTE;
/* Set the internal address to access the wanted page */
AT91C_BASE_TWI->TWI_IADR = WordAddress ;
/* Wait until TXRDY is high to transmit the next data */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXRDY))
status = AT91C_BASE_TWI->TWI_SR;
/* Send the buffer to the page */
for ( Count=0; Count < NumOfBytes ;Count++ )
{
AT91C_BASE_TWI->TWI_THR = *Buffer++;
/* Wait until TXRDY is high to transmit the next data */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXRDY))
status = AT91C_BASE_TWI->TWI_SR;
}
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP))
status = AT91C_BASE_TWI->TWI_SR;
/* Wait 10ms before sending another start.
See Twr time spec. in the datasheet */
AT91F_AT24C_WaitMiliSecond (10);
}
/*-----------------------------------------------------------------------------
Function: AT91F_AT24C_ReadByte(..;..;..)
Arguments:
- <struct at24c *ptAt24c> : Structure of an AT24C Two-wire Eeprom
- <unsigned int Address>: Address to read
Comments:
This function uses a two bytes internal address (IADR) in relation of the
Eeprom's Internal "Word Address".
Return Value: None. No read error checking is done.
-----------------------------------------------------------------------------*/
char AT91F_AT24C_ReadByte (struct at24c *ptAt24c,
unsigned int Address)
{
unsigned int WordAddress;
unsigned int SlaveAddress;
char Data2Read ;
/* 17th bit of the word address. Applicable to the AT24C1024 only */
unsigned char p0=0;
if (ptAt24c->EepromName == AT24C1024)
{
if ( Address > 0xFFFF) {
p0 = 1;
/* Mask the 17th bit to get the 16th LSB */
WordAddress = Address & 0xFFFF ;
SlaveAddress = ptAt24c->SlaveAddress + (p0<<16) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -