drewrisinger
Member
Hi. I'm using a TeensyLC & Winbond W25Q128FV flash memory chip with the latest version of SerialFlash. I tried running the example code (EraseEverything & RawHardwareTest), using all default settings. It appears to not consistently read information back from the flash memory chip, because of what my best efforts identify as a timing issue. I also posted this to https://github.com/PaulStoffregen/SerialFlash/issues/16
So the issues are:
The relevant Arduino sketch code (run from the Arduino environment) is:
I double-checked all wires are hooked into the correct MISO/MOSI/CS/SCLK, as well as GND & Vcc. I then hooked it up to an oscilloscope, and was able to produce the following scope screenshots:
Only once out of about 10 times was the scope able to read the correct values for the sequence, which should be: MOSI 94 00 00 00, then MISO 00 EF 40 18. The scope is configured with the following assignments: D0->CS, D2->MOSI, D3->SCLK, D4->MISO.
My best guess is that the memory chip, as soon as it receives the 94 (read ID) command, latches on the value for the first clock cycle for the data return, a 1 for the MSB of EFh (cursor a), and then after about 700-800ns without a clock cycle relaxes to 0 (cursor b). This code was likely developed and run mostly on a Teensy3, which has a higher clock rate, so the intervening 700-800ns between SPI data transfers would be reduced, so this issue likely would not have been seen. Can you confirm or provide possible solutions?
The following are my suggested solutions based on my assessment of the issue:
So the issues are:
- Can't read Identification bytes from chip (likely because of timing issue)
- Erasing entire flash memory takes <2 seconds (for 128 Mbit flash). While this isn't an issue, I'm more just unaware if the chip is smart enough to know that most sectors are still erased, and so doesn't need erased and can speed it up
The relevant Arduino sketch code (run from the Arduino environment) is:
Code:
SerialFlash.begin(FlashChipSelect);
unsigned char id[3];
SerialFlash.readID(id);
Serial.print("ID:"); Serial.print(id[0], HEX); Serial.print(id[1], HEX); Serial.println(id[2], HEX);
unsigned long size = SerialFlash.capacity(id);
I double-checked all wires are hooked into the correct MISO/MOSI/CS/SCLK, as well as GND & Vcc. I then hooked it up to an oscilloscope, and was able to produce the following scope screenshots:
Only once out of about 10 times was the scope able to read the correct values for the sequence, which should be: MOSI 94 00 00 00, then MISO 00 EF 40 18. The scope is configured with the following assignments: D0->CS, D2->MOSI, D3->SCLK, D4->MISO.
My best guess is that the memory chip, as soon as it receives the 94 (read ID) command, latches on the value for the first clock cycle for the data return, a 1 for the MSB of EFh (cursor a), and then after about 700-800ns without a clock cycle relaxes to 0 (cursor b). This code was likely developed and run mostly on a Teensy3, which has a higher clock rate, so the intervening 700-800ns between SPI data transfers would be reduced, so this issue likely would not have been seen. Can you confirm or provide possible solutions?
The following are my suggested solutions based on my assessment of the issue:
- Speed up or reduce the library code that happens between transfers.
- Manually set the SPI control registers to read on falling edge, the CPOL (either using SPISettings or direct register writes)
- Make all commands some sort of variant on transfer16, which theoretically would have the clocked bytes transferred without any pause.