AT24C02 Driver

/* Define to prevent recursive inclusion -------------------------------------*/

#ifndef __AT24_H

#define __AT24_H



#include <string.h>

#include "hw_twi.h"

#include "hw_def.h"



/*



AT24C02, 2K Bits SERIAL EEPROM:



Internally organized with 32 pages of 8 bytes each,

the 2K Bits requires an 8-bit data word address for random word addressing.



// Serial EEPROM type //////////////////////////////////////////////////////////



#define IIC_EEPROM_AT24C01      1       // AT24C01 - 1K ( 128 x 8) ( 8 byte page write)

#define IIC_EEPROM_AT24C02      2       // AT24C02 - 2K ( 256 x 8) ( 8 byte page write)

#define IIC_EEPROM_AT24C04      4       // AT24C04 - 4K ( 512 x 8) (16 byte page write)

#define IIC_EEPROM_AT24C08      8       // AT24C08 - 8K (1024 x 8) (16 byte page write)

#define IIC_EEPROM_AT24C16     16       // AT24C16 -16K (2048 x 8) (16 byte page write)



       +---+---+---+---+---+---+---+---+

 1k/2K | 1 | 0 | 1 | 0 | A2| A1| A0|R/W| AT24C01A/AT24C02

       +---+---+---+---+---+---+---+---+

       +---+---+---+---+---+---+---+---+

 4k    | 1 | 0 | 1 | 0 | A2| A1| P0|R/W| AT24C04

       +---+---+---+---+---+---+---+---+

       +---+---+---+---+---+---+---+---+

 8k    | 1 | 0 | 1 | 0 | A2| P1| P0|R/W| AT24C08

       +---+---+---+---+---+---+---+---+

       +---+---+---+---+---+---+---+---+

16k    | 1 | 0 | 1 | 0 | P2| P1| P0|R/W| AT24C16

       +---+---+---+---+---+---+---+---+



       +---+---+---+---+---+---+---+---+

512k   | 1 | 0 | 1 | 0 | A2| A1| A0|R/W| AT24C512

       +---+---+---+---+---+---+---+---+



       +---+---+---+---+---+---+---+---+

1M     | 1 | 0 | 1 | 0 | A2| A1| P0|R/W| AT24C1024

       +---+---+---+---+---+---+---+---+



       P0,P1,P2 - Page Address



*/



#define AT24_CMD_READ         ( 0xA1  )

#define AT24_CMD_WRITE        ( 0xA0  )



#define AT24_CHIP_SIZE        ( 0x100 )

#define AT24_PAGE_SIZE        ( 0x08  )



#define AT24_WRITE_TIMEOUT    ( 50 )

#define AT24_PAGE_MASK        ( AT24_PAGE_SIZE-1  )

#define AT24_PAGE_COUNT       ( AT24_CHIP_SIZE/AT24_PAGE_SIZE  )



unsigned int AT24_Init(void);

void AT24_ReadMemory(unsigned int dwAddr,

  unsigned int dwSize, unsigned char * Memory);

void AT24_WriteMemory(unsigned int dwAddr,

  unsigned int dwSize, unsigned char * Memory);



#endif  /*__AT24_H*/
#include "AT24.h"

#include "hw_eeprom_addr.h"



unsigned int AT24_Init(void)

{

#if ( 1 )

  unsigned int TestValue;

  unsigned int i = 0;

  do {

    TestValue = 0xAA;

    AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, (unsigned char *)&TestValue);

    if ( ( i > 0 ) || ( TestValue == 0x55 ) ) break;

    AT24_WriteMemory(EEPROM_ADDR_TEST_UNIT, 1, (unsigned char *)&TestValue);

    i++;

  } while (1);

  return ( TestValue == 0x55 );



#else



  unsigned int TestValue;

  TestValue = 0xAA;

  AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, &TestValue);



  if ( TestValue != 0x55 )

  {

    TestValue = 0x55;

    AT24_WriteMemory(EEPROM_ADDR_TEST_UNIT, 1, &TestValue);



    TestValue = 0xAA;

    AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, &TestValue);

  }

  return ( TestValue == 0x55 );

#endif

}



// only for UserZone 0..2

void AT24_ReadMemory(unsigned int dwAddr,

  unsigned int dwSize, unsigned char * Memory)

