lquadflash Issues Between XTC Versions Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
RitchRock
XCore Addict
Posts: 224
Joined: Tue Jan 17, 2017 9:25 pm

lquadflash Issues Between XTC Versions

Post by RitchRock »

I have found issues with lquadflash when moving from XTC 14.3/4 to XTC 15.2 and 15.3 specially with the XU/XEU216 device.

I have 2 custom boards that both use the ISSI IS25LP016D. One of these boards has 216 while the other board has 316.

First, this is not a USB application. I have a custom DFU function that receives packets via UART, unpacks and upgrades the device firmware. We have been shipping the XU216 version using version 14.3 tools and this all works fine.

Using the 316 part and version XTC 15.2 and 15.3 tools, I have been able to make a few changes and am able to use the DFU task to upgrade firmware. All good. I had some help in this thread: https://www.xcore.com/viewtopic.php?t=8926

Now, when I build the 216 app with version 15.2 or 15.3 tools, including the necessary changes as above, DFU fails at some point (different every time) during the fl_writeImagePage(data) call. If I build the firmware with 14.4 tools it works.

So to summarize:
- Same QSPI part on both boards
- One board 216 part and the other 316
- fl_writeImagePage(data) fails at random points on 216 when built with XTC 15 tools but not XTC 14 tools

This is a major problem for us right now. daz, markp
View Solution
RitchRock
XCore Addict
Posts: 224
Joined: Tue Jan 17, 2017 9:25 pm

Post by RitchRock »

Thinking maybe it had to do with QE bit or write enable, I tried adding this to my code, but same behavior:

Code: Select all

       
       // Write Enable command
       fl_command(0x06, dummy_input, 1, dummy_output, 0);

       // Write Status Register with QE bit set
       unsigned char data = 0x40;  // QE bit is bit 6
       fl_command(0x01, &data, 1, dummy_output, 0);

	// Verify QE and WEL bits
	unsigned char status;
	fl_command(0x05, dummy_input, 1, &status, 1);

	// readback
	debug_printf("Readback status register: 0x%02X\n", status);

	if (status == 0x42) {
		debug_printf("Ready to write new data: QE and WEL set.\n");
	}
	else {
		debug_printf("Status register: 0x%02X - Not ready to write!\n", status);
	}
I get 0x042, which tells me this isn't the issue here...Something changed in version XTC 15+ that prevents reliable writing to our flash device.
markp
Verified
Member++
Posts: 26
Joined: Thu Jan 10, 2019 6:07 pm

Post by markp »

We are looking into this issue and recently reported xflash issues. We are building a picture of all the failures being reported. (such as, what issues are being observed, which XMOS devices cause issues, which flash devices, which operations etc)
Can you confirm:
1) Have you managed to run xflash successfully on both the 216 board and the 316 boards?
2) Does fl_writeImagePage(data) fail on 316 board? You said the 216 fails in your summary above.
Daz
New User
Posts: 2
Joined: Wed Jul 24, 2024 12:05 pm

Post by Daz »

RitchRock wrote: Tue Jan 14, 2025 3:23 am DFU fails at some point (different every time) during the fl_writeImagePage(data) call.
This suggests the timing may be marginal. While we investigate further, could you try a lower SPI clock frequency?

I'd suggest doing this by reverting back to `fl_connectToDevice()` but passing a SPI-spec like the following:

Code: Select all

fl_QSPIPorts ports =
{
  PORT_SQI_CS,
  PORT_SQI_SCLK,
  PORT_SQI_SIO,
  on tile[0]: XS1_CLKBLK_5
};

fl_QuadDeviceSpec deviceSpecs[] = {{
    -1,                     /* default parameters */
    256,                    /* page size */
    0,                      /* num pages */
    3,                      /* address size */
    8,                      /* log2 clock divider */
    0x9F,                   /* QSPI_RDID */
    0,                      /* id dummy bytes */
    3,                      /* id size in bytes */
    0x00000000,             /* device id */
    0x20,                   /* QSPI_SE */
    4096,                   /* Sector erase is always 4KB */
    0x06,                   /* QSPI_WREN */
    0x04,                   /* QSPI_WRDI */
    PROT_TYPE_NONE,         /* no protection */
    {{0,0},{0x00,0x00}},    /* QSPI_SP, QSPI_SU */
    0x02,                   /* QSPI_PP */
    0xEB|(0x0B<<8),         /* QSPI_READ_QUAD */
    1,                      /* 1 read dummy byte */
    SECTOR_LAYOUT_REGULAR,  /* sane sectors */
    {4096,{0,{0}}},         /* regular sector sizes */
    0x05,                   /* QSPI_RDSR */
    0x01,                   /* QSPI_WRSR */
    0x01,                   /* QSPI_WIP_BIT_MASK */
    0xFFFFFFFF,             /* id "don't care" mask */
    0,                      /* quad enable bit */
}};

