Skip to content

Sector delete of sectors 0a and 0b fails #26

@drp0

Description

@drp0

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions