3 Replies Latest reply on Sep 6, 2017 6:34 AM by KTrenholm_1955226

    Configuring and Initializing a Composite USB HID Device on PSoC 5LP?

    KTrenholm_1955226

      Hi all,

       

      I'm working on creating what is essentially an active Dual PS2 to USB converter using a PSoC5LP.  Both devices (A Keyboard and a Mouse) PS2 connections are coming into the PSoC, I need to put the data from both devices onto a single USB line.   I'm currently using the CY8KIT-050 demo kit for proving the idea out.  I have both devices converting to USB individually in separate projects, so i know my HID Descriptors themselves are good, but I'm running into problems configuring the USBFS 3.2 component to combine them into a single composite USB HID.  I am using PSoC Creator v4.1.

       

      First things first, how should the device descriptor be configured for two HIDs?  What's the correct "structure" of the device descriptor?  Is it a single device and configuration with multiple interfaces?  Is it single device with two configurations?  What's the correct way of going about it?  Right now it is laid out as a single device descriptor, with two configuration descriptors.  Each one containing an HID class descriptor:

      UsbCfg.png

      I'm also unclear on how to initialize and send/receive data from a USB device with more than one IN endpoint.  For a single device (Keyboard) with all the data going to the PC in EP1, and data coming in from the PC in EP2, I use the following:

      USBFS_1_Start(0, USBFS_1_DWR_VDDD_OPERATION);
      USBFS_1_EnableOutEP(2);
      while(!USBFS_1_bGetConfiguration());
      USBFS_1_LoadInEP(1,(uint8_t *)USB_Keyboard_Data,8);
      

       

      Then to send any key data to PC and get LED data back to send to the keyboard I call the following periodically:

      while (!USBFS_1_bGetEPAckState(1));
          USBFS_1_LoadInEP(1,(uint8_t *)USB_Keyboard_Data,8);
      USB_LED_Data = USBFS_1_DEVICE0_CONFIGURATION0_INTERFACE0_ALTERNATE0_HID_OUT_BUF[0];
      

      This all works fine.

       

      Now the issues begin when I attempt two HID devices in a single USBFS component.

      EP1(in) and EP2(out) should be taken by the keyboard, so for mouse data, I presume I have to use EP3.  So I initialize:

          USBFS_1_Start(0, USBFS_1_DWR_VDDD_OPERATION);
          USBFS_1_EnableOutEP(2);
          while(!USBFS_1_bGetConfiguration());
          USBFS_1_LoadInEP(1,(uint8_t *)USB_Keyboard_Data,8);
          USBFS_1_LoadInEP(3,(uint8_t *)USB_Mouse_Data,3);
      

       

      Then I try to send/receive the necessary data periodically:

      if (USBFS_1_bGetEPAckState(1) != 0){
              USBFS_1_LoadInEP(1,(uint8_t *)USB_Keyboard_Data,8);
              USB_LED_Data = USBFS_1_DEVICE0_CONFIGURATION0_INTERFACE0_ALTERNATE0_HID_OUT_BUF[0];
      }
      
      if(USBFS_1_bGetEPAckState(3) != 0){
              USBFS_1_LoadInEP(3,(uint8_t *)USB_Mouse_Data,3);
      }
      

       

      When I do this, the EP3 ACK state always comes back 0, so I never load EP3.  The Keyboard data transfer seems to work fine, keys come into the PC and the keyboard LEDs set appropriately for NUM/SCROLL.  It's the mouse on EP3 that I can't seem to get working.

      I've got to be doing something wrong here.  This could be either me misunderstanding how to send/receive data on multiple EP or an error in my configuration of the USBFS component.  Or possibly both.  Any insight would be appreciated.

       

      Thanks for the help.  If I missed any information I can post more.  I can also provide more information on how my USBFS component is configured if need be, but I would know if I'm just completely on the wrong track before diving too deep into the minutiae of the component config.

       

      Message was edited by: Kyle Trenholm

      -Tweaked the EP ACK check from waiting via a while{} to checking via an if{} to prevent code getting locked in a loop.

        • 2. Re: Configuring and Initializing a Composite USB HID Device on PSoC 5LP?
          anks

          Is the enumeration proper for the device

          • 3. Re: Configuring and Initializing a Composite USB HID Device on PSoC 5LP?
            KTrenholm_1955226

            I can't drop the project here, but I think I found the problem and I have been able to get the composite device working as intended.

             

            It looks like my configuration was fine as far as configuration descriptors and EndPoints was concerned, the issue seemed to have been the Product ID.  I'm not sure how windows treats USB devices, but I had used the PID 0xE013 (as shown in AN58726, the Keyboard with LEDs example) and I had used that for when I was testing only a keyboard, but hadn't yet added the mouse to the project.  I'm thinking Windows was pulling the last driver it had for that PID without checking for any changes? Changing the PID to 0xE015 immediately connected both the mouse and keyboard and after some fiddling I have both devices coming through a single USB line with no issues.  I do still have a couple questions though:

             

            1) What are the rules regarding Product ID?  Am I correct in my assumption that once Windows associates a driver with a given PID it will not search the next time it is connected and simply use the associated driver?  If so, does anyone know a way to clear these "Old" associations out?

             

            2) Regarding EndPoints, AN58726 was the Application Note I used for reference for the Keyboard and Composite Device configuration.  It initializes the connection to the PC as follows:

            /*Start USBFS Operation for Device 0
            with 5V operation*/
            USBFS_1_Start(0, USBFS_1_DWR_VDDD_OPERATION);
            /* Enables OUT EP */
            USBFS_1_EnableOutEP(2);
            /* Waits for USB to enumerate */
            while(!USBFS_1_bGetConfiguration());
            /* Begins USB Traffic. Prime the Pump */
            USBFS_1_LoadInEP(1, Keyboard_Data, 8);
            

            From what I've seen, I don't need to use that Out EP2, and I don't know where it's getting it from (status LED data from the PC to the keyboard appears to come in via the control EP (EP0)?).  In my composite device I'm able to ignore EP2 and put the mouse data on that EndPoint and the keyboard LEDs continue to work properly.  In the example of a composite device, this Out EP is not present.  Does anyone know the purpose of why the example code is written this way?