shortened

Dependents:   CDMS_CODE CDMS_CODE_FM_28JAN2017 CDMS_CODE_FM_28JAN2017 CDMS_FM_21JUL2017_EEPROM_JOEL ... more

Fork of eeprom by bernard borredon

Committer:
chaithanyarss
Date:
Sun Jan 08 14:52:42 2017 +0000
Revision:
5:b65b74065b7f
Parent:
4:0c5b1545007c
some changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bborredon 1:a262173cac81 1
bborredon 0:80245aff63ce 2 #include "eeprom.h"
bborredon 0:80245aff63ce 3
bborredon 0:80245aff63ce 4 #define BIT_SET(x,n) (x=x | (0x01<<n))
bborredon 0:80245aff63ce 5 #define BIT_TEST(x,n) (x & (0x01<<n))
bborredon 0:80245aff63ce 6 #define BIT_CLEAR(x,n) (x=x & ~(0x01<<n))
bborredon 0:80245aff63ce 7
chaithanyarss 4:0c5b1545007c 8 const char * const EEPROM::_name[] = {"24C512"};
bborredon 1:a262173cac81 9
bborredon 3:925096a4c7f0 10 /**
bborredon 3:925096a4c7f0 11 * EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type) : _i2c(sda, scl)
bborredon 3:925096a4c7f0 12 *
bborredon 3:925096a4c7f0 13 * Constructor, initialize the eeprom on i2c interface.
bborredon 3:925096a4c7f0 14 * @param sda sda i2c pin (PinName)
bborredon 3:925096a4c7f0 15 * @param scl scl i2c pin (PinName)
bborredon 3:925096a4c7f0 16 * @param address eeprom address, according to eeprom type (uint8_t)
bborredon 3:925096a4c7f0 17 * @param type eeprom type (TypeEeprom)
bborredon 3:925096a4c7f0 18 * @return none
bborredon 3:925096a4c7f0 19 */
bborredon 0:80245aff63ce 20 EEPROM::EEPROM(PinName sda, PinName scl, uint8_t address, TypeEeprom type) : _i2c(sda, scl)
bborredon 0:80245aff63ce 21 {
bborredon 0:80245aff63ce 22
bborredon 0:80245aff63ce 23 _errnum = EEPROM_NoError;
bborredon 0:80245aff63ce 24 _type = type;
bborredon 0:80245aff63ce 25
bborredon 0:80245aff63ce 26 // Check address range
bborredon 0:80245aff63ce 27 _address = address;
bborredon 0:80245aff63ce 28 switch(type) {
bborredon 0:80245aff63ce 29 case T24C512 :
bborredon 0:80245aff63ce 30 if(address > 3) {
bborredon 0:80245aff63ce 31 _errnum = EEPROM_BadAddress;
bborredon 0:80245aff63ce 32 }
bborredon 0:80245aff63ce 33 _address = _address << 1;
bborredon 0:80245aff63ce 34 _page_write = 128;
bborredon 0:80245aff63ce 35 _page_number = 1;
bborredon 0:80245aff63ce 36 break;
bborredon 0:80245aff63ce 37 }
bborredon 0:80245aff63ce 38
bborredon 0:80245aff63ce 39 // Size in bytes
bborredon 0:80245aff63ce 40 _size = _type;
bborredon 0:80245aff63ce 41
bborredon 0:80245aff63ce 42 // Set I2C frequency
bborredon 0:80245aff63ce 43 _i2c.frequency(400000);
bborredon 3:925096a4c7f0 44
bborredon 0:80245aff63ce 45 }
bborredon 0:80245aff63ce 46
bborredon 3:925096a4c7f0 47 /**
bborredon 3:925096a4c7f0 48 * void write(uint32_t address, int8_t data[], uint32_t length)
bborredon 3:925096a4c7f0 49 *
bborredon 3:925096a4c7f0 50 * Write array of bytes (use the page mode)
bborredon 3:925096a4c7f0 51 * @param address start address (uint32_t)
bborredon 3:925096a4c7f0 52 * @param data bytes array to write (int8_t[])
bborredon 3:925096a4c7f0 53 * @param size number of bytes to write (uint32_t)
bborredon 3:925096a4c7f0 54 * @return none
bborredon 3:925096a4c7f0 55 */
bborredon 1:a262173cac81 56 void EEPROM::write(uint32_t address, int8_t data[], uint32_t length)
bborredon 0:80245aff63ce 57 {
bborredon 0:80245aff63ce 58 uint8_t page;
bborredon 1:a262173cac81 59 uint8_t addr = 0;
bborredon 0:80245aff63ce 60 uint8_t blocs,remain;
bborredon 0:80245aff63ce 61 uint8_t fpart,lpart;
bborredon 0:80245aff63ce 62 uint8_t i,j,ind;
bborredon 0:80245aff63ce 63 uint8_t cmd[129];
bborredon 0:80245aff63ce 64 int ack;
bborredon 3:925096a4c7f0 65
bborredon 0:80245aff63ce 66 // Check error
bborredon 0:80245aff63ce 67 if(_errnum)
bborredon 0:80245aff63ce 68 return;
bborredon 0:80245aff63ce 69
bborredon 0:80245aff63ce 70 // Check address
bborredon 0:80245aff63ce 71 if(!checkAddress(address)) {
bborredon 0:80245aff63ce 72 _errnum = EEPROM_OutOfRange;
bborredon 0:80245aff63ce 73 return;
bborredon 0:80245aff63ce 74 }
bborredon 0:80245aff63ce 75
bborredon 0:80245aff63ce 76 // Check length
bborredon 0:80245aff63ce 77 if(!checkAddress(address + length - 1)) {
bborredon 0:80245aff63ce 78 _errnum = EEPROM_OutOfRange;
bborredon 0:80245aff63ce 79 return;
bborredon 0:80245aff63ce 80 }
bborredon 0:80245aff63ce 81
bborredon 0:80245aff63ce 82 // Compute blocs numbers
bborredon 0:80245aff63ce 83 blocs = length / _page_write;
bborredon 0:80245aff63ce 84
bborredon 0:80245aff63ce 85 // Compute remaining bytes
bborredon 0:80245aff63ce 86 remain = length - blocs * _page_write;
bborredon 3:925096a4c7f0 87
bborredon 0:80245aff63ce 88 for(i = 0;i < blocs;i++) {
bborredon 0:80245aff63ce 89 // Compute page number
bborredon 0:80245aff63ce 90 page = 0;
bborredon 0:80245aff63ce 91
bborredon 0:80245aff63ce 92 // Device address
bborredon 0:80245aff63ce 93 addr = EEPROM_Address | _address | (page << 1);
bborredon 0:80245aff63ce 94
chaithanyarss 4:0c5b1545007c 95 // First word address (MSB)
chaithanyarss 4:0c5b1545007c 96 cmd[0] = (uint8_t) (address >> 8);
bborredon 0:80245aff63ce 97
chaithanyarss 4:0c5b1545007c 98 // Second word address (LSB)
chaithanyarss 4:0c5b1545007c 99 cmd[1] = (uint8_t) address;
bborredon 0:80245aff63ce 100
chaithanyarss 4:0c5b1545007c 101 // Add data
chaithanyarss 4:0c5b1545007c 102 for(j = 0;j < _page_write;j++)
chaithanyarss 4:0c5b1545007c 103 cmd[j + 2] = (uint8_t) data[i * _page_write + j];
bborredon 0:80245aff63ce 104
chaithanyarss 4:0c5b1545007c 105 // Write data
chaithanyarss 4:0c5b1545007c 106 ack = _i2c.write((int)addr,(char *)cmd,_page_write + 2);
chaithanyarss 4:0c5b1545007c 107 if(ack != 0) {
chaithanyarss 4:0c5b1545007c 108 _errnum = EEPROM_I2cError;
chaithanyarss 4:0c5b1545007c 109 return;
chaithanyarss 4:0c5b1545007c 110 }
bborredon 0:80245aff63ce 111
chaithanyarss 4:0c5b1545007c 112 // Wait end of write
chaithanyarss 4:0c5b1545007c 113 ready();
bborredon 0:80245aff63ce 114
chaithanyarss 4:0c5b1545007c 115 // Increment address
chaithanyarss 4:0c5b1545007c 116 address += _page_write;
bborredon 0:80245aff63ce 117 }
bborredon 0:80245aff63ce 118
bborredon 3:925096a4c7f0 119 if(remain) {
bborredon 1:a262173cac81 120 // Compute page number
bborredon 1:a262173cac81 121 page = 0;
bborredon 0:80245aff63ce 122
bborredon 1:a262173cac81 123 // Device address
bborredon 1:a262173cac81 124 addr = EEPROM_Address | _address | (page << 1);
bborredon 0:80245aff63ce 125
chaithanyarss 4:0c5b1545007c 126 // Fist word address (MSB)
chaithanyarss 4:0c5b1545007c 127 cmd[0] = (uint8_t) (address >> 8);
bborredon 1:a262173cac81 128
chaithanyarss 4:0c5b1545007c 129 // Second word address (LSB)
chaithanyarss 4:0c5b1545007c 130 cmd[1] = (uint8_t) address;
chaithanyarss 4:0c5b1545007c 131
chaithanyarss 4:0c5b1545007c 132 // Add data for the current page
chaithanyarss 4:0c5b1545007c 133 for(j = 0;j < remain;j++)
chaithanyarss 4:0c5b1545007c 134 cmd[j + 2] = (uint8_t) data[blocs * _page_write + j];
chaithanyarss 4:0c5b1545007c 135
chaithanyarss 4:0c5b1545007c 136 // Write data for the current page
chaithanyarss 4:0c5b1545007c 137 ack = _i2c.write((int)addr,(char *)cmd,remain + 2);
chaithanyarss 4:0c5b1545007c 138 if(ack != 0) {
chaithanyarss 4:0c5b1545007c 139 _errnum = EEPROM_I2cError;
chaithanyarss 4:0c5b1545007c 140 return;
bborredon 0:80245aff63ce 141 }
bborredon 0:80245aff63ce 142
chaithanyarss 4:0c5b1545007c 143 // Wait end of write
chaithanyarss 4:0c5b1545007c 144 ready();
bborredon 0:80245aff63ce 145 }
bborredon 0:80245aff63ce 146
bborredon 0:80245aff63ce 147 }
bborredon 0:80245aff63ce 148
bborredon 3:925096a4c7f0 149 /**
bborredon 3:925096a4c7f0 150 * void write(uint32_t address, int32_t data)
bborredon 3:925096a4c7f0 151 *
bborredon 3:925096a4c7f0 152 * Write long
bborredon 3:925096a4c7f0 153 * @param address start address (uint32_t)
bborredon 3:925096a4c7f0 154 * @param data long to write (int32_t)
bborredon 3:925096a4c7f0 155 * @return none
bborredon 3:925096a4c7f0 156 */
bborredon 1:a262173cac81 157 void EEPROM::write(uint32_t address, int32_t data)
bborredon 0:80245aff63ce 158 {
bborredon 0:80245aff63ce 159 int8_t cmd[4];
bborredon 3:925096a4c7f0 160
bborredon 0:80245aff63ce 161 // Check error
bborredon 0:80245aff63ce 162 if(_errnum)
bborredon 0:80245aff63ce 163 return;
bborredon 0:80245aff63ce 164
bborredon 0:80245aff63ce 165 // Check address
bborredon 0:80245aff63ce 166 if(!checkAddress(address + 3)) {
bborredon 0:80245aff63ce 167 _errnum = EEPROM_OutOfRange;
bborredon 0:80245aff63ce 168 return;
bborredon 0:80245aff63ce 169 }
bborredon 0:80245aff63ce 170
bborredon 0:80245aff63ce 171 memcpy(cmd,&data,4);
bborredon 0:80245aff63ce 172
bborredon 0:80245aff63ce 173 write(address,cmd,4);
bborredon 0:80245aff63ce 174
bborredon 0:80245aff63ce 175 }
bborredon 0:80245aff63ce 176
bborredon 3:925096a4c7f0 177 /**
bborredon 3:925096a4c7f0 178 * void read(uint32_t address, int8_t *data, uint32_t size)
bborredon 3:925096a4c7f0 179 *
bborredon 3:925096a4c7f0 180 * Sequential read byte
bborredon 3:925096a4c7f0 181 * @param address start address (uint32_t)
bborredon 3:925096a4c7f0 182 * @param data bytes array to read (int8_t[]&)
bborredon 3:925096a4c7f0 183 * @param size number of bytes to read (uint32_t)
bborredon 3:925096a4c7f0 184 * @return none
bborredon 3:925096a4c7f0 185 */
bborredon 1:a262173cac81 186 void EEPROM::read(uint32_t address, int8_t *data, uint32_t size)
bborredon 0:80245aff63ce 187 {
bborredon 0:80245aff63ce 188 uint8_t page;
bborredon 0:80245aff63ce 189 uint8_t addr;
bborredon 0:80245aff63ce 190 uint8_t cmd[2];
bborredon 0:80245aff63ce 191 uint8_t len;
bborredon 0:80245aff63ce 192 int ack;
bborredon 3:925096a4c7f0 193
bborredon 0:80245aff63ce 194 // Check error
bborredon 0:80245aff63ce 195 if(_errnum)
bborredon 0:80245aff63ce 196 return;
bborredon 0:80245aff63ce 197
bborredon 0:80245aff63ce 198 // Check address
bborredon 0:80245aff63ce 199 if(!checkAddress(address)) {
bborredon 0:80245aff63ce 200 _errnum = EEPROM_OutOfRange;
bborredon 0:80245aff63ce 201 return;
bborredon 0:80245aff63ce 202 }
bborredon 0:80245aff63ce 203
bborredon 0:80245aff63ce 204 // Check size
bborredon 0:80245aff63ce 205 if(!checkAddress(address + size - 1)) {
bborredon 0:80245aff63ce 206 _errnum = EEPROM_OutOfRange;
bborredon 0:80245aff63ce 207 return;
bborredon 0:80245aff63ce 208 }
bborredon 0:80245aff63ce 209
bborredon 0:80245aff63ce 210 // Compute page number
bborredon 0:80245aff63ce 211 page = 0;
bborredon 0:80245aff63ce 212
bborredon 0:80245aff63ce 213 // Device address
bborredon 0:80245aff63ce 214 addr = EEPROM_Address | _address | (page << 1);
bborredon 0:80245aff63ce 215
chaithanyarss 4:0c5b1545007c 216 len = 2;
bborredon 0:80245aff63ce 217
chaithanyarss 4:0c5b1545007c 218 // First word address (MSB)
chaithanyarss 4:0c5b1545007c 219 cmd[0] = (uint8_t) (address >> 8);
chaithanyarss 4:0c5b1545007c 220
chaithanyarss 4:0c5b1545007c 221 // Second word address (LSB)
chaithanyarss 4:0c5b1545007c 222 cmd[1] = (uint8_t) address;
bborredon 0:80245aff63ce 223
bborredon 0:80245aff63ce 224 // Write command
bborredon 0:80245aff63ce 225 ack = _i2c.write((int)addr,(char *)cmd,len,true);
bborredon 0:80245aff63ce 226 if(ack != 0) {
bborredon 0:80245aff63ce 227 _errnum = EEPROM_I2cError;
bborredon 0:80245aff63ce 228 return;
bborredon 0:80245aff63ce 229 }
bborredon 0:80245aff63ce 230
bborredon 0:80245aff63ce 231 // Sequential read
bborredon 0:80245aff63ce 232 ack = _i2c.read((int)addr,(char *)data,size);
bborredon 0:80245aff63ce 233 if(ack != 0) {
bborredon 0:80245aff63ce 234 _errnum = EEPROM_I2cError;
bborredon 0:80245aff63ce 235 return;
bborredon 0:80245aff63ce 236 }
bborredon 0:80245aff63ce 237
bborredon 0:80245aff63ce 238 }
bborredon 0:80245aff63ce 239
bborredon 3:925096a4c7f0 240 /**
bborredon 3:925096a4c7f0 241 * void read(uint32_t address, int32_t& data)
bborredon 3:925096a4c7f0 242 *
bborredon 3:925096a4c7f0 243 * Random read long
bborredon 3:925096a4c7f0 244 * @param address start address (uint32_t)
bborredon 3:925096a4c7f0 245 * @param data long to read (int32_t&)
bborredon 3:925096a4c7f0 246 * @return none
bborredon 3:925096a4c7f0 247 */
bborredon 1:a262173cac81 248 void EEPROM::read(uint32_t address, int32_t& data)
bborredon 0:80245aff63ce 249 {
bborredon 0:80245aff63ce 250 int8_t cmd[4];
bborredon 3:925096a4c7f0 251
bborredon 0:80245aff63ce 252 // Check error
bborredon 0:80245aff63ce 253 if(_errnum)
bborredon 0:80245aff63ce 254 return;
bborredon 0:80245aff63ce 255
bborredon 0:80245aff63ce 256 // Check address
bborredon 0:80245aff63ce 257 if(!checkAddress(address + 3)) {
bborredon 0:80245aff63ce 258 _errnum = EEPROM_OutOfRange;
bborredon 0:80245aff63ce 259 return;
bborredon 0:80245aff63ce 260 }
bborredon 0:80245aff63ce 261
bborredon 0:80245aff63ce 262 read(address,cmd,4);
bborredon 0:80245aff63ce 263
bborredon 0:80245aff63ce 264 memcpy(&data,cmd,4);
bborredon 0:80245aff63ce 265
bborredon 0:80245aff63ce 266 }
bborredon 0:80245aff63ce 267
bborredon 3:925096a4c7f0 268 /**
bborredon 3:925096a4c7f0 269 * void clear(void)
bborredon 3:925096a4c7f0 270 *
bborredon 3:925096a4c7f0 271 * Clear eeprom (write with 0)
bborredon 3:925096a4c7f0 272 * @param none
bborredon 3:925096a4c7f0 273 * @return none
bborredon 3:925096a4c7f0 274 */
bborredon 1:a262173cac81 275 void EEPROM::clear(void)
bborredon 1:a262173cac81 276 {
bborredon 1:a262173cac81 277 int32_t data;
bborredon 1:a262173cac81 278 uint32_t i;
bborredon 1:a262173cac81 279
bborredon 1:a262173cac81 280 data = 0;
bborredon 1:a262173cac81 281
bborredon 1:a262173cac81 282 for(i = 0; i < _size / 4;i++) {
bborredon 1:a262173cac81 283 write((uint32_t)(i * 4),data);
bborredon 1:a262173cac81 284 }
bborredon 1:a262173cac81 285 }
bborredon 1:a262173cac81 286
bborredon 3:925096a4c7f0 287 /**
bborredon 3:925096a4c7f0 288 * void ready(void)
bborredon 3:925096a4c7f0 289 *
bborredon 3:925096a4c7f0 290 * Wait eeprom ready
bborredon 3:925096a4c7f0 291 * @param none
bborredon 3:925096a4c7f0 292 * @return none
bborredon 3:925096a4c7f0 293 */
bborredon 0:80245aff63ce 294 void EEPROM::ready(void)
bborredon 0:80245aff63ce 295 {
bborredon 0:80245aff63ce 296 int ack;
bborredon 0:80245aff63ce 297 uint8_t addr;
bborredon 1:a262173cac81 298 uint8_t cmd[2];
bborredon 0:80245aff63ce 299
bborredon 0:80245aff63ce 300 // Check error
bborredon 0:80245aff63ce 301 if(_errnum)
bborredon 0:80245aff63ce 302 return;
bborredon 0:80245aff63ce 303
bborredon 0:80245aff63ce 304 // Device address
bborredon 0:80245aff63ce 305 addr = EEPROM_Address | _address;
bborredon 0:80245aff63ce 306
bborredon 1:a262173cac81 307 cmd[0] = 0;
bborredon 0:80245aff63ce 308
bborredon 0:80245aff63ce 309 // Wait end of write
bborredon 0:80245aff63ce 310 do {
bborredon 0:80245aff63ce 311 ack = _i2c.write((int)addr,(char *)cmd,0);
bborredon 1:a262173cac81 312 //wait(0.5);
bborredon 0:80245aff63ce 313 } while(ack != 0);
bborredon 0:80245aff63ce 314
bborredon 0:80245aff63ce 315 }
bborredon 0:80245aff63ce 316
bborredon 3:925096a4c7f0 317 /**
bborredon 3:925096a4c7f0 318 * uint32_t getSize(void)
bborredon 3:925096a4c7f0 319 *
bborredon 3:925096a4c7f0 320 * Get eeprom size in bytes
bborredon 3:925096a4c7f0 321 * @param none
bborredon 3:925096a4c7f0 322 * @return size in bytes (uint32_t)
bborredon 3:925096a4c7f0 323 */
bborredon 0:80245aff63ce 324 uint32_t EEPROM::getSize(void)
bborredon 0:80245aff63ce 325 {
bborredon 0:80245aff63ce 326 return(_size);
bborredon 0:80245aff63ce 327 }
bborredon 0:80245aff63ce 328
bborredon 3:925096a4c7f0 329 /**
bborredon 3:925096a4c7f0 330 * const char* getName(void)
bborredon 3:925096a4c7f0 331 *
bborredon 3:925096a4c7f0 332 * Get eeprom name
bborredon 3:925096a4c7f0 333 * @param none
bborredon 3:925096a4c7f0 334 * @return name (const char*)
bborredon 3:925096a4c7f0 335 */
bborredon 1:a262173cac81 336 const char* EEPROM::getName(void)
bborredon 1:a262173cac81 337 {
bborredon 1:a262173cac81 338 uint8_t i = 0;
bborredon 1:a262173cac81 339
bborredon 1:a262173cac81 340 switch(_type) {
chaithanyarss 4:0c5b1545007c 341 case T24C512 :
bborredon 1:a262173cac81 342 i = 0;
bborredon 1:a262173cac81 343 break;
bborredon 1:a262173cac81 344 }
bborredon 1:a262173cac81 345
bborredon 1:a262173cac81 346 return(_name[i]);
bborredon 1:a262173cac81 347 }
bborredon 1:a262173cac81 348
bborredon 3:925096a4c7f0 349 /**
bborredon 3:925096a4c7f0 350 * uint8_t getError(void)
bborredon 3:925096a4c7f0 351 *
bborredon 3:925096a4c7f0 352 * Get the current error number (EEPROM_NoError if no error)
bborredon 3:925096a4c7f0 353 * @param none
bborredon 3:925096a4c7f0 354 * @return none
bborredon 3:925096a4c7f0 355 */
bborredon 0:80245aff63ce 356 uint8_t EEPROM::getError(void)
bborredon 0:80245aff63ce 357 {
bborredon 0:80245aff63ce 358 return(_errnum);
bborredon 0:80245aff63ce 359 }
bborredon 0:80245aff63ce 360
bborredon 3:925096a4c7f0 361 /**
bborredon 3:925096a4c7f0 362 * bool checkAddress(uint32_t address)
bborredon 3:925096a4c7f0 363 *
bborredon 3:925096a4c7f0 364 * Check if address is in the eeprom range address
bborredon 3:925096a4c7f0 365 * @param address address to check (uint32_t)
bborredon 3:925096a4c7f0 366 * @return true if in eeprom range, overwise false (bool)
bborredon 3:925096a4c7f0 367 */
bborredon 1:a262173cac81 368 bool EEPROM::checkAddress(uint32_t address)
bborredon 0:80245aff63ce 369 {
bborredon 0:80245aff63ce 370 bool ret = true;
bborredon 0:80245aff63ce 371
bborredon 0:80245aff63ce 372 switch(_type) {
bborredon 0:80245aff63ce 373 case T24C512 :
bborredon 0:80245aff63ce 374 if(address >= T24C512)
bborredon 0:80245aff63ce 375 ret = false;
bborredon 0:80245aff63ce 376 break;
bborredon 0:80245aff63ce 377 }
bborredon 0:80245aff63ce 378
bborredon 0:80245aff63ce 379 return(ret);
bborredon 1:a262173cac81 380 }