westfw:
You could use function overloading...
I thought for overloading to work the argument lists must be distinguishable from one another. What I'm thinking is the same argument types (addresses & length) for any of the allowable types.
westfw:
Note that you're being non-standard; memcmp() is a very old and very standardize function that is well defined to compare byte strings. There won't be any speed difference; both EEPROM and RAM are byte-wide and can only actually fetch one byte at a time.
Yes, I understand. That's why the iterator in the loop which calls eeprom_read_byte must vary according to the caller's type.
My latest effort:
.ino
/*
Attempt to duplicate memcmp_P but for EEPROM
V1.6 accomodate 1-byte, 2-byte, and 4-byte arguments and
is converted to library format
https://www.avrfreaks.net/forum/tut-c-using-eeprom-memory-avr-gcc
*/
#include "memcmp_E.h"
void setup() {
Serial.begin(9600);
// ram_data[] based on combo lock code starting at 0020d 12/6/18
byte ram_data[] = {1, 7, 3, 1, 9, 5};
// EEPROM data = 1, 7, 3, 1, 9, 0
int EEPROM_addr = 20;
// compare bytes
if ((memcmp_E(ram_data, EEPROM_addr, 6))) Serial.print("Data mismatch \n");
else Serial.print("Data matches \n");
//
if ((memcmp_E(ram_data, EEPROM_addr, 5))) Serial.print("Data mismatch \n");
else Serial.print("Data matches \n");
// compare words
Serial.print("\n\n");
if (memcmp_EW(ram_data, EEPROM_addr, 2)) Serial.println("word mismatch");
else Serial.print("word match\n");
if (memcmp_EW(ram_data, EEPROM_addr, 3)) Serial.println("word mismatch");
else Serial.print("word match\n");
// compare doubles
Serial.print("\n\n");
if (memcmp_ED(ram_data, EEPROM_addr, 1)) Serial.println("double mismatch");
else Serial.print("double match\n");
if (memcmp_ED(ram_data, EEPROM_addr, 2)) Serial.println("double mismatch");
else Serial.print("double match\n");
}
void loop() {}
.cpp
/*
Operates like memcmp_P but works in the EEPROM space.
V1.6
https://www.avrfreaks.net/forum/tut-c-using-eeprom-memory-avr-gcc
*/
#include "memcmp_E.h"
#include <avr/eeprom.h>
// Compares n bytes of EEPROM with RAM variable.
// Caller provides:
// RAM address, EEPROM address, number of elements to test
// Function exits on first mismatch.
// Returns false if all bytes match, true if any mismatch detected.
//
bool memcmp_E(uint8_t* ramAddr, uint16_t EE_addr, uint8_t len) {
for (int i = 0; i < len; i++) {
uint8_t EE_data = eeprom_read_byte((uint8_t*)EE_addr++);
if (*ramAddr++ - EE_data != 0)
return true;
}
return false;
};
bool memcmp_EW(uint8_t* ramAddr, uint16_t EE_addr, uint8_t len) {
for (int i = 0; i < len*2; i++) {
uint8_t EE_data = eeprom_read_byte((uint8_t*)EE_addr++);
if (*ramAddr++ - EE_data != 0)
return true;
}
return false;
};
bool memcmp_ED(uint8_t* ramAddr, uint16_t EE_addr, uint8_t len) {
for (int i = 0; i < len*4; i++) {
uint8_t EE_data = eeprom_read_byte((uint8_t*)EE_addr++);
if (*ramAddr++ - EE_data != 0)
return true;
}
return false;
};
.h
/*
Attempt to duplicate memcmp_P but for EEPROM
https://www.avrfreaks.net/forum/tut-c-using-eeprom-memory-avr-gcc
*/
#include <avr/eeprom.h>
#ifndef memcmp_E_h
#define memcmp_E_h
class memcmp_E {
public:
memcmp_E(); //constructor
uint8_t* ramAddr;
uint16_t EE_addr;
uint8_t EE_data;
uint8_t len;
uint8_t elementSize;
uint16_t i;
};
bool memcmp_E(uint8_t*, uint16_t, uint8_t);
class memcmp_EW {
public:
memcmp_EW(); //constructor
uint8_t* ramAddr;
uint16_t EE_addr;
uint8_t EE_data;
uint8_t len;
uint8_t elementSize;
uint16_t i;
};
bool memcmp_EW(uint8_t*, uint16_t, uint8_t);
class memcmp_EDW {
public:
memcmp_ED(); //constructor
uint8_t* ramAddr;
uint16_t EE_addr;
uint8_t EE_data;
uint8_t len;
uint8_t elementSize;
uint16_t i;
};
bool memcmp_ED(uint8_t*, uint16_t, uint8_t);
#endif
No claim to elegance but it does work.