fl_connectToDevice(ports, deviceSpecs, 1);
This is derived from the default SPI-spec used for `fl_connect()` but with the clock divider changed from 3 to 8.
RitchRock
XCore Addict
Posts: 224
Joined: Tue Jan 17, 2017 9:25 pm

Post by RitchRock »

markp wrote: Thu Jan 16, 2025 1:18 pm We are looking into this issue and recently reported xflash issues. We are building a picture of all the failures being reported. (such as, what issues are being observed, which XMOS devices cause issues, which flash devices, which operations etc)
Can you confirm:
1) Have you managed to run xflash successfully on both the 216 board and the 316 boards?
2) Does fl_writeImagePage(data) fail on 316 board? You said the 216 fails in your summary above.
Happy to hear XMOS is looking into the issue. I'm guessing like other manufacturers, with plenty of products in the field using the 216, we would have to build any upgrade image with version 14 tools until we can get this working.

1. Yes, I can can flash both boards with version 15 tools and am using the --force-xscope option to speed up programming with both 216 and 316 boards no issue here

Code: Select all

xflash --force-xscope --write-all app_XXXX.bin --target-file system.xn  --verbose 
2. No, fl)writeImagePage(data) does not fail on the 316 board. Yes, it randomly fails on the 216 board. This is writing an update image. One difference is that it seems like XTC 14 tools does something with file compression, while XTC 15 tools does not (when creating the upgrade image).
RitchRock
XCore Addict
Posts: 224
Joined: Tue Jan 17, 2017 9:25 pm

Post by RitchRock »

Daz wrote: Thu Jan 16, 2025 2:47 pm
RitchRock wrote: Tue Jan 14, 2025 3:23 am DFU fails at some point (different every time) during the fl_writeImagePage(data) call.
This suggests the timing may be marginal. While we investigate further, could you try a lower SPI clock frequency?

I'd suggest doing this by reverting back to `fl_connectToDevice()` but passing a SPI-spec like the following:

Code: Select all

fl_QSPIPorts ports =
{
  PORT_SQI_CS,
  PORT_SQI_SCLK,
  PORT_SQI_SIO,
  on tile[0]: XS1_CLKBLK_5
};

fl_QuadDeviceSpec deviceSpecs[] = {{
    -1,                     /* default parameters */
    256,                    /* page size */
    0,                      /* num pages */
    3,                      /* address size */
    8,                      /* log2 clock divider */
    0x9F,                   /* QSPI_RDID */
    0,                      /* id dummy bytes */
    3,                      /* id size in bytes */
    0x00000000,             /* device id */
    0x20,                   /* QSPI_SE */
    4096,                   /* Sector erase is always 4KB */
    0x06,                   /* QSPI_WREN */
    0x04,                   /* QSPI_WRDI */
    PROT_TYPE_NONE,         /* no protection */
    {{0,0},{0x00,0x00}},    /* QSPI_SP, QSPI_SU */
    0x02,                   /* QSPI_PP */
    0xEB|(0x0B<<8),         /* QSPI_READ_QUAD */
    1,                      /* 1 read dummy byte */
    SECTOR_LAYOUT_REGULAR,  /* sane sectors */
    {4096,{0,{0}}},         /* regular sector sizes */
    0x05,                   /* QSPI_RDSR */
    0x01,                   /* QSPI_WRSR */
    0x01,                   /* QSPI_WIP_BIT_MASK */
    0xFFFFFFFF,             /* id "don't care" mask */
    0,                      /* quad enable bit */
}};

fl_connectToDevice(ports, deviceSpecs, 1);
This is derived from the default SPI-spec used for `fl_connect()` but with the clock divider changed from 3 to 8.

