• AVR Freaks

Helpful ReplyProblem with CDC (with IAD) + HID composite device ?

Page: 12 > Showing page 1 of 2
Author
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
2011/02/24 09:08:45 (permalink)
0

Problem with CDC (with IAD) + HID composite device ?

Following upto my earlier posts I'm creating a design with a CDC (using IAD) plus a HID device.
I have compiled a version based upon the http://www.cygnal.org/ubb/Forum9/HTML/001050.html version that at least enumerates to the point that USBlyser or USB View recognize the device as a Communications Device, it doesn't actually work yet, but I'm trying to at least get the reported properties correct.
The problem is USBlyser reports it is expecting two EP's from the HID interface descriptor as it should, but is only seeing one.  I have declared both an IN and OUT EP for the HID interface in the usb_descriptors.c file but the 2nd EP is not appearing ? I have attached the code in the descriptor file. Can anyone see where I've gone wrong ?

#1
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/24 10:21:39 (permalink)
0
Typical, after posting the problem, I spotted the error with the reported endpoints was caused by an incorrect length on the cofiguration descriptor. So now the device shows up now with the correct information in the usb properties page.
But USBlyser does not show it as a composite device, and no device components are shown under that device such as HID-compliant device etc. What might cause this ?
Also in hyperterm, I cannot open that com port. I have created a CDC only version which works fine so probably not the drivers.
#2
newfound
Super Member
  • Total Posts : 1838
  • Reward points : 0
  • Joined: 2003/11/07 12:35:49
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/24 21:36:13 (permalink)
0
You are not the first to post here trying to get this descriptor set working with the PIC. I have a cut'n'paste of someone else's effort still stuck in my source file to compare against.

Like you they also got the WTotalLength wrong in the config descriptor.

From memory I pretty much used the same descriptors in my CDC-HID device. The correct length in the config descriptor by my working version is 0x6b or 107 dec.  Remember also that you may need to change this value in the GET_DESCRIPTOR handler. Not just in the descriptor itself. (Depending on how the descriptor length is handled, there are different ways on different stacks.)

Also, I seem to remember that USBlyser told lies when I used it. It did not seem to understand the IAD or something. I cannot remember what I found but there was something odd with it.

Finally, in the inf file the &MI_0x part of the VID PID string must match how your interfaces are numbered in your descriptors.  If you use Master Tsuneo Chinizei's descriptor (as you are) then use his inf file (&MI_00) and change the VID&PID.

Do not use the microchip inf (MCP2200) or Jan Axelson's HID_CDC inf files because they lay out the interfaces and index them in reverse order. I.E. these use &MI_01 in the inf file.  EDIT: One the other or both are different.



post edited by newfound - 2011/02/24 21:38:31
#3
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/25 06:46:52 (permalink)
0
newfound
From memory I pretty much used the same descriptors in my CDC-HID device. The correct length in the config descriptor by my working version is 0x6b or 107 dec.  Remember also that you may need to change this value in the GET_DESCRIPTOR handler. Not just in the descriptor itself. (Depending on how the descriptor length is handled, there are different ways on different stacks.)


Yes that is what I used.  I seem to not need any changes in the GET_DESCRIPTOR handler.

newfound
Finally, in the inf file the &MI_0x part of the VID PID string must match how your interfaces are numbered in your descriptors.  If you use Master Tsuneo Chinizei's descriptor (as you are) then use his inf file (&MI_00) and change the VID&PID.

Thanks the driver loads up fine now with that inf file, with the correct vid/pids.
Thanks newfound.

I'm nearer it working correctly. USBlyser now reports a composite device correctly, reporting a CDC ACM example device and a USB HID device, but it reports an error, HID device failing to start (The driver shows "This device cannot start. (Code 10)"), and also when using hypertrm to talk to the CDC, the com port fails to open ? Is there anything else obvious I need to do that might explain these problems ?


#4
newfound
Super Member
  • Total Posts : 1838
  • Reward points : 0
  • Joined: 2003/11/07 12:35:49
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/25 08:34:36 (permalink) ☄ Helpful
0

Glad you have progressed. It is very hard to say what else you need to do as I do not lknow what you have done so far.

A code 10 generally means that the device enumerated but the device functions could not be initialized.

