summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/m0eepromtest/m0eepromtest.ino189
-rw-r--r--library.properties10
-rw-r--r--m0EEPROM.cpp58
-rw-r--r--m0EEPROM.h17
4 files changed, 203 insertions, 71 deletions
diff --git a/examples/m0eepromtest/m0eepromtest.ino b/examples/m0eepromtest/m0eepromtest.ino
index 52b1f6b..d4547e9 100644
--- a/examples/m0eepromtest/m0eepromtest.ino
+++ b/examples/m0eepromtest/m0eepromtest.ino
@@ -1,9 +1,20 @@
// m0eepromtest.ino - some simple tests of the m0eeprom library
-#include "m0eeprom.h"
+#include "m0EEPROM.h"
uint8_t rdata[32];
+// prototypes
+//void read_after_reset();
+void test_simple_read_write_one_byte();
+void test_simple_read_write_two_bytes();
+void test_write_one_byte_doesnt_erase_second_byte_in_memory();
+void test_write_and_read_a_string();
+void test_multiple_string_writes_over_page_boundaries();
+void test_multiple_string_writes_over_page_boundaries(uint32_t offset);
+void write_an_arbitrary_structure_to_eeprom();
+void clear_eeprom_bytes(uint16_t offset);
+
void setup(void)
{
Serial.begin(9600);
@@ -11,37 +22,145 @@ void setup(void)
delay( 1 );
}
Serial.flush();
+ Eeprom.begin();
+
+// read_after_reset();
+ clear_eeprom_bytes(0x40);
+ test_simple_read_write_one_byte();
+ test_simple_read_write_two_bytes();
+ test_write_one_byte_doesnt_erase_second_byte_in_memory();
+ test_write_and_read_a_string();
+
+ // offset for write start = 0
+ test_multiple_string_writes_over_page_boundaries();
+ // offset for write start = 27
+ test_multiple_string_writes_over_page_boundaries(27);
+ write_an_arbitrary_structure_to_eeprom();
- Wire.begin();
+}
- size_t i;
- // define large string of data to be written
- cleareeprom();
+void loop(){
+}
+
+/* start tests */
+// two one-byte reads to be used after a reset to ensure that eeprom is stable.
+// enable after you run tests once.
+/*
+void read_after_reset() {
+ unsigned int address = 0;
+ Serial.println("read_after_reset begin");
+ Serial.println(Eeprom.read_byte(address), DEC);
+ Serial.println(Eeprom.read_byte(address+1), DEC);
+
+ Serial.println("read_after_reset end");
+}
+*/
+void test_simple_read_write_one_byte() {
+ unsigned int address = 0x40;
+ Serial.println("test_simple_read_write_one_byte begin");
+// Eeprom.write_byte(address, 0);
+ uint8_t w = 123;
+ Eeprom.write_byte(address, w);
+
+ Serial.println(Eeprom.read_byte(address), DEC);
+ Serial.println("test_simple_read_write_one_byte end");
+}
+
+void test_simple_read_write_two_bytes() {
+ unsigned int address = 0;
+ Serial.println("test_simple_read_write_two_bytes begin");
+ Eeprom.write_byte(address, (uint8_t) 123);
+ Eeprom.write_byte(address+1, 66);
+
+ Serial.println(Eeprom.read_byte(address), DEC);
+ Serial.println(Eeprom.read_byte(address+1), DEC);
+
+ Serial.println("test_simple_read_write_two_bytes end");
+}
+
+// The second byte in memory is preserved here
+void test_write_one_byte_doesnt_erase_second_byte_in_memory() {
+ uint16_t address = 0;
+ Serial.println("test_write_one_byte_doesnt_erase_second_byte_in_memory begin");
+ Eeprom.write_byte(address, 123);
+ Eeprom.write_byte(address+1, 66);
+
+ Eeprom.write_byte(address, 1);
+
+ Serial.println(Eeprom.read_byte(address), DEC);
+ Serial.println(Eeprom.read_byte(address+1), DEC);
+
+ Serial.println("test_write_one_byte_doesnt_erase_second_byte_in_memory end");
+
+}
+
+void test_write_and_read_a_string() {
+ char p[] = "Once again.";
+ uint16_t psize = strlen(p)+1;
+ uint8_t recv[psize]; // where to put the result
+ uint16_t address = 0;
+ Serial.println("test_write_and_read_a_string begin");
+
+ Serial.println(p);
+ uint8_t* rp = (uint8_t*)p;
+
+ for (uint8_t i=0; i<psize; i++) {
+ Serial.print(rp[i], HEX);
+ }
+ Serial.println();
+
+ Eeprom.write_bytes(address, rp, psize);
+ uint8_t* r = Eeprom.read_bytes(address, recv, psize);
+
+ if (r != 0) {
+ // Serial.println("error");
+ Serial.print((char*)r);Serial.println();
+ }
+
+
+ for (uint8_t i=0; i<psize; i++) {
+ Serial.print(recv[i], HEX);
+ }
+ Serial.println();
+
+ Serial.println((char*)recv);
+ Serial.println("test_write_and_read_a_string end");
+}
+
+void test_multiple_string_writes_over_page_boundaries(){
+ test_multiple_string_writes_over_page_boundaries(0);
+}
+
+void test_multiple_string_writes_over_page_boundaries(uint32_t offset){
+ size_t i = 0;
+
+ // define large string of data to be written
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]);
+ Serial.print("string length = "); Serial.println(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);
+ for (i=0;i<10;i++) Eeprom.write_bytes(i*str_len+offset,(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);
+ Eeprom.read_bytes((i*28)+offset, rdata, 28);
Serial.write(rdata,28);
}
+}
-// write a structure
+void write_an_arbitrary_structure_to_eeprom(){
+ // write a structure
typedef
struct Foo {
int x;
float f;
char c;
- char s[10];
+ char s[10] = {0};
} Foo;
Foo foo;
@@ -51,29 +170,14 @@ void setup(void)
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();
+ Serial.print("sizeof(foo) = ");Serial.print(len);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);
+
+ Eeprom.write_bytes(0,p, len);
+ Eeprom.read_bytes(0, rdbuf, len);
Foo* bar = (Foo*) &rdbuf;
Serial.print("bar->x = ");Serial.print(bar->x);Serial.println();
@@ -84,21 +188,22 @@ void setup(void)
// 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();
+ 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]);
+void clear_eeprom_bytes(uint16_t offset){
+ // write zeros for 10 bytes starting at offset.
+ Serial.println("clear_eeprom_bytes begin");
+ uint8_t buff[10] = {0};
+ Eeprom.write_bytes(offset, buff, 10);
- // 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);
+ uint8_t read_buff[10];
+ Eeprom.read_bytes(offset, read_buff, 10);
+ Serial.println((byte) read_buff[1], DEC);
+ Serial.println("clear_eeprom_bytes end");
-}
-
-void loop(){
+
}
diff --git a/library.properties b/library.properties
new file mode 100644
index 0000000..6a90a95
--- /dev/null
+++ b/library.properties
@@ -0,0 +1,10 @@
+name=m0EEPROM
+version=0.1.0
+author=Joe Dumoulin
+maintainer=Joe Dumoulin
+sentence=External eeprom management for samd21
+paragraph=External eeprom management for samd21
+category=Uncategorized
+url=
+architectures=samd
+
diff --git a/m0EEPROM.cpp b/m0EEPROM.cpp
index 10761a7..306e017 100644
--- a/m0EEPROM.cpp
+++ b/m0EEPROM.cpp
@@ -5,7 +5,7 @@
#include "Wire.h"
#include "RingBuffer.h" // for SERIAL_BUFFER_SIZE
-#include "m0EEPROM.h
+#include "m0EEPROM.h"
#define PAGE_SIZE 64 // page size of the 24LC256 in bytes
@@ -23,7 +23,7 @@ uint8_t eeprom::read_byte(uint16_t address) {
Wire.beginTransmission(_device_address);
Wire.write((int)(address >> 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
-
+ Wire.endTransmission();
Wire.requestFrom(_device_address,1);
if (Wire.available()) rdata = Wire.read();
@@ -39,10 +39,15 @@ void eeprom::write_byte(uint16_t address, uint8_t value) {
Wire.write((int)(address >> 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
- Wire.write(data);
+ size_t wresult = Wire.write((int)value);
+ if (wresult == 0){
+// Serial.print("wire write error = "); Serial.println(wresult);
+ }
- Wire.endTransmission();
-
+ uint8_t result = Wire.endTransmission();
+ if (result){
+// Serial.print("wire endTransmission error = "); Serial.println(result);
+ }
delay(6); // at least 5ms for quiescence
}
@@ -50,58 +55,57 @@ void eeprom::write_byte(uint16_t address, uint8_t value) {
// 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) {
+uint8_t* eeprom::read_bytes(uint16_t 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.beginTransmission(_device_address);
+ Wire.write((int)(address >> 8)); // MSB
+ Wire.write((int)(address & 0xFF)); // LSB
Wire.endTransmission();
- Wire.requestFrom(deviceaddress,num_chars);
+ Wire.requestFrom(_device_address, size);
while(Wire.available()) data[i++] = Wire.read();
+ return data;
}
// write a structure of arbitrary size to memory at address.
-// the size of the structure must be less than 64K-address.
+// the size of the structure must be less than 64K-address - start_address.
// The structure is passed as a byte array.
-void eeprom::write_bytes(uint16_t address, uint8_t* data, uint16_t size) {
+void eeprom::write_bytes(uint16_t start_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;
+ uint32_t first_page_size;
unsigned int num_writes;
-// unsigned int data_len=0;
- unsigned char first_write_size;
- unsigned char last_write_size;
- unsigned char write_size;
+ uint8_t first_write_size=0;
+ uint8_t last_write_size=0;
+ uint16_t write_size=0;
// 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;
+ uint8_t page_bits = log2uint(PAGE_SIZE);
+ first_page_size = ((start_address >> page_bits) +1) * PAGE_SIZE - start_address;
// 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_page_size > SERIAL_BUFFER_SIZE){
+ first_write_size = first_page_size - (first_page_size >> buffer_bits) * SERIAL_BUFFER_SIZE;
if (first_write_size == 0) first_write_size = SERIAL_BUFFER_SIZE;
}
else
- first_write_size = first_page;
+ first_write_size = first_page_size;
// 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;
+ num_writes = ((size - first_write_size) >> (buffer_bits)) + 2;
}
else
num_writes = 1;
// Write loop
+ uint16_t address = start_address;
uint8_t i = 0;
for (uint32_t page = 0; page < num_writes; ++page){
if(page==0)
@@ -121,8 +125,8 @@ void eeprom::write_bytes(uint16_t address, uint8_t* data, uint16_t size) {
address += write_size;
delay(6); // needs 5ms for page write
+ }
}
-
-
+eeprom Eeprom;
diff --git a/m0EEPROM.h b/m0EEPROM.h
index 8f58942..870b7e6 100644
--- a/m0EEPROM.h
+++ b/m0EEPROM.h
@@ -1,11 +1,22 @@
// m0EEPROM.h - definitions for 24LC256 EEPROM read and write for m0 SAMD21G18 and adafruit feather
+/* The test code has a bunch of examples of usage.
+*
+* Note that when using multibyte reads or writes, both the SERIAL_BUFFER_SIZE and the PAGE_SIZE are
+* _assumed_ to be powers of 2.
+*/
#ifndef M0EEPROM_H
#define M0EEPROM_H
+#include "Wire.h"
+
class eeprom {
int _device_address; // chip address. currently only supporting one
public:
- begin(device_address=0x50) : _device_address(device_address){}
+ void begin(int device_address=0x50)
+ {
+ _device_address = device_address;
+ Wire.begin();
+ }
// read a byte from the specified address in eeprom memory
uint8_t read_byte(uint16_t address);
@@ -22,7 +33,9 @@ public:
// 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);`
+ void write_bytes(uint16_t address, uint8_t* data, uint16_t size);
};
+extern eeprom Eeprom;
+
#endif // M0EEPROM_H