Open drp0 opened 5 years ago
Thanks for the report.
How on earth did I come up with such a complicated formula?
SPI.transfer((static_cast<uint8_t>(-sector) & 0x01) << (m_bufferSize - 5));
can be replaced with SPI.transfer((sector - 0x0a) << (m_bufferSize - 5))
My solution came from page 13 section 6.9 of the manual at https://www.adestotech.com/wp-content/uploads/doc8782.pdf Perhaps you intended a more generic method across a range of devices?
I tried and failed miserably :) According to the datasheets of the AT45DB041D, AT45DB161D and AT45DB321D, the formula posted above will do the trick:
SPI.transfer((sector - 0x0a) << (m_bufferSize - 5))
Your library works well, thanks.
This is my analysis on sector erase in the AT45DB161E manual: "To perform an erase of Sector 0a or Sector 0b with the standard DataFlash page size (528 bytes), an opcode of 7Ch must be clocked into the device followed by three address bytes comprised of two dummy bits, nine page address bits (PA11 - PA3), and 13 dummy bits. "
0a (all PAn bits = 0) 00 000000000 0000000000000 3 bytes all 0
0b (bit PA3 =1) 00 000000,001 00000,00000000 byte 1 0 byte 2 00100000 (32) byte 3 0
I have found no other issues implementing it on the AT45DB161E. Sector Erasing and protection works. I have written arduino (mega) examples to sequentially write values across successive pages. This includes the use of single data items and structures. Let me know if you would like copies. David
Yes sure. That'd be cool.
I found the E chip had an extended byte, so modified dataflash.cpp to grab the value. It turned out to be 0 and not worth the effort. Therefore delete the following lines in flashtestStructure.ino (line 561) and flashtest3.ino (line 374)
if( id.extendedInfoLength > 0){
Serial.print(F("Extended byte ")); Serial.println(id.extra);
}
Thanks!
I found those docs about D/E differences:
Very useful. There is now a second status byte in the E chip with some good information:
void StatusByte2(){
uint8_t Status;
dataflash.reEnable(); // Reset command decoder
SPI.transfer(0xD7); // Send status read command
Status = SPI.transfer(0); // Status 1
Status = SPI.transfer(0); // Status 2
dataflash.disable();
Serial.print(F("Status register(2): ")); Serial.println(Status, BIN);
if (Status & 128) Serial.println(F(" Device is Ready"));
if (Status & 32) Serial.println(F(" Erase or program Error detected"));
if (Status & 8) Serial.println(F(" Sector Lockdown command is enabled"));
if (Status & 4) Serial.println(F(" A sector is program suspended whilst using buffer 2"));
if (Status & 2) Serial.println(F(" A sector is program suspended whilst using buffer 1"));
if (Status & 1) Serial.println(F(" A sector is erase suspended "));
Serial.println();
}
I am using an AT45DB161E. After reviewing the manual I can not find any significant difference to the AT45DB161D Sector erase works correctly with blocks 1 to 15 and not with sectors 0a and 0b. The issue seems to originate in sectorErase
In the documentation, the E chip sector erase appears functionally the same to the D chip,
The AT45_SECTOR_0A/0B section appears to yield the correct values of 32 and 0, but allocates them to the wrong sector. Sector -1 shoud be 0 and sector 0, 32. My replacement line "if(sector == AT45_SECTOR_0A) SPI.transfer(0x00); else SPI.transfer(32)" fixes the issue.
Here is my flash_SectorErase:
David