This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32F4 USB Host HID application

“We are trying to develop a USB Host HID application where using the controller STM32F4, and the USB stack library available on the ST website, we are trying to send data/command to an USB HID device. But in the library we downloaded from ST site, the host HID application has examples for mouse and keyboard application only.In case of Mouse and keyboard, Host receives but does not transmit back anything while in our application we need to also transmit data.

So do you have any particular HID host example codes or guideline documents for STM32F4xx controller which demonstrates how to transmit the data to the attached external USB device using the ST USB library? “,

Parents
  • Maybe, he is developing it on Keil ;-)

    > we need to also transmit data

    Based on STM32_USB-Host-Device_Lib_V2.1.0
    www.st.com/.../PF257882

    In usbh_hid_core.c,

    1) USBH_HID_InterfaceInit()
    This function is called by the stack, after enumeration, to identify the target device. The original routine examines Interface subclass and protocol for boot keyboard/mouse. For generic HID, check VID/PID of the target, instead. VID/PID on the device descriptor is already read out by the stack at this call.

    VID: pphost->device_prop.Dev_Desc.idVendor
    PID: pphost->device_prop.Dev_Desc.idProduct

    If VID/PID doesn't match, this routine returns USBH_BUSY (ie. other than USBH_OK)

    This original code also traverses endpoint descriptors. It opens the channel (pipe) for the interrupt OUT EP on HID_Machine.hc_num_out channel.

    To send to the interrupt OUT EP,
    2) USBH_HID_Handle()
    In a new state of state machine,
    - Put data to HID_Machine.buff, and write its size to HID_Machine.length
    - Call USBH_InterruptSendData(pdev, HID_Machine.buff, HID_Machine.length, HID_Machine.hc_num_out);

    At the next state,
    Poll the return value of HCD_GetURB_State(pdev , HID_Machine.hc_num_out). When the transfer finishes, HCD_GetURB_State() returns URB_DONE

    To send Output/Feature report over the default EP,
    2') USBH_HID_Handle()
    Put data to HID_Machine.buff, and call USBH_Set_Report() repeatedly, while it returns USBH_BUSY.
    when finishes, it returns USBH_OK / USBH_FAIL / USBH_NOT_SUPPORTED (got STALL from device)

    Tsuneo

Reply
  • Maybe, he is developing it on Keil ;-)

    > we need to also transmit data

    Based on STM32_USB-Host-Device_Lib_V2.1.0
    www.st.com/.../PF257882

    In usbh_hid_core.c,

    1) USBH_HID_InterfaceInit()
    This function is called by the stack, after enumeration, to identify the target device. The original routine examines Interface subclass and protocol for boot keyboard/mouse. For generic HID, check VID/PID of the target, instead. VID/PID on the device descriptor is already read out by the stack at this call.

    VID: pphost->device_prop.Dev_Desc.idVendor
    PID: pphost->device_prop.Dev_Desc.idProduct

    If VID/PID doesn't match, this routine returns USBH_BUSY (ie. other than USBH_OK)

    This original code also traverses endpoint descriptors. It opens the channel (pipe) for the interrupt OUT EP on HID_Machine.hc_num_out channel.

    To send to the interrupt OUT EP,
    2) USBH_HID_Handle()
    In a new state of state machine,
    - Put data to HID_Machine.buff, and write its size to HID_Machine.length
    - Call USBH_InterruptSendData(pdev, HID_Machine.buff, HID_Machine.length, HID_Machine.hc_num_out);

    At the next state,
    Poll the return value of HCD_GetURB_State(pdev , HID_Machine.hc_num_out). When the transfer finishes, HCD_GetURB_State() returns URB_DONE

    To send Output/Feature report over the default EP,
    2') USBH_HID_Handle()
    Put data to HID_Machine.buff, and call USBH_Set_Report() repeatedly, while it returns USBH_BUSY.
    when finishes, it returns USBH_OK / USBH_FAIL / USBH_NOT_SUPPORTED (got STALL from device)

    Tsuneo

