cancel
Showing results for 
Search instead for 
Did you mean: 

USB DFU Host class

Francisco Exp�sito
Associate II
Posted on September 18, 2015 at 09:58

Hello everybody,

I am developing the firmware for a STM32F4 board which has to be capable of flashing slave STM32F4 boards by means of USB DFU.

Since USB Host library doesn't have support for DFU class I am implementing a custom DFU Host class, but I can't get it working.

I have managed to enumerate successfully the slave device:

USB Device Attached

PID: df11h

VID: 483h

Address (#1) assigned.

Manufacturer : STMicroelectronics

Product : STM32 BOOTLOADER

Serial Number : 346139623034

Enumeration done.

This device has only 1 configuration.

Default configuration set.

Switching to Interface (#0)

Class : feh

SubClass : 1h

Protocol : 2h

DFU class started.

The problem comes on the ClassRequest handler. Whenever I issue a DFU_GetStatus request to the device I get one of the following responses:

  1. USBH_BUSY

  2. USBH_OK and response buffer remains unchanged (bytes set to 0). This response makes no sense since device state is appIDLE (0x00) when it should be dfuIDLE (0x02).

/**

* @brief The function is responsible for handling Standard requests for DFU class.

* @param phost: Host handle

* @retval USBH Status

*/

static

USBH_StatusTypeDef USBH_DFU_ClassRequest(USBH_HandleTypeDef *phost){

USBH_DFU_HandleTypeDef * handleDFU;

USBH_StatusTypeDef result;

DFU_STATUS_RESPONSE status;

handleDFU = (USBH_DFU_HandleTypeDef *)phost->pActiveClass->pData;

result = DFU_Get_Status(phost, &status);

if

( result == USBH_OK ){

handleDFU->deviceState = (DFU_STATE)status.bState;

handleDFU->deviceStatus = (DFU_STATUS)status.bStatus;

phost->pUser(phost, HOST_USER_CLASS_ACTIVE);

}

return

result;

}

/*

* DFU_Get_Status

*/

static

USBH_StatusTypeDef DFU_Get_Status(USBH_HandleTypeDef * phost, DFU_STATUS_RESPONSE * status){

USBH_DFU_HandleTypeDef * handleDFU;

DFU_STATUS_RESPONSE_DATA response;

USBH_StatusTypeDef result;

handleDFU = (USBH_DFU_HandleTypeDef * )phost->pActiveClass->pData;

// Initialize the status data structure

memset

(response.bytes, 0, 8);

// Prepare request

phost->Control.setup.b.bmRequestType = USB_EP_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE;

phost->Control.setup.b.bRequest = DFU_GETSTATUS;

phost->Control.setup.b.wIndex.w = handleDFU->interface;

phost->Control.setup.b.wLength.w = 6;

// Send request

result = USBH_CtlReq(phost, response.bytes, 6);

// Get result

if

( result == USBH_OK ){

status->bStatus = response.info.bStatus;

status->bwPollTimeout = response.info.bwPollTimeout;

status->bState = response.info.bState;

status->iString = response.info.iString;

status->reserved = 0;

}

else

{

status->bStatus = DFU_STATUS_ERR_UNKNOWN;

status->bwPollTimeout = 0;

status->bState = STATE_DFU_ERROR;

status->iString = 0;

status->reserved = 0;

}

return

result;

}

Any ideas?

Maybe the almighty clive1 can shed some light... :)

Thank you very much for your time

1 REPLY 1
Francisco Exp�sito
Associate II
Posted on September 21, 2015 at 15:11

Hi!

I've made some progress: I can get device status

successfully

. A call to USBH_CtlReq triggers an internal state machine which handles the request execution. Removing memset (line 15) gets the job done.

Now, I'm stuck on the download process. Whenever I try to send the first packet I consistenly get:

  • DFU_IDLE
  • [send download packet]
  • DFU_DNBUSY
  • [get status]
  • DFU_ERROR [stalled packet]

I've inserted delays of

[bwPollTimeout]

ms before each call to DFU_Get_Status with no luck.

Any ideas?

Thank you very much for your time.