Did you add the HID CLASS REPORT descriptor handler?

Did you add the HID CLASS request handlers?
SET_IDLE
GET_IDLE
SET_PROTOCOL
GET_PROTOCOL


Did you add the required CDC CLASS request handlers?
SET_CONTROL_LINE_STATE
GET_LINE_CODING
SET_LINE_CODING
GET_ENCAPSULATED_RESPONSE
SEND_ENCAPSULATED_COMMAND

Not all these CLASS requests may need to be handled to get past the code 10 and there may be one or two I missed but the point is that you have to add class request handlers.

#5
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/25 09:54:53 (permalink)
0
I am using the microchip usb stack plus the usb framework examples of cdc/hid devices to create my code.
I use the files usb_functions_cdc.c and usb_functions_hid.c which contain the class handlers you mentioned.
I did compile a cdc only and a hid only device and these work fine, so I'm screwing up something in the merging of the those functions into the combined device code.
I used usblyser to log the failure of the comm port to connect to connect to the cdc device, and it is because the several get line coding requests fail with a STALL pid (whereas in the cdc only requests they work work fine) Similarly when starting the hid device, the class requests set idle, get report descriptor requests  fail with a STALL pid. So it's probably something simple in the way I've added those class handlers into the combined device ?

#6
newfound
Super Member
  • Total Posts : 1838
  • Reward points : 0
  • Joined: 2003/11/07 12:35:49
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/25 11:12:58 (permalink)
0
Without seeing any code I can only guess...

Are you directing the CLASS requests to the right handlers by looking at the INTERFACE number (wIndex in the setup packet) to see which interface they belong to? If your HID CLASS request is directed to the CDC CLASS handler and it defaults is not a stall returned to the host? And vice-versa?

Seems to be a good guess at what is happening. Look at other microchip examples of a composite device to see how the stack directs the class requests. I have a feeling that it directs them to one then the other and each flag if they handled the request else a stall is returned.

Really, I cannot remember. You will have to look at this. Its 5AM and time for me to sleep. 
 


#7
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/28 07:12:03 (permalink)
0
I too am experiencing exactly the same issue. I have a HID and CDC composite device that appears correctly to USBlyzer and windows as the correct devices, but when I go to write to the CDC device from code it gets an "Unsuccessful (Stall PID)". I know the code that im calling it with is fine as its works with the stand alone CDC firmware. If i try to connect to the device with hyperterm it connects but not write. The HID device part is working fine both IN and OUT.

I have looked over the composite device examples to see if there is some trick with the endpoints but I can't see it. It's getting late here so maybe my mind is not fresh.


post edited by FluxCapacitor - 2011/02/28 07:19:33
#8
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/28 08:41:29 (permalink)
0
I found the problem with mine! It lay in the USB descriptor endpoint addresses. I noticed duplicate addresses in USBlyzer and when I looked at the code I saw that the HID joystick example used _EP_IN and _EP_OUT and the CDC example used _EP01_IN on one of the end points.

I have left the HID endpoints as _EP_IN and _EP_OUT. I changed CDC endpoints to _EP02_IN, _EP03_OUT and _EP03_IN and everything worked.

Also make sure your endpoint allocations are not overlapping in your usb_config.h

Hope this helps you too :)
#9
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/02/28 16:56:40 (permalink)
0
Well I spoke too soon. The info in my last post was an issue but it only solves half the problem. I can get only CDC or HID working at once, but I can control which one works by letting either my Main function allocate the USB memory or the usb_function_cdc.c allocate USB memory. So I think if this was in another code file and all required variable were listed under it, then it might work. Anyone got any suggestions?
#10
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/01 05:08:16 (permalink)
0
I'm still struggling, but making some progress. Both CDC + HID show up in my device list. The CDC can be opened from hypertrm ok and I see the set/get linecoding calls working fine in usblyser. However attempts to type a character from hypertrm causes an OUT transaction with the value of the key shown correctly, but the OUT transaction does not respond, and after a while shown as cancelled. The HID device reports correctly, and is reported as working now. I haven't tested it actually does stuff yet.