Children
  • Hi Tsuneo,

    Thanks....

    Yes Platform is Keil-arm with Ulink-2,
    Library is : Stm32_f105-07_f2_f4_usb-host-device_lib\STM32_USB-Host-Device_Lib_V2.0.0\Project\USB_Host_Examples\HID\MDK-ARM

    Enumeration is done....

    What I have done is as below

    uint8_t Power_Down[]={16,1};
    //------------------------------------------------------------------------
    case HID_IDLE: HID_Machine.cb->Init(); // HID_Machine.state = HID_GET_DATA; // comment by krunal HID_Machine.state = HID_SEND_DATA; // Added by krunal break;

    /* HID_SEND_DATA is added by krunal*/
    case HID_SEND_DATA:

    USBH_Set_Report (pdev, phost, reportType, uint8_t reportId, uint8_t reportLen, Power_Down);
    HID_Machine.state = HID_GET_DATA; break; case HID_GET_DATA:

    break;

    //------------------------------------------------------------------------

    If above is true than
    In function USBH_Set_Report(,,,,);
    What is report type,report id, report length?

    -Krunal

  • > What is report type,report id, report length?

    The report is specific to your device.
    If you wouldn't know about the report, you have to pick it up from sniffer trace.
    Run a sniffer on a PC, and connect the target device to the PC.
    Play with the device on a PC application, and find the report on the sniffer log.

    Tsuneo

  • Beagle sniffer Report :
    Data transmit : OK
    Data Receive : OK

    I have used below function for transmit data

    USBH_InterruptSendData(,,,);

    Status: URB done ,USBH ok

    Analyze the transmit data from HOST(STM34 board) to Braille with Beagle analyzer
    Problem found with transmit data string at device output(In sniffer log) which is not same as our transmitting data.

    For example if we are transmitting data

    Braille_Disp[]={0x01,0x01,0x02,0x03…};//18 bytes including display ID
    
    In this case beagle is showing Out_txn data
    {0x00 ,0x01,0x01,0x02,0x03 …..}
    
    i.e.. 0x00 ahead of actual data buffer
    

    So kindly help me to solve this problem.

    Regards,
    Krunal

  • How about the alignment of the buffer?
    The buff parameter of USBH_InterruptSendData() is fed to USB_OTG_WritePacket() as its src parameter. In this routine, src is expected to be aligned in 4 bytes (DWORD).

    STM32_USB-Host-Device_Lib_V2.1.0\Libraries\STM32_USB_OTG_Driver\src\usb_core.c
    
    USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev,
                                    uint8_t             *src,
                                    uint8_t             ch_ep_num,
                                    uint16_t            len)
    {
      USB_OTG_STS status = USB_OTG_OK;
      if (pdev->cfg.dma_enable == 0)
      {
        uint32_t count32b= 0 , i= 0;
        __IO uint32_t *fifo;
    
        count32b =  (len + 3) / 4;
        fifo = pdev->regs.DFIFO[ch_ep_num];
        for (i = 0; i < count32b; i++, src+=4)
        {
          USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) );
        }
      }
      return status;
    }
    

    Tsuneo

  • Hello,
    Actually project was on hold.

    Thanks again for help.

    In my case above function(As Mr.Tsuneo suggested) is not calling by below Interrupt routine for data transmitt

    I want to transmit
    
    uint8_t Disp_braille_data[20]={0x1b,0x01,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x16,0x16};
    
    I used
     USBH_InterruptSendData(pdev,
                                  Disp_braille_data,//HID_Machine.buff,
                                  20,//HID_Machine.length,
                                  HID_Machine.hc_num_out);
    

    Above function is calling

    USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
    {
    ......
    ......
    ......
    ......
    ......
    
    
      if (pdev->cfg.dma_enable == 1)
      {
        USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff);
      }
    
    
      hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
      hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev);
    
      /* Set host channel enable */
      hcchar.b.chen = 1;
      hcchar.b.chdis = 0;
      USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
    ......
    ......
    ......
    ......
    ......
    }
    


    Above function is transmitting data.
    Sniffer: Totalphase analyser
    resource:\STM32_F105-07_F2xx_USB-Host-Device_Lib_V2.0.0\Project\USB_Host_Examples\HID\MDK-ARM

    Sniffer log:
    OUT txn : 00 1B 01 03 04 05 06 07 08 09 10 11 12 13 14 15 16 16 16 - OUT Packet : E1 01 C1 - DATA0 Packet : C3 00 1B 01 03 04 05 06 07 08 09 10 11 12 13 14 15 16 16 16 9B 26 - ACK Packet : D2 (Status ok)

    So again question is same why 0x00 ahead of original data frame.

    I tried but unable to find solution. So please help me.

    Regards,
    Krunal