cancel
Showing results for 
Search instead for 
Did you mean: 

stm32cube, usb host, hid mouse/keyboard

arnie1
Associate
Posted on October 09, 2016 at 14:54

hello,

I've been trying to set up some basic usb comunication with a usb mouse using my stm32f4 discvery. there are no usb examples for my board so I went in to look at other boards.

I generated a project with cube inlcuding USB_OTG_FS in host only mode and four IO pins for LED's.

I had a look in the files and it seemed like reading mouse buttons would be fairly trivial, but I can't make it work.

if I run

[code]devtype = USBH_HID_GetDeviceType(&hUsbHostFS);[/code]

it detects the device correctly.

[code]USBH_HID_MouseInit(&hUsbHostFS)[/code] returns USBH_OK

but no matter what I try

[code]mouse=USBH_HID_GetMouseInfo(&hUsbHostFS);[/code] is always NULL

''USBH_HID_MouseInit'' is never mentioned in the documentation(DM00105256.pdf)

also, only the RTOS examples use them. Reading the standalone example, it would seem that to comunicate with a mouse would be as simple as runing GetDeviceType, and GetMouseInfo, but I can't get it to work.

this is all the code I added, it's executed in the main while

[code]

    if(Appli_state == APPLICATION_READY){

    switch(state)

    {

    case 0:

          devtype = USBH_HID_GetDeviceType(&hUsbHostFS);

           if(devtype == HID_MOUSE){

               HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14,1);

               HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,0);

               state=1;

           }

           else if(devtype == HID_KEYBOARD){

               HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14,0);

               HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,1);

               state=2;

           }

           else{

               HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14,0);

               HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,0);

           }

    break;

    case 1:

        if(USBH_HID_MouseInit(&hUsbHostFS)==0){

            HAL_GPIO_WritePin(GPIOD,GPIO_PIN_15,1);

            state=3;

        }

        else {

            HAL_GPIO_WritePin(GPIOD,GPIO_PIN_15,0);

            state=0;

        }

    break;

    case 3:

        mouse=USBH_HID_GetMouseInfo(&hUsbHostFS);

        if(mouse != NULL)HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,1);

        else HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,0);

    break;

    default:

        break;

    }

    }

    if(Appli_state != APPLICATION_READY) state=0;

[/code]
9 REPLIES 9
Amel NASRI
ST Employee
Posted on October 11, 2016 at 15:53

Hi nurd,

If you start from the example STM32Cube_FW_F4_V1.13.0\Projects\STM324xG_EVAL\Applications\USB_Host\HID_Standalone, then comment all board specific features, you should be able to run the example on your discovery board.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on September 22, 2017 at 00:27

sorry, I have the same problem. I try to use stm32cube to configure usb host hid for communication with usb mouse but it's not work.

Please help me.

Posted on November 14, 2017 at 17:03

I run 4 examples in STM32F746G-DISCO,  with RTOS, and standalone. The example that I run is the ones provided by st, without any modifications, and it didn't work.

Posted on November 14, 2017 at 17:15

I have also tested it on a custom board (stm32f401), and the same problem. It can comunicate with a microsoft keyboard, but when I plug a cheaper keyboard (leadership and other brands, chinese keyboards), it starts the keyboard, and disconects, I'm sure the keyboard works, and also STM32F746G-DISCO is supossed to work properly (works with microsoft keyboard). I'm compiling with sw4stm32.

erisson
Associate II

I think you need two basic functions: MX_USB_HOST_Init() and MX_USB_HOST_Process();

[code]

int main(void)

{

[...]

 MX_USB_HOST_Init();

while (1)

{

 MX_USB_HOST_Process();

if(Appli_state == APPLICATION_READY)

{

[...]

}

}

}

[/code]

In addition to enabling VBUS

[code]

/**

 * @brief Drive VBUS.

 * @param phost: Host handle

 * @param state : VBUS state

 *     This parameter can be one of the these values:

 *      0 : VBUS Active

 *      1 : VBUS Inactive

 * @retval Status

 */

USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state)

