SPIFBlockDevice not erasing or writing to the SST26VF016 on MK64F

Hello,

I’ve run into an issue with the SPIFBlockDevice driver when trying to work with the SST26VF016 on the MK64F. I’m simply trying to run GitHub - ARMmbed/mbed-os-example-blockdevice: The Mbed OS block device example, but I see some strange behaviors.

  • The erase call returns a SPIF_BD_ERROR_INVALID_ERASE_PARAMS error.
  • The write call does not update the bits, and the read call always returns the old values.

Is there any additional configuration of the spif driver needed to work with this memory chip?

Hi Kyle,

could you specify what version of Mbed OS you are using as this may help you get an answer?

Thanks
Anna

Hi Anna,

I’m on the latest version, 6.2.

@AnnaBridge is anyone able to help on this?

Hi Kyle, I’ve asked internally if there is anyone that could help at the moment.

1 Like

Hi Kyle,

an internal ticket has been raised and will be planned in for investigation at some point (other priorities not withstanding).

Regards
Anna

Some additional info:

When I run the example, if a full erase has been triggered, it will still fail, but it appears to read and write with an offset. This may be related to the erase error:

image

And here’s the code, only real modification is the addition of the spi code to trigger the full chip erase.

Code

#include “mbed.h”

#include “SPIFBlockDevice.h”

FileHandle *mbed::mbed_override_console(int)

{

static BufferedSerial serial(PTC15, PTC14);  //Use for CFG 1 varients

return &serial;

}

// Create flash device on SPI bus with PTE5 as chip select

SPIFBlockDevice spif(PTD2, PTD3, PTD1, PTD0, 20000000);

SPI spi(PTD2, PTD3, PTD1, PTD0);

unsigned char block_protection_10[18];

void WriteEnable(void) {

spi.select();

spi.write(0x06);

spi.deselect();

}

void ClearBlockProtect(void) {

unsigned char i = 0;

block_protection_10[0] = 0x00;

block_protection_10[1] = 0x00;

block_protection_10[2] = 0x00;

block_protection_10[3] = 0x00;

block_protection_10[4] = 0x00;

block_protection_10[5] = 0x00;

block_protection_10[6] = 0x00;

block_protection_10[7] = 0x00;

block_protection_10[8] = 0x00;

block_protection_10[9] = 0x00;

block_protection_10[10] = 0x00;

block_protection_10[11] = 0x00;

block_protection_10[12] = 0x00;

block_protection_10[13] = 0x00;

block_protection_10[14] = 0x00;

block_protection_10[15] = 0x00;

block_protection_10[16] = 0x00;

block_protection_10[17] = 0x00;

WriteEnable();

spi.select();

spi.write(0x42);

for (i = 18; i > 0; i--) {spi.write(block_protection_10[i - 1]);}

spi.deselect();

}

void ChipErase(void) {

ClearBlockProtect();

WriteEnable();

spi.select();

spi.write(0xC7);

spi.deselect();

}

int main()

{

//DigitalOut wp(PTB19);

printf("spif test\n");



// Initialize the SPI flash device, and print the memory layout

spif.init();

printf("spif size: %llu\n",         spif.size());

printf("spif read size: %llu\n",    spif.get_read_size());

printf("spif program size: %llu\n", spif.get_program_size());

printf("spif erase size: %llu\n",   spif.get_erase_size());

ThisThread::sleep_for(1);

// Write "Hello World!" to the first block

char *buffer = (char *)malloc(spif.get_erase_size());

sprintf(buffer, "Hello World!\n");



int rc = spif.erase(0, spif.get_erase_size());

if(rc != 0){

    printf("Erase Failed: %d\n", rc);

}

rc = spif.program(buffer, 0, spif.get_erase_size());

if(rc != 0){

    printf("Program Failed: %d\n", rc);

}

sprintf(buffer, "NOPE\n");

// Read back what was stored

rc = spif.read(buffer, 0, spif.get_erase_size());

if(rc != 0){

    printf("Read Failed: %d\n", rc);

}

printf("Contents: %s\n", buffer);

// Deinitialize the device

spif.deinit();

}

Hi Kyle,

Thanks for sharing the code which has given bit more context on this issue.

Key points from this flash device datasheet

  1. Uniform 4 KByte erasable sectors with eight 8KByte parameters.
  2. Also, it has two 32 KByte and 30 64 KByte erasableoverlay blocks.

This flash device erasable sector sizes are not uniform and differ based on an address which is requested in erase() API

In Mbed OS, SPIFBlockDevice::get_erase_size() API returns the minimum erase size supported by this flash, which is 4KB when there is no address argument. In your application, erase() API is using get_erase_size() for in_size argument which becomes 4KB. But erase() API implementation contains an internal pre-erase check that compares the requested erase size (4KB) with the specific get_erase_size(addr) (32KB or 64KB) and finds that they don’t match, which might be a reason for the error observed.

We are recommending to use this get_erase_size(bd_addr_t addr) API and addr argument should be the same as the one passed to erase() API and to see whether that helps.

Thanks @raj85kumar.

@kyle_spinnaker So, in the example you call spif.erase(0, ...) at address 0. Similarly could you replace spif.get_erase_size() with spif.get_erase_size(0) and please let us know if the issue goes away? Thanks in advance!

Edit: If this doesn’t work, could you help us to identify which line SPIF_BD_ERROR_INVALID_ERASE_PARAMS is reported? (There are three in in SPIFBlockDevice.cpp.)

Hi @ldong

Thanks for the response. That did not fix the issue.

After looking at this on a logic analyzer, we think it actually may have to do with the use of dummy bytes on the driver, some of the data certain reads is being dropped due to the driver sending a dummy byte when none is expected.

We believe the issue may be with the following lines in SPIFBlockDevice.cpp around line 480.

// Write Dummy Cycles Bytes

for (uint32_t i = 0; i < dummy_bytes; i++) {

    _spi.write(dummy_byte);

}

// Read Data

for (bd_size_t i = 0; i < size; i++) {

    buffer[i] = _spi.write(0);

}

Looking at the logic analyzer, it seems that the spif is sending the first byte of data on some reads in response to the dummy byte, causing offset problems and I believe also a problem getting the regions from the chip.

Hi @kyle_spinnaker,

In your initial question,

Does this still happen? Could you identify which line of SPIFBlockDevice.cpp the error comes from (there are three possibilities)?

Hi Kyle,

You seem to have encountered a different issue. As we do not support your flash device, we cannot offer you more support. As an open-source project, we welcome fixes to Mbed OS, so if you find an issue with the SPIFBlockDevice and would like to contribute a fix then we would very much welcome that.

Hi @raj85kumar,

I have similar issues with this flash chip. I unfortunately cannot afford to debug this issue and would like to use another flash chip instead. Do you maintain a list of tested flash chips with Mbed OS?

@ldong @raj85kumar I would like to up this as I do not want to order another incompatible flash chip. A list of tested flash ICs would be appreciated.

@boraozgen Hi, built-in flash chips on our supported targets are tested, and chips from the same series as an on-board flashes (e.g. with different capacities) are mostly likely to work too.

We were able to identify the problem and create a custom port. It appears that the mbed driver incorrectly inserts dummy bytes into certain read operations, causing data the be dropped.

@kyle_spinnaker Good to know you’ve resolved the issue :+1: Please feel free to create a pull request on GitHub, or let us know the exact problem, thanks :slight_smile:

@ldong thank you for the information, I will check it out. I still think a list of supported chips would be helpful to users.

@kyle_spinnaker Way to go! It would be great if you could share the changes on GitHub.