Renamed read and write functions so they speak for them selves and do no longer recursively call themselves, causing hangs. Also changed the way they return values. and added double and string handling.

EEPROM.cpp

Committer:
JackB
Date:
2016-11-23
Revision:
1:b90c5754d8db
Parent:
0:dac961a38be5

File content as of revision 1:b90c5754d8db:

/***********************************************************
Author: Bernard Borredon
Version: 1.3
  - Correct write(uint32_t address, int8_t data[], uint32_t length) for eeprom >= T24C32.
    Tested with 24C02, 24C08, 24C16, 24C64, 24C256, 24C512, 24C1025 on LPC1768 (mbed online and µVision V5.16a).
  - Correct main test.
    
Date : 12 decembre 2013
Version: 1.2
  - Update api documentation
  
Date: 11 december 2013
Version: 1.1
  - Change address parameter size form uint16_t to uint32_t (error for eeprom > 24C256).
  - Change size parameter size from uint16_t to uint32_t (error for eeprom > 24C256).
    - Correct a bug in function write(uint32_t address, int8_t data[], uint32_t length) :
      last step must be done only if it remain datas to send.
    - Add function getName.
    - Add function clear.
    - Initialize _name array.

Date: 27 december 2011
Version: 1.0

Jack: Many thanks Bernard!

Changed a lot of things by Jack Berkhout 23-11-2016
- Renamed read and write functions so they speak for them selves and do no longer
recursively call themselves, causing hangs.
- Also changed the way they return values. and added double and string handling.

************************************************************/
#include "EEPROM.h"

#define BIT_SET(x,n) (x=x | (0x01<<n))
#define BIT_TEST(x,n) (x & (0x01<<n))
#define BIT_CLEAR(x,n) (x=x & ~(0x01<<n))

const char * const EEPROM::_name[] = {"24C01","24C02","24C04","24C08","24C16","24C32",
                                        "24C64","24C128","24C256","24C512","24C1024","24C1025"};

/**
 * EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type) : _i2c(sda, scl)
 *
 * Constructor, initialize the eeprom on i2c interface.
 * @param sda sda i2c pin (PinName)
 * @param scl scl i2c pin (PinName)
 * @param address eeprom address, according to eeprom type (uint8_t)
 * @param type eeprom type (TypeEeprom) 
 * @return none
*/
EEPROM::EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type) : _i2c(sda, scl) 
//EEPROM::EEPROM(I2C* i2c, uint8_t address, TypeEeprom type) 
{
//     _i2c = i2c;
 
    _errnum = EEPROM_NoError;
    _type = type;
    
    // Check address range
    _address = address;
    switch(type) {
        case T24C01 :
        case T24C02 :
            if(address > 7) {
                _errnum = EEPROM_BadAddress;
            }
            _address = _address << 1;
            _page_write = 8;
            _page_number = 1;
            break;
        case T24C04 :
            if(address > 7) {
                _errnum = EEPROM_BadAddress;
            }
            _address = (_address & 0xFE) << 1;
            _page_write = 16;
            _page_number = 2;
            break;
        case T24C08 :
            if(address > 7) {
                _errnum = EEPROM_BadAddress;
            }
            _address = (_address & 0xFC) << 1;
            _page_write = 16;
            _page_number = 4;
            break;
        case T24C16 :
            _address = 0;
            _page_write = 16;
            _page_number = 8;
            break;
        case T24C32 :
        case T24C64 :
            if(address > 7) {
                _errnum = EEPROM_BadAddress;
            }
            _address = _address << 1;
            _page_write = 32;
            _page_number = 1;
            break;
        case T24C128 :
        case T24C256 :
            if(address > 3) {
                _errnum = EEPROM_BadAddress;
            }
            _address = _address << 1;
            _page_write = 64;
            _page_number = 1;
            break;
        case T24C512 :
            if(address > 3) {
                _errnum = EEPROM_BadAddress;
            }
            _address = _address << 1;
            _page_write = 128;
            _page_number = 1;
            break;
        case T24C1024 :
            if(address > 7) {
                _errnum = EEPROM_BadAddress;
            }
            _address = (_address & 0xFE) << 1;
            _page_write = 128;
            _page_number = 2;
            break;
        case T24C1025 :
            if(address > 3) {
                _errnum = EEPROM_BadAddress;
            }
            _address = _address << 1;
            _page_write = 128;
            _page_number = 2;
            break;
    }
  
    // Size in bytes
    _size = _type;
    if(_type == T24C1025) {
        _size = T24C1024;
    }
    
    // Set I2C frequency
    _i2c.frequency(400000);
}

