Giter Club home page Giter Club logo

arduino-dataflash's People

Contributors

blockos avatar zharovdv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduino-dataflash's Issues

Return values

Add return values so that we can check for invalid arguments (for example when the chip has only one buffer).
See #17

Documentation

Write a proper README and fill the wiki with examples.

PageRead question

Reading the datasheet for the AT45DB04D chip it talks about padding the stream with 4 "dont care" bits in between the opcode and the page address:

Main Memory Page Read

A Main Memory Page Read allows the user to read data directly from any one of the 2048 pages in the main memory, bypassing both of the data buffers and leaving the contents of the buffers unchanged.

To start a page read, an opcode of 52H or D2H must be clocked into the device fol-lowed by 24 address bits and 32 don’t care bits.

The first four bits of the 24-bit address sequence are reserved bits, the next 11 address bits (PA10 - PA0) specify the page address,and the next nine address bits (BA8 - BA0) specify the starting byte address within the page.

How are the "first four bits" handled below?

for this chip, m_buffersize comes out to 9, and therefore the inline function pageToHiU8 equates to 16-9 and 16-8 for pageToLoU8.

I'm just a bit confused how we're handling the four empty bits for this 4 megabit chip...

void DataFlash::pageRead(uint16_t page, uint16_t offset)
{
reEnable(); // Reset command decoder.

/* Send opcode */
SPI.transfer(DATAFLASH_PAGE_READ);

/* Address (page | offset)  */
SPI.transfer(pageToHiU8(page));  // aka page >> 7
SPI.transfer(pageToLoU8(page) | (uint8_t)(offset >> 8)); // aka page << 1 | offset>>8
SPI.transfer((uint8_t)(offset & 0xff));

/* 4 "don't care" bytes */
SPI.transfer(0);
SPI.transfer(0);
SPI.transfer(0);
SPI.transfer(0);

// Can't disable the chip here!

}

AT45DB041D interfacing with arduino Uno

Hi, i am trying to interfacing AT45DB041D with arduino uno.
I am trying to upload pagetest code from your library, but i am unable to get any result on serial monitor i am getting 0 value for all outputs.

Tests

Add tests to validate address computation. Maybe do this in the form of a set of unit tests.

BufferToPage should block at beginning, not end

The BufferToPage method currently initiates the ram -> flash transfer and blocks until completion. this should be reversed. the reason the device has two ram buffers is so that you could continuously write data to it without having the consumer wait for the flush operation.

it should be

function BufferToPage(number)
while (busy) wait;

initiateTransfer(number)
return

and the operations that read flash directly should wait as well. this way, if i'm writing a chunk of data that's larget than the ram buffer, i can initiate the flush, pop out, switch ram buffers and keep writing. the time necessary to flush a buffer to flash is less than the time necessary to fill a ram buffer.

Transparent access

See if adding the following methods/classes improves the usability:

  • overload operator[]
  • iterator class à la STL

Read status register command not working with Mega2650

I've used the library with a AT45DB011D and an Uno successfully, but when using with a Mega2650 I get nothing returned from the read status register command. I found I have to use a CS pin other than the Mega2650 SPI SS pin which is pin 53.

AT45DB041E always busy

Hi! I'm trying to interface an Arduino Leonardo to an AT45DB041E, but I seem to never be able to write to it, as it always gets stuch waiting for the device to get ready:

  SPI.begin();
  flash.setup(1);
  flash.begin();

  flash.bufferWrite(1, 0); // Aways gets stuck here
  for(int i=0;i < 256; i++)
  {
    SPI.transfer(0x00);
  }
  flash.bufferToPage(1, 0);

Any idea what am I doing wrong?

Use SPI library

Use Arduino SPI library. If the host version doesn't support it (too old) the old code may be use. It maybe wise to prompt a warning message telling the user that it may be wise to update his version.

Ref:

Wrong status read from device and subsequent pageRead failure

I'm using a Teensy 3.1 and a AT45DB161D. For some reason, the very first status code read from the chip always returns 0. This causes the dataflash library to misinitialize its member variables and subsequently, most functions don't work as expected. I've narrowed it down to the SPI mode: with SPI mode 0, it works. With SPI mode 3, the first status code is 0 and subsequent status codes are good.

Therefore two suggestions for dataflash:

  1. maybe change to SPI mode 0
  2. prevent buffer overrun in Dataflash::setup() due to deviceIndex out-of-range (e.g. choose a default chip type)

Below is a small example program to reproduce (only shows the first status code):

include <SPI.h>

define MY_SCS 10

uint8_t st;

void setup() {
Serial.begin(9600);

// initialize SPI
pinMode(MY_SCS, OUTPUT);
digitalWrite(MY_SCS, HIGH);
SPI.begin();
SPI.setDataMode(SPI_MODE3); // NO
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV2);

// enable chip
digitalWrite(MY_SCS, LOW);

// status
SPI.transfer(0xd7);
st = SPI.transfer(0);

// disable chip
digitalWrite(MY_SCS, HIGH);

}

void loop() {
Serial.println(st, HEX);
delay(1000);
}

Add documentation!

Add documentation to the Readme file.
Generate the doxygen doc and put it in the wiki.

Sector delete of sectors 0a and 0b fails

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

pageTest.ino error: test/Dummy.h: No such file or directory

I tried to compile the pageTest sketch for Uno and it gave the error:

test/Dummy.h: No such file or directory

Here is the full output:

C:\Program Files (x86)\Arduino\libraries\arduino-dataflash\DataFlash_test.cpp:4:24: fatal error: test/Dummy.h: No such file or directory

 #include "test/Dummy.h"

                        ^

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Uno.

Problem with pageRead()

Hi,

I'm working on porting your library to Energia (MSP430 Arduino like IDE). Another point : it's a version E (not a D but what are the differences ?)

After very few changements, seems to be OK except one point : pageRead() does not work reading page 0.And I can't explain why ... It's ok this other pages or using pageToBuffer()+bufferRead().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.