shortened

Dependents:   CDMS_CODE CDMS_CODE_FM_28JAN2017 CDMS_CODE_FM_28JAN2017 CDMS_FM_21JUL2017_EEPROM_JOEL ... more

Fork of eeprom by bernard borredon

eeprom.cpp

Committer:
chaithanyarss
Date:
2017-01-08
Revision:
5:b65b74065b7f
Parent:
4:0c5b1545007c

File content as of revision 5:b65b74065b7f:


#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[] = {"24C512"};

/**
 * 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) 
{
  
  _errnum = EEPROM_NoError;
  _type = type;
  
  // Check address range
  _address = address;
  switch(type) {
                 case T24C512 :
                    if(address > 3) {
                      _errnum = EEPROM_BadAddress;
                    }
                    _address = _address << 1;
                    _page_write = 128;
                    _page_number = 1;
                    break;
  }
  
  // Size in bytes
  _size = _type;
  
  // 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(uint32_t address, int8_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;
    
  // 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;
  
     // Device address
     addr = EEPROM_Address | _address | (page << 1);
  
     // 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;
  
    // Device address
    addr = EEPROM_Address | _address | (page << 1);
  
    // 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 write(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 address, int32_t data)
{
  int8_t cmd[4];
    
  // Check error
  if(_errnum) 
    return;
    
  // Check address
  if(!checkAddress(address + 3)) {
    _errnum = EEPROM_OutOfRange;
    return;
  }
  
  memcpy(cmd,&data,4);
  
  write(address,cmd,4);
  
}

/**
 * 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(uint32_t address, int8_t *data, uint32_t size)
{
  uint8_t page;
  uint8_t addr;
  uint8_t cmd[2];
  uint8_t len;
  int ack;
    
  // 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;
  
  // Device address
  addr = EEPROM_Address | _address | (page << 1);
  
  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 read(uint32_t address, int32_t& data)
 *
 * Random read long
 * @param address start address (uint32_t)
 * @param data long to read (int32_t&)
 * @return none
*/
void EEPROM::read(uint32_t address, int32_t& data)
{
  int8_t cmd[4];
    
  // Check error
  if(_errnum) 
    return;
    
  // Check address
  if(!checkAddress(address + 3)) {
    _errnum = EEPROM_OutOfRange;
    return;
  }
 
  read(address,cmd,4);
  
  memcpy(&data,cmd,4);
  
}

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

/**
 * 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 T24C512 :
                                         i = 0;
                     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 T24C512 :
                     if(address >= T24C512)
                       ret = false;
                     break;
  }
  
  return(ret);
}