Thanks I will test this. I want to mention though that I am having the failure on both 15.2 and 15.3. For the 15.2 version I tried still using flconnectodevice() with the SPI-spec for this flash device built into the tools with no luck.

I think trying the speed is a good idea and will test this when I get a chance. I wonder, like in my other reply if the compression that doesn't seem to be present in XTC 15 tools makes a difference here?
RitchRock
XCore Addict
Posts: 224
Joined: Tue Jan 17, 2017 9:25 pm

Post by RitchRock »

I have had a chance to do more testing today all on the 216 board.

1. Using XTC 15.3 I copied over the old SPI-Spec for my flash from the 14.4 tools as follows and then used this with flConnectToDevice(). This results in my DFU task finishing ( fl_writeImagePage(data) does not stumble any longer after this change). I did not change the divider. My spec is exactly as follows:

Code: Select all

fl_QuadDeviceSpec deviceSpecs[] = {{
    ISSI_IS25LP016D,        // IS25LP016D
    256,                    // page size
    8192,                   // num pages 
    3,                      // address size
    3,                      // log2 clock divider 
    0x9F,                   // QSPI_RDID 
    0,                      // id dummy bytes
    3,                      // id size in bytes
    0x9D6015,               // device id 
    0x20,                   // QSPI_SE 
    4096,                   // Sector erase is always 4KB 
    0x06,                   // QSPI_WREN 
    0x04,                   // QSPI_WRDI 
    PROT_TYPE_NONE,         // no protection 
    {{0,0},{0x00,0x00}},    // QSPI_SP, QSPI_SU 
    0x02,                   // QSPI_PP 
    0xEB,                   // QSPI_READ_FAST 
    1,                      // 1 read dummy byte 
    SECTOR_LAYOUT_REGULAR,  // mad sectors 
    {4096,{0,{0}}},        //regular sector sizs 
    0x05,                   // QSPI_RDSR 
    0x01,                   // QSPI_WRSR 
    0x01,                   // QSPI_WIP_BIT_MASK 
    0xFFFFFFFF,             // id "don't care" mask 
    0,                      // quad enable bit 
}};
2. Unfortunately the upgrade is still not working. The original factory boot image is always loaded, like there is some issue with the upgrade. So I read back the flash image using --read-all and then used the --analyze and got the following results:

Code: Select all

Loader xflashReadAll_upgrade_not_booting.bin:
  Size: 0x15CC bytes (0x573 words)
  CRC: 0xCF85FF5C (GOOD)

  User address: 0x2B000
  Search limit: 0x1FF000

  ID number: 0 (0x0)
  ID string: None

Factory image xflashReadAll_upgrade_not_booting.bin[0]:
  Offset: 0x15D4
  Image tag: 0xCA7FA11
  Page CRC: 0xC800BE4B (GOOD)
  Image CRC: 0xF58E79F4 (GOOD)

  Version: 0x0
  Features: 0x40
    Switch setup present

  Size: 0x28C38 bytes
  Length: 0x28C38 bytes

  Boot address: 0x0
  Overlay address: 0x0
  Overlay offset: 0x0

  Switch setup table offset: 0x38
  Core table offset: 0x40

  Tools version: 15.3.0
  Image format: 5 (Tools 15.2)

    Switch setup xflashReadAll_upgrade_not_booting.bin[0]:
      Offset: 0x80
      Size: 0x1F28 bytes (0x7CA words)
      CRC: 0x076D28A3 (GOOD)

  Number of cores: 2

    Core xflashReadAll_upgrade_not_booting.bin[0][0]:
      Offset: 0x1FA8
      Size: 0x13330 bytes (0x4CCC words)
      Channel end: 0x80020002
      CRC: 0xDCE351DE (GOOD)

        SWMEM address: 0x0
        SWMEM offset: 0x0
        SWMEM size: 0x0 bytes

        EXTMEM offset: 0x0
        EXTMEM size: 0x0 bytes

    Core xflashReadAll_upgrade_not_booting.bin[0][1]:
      Offset: 0x152D8
      Size: 0x13960 bytes (0x4E58 words)
      Channel end: 0x80030002
      CRC: 0x758DF8A9 (GOOD)

        SWMEM address: 0x0
        SWMEM offset: 0x0
        SWMEM size: 0x0 bytes

        EXTMEM offset: 0x0
        EXTMEM size: 0x0 bytes

