Skip to content

Commit

Permalink
Improved determineNoWrite, removed static references to Serial (#63)
Browse files Browse the repository at this point in the history
* Improved  determineNoWrite, now works with larger EEPROMS. tested with AT24C02, AT24C23 and AT24C256
* Added loop exit, updated license and changelog

---------

Co-authored-by: Roeland Kluit <roeland@kluit.net>
  • Loading branch information
roelandkluit and Roeland Kluit authored Jan 2, 2024
1 parent 42cdf1a commit ee4d38a
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 34 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [1.8.2] - 2023-01-02
- updated **uint32_t determineSizeNoWrite()**, kudos to roelandkluit
- minor edits

## [1.8.1] - 2023-12-14
- add **uint32_t determineSizeNoWrite()**, kudos to roelandkluit
Expand Down
107 changes: 80 additions & 27 deletions I2C_eeprom.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: I2C_eeprom.cpp
// AUTHOR: Rob Tillaart
// VERSION: 1.8.1
// VERSION: 1.8.2
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
// URL: https://github.com/RobTillaart/I2C_EEPROM.git

Expand Down Expand Up @@ -55,7 +55,7 @@ I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize, T

bool I2C_eeprom::begin(int8_t writeProtectPin)
{
// if (_wire == 0) Serial.println("zero"); // test #48
// if (_wire == 0) SPRNL("zero"); // test #48
_lastWrite = 0;
_writeProtectPin = writeProtectPin;
if (_writeProtectPin >= 0)
Expand Down Expand Up @@ -290,9 +290,9 @@ uint32_t I2C_eeprom::determineSize(const bool debug)
folded = (cnt == 2);
if (debug)
{
Serial.print(size, HEX);
Serial.print('\t');
Serial.println(readByte(size), HEX);
SPRNH(size, HEX);
SPRN('\t');
SPRNLH(readByte(size), HEX);
}

// restore old values
Expand All @@ -304,33 +304,86 @@ uint32_t I2C_eeprom::determineSize(const bool debug)
return 0;
}


// new 1.8.1 #61
// updated 1.8.2 #63
//
// Returns:
// 0 if device size cannot be determined or device is not online
// 1 if device has default bytes in first dataFirstBytes bytes [0-BUFSIZE]
// Write some dataFirstBytes to the first bytes and retry or use the determineSize method
// 2 if device has all the same bytes in first dataFirstBytes bytes [0-BUFSIZE]
// Write some random dataFirstBytes to the first bytes and retry or use the determineSize method
// >= 128 Device size in bytes
uint32_t I2C_eeprom::determineSizeNoWrite()
{
#define BUFSIZE (32)
// try to read a byte to see if connected
if (!isConnected()) return 0;

bool addressSize = _isAddressSizeTwoWords;
byte dummyVal = 0;
uint32_t lastOkSize = 0;
_isAddressSizeTwoWords = true; //Otherwise reading large EEPROMS fails
bool isModifiedFirstSector = false;
bool dataIsDifferent = false;

for (uint32_t size = 128; size <= 65536; size *= 2)
byte dataFirstBytes[BUFSIZE];
byte dataMatch[BUFSIZE];
readBlock(0, dataFirstBytes, BUFSIZE);

for (uint8_t pos = 0; pos < BUFSIZE; pos++)
{
_isAddressSizeTwoWords = (size > I2C_DEVICESIZE_24LC16); // == 2048
if (dataIsDifferent || pos == 0)
{
//ignore futher comparison if dataFirstBytes is not the same in buffer
//Ignore first byte
}
else if (dataFirstBytes[pos - 1] != dataFirstBytes[pos])
{
dataIsDifferent = true;
}

if (dataFirstBytes[pos] != 0xFF && dataFirstBytes[pos] != 0x00)
{
//Default dataFirstBytes value is 0xFF or 0x00
isModifiedFirstSector = true;
}

if (dataIsDifferent && isModifiedFirstSector)
break;
}

// Try to read last byte of the block, should return length of 0 when fails
if (readBlock(size - 1, &dummyVal, 1) == 0)
{
if (!isModifiedFirstSector)
{
//Cannot determine diff, at least one of the first bytes within 0 - len [BUFSIZE] needs to be changed.
//to something other than 0x00 and 0xFF
_isAddressSizeTwoWords = addressSize;
break;
}
else
return 1;
}
if (!dataIsDifferent)
{
//Data in first bytes within 0 - len [BUFSIZE] are all the same.
_isAddressSizeTwoWords = addressSize;
return 2;
}

//Read from larges to smallest size
for (uint32_t size = 32768; size >= 64; size /= 2)
{
_isAddressSizeTwoWords = (size >= I2C_DEVICESIZE_24LC16); // == 2048

// Try to read last byte of the block, should return length of 0 when fails for single byte devices
// Will return the same dataFirstBytes as initialy read on other devices as the datapointer could not be moved to the requested position
delay(2);
uint16_t bSize = readBlock(size, dataMatch, BUFSIZE);

if (bSize == BUFSIZE && memcmp(dataFirstBytes, dataMatch, BUFSIZE) != 0)
{
lastOkSize = size;
}
//Read is perfomed just over size (size + BUFSIZE), this will only work for devices with mem > size; therefore return size * 2
_isAddressSizeTwoWords = addressSize;
return size * 2;
}
}
return lastOkSize;
_isAddressSizeTwoWords = addressSize;
return 0;
}


