SPI to External FLASH

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi.

I am using the MACRONIX MX25L1606E, 16MB flash as the external flash with SPI as an interface to it from the 43341 module.

I am able to repurpose the jedec_id command and I am able to successfully read the JEDEC ID value:

/* Prepare a message to read spi flash JEDEC ID */

    /* First segment is a write segment */

    segments[0].tx_buffer = &jedec_id_command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* Second segment is a read segment */

    segments[1].tx_buffer = NULL;

    segments[1].length = 3;

    segments[1].rx_buffer = jedec_id_value;

    /* Transfer two segments */

    wiced_spi_transfer( &wiced_spi_flash, segments, 2 );

I tried to use the same to write some data using program page command (0x02) and read from the same location to confirm. However, wiced_spi_transfer() does not return any error during write or read ...here is the sample code ...

/* ------------------------------------------------------------------------ JEDEC id*/

    read_jedec();

/* ------------------------------------------------------------------------ Write Enable */

    command = 0x06;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* SPI transfer segment */

    wiced_spi_transfer( &wiced_spi_flash, segments, 1);

    /* ------------------------------------------------------------------------ Read the status register */

    command = 0x05;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* Second segment is a read segment */

    segments[1].tx_buffer = NULL;

    segments[1].length = 1;

    segments[1].rx_buffer = &(command_value[0]);

     wiced_spi_transfer( &wiced_spi_flash, segments, 2 );

    printf("Read the Status Register value as %u\n", command_value[0]);

    /* ------------------------------------------------------------------------ Write Data */

    command = 0x02;

    command_value[0] = 0x01;

    command_value[0] = 0x02;

    command_value[0] = 0x03;

    memset(data_out, 0, MAX_DATA_OUT);

    memset(data_in, 0, MAX_DATA_OUT);

    data_out[0] = command;

    data_out[1] = 0x07;

    data_out[2] = 0x00;

    data_out[3] = 0x00;

    data_out[4] = 0x01;

    data_out[5] = 0x02;

    data_out[6] = 0x03;

    data_out[7] = 0x04;

   

    segments[0].tx_buffer = data_out;

    segments[0].length = 8;

    segments[0].rx_buffer = NULL;

    result = wiced_spi_transfer( &wiced_spi_flash, segments, 1);

    if(result != WICED_SUCCESS) {

        printf("Error writing to serial flash\n");

    }

    /* ------------------------------------------------------------------------ Write Disable */

    /* First segment is a write segment */

    command = 0x04;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /*SPI transfer segment */

    wiced_spi_transfer( &wiced_spi_flash, segments, 1);

  

    /* ------------------------------------------------------------------------ Read the status register */

    command = 0x05;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* Second segment is a read segment */

    segments[1].tx_buffer = NULL;

    segments[1].length = 1;

    segments[1].rx_buffer = &(command_value[0]);

    wiced_spi_transfer( &wiced_spi_flash, segments, 2 );

    printf("Read the Status Register value as %u\n", command_value[0]);

  

    /* ------------------------------------------------------------------------ Read */

    command = 0x03;

    memset(data_out, 0, MAX_DATA_OUT);

    memset(data_in, 0, MAX_DATA_OUT);

    data_out[0] = command;

    data_out[1] = 0x07;

    data_out[2] = 0x00;

    data_out[3] = 0x00;

      

    segments[0].tx_buffer = data_out;

    segments[0].length = 4;

    segments[0].rx_buffer = NULL;

   

    /* Second segment is a read segment */

    segments[1].tx_buffer = NULL;

    segments[1].length = 4;

    segments[1].rx_buffer = data_in;

 

    result = wiced_spi_transfer( &wiced_spi_flash, segments, 2 );

    if(result != WICED_SUCCESS) {

        printf("Error reading from serial flash\n");

    }

I have looked at the sample code at libraries/drivers/spi_slave/master/spi_master.c and I wish to repurpose it, however I don't have an SPI slave (as in the External Flash is the SPI slave) and I don't use any of the GPIOs for the data ready pin.

0 Likes
6 Replies
Anonymous
Not applicable

I get the following output:

Starting WICED v3.5.1

Platform ISM43341_M4G_L44 initialised

Started ThreadX v5.6

Initialising NetX_Duo v5.7_sp2

Creating Packet pools

WWD SDIO interface initialised

WLAN MAC Address : C4:7F:51:80:27:95

WLAN Firmware    : wl0: Oct 13 2014 15:25:13 version 6.10.190.51 (r507746) FWID 01-60cadeb3

Initialising

*** SPI TEST

Flash ID = C2 20 15

*** SPI TEST: SUCCEED

Read the Status Register value as 2

Read the Status Register value as 0

0x00 0x00 0x00 0x00

0 Likes

You should erase the flash first before write if flash already had programmed data on it!

