-
Notifications
You must be signed in to change notification settings - Fork 14
Open
Description
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
void DataFlash::sectorErase(int8_t sector)
{
/* Wait for the end of the previous operation. */
waitUntilReady();
reEnable();
/* Send opcode */
SPI.transfer(DATAFLASH_SECTOR_ERASE); // 0x7C
if((sector == AT45_SECTOR_0A) || (sector == AT45_SECTOR_0B))
{
SPI.transfer(0x00);
if(sector == AT45_SECTOR_0A) SPI.transfer(0x00); else SPI.transfer(32);
//SPI.transfer((static_cast<uint8_t>(-sector) & 0x01) << (m_bufferSize - 5));
}
else
{
uint8_t shift = m_bufferSize + m_pageSize - m_sectorSize - 16;
SPI.transfer(sector << shift);
SPI.transfer(0x00);
}
SPI.transfer(0x00);
/* Start sector erase.
The chip remains busy until this operation finishes. */
disable();
}
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:
// flash_sectorErase
/*
* mini, mega
* pin1(misi) to mosi 11, 51
* pin2(sck ) to sck 13, 52
* pin3(rest) to reset 8, 8
* pin4(sc ) to cS 10, 53
* pin5(wp ) to wp 7, 7
* pin6 Vcc 3v3
* pin7 gnd 0v
* pin8(miso) to misi 12, 50
*/
#include <SPI.h>
#include "DataFlash.h"
#if defined(__AVR_ATmega2560__)
static const int csPin= 53; // mega
#else
static const int csPin= 10;
#endif
static const int resetPin = 8;
static const int wpPin= 7;
DataFlash dataflash;
uint8_t currentSector;
static const uint16_t bufferSize[7] = { 264, 264, 264, 264, 528, 528, 528 };
static const uint16_t pagesSector0b[7] = { 120, 120, 248, 248, 248, 120, 248 };
static const uint16_t pagesPerSector[7] = { 128, 128, 256, 256, 256, 128, 256 };
void setup(){
Serial.begin(115200);
delay(1000);
/* Initialize SPI */
SPI.begin();
delay(10);
/* Initialize dataflash */
dataflash.setup(csPin, resetPin, wpPin);
delay(10);
dataflash.begin();
delay(10);
Serial.print("Manual buffer erase : on\n");
dataflash.manualErase();
flashInfo();
int8_t res = 0;
res += testSectorErase(AT45_SECTOR_0A);
res += testSectorErase(AT45_SECTOR_0B);
for(uint8_t i=1; i<16; i++) res += testSectorErase(i);
Serial.print("\nTest ");
if(res != 17) Serial.println("failed!"); else Serial.println("successful!");
delay(2000);
testAll(); // check each byte = 0xFF
}
void fillPages(uint16_t pageStart, uint16_t pageCount, uint16_t bufferSize){
uint8_t myBuffer = 0;
uint16_t page = 0;
for(page=pageStart; page<(pageStart+pageCount); page++){
dataflash.bufferWrite(myBuffer, 0);
for(uint16_t j=0; j<bufferSize; j++)SPI.transfer( j & 0xff );
dataflash.bufferToPage(myBuffer, page);
int8_t res = dataflash.isPageEqualBuffer(page, myBuffer);
if(res == 0){
Serial.print("Page ");
Serial.print(page);
Serial.print(" failed to fill");
}
myBuffer ^= 1; // toggle buffer 0 and 1
}
}
void setBuffer(uint8_t thisBuffer, uint8_t val, uint16_t bufSize){
dataflash.bufferWrite(thisBuffer, 0);
for(uint16_t i=0; i<bufSize; i++) SPI.transfer(val);
}
int8_t testSectorErase(int8_t sectorId){//int8_t ?
uint16_t pageStart, pageCount;
uint8_t thisStatus = dataflash.status();
uint8_t deviceIndex = ((thisStatus & 0x38) >> 3) - 1;
if(sectorId == AT45_SECTOR_0A){
pageStart = 0;
pageCount = 8;
}
else if(sectorId == AT45_SECTOR_0B){
pageStart = 8;
pageCount = pagesSector0b[deviceIndex];
}
else
{
pageStart = pagesPerSector[deviceIndex] * static_cast<uint16_t>(sectorId);
pageCount = pagesPerSector[deviceIndex];
}
Serial.print("\nTesting sector "); Serial.println(sectorId);
Serial.print("Page start ");Serial.print(pageStart);
Serial.print(" Page count "); Serial.println(pageCount);
Serial.print("Filling pages\n");
fillPages(pageStart, pageCount, bufferSize[deviceIndex]);
Serial.println("Erasing sector");
dataflash.sectorErase(sectorId);
Serial.println("Check pages");
uint16_t res = checkPages(pageStart, pageCount, deviceIndex);
if(res != pageCount){
Serial.print("\nFAILURE! ("); Serial.print(res);Serial.print(" out of ");
Serial.print(pageCount); Serial.println(")");
return 0;
}
return 1;
}
uint16_t checkPages(uint16_t pageStart, uint16_t pageCount, uint8_t deviceIndex){
uint16_t count = 0;
int8_t res;
setBuffer(0, 0xFF, bufferSize[deviceIndex]); // fill buffer 0 with 0xFF
for(uint16_t page = pageStart; page < (pageCount+pageStart); page++){
res = dataflash.isPageEqualBuffer(page, 0);
Serial.print("Page "); Serial.print(page);
if(res == 1) {
count++;
Serial.println(" was succesfully erased.");
}else Serial.println (" was not properly erased.");
}
return count;
}
void testAll(){
unsigned long errcount = 0;
int pcount = 0;
Serial.println("\nTest all:");
for (int pagecount = 0; pagecount <4095; pagecount++){//4096
dataflash.pageRead(pagecount,0);
pcount = 0;
Serial.print("Page ");Serial.print(pagecount);
//Serial.println();
for(int i=0; i< DF_45DB161_PAGESIZE; i++){ // 528
uint8_t data = SPI.transfer(0xff);
if (data != 255) {
//Serial.print(i);Serial.print(" ");
//Serial.print( (char)data);
//Serial.print(" "); Serial.println(data);
errcount ++;
pcount++;
}
}
if(pcount > 0) {
Serial.print(" Page error ");Serial.println(pcount);
} else Serial.println();
}
Serial.print("Error count ");Serial.println(errcount);
}
void flashInfo(){
/* Read status register */
uint8_t myStatus = dataflash.status();
DataFlash::ID id;
/* Read manufacturer and device ID */
dataflash.readID(id);
/* Display status register */
Serial.print("Status register :");
Serial.println(myStatus, BIN);
/* Display manufacturer and device ID */
Serial.print("Manufacturer ID : "); // Should be 00011111
Serial.println(id.manufacturer, HEX);
Serial.print("Device ID (part 1) : "); // Should be 00011111
Serial.println(id.device[0], HEX);
Serial.print("Device ID (part 2) : "); // Should be 00000000
Serial.println(id.device[1], HEX);
Serial.print("Extended Device Information String Length : "); // 00000000
Serial.println(id.extendedInfoLength, HEX);
}
void loop(){
}
David
Metadata
Metadata
Assignees
Labels
No labels