So it looks like the control endpoint, and the comm EP for the CDC, and the HID EP work ok, but the data ep for the CDC are not working ?
I've  added the standard calls in USBCBCheckOtherReq to call the HID and CDC handlers USBCheckCDCRequest, USBCheckHIDRequest to handle the class requests.
The single microchip HID or CDC examples work fine, as does the microchip MSD+CDC example.
The order of interfaces/EP's is different in my version which uses Tsuneo Chinizei's descriptors which list the interfaces in a different order ie 0->cdc comm, 1->cdc data, 3->hid and the EP's used are 2 for CDC comm, 3 for CDC data, and 1 for hid data, but I think I've made the correct changes in usb_config.h to match this order.

#11
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/01 06:06:52 (permalink)
0
First of all, do you mind attaching both the description and config USB files to see?

Secondly, where are you defining the USB RAM? The definition of the RAM is the problem spot for me, I can switch either HID or CDC to work depending on where I declare it because both need to allocated variable in that RAM space. But note that in my case no matter what, the devices appear correctly to windows so that part is all ok, its just the comms to the CDC.
post edited by FluxCapacitor - 2011/03/01 06:09:18
#12
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 03:02:45 (permalink)
0
I've attached the descriptors file, but the attachments upload dialog doesn't allow .h files for some reason ? so here it is in the body less the standard boilerplate at the top, and some commented out code.

I'm not sure what you mean about USB memory ?


/********************************************************************
 #ifndef USBCFG_H
#define USBCFG_H

/** DEFINITIONS ****************************************************/
#define USB_EP0_BUFF_SIZE        8    // Valid Options: 8, 16, 32, or 64 bytes.
#define USB_MAX_NUM_INT         1   // For tracking Alternate Setting
#define USB_MAX_EP_NUMBER        3

//Device descriptor - if these two definitions are not defined then
#define USB_USER_DEVICE_DESCRIPTOR &device_dsc
#define USB_USER_DEVICE_DESCRIPTOR_INCLUDE extern ROM USB_DEVICE_DESCRIPTOR device_dsc

//Configuration descriptors - if these two definitions do not exist then
//  a ROM BYTE *ROM variable named exactly USB_CD_Ptr[] must exist.
#define USB_USER_CONFIG_DESCRIPTOR USB_CD_Ptr
#define USB_USER_CONFIG_DESCRIPTOR_INCLUDE extern ROM BYTE *ROM USB_CD_Ptr[]

#define USB_PING_PONG_MODE USB_PING_PONG__FULL_PING_PONG

#define USB_INTERRUPT

/* Parameter definitions are defined in usb_device.h */
#define USB_PULLUP_OPTION USB_PULLUP_ENABLE

#define USB_TRANSCEIVER_OPTION USB_INTERNAL_TRANSCEIVER

#define USB_SPEED_OPTION USB_FULL_SPEED

#define USB_ENABLE_STATUS_STAGE_TIMEOUTS    //Comment this out to disable this feature. 

#define USB_STATUS_STAGE_TIMEOUT     (BYTE)45   //Approximate timeout in milliseconds, except when
                                                //USB_POLLING mode is used, and USBDeviceTasks() is called at < 1kHz
                                                //In this special case, the timeout becomes approximately:

#define USB_SUPPORT_DEVICE

#define USB_NUM_STRING_DESCRIPTORS 3

#define USB_ENABLE_ALL_HANDLERS

/** DEVICE CLASS USAGE *********************************************/
#define USB_USE_HID
#define USB_USE_CDC

/** ENDPOINTS ALLOCATION *******************************************/

/* CDC */
#define CDC_COMM_INTF_ID        0x00
#define CDC_COMM_EP              1
#define CDC_COMM_IN_EP_SIZE      8

#define CDC_DATA_INTF_ID        0x01
#define CDC_DATA_EP             2
#define CDC_DATA_OUT_EP_SIZE    32
#define CDC_DATA_IN_EP_SIZE     32

#define USB_CDC_SET_LINE_CODING_HANDLER mySetLineCodingHandler

#define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1 //Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and Serial_State commands

/* HID */
#define HID_INTF_ID             0x02
#define HID_EP                     3
#define HID_INT_OUT_EP_SIZE     16
#define HID_INT_IN_EP_SIZE      16
#define HID_NUM_OF_DSC          3
#define HID_RPT01_SIZE          29

