cancel
Showing results for 
Search instead for 
Did you mean: 

USB Leave DFU Mode Issue

erik239955_st
Associate II
Posted on March 01, 2011 at 22:06

USB Leave DFU Mode Issue

1 REPLY 1
erik239955_st
Associate II
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;

}