EEPROM with 64kByte Memory
AT24C64D.cpp
- Committer:
- x1dmoesc
- Date:
- 2019-03-05
- Revision:
- 4:660801ce718c
- Parent:
- 3:8a0bfc787463
File content as of revision 4:660801ce718c:
#include "AT24C64D.h"
#include "math.h"
//******************************************************************************//
// uiAddr: user address [A2...A0]
//******************************************************************************//
AT24C64D::AT24C64D(I2C *_i2c, uint8_t uiAddr) //
: AT24C64D_W( HARD_ADDR| (uiAddr & USER_ADDR_MASK) << 1), // Initialisation of const WRITE
AT24C64D_R( AT24C64D_W | 0x01 ){
printf("Contructor of EEPROM AT24C64D...");
bAck = NACK;
timer = new Timer;
startTimer();
i2c = _i2c;
for(int a; a <= SIZE_PAGE; a++)
cBuffer[a] = 0x00;
printf("end\n");
uiAddrWrite = 0;
uiAddrRead = 0;
}
//******************************************************************************//
// Returns the address of the spi bus. This is the combination of the Hardware //
// chip address and the user defined addres [A2..A0] //
//******************************************************************************//
uint8_t AT24C64D::getAddrBus(){
return AT24C64D_W;
}
//******************************************************************************//
// Returns the user defined address [A2..A0] //
//******************************************************************************//
uint8_t AT24C64D::getAddrUser(){
return (AT24C64D_W >> 1) & USER_ADDR_MASK;
}
//******************************************************************************//
// Sets the address for the writing position. If the address is higher as the //
// max. memory address, then the writing address will be 0x00. //
//******************************************************************************//
void AT24C64D::setAddrWrite(uint16_t Addr){
if(uiAddrWrite > MEM_ADDR_MAX) uiAddrWrite = 0;
else uiAddrWrite = Addr;
}
//******************************************************************************//
// Increments the writing address. If the address is higher as the max. memory //
// adress, it will be roll over. //
//******************************************************************************//
void AT24C64D::incAddrWrite(){
if(uiAddrWrite >= MEM_ADDR_MAX) uiAddrWrite = 0;
else uiAddrWrite++;
}
//******************************************************************************//
// Decrements the writing address. If the address is smaller or equals to zero, //
// it will be roll over. //
//******************************************************************************//
void AT24C64D::decAddrWrite(){
if(uiAddrWrite <= 0) uiAddrWrite = 4095;
else uiAddrRead--;
}
//******************************************************************************//
// Returns the current writing address. //
//******************************************************************************//
uint16_t AT24C64D::getAddrWrite(){
return uiAddrWrite;
}
//******************************************************************************//
// Sets the address for the reading position. If the address is higher as the //
// max. memory address, then the writing address will be 0x00. //
//******************************************************************************//
void AT24C64D::setAddrRead(uint16_t Addr){
if(uiAddrRead > MEM_ADDR_MAX) uiAddrRead = 0;
else uiAddrRead = Addr;
}
//******************************************************************************//
// Increments the writing address. If the address is higher as the max. memory //
// adress, it will be roll over. //
//******************************************************************************//
void AT24C64D::incAddrRead(){
if(uiAddrRead >= MEM_ADDR_MAX) uiAddrRead = 0;
else uiAddrRead++;
}
//******************************************************************************//
// Decrements the writing address. If the address is smaller or equals to zero, //
// it will be roll over. //
//******************************************************************************//
void AT24C64D::decAddrRead(){
if(uiAddrRead <= 0) uiAddrRead = 4095;
else uiAddrRead--;
}
//******************************************************************************//
// Returns the current reading address. //
//******************************************************************************//
uint16_t AT24C64D::getAddrRead(){
return uiAddrRead;
}
//******************************************************************************//
// After an interruption in protocol, power loss or system reset, the 2-wire //
// part can be protocol reset. //
//******************************************************************************//
void AT24C64D::reset(){
i2c->start();
i2c->write(0x00);
i2c->start();
i2c->stop();
return;
}
/******************************************************************************/
// not implemented
/******************************************************************************/
bool AT24C64D::erase(){
return NACK;
}
//******************************************************************************//
// Writes a data byte to the current write address (uiAddrWrite). If all //
// transmitions are successful, it will be returned a ACK. Otherwise a NACK. //
// The uiAddrWrite will be incremented, if the transmition was successfull. //
//******************************************************************************//
bool AT24C64D::write(char * cData){
return write(uiAddrWrite, cData);
}
//******************************************************************************//
// Writes a data byte to the given address uiAddr. If all transmitions are //
// successful, it will be returned a ACK. Otherwise a NACK. The uiAddrWrite //
// will be set and incremented, if the transmition was successfull. //
//******************************************************************************//
bool AT24C64D::write(uint16_t uiAddr, char * cData){
bAck = NACK;
uiTimeOut = TIMEOUT_VAL;
while(not isReady());
ACKpolling(AT24C64D_W);
uiAddr = uiAddr & ADDR_MASK;
cBuffer[0] = (uiAddr >> 8) & 0xFF;
cBuffer[1] = uiAddr & 0xFF;
cBuffer[2] = (*cData);
//printf("Write on EEPROM address 0x%02x %02x the Byte 0x%02x\n", cBuffer[0], cBuffer[1], cBuffer[2]);
bAck &= i2c->write(AT24C64D_W, cBuffer, 3);
startTimer();
uiAddrWrite = uiAddr;
//incAddrWrite();
return bAck;
}
//******************************************************************************//
// Writes a data byte to address uiAddr. If all transmitions are successful, //
// it will be returned a ACK. Otherwise a NACK. After every successful //
// transmition, the writeAddr will new set and at the end incremented. //
//******************************************************************************//
bool AT24C64D::write(uint16_t uiAddr, char * cData, uint16_t uiLength){
return NACK;
}
//******************************************************************************//
//
//******************************************************************************//
bool AT24C64D::read(char *cData){
return read(uiAddrRead, cData);
}
//******************************************************************************//
//
//******************************************************************************//
bool AT24C64D::read(uint16_t uiAddr, char *cData){
// bAck = ACKpolling(AT24C64D_R); // polling for ACK
//if(bAck == ACK){
uiAddrRead = uiAddr & ADDR_MASK;
cBuffer[0] = (uiAddrRead >> 8) & 0xFF;
cBuffer[1] = uiAddrRead & 0xFF;
i2c->start();
i2c->write(AT24C64D_W);
i2c->write(cBuffer[0]);
i2c->write(cBuffer[1]);
//i2c->read(AT24C64D_R, cData, 10);
i2c->start();
i2c->write(AT24C64D_R);
*cData = i2c->read(false);
i2c->stop();
//}
return bAck;
}
//******************************************************************************//
// Reads data with length uiLength from Memory on address uiAddr. If all //
// transmitions are successful, it will be returned a ACK. Otherwise a NACK. //
// After every successful transmition, the readAddr will new set and at the //
// end incremented. When the memory address limit is reached, the data word //
// address will “roll over” and the sequential read will continue. //
//******************************************************************************//
bool AT24C64D::read(uint16_t uiAddr, char *cData, uint16_t uiLength){
if(uiLength == 0){
printf("Read from EPPROM with a size of 0\n");
return NACK;
}
//ACKpolling(AT24C64D_R);
uiAddrRead = uiAddr & ADDR_MASK;
cBuffer[0] = (uiAddrRead >> 8) & 0xFF;
cBuffer[1] = uiAddrRead & 0xFF;
int iPos = 0;
i2c->start();
i2c->write(AT24C64D_W);
i2c->write(cBuffer[0]);
i2c->write(cBuffer[1]);
i2c->start();
i2c->write(AT24C64D_R);
while(iPos < uiLength - 1){
cData[iPos] = i2c->read(true);
iPos++;
}
cData[iPos] = i2c->read(false);
i2c->stop();
return bAck;
}
/******************************************************************************/
//
/******************************************************************************/
bool AT24C64D::isReady(){
if(timer->read_ms() > READY_TIME_MS){
//printf("Time: %d\n", timer->read_ms());
bReady = true;
if(bTimerRun){
timer->stop();
bTimerRun = false;
}
}
return bReady;
}
/******************************************************************************/
//
/******************************************************************************/
void AT24C64D::startTimer(){
timer->start();
timer->reset();
bReady = false;
bTimerRun = true;
}
/******************************************************************************/
//
/******************************************************************************/
bool AT24C64D::ACKpolling(uint8_t uiAdr){
bAck = NACK;
uiTimeOut = TIMEOUT_VAL;
while(bAck != ACK){
i2c->start();
bAck = (bool) i2c->write(uiAdr); // return 0 -> NACK | 1 -> ACK | 2 -> TimeOut
i2c->stop();
uiTimeOut--;
if(uiTimeOut == 0){
printf("Read from EPPROM: timeout\n");
return NACK;
}
wait(100e-6);
}
return bAck;
}