DFU with custom flash

Technical questions regarding the XTC tools and programming with XMOS.
MarcAntigny
Active Member
Posts: 61
Joined: Tue Feb 13, 2018 2:50 pm

Post by MarcAntigny »

Hi mon,
I finally managed to get it to work. I needed to change the flash_devices array to :

Code: Select all

fl_QuadDeviceSpec flash_devices[] = {FL_QUADDEVICE_ISSI_IS25LQ016B, FL_QUADDEVICE_ISSI_IS25LP016D};
Now it works with DFU. I suspect that the flash was programmed in sort of default mode (using SPI) and not in QSPI so the DFU couldn't managed to do it in QSPI.
The thread viewtopic.php?f=7&t=6146 is good (I already had done what bowerymarc wrote before I had my problem but keep it for other interested people)

Thank you for your help mon. If you have info from Thesycon on the documentation of the error, I'd be glad if you'd keep me informed.
Marc
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am

Post by mon2 »

Excellent! Thanks for the positive closure on the issue and this thread.

THESYCON is questioning the details of the license holder for the DFU tool before they will help. Simple question was raised on what this error code means and the root cause.

Hope they will reply to redeem themselves of this closed source tool. Informed them that XMOS is the license holder. Proper technical support is a lost art - we have won so much OEM business due to us helping even clients who were not our customer. True story, one client busted us for so much support for a $30 USD purchase using a hotmail account. After 3 days, the client was operational and they reported that we supplied the highest level of support out of all those they contacted. That client then opened an account and business relationship with us - client was HP. That was about 15-20 years ago and we still hold them as an OEM account along with Foxconn. Stories for the next generation of "start ups"...
thesycon_response.png
You do not have the required permissions to view the files attached to this post.
User avatar
akp
XCore Expert
Posts: 580
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

Hi guys,

@mon2 -- awesome story about HP, thanks for sharing.. entertained angels unawares!

Just as a note, we had a co-op student compile the xmosdfu.cpp for Windows (VS Express 2017) with just a few changes, and he confirmed it works. Just so you can avoid interacting with the "kind" folks at Thesycon.

You need to use the DLL release of libusb-1.0 from the Windows binaries at https://libusb.info/ ... I think we built a 32 bit binary so we used the 32 bit dll (I always tend to build 32 bit Windows applications for some reason, not that many people run 32 bit Windows anymore but there's some old Win 7 32 bit installs hanging around I suppose). And you need the WinUSB driver installed for libusb-1.0 to work I believe.

Here is the patch we did to the xmosdfu.cpp

Code: Select all