Upgrade image xflashReadAll_upgrade_not_booting.bin[1]:
  Offset: 0x2B000
  Image tag: 0xCA7FA11
  Page CRC: 0x872313CA (GOOD)
  Image CRC: 0xDA92FCE6 (FAIL)

  Version: 0x1
  Features: 0x40
    Switch setup present

  Size: 0x28B68 bytes
  Length: 0x28B68 bytes

  Boot address: 0x0
  Overlay address: 0x0
  Overlay offset: 0x0

  Switch setup table offset: 0x38
  Core table offset: 0x40

  Tools version: 15.3.0
  Image format: 5 (Tools 15.2)

    Switch setup xflashReadAll_upgrade_not_booting.bin[1]:
      Offset: 0x80
      Size: 0x1F28 bytes (0x7CA words)
      CRC: 0x076D28A3 (GOOD)

  Number of cores: 2

    Core xflashReadAll_upgrade_not_booting.bin[1][0]:
      Offset: 0x1FA8
      Size: 0x132B0 bytes (0x4CAC words)
      Channel end: 0x80020002
      CRC: 0xFFFFFFFF (FAIL)

        SWMEM address: 0x0
        SWMEM offset: 0x0
        SWMEM size: 0x0 bytes

        EXTMEM offset: 0x0
        EXTMEM size: 0x0 bytes

    Core xflashReadAll_upgrade_not_booting.bin[1][1]:
      Offset: 0x15258
      Size: 0x13910 bytes (0x4E44 words)
      Channel end: 0x80030002
      CRC: 0xFFFFFFFF (FAIL)

        SWMEM address: 0x0
        SWMEM offset: 0x0
        SWMEM size: 0x0 bytes

        EXTMEM offset: 0x0
        EXTMEM size: 0x0 bytes

Dumping stage 2 loader to loader.bin
Dumping image 0 to image0.bin
Dumping image 0 switch setup code to image0_swsetup.bin
Dumping image 0 core 0 code to image0_core0.bin
Dumping image 0 core 1 code to image0_core1.bin
Dumping image 1 to image1.bin
Dumping image 1 switch setup code to image1_swsetup.bin
Dumping image 1 core 0 code to image1_core0.bin
Dumping image 1 core 1 code to image1_core1.bin

3. OBVs there is a CRC failure with the upgrade images, but I'm not sure why. I build the upgrade with the following command. I can run the upgrade on its own (from the .xe the upgrade is created from) just fine.

Code: Select all

xflash --factory-version 15.3 --upgrade 1 app_XXXXX.xe -o XXXXXX.bin --verbose

4. Using the xflash_image_check app from XTC 14.4 I checked upgrade images created with v14.4 tools and 15.3. For the upgrade images created with XTC14.4 I get 'Valid Image found on sector boundary @0' but with upgrade image create with XTC 15.3 I get 'No image tags found in file'. Further, if I create build an .xe with XTC 15.3 and then create an upgrade image from these with both 14.4 and 15.3 it also follows this pattern. I think there is something going on with how version 15 tools makes the upgrade image.
markp
Verified
Member++
Posts: 26
Joined: Thu Jan 10, 2019 6:07 pm

Post by markp »

We are trying to recreate your issues. The fist issue I would like to reproduce is where fl_writeImagePage(data) was "intermittently" failing. I cannot reproduce this using our XCORE-200-EXPLORER 216 with IS25LP016D. Could you send me the code fragment prior to your change to use the SPI-spec from 14.4 tools? (Were you using fl_connect()?).

I have tried with Tools 15.1.4, 15.2.1 and 15.3.0 with fl_connect() and with fl_connectToDevice().
I have also tried on our XCORE-AI-EXPLORER 316 board - this has a ADESTO AT25FF32 device.

Perhaps you could try the test program below on your target board.

For the test, I first burn a simple factory image (which has just a while(1) loop) in the device with the same tools version that I use to run the next part of test:
% xcc -target=XCORE-200-EXPLORER -g -o bin/factory.xe factory.c
% xflash --factory bin/factory.xe 262144

I then build the test program below with
% xcc -target=XCORE-200-EXPLORER -lquadflash -g -o bin/main.xe main.xc
and run it with:
% xrun --io bin/main.xe



