cancel
Showing results for 
Search instead for 
Did you mean: 

Question about USBH_BulkReceiveData() Usage

kroesswang_thomas
Associate II
Posted on October 23, 2012 at 15:30

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.

3 REPLIES 3
dmakhrov9
Associate II
Posted on October 23, 2012 at 16:15

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;

}

kroesswang_thomas
Associate II
Posted on October 23, 2012 at 16:28

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;

}

dmakhrov9
Associate II
Posted on October 23, 2012 at 17:32

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 🙂