cancel
Showing results for 
Search instead for 
Did you mean: 

USB Host With Multiple Vendor Specific Devices

jwormsley
Associate III
Posted on August 28, 2014 at 22:23

I'm new to USB programming, and am having some trouble getting my head around the concepts involved.  Hopefully someone can have a look at what I think I need to do to meet my goals and tell me where I'm right and where I'm horribly wrong.

First, my goal is to replace an STM32F103 series CPU on a board that uses all five serial ports available on the CPU, plus four more implemented via a quad UART via the FSMC, with an STM32F417 series CPU.  In the process, I want to be able to connect to some of those serial devices via USB instead, as USB versions of them exist (some are also dual interface), eliminating the need for the quad UART.  These devices include a pinpad, receipt printer, and cellular modem.  I'd also like to be able to insert a USB flash drive to perform software updates.

To do this, I know I'll have to add a USB hub chip to my board, but this doesn't seem to hard from a hardware standpoint.  Where things look difficult is with the software to handle all of this.  It's not simple like RS-232 serial ports.

Here's what I've managed to learn by going through the various demo code available via the STM32Cube package for the F4.

1. For devices that can be controlled via a class driver, I can use USBH_RegisterClass to allow the USB stack to recognize that class.  This should be sufficient for the flash drive by using the MSC class from the examples.

2. Most of my devices are VENDOR SPECIFIC, and so I will have to write a new class driver for this, that will in turn have to handle the individual devices based on their VID/PID values.  Hopefully I can use the HID example that determines whether a mouse or keyboard is attached as an example of figuring out which devices I have attached.  I do not know how to handle this via the VID/PID however, because the HID example uses subclass to determine mouse vs keyboard, and my subclasses are the same on the vendor specific devices.

3. USBH_Process will handle the high level USB functions such as enumeration, and pass any lower level things to the class driver(s).

4. USBH_BulkSendData and USBH_BulkReceiveData will be used to send and receive data from my devices.  These work by setting flags in the state machine for the device handle, which the state machine then processes.

Obviously I'm missing quite a lot here.  I'm trying to work on modifying one of the examples (CDC in this case, as it is similar to the cellular modem in terms of function) to handle the Vendor Specific class that my device uses.  I can get it as far as recognizing that this is a vendor specific class, but crash trying to execute the state machine in the HOST_CLASS_REQUEST state.

I've done a lot of searching, and I haven't really found much useful about interfacing to a vendor specific class device, and nothing about integrating a hub and supporting more than one of them.

Any pointers would be greatly appreciated.

Thanks,

  Jeff
24 REPLIES 24
christo
Associate III
Posted on September 19, 2015 at 01:07

Hi to All,

I make a step ahead with adding for testing purposes in usbh_cdc.c alternative staff in case of CP2102:

static USBH_StatusTypeDef USBH_CDC_InterfaceInit (USBH_HandleTypeDef *phost)
{ 
USBH_StatusTypeDef status = USBH_FAIL ;
uint8_t interface;
CDC_HandleTypeDef *CDC_Handle;
if (phost->pActiveClass->idVendor == 0x10c4 && phost->pActiveClass->idProduct == 0xea60) {
// CP2102
USBH_SelectInterface (phost, interface);
phost->pActiveClass->pData = (CDC_HandleTypeDef *)USBH_malloc (sizeof(CDC_HandleTypeDef));
CDC_Handle = (CDC_HandleTypeDef*) phost->pActiveClass->pData;
interface = USBH_FindInterface(phost,
0xff,
0x00,
0x00);
...
status = USBH_OK;
}
}
else {
// CDC interface = USBH_FindInterface(phost,
COMMUNICATION_INTERFACE_CLASS_CODE,
ABSTRACT_CONTROL_MODEL,
COMMON_AT_COMMAND);
...
status = USBH_OK;
}
}
}
return status;
}

Analogous alternative staff is added in:

