help with dataflash library example

I am attempting to use the dataflash library from the playground which can be found here Arduino Playground - Dataflash I have an AT45DB081D (data sheet here) http://www.atmel.com/Images/doc3596.pdf on a break out board and connected to my UNO with VCC going to the 3.3V output and the rest go to the locations specified in the library. I am trying to get the example to run so that I can build off of that. I initially got compile errors because of WProgram.h so I changed that to Arduino.h since I am using IDE 1.0. Then I got compile errors because BYTE is no longer supported so I removed that and then everything compiled. However, it gets to a while loop and appears to hang. I posted the sketch right up to the point where it hangs and I notated it in the code where I get to. I also tried the library in its original format with IDE 0023 with the same results. I also tried a second AT45DB081D on a breadboard Arduino running an 8mhz internal clock which also gave the same results.

#include <dataflash.h>

int lastpage=0; //last page written to
int pages=5; //total pages that will be used changed from 25 to 5
Dataflash dflash; 

void setup()
{
  Serial.begin(115200);
  Serial.print('h');
  Serial.print('i');
  Serial.print('\n');//debug
  dflash.init(); //initialize the memory (pins are defined in dataflash.cpp
}

void loop()
{
  int j = 0;
  int i = 0;
  char messageline[] = "This is only a test on page: ";
  char lpstring[] = "lastpage: ";
  char int_string[10];

  itoa(lastpage, int_string, 10); // make string of the pagenumber
  strcat(messageline, int_string); //append to the messagline string
  //for (int i=0; messageline[i] != '\0'; i++){
  while (messageline[i] != '\0'){
    Serial.print(messageline[i]); //This prints the first letter of the array and then stops
    dflash.Buffer_Write_Byte(1, i, messageline[i]);  //it seems to get hung here and it does not loop through
    Serial.println("transmitting"); //this never prints so I assume it gets hung above
    j = i;
    i++;
  }
//my output looks like this

 hi 
T

I have never seen a while loop hang before so I am a little lost as to what to try next. Any suggestions on how I can troubleshoot this are appreciated.

I have never seen a while loop hang before

Which while loop do you think is hanging? I don't think that is your problem.

  char messageline[] = "This is only a test on page: ";
  char lpstring[] = "lastpage: ";
  char int_string[10];

  itoa(lastpage, int_string, 10); // make string of the pagenumber
  strcat(messageline, int_string); //append to the messagline string

messageline is exactly large enough to hold the text you provided and the trailing NULL. There are exactly 0 bytes extra, in which you try to store at least one more byte. Fail.

Now that you have stomped on memory you don't own, unpredictable results will occur. It is not even worth the effort to read further. You absolutely MUST fix this problem before we can even think about looking at the rest of the code.

PaulS- I made the suggested change to the array and initialize it with plenty of extra room. This unfortunately had no effect. I spent more time going over everything I realized that I had incorrectly introduced Arduino.h into the library and fixing that helped somewhat. Then I spent some more time reading the datasheet and trying things which has also netted some results. According to the library Pins 3 (reset) and pin 5 (WP) should be put into Arduino digital pins 7 and 8 which is what I had been doing. When I had it wired like this the while loops would usually hang. Based on the data sheet these should be run to VCC so I connected them to the 3.3V pin on the Arduino. Moving WP and reset to VCC had a big impact and suddenly the while loops were not getting hung. The issue I seem to have now is that I am getting all zeros back when reading the buffer. I am not sure how to diagnose if the issue on the read side or if I am not getting the data stored. Any suggestions on how to do this are appreciated!

I made the suggested change to the array and initialize it with plenty of extra room. This unfortunately had no effect.

I can't see the changes that you made.

Here is the block of code that I changed, the rest is the same.

  char messageline[35] = "this is only a test on page: "; 
  char lpstring[15] = "lastpage: ";
  char int_string[10];
//here is the output I am getting. I was getting all zeros and today I get 255 and I cant explain why.
This is only a test on page: 0	lastpage: 0
This is only a test on page: 1	lastpage: 1
This is only a test on page: 2	lastpage: 2
This is only a test on page: 3	lastpage: 3
This is only a test on page: 4	lastpage: 4
This is only a test on page: 5	lastpage: 5
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255  page: 32

the rest is the same.

That can't be, to produce the output you show. Humor me, and post all the code.

PaulS- here is all the code. One thing I did notice is that there is a Serial.print('\t'): which never prints in the output. I am not sure what that means but I suspect it is significant.

#include <dataflash.h>


int lastpage=0; //last page written to
int pages=5; //total pages that will be used changed from 25 to 5
Dataflash dflash; 

void setup()
{
  Serial.begin(115200);
  Serial.write('h');
  Serial.write('i');
  Serial.write('\n');//debug
  dflash.init(); //initialize the memory (pins are defined in dataflash.cpp
}

void loop()
{
  
  char messageline[35] = "This is only a test on page: ";
  char lpstring[15] = "lastpage: ";
  char int_string[10];

  itoa(lastpage, int_string, 10); // make string of the pagenumber
  strcat(messageline, int_string); //append to the messagline string
  
  int j = 0;
  int i = 0;
  while (messageline[i] != '\0'){
    Serial.write(messageline[i]); //just a check to see if the loop is working
    dflash.Buffer_Write_Byte(1, i, messageline[i]);  //write to buffer 1, 1 byte at the time
    j = i;
    i++;
  }
  i=0;
  dflash.Buffer_Write_Byte(1, j+1, '\0'); //terminate the string in the buffer
  Serial.print('\t');
  dflash.Buffer_To_Page(1, lastpage); //write the buffer to the memory on page: lastpage

    strcat(lpstring, int_string);
  for(int i=0; lpstring[i] != '\0';i++)
  {
    dflash.Buffer_Write_Byte(2, 20, lpstring[i]); //write to buffer 2 the lastpage number that was used

    Serial.print(lpstring[i]); //write to serial port the lastpage number written to
  }
  Serial.println();
  lastpage++;
  if (lastpage > pages) //if we reach the end of the range of pages
  {
    lastpage = 0;
    for (int i=0;i<=pages;i++)
    {
      dflash.Page_To_Buffer(i, 1);//copy page i to the buffer

      for(int j=0;j<32;j++) //32 depends on the amount of data on the page
        // testing for a specific charater is also possible
      {
        Serial.print(dflash.Buffer_Read_Byte(1, j)); //print the buffer data to the serial port
      }
      Serial.print("  page: "); 
      Serial.println(i); //print the last read page number
    }
  }
  delay(200); //slow it down a bit, just for easier reading
}

Here is the output based on the code above.

This is only a test on page: 0	lastpage: 0
This is only a test on page: 1	lastpage: 1
This is only a test on page: 2	lastpage: 2
This is only a test on page: 3	lastpage: 3
This is only a test on page: 4	lastpage: 4
This is only a test on page: 5	lastpage: 5
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255  page: 0
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255  page: 1
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255  page: 2
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255  page: 3
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255  page: 4
255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255255  page: 5

One thing I did notice is that there is a Serial.print('\t'): which never prints in the output. I am not sure what that means but I suspect it is significant.

That's a tab character. Exactly what the receiver is supposed to do with it is not defined. To some, it means something. To others, it is meaningless.

  Serial.write('h');
  Serial.write('i');
  Serial.write('\n');//debug

Why are you sending these characters as binary data?

Here is the output based on the code above.

I don't see hi...

  i=0;
  dflash.Buffer_Write_Byte(1, j+1, '\0'); //terminate the string in the buffer

Swap the order of these, and get rid of j.

  dflash.Buffer_To_Page(1, lastpage); //write the buffer to the memory on page: lastpage

lastPage is not a buffer. So, what, exactly is this function call doing? Where, specifically, is it writing to on the page?

What is the first argument to both of the functions?

      dflash.Page_To_Buffer(i, 1);//copy page i to the buffer

Since when is 1 a buffer?

It appears that you are writing data to the flash, and then dumping garbage over the top of it.

Then, the garbage trashes memory when you misuse the Page_To_Buffer() method. After that, you can't reasonably expect ANYTHING to work.

PaulS- Just to clarify this code was the example provided in the library and I didn't write any of it. I am just attempting to get it working and learn in the process. The original code was written by ATMEL for the butterfly to work with the external SPI flash memory. Someone took that and turned it into a library and created this example. I am just learning so I don't understand all of it but I will try to answer as best I can and try your suggestions.

Serial.write('h');
Serial.write('i');
Serial.write('\n');//debug

Why are you sending these characters as binary data?

I have no idea why they did this in the example code but I do get "hi" at the start of the output. I did not post that since the output loops and the initial data was overwritten quickly and I did not stop the output quick enough to get it. But it does output properly.

dflash.Buffer_Write_Byte(1, j+1, '\0'); //terminate the string in the buffer
dflash.Buffer_To_Page(1, lastpage); //write the buffer to the memory on page: lastpage
What is the first argument to both of the functions?

The first argument to both of these is specifying to use buffer 1. There are 2 buffers and you can either write to either buffer 1 or buffer 2. If I understand everything correctly (and I may not) the buffer_Write_Byte function writes to buffer 1 with index j +1 which was the last written index +1 and it puts a NULL termination at the end of it. Once the buffer is written function Buffer_To_Page is called and the 1 specifies that buffer 1 should be written to the page lastpage which is a variable from 0-5.

Since when is 1 a buffer?

it is not a buffer, it just specifies which buffer to use. In this case either buffer 1 or 2 can be used and this code species buffer 1.

lastPage is not a buffer. So, what, exactly is this function call doing? Where, specifically, is it writing to on the page?

I don't have a good answer for that. I am trying to read the datasheet and files in the library but progress is sloooooow. I am reading as much as I can so I can try to understand all the logic in the library which is why my replies are slow. I will keep trying to understand this and see if I can come up with an answer.

If I understand everything correctly (and I may not) the buffer_Write_Byte function writes to buffer 1 with index j +1 which was the last written index +1 and it puts a NULL termination at the end of it.

It does, but the value in j is the same value in i, before you reset i. Use i in the Buffer_Write_Byte() function before you reset it, and you don't need j.

Once the buffer is written function Buffer_To_Page is called and the 1 specifies that buffer 1 should be written to the page lastpage which is a variable from 0-5.

OK, so Buffer_To_Page is what commits the buffer to the flash memory. Prior to that, the data was being written to the buffer only.

So, what, exactly is this function call doing? Where, specifically, is it writing to on the page?

Never mind. You've answered that, already.

The Page_To_Buffer() method, then, is doing the reverse - getting data from the flash into a buffer, one page at a time.

I have finally had some success! I wrote a test sketch that wrote to buffer 1 and then read buffer 1 without ever transferring it to the a page. This failed which lead me to believe that it was a wiring issue. I used the voltmeter and did find a jumper on my break out board which I corrected. This still did not correct the issue though. Then I found that my UNO has 2 GND pins and one of them only gets very intermittent connectivity. So I moved the GND jumper wire over to the second GND socket and everything started to work. I can write to the buffer, write the buffer to a page and then read it all back properly now.

However I do still have an issue. This setup is using an UNO but my final application is an SMT application and I had the PCB's made already. The chip select pin is typically pin 10 but I used pin 9. I figured it would be easy enough to change the pin in the CPP file for the library. So I made the following change to the CPP file and I moved the Chip Select jumper from UNO pin 10 to pin 9.

#define SLAVESELECT  9//ss pin assignment was 10 and I change to 9.

As soon as I recompile the sketch and try to run it on the UNO with no other changes the initial while loop that tries to write to the buffer hangs. As soon as I change the SLAVESELECT back to pin 10 (and move the CS jumper wire) it works perfectly again. Is there someplace else I should be looking to change the pin assignment?