diff options
| author | joe.dumoulin <joe.dumoulin@gmail.com> | 2017-07-20 20:21:56 -0700 |
|---|---|---|
| committer | joe.dumoulin <joe.dumoulin@gmail.com> | 2017-07-20 20:21:56 -0700 |
| commit | 801bf60c7911078a94f48c3f3c25b988e8b4ac21 (patch) | |
| tree | c8b3808ad0c902a17f0114dab3e8e9fc3a0c34cc | |
first commit
| -rw-r--r-- | examples/m0eepromtest/m0eepromtest.ino | 104 | ||||
| -rw-r--r-- | m0EEPROM.cpp | 128 | ||||
| -rw-r--r-- | m0EEPROM.h | 28 |
3 files changed, 260 insertions, 0 deletions
diff --git a/examples/m0eepromtest/m0eepromtest.ino b/examples/m0eepromtest/m0eepromtest.ino new file mode 100644 index 0000000..52b1f6b --- /dev/null +++ b/examples/m0eepromtest/m0eepromtest.ino @@ -0,0 +1,104 @@ +// m0eepromtest.ino - some simple tests of the m0eeprom library + +#include "m0eeprom.h" + +uint8_t rdata[32]; + +void setup(void) +{ + Serial.begin(9600); + while ( ! Serial ) { + delay( 1 ); + } + Serial.flush(); + + Wire.begin(); + + size_t i; + // define large string of data to be written + cleareeprom(); + + char str_data[]={"Hello-1234567890-and-abcdefghijklmnopqrstuvwxyz-Goodbye\n"}; + size_t str_len = strlen(str_data); + // Work out length of data +// char str_len=0; +// do{ str_len++; } while(str_data[str_len]); + + // Write out data several times consecutively starting at address 0 + for(i=0;i<WRITE_CNT;i++) writeEEPROM(eeprom1,i*str_len,(uint8_t*)str_data, str_len); + + // read back the data 28 bytes at a time + // reading data doesn't suffer from the page boundary rules + Serial.println("DATA READ"); + for(i=0;i<20;i++) { + readEEPROM(eeprom1, (i*28), rdata, 28); + Serial.write(rdata,28); + } + +// write a structure + typedef + struct Foo { + int x; + float f; + char c; + char s[10]; + } Foo; + Foo foo; + + foo.x = 61200; + foo.f = 9e7; + foo.c = 'a'; + strcpy(foo.s, "Hello"); + + size_t len = sizeof(foo); + Serial.print("sizeof(foo) = ");Serial.print(sizeof(foo));Serial.println(); + Serial.print("sizeof(int) = ");Serial.print(sizeof(int));Serial.println(); + Serial.print("sizeof(float) = ");Serial.print(sizeof(float));Serial.println(); + + char hexchr[2]; // for printing + uint8_t rdbuf[len]; + for (int j=0; j<len; j++) rdbuf[j]=0; + for (int j=0; j<len; j++) { + sprintf(hexchr, "%02X", rdbuf[j]); + Serial.print(hexchr); + } + Serial.println(); + + // some debugging + uint8_t* p = (uint8_t*)&foo; + for (int j=0; j<len; j++) { + sprintf(hexchr, "%02X", p[j]); + Serial.print(hexchr); + } + Serial.println(); + + writeEEPROM(eeprom1,1000,p, len); + readEEPROM(eeprom1,1000, rdbuf, len); + + Foo* bar = (Foo*) &rdbuf; + Serial.print("bar->x = ");Serial.print(bar->x);Serial.println(); + Serial.print("bar->f = ");Serial.print(bar->f);Serial.println(); + Serial.print("bar->c = ");Serial.print(bar->c);Serial.println(); + Serial.print("bar->s = ");Serial.print(bar->s);Serial.println(); + + // print rdbuf size + for (size_t i = 0; i < len; ++i){ + sprintf(hexchr, "%02X", rdbuf[i]); + Serial.print("rdbuf[");Serial.print(i);Serial.print("] = ");Serial.print(hexchr);Serial.println(); + } +} + +void cleareeprom() { + char Clear[] ={"000000000000000000000000000000000000000000000000000000000000000"}; + // Work out length of data + char str_len=0; + do{ str_len++; } while(Clear[str_len]); + + // Write out data several times consecutively starting at address 0 + for(size_t i=0;i<WRITE_CNT;i++) writeEEPROM(eeprom1,i*str_len,(uint8_t*)Clear, str_len); + +} + +void loop(){ +} + diff --git a/m0EEPROM.cpp b/m0EEPROM.cpp new file mode 100644 index 0000000..10761a7 --- /dev/null +++ b/m0EEPROM.cpp @@ -0,0 +1,128 @@ +// m0EEPROM.cpp - implementation of eeprom memory library +// + +#include "Arduino.h" +#include "Wire.h" +#include "RingBuffer.h" // for SERIAL_BUFFER_SIZE + +#include "m0EEPROM.h + +#define PAGE_SIZE 64 // page size of the 24LC256 in bytes + +// get the uint log based 2 of the number. +uint8_t log2uint(uint32_t v) { + uint32_t z = 0; + while (v >>=1) z++; + return z; +} + +// read a byte from the specified address in eeprom memory +uint8_t eeprom::read_byte(uint16_t address) { + uint8_t rdata = 0xFF; + + Wire.beginTransmission(_device_address); + Wire.write((int)(address >> 8)); // MSB + Wire.write((int)(address & 0xFF)); // LSB + + Wire.requestFrom(_device_address,1); + + if (Wire.available()) rdata = Wire.read(); + + return rdata; + +} + +// write a single byte of data to the given address in eeprom memory +void eeprom::write_byte(uint16_t address, uint8_t value) { + Wire.beginTransmission(_device_address); + + Wire.write((int)(address >> 8)); // MSB + Wire.write((int)(address & 0xFF)); // LSB + + Wire.write(data); + + Wire.endTransmission(); + + delay(6); // at least 5ms for quiescence +} + +// read a structure of arbitrary size from address. +// the size of the structure must be less than 64K-address. +// returns a byte array of memory specified. The byte array data +// must be preallocated to the expected size. +uint8_t* eeprom::read_bytes(uint16_t start_address, uint8_t* data, uint16_t size) { + unsigned char i=0; + Wire.beginTransmission(deviceaddress); + Wire.write((int)(eeaddress >> 8)); // MSB + Wire.write((int)(eeaddress & 0xFF)); // LSB + Wire.endTransmission(); + + Wire.requestFrom(deviceaddress,num_chars); + + while(Wire.available()) data[i++] = Wire.read(); + +} + +// write a structure of arbitrary size to memory at address. +// the size of the structure must be less than 64K-address. +// The structure is passed as a byte array. +void eeprom::write_bytes(uint16_t address, uint8_t* data, uint16_t size) { + // Uses Page Write for 24LC256 + // Allows for EEPROM_PAGE_SIZE byte page boundary + // Splits string into max BUFFER_SIZE byte writes +// uint8_t counter=0; + unsigned int address; + uint32_t first_page_len; + unsigned int num_writes; +// unsigned int data_len=0; + unsigned char first_write_size; + unsigned char last_write_size; + unsigned char write_size; + + // get the amount of memory to write in the first page of eeprom + uint8_t page_bits = log2uint(EEPROM_PAGE_SIZE); + first_page = ((start_address >> page_bits) +1) * EEPROM_PAGE_SIZE -startaddress; + + // get the size of the first write based on the I2C buffer size + uint8_t buffer_bits = log2uint(SERIAL_BUFFER_SIZE); + if (first_page > SERIAL_BUFFER_SIZE){ + first_write_size = first_page - (first_page >> buffer_bits) * SERIAL_BUFFER_SIZE; + if (first_write_size == 0) first_write_size = SERIAL_BUFFER_SIZE; + } + else + first_write_size = first_page; + + // now get the size of the last write in the final page + // and the total number of pages to write. + if (size > first_write_size){ + last_write_size = (size - first_write_size) % SERIAL_BUFFER_SIZE; + num_writes = ((data_len - first_write_size) >> (buffer_bits)) + 2; + } + else + num_writes = 1; + + // Write loop + uint8_t i = 0; + for (uint32_t page = 0; page < num_writes; ++page){ + if(page==0) + write_size = first_write_size; + else if (page == (num_writes-1)) + write_size = last_write_size; + else write_size = SERIAL_BUFFER_SIZE; + + // I2C handshake and comms happens here + Wire.beginTransmission(_device_address); + Wire.write((int)((address) >> 8)); // MSB + Wire.write((int)((address) & 0xFF)); // LSB + for (uint8_t counter=0; counter<write_size; ++counter,++i){ + Wire.write(data[i]); + } + Wire.endTransmission(); + address += write_size; + + delay(6); // needs 5ms for page write +} + + + + diff --git a/m0EEPROM.h b/m0EEPROM.h new file mode 100644 index 0000000..8f58942 --- /dev/null +++ b/m0EEPROM.h @@ -0,0 +1,28 @@ +// m0EEPROM.h - definitions for 24LC256 EEPROM read and write for m0 SAMD21G18 and adafruit feather +#ifndef M0EEPROM_H +#define M0EEPROM_H + +class eeprom { + int _device_address; // chip address. currently only supporting one +public: + begin(device_address=0x50) : _device_address(device_address){} + + // read a byte from the specified address in eeprom memory + uint8_t read_byte(uint16_t address); + + // write a single byte of data to the given address in eeprom memory + void write_byte(uint16_t address, uint8_t value); + + // read a structure of arbitrary size from address. + // the size of the structure must be less than 64K-address. + // returns a byte array of memory specified. The byte array data + // must be preallocated to the expected size. + uint8_t* read_bytes(uint16_t address, uint8_t* data, uint16_t size); + + // write a structure of arbitrary size to memory at address. + // the size of the structure must be less than 64K-address. + // The structure is passed as a byte array. + void write_bytes(uint16_t address, uint8_t* data, uint16_t size);` +}; + +#endif // M0EEPROM_H |