USBH_StatusTypeDef USBH_CDC_InterfaceDeInit (USBH_HandleTypeDef *phost)
{
CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef*) phost->pActiveClass->pData;
if (phost->pActiveClass->idVendor == 0x10c4 && phost->pActiveClass->idProduct == 0xea60) {
// CP2102
...
}
else {
// CDC
...
}
return USBH_OK;
}

The result is:

// CP2102
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: ea60h
VID: 10c4h
Address (#1) assigned.
Manufacturer : Silicon Labs
Product : CP2102 USB to UART Bridge Controller
Serial Number : 0001
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : ffh
SubClass : 0h
Protocol : 0h
CDC class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 255
USBH_UserProcess HOST_USER_DISCONNECTION: 255
USB Device disconnected
// CDC
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: 5740h
VID: 483h
Address (#1) assigned.
Manufacturer : STMicroelectronics
Product : ChibiOS/RT Virtual COM Port
Serial Number : 301
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : 2h
SubClass : 2h
Protocol : 1h
CDC class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 2
USBH_UserProcess: HOST_CDC_CLASS_ACTIVATED
USBH_UserProcess HOST_USER_DISCONNECTION: 2
USB Device disconnected

The only stage did not present in case of CP2102 is: HOST_CDC_CLASS_ACTIVATED I try to follow the state machine logic and see that HOST_CHECK_CLASS passed successfully but next phase HOST_CLASS_REQUEST is not entered. I think that both cases have to follow the same logic so it is easier to test the things in a single file which will be split as CDC and CP210x host class drivers later on. Finally, some control functions have to be rewritten as well. The main difference for now between CDC and CP2102 cases is that CP2102 did not has control end point. Any ideas where to search the problem? Best regards Chris
christo
Associate III
Posted on September 19, 2015 at 15:51

Hi to All,

Found the problem with class activation. Set/GetLineCoding ave to be re-written. The result of registration and activation of multiply USB classes is:

The C library printf function was re-targeted to the UART
USB OTG FS Host
Starting MultiDevice Demo
// CDC: ChibiOS/RT Virtual COM Port
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: 5740h
VID: 483h
Address (#1) assigned.
Manufacturer : STMicroelectronics
Product : ChibiOS/RT Virtual COM Port
Serial Number : 301
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : 2h
SubClass : 2h
Protocol : 1h
CDC class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 0x02
USBH_UserProcess: HOST_CDC_CLASS_ACTIVATED
USBH_UserProcess HOST_USER_DISCONNECTION: 0x02
USB Device disconnected
// Silicon Labs CP2102
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: ea60h
VID: 10c4h
Address (#1) assigned.
Manufacturer : Silicon Labs
Product : CP2102 USB to UART Bridge Controller
Serial Number : 0001
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : ffh
SubClass : 0h
Protocol : 0h
CDC class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 0xff
ERROR: GetLineCoding is not provided for this Class Driver.
USBH_UserProcess: HOST_CP2102_CLASS_ACTIVATED
USBH_UserProcess HOST_USER_DISCONNECTION: 0xff
USB Device disconnected
// HID: Mouse
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: c10ah
VID: 9dah
Address (#1) assigned.
Manufacturer : A4Tech
Product : USB Mouse
Serial Number : N/A
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : 3h
SubClass : 1h
Protocol : 2h
Mouse device found!
HID class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 0x03
USBH_UserProcess: HOST_HID_CLASS_ACTIVATED
USBH_UserProcess HOST_USER_DISCONNECTION: 0x03
USB Device disconnected
// HID: Keyboard
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: 26h
VID: 1c4fh
Address (#1) assigned.
Manufacturer : SIGMACHIP
Product : USB Keyboard
Serial Number : N/A
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : 3h
SubClass : 1h
Protocol : 1h
KeyBoard device found!
HID class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 0x03
USBH_UserProcess: HOST_HID_CLASS_ACTIVATED
USBH_UserProcess HOST_USER_DISCONNECTION: 0x03
USB Device disconnected
// Mass Storage Device
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: 119h
VID: bdah
Address (#1) assigned.
Manufacturer : Generic
Product : USB2.0-CRW
Serial Number : 20090815198100000
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : 8h
SubClass : 6h
Protocol : 50h
MSC class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 0x08
Number of supported LUN: 1
LUN #0:
Inquiry Vendor : Generic-
Inquiry Product : SD/MMC
Inquiry Version : 1.00
Sense Key : 6
Additional Sense Code : 28
Additional Sense Code Qualifier: 0
USBH_UserProcess: HOST_MCS_CLASS_ACTIVATED
USBH_UserProcess FATFS_LinkDriver: 0:/
USB Disk Content:
size name
8924 
4706 
8594 
<
dir
> 
8924 
4706 
8594 
<
dir
> 
8924 
4706 
8594 
<
dir
> 
8924 
4706 
8594 
USBH_UserProcess HOST_USER_DISCONNECTION: 0x08
USB Device disconnected
// Audio
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: f211h
VID: 1130h
Address (#1) assigned.
Manufacturer : N/A
Product : USB AUDIO
Serial Number : N/A
Enumeration done.
This device has only 1 configurDefault configuration set.
AUDIO class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 0x01
USBH_UserProcess: HOST_AUDIO_CLASS_ACTIVATED
USBH_UserProcess HOST_USER_DISCONNECTION: 0x01
USB Device disconnected

Next step is to verify control and data communications with CDC and CP2102 devices. Best regards Chris
christo
Associate III
Posted on September 22, 2015 at 15:19

Hi to All,

My target is to transfer data between USB CDC or CP2102 device connected to USB FS interface of stm32f4discovery (initialized as host) and UART. I have managed to receive data via USB host CDC initializing it in Application_Process() at APPLICATION_CDC state and forward them to UART from USBH_CDC_ReceiveCallback(...). It works well but I have faced to a problem trying to transmit received from UART data via USB host CDC. First test was to transmit a few bytes (character command for the connected CDC device) from Application_Process() at APPLICATION_CDC state just after initializing of receiving the data via USB host CDC and it works well (single transfer of 6 bytes). USBH_CDC_TransmitCallback(...) is invoked as expect (only LED is triggered there). Unfortunately, it stops working when I add in man loop following code to read byte from UART and transmit it via USB host CDC:

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USB Host Background task */
USBH_Process(&hUSBHost);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Application_Process();
{
if(HAL_UART_Receive(&huart2, CDC_TX_Buffer, 1, 0) == HAL_OK)
{
BSP_LED_Toggle(Green_LED);
USBH_CDC_Transmit(&hUSBHost, CDC_TX_Buffer, 1);
}
}
}
/* USER CODE END 3 */

and the bytes received from UART are transmitted to USB host CDC very rarely and irregularly. I am transferring data byte by byte because they are entered by the user manually. Later on I plan to initiate this data path from UAR IRQ but the problem for now is in USBH_CDC_Transmit stage. Other problem is when CP2102 device is connected to USB host. In such a case no date are received and transmitted at all. As I mention before I use CDC implementation for communication with CP2102 via bulk endpoints and probably this is the problem. Unfortunately I did not know if this functions have to be changed and how. Can somebody help me to solve above problems? Thanks in advance Chris
christo
Associate III
Posted on September 23, 2015 at 22:19

Hi to All,

Searching Internet I find discussion thread ''

/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Problem%20with%20USB%20Host%20CDC%20class&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21

'' where firman recommend to substitute:

USBx_HC(chnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS; 
USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; 

with something like

uint32_t tmp;
tmp = USBx_HC(chnum)->HCCHAR;
tmp |= USB_OTG_HCCHAR_CHENA;
tmp &= ~ USB_OTG_HCCHAR_CHDIS;
USBx_HC(chnum)->HCCHAR = tmp;

I found 3 occurrences in file stm32f4xx_hal_hcd.c. Recommend substitution solve my problem to transmit data to the devise. I do not make any reliability tests for now but noticed some data lost in massive data sent from the device to the host. Best regards Chris
christo
Associate III
Posted on September 26, 2015 at 11:02

Hi to All,

I have successfully run USB CDC / CP2102 Host to serial demo. It become possible after partial implementation of Silicon Labs CP2102 vendor specific protocol inside CDC host class driver of STM32 USB Host Library. Of course, Tsuneo advise is used to recognize vendor specific protocol devices which needs core library files modification. This is debug log and terminal activity from CDC Host demo running on STM32F4Discovery board with USB OTG to Host and CP2102 USB to Serial adapters connected to CDC/MSC Device demo based on ChibiOS and running on Olimex STM32-H405 like board:

The C library printf function was re-targeted to the UART
USB OTG FS Host
Starting MultiDevice Demo
USBH_UserProcess: HOST_USER_CONNECTION
USB Device Attached
PID: ea60h
VID: 10c4h
Address (#1) assigned.
Manufacturer : Silicon Labs
Product : CP2102 USB to UART Bridge Controller
Serial Number : 0001
Enumeration done.
This device has only 1 configuration.
Default configuration set.
Switching to Interface (#0)
Class : ffh
SubClass : 0h
Protocol : 0h
DEBUG : Found in USBH_CDC_InterfaceInit:
 DataItf.OutPipe/OutEp/EpSize 2/01/64
 DataItf.InPipe/InEp/EpSize 3/81/64
 CDC class started.
USBH_UserProcess HOST_USER_CLASS_SELECTED: 0xff
USBH_UserProcess: HOST_CP2102_CLASS_ACTIVATED
ch> info
Kernel: 2.6.8
Compiler: GCC 4.9.3 20150303 (release) [ARM/embedded-4_9-branch revision 221220]
Architecture: ARMv7-ME
Core Variant: Cortex-M4
Port Info: Advanced kernel mode
Platform: STM32F407/F417 High Performance with DSP and FPU
Board: ChR stm32-h103_405rg
Build time: Aug 28 2015 - 02:33:59
ch> help
Commands: help exit info systime mem threads test time settime tree wfile write
ch>

Currently both implementations coexist and a single driver is able to recognize both CDC and CP2102 devices and load modified CDC class driver. As a result demo act as a USB Host to serial adapter. In addition some other devices (MSC, HID and Audio) can also be recognized but only MSC one has a simple application (lists files and directories from USB MSC device). Unfortunately, only CP210x_IFC_ENABLE is used really and optionally CP210x_GET_BAUDRATE. For implementing the full set of commands CP210x class driver has to be derived and changed to appropriate structure. That is why CP2102 line settings cannot be controlled by the USB Host and the default 115200,8,1,n,n parameter set is used. Current solution is simpler than the case of separate class drivers and can be enough for many use cases. Because the current forum thread is too lonely I do not plan to share my work until some interest appears. Best regards Chris
christo
Associate III
Posted on September 30, 2015 at 23:38

The problem is fixed in stm32f4xx_hal_hcd.c version V1.4.0 dated 14-August-2015

mihnea95rusu
Associate II
Posted on October 14, 2015 at 13:51

Hey,

I'm trying to write a USB Host driver for a vendor specific device and I would appreciate any help I can get. It's a pretty simple device with only 1 bulk endpoint and 1 control, without too many complicated functionalities. I've looked through the provided classes as examples but I don't really know how to start writing one of my own... 

Hi mihnea95rusu

Take a look on:

If find above staff helpful it would be fine to have some feedback from you.

Best regards

Chris

You're poking ghosts from 2015.

It is helpful to have workable links, the last forum transition destroyed a lot of content, mostly links and in-line/formatted code examples.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hello Christo,

I am trying to do the same for CP2104, but I had no success until now.

when I am following your step at the beginning, by defining the IdVendor and idProduct I got this error:

a value of type "USBH_StatusTypeDef (*)(USBH_HandleTypeDef *)" cannot be used to initialize an entity of type "uint16_t"

I really Appreciate you if you share with me your code.

many thanks

Moh