Hello,
I think that a few comments about the code posted on your website are in order. One of your preliminary comments:
You will notice that slave select pin is not used. Because I only used this one chip, I tied the SS, WP, and HOLD pins to hi/low as per my needs.
Tying the SS (or CS) pin low is not an option for an EEPROM device. The line must be lowered prior to the commencement of a command sequence (to indicate that a command byte will follow), and raised at the completion of the command sequence. For a write or erase command, execution will not commence until this occurs.
There still seems to be some confusion over the role of the SPI flags SPTEF and SPRF. My understanding is that many of the time delays that you have introduced should not be necessary, but were required because of improper handling of the SPRF flag. The amount of delay would also have been dependent on the SPI clock rate chosen. With appropriate handling of SPRF, the clock rate should be non-critical, provided it is less than the maximum limit specified for the EEPROM.
Now for some comments on snippets of your code, to outline some of the perceived problems -
Snippet 1:
void SPI_WREN(void)
{
CS_ON;
delay(2); // Probably unnecessary for EEPROM
while (!(SPIS & 0x20)); // Wait until ready to send
// SPTEF should normally be already set here
SPID = WREN; // Send byte value
delay(1);
// Delay is needed for completion of SPI transfer prior to raising CS
// A better solution is to test the SPRF flag
while (!(SPIS & 0x80)); // Wait until transfer is complete
(void)SPID; // Clears SPRF - prevents overrun on next transfer
CS_OFF;
delay(1); // Unnecessary
}
Snippet 2:
byte SPI_RDSR(void)
{
CS_ON;
delay(2); // Probably unnecessary for EEPROM
while (!(SPIS & 0x20)); // Wait until ready to send
// SPTEF should normally be already set here
SPID = RDSR; // Send byte value
while (!(SPIS & 0x20)); // Wait until ready to send
// SPTEF should again be set because of double buffering
SPID = DUMMY; // Send byte value
delay(1); // Unnecessary
while (!(SPIS & 0x80)); // Wait until ready to send
// SPRF will become set on completion of the first byte transfer
// SPID will contain the result of this transfer (invalid value)
// On completion of the second transfer, an overrun state will remain until SPRF is cleared
// The result of the second transfer will be lost
delay(4); // Unnecessary with appropriate SPRF handling
CS_OFF;
delay(1); // Unnecessary
return SPID; // This read will clear both SPRF and the overrun state
}
There are many other instances throughout the code with similar issues. The cardinal rule for SPI master transfers -
Wait until each byte transfer is complete, and then always clear the SPRF flag to prevent an overrun condition.
If this is strictly followed, there should be few timing issues. While I have not used the 25AA512 device, I have used smaller capacity SPI EEPROM devices - I cannot see that there are more severe timing requirements for the larger device, and I do not know of any special power-up requirements.
See what you make of the attached experimental code.
Regards,
Mac
Message Edited by bigmac on 2009-03-19 03:42 PM