shortened
Dependents: CDMS_CODE CDMS_CODE_FM_28JAN2017 CDMS_CODE_FM_28JAN2017 CDMS_FM_21JUL2017_EEPROM_JOEL ... more
Fork of eeprom by
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); }