Expand Down Expand Up @@ -535,10 +588,10 @@ int I2C_eeprom::_WriteBlock(const uint16_t memoryAddress, const uint8_t * buffer
// {
// if (_debug)
// {
// Serial.print("mem addr w: ");
// Serial.print(memoryAddress, HEX);
// Serial.print("\t");
// Serial.println(rv);
// SPRN("mem addr w: ");
// SPRNH(memoryAddress, HEX);
// SPRN("\t");
// SPRNL(rv);
// }
// return -(abs(rv)); // error
// }
Expand All @@ -558,10 +611,10 @@ uint8_t I2C_eeprom::_ReadBlock(const uint16_t memoryAddress, uint8_t * buffer, c
{
// if (_debug)
// {
// Serial.print("mem addr r: ");
// Serial.print(memoryAddress, HEX);
// Serial.print("\t");
// Serial.println(rv);
// SPRN("mem addr r: ");
// SPRNH(memoryAddress, HEX);
// SPRN("\t");
// SPRNL(rv);
// }
return 0; // error
}
Expand Down
19 changes: 15 additions & 4 deletions I2C_eeprom.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: I2C_eeprom.h
// AUTHOR: Rob Tillaart
// VERSION: 1.8.1
// VERSION: 1.8.2
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
// URL: https://github.com/RobTillaart/I2C_EEPROM.git

Expand All @@ -11,8 +11,7 @@
#include "Wire.h"


#define I2C_EEPROM_VERSION (F("1.8.0"))

#define I2C_EEPROM_VERSION (F("1.8.2"))

#define I2C_DEVICESIZE_24LC512 65536
#define I2C_DEVICESIZE_24LC256 32768
Expand All @@ -34,11 +33,23 @@
#define I2C_WRITEDELAY 5000
#endif


#ifndef UNIT_TEST_FRIEND
#define UNIT_TEST_FRIEND
#endif

//#define ENABLE_DEBUG

#ifdef ENABLE_DEBUG
#define SPRN Serial.print
#define SPRNL Serial.println
#define SPRNH Serial.print
#define SPRNLH Serial.println
#else
#define SPRN(MSG)
#define SPRNH(MSG,MSG2)
#define SPRNL(MSG)
#define SPRNLH(MSG,MSG2)
#endif

class I2C_eeprom
{
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2011-2023 Rob Tillaart
Copyright (c) 2011-2024 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ void setup()
{
Serial.println("SIZE: could not determine size");
}
else if (size == 1)
{
Serial.println("SIZE: device has default data in first bytes, write some data and retry or use the determineSize method");
}
else if (size == 2)
{
Serial.println("SIZE: device has all the same data in first bytes, write some data and retry");
}
else if (size > 1024)
{
Serial.print("SIZE: ");
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/I2C_EEPROM.git"
},
"version": "1.8.1",
"version": "1.8.2",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=I2C_EEPROM
version=1.8.1
version=1.8.2
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Library for I2C EEPROMS
Expand Down

0 comments on commit ee4d38a

Please sign in to comment.