SPI Issues writing to W25Q64FV with SerialFlash Library
Posted: 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:
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
The SerialFlash.write looks like this:
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?
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
sig: FFFFFFFF FFFFFFFF
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;
}
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();
SPIPORT.beginTransaction(SPICONFIG);
CSASSERT();
// write enable command
SPIPORT.transfer(0x06);
CSRELEASE();
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
CSASSERT();
if (flags & FLAG_32BIT_ADDR) {
SPIPORT.transfer(0x02); // program page command
SPIPORT.transfer16(addr >> 16);
SPIPORT.transfer16(addr);
} else {
SPIPORT.transfer16(0x0200 | ((addr >> 16) & 255));
SPIPORT.transfer16(addr);
}
addr += pagelen;
len -= pagelen;
do {
SPIPORT.transfer(*p++);
} while (--pagelen > 0);
CSRELEASE();
busy = 4;
SPIPORT.endTransaction();
} while (len > 0);
}
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?