PSoC5LP - Multiple USB devices on single USBFS component?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Hi all,

   

I have some questions about USB functionality on a PSoC5LP.  The project I'm working on requires multiple USB devices on a single USB connection.  Namely, both a USB HID (keypad) and a USB UART.  I have gotten both of these components working separately (I.E. in different projects) but I can't seem to figure out how to run both these devices at the same time on the same USBFS component.  For the USB UART, I used the descriptor template USBUART_TwoComPorts.root.xml (came with PSoC Creator) and deleted the second COM port from the descriptor (CDC Interface 3 and 4), as I only need one of the COM ports.  This works on its own, and I can take data in and echo it back to the virtual COM port as seen from my PC.  However I can't seem to get it working in conjunction with a USB HID in the same component.

   

I imagine there are rules to running multiple devices on this single USBFS component, I'm just not aware of them.
I'm currently starting USB up as follows:

   

uint8 Keyboard_Data[8] = {0,0,0,0,0,0,0,0};
USBFS_1_Start(0,USBFS_1_DWR_VDDD_OPERATION);  //Start up the USB HID Keypad    
USBFS_1_EnableOutEP(2);
USBFS_1_Start(1,USBFS_1_DWR_VDDD_OPERATION);  //Start up the USB UART
while(!USBFS_1_bGetConfiguration());
USBFS_1_LoadInEP(1, Keyboard_Data, 8);
USBFS_1_CDC_Init();

   

I then call the following periodically to send keyboard data:

   

if(USBFS_1_bGetEPAckState(1)) {
    USBFS_1_LoadInEP(1, Keyboard_Data, 8);
    while(!USBFS_1_bGetEPAckState(1));
}

   

I also call a periodic function to take in CDC data and echo it back:

   

    if (USBFS_1_DataIsReady()){
        count = USBFS_1_GetAll(USB_Buffer);     /*MAX 64 BYTES PER SPEC*/
        if (count != 0){
            /*We have data*/   
            /*Wait until ready to send data*/
            while (!USBFS_1_CDCIsReady());
            /*Echo it back*/
            USBFS_1_PutData(USB_Buffer,count);
            /*If we are at max buffer size, append a NULL to assure PC identifies end of data*/
            if (count == MAX_USBUART_BUFFSIZE){
                while (!USBFS_1_CDCIsReady());
                USBFS_1_PutData(NULL,0);
            }
        }
    }

   

Where I run into problems is when I attempt to add a USB UART.

   

My question is, in what way should I be configuring/starting the devices up as to have the USB UART function at the same time as the HID Keypad?  What considerations do I need to have in mind so that the devices play nice with each other?  I'm very new to using PSoC and USB so it's possible it's something very obvious that I'm just not familiar with.

   

Any advice would be greatly appreciated.

   

Thanks!

0 Likes
1 Solution
11 Replies
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

A quick update after having messed around further.

   

Some issues I believe were being caused by conflicting Endpoints.  Once I configured all the devices to not share any endpoints I am able to get both working in the same project, but only if I start one device and not the other.  I.E. starting only the USB UART (CDC) functions as a COM port, and starting only the HID Keypad functions as a USB Keyboard.  However I still can't get both running at once to be recognized by windows.  Do I have to wait for the configuration (USBFS_1_bGetConfiguration()) each time I start a device, or can I start both devices then wait for USBFS_1_bGetConfiguration()? 

   

Here's the code for what I'm referring to:

   
    

Working (Enable Device 1 or 2):

    

USBFS_1_Start(1,USBFS_1_DWR_VDDD_OPERATION);
while(!USBFS_1_bGetConfiguration());
USBFS_1_CDC_Init();

    

OR

    

USBFS_1_Start(0,USBFS_1_DWR_VDDD_OPERATION);  
USBFS_1_EnableOutEP(2);
while(!USBFS_1_bGetConfiguration());
USBFS_1_LoadInEP(1, Keyboard_Data, 8);

   
   

 

   
    

Not Working (Enable Both Device 1 and 2):

    

