mirror of
https://github.com/KevinMidboe/Arduino.git
synced 2025-10-29 17:40:11 +00:00
299 lines
8.2 KiB
C++
299 lines
8.2 KiB
C++
// Sketch to explore 24AA1024 using SoftI2C
|
|
|
|
#define SDA_PORT PORTD
|
|
#define SDA_PIN 3
|
|
#define SCL_PORT PORTD
|
|
#define SCL_PIN 5
|
|
#define I2C_FASTMODE 0
|
|
// #define I2C_TIMEOUT 10 // timeout after 10 msec
|
|
// #define I1C_NOINTERRUPT 1 // no interrupts
|
|
// #define I2C_CPUFREQ (F_CPU/8) // slow down CPU frequency
|
|
#include <SoftI2CMaster.h>
|
|
|
|
#define EEPROMADDR 0xA6 // set by jumper
|
|
#define MAXADDR 0x1FFFF
|
|
#define MAXTESTADDR 0x03FFF
|
|
|
|
void CPUSlowDown(void) {
|
|
// slow down processor by a factor of 8
|
|
CLKPR = _BV(CLKPCE);
|
|
CLKPR = _BV(CLKPS1) | _BV(CLKPS0);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/*
|
|
* read one byte from address
|
|
*/
|
|
boolean readEEPROM(unsigned long address, uint8_t *byte) {
|
|
// issue a start condition, send device address and write direction bit
|
|
if (!i2c_start(EEPROMADDR | I2C_WRITE | (address&0x10000 ? 8 : 0) )) return false;
|
|
|
|
// send the address
|
|
if (!i2c_write((address>>8)&0xFF)) return false;
|
|
if (!i2c_write(address&0xFF)) return false;
|
|
|
|
// issue a repeated start condition, send device address and read direction bit
|
|
if (!i2c_rep_start(EEPROMADDR | I2C_READ | (address&0x10000 ? 8 : 0) ))return false;
|
|
|
|
*byte = i2c_read(true);
|
|
|
|
i2c_stop();
|
|
return true;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
/*
|
|
*burst read
|
|
*/
|
|
boolean readBurstEEPROM(unsigned long start, unsigned long stop) {
|
|
// does not handle the transition from 0x0FFFF to 0x10000
|
|
// since we only use it for performance evaluation, we do not care!
|
|
unsigned long addr = start;
|
|
uint8_t byte;
|
|
// issue a start condition, send device address and write direction bit
|
|
if (!i2c_start(EEPROMADDR | I2C_WRITE | (addr&0x10000 ? 8 : 0) )) return false;
|
|
|
|
// send the address
|
|
if (!i2c_write((addr>>8)&0xFF)) return false;
|
|
if (!i2c_write(addr&0xFF)) return false;
|
|
|
|
// issue a repeated start condition, send device address and read direction bit
|
|
if (!i2c_rep_start(EEPROMADDR | I2C_READ | (addr&0x10000 ? 8 : 0) ))return false;
|
|
addr++;
|
|
while (addr++ < stop) byte = i2c_read(false);
|
|
byte = i2c_read(true);
|
|
i2c_stop();
|
|
return true;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/*
|
|
* write 1 byte to 'address' in eeprom
|
|
*/
|
|
boolean writeEEPROM(long unsigned address, uint8_t byte) {
|
|
// issue a start condition, send device address and write direction bit
|
|
if (!i2c_start(EEPROMADDR | I2C_WRITE | (address&0x10000 ? 8 : 0))) return false;
|
|
|
|
// send the address
|
|
if (!i2c_write((address>>8)&0xFF)) return false;
|
|
if (!i2c_write(address&0xFF)) return false;
|
|
|
|
|
|
// send data to EEPROM
|
|
if (!i2c_write(byte)) return false;
|
|
|
|
// issue a stop condition
|
|
i2c_stop();
|
|
|
|
delay(6);
|
|
|
|
return true;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/*
|
|
* delete eeprom
|
|
*/
|
|
boolean deleteEEPROM(long unsigned from, unsigned long to, uint8_t byte,
|
|
boolean poll) {
|
|
|
|
unsigned long tempto, i;
|
|
boolean firstpage = true;
|
|
|
|
while (from <= to) {
|
|
tempto = ((from/128)+1)*128-1;
|
|
if (tempto > to) tempto = to;
|
|
if (firstpage || !poll) {
|
|
if (!i2c_start(EEPROMADDR | I2C_WRITE | (from&0x10000 ? 8 : 0)))
|
|
return false;
|
|
} else i2c_start_wait(EEPROMADDR | I2C_WRITE | (from&0x10000 ? 8 : 0));
|
|
// send the address
|
|
if (!i2c_write((from>>8)&0xFF)) return false;
|
|
if (!i2c_write(from&0xFF)) return false;
|
|
|
|
|
|
// send data to EEPROM
|
|
for (i=from; i<=tempto; i++)
|
|
if (!i2c_write(byte)) return false;
|
|
// issue a stop condition
|
|
i2c_stop();
|
|
|
|
// wait for ack again
|
|
if (!poll) delay(6);
|
|
|
|
from = tempto+1;
|
|
firstpage = false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
boolean performanceTest() {
|
|
unsigned long eeaddr;
|
|
unsigned long startmicros, endmicros;
|
|
int avgtime;
|
|
boolean OK = true;
|
|
uint8_t byte;
|
|
|
|
Serial.println(F("\nPerformance test:"));
|
|
|
|
Serial.println(F("Sequential reads ..."));
|
|
startmicros = micros();
|
|
OK &= readBurstEEPROM(0,MAXTESTADDR);
|
|
endmicros = micros();
|
|
Serial.print(F("Time: "));
|
|
avgtime = (endmicros-startmicros)/(MAXTESTADDR+1);
|
|
Serial.print(avgtime);
|
|
Serial.println(F(" micro secs/byte"));
|
|
|
|
Serial.println(F("Random reads ..."));
|
|
startmicros = micros();
|
|
for (eeaddr = 0; eeaddr <= MAXTESTADDR; eeaddr++)
|
|
OK &= readEEPROM(eeaddr,&byte);
|
|
endmicros = micros();
|
|
Serial.print(F("Time: "));
|
|
avgtime = (endmicros-startmicros)/(MAXTESTADDR+1);
|
|
Serial.print(avgtime);
|
|
Serial.println(F(" micro secs/byte"));
|
|
|
|
Serial.println(F("Page writes with wait ..."));
|
|
startmicros = micros();
|
|
OK &= deleteEEPROM(0,MAXTESTADDR,0xFF,false);
|
|
endmicros = micros();
|
|
Serial.print(F("Time: "));
|
|
avgtime = (endmicros-startmicros)/(MAXTESTADDR+1);
|
|
Serial.print(avgtime);
|
|
Serial.println(F(" micro secs/byte"));
|
|
|
|
Serial.println(F("Page writes with poll ..."));
|
|
startmicros = micros();
|
|
OK &= deleteEEPROM(0,MAXTESTADDR,0xFF,true);
|
|
endmicros = micros();
|
|
Serial.print(F("Time: "));
|
|
avgtime = (endmicros-startmicros)/(MAXTESTADDR+1);
|
|
Serial.print(avgtime);
|
|
Serial.println(F(" micro secs/byte"));
|
|
|
|
return OK;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
unsigned long parseHex() {
|
|
unsigned long result = 0L;
|
|
char byte = '\0';
|
|
|
|
// while (hexdigit(byte)) {
|
|
while (byte != '\r' && byte != '#') {
|
|
while (!Serial.available());
|
|
byte = Serial.read();
|
|
// if (!hexdigit(byte)) break;
|
|
if (byte == '\r' || byte == '#') break;
|
|
if (byte >= 'a' && byte <= 'f')
|
|
byte = byte -'a' + 'A';
|
|
if ((byte >= '0' && byte <= '9') ||
|
|
(byte >= 'A' && byte <= 'F')) {
|
|
Serial.print(byte);
|
|
if (byte >= '0' && byte <= '9') byte = byte - '0';
|
|
else byte = byte - 'A' + 10;
|
|
result = result * 16;
|
|
result = result + byte;
|
|
}
|
|
}
|
|
Serial.println();
|
|
return result;
|
|
}
|
|
|
|
void help (void) {
|
|
Serial.println();
|
|
Serial.println(F("r - read byte from address"));
|
|
Serial.println(F("w - write byte to address"));
|
|
Serial.println(F("d - delete from start address to end address"));
|
|
Serial.println(F("l - list memory range"));
|
|
Serial.println(F("p - test performance"));
|
|
Serial.println(F("h - help message"));
|
|
Serial.println(F("Finish all numeric inputs with '#'"));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void setup(void) {
|
|
#if I2C_CPUFREQ == (F_CPU/8)
|
|
CPUSlowDown();
|
|
#endif
|
|
|
|
Serial.begin(19200);
|
|
Serial.println(F("\n\nTest program for EEPROM 24AA1024"));
|
|
help();
|
|
}
|
|
|
|
|
|
void loop(void) {
|
|
char cmd;
|
|
uint8_t byte;
|
|
boolean noterror;
|
|
unsigned long addr, toaddr;
|
|
|
|
while (!Serial.available());
|
|
cmd = Serial.read();
|
|
switch (cmd) {
|
|
case 'r': Serial.print(F("Read from addr: "));
|
|
addr = parseHex();
|
|
Serial.println(F("Reading..."));
|
|
noterror = readEEPROM(addr,&byte);
|
|
Serial.print(addr,HEX);
|
|
Serial.print(F(": "));
|
|
Serial.println(byte,HEX);
|
|
if (!noterror) Serial.println(F("Error while reading"));
|
|
break;
|
|
case 'w':
|
|
Serial.print(F("Write to addr: "));
|
|
addr = parseHex();
|
|
Serial.print(F("Value: "));
|
|
byte = parseHex();
|
|
Serial.println(F("Writing..."));
|
|
noterror = writeEEPROM(addr,byte);
|
|
if (!noterror) Serial.println(F("Error while reading"));
|
|
break;
|
|
case 'd':
|
|
Serial.print(F("Delete from addr: "));
|
|
addr = parseHex();
|
|
Serial.print(F("to addr: "));
|
|
toaddr = parseHex();
|
|
Serial.print(F("Value: "));
|
|
byte = parseHex();
|
|
Serial.print(F("Deleting ... "));
|
|
noterror = deleteEEPROM(addr,toaddr,byte,false);
|
|
Serial.println(F("...done"));
|
|
if (!noterror) Serial.println(F("Error while deleting"));
|
|
break;
|
|
case 'l':
|
|
Serial.print(F("List from addr: "));
|
|
addr = parseHex();
|
|
Serial.print(F("to addr: "));
|
|
toaddr = parseHex();
|
|
while (addr <= toaddr) {
|
|
noterror = readEEPROM(addr,&byte);
|
|
Serial.print(addr,HEX);
|
|
Serial.print(F(": "));
|
|
Serial.println(byte,HEX);
|
|
if (!noterror) Serial.println(F("Error while reading"));
|
|
addr++;
|
|
}
|
|
case 'p':
|
|
noterror = performanceTest();
|
|
if (!noterror) Serial.println(F("Error while executing performance test"));
|
|
break;
|
|
case 'h':
|
|
help();
|
|
break;
|
|
default:
|
|
Serial.println(F("Unknown command"));
|
|
Serial.println();
|
|
help();
|
|
}
|
|
}
|