/**
 * void write(uint32_t address, int8_t data[], uint32_t length)
 *
 * Write array of bytes (use the page mode)
 * @param address start address (uint32_t)
 * @param data bytes array to write (int8_t[])
 * @param size number of bytes to write (uint32_t)
 * @return none
*/
void EEPROM::write_data_array(uint32_t address, uint8_t data[], uint32_t length)
{
    uint8_t page;
    uint8_t addr = 0;
    uint8_t blocs,remain;
    uint8_t fpart,lpart;
    uint8_t i,j,ind;
    uint8_t cmd[129];
    int ack;

    // wait until ready
    ready();

    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
  
    // Check length
    if(!checkAddress(address + length - 1)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
  
    // Compute blocs numbers
    blocs = length / _page_write;
    
    // Compute remaining bytes
    remain = length - blocs * _page_write;

    for(i = 0;i < blocs;i++) {
        // Compute page number
        page = 0;
        if(_type < T24C32) {
            page = (uint8_t) (address / 256);
        }
  
        // Device address
        addr = EEPROM_Address | _address | (page << 1);
  
        if(_type < T24C32) {
            // Word address
            cmd[0] = (uint8_t) (address - page * 256);
     
            if((uint8_t) ((address + _page_write) / 256) == page) { // Data fit in the same page
                // Add data 
                for(j = 0;j < _page_write;j++) {
                    cmd[j + 1] = (uint8_t) data[i * _page_write + j];
                }
    
                // Write data
                ack = _i2c.write((int)addr,(char *)cmd,_page_write + 1);
                if(ack != 0) {
                    _errnum = EEPROM_I2cError;
                    return;
                }
  
                // Wait end of write
                ready();
       
                // Increment address
                address += _page_write;
            }
            else { // Data on 2 pages. We must split the write
                // Number of bytes in current page
                fpart = (page + 1) * 256 - address;
       
                // Add data for current page
                for(j = 0;j < fpart;j++) {
                    cmd[j + 1] = (uint8_t) data[i * _page_write + j];
                }
    
                // Write data for current page
                ack = _i2c.write((int)addr,(char *)cmd,fpart + 1);
                if(ack != 0) {
                    _errnum = EEPROM_I2cError;
                    return;
                }
  
                // Wait end of write
                ready();
       
                // Increment address
                address += fpart;
       
                if(page < _page_number - 1) {
                    // Increment page
                    page++;
       
                    // Device address
                    addr = EEPROM_Address | _address | (page << 1);
       
                    // Word address
                    cmd[0] = (uint8_t) (address - page * 256);
       
                    // Data index
                    ind = i * _page_write + fpart;
       
                    // Number of bytes in next page
                    lpart = _page_write - fpart;
       
                    // Add data for next page
                    for(j = 0;j < lpart;j++) {
                        cmd[j + 1] = (uint8_t) data[ind + j];
                    }
    
                    // Write data for next page
                    ack = _i2c.write((int)addr,(char *)cmd,lpart + 1);
                    if(ack != 0) {
                        _errnum = EEPROM_I2cError;
                        return;
                    }
  
                    // Wait end of write
                    ready();
       
                    // Increment address
                    address += lpart;
                }
            }
        }
        else {
            // First word address (MSB)
            cmd[0] = (uint8_t) (address >> 8);
       
            // Second word address (LSB)
            cmd[1] = (uint8_t) address;
       
            // Add data 
            for(j = 0;j < _page_write;j++) {
                cmd[j + 2] = (uint8_t) data[i * _page_write + j];
            }
    
            // Write data
            ack = _i2c.write((int)addr,(char *)cmd,_page_write + 2);
            if(ack != 0) {
                _errnum = EEPROM_I2cError;
                return;
            }
  
            // Wait end of write
            ready();
       
            // Increment address
            address += _page_write;
        }
    }
  
    if(remain) {
        // Compute page number
        page = 0;
        if(_type < T24C32) {
            page = (uint8_t) (address / 256); 
        }
        
        // Device address
        addr = EEPROM_Address | _address | (page << 1);
        
        if(_type < T24C32) {
            // Word address
            cmd[0] = (uint8_t) (address - page * 256);
  
            if((uint8_t) ((address + remain) / 256) == page) { // Data fit in the same page
                // Add data for the current page
                for(j = 0;j < remain;j++)
                cmd[j + 1] = (uint8_t) data[blocs * _page_write + j];
                
                // Write data for the current page
                ack = _i2c.write((int)addr,(char *)cmd,remain + 1);
                if(ack != 0) {
                    _errnum = EEPROM_I2cError;
                    return;
                }
  
                // Wait end of write
                ready();
            }
            else { // Data on 2 pages. We must split the write
                // Number of bytes in current page
                fpart = (page + 1) * 256 - address;
    
                // Add data for current page
                for(j = 0;j < fpart;j++) {
                    cmd[j + 1] = (uint8_t) data[blocs * _page_write + j];
                }
    
                // Write data for current page
                ack = _i2c.write((int)addr,(char *)cmd,fpart + 1);
                if(ack != 0) {
                    _errnum = EEPROM_I2cError;
                    return;
                }
                
                // Wait end of write
                ready();
                
                // Increment address
                address += fpart;
                
                if(page < _page_number - 1) {
                    // Increment page
                    page++;
                    
                    // Device address
                    addr = EEPROM_Address | _address | (page << 1);
                    
                    // Word address
                    cmd[0] = (uint8_t) (address - page * 256);
                    
                    // Data index
                    ind = blocs * _page_write + fpart;
                    
                    // Number of bytes in next page
                    lpart = remain - fpart;
    
                    // Add data for next page
                    for(j = 0;j < lpart;j++) {
                        cmd[j + 1] = (uint8_t) data[ind + j];
                    }
    
                    // Write data for next page
                    ack = _i2c.write((int)addr,(char *)cmd,lpart + 1);
                    if(ack != 0) {
                        _errnum = EEPROM_I2cError;
                        return;
                    }
        
                    // Wait end of write
                    ready();
                }
            }
        }
        else {
            // Fist word address (MSB)
            cmd[0] = (uint8_t) (address >> 8);
            
            // Second word address (LSB)
            cmd[1] = (uint8_t) address;

            // Add data for the current page
            for(j = 0;j < remain;j++) {
                cmd[j + 2] = (uint8_t) data[blocs * _page_write + j];
            }
            
            // Write data for the current page
            ack = _i2c.write((int)addr,(char *)cmd,remain + 2);
            if(ack != 0) {
                _errnum = EEPROM_I2cError;
            return;
            }
  
            // Wait end of write
            ready();
        }
    }
}


/**
 * void read(uint32_t address, void *data, uint32_t size)
 *
 * Random read anything
 * @param address start address (uint32_t)
 * @param data data to read (void *)
 * @param size number of bytes to read (uint32_t)
 * @return none
*/
void EEPROM::read_data(uint32_t address, void *data, uint32_t size)
{
    int8_t *cmd = NULL;
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address + size - 1)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
  
    cmd = (int8_t *)malloc(size);
    
    if(cmd == NULL) {
        _errnum = EEPROM_MallocError;
        return;
    }
  
//  read_data_array(address,(int8_t *)cmd,size);
  
    memcpy(data,cmd,size);
    
    free(cmd);
}