{

  //memset( Memory, 0xFF, dwSize );

  if ( dwAddr + dwSize > AT24_CHIP_SIZE ) return;



#if ( AT24_CHIP_SIZE > 0x0800 )     // AT24C32 > 2048 Bytes



#else                               // AT24C16 : 2048 Bytes : P2:P1:P0:ADDR



  // Write Address

  HW_TWI_Start( HW_TWI_AT24 );

  HW_TWI_SendByte(HW_TWI_AT24,  AT24_CMD_WRITE | ( (dwAddr>>8) << 1 ) );

  if ( HW_TWI_ReadACK( HW_TWI_AT24 ) == HW_TWI_NACK )

  {

    HW_TWI_Stop( HW_TWI_AT24 );

    return;

  }



  HW_TWI_SendByte(HW_TWI_AT24,  dwAddr );

  HW_TWI_ReadACK( HW_TWI_AT24 );



  // READ Data

  HW_TWI_Start( HW_TWI_AT24 );

  HW_TWI_SendByte(HW_TWI_AT24,  AT24_CMD_READ | ( (dwAddr>>8) << 1 ) );

  HW_TWI_ReadACK( HW_TWI_AT24 );



  while ( dwSize )

  {

    *Memory = HW_TWI_ReceiveByte  ( HW_TWI_AT24 );

    if ( dwSize == 1 )

      HW_TWI_SendACK( HW_TWI_AT24, HW_TWI_NACK );

    else

      HW_TWI_SendACK( HW_TWI_AT24, HW_TWI_ACK );



    Memory++;

    dwSize--;

  }



  HW_TWI_Stop( HW_TWI_AT24 );



#endif

}



void AT24_WritePage(unsigned int dwAddr,

  unsigned int dwSize, unsigned char * Memory)

{

#if ( AT24_CHIP_SIZE > 0x0800 )     // AT24C32 > 2048 Bytes



#else                               // AT24C16 : 2048 Bytes : P2:P1:P0:ADDR



  HW_TWI_Start( HW_TWI_AT24 );

  HW_TWI_SendByte(HW_TWI_AT24,  AT24_CMD_WRITE | ( (dwAddr>>8) << 1 ) );

  if ( HW_TWI_ReadACK( HW_TWI_AT24 ) == HW_TWI_NACK )

  {

    HW_TWI_Stop( HW_TWI_AT24 );

    return;

  }



  HW_TWI_SendByte(HW_TWI_AT24,  dwAddr );

  HW_TWI_ReadACK( HW_TWI_AT24 );



  while ( dwSize )

  {

    HW_TWI_SendByte(HW_TWI_AT24,  *Memory );

    HW_TWI_ReadACK( HW_TWI_AT24 );

    Memory++;

    dwSize--;

  }

  HW_TWI_Stop( HW_TWI_AT24 );



  // Poll Ack from eeprom

HW_TWI_WaitComplete(HW_TWI_AT24,

    AT24_CMD_WRITE | ( (dwAddr>>8) << 1 ), AT24_WRITE_TIMEOUT);



#endif



}



/*



When the word address, internally generated, reaches the page boundary,

the following byte is placed at the beginning of the same page.



If more than eight (1K/2K) or sixteen (4K, 8K, 16K) data words

are transmitted to the EEPROM, the data word address

will roll over and previous data will be overwritten.

*/



void AT24_WriteMemory(unsigned int dwAddr,

  unsigned int dwSize, unsigned char * Memory)

{

  unsigned int dwSizeInPage;



  if ( dwAddr + dwSize > AT24_CHIP_SIZE ) return;



  while ( dwSize > 0 )

  {

    dwSizeInPage = AT24_PAGE_SIZE - ( dwAddr & (AT24_PAGE_SIZE-1) );

    if ( dwSizeInPage > dwSize ) dwSizeInPage = dwSize;



    AT24_WritePage(dwAddr, dwSizeInPage, Memory);



    dwSize -= dwSizeInPage;

    Memory += dwSizeInPage;

    dwAddr += dwSizeInPage;

    // now it must be page alignment

  }

}

 

posted @ 2013-04-28 18:29  IAmAProgrammer  阅读(1635)  评论(0编辑  收藏  举报