2012-10-23 06:30 AM
Hello!
I'm currently working on a project using the STM32F4 Discovery board as a CDC-Host. I have succesfully enumerated my usb device and also successfully used USBH_BulkSendData(). But now I'm unsure about how to use USBH_BulkReceiveData() correctly. Do I have to execute it before polling (HCD_GetURB_State(pdev , MSC_Machine.hc_num_in) == URB_DONE), or do I have to poll before executing the receive-handle? When I execute USBH_BulkReceiveData() first, the STM32 goes into an infinite USB-interrupt loop. But when I poll first the URB_State always stays URB_IDLE. I have studied the MSC Host example file but it doesn't provide an answer to my question.2012-10-23 07:15 AM
This modified code from MSC worked for me. But that was pain. Still do not understand how it functions :)
static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev , void *phost) { USBH_HOST *pphost = phost; USBH_Status status = USBH_BUSY; uint8_t appliStatus = 0; uint16_t tempInt; if(HCD_IsDeviceConnected(pdev)) { switch(USBH_MSC_BOTXferParam.MSCState) { case USBH_MSC_BOT_INIT_STATE: USBH_MSC_Init(pdev); USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_BULK; break; case USBH_MSC_BOT_BULK: USBH_BulkReceiveData (pdev, Buffer, 512, MSC_Machine.hc_num_in); USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_PAUSE3; break; case USBH_MSC_BOT_PAUSE3: if(HCD_GetURB_State(pdev , MSC_Machine.hc_num_in) == URB_DONE) { // you stuff pphost->usr_cb->UserApplication(Buffer); USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_FINISH; } break; case USBH_MSC_BOT_FINISH: break; //************************************************************** case USBH_MSC_CTRL_ERROR_STATE: /* Issue Clearfeature request */ status = USBH_ClrFeature(pdev, phost, 0x00, pphost->Control.hc_num_out); if(status == USBH_OK ) { /* If GetMaxLun Request not support, assume Single LUN configuration */ MSC_Machine.maxLun = 0; USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; } break; case USBH_MSC_BOT_USB_TRANSFERS: /* Process the BOT state machine */ USBH_MSC_HandleBOTXfer(pdev , phost); break; case USBH_MSC_DEFAULT_APPLI_STATE: /* Process Application callback for MSC */ appliStatus = 0; if(appliStatus == 0) { USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE; } else if (appliStatus == 1) { /* De-init requested from application layer */ status = USBH_APPLY_DEINIT; } break; case USBH_MSC_UNRECOVERED_STATE: status = USBH_UNRECOVERED_ERROR; break; default: break; } } return status; }2012-10-23 07:28 AM
Thanks for the quick answer!
I also used USBH_MSC_Handle to build my Statemachine. What I removed was USBH_MSC_Init(pdev), because as far as I know these function is only for storage devices and I don't need those. My Handle function looks like this: The device sends a response to the SCIP2.0 message. But I never reach case 2 because after the USBH_BulkReceiveData()-function the STM32 gets into an interrupt loop. static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev , void *phost) { USBH_HOST *pphost = phost; USBH_Status status = USBH_BUSY; uint8_t mscStatus = USBH_MSC_BUSY; uint8_t appliStatus = 0; uint8_t scip20 [8] = {'S','C','I','P','2','.','0',0x0A}; uint8_t scip_BM [3] = {'B','M',0x0A}; uint8_t scip_QT [3] = {'Q','T',0x0A}; static uint8_t answer [40]; static uint8_t urb_status; if(HCD_IsDeviceConnected(pdev)) { switch(cdc_state) { case USBH_MSC_BOT_INIT_STATE: urb_status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out); if(urb_status != URB_NOTREADY) { USBH_BulkSendData (pdev, &scip20[0], 7 , MSC_Machine.hc_num_out); } cdc_state = 1; //USB_OTG_BSP_mDelay(100); break; case 1: urb_status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out); if(urb_status == URB_DONE) { USBH_BulkReceiveData (pdev, answer, USBH_MSC_MPS_SIZE , MSC_Machine.hc_num_in); cdc_state = 2; //USB_OTG_BSP_mDelay(100); } break; case 2: if(HCD_GetURB_State(pdev , MSC_Machine.hc_num_in) == URB_DONE) { USBH_BulkSendData (pdev, &scip_QT[0], 3 , MSC_Machine.hc_num_out); cdc_state = 3; } break; default: break; } } return status; }2012-10-23 08:32 AM
I believed I understood C-language before I looked at ST's USB host stack. To me, it is a switch-case-function-pointer massacre :)