cancel
Showing results for 
Search instead for 
Did you mean: 

USB Host and Composite device..

mak1308
Associate III
Posted on February 08, 2016 at 12:03

How to make on STM32F4 USB a host with support of the Composite device?

I made the project in CubeMX, but in this project there is a support of different classes of devices, but there is no support of the Composite device.

#host #usb
10 REPLIES 10
Walid FTITI_O
Senior II
Posted on February 09, 2016 at 11:56

Hi g.marat,

Could you specify which version of CubeMx you are using ?

-Hannibal-

mak1308
Associate III
Posted on February 09, 2016 at 13:18

Version 4.12.0

Walid FTITI_O
Senior II
Posted on March 10, 2016 at 18:57

Hi g.marat, 

Try the new version 4.13.0

-Hannibal-

tsuneo
Senior
Posted on March 11, 2016 at 14:23

Regardless of CubeMX version,

STM32_USB_Host_Library V3.2.2 / 07-July-2015 (included in the latest STM32Cube_FW_F4_V1.11.0) doesn't support composite device yet.

It is obvious when you see this code in usbh_core.c

USBH_StatusTypeDef  USBH_Process(USBH_HandleTypeDef *phost)

{

  ...  

  switch (phost->gState)

  {

  ...

  case HOST_CHECK_CLASS:

    

    if(phost->ClassNumber == 0)

    {

      USBH_UsrLog (''No Class has been registered.'');

    }

    else

    {

      phost->pActiveClass = NULL;

      

      for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS ; idx ++)

      {

        if(phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass)  // <----

        {

          phost->pActiveClass = phost->pClass[idx];

        }

      }

Just the first interface (Itf_Desc[0]) is hard-coded, here.

To support a composite device,

''case HOST_CHECK_CLASS:'',''case HOST_CLASS_REQUEST:'', and ''case HOST_CLASS:'' should be modified so that these cases do their job for each interface.

Tsuneo

Posted on January 19, 2017 at 08:12

Hi, i'm trying to do the similar thing to g.marat.

I used stm32f4 discovery board to communicate with Dualshock4 (PS4's controller) which has 4 interface (bNumInterfaces) but there are 6

element

s in the Itf_Desc[] array.

After i connected then read the CfgDesc i found that only Itf_Desc[5] is HID class. So now i'm trying to communicate with that interface.

Here is what i had done:

in case HOST_CHECK_CLASS: hard-coded Itf_Desc[5]

in function: USBH_HID_InterfaceInit, i set phost->Control.pipe_in=HID_Handle->InPipe and phost->Control.pipe_out = HID_Handle->OutPipe .

but then i got stuck at USBH_HID_GetHIDDescriptor because USBH_HandleEnum 's state is USBH_BUSY and URB_Status is USBH_URB_NOTREADY.

hope you could help my case.

Posted on January 19, 2017 at 17:06

Liêm Lê wrote:

Dualshock4 (PS4's controller) which has 4 interface (bNumInterfaces) but there are 6

element

s in the Itf_Desc[] array.

It sounds odd.

I don't have Dualshock 4. I've searched for its descriptors on the net, found them on these sites.

http://www.psdevwiki.com/ps4/DS4-USB

http://eleccelerator.com/wiki/index.php?title=DualShock_4

According to these sites, Dualshock 4 exposes just single HID interface.

A couple of more sites also show the same descriptors.

Once on your PC, read out the descriptors of your Dualshock4.

You may have a variant of Dualshock4 😉

Here are utilities for each OS,

Windows - USBView

http://www.ftdichip.com/Support/Utilities.htm ♯ MicrosoftUSBView

Linux - lsusb command

MacOSX - USBProber

http://superuser.com/questions/781982/how-can-i-install-usb-prober-from-the-developer-sdk-on-mac-os-x

If your Dualshock4 would be the standard one (single HID I/F), you may start with HID host example, generated by CubeMX.

Tsuneo

Posted on January 20, 2017 at 05:29

First of all, thanks you for your time

yep , i had already read those site few days ago but their information is for old Dualshock 4 (CUH-ZCT1) , mine is CUH-ZCT2  and i cant find any site show this version's descriptors.

the PID of CUH-ZCT2 is 0x09CC when CUH-ZCT1 is 0x05C4

I had successfully read my keyboard and mouse with HID host generated by CubeMX.

I have just tested with my friend's Dualshock 3 which have 1 interface, and it had gone further

Here is the descriptor i get when use USBView :

Device Descriptor:

bcdUSB: 0x0200

bDeviceClass: 0x00

bDeviceSubClass: 0x00

bDeviceProtocol: 0x00

bMaxPacketSize0: 0x40 (64)

idVendor: 0x054C (Sony Corporation)

idProduct: 0x09CC

bcdDevice: 0x0100

iManufacturer: 0x01

0x0409: 'Sony Interactive Entertainment'

iProduct: 0x02

0x0409: 'Wireless Controller'

iSerialNumber: 0x00

bNumConfigurations: 0x01

ConnectionStatus: DeviceConnected

Current Config Value: 0x01

Device Bus Speed: Full

Device Address: 0x0A

Open Pipes: 2

Endpoint Descriptor:

bEndpointAddress: 0x84 IN

Transfer Type: Interrupt

wMaxPacketSize: 0x0040 (64)

bInterval: 0x05

Endpoint Descriptor:

bEndpointAddress: 0x03 OUT

Transfer Type: Interrupt

wMaxPacketSize: 0x0040 (64)

bInterval: 0x05

Configuration Descriptor:

wTotalLength: 0x00E1

bNumInterfaces: 0x04

bConfigurationValue: 0x01

iConfiguration: 0x00

bmAttributes: 0xC0 (Bus Powered Self Powered )

MaxPower: 0xFA (500 Ma)

Interface Descriptor:

bInterfaceNumber: 0x00

bAlternateSetting: 0x00

bNumEndpoints: 0x00

bInterfaceClass: 0x01 (Audio)

bInterfaceSubClass: 0x01 (Audio Control)

bInterfaceProtocol: 0x00

iInterface: 0x00

Audio Control Interface Header Descriptor:

bLength: 0x0A

bDescriptorType: 0x24

bDescriptorSubtype: 0x01

bcdADC: 0x0100

wTotalLength: 0x0047

bInCollection: 0x02

baInterfaceNr[1]: 0x01

baInterfaceNr[2]: 0x02

Audio Control Input Terminal Descriptor:

bLength: 0x0C

bDescriptorType: 0x24

bDescriptorSubtype: 0x02

bTerminalID: 0x01

wTerminalType: 0x0101 (USB streaming)

bAssocTerminal: 0x06

bNrChannels: 0x02

wChannelConfig: 0x0003

iChannelNames: 0x00

iTerminal: 0x00

Audio Control Feature Unit Descriptor:

bLength: 0x0A

bDescriptorType: 0x24

bDescriptorSubtype: 0x06

bUnitID: 0x02

bSourceID: 0x01

bControlSize: 0x01

bmaControls[0]:

03

bmaControls[1]:

00

bmaControls[2]:

00

iFeature: 0x00

Audio Control Output Terminal Descriptor:

bLength: 0x09

bDescriptorType: 0x24

bDescriptorSubtype: 0x03

bTerminalID: 0x03

wTerminalType: 0x0402 (Headset)

bAssocTerminal: 0x04

bSoruceID: 0x02

iTerminal: 0x00

Audio Control Input Terminal Descriptor:

bLength: 0x0C

bDescriptorType: 0x24

bDescriptorSubtype: 0x02

bTerminalID: 0x04

wTerminalType: 0x0402 (Headset)

bAssocTerminal: 0x03

bNrChannels: 0x01

wChannelConfig: 0x0000

iChannelNames: 0x00

iTerminal: 0x00

Audio Control Feature Unit Descriptor:

bLength: 0x09

bDescriptorType: 0x24

bDescriptorSubtype: 0x06

bUnitID: 0x05

bSourceID: 0x04

bControlSize: 0x01

bmaControls[0]:

03

bmaControls[1]:

00

iFeature: 0x00

Audio Control Output Terminal Descriptor:

bLength: 0x09

bDescriptorType: 0x24

bDescriptorSubtype: 0x03

bTerminalID: 0x06

wTerminalType: 0x0101 (USB streaming)

bAssocTerminal: 0x01

bSoruceID: 0x05

iTerminal: 0x00

Interface Descriptor:

bInterfaceNumber: 0x01

bAlternateSetting: 0x00

bNumEndpoints: 0x00

bInterfaceClass: 0x01 (Audio)

bInterfaceSubClass: 0x02 (Audio Streaming)

bInterfaceProtocol: 0x00

iInterface: 0x00

Interface Descriptor:

bInterfaceNumber: 0x01

bAlternateSetting: 0x01

bNumEndpoints: 0x01

bInterfaceClass: 0x01 (Audio)

bInterfaceSubClass: 0x02 (Audio Streaming)

bInterfaceProtocol: 0x00

iInterface: 0x00

Audio Streaming Class Specific Interface Descriptor:

bLength: 0x07

bDescriptorType: 0x24

bDescriptorSubtype: 0x01

bTerminalLink: 0x01

bDelay: 0x01

wFormatTag: 0x0001 (PCM)

Audio Streaming Format Type Descriptor:

bLength: 0x0B

bDescriptorType: 0x24

bDescriptorSubtype: 0x02

bFormatType: 0x01

bNrChannels: 0x02

bSubframeSize: 0x02

bBitResolution: 0x10

bSamFreqType: 0x01

tSamFreq[1]: 0x007D00 (32000 Hz)

Endpoint Descriptor:

bEndpointAddress: 0x01 OUT

Transfer Type: Isochronous

wMaxPacketSize: 0x0084 (132)

wInterval: 0x0001

bSyncAddress: 0x00

Audio Streaming Class Specific Audio Data Endpoint Descriptor:

bLength: 0x07

bDescriptorType: 0x25

bDescriptorSubtype: 0x01

bmAttributes: 0x00

bLockDelayUnits: 0x00

wLockDelay: 0x0000

Interface Descriptor:

bInterfaceNumber: 0x02

bAlternateSetting: 0x00

bNumEndpoints: 0x00

bInterfaceClass: 0x01 (Audio)

bInterfaceSubClass: 0x02 (Audio Streaming)

bInterfaceProtocol: 0x00

iInterface: 0x00

Interface Descriptor:

bInterfaceNumber: 0x02

bAlternateSetting: 0x01

bNumEndpoints: 0x01

bInterfaceClass: 0x01 (Audio)

bInterfaceSubClass: 0x02 (Audio Streaming)

bInterfaceProtocol: 0x00

iInterface: 0x00

Audio Streaming Class Specific Interface Descriptor:

bLength: 0x07

bDescriptorType: 0x24

bDescriptorSubtype: 0x01

bTerminalLink: 0x06

bDelay: 0x01

wFormatTag: 0x0001 (PCM)

Audio Streaming Format Type Descriptor:

bLength: 0x0B

bDescriptorType: 0x24

bDescriptorSubtype: 0x02

bFormatType: 0x01

bNrChannels: 0x01

bSubframeSize: 0x02

bBitResolution: 0x10

bSamFreqType: 0x01

tSamFreq[1]: 0x003E80 (16000 Hz)

Endpoint Descriptor:

bEndpointAddress: 0x82 IN

Transfer Type: Isochronous

wMaxPacketSize: 0x0022 (34)

wInterval: 0x0001

bSyncAddress: 0x00

Audio Streaming Class Specific Audio Data Endpoint Descriptor:

bLength: 0x07

bDescriptorType: 0x25

bDescriptorSubtype: 0x01

bmAttributes: 0x00

bLockDelayUnits: 0x00

wLockDelay: 0x0000

Interface Descriptor:

bInterfaceNumber: 0x03

bAlternateSetting: 0x00

bNumEndpoints: 0x02

bInterfaceClass: 0x03 (HID)

bInterfaceSubClass: 0x00

bInterfaceProtocol: 0x00

iInterface: 0x00

HID Descriptor:

bcdHID: 0x0111

bCountryCode: 0x00

bNumDescriptors: 0x01

bDescriptorType: 0x22

wDescriptorLength: 0x01FB

Endpoint Descriptor:

bEndpointAddress: 0x84 IN

Transfer Type: Interrupt

wMaxPacketSize: 0x0040 (64)

bInterval: 0x05

Endpoint Descriptor:

bEndpointAddress: 0x03 OUT

Transfer Type: Interrupt

wMaxPacketSize: 0x0040 (64)

bInterval: 0x05

And it's similar which the one i got by stm32f4.

Posted on January 20, 2017 at 14:36

Liêm Lê wrote:

mine is CUH-ZCT2 (Dualshock 4 ver2)

OK, your USB device is a composite device of four interfaces,

0 Audio Control 1 Audio Streaming (OUT) 2 Audio Streaming (IN) 3 HID

You may still start at a USBHID host generated by CubeMX.

CubeMX: v4.0 CubeF4: v1.0

The Cube HID host is customized for boot mouse and keyboard.

A little modification will release this limitation. Here is the snippet.

As your device has four interfaces, this macro should be touched to accept more interfaces than the default.

usbh_conf.h
// line 56:
#define USBH_MAX_NUM_INTERFACES 2 <--- 4
�?�?�?

To accept the HID interface of DS4, USBH_HID_InterfaceInit is modified.

usbh_hid.c
static USBH_StatusTypeDef USBH_HID_InterfaceInit (USBH_HandleTypeDef *phost)
{
...
// replace line 147
// interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, 0xFF);
 interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, 0x00, 0x00);
...
// delete from line 161 to 176
 /*Decode Bootclass Protocol: Mouse or Keyboard*/
 if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE)
 {
 USBH_UsrLog ('KeyBoard device found!'); 
 HID_Handle->Init = USBH_HID_KeybdInit; 
 }
 else if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol == HID_MOUSE_BOOT_CODE) 
 {
 USBH_UsrLog ('Mouse device found!'); 
 HID_Handle->Init = USBH_HID_MouseInit; 
 }
 else
 {
 USBH_UsrLog ('Protocol not supported.'); 
 return USBH_FAIL;
 }
// add this line, instead
 HID_Handle->Init = USBH_HID_MouseInit; // replace with USBH_HID_DS4Init, after DS4 handler is established
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Now that, the modified host code catches the HID interface of the DS4.

As the next steps,

1) Read out the report descriptor from your DS4 2) Identify report fields for DS4 axes, buttons, hat switches and specific functions