/** DEFINITIONS ****************************************************/

#endif //USBCFG_H


#13
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 03:14:07 (permalink)
0
there is some RAM allocated to the USB functionality and if the structures that are used for the in and out endpoints are not allocated in it, then the data will not come through.

Here it is from usb_function_cdc.c


/* V A R I A B L E S ********************************************************/
#if defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50)
    #pragma udata usbram2
#elif defined(__18F2455) || defined(__18F2550) || defined(__18F4455) || defined(__18F4550)\
    || defined(__18F2458) || defined(__18F2553) || defined(__18F4458) || defined(__18F4553)
    #pragma udata USB_VARIABLES=0x500
#elif defined(__18F4450) || defined(__18F2450)
    #pragma udata USB_VARIABLES=0x480
#else
    #pragma udata
#endif

volatile FAR CDC_NOTICE cdc_notice;
volatile FAR unsigned char cdc_data_rx[CDC_DATA_OUT_EP_SIZE];
volatile FAR unsigned char cdc_data_tx[CDC_DATA_IN_EP_SIZE];
LINE_CODING line_coding;    // Buffer to store line coding information


But if you define a similar section in your main file, just like in the HID examples, it stuffs up and will not accept the data on the CDC. I started to test this theory by importing usb_function_cdc.c into my project locally. This caused it to throw a compile time error to say I can't define these in two spots, so then I commented out the similar code in my main function. This caused my HID stuff to stop working but the CDC stuff started working fine. I then did the opposite and the HID started to work and the CDC failed again.

Is this making sense?
#14
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 03:23:09 (permalink)
0
Another thing I noticed with your code, which im not sure is an issue, is that in the config file the HID endpoints are addressed as the third endpoint. In your descriptor its numbered the first?

This is how the endpoints are defined in the libraries:

 
#define _EP_IN      0x80
#define _EP_OUT     0x00
#define _EP01_OUT   0x01
#define _EP01_IN    0x81
#define _EP02_OUT   0x02
#define _EP02_IN    0x82
#define _EP03_OUT   0x03
#define _EP03_IN    0x83


This might not matter, maybe the important thing is that the are unique???
post edited by FluxCapacitor - 2011/03/02 03:26:51
#15
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 04:54:35 (permalink)
0
FluxCapacitor
Another thing I noticed with your code, which im not sure is an issue, is that in the config file the HID endpoints are addressed as the third endpoint. In your descriptor its numbered the first?
This might not matter, maybe the important thing is that the are unique???

In the descriptors it is shown as HID_EP which is defined as 3 in the config file.

I think you're onto something with the usb ram, I'm still trying to work it out.
In my case the interfaces enumerate fine, and the drivers for the cdc and hid start fine.
But only the CDC comm channel works, the data channel sends a USB out, but no repsonse is seen, and the hid out endpoint works ok, but the hid in endpoint fails at the pc end.

#16
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 05:29:16 (permalink)
0
tonyb61
I think you're onto something with the usb ram, I'm still trying to work it out.
In my case the interfaces enumerate fine, and the drivers for the cdc and hid start fine.
But only the CDC comm channel works, the data channel sends a USB out, but no repsonse is seen, and the hid out endpoint works ok, but the hid in endpoint fails at the pc end.


You are pretty much describing the same thing as I have. I think the solution is to have a separate file that does the variable allocation for both CDC and HID in the one file. This will eliminate the compile time error and solve the issue. I will try this now. If I succeed I will give you that file.

#17
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 06:13:31 (permalink) ☄ Helpful
0
Ok. Ive solved it. Here is what you need to do. The following code samples have notes in each one that says where you need to replace my structures to your own requirements, but the principal is the same.

1. Make a local copy of usb_function_cdc.c in your project.