=================

Code: Select all

#include <stdio.h>
#include <quadflash.h>
#include <platform.h>

unsigned char pageData[65536];

fl_QSPIPorts qspi_ports =
{
  PORT_SQI_CS,
  PORT_SQI_SCLK,
  PORT_SQI_SIO,
  on tile[0]: XS1_CLKBLK_2
};

const unsigned MAX_IMAGE_SIZE = 1 * 1024 * 1024;
#define ADESTO_AT25FF32 17

static const fl_QuadDeviceSpec fl_quaddeviceSpecs[] =
{
  {
    ADESTO_AT25FF32,        /* ADESTO_AT25FF32 */
    256,                    /* page size */
    16384,                  /* num pages */
    3,                      /* address size */
    3,                      /* log2 clock divider */
    0x9F,                   /* QSPI_RDID (Read JEDEC ID) */
    0,                      /* id dummy bytes */
    3,                      /* id size in bytes */
    0x1F4708,               /* device id */
    0x20,                   /* QSPI_SE */
    4096,                   /* Sector erase is always 4KB */
    0x06,                   /* QSPI_WREN */
    0x04,                   /* QSPI_WRDI */
    PROT_TYPE_NONE,         /* no protection */
    {{0,0},{0x00,0x00}},    /* QSPI_SP, QSPI_SU */
    0x02,                   /* QSPI_PP (Page program) */
    0xEB,                   /* QSPI_READ_FAST */
    1,                      /* 1 read dummy byte */
    SECTOR_LAYOUT_REGULAR,  /* mad sectors */
    {4096,{0,{0}}},         /* regular sector sizes */
    0x05,                   /* QSPI_RDSR */
    0x01,                   /* QSPI_WRSR */
    0x01,                   /* QSPI_WIP_BIT_MASK */
  },

  {
    ISSI_IS25LP016D,        // IS25LP016D
    256,                    // page size
    8192,                   // num pages 
    3,                      // address size
    3,                      // log2 clock divider 
    0x9F,                   // QSPI_RDID 
    0,                      // id dummy bytes
    3,                      // id size in bytes
    0x9D6015,               // device id 
    0x20,                   // QSPI_SE 
    4096,                   // Sector erase is always 4KB 
    0x06,                   // QSPI_WREN 
    0x04,                   // QSPI_WRDI 
    PROT_TYPE_NONE,         // no protection 
    {{0,0},{0x00,0x00}},    // QSPI_SP, QSPI_SU 
    0x02,                   // QSPI_PP 
    0xEB,                   // QSPI_READ_FAST 
    1,                      // 1 read dummy byte 
    SECTOR_LAYOUT_REGULAR,  // mad sectors 
    {4096,{0,{0}}},        //regular sector sizs 
    0x05,                   // QSPI_RDSR 
    0x01,                   // QSPI_WRSR 
    0x01,                   // QSPI_WIP_BIT_MASK 
    0xFFFFFFFF,             // id "don't care" mask 
    0,                      // quad enable bit 
  },
};


int main() 
{
    par {

    on tile[0]: {
        int r;
        unsigned count = 0;
        unsigned id, size;

        fl_BootImageInfo b;

#if 1
        r= fl_connect(qspi_ports);
#else        
        r = fl_connectToDevice(qspi_ports, fl_quaddeviceSpecs, sizeof(fl_quaddeviceSpecs)/sizeof(fl_quaddeviceSpecs[0]));
#endif
        printf("fl_connectToDevice() = %d\n", r);

        id = fl_getJedecId();
        size = fl_getFlashSize();
        printf("JedecId = 0x%08x, size = 0x%08x\n", id, size);

        const int psize = fl_getPageSize() ;
        for (unsigned i=0; i<psize; i++) {
            pageData[i] = i;            
        }

        r = fl_getFactoryImage(b);    // required

        printf("fl_getFactoryImage() = %d\n", r);

        printf("b.startAddress: 0x%08x, size 0x%08x, factory %d, tag %d\n", b.startAddress, b.size, b.factory, b.factory);

        while (fl_startImageAdd(b, MAX_IMAGE_SIZE, 0)) {
            count++;
        }
        printf("fl_startImageAdd count: %d\n", count);

        const unsigned numWritePages = MAX_IMAGE_SIZE / (unsigned)psize;

        for (unsigned i=0; i<numWritePages; i++) {
            r = fl_writeImagePage(pageData);
            if (0 != r) {
                fprintf(stderr, "FATAL: fl_writeImagePage() failed. At page %d, code %d\n", i, r);
            }
        }

        printf("Written %d pages\n", numWritePages);

        fl_endWriteImage();
        fl_disconnect();
    }
    }
}
=================
RitchRock
XCore Addict
Posts: 224
Joined: Tue Jan 17, 2017 9:25 pm