The report descriptor defines the size of reports and their fields for input/output/feature reports (data block). It also gives suggestions of field type (Axis, button, hat switch). But just with the report descriptor, each data field can't be identified. You'll identify each field by finding the field whose value changes when you would manipulate each axis/botton.

There are a couple way to read out the report descriptor, here is easier one 😉

0. Download the trial (33 days) of USBlyzer

http://www.usblyzer.com/download.htm

1. Run USBlyzer. Under Capture menu, confirm that 'Capture Hot-plugged' has check mark. If not, select it once. 2. push 'Start Capture' button 3. Plug in your DS4 to the PC. - USBlyzer starts to log the traffic 4. After 3-4 seconds, push 'Stop Capture' button 5. On the Device Tree pane, find the target and click 'USB Human Interface Device' just above the target. - USB Properties pane shows the descriptors of the mouse with HID report descriptor. 6. Right click on USB Properties pane, and choose 'Export' on the right menu. - file dialog saves a HTML file of descriptors.

Please post the descriptors HTML file, here.

We'll analyze the report descriptor, together.

Tsuneo

Posted on January 21, 2017 at 13:27

Hi Tsuneo,

As i mentioned before even the cfgDesc said it has 4 interface (bNumInterfaces) but there is 6 elements Itf_Desc[] array. so the USBH_MAX_NUM_INTERFACES should be 6.(i attached an image).

