xCORE-200 QuadSPI Write Flash Data

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
CrAzIaNhAx
Member
Posts: 10
Joined: Thu Mar 17, 2016 7:25 am

xCORE-200 QuadSPI Write Flash Data

Post by CrAzIaNhAx »

Hi,

I am developing on the xCORE-200 MC Audio board trying to get persistent flash memory working. I have followed the steps in AN00188 (http://www.xmos.com/support/appnotes/AN00188) and was able to get my application reading from the binary file as per the example but I have not been able to write to this file. I have tried fl_writeData and fl_writeDataPage functions with no luck, yet fl_readData and fl_readDataPage work fine. Below are my functions. What am I missing?

Code: Select all

 void app(fl_QSPIPorts &ports, client uart_tx_if uart_tx, client uart_rx_if uart_rx)
{
    char config[CONFIG_SIZE];
    char read;

    readConfig(ports, config, CONFIG_SIZE);
    read = config[0];
    
    uart_tx.write(config[0]);
    config[0] = read + 1;

    writeConfig(ports, config, CONFIG_SIZE);

    ...
}

int readConfig (fl_QSPIPorts &ports, char *config, char size)
{

  // Connect to the QuadSPI device using the quadflash library function fl_connectToDevice.
  if(fl_connectToDevice(ports, deviceSpecs, sizeof(deviceSpecs)/sizeof(fl_QuadDeviceSpec)) != 0)
  {
    return 1;
  }

  if(fl_readData(0, size, config) != 0)
  {
    return 1;
  }

  // Disconnect from the QuadSPI device.
  fl_disconnect();


  return 0;
}

int writeConfig (fl_QSPIPorts &ports, char *config, char size)
{
  char writeBuffer[PAGE_SIZE];

  // Connect to the QuadSPI device using the quadflash library function fl_connectToDevice.
  if(fl_connectToDevice(ports, deviceSpecs, sizeof(deviceSpecs)/sizeof(fl_QuadDeviceSpec)) != 0)
  {
    return 1;
  }

  if(fl_writeData(0, size, config, writeBuffer) != 0)
  {
    return 1;
  }

  // Disconnect from the QuadSPI device.
  fl_disconnect();


  return 0;
}

int writeConfigPage (fl_QSPIPorts &ports, char *config, char size)
{
  char writeBuffer[PAGE_SIZE];

  for(int i = 0; i < PAGE_SIZE; ++i)
  {
      if(i < size)
      {
          writeBuffer[i] = config[i];
      }
      else
      {
          writeBuffer[i] = 0;
      }
  }

  // Connect to the QuadSPI device using the quadflash library function fl_connectToDevice.
  if(fl_connectToDevice(ports, deviceSpecs, sizeof(deviceSpecs)/sizeof(fl_QuadDeviceSpec)) != 0)
  {
    return 1;
  }

  if(fl_writeDataPage(0, writeBuffer) != 0)
  {
    return 1;
  }

  // Disconnect from the QuadSPI device.
  fl_disconnect();


  return 0;
}
Thanks,
Daniel


User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Hello Daniel. We have the XCORE-200 Explorer kit and thought to test out the same QuadSPI Flash application note. After reviewing the schematics, our Explorer board appears to match the XCORE-200 Audio MC board which you have with respect to the external SPI flash. Respectively, anticipated that we should both see the same results.

In summary, the application code works on the writes to the SPI flash and somewhat blinded by the very very bright RGB led onboard this kit (selection of this LED is a fail - obviously intended for digital signage or similar). Did I note that the LED is bright ?

The application note uses the XMOS tools (either command line) or GUI version to write the string of data into the external flash device. Have you done this ? Did the 12 bytes of LED data get saved ok on your board ?

We followed the application note documentation and used the command line version for the 12 byte save and after correcting a few of the typos, the lengthy write (about 2-5 minutes) to the flash took effect on our Explorer Board just fine.

Typos are:
xflash --factory bin/qspi-persistent_stroage.xe --boot-partition-size 0x80000 --data src/data.bin

should be:
xflash --factory bin/qspi_persistent_storage.xe --boot-partition-size 0x80000 --data src/data.bin

NB:
remove hyphen in filename and change to underscore.
spelling of storage is incorrect in the filename

Moving forward, we applied the fl_writeData(0, size, config, writeBuffer) from your posted code, the fl_xx code does write into the flash device fine.

To test, did the following:

1) Import the code for this application note for the QuadSPI.

2) Replaced the supplied routine for led_driver with the following:

Code: Select all


  // you will need to add the following if you wish to view the printf outputs
  //#include <stdio.h>   // uncomment this line to allow for the printf

