David Möschwitzer / AT24C64D
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AT24C64D.cpp Source File

AT24C64D.cpp

00001 #include "AT24C64D.h"
00002 #include "math.h"
00003 
00004 
00005 
00006 //******************************************************************************//
00007 // uiAddr:   user address [A2...A0]
00008 //******************************************************************************//
00009 AT24C64D::AT24C64D(I2C *_i2c, uint8_t uiAddr)                            //
00010     :   AT24C64D_W( HARD_ADDR| (uiAddr & USER_ADDR_MASK) << 1),               // Initialisation of const WRITE
00011         AT24C64D_R( AT24C64D_W | 0x01 ){
00012         
00013         
00014         printf("Contructor of EEPROM AT24C64D...");
00015         bAck = NACK;
00016         timer = new Timer;
00017         startTimer();
00018         
00019         i2c = _i2c;
00020         
00021         for(int a; a <= SIZE_PAGE; a++)
00022             cBuffer[a] = 0x00;
00023         
00024         printf("end\n");
00025         
00026         uiAddrWrite = 0;
00027         uiAddrRead  = 0;
00028 }
00029 
00030 
00031 //******************************************************************************//
00032 //  Returns the address of the spi bus. This is the combination of the Hardware //
00033 //  chip address and the user defined addres [A2..A0]                           //
00034 //******************************************************************************//
00035 uint8_t AT24C64D::getAddrBus(){
00036     return AT24C64D_W;
00037 }
00038 
00039 
00040 
00041 //******************************************************************************//
00042 //  Returns the user defined address [A2..A0]                                   //
00043 //******************************************************************************//
00044 uint8_t AT24C64D::getAddrUser(){
00045     return (AT24C64D_W >> 1) & USER_ADDR_MASK;
00046 }
00047 
00048 //******************************************************************************//
00049 //  Sets the address for the writing position. If the address is higher as the  //
00050 //  max. memory address, then the writing address will be 0x00.                 //
00051 //******************************************************************************//
00052 void AT24C64D::setAddrWrite(uint16_t Addr){    
00053     if(uiAddrWrite > MEM_ADDR_MAX)  uiAddrWrite = 0;
00054     else                            uiAddrWrite = Addr;
00055 
00056 }
00057 
00058 
00059 //******************************************************************************//
00060 // Increments the writing address. If the address is higher as the max. memory  //
00061 // adress, it will be roll over.                                                //
00062 //******************************************************************************//
00063 void AT24C64D::incAddrWrite(){
00064     if(uiAddrWrite >= MEM_ADDR_MAX) uiAddrWrite = 0;
00065     else                            uiAddrWrite++;
00066 }
00067 
00068 
00069 
00070 //******************************************************************************//
00071 // Decrements the writing address. If the address is smaller or equals to zero, //
00072 // it will be roll over.                                                        //
00073 //******************************************************************************//
00074 void AT24C64D::decAddrWrite(){
00075     if(uiAddrWrite <= 0)            uiAddrWrite = 4095;
00076     else                            uiAddrRead--;
00077 }
00078 
00079 
00080 
00081 //******************************************************************************//
00082 // Returns the current writing address.                                         //
00083 //******************************************************************************//
00084 uint16_t AT24C64D::getAddrWrite(){
00085     return uiAddrWrite;
00086 }
00087 
00088 
00089 
00090 //******************************************************************************//
00091 //  Sets the address for the reading position. If the address is higher as the  //
00092 //  max. memory address, then the writing address will be 0x00.                 //
00093 //******************************************************************************//
00094 void AT24C64D::setAddrRead(uint16_t Addr){    
00095     if(uiAddrRead > MEM_ADDR_MAX)   uiAddrRead = 0;
00096     else                            uiAddrRead = Addr;
00097 
00098 }
00099 
00100 
00101 //******************************************************************************//
00102 // Increments the writing address. If the address is higher as the max. memory  //
00103 // adress, it will be roll over.                                                //
00104 //******************************************************************************//
00105 void AT24C64D::incAddrRead(){
00106     if(uiAddrRead >= MEM_ADDR_MAX) uiAddrRead = 0;
00107     else                            uiAddrRead++;
00108 }
00109 
00110 
00111 
00112 //******************************************************************************//
00113 // Decrements the writing address. If the address is smaller or equals to zero, //
00114 // it will be roll over.                                                        //
00115 //******************************************************************************//
00116 void AT24C64D::decAddrRead(){
00117     if(uiAddrRead <= 0)             uiAddrRead = 4095;
00118     else                            uiAddrRead--;
00119 }
00120 
00121 
00122 
00123 //******************************************************************************//
00124 //  Returns the current reading address.                                        //
00125 //******************************************************************************//
00126 uint16_t AT24C64D::getAddrRead(){
00127     return uiAddrRead;
00128 }
00129 
00130 
00131 //******************************************************************************//
00132 //  After an interruption in protocol, power loss or system reset, the 2-wire   //
00133 //  part can be protocol reset.                                                 //
00134 //******************************************************************************//
00135 void AT24C64D::reset(){
00136     i2c->start();
00137     i2c->write(0x00);
00138     i2c->start();
00139     i2c->stop();
00140     
00141     return;
00142 }
00143 
00144 
00145 
00146 /******************************************************************************/
00147 // not implemented
00148 /******************************************************************************/
00149 bool  AT24C64D::erase(){
00150     return NACK;
00151 }
00152 
00153 
00154 
00155 //******************************************************************************//
00156 //  Writes a data byte to the current write address (uiAddrWrite). If all       //
00157 //  transmitions are successful, it will be returned a ACK. Otherwise a NACK.   //
00158 //  The uiAddrWrite will be incremented, if the transmition was successfull.    //
00159 //******************************************************************************//
00160 bool AT24C64D::write(char * cData){
00161     return write(uiAddrWrite, cData);
00162 }
00163     
00164     
00165 //******************************************************************************//
00166 //  Writes a data byte to the given address uiAddr. If all transmitions are     //
00167 //  successful, it will be returned a ACK. Otherwise a NACK. The uiAddrWrite    //
00168 //  will be set and incremented, if the transmition was successfull.            //      
00169 //******************************************************************************//
00170 bool AT24C64D::write(uint16_t uiAddr, char * cData){
00171     
00172     bAck        = NACK;
00173     uiTimeOut   = TIMEOUT_VAL; 
00174     
00175     
00176     while(not isReady());
00177     ACKpolling(AT24C64D_W);
00178     
00179     uiAddr      = uiAddr & ADDR_MASK;            
00180     cBuffer[0]  = (uiAddr >> 8) & 0xFF;
00181     cBuffer[1]  = uiAddr & 0xFF;
00182     cBuffer[2]  = (*cData);      
00183     
00184     //printf("Write on EEPROM address 0x%02x %02x the Byte 0x%02x\n", cBuffer[0], cBuffer[1], cBuffer[2]);
00185 
00186     bAck &= i2c->write(AT24C64D_W, cBuffer, 3);
00187     startTimer();
00188     
00189     
00190     uiAddrWrite = uiAddr;
00191     //incAddrWrite();
00192     
00193     return bAck;
00194 }
00195 
00196 
00197 //******************************************************************************//
00198 //  Writes a data byte to address uiAddr. If all  transmitions are successful,  //
00199 //  it will be returned a ACK. Otherwise a NACK. After every successful         //
00200 //  transmition, the writeAddr will new set and at the end incremented.         //       
00201 //******************************************************************************//
00202 bool AT24C64D::write(uint16_t uiAddr, char * cData, uint16_t uiLength){
00203     return NACK;
00204 }
00205 
00206 
00207 
00208 
00209 //******************************************************************************//
00210 //
00211 //******************************************************************************//
00212 bool AT24C64D::read(char *cData){ 
00213     return read(uiAddrRead, cData);
00214 }
00215 
00216 
00217 //******************************************************************************//
00218 //
00219 //******************************************************************************//
00220 bool AT24C64D::read(uint16_t uiAddr, char *cData){ 
00221     
00222    // bAck = ACKpolling(AT24C64D_R);                                              // polling for ACK
00223     
00224     //if(bAck == ACK){
00225 
00226         uiAddrRead = uiAddr & ADDR_MASK;               
00227         cBuffer[0] = (uiAddrRead >> 8) & 0xFF;
00228         cBuffer[1] = uiAddrRead & 0xFF;
00229         
00230         i2c->start();
00231         i2c->write(AT24C64D_W);
00232         i2c->write(cBuffer[0]);
00233         i2c->write(cBuffer[1]);
00234         //i2c->read(AT24C64D_R, cData, 10);
00235         
00236         i2c->start();
00237         i2c->write(AT24C64D_R);
00238         *cData = i2c->read(false);
00239         i2c->stop();
00240     //}
00241     return bAck;
00242 }
00243 
00244 
00245 
00246 //******************************************************************************//
00247 //  Reads data with length uiLength from Memory on address uiAddr. If all       //
00248 //  transmitions are successful, it will be returned a ACK. Otherwise a NACK.   //
00249 //  After every successful transmition, the readAddr will new set and at the    //
00250 //  end incremented. When the memory address limit is reached, the data word    //
00251 //  address will “roll over” and the sequential read will continue.             //
00252 //******************************************************************************//
00253 bool AT24C64D::read(uint16_t uiAddr, char *cData, uint16_t uiLength){ 
00254     
00255     if(uiLength == 0){
00256         printf("Read from EPPROM with a size of 0\n");
00257         return NACK;
00258     }
00259     
00260     //ACKpolling(AT24C64D_R);
00261     
00262     
00263     
00264     uiAddrRead = uiAddr & ADDR_MASK;    
00265             
00266     cBuffer[0] = (uiAddrRead >> 8) & 0xFF;
00267     cBuffer[1] = uiAddrRead & 0xFF;
00268     int iPos = 0;
00269     
00270     i2c->start();
00271     i2c->write(AT24C64D_W);
00272     i2c->write(cBuffer[0]);
00273     i2c->write(cBuffer[1]);
00274     i2c->start();
00275     i2c->write(AT24C64D_R);
00276     while(iPos < uiLength - 1){
00277         cData[iPos] = i2c->read(true);
00278         iPos++;
00279     }
00280     cData[iPos] = i2c->read(false);
00281     i2c->stop();
00282     
00283     return bAck;
00284 }
00285 
00286 
00287 
00288 /******************************************************************************/
00289 //
00290 /******************************************************************************/
00291 bool AT24C64D::isReady(){
00292     
00293     if(timer->read_ms() > READY_TIME_MS){
00294         //printf("Time: %d\n", timer->read_ms());
00295         bReady = true;
00296 
00297         if(bTimerRun){
00298             timer->stop();
00299             bTimerRun = false;
00300         }
00301     }
00302     
00303     return bReady;
00304 }
00305 
00306 
00307 /******************************************************************************/
00308 //
00309 /******************************************************************************/
00310 void AT24C64D::startTimer(){
00311     
00312     timer->start();
00313     timer->reset();
00314 
00315     bReady      = false;    
00316     bTimerRun   = true;
00317 }
00318 
00319 
00320 
00321 /******************************************************************************/
00322 //
00323 /******************************************************************************/
00324 bool AT24C64D::ACKpolling(uint8_t uiAdr){
00325     
00326     bAck        = NACK;
00327     uiTimeOut   = TIMEOUT_VAL;
00328     
00329     while(bAck != ACK){
00330         i2c->start();
00331         bAck = (bool) i2c->write(uiAdr);                                        // return 0 -> NACK | 1 -> ACK | 2 -> TimeOut
00332         i2c->stop();
00333         
00334         uiTimeOut--;
00335         if(uiTimeOut == 0){
00336             printf("Read from EPPROM: timeout\n");
00337             return NACK;
00338         }       
00339     
00340         wait(100e-6);
00341     }
00342     
00343     return bAck;
00344 }