@@ -112,19 +112,19 @@
 }
 
 int xmos_dfu_resetdevice(void) {
-  libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETDEVICE, 0, 0, NULL, 0, 0);
+  return libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETDEVICE, 0, 0, NULL, 0, 0);
 }
 
 int xmos_dfu_revertfactory(void) {
-  libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_REVERTFACTORY, 0, 0, NULL, 0, 0);
+  return libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_REVERTFACTORY, 0, 0, NULL, 0, 0);
 }
 
 int xmos_dfu_resetintodfu(unsigned int interface) {
-  libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETINTODFU, 0, interface, NULL, 0, 0);
+  return libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETINTODFU, 0, interface, NULL, 0, 0);
 }
 
 int xmos_dfu_resetfromdfu(unsigned int interface) {
-  libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETFROMDFU, 0, interface, NULL, 0, 0);
+  return libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETFROMDFU, 0, interface, NULL, 0, 0);
 }
 
 int dfu_detach(unsigned int interface, unsigned int timeout) {
@@ -199,7 +199,13 @@
   unsigned char strIndex = 0;
   unsigned int dfuBlockCount = 0;
 
-  inFile = fopen( file, "rb" );
+  errno_t err = fopen_s(&inFile, file, "rb");
+  if (0 != err)
+  {
+    fprintf(stderr, "Error: Failed to open input data file with error %lu.\n", (unsigned long)err);
+    return -1;
+  }
+
   if( inFile == NULL ) {
     fprintf(stderr,"Error: Failed to open input data file.\n");
     return -1;
@@ -255,7 +261,13 @@
   unsigned int block_size = 64;
   unsigned char block_data[64];
 
-  outFile = fopen( file, "wb" );
+  errno_t err = fopen_s( &outFile, file, "wb" );
+  if (0 != err)
+  {
+    fprintf(stderr, "Error: Failed to open output data file with error %lu.\n", (unsigned long)err);
+    return -1;
+  }
+
   if( outFile == NULL ) {
     fprintf(stderr,"Error: Failed to open output data file.\n");
     return -1;
@@ -273,6 +285,7 @@
   }
 
   fclose(outFile);
+  return 0;
 }
 
 int main(int argc, char **argv) {
@@ -380,7 +393,7 @@
     printf("Waiting for device to restart and enter DFU mode...\n");
 
     // Wait for device to enter dfu mode and restart
-    system("sleep 20");
+    system("timeout 20 /nobreak");
 
     // NOW IN DFU APPLICATION MODE
 
@@ -429,7 +442,7 @@
     printf("... Reverting device to factory image\n");
     xmos_dfu_revertfactory(); 
     // Give device time to revert firmware
-    system("sleep 2");
+    system("timeout 2 /nobreak");
     xmos_dfu_resetfromdfu(XMOS_DFU_IF);
   } 
   else{
cheers!
User avatar
akp
XCore Expert
Posts: 580
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

Here is the full xmosdfu.cpp file for MSVC
You do not have the required permissions to view the files attached to this post.
nestor_lee
Member
Posts: 13
Joined: Tue Nov 26, 2019 11:27 am

Post by nestor_lee »

akp wrote: Tue Jun 18, 2019 7:29 pm Here is the full xmosdfu.cpp file for MSVC
Hi akp,

Could you share your compiled 32bit windows exutable?
I'm doing the DFU test on windows, but have no xmosdfu.exe to use.
Thanks
User avatar
akp
XCore Expert
Posts: 580
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

I would recommend you compile it using MSVC Express. I haven't tested the executable myself, it was a co-op student on a prior work term who did this work. But my instructions above should get you going.
nestor_lee
Member
Posts: 13
Joined: Tue Nov 26, 2019 11:27 am

Post by nestor_lee »

akp wrote: Tue Nov 26, 2019 5:43 pm I would recommend you compile it using MSVC Express. I haven't tested the executable myself, it was a co-op student on a prior work term who did this work. But my instructions above should get you going.
Hi Akp,

I understand.
I'm compiling it on windows, but haven't been able to fix all the compiling errors yet...
If you got the executable on hand, I will be appretiated if you can share it and let me give it a try.
Thanks.
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am

Post by mon2 »

@akp. Hi.

Working on a similar case and new to use of libusb. Have the demo code from Microsoft compiled ok using Visual Studio 2019 but unable to compile your shared DFU host code.

Would you have the full project / solution available for this code?

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

Post by mon2 »

@akp, have it mostly working. Now can compile on Visual Studio 2019 but masked out the code that is raising the last batch of errors. Will review again when less tired.

Code: Select all


static int find_xmos_device(unsigned int id, unsigned int list)
{
    libusb_device* dev;
    libusb_device** devs;
    int i = 0;
    int found = 0;

    libusb_get_device_list(NULL, &devs);

    while ((dev = devs[i++]) != NULL)
    {
        int foundDev = 0;
        struct libusb_device_descriptor desc;
        libusb_get_device_descriptor(dev, &desc);
        printf("VID = 0x%x, PID = 0x%x, BCDDevice: 0x%x\n", desc.idVendor, desc.idProduct, desc.bcdDevice);
        
        if (desc.idVendor == XMOS_VID)
        {
            for (int j = 0; j < sizeof(pidList) / sizeof(unsigned short); j++)
            {
                if (desc.idProduct == pidList[j] && !list)
                {
                    foundDev = 1;
                    break;
                }
            }
        }
        /*  
        //
        // masked out the code that is raising the last batch of errors on VS 2019 (free from MS)
        // there is more than one solution to locate the XMOS specific hardware
        //
        if (foundDev)
        {
            if (found == id)
            {
                if (libusb_open(dev, &devh) < 0)
                {
                    return -1;
                }
                else
                {
                    libusb_config_descriptor* config_desc = NULL;
                    libusb_get_active_config_descriptor(dev, &config_desc);
                    if (config_desc != NULL)
                    {
                        for (int j = 0; j < config_desc->bNumInterfaces; j++)
                        {
                            const libusb_interface_descriptor* inter_desc = ((libusb_interface*)&config_desc->interface[j])->altsetting;
                            if (inter_desc->bInterfaceClass == 0xFE && inter_desc->bInterfaceSubClass == 0x1)
                            {
                                XMOS_DFU_IF = j;
                            }
                        }
                    }
                    else
                    {
                        XMOS_DFU_IF = 0;
                    }
                }
                break;
            }
            found++;
        }*/
    }

    libusb_free_device_list(devs, 1);

    return devh ? 0 : -1;
}

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

Post by mon2 »

Ok. May have it fixed now. Will test tomorrow.

Code: Select all

static int find_xmos_device(unsigned int id, unsigned int list)
{
    libusb_device* dev;
    libusb_device** devs;
    int i = 0;
    int found = 0;

    libusb_get_device_list(NULL, &devs);

    //
    // traverse through the list of USB IDs found mated with the system
    // print and check each ID against the XMOS_VID
    //
    while ((dev = devs[i++]) != NULL)
    {
        int foundDev = 0;
        struct libusb_device_descriptor desc;
        libusb_get_device_descriptor(dev, &desc);
        printf("VID = 0x%x, PID = 0x%x, BCDDevice: 0x%x\n", desc.idVendor, desc.idProduct, desc.bcdDevice);
        
        //
        // is this USB device containing the XMOS_VID?
        //
        if (desc.idVendor == XMOS_VID)
        {
            //
            // yes. check if the USB device matches one of the PIDs in our list
            //
            for (int j = 0; j < sizeof(pidList) / sizeof(unsigned short); j++)
            {
                if (desc.idProduct == pidList[j] && !list)
                {
                    foundDev = 1;
                    break;
                }
            }
        }
        
        if (foundDev)
        {
            if (found == id)
            {
                if (libusb_open(dev, &devh) < 0)
                {
                    return -1;
                }
                else
                {
                    struct libusb_config_descriptor *config_desc = NULL;
                    libusb_get_active_config_descriptor(dev, &config_desc);
                    if (config_desc != NULL)
                    {
                        for (int j = 0; j < config_desc->bNumInterfaces; j++)
                        {
                            struct libusb_interface_descriptor* inter_desc = ((struct libusb_interface*)&config_desc->interface[j])->altsetting;
                            if (inter_desc->bInterfaceClass == 0xFE && inter_desc->bInterfaceSubClass == 0x1)
                            {
                                XMOS_DFU_IF = j;
                            }
                        }
                    }
                    else
                    {
                        XMOS_DFU_IF = 0;
                    }
                }
                break;
            }
            found++;
        }
    }

    libusb_free_device_list(devs, 1);

    return devh ? 0 : -1;
}

Time to watch Cobra Kai S3 :)