/**
 * void read(uint32_t address, int8_t *data, uint32_t size)
 *
 * Sequential read byte
 * @param address start address (uint32_t)
 * @param data bytes array to read (int8_t[]&)
 * @param size number of bytes to read (uint32_t)
 * @return none
*/
void EEPROM::read_data_array(uint32_t address, uint8_t *data, uint32_t size)
{
    uint8_t page;
    uint8_t addr;
    uint8_t cmd[2];
    uint8_t len;
    int ack;
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
    
    // Check size
    if(!checkAddress(address + size - 1)) {
        _errnum = EEPROM_OutOfRange; 
        return;
    }
    
    // Compute page number
    page = 0;
    if(_type < T24C32) {
        page = (uint8_t) (address / 256); 
    }
        
    // Device address
    addr = EEPROM_Address | _address | (page << 1);
    
    if(_type < T24C32) {
        len = 1;
        
        // Word address
        cmd[0] = (uint8_t) (address - page * 256);
    }
    else {
        len = 2;
        
        // First word address (MSB)
        cmd[0] = (uint8_t) (address >> 8);
        
        // Second word address (LSB)
        cmd[1] = (uint8_t) address;
    }
    
    // Write command 
    ack = _i2c.write((int)addr,(char *)cmd,len,true);
    if(ack != 0) {
        _errnum = EEPROM_I2cError;
        return;
    }
    
    // Sequential read
    ack = _i2c.read((int)addr,(char *)data,size);
    if(ack != 0) {
        _errnum = EEPROM_I2cError;
        return;
    }
}

