cancel
Showing results for 
Search instead for 
Did you mean: 

Writing a USB host for a Composite USB device. (Quectel BG96 modem)

Ashei.8
Associate II

0690X00000ArgV7QAJ.jpgI started off by using the STM cube generated libraries.Reviewing modem's documentation, i assumed that it will be just a CDC device with a few minor changes. I asked Quectel for device descriptor, they sent me one for EC21/EC25 which is similar to BG96.

According to the doc, EC21/EC25 creates five interfaces. (image) i verified it after reading complete device descriptor for BG96. (attached)

Itf_Desc	USBH_InterfaceDescTypeDef [5]	0x2000faa6 <hUsbHostFS+830>	
	Itf_Desc[0]	USBH_InterfaceDescTypeDef	{...}	
		bLength	uint8_t	9 '\t'	
		bDescriptorType	uint8_t	4 '\004'	
		bInterfaceNumber	uint8_t	0 '\0'	
		bAlternateSetting	uint8_t	0 '\0'	
		bNumEndpoints	uint8_t	2 '\002'	
		bInterfaceClass	uint8_t	255 'ÿ'	
		bInterfaceSubClass	uint8_t	255 'ÿ'	
		bInterfaceProtocol	uint8_t	255 'ÿ'	
		iInterface	uint8_t	0 '\0'	
		Ep_Desc	USBH_EpDescTypeDef [3]	0x2000fab0 <hUsbHostFS+840>	
	Itf_Desc[1]	USBH_InterfaceDescTypeDef	{...}	
		bLength	uint8_t	9 '\t'	
		bDescriptorType	uint8_t	4 '\004'	
		bInterfaceNumber	uint8_t	1 '\001'	
		bAlternateSetting	uint8_t	0 '\0'	
		bNumEndpoints	uint8_t	2 '\002'	
		bInterfaceClass	uint8_t	255 'ÿ'	
		bInterfaceSubClass	uint8_t	255 'ÿ'	
		bInterfaceProtocol	uint8_t	255 'ÿ'	
		iInterface	uint8_t	0 '\0'	
		Ep_Desc	USBH_EpDescTypeDef [3]	0x2000fad2 <hUsbHostFS+874>	
	Itf_Desc[2]	USBH_InterfaceDescTypeDef	{...}	
		bLength	uint8_t	9 '\t'	
		bDescriptorType	uint8_t	4 '\004'	
		bInterfaceNumber	uint8_t	2 '\002'	
		bAlternateSetting	uint8_t	0 '\0'	
		bNumEndpoints	uint8_t	3 '\003'	
		bInterfaceClass	uint8_t	255 'ÿ'	
		bInterfaceSubClass	uint8_t	255 'ÿ'	
		bInterfaceProtocol	uint8_t	255 'ÿ'	
		iInterface	uint8_t	0 '\0'	
		Ep_Desc	USBH_EpDescTypeDef [3]	0x2000faf4 <hUsbHostFS+908>	
	Itf_Desc[3]	USBH_InterfaceDescTypeDef	{...}	
		bLength	uint8_t	9 '\t'	
		bDescriptorType	uint8_t	4 '\004'	
		bInterfaceNumber	uint8_t	3 '\003'	
		bAlternateSetting	uint8_t	0 '\0'	
		bNumEndpoints	uint8_t	3 '\003'	
		bInterfaceClass	uint8_t	255 'ÿ'	
		bInterfaceSubClass	uint8_t	254 'þ'	
		bInterfaceProtocol	uint8_t	255 'ÿ'	
		iInterface	uint8_t	0 '\0'	
		Ep_Desc	USBH_EpDescTypeDef [3]	0x2000fb16 <hUsbHostFS+942>	
	Itf_Desc[4]	USBH_InterfaceDescTypeDef	{...}	
		bLength	uint8_t	9 '\t'	
		bDescriptorType	uint8_t	4 '\004'	
		bInterfaceNumber	uint8_t	4 '\004'	
		bAlternateSetting	uint8_t	0 '\0'	
		bNumEndpoints	uint8_t	3 '\003'	
		bInterfaceClass	uint8_t	255 'ÿ'	
		bInterfaceSubClass	uint8_t	255 'ÿ'	
		bInterfaceProtocol	uint8_t	255 'ÿ'	
		iInterface	uint8_t	0 '\0'	
		Ep_Desc	USBH_EpDescTypeDef [3]	0x2000fb38 <hUsbHostFS+976>	

Now, i think to get it to work, i would need to write a class for composite device. I have scavenged the Internets for anything useful, while also experimenting with the CDC class.

i have found a couple of things as

  1. USBH_Process is written in such a way that it will only support a single interface. and that ''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.

for example from Case HOST_CHECK_CLASS:

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

2. Piggybacking over CDC class would be impossible(or i would have to rewrite most of the code, as there are multiple checks within the class's methods(find_interface etc ) to have 0xFF (vendor specific) declared as no valid interface.

The good thing is almost all the endpoints are described as BULK in EC21, so im guessing i would only need one CDC class.

So, For in order to get it to work, i would need to modify usbh_process as well as the entire CDC class.

Am i going in the right direction?

Anyone knows anything about how it can be or should be done?

would i need to know specific codes? there are lot of defines in usbh_cdc.h, would they work? BG96 uses Qualcomms MDM 9206. do they use different codes to get things done?

Any help would be appreciated.

1 REPLY 1
Danish1
Lead II

I tried and failed with Telit modems. I think they used Qualcomm's proprietary QMI protocol and the Quectel might be similar. That's not to say you won't succeed but might need better insight or luck than I had.

If you're familiar with Linux drivers, you might get better insight by looking at gobinet or qmi_wwan.