USBFS_1_Start(0,USBFS_1_DWR_VDDD_OPERATION);  
USBFS_1_EnableOutEP(2);
USBFS_1_Start(1,USBFS_1_DWR_VDDD_OPERATION);
while(!USBFS_1_bGetConfiguration());
USBFS_1_LoadInEP(1, Keyboard_Data, 8);
USBFS_1_CDC_Init();

   
0 Likes
himam_31
Employee
Employee
50 likes received 25 likes received 10 likes received

Hello ,

   

In your case you have multiple interfaces. You must use Interface Association Descriptor(IAD). IAD will bind a set of endpoints to a particular interface.Please let u sknow if you have used IAD in the project.

   

Thanks,

   

Hima

0 Likes

Yes, I am using an IAD, it is located in the tree underneath the USB UART Device Descriptor (see attached screengrab).  Do I need to include one for each device (Both the USB UART as well as the HID)?

   

The IAD I have now is below:

   

   

0 Likes
himam_31
Employee
Employee
50 likes received 25 likes received 10 likes received

Hello,

   

You need not give IAD for HID since it has only one interface.In the IAD please assign the parameters as follows,

   

Function Class: 0xEF

   

Function Subclass:0

   

Protocol:0x01

   

Thanks,

   

Hima

0 Likes

Thanks for the response.  I did as advised (see capture screenshot):

   

   

Now I get a single "USB Composite Device" in the Windows device manager.  Is this expected?  If so, how should I go about acquiring a driver that encompasses both the USB UART COM port as well as the HID Keyboard?

   

Also, is my initialization correct in code?  Do I need to initialize the HID and CDC in any specific order?

   

USBFS_1_Start(0,USBFS_1_DWR_VDDD_OPERATION);  
USBFS_1_EnableOutEP(2);
USBFS_1_Start(1,USBFS_1_DWR_VDDD_OPERATION);
while(!USBFS_1_bGetConfiguration());
USBFS_1_LoadInEP(1, Keyboard_Data, 8);

   

USBFS_1_CDC_Init();

   

 

   

Thanks again for the assistance!

   

0 Likes
lock attach
Attachments are accessible only for community members.
emen_2218296
Level 4
Level 4
25 replies posted 10 replies posted 5 replies posted

You are using two device descriptors. But note that there is only one device descriptor you can use when you enumerate. Try iAD like below. 

   

   

 

   

I have not tried this on my board. But if this does not work, change device descriptor as,

   

bDeviceClass = 0xEF

   

bDeviceSubClass = 0x02

   

bDeviceProtocol = 0x01

   

 

   

0 Likes
Anonymous
Not applicable

I have a similar issue. I am trying to convert an Audio class device to a composite Audio / CDC. I have successfully defined the Interface Association Descriptor for both the Audio class interfaces and the CDC interfaces, so that both the Audio device and the USB serial port get enumerated correctly by Windows. But when I try to open the Audio device on Windows, it fails.

   

Do I need to perform any specific initialization at the PSoC side once I converted the Audio class descriptor to a composite descriptor? Or will all the USBFS provided interfaces be served automatically? 

   

Will the composite Audio / CDC work at all? I am using a PSoC Creator 3.3 with a CY8C3246PVI device.

   

Thanks, Vojtech

0 Likes

I am not clear on this response. Did the attached HID project file work as needed?  I am trying to do something similar with two MIDI I/F's on one USB physical port and am not finding success.

0 Likes

BTW re my post  above I am referring to the project attached by

emen_2218296

0 Likes
himam_31
Employee
Employee
50 likes received 25 likes received 10 likes received

Hello,

We have published a KBA regrading this

Implementing USB Composite Device with PSoC 3, PSoC 4L, or PSoC 5LP - KBA223141

Thanks,

Hima

david-given
Level 4
Level 4
10 sign-ins 5 sign-ins First solution authored

Very belatedly: I have an example of doing precisely this (USB HID keyboard with a UART for debugging) here.

GitHub - davidgiven/maxii-keyboard: PSoC5 firmware to for an ancient MAX-II industrial keyboard