SPI Issues writing to W25Q64FV with SerialFlash Library

Posts: 1
Joined: Mon Mar 04, 2019 5:46 am

SPI Issues writing to W25Q64FV with SerialFlash Library

Postby marsthrax » Mon Mar 04, 2019 6:17 am

I'm trying to use a Teensy Prop Shield in combination with an Adafruit ESP32 Feather. I am having issues writing to the SPI flash memory on board the Prop Shield. As I understand, the CS pin is connected to Pin 13, and configuring it to use that pin appears to let me erase the memory (SerialFlash.eraseAll() appears to overwrite all memory with 0xFF successfully). The recommended library for the prop shield is SerialFlash (https://github.com/PaulStoffregen/SerialFlash).

Unfortunately, when I try to create a file, the writes themselves appear to be corrupted somehow. I added debugging to print out what the library is trying to write, and what is actually read back after the write:

Code: Select all

Read Chip Identification:
  JEDEC ID:     F7 20 B
  Part Nummber:   Memory Size:  1048576 bytes
  Block Size:   65536 bytes
To Write: FA96554C 18F60258
Writing signature
WR: addr 00000000, len 8
WR: addr 00000000, pagelen 8
Reading back write, verifying sig
sig: 00000000
sig: 7DCB2A26 0C7B012C

The first "sig" line is all 0xFF because of the SerialFlash.eraseAll() call I have earlier in my initialization.
The "To Write" shows the array of two uint32_t that is being written
The second "sig" is the address to write at (0x00)
The third "sig" is what was actually read back when verifying. The first uint32 should be the magic word (FA96554C), while the second should be the maximum number of files and the string size (18F60258)

From the library, this is what is happening

Code: Select all

static uint32_t check_signature(void)
        uint32_t sig[2];

        SerialFlash.read(0, sig, 8);
        Serial.printf("sig: %08X %08X\n", sig[0], sig[1]);
        if (sig[0] == 0xFA96554C) return sig[1];
        if (sig[0] == 0xFFFFFFFF) {
                sig[0] = 0xFA96554C;
                sig[1] = ((uint32_t)(DEFAULT_STRINGS_SIZE/4) << 16) | DEFAULT_MAXFILES;
                Serial.printf("To Write: %08X %08X\n", sig[0], sig[1]);
                Serial.println("Writing signature");
                SerialFlash.write(0, sig, 8);
                while (!SerialFlash.ready()) ; // TODO: timeout
                SerialFlash.read(0, sig, 8);
                Serial.println("Reading back write, verifying sig");
                if (sig[0] == 0xFA96554C) return sig[1];
        return 0;
The SerialFlash.write looks like this:

Code: Select all

static SPIClass& SPIPORT = SPI; //This occurs early in the file

void SerialFlashChip::write(uint32_t addr, const void *buf, uint32_t len)
        const uint8_t *p = (const uint8_t *)buf;
        uint32_t max, pagelen;

        Serial.printf("WR: addr %08X, len %d\n", addr, len);
        do {
                if (busy) wait();
                // write enable command
                max = 256 - (addr & 0xFF);
                pagelen = (len <= max) ? len : max;
                Serial.printf("WR: addr %08X, pagelen %d\n", addr, pagelen);
                delayMicroseconds(1); // TODO: reduce this, but prefer safety first
                if (flags & FLAG_32BIT_ADDR) {
                        SPIPORT.transfer(0x02); // program page command
                        SPIPORT.transfer16(addr >> 16);
                } else {
                        SPIPORT.transfer16(0x0200 | ((addr >> 16) & 255));

                addr += pagelen;
                len -= pagelen;
                do {
                } while (--pagelen > 0);
                busy = 4;
        } while (len > 0);
So, a few questions:
1) Is there something about how this library is using SPI that could cause the corruption on write?
2) Is there another library I could potentially use instead that is known to work with ESP32?
3) Any ideas on how I can debug exactly what is happening, or ideas on how to fix the apparent corruption in the write?

Who is online

Users browsing this forum: No registered users and 8 guests