/**
 * void write(uint32_t address, void *data, uint32_t size)
 *
 * Write anything (use the page write mode)
 * @param address start address (uint32_t)
 * @param data data to write (void *)
 * @param size number of bytes to write (uint32_t)
 * @return none
*/
void EEPROM::write_data(uint32_t address, void *data, uint32_t size)
{
    int8_t *cmd = NULL;
    
    // wait until ready
    ready();

    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address + size - 1)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
  
    cmd = (int8_t *)malloc(size);
    if(cmd == NULL) {
        _errnum = EEPROM_MallocError;
        return;
    }

    memcpy(cmd,(uint8_t *)data,size);
    
    write_data_array(address,(uint8_t *)cmd,size);
    
    free(cmd);
}

/**
 * void write_uint8_t(uint32_t address, int8_t data)
 *
 * Write byte
 * @param address start address (uint32_t)
 * @param data byte to write (int8_t)
 * @return none
*/
void EEPROM::write_uint8_t(uint32_t address, uint8_t data)
{
    uint8_t page;
    uint8_t addr;
    uint8_t cmd[3];
    int len;
    int ack;
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
  
    // Compute page number
    page = 0;
    if(_type < T24C32) {
        page = (uint8_t) (address / 256); 
    }
  
    // Device address
    addr = EEPROM_Address | _address | (page << 1);
 
    if(_type < T24C32) {
        len = 2;
        
        // Word address 
        cmd[0] = (uint8_t) (address - page * 256);
        
        // Data
        cmd[1] = (uint8_t) data;
    }
    else {
        len = 3;
        
        // First word address (MSB)
        cmd[0] = (uint8_t) ((address >> 8) & 0xff);
        
        // Second word address (LSB)
        cmd[1] = (uint8_t) (address & 0xff);
        
        // Data
        cmd[2] = (uint8_t) data;
    }
    
    ack = _i2c.write((int)addr, (char *)cmd, len);
    if(ack != 0) {
        _errnum = EEPROM_I2cError;
        return;
    }
    
    // Wait end of write
//    ready();
}

/**
 * void write_uint16_t(uint32_t address, int16_t data)
 *
 * Write short
 * @param address start address (uint32_t)
 * @param data short to write (int16_t)
 * @return none
*/
void EEPROM::write_uint16_t(uint32_t address, uint16_t data)
{
    int8_t cmd[2];
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address + 1)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
    
    memcpy(cmd,&data,2);
    
    write_data(address,cmd,2);
}

/**
 * void write_uint32_t(uint32_t address, int32_t data)
 *
 * Write long
 * @param address start address (uint32_t)
 * @param data long to write (int32_t)
 * @return none
*/
void EEPROM::write_uint32_t(uint32_t address, uint32_t data)
{
    int8_t cmd[4];
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address + 3)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
    
    memcpy(cmd,&data,4);
    
    write_data(address,cmd,4);
}

/**
 * void write_float(uint32_t address, float data)
 *
 * Write float
 * @param address start address (uint32_t)
 * @param data float to write (float)
  * @return none
*/
void EEPROM::write_float(uint32_t address, float data)
{
    int8_t cmd[4];
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address + 3)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
    
    memcpy(cmd,&data,4);
    
    write_data(address,cmd,4);
}

/**
 * void write_double(uint32_t address, double data)
 *
 * Write double
 * @param address start address (uint32_t)
 * @param data double to write (double)
  * @return none
*/
void EEPROM::write_double(uint32_t address, double data)
{
    int8_t cmd[8];
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address + 7)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
    
    memcpy(cmd,&data,8);
    
    write_data(address,cmd,8);
}

/**
 * void write_string(uint32_t address, char * data)
 *
 * Write char *
 * @param address start address (uint32_t)
 * @param data char * to write (char *)
  * @return none
*/
void EEPROM::write_string(uint32_t address, char * data)
{
    int8_t cmd[32];
    
    int len = strlen(data);
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address + len)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
//    for (int i = 
    memcpy(cmd,data,len+1);
    
    write_data(address,cmd,len+1);
}

