summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe.dumoulin <joe.dumoulin@gmail.com>2017-07-20 20:21:56 -0700
committerjoe.dumoulin <joe.dumoulin@gmail.com>2017-07-20 20:21:56 -0700
commit801bf60c7911078a94f48c3f3c25b988e8b4ac21 (patch)
treec8b3808ad0c902a17f0114dab3e8e9fc3a0c34cc
first commit
-rw-r--r--examples/m0eepromtest/m0eepromtest.ino104
-rw-r--r--m0EEPROM.cpp128
-rw-r--r--m0EEPROM.h28
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