DFU code stalling on board side

Technical questions regarding the XTC tools and programming with XMOS.
rgilio
Active Member
Posts: 36
Joined: Wed Jul 03, 2019 1:01 am

Post by rgilio »

1. Thanks for the list, I was already using GHEX but it's always good to know alternatives.

2. I spent some time trying to flash on windows but still didn't have any luck. This is the following output I'm receiving

Code: Select all

Driver API DLL successfully loaded. API Version: 4.08
Downloading C:\Users\test\fw_upgr.bin to target 0 ...
 State 6 (Failed), 0 of 52736 bytes downloaded ... .....
Download failed, completionStatus=0xEF000004
I'm unsure exactly why it failed, even with the verbose flag that's all I get from output. I'm guessing I'm running into the same error.

3. I've verified that the erase-all works since after I did a read back of the flash I got back 2mb of 0xF's for the entire read back. I did have to erase the flash through a different method though, the command provided was giving me issues.

Code: Select all

xflash --erase-all --verbose --spi-spec IS25LQ016B 
Error: F03146 Input file for option --spi-spec IS25LQ016B not found
4. I'm using the XN file that was already in the sw_usb_audio-[sw]_6.15.2 project for app_usb_aud_mic_array. The XN file has S25FL116K used as the default flash type. I changed it to be IS25LQ016B but didn't notice a difference in behavior.


I also tested DFU on the Multichannel Audio Platform https://www.xmos.com/products/audio/kits and that worked just fine with xmosdfu on my Linux machine. So I'm left to believe that it's either the hardware/code. I've swapped out my board with several others that we have here and am running into the same issue across all of them so I think it's unlikely a hardware issue. The leads me to believe the problem must be laying in software somewhere.
I'm going to look through and see if there's a glaring difference in the project configs and XN files between the Multi Channel Board and the Mic Array board. I'll provide any updates if I find anything regarding any notable differences.


rgilio
Active Member
Posts: 36
Joined: Wed Jul 03, 2019 1:01 am

Post by rgilio »

I've also gone through the following threads but had no luck:

https://www.xcore.com/viewtopic.php?f=26&t=7162
https://www.xcore.com/viewtopic.php?f=2 ... r&start=10
https://www.xcore.com/viewtopic.php?f=7&t=6146&start=30

These threads lead me to believe there's an integration issue with the Flash Device itself and the DFU code, however I seem to be running into another edge case in my situation unless I'm not implementing the solutions correctly.
I also didn't notice anything substantial in the Makefiles and XN files for the XE and XUF boards that would be causing this issue. The only thing would be that they're using a different flash device.
rgilio
Active Member
Posts: 36
Joined: Wed Jul 03, 2019 1:01 am

Post by rgilio »

I was able to track down the first issue (and hopefully only issue).

It seems that the flash_interface::flash_cmd_init function is failing.

Code: Select all

int flash_cmd_enable_ports() __attribute__ ((weak));
int flash_cmd_enable_ports() {
  return 0;
}