{

 /* USER CODE BEGIN 0 */

 /* USER CODE END 0*/

 if (phost->id == HOST_FS)

 {

  if (state == 0)

  {

   /* Drive high Charge pump */

   /* ToDo: Add IOE driver control */

   /* USER CODE BEGIN DRIVE_HIGH_CHARGE_FOR_FS */

HAL_GPIO_WritePin(OTG_PWR_OUT_GPIO_Port, OTG_PWR_OUT_Pin, GPIO_PIN_SET);

   /* USER CODE END DRIVE_HIGH_CHARGE_FOR_FS */

  }

  else

  {

   /* Drive low Charge pump */

   /* ToDo: Add IOE driver control */

   /* USER CODE BEGIN DRIVE_LOW_CHARGE_FOR_FS */

HAL_GPIO_WritePin(OTG_PWR_OUT_GPIO_Port, OTG_PWR_OUT_Pin, GPIO_PIN_RESET);

   /* USER CODE END DRIVE_LOW_CHARGE_FOR_FS */

  }

 }

 HAL_Delay(200);

 return USBH_OK;

}

[/code]

I'm reading the values ​​but I do not know how to interpret them.

AAgha
Associate II

Hi engenharia4

can you tell me about your microsoft keyboard details!?

i run the code like above with microsoft curve 3000 keyboard but i cant get data form that and always return NULL!

I would appreciate for your answer

HI,

Take a look at this,

https://community.st.com/s/question/0D50X00009XkZ4KSAV/usb-host

https://community.st.com/s/question/0D50X00009XkeVgSAJ/stm32cubef4-applications-usb-host-hid-device-issue

for me, it was the answer,

I have followed changes proposed by @tsuneo​ , and got all keyboards working.

hope this helps.

Att.

thanks for your reply

you just exchange the HID_Handle->state = HID_IDLE; with HID_Handle->state = HID_SYNC;

then keyboards start to communicate?!

in my case it doesnt work, can you share your code!?

regards

code at main. c:

   extern USBH_HandleTypeDef hUsbHostFS;

   extern HID_KEYBD_Info_TypeDef    keybd_info;

   unsigned int output=0;

   if(USBH_HID_GetDeviceType(&hUsbHostFS)==0x02)

   {

      output=USBH_HID_GetRAWCode(USBH_HID_GetKeybdInfo(&hUsbHostFS));

   }

code at usb_hid.c:

/**

 * @brief USBH_HID_Process

 *        The function is for managing state machine for HID data transfers

 * @param phost: Host handle

 * @retval USBH Status

 */

static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)

{

 USBH_StatusTypeDef status = USBH_OK;

 HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;

 switch (HID_Handle->state)

 {

 case HID_INIT:

   HID_Handle->Init(phost);

   HID_Handle->state = HID_SYNC;   // skip HID_IDLE state

   break;

 case HID_IDLE:

   if(USBH_HID_GetReport (phost,

                          0x01,

                           0,

                           HID_Handle->pData,

                           HID_Handle->length) == USBH_OK)

   {

     fifo_write(&HID_Handle->fifo, HID_Handle->pData, HID_Handle->length); 

     HID_Handle->state = HID_SYNC;

   }

   break;

 case HID_SYNC:

   /* Sync with start of Even Frame */

   if(phost->Timer & 1)

   {

     HID_Handle->state = HID_GET_DATA;

   }

#if (USBH_USE_OS == 1)

   osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);

#endif  

   break;

 case HID_GET_DATA:

   USBH_InterruptReceiveData(phost,

                             HID_Handle->pData,

                             HID_Handle->length,

                             HID_Handle->InPipe);

   HID_Handle->state = HID_POLL;

   HID_Handle->timer = phost->Timer;

   HID_Handle->DataReady = 0;

   break;

 case HID_POLL:

   if(USBH_LL_GetURBState(phost , HID_Handle->InPipe) == USBH_URB_DONE)

   {

     if(HID_Handle->DataReady == 0)

     {

       fifo_write(&HID_Handle->fifo, HID_Handle->pData, HID_Handle->length);

       HID_Handle->DataReady = 1;

       USBH_HID_EventCallback(phost);

#if (USBH_USE_OS == 1)

   osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);

#endif         

     }

   }

   else if(USBH_LL_GetURBState(phost , HID_Handle->InPipe) == USBH_URB_STALL) /* IN Endpoint Stalled */

   {

     /* Issue Clear Feature on interrupt IN endpoint */

     if(USBH_ClrFeature(phost,

                        HID_Handle->ep_addr) == USBH_OK)

     {

       /* Change state to issue next IN token */

       HID_Handle->state = HID_GET_DATA;

     }

   }

   break;

 default:

   break;

 }

 return status;

}