/**
 * void read(uint32_t address, int8_t& data)
 *
 * Random read byte
 * @param address start address (uint32_t)
 * @param data byte to read (int8_t&)
 * @return none
*/
void EEPROM::read_uint8_t(uint32_t address, uint8_t& data)
{
    uint8_t page;
    uint8_t addr;
    uint8_t cmd[2];
    uint8_t len;
    int ack;
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Check address
    if(!checkAddress(address)) {
        _errnum = EEPROM_OutOfRange;
        return;
    }
    
    // Compute page number
    page = 0;
    if(_type < T24C32) {
        page = (uint8_t) (address / 256);
    }
  
    // Device address
    addr = EEPROM_Address | _address | (page << 1);
  
    if(_type < T24C32) {
        len = 1;
        
        // Word address
        cmd[0] = (uint8_t) (address - page * 256);
    }
    else {
        len = 2;
        
        // First word address (MSB)
        cmd[0] = (uint8_t) (address >> 8);
        
        // Second word address (LSB)
        cmd[1] = (uint8_t)address;
    }
    
    // Write command
    ack = _i2c.write((int)addr,(char *)cmd,len,true);
    if(ack != 0) {
        _errnum = EEPROM_I2cError;
        return;
    }
  
    // Read data
    ack = _i2c.read((int)addr,(char *)&data,sizeof(data));
    if(ack != 0) {
        _errnum = EEPROM_I2cError;
    }
}

/**
 * void read(int8_t& data)
 *
 * Current address read byte
 * @param data byte to read (int8_t&)
 * @return none
 */
void EEPROM::read(uint8_t& data)
{
    uint8_t addr;
    int ack;
    
    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Device address
    addr = EEPROM_Address | _address;
    
    // Read data
    ack = _i2c.read((int)addr,(char *)&data,sizeof(data));
    if(ack != 0) {
        _errnum = EEPROM_I2cError;
    }
}

/**
 * int8_t read(uint32_t address, int8_t)
 *
 * Random read byte
 * @param address start address (uint32_t)
 * @return data byte to read (int8_t&)
*/
uint8_t EEPROM::read_uint8_t(uint32_t address)
{
    int8_t cmd[1];
    uint8_t data;

    // wait until ready
    ready();
    
    // Check error
    if(_errnum) {
        return -1;
    }
    
    // Check address
    if(!checkAddress(address + 1)) {
        _errnum = EEPROM_OutOfRange;
        return -1;
    }
    
    read_data_array(address,(uint8_t *)cmd,1);
    
    memcpy(&data,cmd,1);
    return data;
}

/**
 * int16_t read(uint32_t address)
 *
 * Random read short
 * @param address start address (uint32_t)
 * @return data short to read (int16_t&)
*/
uint16_t EEPROM::read_uint16_t(uint32_t address)
{
    int8_t cmd[2];
    uint16_t data;
        
    // wait until ready
    ready();

    // Check error
    if(_errnum) {
        return -1;
    }
    
    // Check address
    if(!checkAddress(address + 1)) {
        _errnum = EEPROM_OutOfRange;
        return -1;
    }
    
    read_data_array(address,(uint8_t *)cmd,2);
    
    memcpy(&data,cmd,2);
    return data;
}

/**
 * int32_t read(uint32_t address)
 *
 * Random read long
 * @param address start address (uint32_t)
 * @return data long to read (int32_t&)
*/
uint32_t EEPROM::read_uint32_t(uint32_t address)
{
    int8_t cmd[4];
    uint32_t data;
    
    // wait until ready
    ready();

    // Check error
    if(_errnum) {
        return -1;
    }
    
    // Check address
    if(!checkAddress(address + 3)) {
        _errnum = EEPROM_OutOfRange;
        return -1;
    }
    
    read_data_array(address,(uint8_t *)cmd,4);
    
    memcpy(&data,cmd,4);
    return data;
}

/**
 * float read(uint32_t address)
 *
 * Random read float
 * @param address start address (uint32_t)
 * @return data float to read (float&)
 */
//void EEPROM::read_float(uint32_t address, float& data)
float EEPROM::read_float(uint32_t address)
{
    int8_t cmd[4];
    float data;
    
    // wait until ready
    ready();

    // Check error
    if(_errnum) {
        return -1.0f;
    }
    
    // Check address
    if(!checkAddress(address + 3)) {
        _errnum = EEPROM_OutOfRange;
        return -1.0f;
    }
    
    read_data_array(address,(uint8_t *)cmd,4);
    
    memcpy(&data,cmd,4);
    return data;
}

/**
 * double read(uint32_t address)
 *
 * Random read double
 * @param address start address (uint32_t)
 * @return data double to read (double&)
 */
