wollewald / EEPROM_SPI_WE

Arduino library for SPI based EEPROMs
https://wolles-elektronikkiste.de/en/eeprom-part-3-external-spi-eeproms
MIT License
9 stars 2 forks source link

Allow for lower SPI clock in ::init() method #3

Open kuader opened 10 months ago

kuader commented 10 months ago

Hi,

I had some trouble using the library with the Microchip 25LC640-I/SN since this EEPROM only works reliably with clock rates of up to 2 MHz. Since the default clock is set to 8 MHz, the init method fails.

After changing the default clock in EEPROM_SPI_WE.cpp:22

https://github.com/wollewald/EEPROM_SPI_WE/blob/b8fdc0bd584f040c6a2711b50b6058a19eaf521f/src/EEPROM_SPI_WE.cpp#L20-L22

everything worked perfectly.

Would you be open to adding a clock parameter to the ::init() method like below?

bool EEPROM_SPI_WE::init(unsigned long clock = 8000000){    
    _spi->begin();
    mySPISettings = SPISettings(clock, MSBFIRST, SPI_MODE0);
    [...]
}

On a side note, the failure mode of the ::init method ended in an infinite loop - is this the intended behavior or do you want me to investigate further what happened here?

wollewald commented 10 months ago

Hi @kuader, passing variables to init functions is not very common. I prefer to pass the spi clock rate to the constructor.

I have created a branch where I have implemented this:

https://github.com/wollewald/EEPROM_SPI_WE/tree/EEPROM_SPI_WE_modified

Do you want to try? I have adjusted the example sketch EEPROM_SPI_WE_basic_read_write.ino in this branch.

EEPROM_SPI_WE myEEP = EEPROM_SPI_WE(csPin, wpPin, 2000000);

I think the reason for the infinite loop is that if the SPI communication is not working, the MCU is waiting forever for an answer. Not sure how to implement a kind of time out.

kuader commented 10 months ago

Hi @wollewald , thanks for the fast response!

I tried the updated version from the other branch and can confirm the SPI clock is set as expected, so I had no further issues.

Regarding the infinite loop, I just hooked the EEPROM up to a logic analyzer to check what happens (with the old version, so clock is still 8 MHz)

EEPROM_8MHz

It looks like the MCU is continously sending the CMD 0x05 = EEP_RDSR. My guess is that from this code path:

init() -> writeProtect(PROTECT_NONE) -> eepromWriteEnable() -> eepromWriteStatusReg(EEP_WREN)

we end up in the while loop EEPROM_SPI_WE.cpp:222

https://github.com/wollewald/EEPROM_SPI_WE/blob/b8fdc0bd584f040c6a2711b50b6058a19eaf521f/src/EEPROM_SPI_WE.cpp#L215-L223

where we call into isBusy(),

https://github.com/wollewald/EEPROM_SPI_WE/blob/b8fdc0bd584f040c6a2711b50b6058a19eaf521f/src/EEPROM_SPI_WE.cpp#L193-L197

but since we always recieve statusReg = 0xFF due to the EEPROM beeing to slow to actually answer, isBusy() always returns true.

Maybe the while loop could be an appropriate place to check for a timeout?

wollewald commented 10 months ago

Hi @kuader , good that the clock setting works. Thanks for testing. I will also have a look at the other part, but this will take a bit. Hopefully I come to that next weekend.

wollewald commented 10 months ago

Hi Kuader, I have released a new version with the clock speed option. Still need to think about the other issue. Not sure yet if I implement something just for the init function or general.