Skip to content

Commit

Permalink
fix: pageSize errors and small EEPROMs
Browse files Browse the repository at this point in the history
* feat: added pageSize according to EEPROM size.
* fix: page fault when writing and reading.
* fix: error when using small EEPROMs.
  • Loading branch information
GogoVega committed May 24, 2022
1 parent 0368c76 commit 0fa1db6
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 59 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Library to write an RFID Code in the [EEPROM](https://docs.arduino.cc/learn/buil

This library is used for saving an RFID Code to your Arduino's EEPROM or I2C EEPROM rather than your Code to avoid **showing your RFID Code**. To then check if the Code corresponds to a Code already registered.

**Warning:** you must use the same number of bytes in your functions as defined in the Constructor and less than or equal to 16!
**Warning:** you must use the same number of bytes in your functions as defined in the Constructor!

## How To Use

Expand Down Expand Up @@ -58,6 +58,8 @@ void begin(twiClockFreq_t twiFreq);
Use one of the enumerations below to set EEPROM Size:
```
{
RFIDtoEEPROM_I2C::kbits_1,
RFIDtoEEPROM_I2C::kbits_2,
RFIDtoEEPROM_I2C::kbits_4,
RFIDtoEEPROM_I2C::kbits_8,
RFIDtoEEPROM_I2C::kbits_16,
Expand Down Expand Up @@ -100,13 +102,11 @@ This library contains several functions:
## Future Features
- Support for small I2C EEPROMs (1 - 2Kbits).
- Increase the number of recordable Cards (currently set to 255).
- Improve error handling.
## Limitations
- The Number of Bytes in the UID must be less than or equal to 16!
- The Number of recordable Cards is fixed at 255.
## License
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_example/basic_example.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* - Erase all Cards.
*
* Warning: you must use the same number of bytes in your functions as defined
* in the Constructor and less than or equal to 16!
* in the Constructor!
*
* Create April 2022
*
Expand Down
2 changes: 1 addition & 1 deletion examples/mfrc522_example/mfrc522_example.ino
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
* Warning: you must use the same number of bytes in your functions as defined
* in the Constructor and less than or equal to 16!
* in the Constructor!
*
* Create April 2022
*
Expand Down
1 change: 0 additions & 1 deletion src/Card/Card.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ class Card : protected Code
void CardRestoration(uint8_t nbr);
uint8_t _byteNumber;
uint8_t _maxCards;
uint8_t _pageSize = 16;
};

#endif // _Card_h
171 changes: 126 additions & 45 deletions src/Code/Code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
#include <RFIDtoEEPROM.h>
#include <Wire.h>

#ifndef BUFFER_LENGTH
#define BUFFER_LENGTH 32
#endif

#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif

#if defined(ARDUINO_ARCH_RP2040)

/*!
Expand All @@ -31,21 +39,35 @@
@param Code Variable that will be modified by reading.
@param byteNumber The Number of byte to read.
*/
void Code::read(uint8_t address, byte *Code, uint8_t byteNumber)
void Code::read(uint32_t address, byte *Code, uint8_t byteNumber)
{
while (isBusy())
delayMicroseconds(100);
uint8_t rxStatus = 0;

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8));
Wire.write((uint8_t)(address & 0xFF));
Wire.endTransmission();
Wire.requestFrom((uint8_t)_eepromAddr, (uint8_t)byteNumber);

uint8_t i = 0;
while (Wire.available())
while (byteNumber > 0)
{
Code[i++] = Wire.read();
uint8_t bytePage = _pageSize - ( address & (_pageSize - 1) );
uint8_t byteRead = min((min(bytePage, byteNumber)), (BUFFER_LENGTH - 2));

while (isBusy())
delayMicroseconds(100);

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8)); // MSB
Wire.write((uint8_t)(address & 0xFF)); // LSB
rxStatus = Wire.endTransmission();
if (rxStatus != 0) break; // Read error

Wire.requestFrom((uint8_t)_eepromAddr, (uint8_t)byteRead);

uint8_t i = 0;
while (Wire.available())
{
Code[i++] = Wire.read();
}

address += byteRead; // Increment the EEPROM address
Code += byteRead; // Increment the input data pointer
byteNumber -= byteRead; // Decrement the number of bytes left to read
}
}

Expand All @@ -55,18 +77,31 @@ void Code::read(uint8_t address, byte *Code, uint8_t byteNumber)
@param Code Code to write.
@param byteNumber The Number of byte to write.
*/
void Code::write(uint8_t address, byte *Code, uint8_t byteNumber)
void Code::write(uint32_t address, byte *Code, uint8_t byteNumber)
{
while (isBusy())
delayMicroseconds(100);
uint8_t txStatus = 0;

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8));
Wire.write((uint8_t)(address & 0xFF));
Wire.write(Code, (uint8_t)byteNumber);
Wire.endTransmission();
while (byteNumber > 0)
{
uint8_t bytePage = _pageSize - ( address & (_pageSize - 1) );
uint8_t byteWrite = min((min(bytePage, byteNumber)), (BUFFER_LENGTH - 2));

delayMicroseconds(500);
while (isBusy())
delayMicroseconds(100);

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8)); // MSB
Wire.write((uint8_t)(address & 0xFF)); // LSB
Wire.write(Code, (uint8_t)byteWrite);
txStatus = Wire.endTransmission();
if (txStatus != 0) break; // Write error

address += byteWrite; // Increment the EEPROM address
Code += byteWrite; // Increment the input data pointer
byteNumber -= byteWrite; // Decrement the number of bytes left to write

delayMicroseconds(500);
}
}

/*!
Expand All @@ -88,7 +123,7 @@ uint32_t Code::length()
@param Code Variable that will be modified by reading.
@param byteNumber The Number of byte to read.
*/
void Code::read(uint8_t address, byte *Code, uint8_t byteNumber)
void Code::read(uint32_t address, byte *Code, uint8_t byteNumber)
{
if (_local)
{
Expand All @@ -99,19 +134,33 @@ void Code::read(uint8_t address, byte *Code, uint8_t byteNumber)
}
else
{
while (isBusy())
delayMicroseconds(100);
uint8_t rxStatus = 0;

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8));
Wire.write((uint8_t)(address & 0xFF));
Wire.endTransmission();
Wire.requestFrom((uint8_t)_eepromAddr, (uint8_t)byteNumber);

uint8_t i = 0;
while (Wire.available())
while (byteNumber > 0)
{
Code[i++] = Wire.read();
uint8_t bytePage = _pageSize - ( address & (_pageSize - 1) );
uint8_t byteRead = min((min(bytePage, byteNumber)), (BUFFER_LENGTH - 2));

while (isBusy())
delayMicroseconds(100);

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8)); // MSB
Wire.write((uint8_t)(address & 0xFF)); // LSB
rxStatus = Wire.endTransmission();
if (rxStatus != 0) break; // Read error

Wire.requestFrom((uint8_t)_eepromAddr, (uint8_t)byteRead);

uint8_t i = 0;
while (Wire.available())
{
Code[i++] = Wire.read();
}

address += byteRead; // Increment the EEPROM address
Code += byteRead; // Increment the input data pointer
byteNumber -= byteRead; // Decrement the number of bytes left to read
}
}
}
Expand All @@ -122,7 +171,7 @@ void Code::read(uint8_t address, byte *Code, uint8_t byteNumber)
@param Code Code to write.
@param byteNumber The Number of byte to write.
*/
void Code::write(uint8_t address, byte *Code, uint8_t byteNumber)
void Code::write(uint32_t address, byte *Code, uint8_t byteNumber)
{
if (_local)
{
Expand All @@ -137,16 +186,29 @@ void Code::write(uint8_t address, byte *Code, uint8_t byteNumber)
}
else
{
while (isBusy())
delayMicroseconds(100);
uint8_t txStatus = 0;

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8));
Wire.write((uint8_t)(address & 0xFF));
Wire.write(Code, (uint8_t)byteNumber);
Wire.endTransmission();
while (byteNumber > 0)
{
uint8_t bytePage = _pageSize - ( address & (_pageSize - 1) );
uint8_t byteWrite = min((min(bytePage, byteNumber)), (BUFFER_LENGTH - 2));

delayMicroseconds(500);
while (isBusy())
delayMicroseconds(100);

Wire.beginTransmission((uint8_t)_eepromAddr);
if (_twoAddress) Wire.write((uint8_t)(address >> 8)); // MSB
Wire.write((uint8_t)(address & 0xFF)); // LSB
Wire.write(Code, (uint8_t)byteWrite);
txStatus = Wire.endTransmission();
if (txStatus != 0) break; // Write error

address += byteWrite; // Increment the EEPROM address
Code += byteWrite; // Increment the input data pointer
byteNumber -= byteWrite; // Decrement the number of bytes left to write

delayMicroseconds(500);
}
}
}

Expand All @@ -169,7 +231,7 @@ uint32_t Code::length()
@param address Address for reading.
@return the byte read (uint8_t).
*/
uint8_t Code::read(uint8_t address)
uint8_t Code::read(uint32_t address)
{
uint8_t data;

Expand All @@ -182,15 +244,15 @@ uint8_t Code::read(uint8_t address)
@param address Address for writing.
@param data the byte to write.
*/
void Code::write(uint8_t address, uint8_t data)
void Code::write(uint32_t address, uint8_t data)
{
if (read(address) != data)
write(address, &data, 1);
}

/*!
@brief Check if device is not answering (currently writing).
@return Returns true if writing in progress (bool).
@return true if writing in progress (bool).
*/
bool Code::isBusy()
{
Expand All @@ -200,3 +262,22 @@ bool Code::isBusy()

return (true);
}

/*!
@brief Returns the page size of EEPROM.
@param eepromSize EEPROM size in Kbits.
@return the page size of EEPROM (uint8_t).
*/
uint8_t Code::pageSize(uint32_t eepromSize)
{
if (eepromSize < RFIDtoEEPROM_I2C::kbits_4)
return 8;
else if (eepromSize < RFIDtoEEPROM_I2C::kbits_32)
return 16;
else if (eepromSize < RFIDtoEEPROM_I2C::kbits_128)
return 32;
else if (eepromSize < RFIDtoEEPROM_I2C::kbits_512)
return 64;

return 128;
}
18 changes: 10 additions & 8 deletions src/Code/Code.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,18 @@
class Code
{
protected:
void read(uint8_t address, byte *Code, uint8_t byteNumber);
uint8_t read(uint8_t address);
void write(uint8_t address, byte *Code, uint8_t byteNumber);
void write(uint8_t address, uint8_t data);
uint32_t length();

bool _local = true;
void read(uint32_t address, byte *Code, uint8_t byteNumber);
uint8_t read(uint32_t address);
void write(uint32_t address, byte *Code, uint8_t byteNumber);
void write(uint32_t address, uint8_t data);
uint8_t pageSize(uint32_t eepromSize);
uint32_t length(void);

bool _local;
bool _twoAddress;
uint8_t _eepromAddr;
uint16_t _eepromSize;
uint8_t _pageSize;
uint32_t _eepromSize;

private:
bool isBusy(void);
Expand Down
2 changes: 2 additions & 0 deletions src/RFIDtoEEPROM/RFIDtoEEPROM.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class RFIDtoEEPROM_I2C : public Card
//EEPROM size in kbits.
enum eeprom_size_t
{
kbits_1 = 1,
kbits_2 = 2,
kbits_4 = 4,
kbits_8 = 8,
kbits_16 = 16,
Expand Down
1 change: 1 addition & 0 deletions src/RFIDtoEEPROM/RFIDtoEEPROM_I2C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ RFIDtoEEPROM_I2C::RFIDtoEEPROM_I2C(eeprom_size_t eepromSize, uint8_t address, ui
_local = false;
_eepromAddr = address;
_eepromSize = eepromSize;
_pageSize = pageSize(eepromSize);
_twoAddress = eepromSize > kbits_16 ? true : false;
}

Expand Down

0 comments on commit 0fa1db6

Please sign in to comment.