Post by RitchRock »

I really appreciate the time to recreate the issue and will test the program you sent.

I went through and grabbed the relevant code (including my XMOS reboot function that still seems to work with XCORE.AI). Yes, to be clear I was having failures using the flconnnect() as below. Happy to explain anything here. The case i_qspi_storage.dfu_data gets called repeatedly every time a dfu data packet arrives to my device.

Code: Select all

/*
 * dfu.xc
 *
 *  Created on: Mar 17, 2021
 *      
 */

static unsigned write_offset = -1;

void begin_write_upgrade_image(void) {
  write_offset = 0;
  debug_printf("Ready to begin DFU update at write offset 0\n");
}

void abort_write_upgrade_image(void) {
  write_offset = -1;
}

int write_upgrade_image_page(int address, unsigned char data[FLASH_PAGE_SIZE]) {

  if (address == write_offset) {
    // The following line shows intermittent failure (appears at least half way done with DFU) on XU216 using XTC 15 Tools)
    if (fl_writeImagePage(data) != 0) {
      debug_printf("Failed to write page at address %d\n", address);
      return 1;
    }
    debug_printf("Wrote offset %d\n", write_offset);
    write_offset += FLASH_PAGE_SIZE;
    return 0;
  }
  return 1;
}


unsigned get_tile_id(tileref);
extern tileref tile[];

/* Reboots XMOS device by writing to the PLL config register */
void xmos_reboot(void)
{
    unsigned int pllVal;
    unsigned int localTileId = get_local_tile_id();
    unsigned int tileId;
    unsigned int tileArrayLength;

    asm volatile ("ldc %0, tile.globound":"=r"(tileArrayLength));

    /* Reset all remote tiles */
    for(int i = 0; i < tileArrayLength; i++)
    {
        /* Cannot cast tileref to unsigned */
        tileId = get_tile_id(tile[i]);

        /* Do not reboot local tile yet */
        if (localTileId != tileId)
        {
            read_sswitch_reg(tileId, 6, pllVal);
            pllVal &= 0x7FFFFFFF; // Mask the XS2 no reset bit
            write_sswitch_reg_no_ack(tileId, 6, pllVal);
        }
    }

    /* Finally reboot this tile */
    read_sswitch_reg(localTileId, 6, pllVal);
    pllVal &= 0x7FFFFFFF;
    write_sswitch_reg_no_ack(localTileId, 6, pllVal);

}


/*
 * qspi_storage.xc
 *
 *  Created on: Jan 26, 2021
 * // QSPI Interface Server task
*/

// ... Defines and static variables left out

