Flash Memory help

Status
Not open for further replies.

Dionysus

Active member
Good afternoon! I'm using a Teensy 4.0 with the Audio shield (rev D) and I've just tried to attach a W25Q128JVSIQ-ND flash memory chip. This was unlike any soldering I've ever done before, so I'm quite willing to believe that I'd attached it pooorly or somehow destroyed it in the process, but I'm not sure how to go about debugging that.

I've been trying the verious SerialFlash examples. Starting with EraseEverything, which returns:

Code:
Flash Memory has 16777216 bytes.

Erasing ALL Flash Memory:

  estimated wait: 52 seconds.

  Yes, full chip erase is SLOW!

Erase completed

  actual wait: 0 seconds.

And then the RawHardwareTest, which gives me:
Code:
Raw SerialFlash Hardware Test



Read Chip Identification:

  JEDEC ID:     6F 40 18

  Part Nummber: (unknown chip)

  Memory Size:  16777216 bytes

  Block Size:   65536 bytes



Reading Chip...

  Previous data found at address 0

  You must fully erase the chip before this test

  found this: 7F FF 7F FF 7F FF 7F FF 

     correct: 00 00 00 00 15 F5 95 4B 



Tests Failed  :{



The flash chip may be left in an improper state.

You might need to power cycle to return to normal.

In a previous post, Paul said that all zeroes for the ID line indicated a faulty chip and, indeed, I was getting all zeroes. I went back and poked at the solder a bit, though, and now it's giving me 6F 40 18. Is that a good sign? I'm not sure how to know if the hardware is working, let alone the software.

Finally, I tried the CopyFromSD code, which was able to read the SD card, but said, "unable to create file" every time. I'll attach my version of that here—I did (eventually) remember to change the SCK to 13 and the MOSI to 11, but there might be a ton of other things that I'm missing. I'm also attaching a photo, but I'm not sure if itwill be useful.

Thank you in advance for any suggestions!

IMG_20200508_135636.jpg

Code:
#include <SerialFlash.h>
#include <SD.h>
#include <SPI.h>

const int SDchipSelect = 10;    // Audio Shield has SD card CS on pin 10
const int FlashChipSelect = 6; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash

void setup() {
  //uncomment these if using Teensy audio shield
  SPI.setSCK(13);  // Audio shield has SCK on pin 14
  SPI.setMOSI(11);  // Audio shield has MOSI on pin 7

  //uncomment these if you have other SPI chips connected
  //to keep them disabled while using only SerialFlash
  pinMode(4, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);

  Serial.begin(9600);

  // wait up to 10 seconds for Arduino Serial Monitor
  unsigned long startMillis = millis();
  while (!Serial && (millis() - startMillis < 10000)) ;
  delay(100);
  Serial.println("Copy all files from SD Card to SPI Flash");

  if (!SD.begin(SDchipSelect)) {
    error("Unable to access SD card");
  }
  if (!SerialFlash.begin(FlashChipSelect)) {
    error("Unable to access SPI Flash chip");
  }

  File rootdir = SD.open("/");
  while (1) {
    // open a file from the SD card
    Serial.println();
    File f = rootdir.openNextFile();
    if (!f) break;
    const char *filename = f.name();
    Serial.print(filename);
    Serial.print("    ");
    unsigned long length = f.size();
    Serial.println(length);

    // check if this file is already on the Flash chip
    if (SerialFlash.exists(filename)) {
      Serial.println("  already exists on the Flash chip");
      SerialFlashFile ff = SerialFlash.open(filename);
      if (ff && ff.size() == f.size()) {
        Serial.println("  size is the same, comparing data...");
        if (compareFiles(f, ff) == true) {
          Serial.println("  files are identical :)");
          f.close();
          ff.close();
          continue;  // advance to next file
        } else {
          Serial.println("  files are different");
        }
      } else {
        Serial.print("  size is different, ");
        Serial.print(ff.size());
        Serial.println(" bytes");
      }
      // delete the copy on the Flash chip, if different
      Serial.println("  delete file from Flash chip");
      SerialFlash.remove(filename);
    }

    // create the file on the Flash chip and copy data
    if (SerialFlash.create(filename, length)) {
      SerialFlashFile ff = SerialFlash.open(filename);
      if (ff) {
        Serial.print("  copying");
        // copy data loop
        unsigned long count = 0;
        unsigned char dotcount = 9;
        while (count < length) {
          char buf[256];
          unsigned int n;
          n = f.read(buf, 256);
          ff.write(buf, n);
          count = count + n;
          Serial.print(".");
          if (++dotcount > 100) {
             Serial.println();
             dotcount = 0;
          }
        }
        ff.close();
        if (dotcount > 0) Serial.println();
      } else {
        Serial.println("  error opening freshly created file!");
      }
    } else {
      Serial.println("  unable to create file");
    }
    f.close();
  }
  rootdir.close();
  delay(10);
  Serial.println("Finished All Files");
}


bool compareFiles(File &file, SerialFlashFile &ffile) {
  file.seek(0);
  ffile.seek(0);
  unsigned long count = file.size();
  while (count > 0) {
    char buf1[128], buf2[128];
    unsigned long n = count;
    if (n > 128) n = 128;
    file.read(buf1, n);
    ffile.read(buf2, n);
    if (memcmp(buf1, buf2, n) != 0) return false; // differ
    count = count - n;
  }
  return true;  // all data identical
}


void loop() {
}

void error(const char *message) {
  while (1) {
    Serial.println(message);
    delay(2500);
  }
}
 
I have a T_4.0 here with Rev D Audio with Winbond Flash installed. This is with IDE 1.8.12 and TD 1.52 B4::

Running EraseEverything worked in 45 seconds - it works with these values at the code start:
Code:
[B]const int FlashChipSelect = 6; // digital pin for flash chip CS pin[/B]
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash

SerialFlashFile file;

const unsigned long testIncrement = 4096;

void setup() {
[I]  //uncomment these if using Teensy audio shield
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7
[/I]
  //uncomment these if you have other SPI chips connected
  //to keep them disabled while using only SerialFlash
  //pinMode(4, INPUT_PULLUP);
  //pinMode(10, INPUT_PULLUP);

  Serial.begin(9600);

  // wait up to 10 seconds for Arduino Serial Monitor
  unsigned long startMillis = millis();
  while (!Serial && (millis() - startMillis < 10000)) ;
  delay(100);

[B]  if (!SerialFlash.begin(FlashChipSelect)) {[/B]

Then moving to RawHardwareTest - using the same chip select and default SPI it shows:
Code:
Raw SerialFlash Hardware Test

Read Chip Identification:
  JEDEC ID:     EF 40 18
  Part Nummber: W25Q128FV
  Memory Size:  16777216 bytes
  Block Size:   65536 bytes

Reading Chip...

Writing 8192 signatures

Double Checking All Signatures:
  all 8192 signatures read ok

Checking Signature Pairs
  all 4095 signature pairs read ok

Checking Read-While-Write (Program Suspend)
  write 256 bytes at 256
  write time was 369 microseconds.
  read-while-writing: 00 00 00 00 15 F5 95 4B 
  test passed, good read while writing

Checking Read-While-Erase (Erase Suspend)
  erase time was 221038 microseconds.
  erase correctly erased 65536 bytes
  read-while-erasing: 00 00 00 00 15 F5 95 4B 
  test passed, good read while erasing

All Tests Passed  :-)

Test data was written to your chip.  You must run
EraseEverything before using this chip for files.

Then returned to EraseEverything and it completed:
Code:
Flash Memory has 16777216 bytes.
Erasing ALL Flash Memory:
  estimated wait: 40 seconds.
  Yes, full chip erase is SLOW!
.............................................
Erase completed
  actual wait: 46 seconds.
 
Well, shoot, that's not working for me. The only difference is that I'm using the teensy loader 1.51, but I can't imagine that *that's* my problem. EraseEverything did not return "Unable to access SPI Flash Chip", but it did complete instantly.

Does this mean that I should rule out software problems and assume that I just have a faulty chip or, much more likely, installed it upside down? I'm hopeful that because it's getting the size and id of the chip that means it's communicating, but this is such a simple program and it's working on your identical hardware, so that's not a great sign.

Incidentaly, in your code you've left the audio shield and the SPI code commented. Are those not needed after all?

Thanks again!
 
Well, shoot, that's not working for me. The only difference is that I'm using the teensy loader 1.51, but I can't imagine that *that's* my problem. EraseEverything did not return "Unable to access SPI Flash Chip", but it did complete instantly.

Does this mean that I should rule out software problems and assume that I just have a faulty chip or, much more likely, installed it upside down? I'm hopeful that because it's getting the size and id of the chip that means it's communicating, but this is such a simple program and it's working on your identical hardware, so that's not a great sign.

Incidentaly, in your code you've left the audio shield and the SPI code commented. Are those not needed after all?

Thanks again!

Here is an image of my soldering - your chip seems oriented the same / properly:
View attachment 19854

Using the T_4 with Rev D Audio the default SPI are used so no commands to adjust are needed. It was needed on T_3.x boards because of an audio pin conflict and option to move the SPI pin. But the REV D layout and T_4.0 pin position doesn't require that move from default SPI ( and doesn't have that option with MCU as it is ).

Seems to be a chip or soldering issue. Where did you get the Winbond chip? I got some on ebay that were suspect and failed. These good ones came from Digikey - and I just got some more to use next.

If you have flux paste or liquid ( I got a tub of paste ) put a bit on the pads with a clean solder tip touch the pads&pins to reflow the solder - the flux helps faster heat transfer and reflow. Without separate flux it will take longer to reheat the joint and it won't reflow as well - but adding more fresh solder could cause excess and bridging needing to be removed. Solder wick can help with that - but again flux helps there too.

Make sure the pins are not bridged. Then I'd bath chip with isopropyl alcohol ( 70 or 90%) and wipe with my cleaning toothbrush, rinse again and dry. I dry after removing any excess with hairdryer in my hand until I bake it to hold-able temp and moving it around to push/evaporate out any fluid pockets (especially if the top got wet too) then let cool and finish drying before powering it up again.
 
Sounds good, I will give all of that a try! This is from digikey, as well, so that's probably good. As I say, this is the first time I've soldered anything like this, so I'm not too surprised.

Thanks!
 
Sounds good, I will give all of that a try! This is from digikey, as well, so that's probably good. As I say, this is the first time I've soldered anything like this, so I'm not too surprised.

Thanks!

Digikey chip is promising source. The bottom pads look clean enough. The top pins look a bit blobby - it is hard to work against that header strip :(

If you have de-solder wick - and hopefully flux? - I'd start with wick removing excess from those upper pins. The wick will pull off some and end up with it reheated to reflow. Then touch the pin and pad together on each with just the iron - maybe putting a touch more solder if needed though the wick usually ends up not cleaning too much without extra effort.
 
Wow. I'm so much envious! Outstanding. :D

That one did come out well :) That isn't my first - and certainly not my worst - just the one I found to post elsewhere to show the size diff between the FLASH chip and the 8MB PSRAM chip sitting off to the side.

Getting the first pin with solder on straight makes the rest go well with it held in place right.
 
I see you have a SD card in the socket. Remove it while doing these tests, so the flash chip is the only device connected to the SPI pins.

Reading 6F 40 18 for the JEDEC ID is a very good sign your chip is good and this may work once we figure out what's going wrong.
 
If you have a multimeter, perhaps put it in continuous mode (may have a speaker or music icon) and touch the probes to every leg next to each other. If you hear a beep, it means there is a bridge in your solder between the two legs.
 
Thank you all for the help! It turns out that solder braid is a thing—who knew?!—and that helped me clean up my soldering enormously and, I think, fixed that problem.

However, whenever I plug in my touchscreen it is no longer able to access the flash chip. I removed everything, and re-soldered all my wires, and then tested it one at a time, running CopyFromSD. Adding each pin from the touchscreen was fine—the program said, "already exists on the Flash chip".

However, as soon as I connected the T_DO to pin 12, it says "unable to create file".

Is it possible to use a different pin? Maybe pin 34, which I see is labled "MISO2"?

Thanks again for all the help!
 
Solder braid ... ds-solder wick - is a cool thing ... but gets really hot using it.

Touchscreen: Did it get its own CS pin unique and not used by anything else - one for display and one for touch? and specified in the .begin()? Not sure what the display and touch controller is - hopefully it properly tri-states the DO line. Otherwise DO shared for SPi will have an issue.

The MISO2 line is on SPI2 so it won't work with SPI
 
The touchscreen is using pin 8 as it's CS pin for touch detection and pin 14 for the display. Pin 14 is also the SCK for the audio board SD card, but that doesn't seem to be causing any problems (which is to say, when I haven't connected the touch part of the screen, it can read the SD card and write to the chip).

SD.begin() specifies pin 10 for the SD Card and SerialFlash.begin() specifies 6 for the flash chip. I'll post the first half of the code here; I haven't made any changes to the second half from the example:

Code:
#include <SerialFlash.h>
#include <SD.h>
#include <SPI.h>

const int SDchipSelect = 10;    // Audio Shield has SD card CS on pin 10
const int FlashChipSelect = 6; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash

void setup() {
  //uncomment these if using Teensy audio shield
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7

  //uncomment these if you have other SPI chips connected
  //to keep them disabled while using only SerialFlash
  //pinMode(4, INPUT_PULLUP);
  //pinMode(10, INPUT_PULLUP);

  Serial.begin(9600);

  // wait up to 10 seconds for Arduino Serial Monitor
  unsigned long startMillis = millis();
  while (!Serial && (millis() - startMillis < 10000)) ;
  delay(100);
  Serial.println("Copy all files from SD Card to SPI Flash");

  if (!SD.begin(SDchipSelect)) {
    error("Unable to access SD card");
  }
  if (!SerialFlash.begin(FlashChipSelect)) {
    error("Unable to access SPI Flash chip");
  }

  File rootdir = SD.open("/DATA");
 
Yes, you're absolutely right, of course. Well, that explains why there wasn't a conflict with the screen display CS being on pin 14!
 
Unfortunately, there is apparently still some conflict with the T_DO pin, and the flash chip, because when I connect the touchscreen it can no longer access the flash card.

Is there a way to disable the touchscreen while I'm using the flash, somehow?

Thanks again!
 
Status
Not open for further replies.
Back
Top