2. Change the section of code in usb_function_cdc.c to this:

 
/* V A R I A B L E S ********************************************************/
/*#if defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50)
    #pragma udata usbram2
#elif defined(__18F2455) || defined(__18F2550) || defined(__18F4455) || defined(__18F4550)\
    || defined(__18F2458) || defined(__18F2553) || defined(__18F4458) || defined(__18F4553)
    #pragma udata USB_VARIABLES=0x500
#elif defined(__18F4450) || defined(__18F2450)
    #pragma udata USB_VARIABLES=0x480
#else
    #pragma udata
#endif
*/
extern volatile FAR CDC_NOTICE cdc_notice;
extern volatile FAR unsigned char cdc_data_rx[CDC_DATA_OUT_EP_SIZE];
extern volatile FAR unsigned char cdc_data_tx[CDC_DATA_IN_EP_SIZE];
extern LINE_CODING line_coding;    // Buffer to store line coding information


3. Change your code in Main.c where the HID example set its USB variables to this:

 
/*
#if defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50)
    #pragma udata usbram2
#elif defined(__18F2455) || defined(__18F2550) || defined(__18F4455) || defined(__18F4550)\
    || defined(__18F2458) || defined(__18F2553) || defined(__18F4458) || defined(__18F4553)
    #pragma udata USB_VARIABLES=0x500
#elif defined(__18F4450) || defined(__18F2450)
    #pragma udata USB_VARIABLES=0x480
#else
    #pragma udata
#endif
*/
/*
#if (defined(USER_GET_REPORT_HANDLER) || defined (USER_SET_REPORT_HANDLER))  
        unsigned char hid_report_feature[USB_EP0_BUFF_SIZE];
#endif
*/

//Your input or output variables go here
extern INPUT_CONTROLS FJoystickInput;


4. Create a new c file with the following code:

 
#include "GenericTypeDefs.h"
#include "USB/usb_function_cdc.h"

//Change this to your own structure
typedef union _INPUT_CONTROLS_TYPEDEF
{
    struct
    {
        struct
        {
            BYTE B1:1;
            BYTE B2:1;
            BYTE B3:1;
            BYTE B4:1;
            BYTE B5:1;
            BYTE B6:1;
            BYTE B7:1;
            BYTE B8:1;
            BYTE B9:1;
            BYTE B10:1;
            BYTE B11:1;
            BYTE B12:1;
            BYTE B13:1;
            BYTE B14:1;
            BYTE B15:1;
            BYTE B16:1;
        } Buttons;
    } Members;
    BYTE val[2];
} INPUT_CONTROLS;

#if defined(__18F2455) || defined(__18F2550) || defined(__18F4455) \
    || defined(__18F4550) || defined(__18F2458) || defined(__18F2453) \
    || defined(__18F4558) || defined(__18F4553) || defined(__18F4458)
    #pragma udata USB_VARIABLES=0x500
#elif defined(__18F4450) || defined(__18F2450)
    #pragma udata USB_VARIABLES=0x480
#else
    #pragma udata
#endif


INPUT_CONTROLS FJoystickInput;

volatile FAR CDC_NOTICE cdc_notice;
volatile FAR unsigned char cdc_data_rx[CDC_DATA_OUT_EP_SIZE];
volatile FAR unsigned char cdc_data_tx[CDC_DATA_IN_EP_SIZE];
LINE_CODING line_coding;    // Buffer to store line coding information

post edited by FluxCapacitor - 2011/03/02 06:15:12
#18
tonyb61
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2010/08/26 04:16:23
  • Location: 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 10:34:43 (permalink)
0
Hi fluxcapacitor. Your examples helped greatly, thanks.
I'm not as far along as you. My HID device works fine now, with transfers in both directions working fine.
However my cdc device still has a problem with the data channel. I think this must be something else.
I use hypertrm to connect to the cdc, and I use the code in main.c  from the microchip msd-cdc composite example for handling the rs232 side buffers. This basically implements a loopback so a typed character is sent from hypertrm, via the usbser driver, resulting in an out transfer on the usb bus to my device, but I never get an ack for that out transfer, but the comm channel seems to work ok when "calling" the cdc device which uses the set/get linecoding standard.



#19
FluxCapacitor
New Member
  • Total Posts : 12
  • Reward points : 0
  • Status: offline
Re:Problem with CDC (with IAD) + HID composite device ? 2011/03/02 15:55:21 (permalink)
0
No prob Tony. Glad it helped. I have joined two different bit of code together, the HID Joystick and CDC Serial Emulator examples. The other thing you might want to try is my USB config and descriptor files in case there is some very hard to see bug in your version. If you want those let me know.
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5