int qspi_storage(server qspi_storage_if i_qspi_storage)
{            
    /// Code Left Out ...

    while(1)
    {
        select
        {

            // Code Left Out ...
            
            case i_qspi_storage.dfu_start() -> uint8_t return_val:
                DFU_STATUS = 0;
                debug_printf("\n\nDFU Start - Connecting to the QuadSPI device using the quadflash library function fl_connect.\n");
                if(fl_connect(qspi_ports) != 0)
                {
                    return 1;
                }
                
                fl_BootImageInfo image;
                fl_BootImageInfo factory_image;

                int flashstatus = fl_getFactoryImage(image);

                factory_image = image;

                if (flashstatus != 0)
                {
                    debug_printf("No factory image exists in flash\n");
                    DFU_STATUS = no_factory_image; // No factory image
                    return 0;
                }
                else
                {
                    flashstatus = fl_getNextBootImage(image);

                    if (flashstatus != 0)
                    {
                        // No upgrade image exists in flash
                        debug_printf("No upgrade image exists in flash\n");
                    }

                    int result;

                    do
                    {
                        if (flashstatus != 0)
                        {
                            result = fl_startImageAdd(factory_image, FLASH_MAX_UPGRADE_IMAGE_SIZE, 0);
                        }
                        else
                        {
                            result = fl_startImageReplace(image, FLASH_MAX_UPGRADE_IMAGE_SIZE);
                        }
                    } while (result > 0);

                    if (result < 0)
                    {
                        debug_printf("Failed to start image upgrade\n");
                        DFU_STATUS = start_image_upgrade_failure;
                    }
                    else
                    {
                        begin_write_upgrade_image();
                        DFU_STATUS = dfu_no_error;
                    }
                    
                    return_val = DFU_STATUS;
                }
                break;

            case i_qspi_storage.dfu_data(uint8_t buffer[]) -> uint8_t return_val:
                unsigned int dfu_bytes_available = 1024;
                unsigned int packet_index = 4; // data [0] to [3] is command and block index
                DFU_STATUS = 0;

                // Fill scratch buffer with incomming dfu data
                for (int i =0; i < LARGE_PACKET_LENGTH; i++)
                {
                    scratch_buffer[i] = buffer[i];
                }

                dfu_block_count = (scratch_buffer[2]<<8) + scratch_buffer[3];

                //debug_printf("qspi_storage.xc command = %d   block_count = %d\n", scratch_buffer[1], dfu_block_count);

                if (dfu_next_write_address != (dfu_block_count * FLASH_PAGE_SIZE * packet_index))
                {
                    DFU_STATUS = address_invalid;
                }
                else
                {
                    // Fill flash page buffer and program with block data. 4 pages per block.
                    for (int k = 0; k < 4; k++)
                    {
                        memcpy(dfu_flash_page_buf, &scratch_buffer[packet_index], FLASH_PAGE_SIZE);
                        
                        // This is where the DFU function to write is called (and sometimes fails)
                        if (write_upgrade_image_page(dfu_flash_write_addr, dfu_flash_page_buf) != 0) {
                            debug_printf("Failed to write\n");
                            DFU_STATUS = address_invalid;
                            break;
                        }
                        else {
                            DFU_STATUS = dfu_no_error;
                        }
                        packet_index += FLASH_PAGE_SIZE;
                        dfu_flash_write_addr += FLASH_PAGE_SIZE;
                    }
                    dfu_next_write_address += dfu_bytes_available;
                }

                return_val = DFU_STATUS;
                break;

            case i_qspi_storage.dfu_done() -> uint8_t return_val:
                DFU_STATUS = 0;

                //Finalize DFU Upgrade
                if (fl_endWriteImage() !=0)
                {
                    debug_printf("Failed to end image write.\n");
                    DFU_STATUS = endWriteImage_failure;
                }

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

                DFU_STATUS = dfu_no_error;
                return_val = DFU_STATUS;
                break;

            case i_qspi_storage.dfu_restart():
                debug_printf("XMOS Restart.\n");
                delay_milliseconds(5000);
                xmos_reboot();
                while(1);
                break;

                // Code Left Out
        }
    }
}
RitchRock
XCore Addict
Posts: 224
Joined: Tue Jan 17, 2017 9:25 pm

Post by RitchRock »

I had a chance to run the program you sent and it runs successfully every time using both fl_connectToDevice and fl_connect. The fl_startImageAdd count changes on every run, but I believe this is expected as the flash preparation isn't deterministic.

I also went a step further and prepared the factory image exactly like how I do, by first creating the .bin with a data partition, programming this in the same manner I do with my device and then running the main() app you gave me to test flash writing. Runs successfully every time again.

I'm at a loss as to why mine was failing using fl_connect(), but not fl_connectToDevice().

Here is the output using flconnect:

Code: Select all

fl_connectToDevice() = 0
JedecId = 0x009d6015, size = 0x00200000
fl_getFactoryImage() = 0
b.startAddress: 0x000015d4, size 0x00040000, factory 1, tag 1
fl_startImageAdd count: 5985156
Written 4096 pages
and then using fl_connectToDevice():

Code: Select all

fl_connectToDevice() = 0
JedecId = 0x009d6015, size = 0x00200000
fl_getFactoryImage() = 0
b.startAddress: 0x000015d4, size 0x00040000, factory 1, tag 1
fl_startImageAdd count: 5915765
Written 4096 pages
I