Need to wait  the flash ready after erase or write (it take time too!)!

0 Likes
Anonymous
Not applicable

Jone,

Hi.

Thanks for the reply. I tried the chip erase. I have also put a 20 second wait for the chip erase to finish (which is actually the maximum time for the MACRONIX flash chip). However, when I read it after (write enable is disabled), I still read a 0 instead of 0xff ...

/* ------------------------------------------------------------------------ JEDEC id*/

    read_jedec();

/* ------------------------------------------------------------------------ Write Enable */

    command = 0x06;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* Transfer the segment */

    wiced_spi_transfer( &wiced_spi_flash, segments, 1);

    /* ------------------------------------------------------------------------ Read the status register */

    command = 0x05;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* Second segment is a read segment */

    segments[1].tx_buffer = NULL;

    segments[1].length = 1;

    segments[1].rx_buffer = &(command_value[0]);

    wiced_spi_transfer( &wiced_spi_flash, segments, 2 );

    printf("Read the Status Register value as %u\n", command_value[0]);

    /* ------------------------------------------------------------------------ chip erase */

    /* First segment is a write segment */

    printf("Chip Erase in Progress \n");

    command = 0xC7;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* Transfer the segment */

    wiced_spi_transfer( &wiced_spi_flash, segments, 1 );

    //Delay for 20 seconds

    wiced_rtos_delay_milliseconds( 20000 );

     /* ------------------------------------------------------------------------ Write Disable */

    /* First segment is a write segment */

    command = 0x04;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

  

    /* Transfer the segment */

    wiced_spi_transfer( &wiced_spi_flash, segments, 1);

 

     /* ------------------------------------------------------------------------ Read the status register */

    command = 0x05;

    segments[0].tx_buffer = &command;

    segments[0].length = 1;

    segments[0].rx_buffer = NULL;

    /* Second segment is a read segment */

    segments[1].tx_buffer = NULL;

    segments[1].length = 1;

    segments[1].rx_buffer = &(command_value[0]);

    wiced_spi_transfer( &wiced_spi_flash, segments, 2 );

    printf("Read the Status Register value as %u\n", command_value[0]);

    /* ------------------------------------------------------------------------ Read */

    command = 0x03;

    memset(data_out, 0, MAX_DATA_OUT);

    memset(data_in, 0, MAX_DATA_OUT);

    data_out[0] = command;

    data_out[1] = 0x00;

    data_out[2] = 0x00;

    data_out[3] = 0x00;

 

    segments[0].tx_buffer = data_out;

    segments[0].length = 4;

    segments[0].rx_buffer = NULL;

  

    /* Second segment is a read segment */

    segments[1].tx_buffer = NULL;

    segments[1].length = 8;

    segments[1].rx_buffer = data_in;

    result = wiced_spi_transfer( &wiced_spi_flash, segments, 2 );

    if(result != WICED_SUCCESS) {

        printf("Error reading from serial flash\n");

    }

    //printf("Read the Status Register value as %u\n", command_value[0]);

    dump_bytes(data_in, 8);

                                                                                     

Starting WICED v3.5.1

Platform ISM43341_M4G_L44 initialised

Started ThreadX v5.6

Initialising NetX_Duo v5.7_sp2

Creating Packet pools

WWD SDIO interface initialised

WLAN MAC Address : C4:7F:51:80:27:95

WLAN Firmware    : wl0: Oct 13 2014 15:25:13 version 6.10.190.51 (r507746) FWID 01-60cadeb3

Initialising

*** SPI TEST

Flash ID = C2 20 15

*** SPI TEST: SUCCEED

Read the Status Register value as 2

Chip Erase in Progress

Read the Status Register value as 0

0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

0 Likes
Anonymous
Not applicable

any updates

0 Likes
Anonymous
Not applicable

nothing much progress on this front. I will probably start working on this issue by mid-may or June.

0 Likes
Anonymous
Not applicable

I ran into the same problem where writing to the MX25L16060E sflash chip would write the wrong numbers to the sflash. This is the chip that is normally used on the ISMART ISM43340 demo board from Inventek. It turns out the paging used by the WICED sflash driver is broken. Consequently for many supported chips It only sends a single byte of data to the sflash at a time and then waits for that to complete before sending the next byte. For the Over the Air Update(OTA) process that I am working on we are typically downloading 600,000 bytes or more. This takes a very long time.

The simplest way to fix this problem is to disable paging on the Macronix chips by setting max_write_size=1 in sflash_write(). I created a patch that fixes this problem in a different thread. I made the default page size 256 bytes and if you are using any sflash chips that will not work with that, you will need to add them to the list of chips where paging is disabled. Here is the link:

sflash paging used by download_apps in WICED 6.0.1 is broken particularly on Macronix sflash

"https://community.cypress.com/message/149694#149694"