Skip to main content
erik239955_st
Associate II
March 1, 2011
Question

USB Leave DFU Mode Issue

  • March 1, 2011
  • 1 reply
  • 636 views
Posted on March 01, 2011 at 22:06

USB Leave DFU Mode Issue

    This topic has been closed for replies.

    1 reply

    erik239955_st
    Associate II
    June 10, 2011
    Posted on June 10, 2011 at 17:36

    Update:

    I have been able to leave the DFU boot loader code and return to the user application code by manually setting the address pointer prior to sending the  DFU_DNLOAD request with 0 data.  

    The only downside is that it seems to fail about 1 out of 4 times. The user application uses the USB IP to implement a HID device.  When the exit function works properly the device will automatically enumerate with the PC as a HID device and will run the user application.  When it fails the PC will not recognize the device at which point a physical reset is required to start the user application.

    I think the problem is related to Note 2 on page 22 of AN3156.  This note states:

    When performing a jump from the bootloader to a loaded application code which uses the USB IP, the user application has to disable all pending USB interrupts and reset the core before enabling interrupts. Otherwise, a pending interrupt (issued from the boot loader code) may interfere with the user code and cause a functional failure. This procedure is not needed after exiting the system memory boot mode.

    Here is the code snippet of the DLL function that performs the exit operation:

    uint8_t DfuExit()

    {

    /* intermediate variables */

    uint8_t ExitStatus = 0;

    UCHAR Buffer = 0;

    UCHAR *pBuffer = &Buffer;

    DFUSTATUS DfuStatus;

    UCHAR DfuState;

    DWORD dwRet;

    UCHAR AddrPtrCmd[5] = {0x21, 0x00, 0x00, 0x00, 0x08}; 

    /* open device driver */

    if(DfuOpenDriver())

    {

    /* check current dfu status */

    STDFU_Getstatus(&DfuHandle, &DfuStatus);

    /* check for previous dfu error */

    if(DfuStatus.bState  == STATE_DFU_ERROR)

    {

    /* clear error status */

    STDFU_Clrstatus(&DfuHandle);

    /* check current dfu status */

    STDFU_Getstatus(&DfuHandle, &DfuStatus);

    }

    /* check current dfu state */

    if((DfuStatus.bState == STATE_DFU_IDLE) | (DfuStatus.bState == STATE_DFU_DOWNLOAD_IDLE))

    {

    /* set download request to set address pointer */

    STDFU_Dnload(&DfuHandle, AddrPtrCmd, 5, 0);

    /* get current dfu status */

    STDFU_Getstatus(&DfuHandle, &DfuStatus);

    /* check current dfu status */

    if((DfuStatus.bState == STATE_DFU_DOWNLOAD_BUSY))

    {

    /* get current dfu status*/

    STDFU_Getstatus(&DfuHandle, &DfuStatus);

    /* check status again to see if stack pointer was set */

    if(DfuStatus.bState != STATE_DFU_ERROR)

    {

    /* send dowload request with 0 data */

    STDFU_Dnload(&DfuHandle, pBuffer, 0, 0); 

    /* get current dfu status */

    STDFU_Getstatus(&DfuHandle, &DfuStatus);

    /* check dfu status */

    if(DfuStatus.bState == STATE_DFU_MANIFEST)

    {

    ExitStatus = 1;

    }

    }

    }

    }

    /* close device driver */

    DfuCloseDriver();

    }

    return ExitStatus;

    }