And i had done the same thing you said about

USBH_HID_InterfaceInit() function. Not just that, the USBH_SelectInterface (phost, interface) need to be modified too. 
USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface) {  USBH_StatusTypeDef status = USBH_OK;   // if(interface < phost->device.CfgDesc.bNumInterfaces) // {  phost->device.current_interface = interface;  USBH_UsrLog ('Switching to Interface (#%d)', interface);  USBH_UsrLog ('Class : %xh', phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass );  USBH_UsrLog ('SubClass : %xh', phost->device.CfgDesc.Itf_Desc[interface].bInterfaceSubClass );  USBH_UsrLog ('Protocol : %xh', phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol );  // } // else // { // USBH_ErrLog ('Cannot Select This Interface.'); // status = USBH_FAIL;  // }  return status;  }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Because

USBH_FindInterface(phost, phost->pActiveClass->ClassCode, 0x00, 0x00); returned 5 but phost->device.CfgDesc.bNumInterfaces just only 4. 
I have a question about opening pipe too. Why they not set phost->Control.pipe_out/in after opened it 
for ( ;num < max_ep; num++)  {  if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress & 0x80)  {  HID_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress);  HID_Handle->InPipe =\  USBH_AllocPipe(phost, HID_Handle->InEp);    /* Open pipe for IN endpoint */  USBH_OpenPipe (phost,  HID_Handle->InPipe,  HID_Handle->InEp,  phost->device.address,  phost->device.speed,  USB_EP_TYPE_INTR,  HID_Handle->length);     //phost->Control.pipe_in=HID_Handle->InPipe;  USBH_LL_SetToggle (phost, HID_Handle->InPipe, 0);    }  else  {  HID_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress);  HID_Handle->OutPipe =\  USBH_AllocPipe(phost, HID_Handle->OutEp);    /* Open pipe for OUT endpoint */  USBH_OpenPipe (phost,  HID_Handle->OutPipe,  HID_Handle->OutEp,   phost->device.address,  phost->device.speed,  USB_EP_TYPE_INTR,  HID_Handle->length);     //phost->Control.pipe_out=HID_Handle->OutPipe;  USBH_LL_SetToggle (phost, HID_Handle->OutPipe, 0);     }    } �?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

After i done all of those i still got stuck at USBH_HID_ClassRequest() in case HID_REQ_GET_HID_DESC:

case HID_REQ_GET_HID_DESC:    /* Get HID Desc */     if (USBH_HID_GetHIDDescriptor (phost, USB_HID_DESC_SIZE)== USBH_OK)  {  USBH_HID_ParseHIDDesc(&HID_Handle->HID_Desc, phost->device.Data);  HID_Handle->ctl_state = HID_REQ_GET_REPORT_DESC;  }    break;�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

USBH_HID_GetHIDDescriptor can't return USBH_OK.

USBH_HID_SetProtocol (phost, 0) in 'case HID_REQ_SET_PROTOCOL:' got the same problem too.

So i bypassed those then get into USBH_HID_Process() but it stuck in 'case HID_IDLE:' too.

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;�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

i wish that it could be easy as said 😉

Do you have or know where i can get some documents about USB host, i did some search but only got 2 site :

http://www.beyondlogic.org/usbnutshell/usb6.shtml#StandardDeviceRequests

http://www.usbmadesimple.co.uk/ums_5.htm

and both of those don't explain about parameters of USB HID Request.

i couldn't get the meanning of wValue and wIndex in this function:

USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,  uint8_t reportType,  uint8_t reportId,  uint8_t* reportBuff,  uint8_t reportLen) {    phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_RECIPIENT_INTERFACE |\  USB_REQ_TYPE_CLASS;      phost->Control.setup.b.bRequest = USB_HID_GET_REPORT;  phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;    phost->Control.setup.b.wIndex.w = 0;  phost->Control.setup.b.wLength.w = reportLen;    return USBH_CtlReq(phost, reportBuff , reportLen ); }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

________________

Attachments :

debug.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyyk&d=%2Fa%2F0X0000000bEo%2FMj53S8USgoKRhQ7pbWjga5ZaZIdmAueJL9P6yHWw27M&asPdf=false