/* Returns non-zero for error */
int flash_cmd_init(void)
{
    fl_BootImageInfo image;

    if (!flash_device_open)
    {
        if (flash_cmd_enable_ports()) <----- Fails
            flash_device_open = 1;
    }
    if (!flash_device_open)
    {
        return 1; <--- Returns Error
    }
...
I was able to trace down that the flash_device_open flag is not being set to true because the flash_cmd_enable_ports() is returning a 0. As noted above, the flash_cmd_enable_ports() seems to be returning a 0 no matter what so the flag will always be false. Is this intended, if so, why is this set up like this? I want to guess that the flash_cmd_enable_ports() is really doing other things behind the scenes and failing. This is causing the dfu::DFU_OpenFlash function to always return an error which means DFU won't work. My guess is that there's something specific that needs to be done to allow the flash ports to be enabled or configured somewhere but I'm unaware of where that'd be done or how I'd go about fixing it.

Any help with this would be appreciated.

Quick Edit: I've found where the real function call is going to (flashlib_user::flash_cmd_enable_ports()).

The line it's failing on is fl_conenctToDevice(&q_qflash, flash_devices, 1)

Code: Select all

#ifdef DFU_FLASH_DEVICE
    result = fl_connectToDevice(&p_qflash, flash_devices, 1);
#else
    /* Use default flash list */
#ifdef QUAD_SPI_FLASH
    result = fl_connect(&p_qflash);
#else
    result = fl_connect(&p_flash);
I've tried setting the flash device to be all of the devices listed in the fl_QuadDeviceSpec struct but none of them worked. (The XUF216 mic array uses the FL_QUADDEVICE_ISSI_IS25LQ032B)

Code: Select all

fl_QuadDeviceSpec deviceSpecs[] =
{
  FL_QUADDEVICE_SPANSION_S25FL116K,
  FL_QUADDEVICE_SPANSION_S25FL132K,
  FL_QUADDEVICE_SPANSION_S25FL164K,
  FL_QUADDEVICE_ISSI_IS25LQ080B,
  FL_QUADDEVICE_ISSI_IS25LQ016B,
  FL_QUADDEVICE_ISSI_IS25LQ032B,
};//fl_QuadDeviceSpec
I've verified that the p_qflash port assignment is correct:

Code: Select all

fl_QSPIPorts p_qflash =
{
    XS1_PORT_1B,
    XS1_PORT_1C,
    XS1_PORT_4B,
    CLKBLK_FLASHLIB
};
The only thing I can think of is that the flash chip inside is different than what the schematic says/the QuadDevice config is incorrect which would be why it's failing. However, I find it unlikely for the schematic to be incorrect.
Is there anything I can do to debug what exactly about the connect is failing?
rgilio
Active Member
Posts: 36
Joined: Wed Jul 03, 2019 1:01 am

Post by rgilio »

Alright so the only lead I've got regarding this is that if I pass in "UNKNOWN" as my "flash_devices = {UNKNOWN}".

That'll pass in an fl_QuadDeviceSpec with all its values equal to 0.
This actually will get past the fl_ConnectToDevice() function, however since everything is 0'd out. It fails to do anything afterwards and then can't grab the factory image.
I used this as a baseline to figure out which parameter was causing the failure and I discovered that the device ID of the FL_QUADDEVICE is the culprit in this scenario. I went ahead and changed the device ID to always be 0 and that gets me past the fl_ConnectToDevice function with all of the other parameters left at their default value i.e. pageSize = 256 and so on. However, the failure to grab the factory image remains the same.

Code: Select all

if (fl_getFactoryImage(&image) != 0) {return 1;}
I'm not sure what this means regarding the configuration/state of the internal flash chip. And it's not clear why it is unable to grab the factory image.
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am

Post by mon2 »

Hi. You should be able to use standard SPI commands to read out the ID of the internal flash device. Then using this value, you can google and locate the true identity of the flash buried inside the CPU (XUF series).

Attached is our small but working code that should be simple enough to use on your PCB to send / receive standard SPI commands to extract out the FLASH ID / Manufacturer ID, etc.

From memory (ok, pun intended :), change the port pin definition inside this project to match the FLASH pins used internally by your CPU -> compile and run. Do review the code flow and use it to dump the IDs only before proceeding any further. We used the same code to configure a non-QSPI flash from Digikey / Mouser and then enable the QSPI bit for the XHRA CPU.

Please post your results and the IDs that are read back from your CPU.

workspace_spi_xmos.rar
You do not have the required permissions to view the files attached to this post.
rgilio
Active Member
Posts: 36
Joined: Wed Jul 03, 2019 1:01 am

Post by rgilio »

I might be a bit confused here about using the SPI interface with my device. I've loaded the project into the workspace and looked into changing the Port Pin Definition to match the FLASH pins by the CPU but it doesn't seem like they line up (unless I'm missing something). In figure 8 in the XUF216 datasheet (https://www.xmos.com/download/XUF216-51 ... (1.16).pdf) it looks like there's only 3 ports for me to reference because we have QSPI. There doesn't appear to be an MISO and MOSI port for me to specify unless I need to isolate the 4B line (but even then I'm unsure of which lines I'd be using for a particular port). I can see in the XE216/XU216 datasheet that it has definitions for MISO/MOSI (https://www.xmos.com/download/XE216-512 ... (1.16).pdf) so I would have expected to see something similar in the XUF216

Also, I'm a bit confused by "standard SPI commands". I'll admit I'm a bit unfamiliar with SPI in general and after looking around I couldn't find any information on what you mean by standard SPI commands, could you clarify this?
rgilio
Active Member
Posts: 36
Joined: Wed Jul 03, 2019 1:01 am

Post by rgilio »

I went ahead and slightly modified the app function in the code you provided. I output the resulting values from the lines with commented commands.
I think I'm still doing something incorrect here to properly read back these values as the output doesn't look correct at all.

Here's the printing format I followed.

Code: Select all

//spi.begin_transaction(0, 100, SPI_MODE_0);
//printf("WREN: %d\n", spi.transfer8(0x06)); // WREN
//spi.end_transaction(100); 
The following output for each transfer.

Code: Select all

WREN: 0
ENABLE QE:0
Enabled: 0
WREN: 0
WRDI: 0
ENABLE QE: 255
READ QE: 255
READ ID: 255
VAL1: 255
VAL2: 34
VAL3: 255
VAL4: 255
VAL5: 255
rgilio
Active Member
Posts: 36
Joined: Wed Jul 03, 2019 1:01 am

Post by rgilio »