//void EEPROM::read_double(uint32_t address, double& data)
double EEPROM::read_double(uint32_t address)
{
    int8_t cmd[8];
    double data;
    
    // wait until ready
    ready();

    // Check error
    if(_errnum) {
        return -1.0f;
    }
    
    // Check address
    if(!checkAddress(address + 7)) {
        _errnum = EEPROM_OutOfRange;
        return -1.0f;
    }
    
    read_data_array(address,(uint8_t *)cmd,8);
    
    memcpy(&data,cmd,8);
    return data;
}

/**
 * double read_string(uint32_t address)
 *
 * Random read char *
 * @param address start address (uint32_t)
 * @return data char * to read (char *&)
 */
char * EEPROM::read_string(uint32_t address)
{
    // wait until ready
    ready();

    // Check error
    if(_errnum) {
        return "";
    }
    
    // Check address
    if(!checkAddress(address + 7)) {
        _errnum = EEPROM_OutOfRange;
        return "";
    }
    int cont = true;
    int i = 0;
    while (cont) {
        buffer[i] = (char)read_uint8_t(address+i);
        if (buffer[i] == 0) {
            cont = false;
        }
        i++;
        if (i >= 32) {
            cont = false;
        }
    }
    return buffer;
}

/**
 * void clear(void)
 *
 * Clear eeprom (write with 0)
 * @param none
 * @return none
 */
void EEPROM::clear(void)
{
  for(uint32_t i = 0; i < _size / 4; i++) {
     write_uint32_t((uint32_t)(i * 4), 0x00000000);  
  }
}

/**
 * void ready(void)
 *
 * Wait eeprom ready
 * @param none
 * @return none
*/
void EEPROM::ready(void)
{
    int ack;
    uint8_t addr;
    uint8_t cmd[2];
    
    // Check error
    if(_errnum) {
        return;
    }
    
    // Device address
    addr = EEPROM_Address | _address;
    
    cmd[0] = 0;
    
    // Wait end of write
    do {
        ack = _i2c.write((int)addr,(char *)cmd,0);
        //wait(0.5);
    } while(ack != 0);
}

/**
 * uint32_t getSize(void)
 *
 * Get eeprom size in bytes
 * @param  none
 * @return size in bytes (uint32_t)
*/
uint32_t EEPROM::getSize(void)
{
    return(_size);
}

/**
 * const char* getName(void)
 *
 * Get eeprom name
 * @param none
 * @return name (const char*)
 */
const char* EEPROM::getName(void)
{
    uint8_t i = 0;
    
    switch(_type) {
        case T24C01 :
            i = 0;
            break;
        case T24C02 :
            i = 1;
            break;
        case T24C04 :
            i = 2;
            break;
        case T24C08 :
            i = 3;
            break;
        case T24C16 :
            i = 4;
            break;
        case T24C32 :
            i = 5; 
            break;
        case T24C64 :
            i = 6;
            break;
        case T24C128 :
            i = 7;
            break;
        case T24C256 :
            i = 8;
            break;
        case T24C512 :
            i = 9;
            break;
        case T24C1024 :
            i = 10;
            break;
        case T24C1025 :
            i = 11;
            break;
    }
  
    return(_name[i]);
}

/**
 * uint8_t getError(void)
 *
 * Get the current error number (EEPROM_NoError if no error)
 * @param none
 * @return none
*/
uint8_t EEPROM::getError(void)
{
    return(_errnum);
}

/**
 * bool checkAddress(uint32_t address)
 *
 * Check if address is in the eeprom range address
 * @param address address to check (uint32_t)
 * @return true if in eeprom range, overwise false (bool)
*/
bool EEPROM::checkAddress(uint32_t address)
{
    bool ret = true;
    
    switch(_type) {
        case T24C01 :
            if(address >= T24C01)
                ret = false;
            break;
        case T24C02 :
            if(address >= T24C02)
                ret = false;
            break;
        case T24C04 :
            if(address >= T24C04)
                ret = false;
            break;
        case T24C08 :
            if(address >= T24C08)
                ret = false;
            break;
        case T24C16 :
            if(address >= T24C16)
                ret = false;
            break;
        case T24C32 :
            if(address >= T24C32)
                ret = false;
            break;
        case T24C64 :
            if(address >= T24C64)
                ret = false;
            break;
        case T24C128 :
            if(address >= T24C128)
                ret = false;
            break;
        case T24C256 :
            if(address >= T24C256)
                ret = false;
            break;
        case T24C512 :
            if(address >= T24C512)
                ret = false;
            break;
        case T24C1024 :
            if(address >= T24C1024)
                ret = false;
            break;
        case T24C1025 :
            if(address >= T24C1025 - 1)
                ret = false;
            break;
    }
    
    return(ret);
}