int led_driver (void)
{
  char led_byte_buffer[NUM_LED_BYTES];  // Buffer to hold the 12 bytes read from the data partition.
  char writeBuffer[0x2000];  // Buffer
  char config[NUM_LED_BYTES];  // Buffer to hold the 12 bytes read from the data partition.

  int delay = 50;                       // Initial delay 50 ms.
  int led_counter = 0;                  // A counter to count through the led patterns.
  char i;
  char size;

  size = 12;

  config[0] = 0x55;
  config[1] = 0xaa;
  config[2] = 0x01;
  config[3] = 0x02;
  config[4] = 0x03;
  config[5] = 0x04;
  config[6] = 0x05;
  config[7] = 0x06;
  config[8] = 0x07;
  config[9] = 0x08;
  config[10] = 0x09;
  config[11] = 0x0a;


  printf("\nWriting to flash...\n");

  for(i=0; i<12; i++)
      printf(" %02x ",config[i]);

  // Connect to the QuadSPI device using the quadflash library function fl_connectToDevice.
 if(fl_connectToDevice(ports, deviceSpecs, sizeof(deviceSpecs)/sizeof(fl_QuadDeviceSpec)) != 0)
  {
   return 1;
  }

 printf("\n\nFlash Size: %x\n",fl_getFlashSize());

 printf("\nMin bufffer required : %04x\n",fl_getWriteScratchSize(0,2));

if(fl_writeData(0, size, config, writeBuffer) != 0)
  {
    printf("\nFail !!");
    return 1;
  }

  // Disconnect from the QuadSPI device.
 fl_disconnect();

 printf("\nFinished writing to flash.\n");

  // Connect to the QuadSPI device using the quadflash library function fl_connectToDevice.
  if(fl_connectToDevice(ports, deviceSpecs, sizeof(deviceSpecs)/sizeof(fl_QuadDeviceSpec)) != 0)
  {
    return 1;
  }


  // Read all 12 bytes from offset 0 in the data partition and store them in
  // the buffer led_byte_buffer using the flash library function fl_readData.
  if(fl_readData(0, NUM_LED_BYTES, led_byte_buffer) != 0)
  {
    return 1;
  }

  // Disconnect from the QuadSPI device.
  fl_disconnect();

  printf("\nReading from flash buffer...\n");

  for(i=0; i<12; i++)
      printf("\nled_byte_buffer[%02x]  : %02x ",i,led_byte_buffer[i]);

   return 0;
}

Code: Select all

Writing to flash...
 55  aa  01  02  03  04  05  06  07  08  09  0a 

Flash Size: 200000

Min bufffer required : 1000

Finished writing to flash.

Reading from flash buffer...

led_byte_buffer[00]  : 55 
led_byte_buffer[01]  : aa 
led_byte_buffer[02]  : 01 
led_byte_buffer[03]  : 02 
led_byte_buffer[04]  : 03 
led_byte_buffer[05]  : 04 
led_byte_buffer[06]  : 05 
led_byte_buffer[07]  : 06 
led_byte_buffer[08]  : 07 
led_byte_buffer[09]  : 08 
led_byte_buffer[0a]  : 09 
led_byte_buffer[0b]  : 0a 
Did not test the write page library call but assuming that works fine.
User avatar
Ross
XCore Expert
Posts: 962
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »


Typos are:
xflash --factory bin/qspi-persistent_stroage.xe --boot-partition-size 0x80000 --data src/data.bin

should be:
xflash --factory bin/qspi_persistent_storage.xe --boot-partition-size 0x80000 --data src/data.bin

NB:
remove hyphen in filename and change to underscore.
spelling of storage is incorrect in the filename
Thanks, have pushed a fix for the next release.
CrAzIaNhAx
Member
Posts: 10
Joined: Thu Mar 17, 2016 7:25 am

Post by CrAzIaNhAx »

Thanks for the reply mon2. Looking through your code I have found the issue with my write function. My write data buffer was not big enough, thought it only needed to be as big as the flash page size writing a page at a time but apparently the qflash library requires a larger buffer.
aelder
Active Member
Posts: 37
Joined: Mon Sep 24, 2012 1:45 pm

Post by aelder »

Following on from this thread, if I run the following on an xCORE-200 eXplorer using Xtag load and run

Code: Select all

    // Connect to the QuadSPI device using the quadflash library function fl_connectToDevice.
    if(fl_connectToDevice(q, deviceSpecs, sizeof(deviceSpecs)/sizeof(fl_QuadDeviceSpec)) != 0) {
        printf("ERROR - Flash device not found\n");
        return 1;
    }

    printf("\n\nFlash Type: %d\n", fl_getFlashType());
    printf("Flash Size: %x\n", fl_getFlashSize());
    printf("Flash fl_getDataPartitionSize: %d\n", fl_getDataPartitionSize());
    printf("Flash fl_getNumDataSectors: %d\n", fl_getNumDataSectors());
    printf("Flash fl_getDataSectorSize(0): %d\n", fl_getDataSectorSize(0));
    printf("Flash fl_getWriteScratchSize(0, 64): %d\n", fl_getWriteScratchSize(0, 64));
I get
Flash Type: 1
Flash Size: 200000
Flash fl_getDataPartitionSize: 0
Flash fl_getNumDataSectors: 0
Flash fl_getDataSectorSize(0): 0
Flash fl_getWriteScratchSize(0, 64): -1
What have I messed up? Note, I have never run xflash on this board. Is that required to initialize/format the flash for the quadflash library to use?
aelder
Active Member
Posts: 37
Joined: Mon Sep 24, 2012 1:45 pm

Post by aelder »

Posting my own solution - you need to run xflash before flash library will work. I ran it, and now I get
Flash Type: 1
Flash Size: 200000
Flash fl_getDataPartitionSize: 1572864
Flash fl_getNumDataSectors: 384
Flash fl_getDataSectorSize(0): 4096
Flash fl_getWriteScratchSize(0, 64): 4096
which is 100% correct.
Post Reply