Acknowledge polling in EEPROM

i2cpic

I am using C18 compiler and I learned that acknowledge polling feature will greatly help in reducing the write time that is to remove the fixed delay in traditional methods. Well I am using EEPROM 24LC256 and there is a feature for acknowledge polling in it.

I have written a code for Acknowledge Polling.

  long eewrite_p( int address,int msg)
    {
        int my_response;
        int i;
        i2c_init();
                                    //if(!i2c_initialised) return '\0';
        StartI2C();                 //Send the Start Bit
        Nop();
        IdleI2C();                  //Wait to complete
        Nop();
        WriteI2C( 0xA0 );
        Nop();
        IdleI2C();
        //Wait to complete

        WriteI2C( address>>8);
        Nop();
        IdleI2C();

        WriteI2C(address&0xFF);
        Nop();
        IdleI2C();

        my_response = WriteI2C(msg);
        Nop();

        AckI2C();
        IdleI2C();

        StopI2C();              //Send the Stop condition
        Nop();
        IdleI2C();              //Wait to complete
    }

Well, this is an old code w/o acknowledge polling. I've read about acknowledge polling for every Control Byte/Data/Address Byte is necessary. Correct me if I am wrong. Do we need to do an acknowledge polling for every Byte written in to the chip?

Another doubt I have is if we check for acknowledgement and if it is not received then the Datasheet/App notes says wait till Acknowledge is received. Else the code is polled till Acknowledge is received.

Well, previously I tried writing EE device address, one function after another, w/o any delay in between them and I trust it must not have been written well. How can I modify the current code to make use of Acknowledge polling?

Best Answer

If a typical EEPROM acknowledges the first byte following a start condition, there is no defined sequence of events via which it would fail to acknowledge any other byte which is sent in accordance with specifications. Testing for acknowledgment after subsequent bytes might help code detect that something went wrong if a glitch occurs and knocks things "out of sync", but may not really help anything unless the code can do something useful in response.

In my own code, my normal approach is to bit-bang I2C with routines:

bit I2C_StartRead(unsigned char address);
bit I2C_StartWrite(unsigned char address);
void I2C_PutByte(unsigned char dat);
unsigned char I2C_GetByte(void);
void I2C_Stop();

I2C_StartRead and I2C_StartWrite will drive the clock high, release SDA, and, if data isn't high, drive the clock low then high until it is. They will then clock out the address byte and put the clock wire high for the following ACK, and check the state of SDA, returning 1 if SDA is asserted and 0 if it is not.

Bit-bang I2C may seem tricky, but I've generally found it easier than using the master-I2C hardware. Among other things, the master I2C hardware includes "get byte and ACK" or "get byte and NAK" functions, effectively requiring that code know before it reads a byte whether it will want another byte after it. With a bit-bang I2C implementation, one can have the I2C_GetByte routine exit after reading the last data bit, but without having ACKed or NAKed it, and then have the next call to GetByte acknowledge the previous byte (if there is no next I2C_GetByte call before the next I2C_StartRead or I2C_Stop, the latter two calls will output a NAK).