6 Replies Latest reply on Jan 10, 2018 8:22 PM by webmstreric

    SPI to External FLASH

    mkochhal

      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.

        • 1. Re: SPI to External FLASH
          mkochhal

          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

          • 2. Re: SPI to External FLASH
            jone_yi_1844281

            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!)!

            • 3. Re: SPI to External FLASH
              mkochhal

              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

              • 4. Re: SPI to External FLASH
                lallaw10

                any updates

                • 5. Re: SPI to External FLASH
                  mkochhal

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

                  • 6. Re: SPI to External FLASH
                    webmstreric

                    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 driver paging is broken particularly on Macronix sflash(WICED 6.0.1)

                     

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

                    1 of 1 people found this helpful