From f17634478969895d92b062877c04df5e3e90317f Mon Sep 17 00:00:00 2001 From: "joe.dumoulin" Date: Sun, 30 Jul 2017 14:28:05 -0700 Subject: working library with tests. Lacks error tracking. --- examples/m0eepromtest/m0eepromtest.ino | 189 +++++++++++++++++++++++++-------- library.properties | 10 ++ m0EEPROM.cpp | 58 +++++----- m0EEPROM.h | 17 ++- 4 files changed, 203 insertions(+), 71 deletions(-) create mode 100644 library.properties 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; ix = ");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> 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 -- cgit v1.2.3