Adding Virtual Serial Port to Audio USB reference app Topic is solved

Technical discussions related to any XMOS development kit or reference design. Eg XK-1A, sliceKIT, etc.
Post Reply
lorenzochiesi
Active Member
Posts: 34
Joined: Mon Sep 05, 2016 4:20 pm

Adding Virtual Serial Port to Audio USB reference app

Post by lorenzochiesi »

Hi All,

I'm trying to add a Virtual Serial Port in the USB UAC2 audio reference application running on x200 MC Audio v2.

What I need is crate a communication channel between the host PC and some hardware I'll want to integrate on a board I'm developing, based on the audio reference design.

A a virtual serial port based on the code documented in appnote AN00124 is a perfect solution, the only problem is to integrate it in the USB audio firmware.

At the moment I disabled MIDI and HID interface to reduce thread number in XUD tile and integrate all the code of the appnote into the reference design on the XUD tile.

-I added the necessaries interfaces and endpoints to the project structures and integrate audio device descriptors with descriptors of the CDC interface similarly as HID interface does

-I added a thread in the usb_audio_core() function, where XUD manager run, to manage the CDC Endpoints

-I integrated in the Endpoint0() handler function the code to manage request related to CDC similarly to what is done for DFU:

Code: Select all

[...]
                case USB_BMREQ_H2D_CLASS_INT:
                case USB_BMREQ_D2H_CLASS_INT:
                    {
                        unsigned interfaceNum = sp.wIndex & 0xff;
					    //unsigned request = (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5);

//LC: Added management for CDC interface
#ifdef CDC
                        /* Inspect for CDC Communications Class interface num */
                        unsigned CDC_IF = INTERFACE_NUMBER_CDC;
                        if(interfaceNum == CDC_IF)
                        {
                            /* Returns  XUD_RES_OKAY if handled,
                             *          XUD_RES_ERR if not handled,
                             *          XUD_RES_RST for bus reset */
                            result = ControlInterfaceClassRequests(ep0_out, ep0_in, sp);
                        }
#endif

                        /* TODO Check on return value retval =  */
#ifdef DFU
                        unsigned DFU_IF = INTERFACE_NUMBER_DFU;

                        /* DFU interface number changes based on which mode we are currently running in */
                        if (DFU_mode_active)
                        {
                            DFU_IF = 0;
                        }

                        if (interfaceNum == DFU_IF)
                        {
                            int reset = 0;

                            /* If running in application mode stop audio */
                            /* Don't interupt audio for save and restore cmds */
                            if ((DFU_IF == INTERFACE_NUMBER_DFU) && (sp.bRequest != XMOS_DFU_SAVESTATE) &&
                                (sp.bRequest != XMOS_DFU_RESTORESTATE))
                            {
                                // Stop audio
                                outuint(c_audioControl, SET_SAMPLE_FREQ);
                                outuint(c_audioControl, AUDIO_STOP_FOR_DFU);
                                // Handshake
							    chkct(c_audioControl, XS1_CT_END);
                            }

                            /* This will return 1 if reset requested */
                            result = DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface, &reset);

                            if(reset)
                            {
                                DFUDelay(50000000);
                                device_reboot(c_audioControl);
                            }
                        }
#endif
[...]
- All build smootly!
- Host correctly enumerate the device
(lsusb show that the descriptor is as expected)
-the audio interface still work perfectly
-dmesg show only the following error:

Code: Select all

cdc_acm: probe of 1-1.3:1.4 failed with error -22
-the visrtual serial port will not be created on both linux/window

Running some debug on the code I see that the function ControlInterfaceClassRequests() that I added in the endpoint0 handler is never executed!!

This because in case of request USB_BMREQ_H2D_CLASS_INT or USB_BMREQ_D2H_CLASS_INT the interfaceNum never match the INTERFACE_NUMBER_CDC that is 4.
(0/1/2 are related to audio, 3 is DFU, 4/5 are CDC)

Is it normal? when this function should be called?
Any Idea of where problem can be or how to proceed with debug?

If someone is interested I can share all the code, I think can be useful for many

Many thanks,
Lorenzo


View Solution
User avatar
Thomas
Experienced Member
Posts: 66
Joined: Fri Feb 05, 2010 12:34 pm

Post by Thomas »

Hi Lorenzo
It looks like you have done a lot of things right already.
I did that integration myself in the past and came to the same issue:
ControlInterfaceClassRequests() that I added in the endpoint0 handler is never executed

The problem was that the bSubordinateInterface0 and bDataInterface needed updating for the new index 5 ( IF 5 (alt 0) CDC Data, 0, No class specific protocol required).

Here are the correct settings for descriptors.h

/* Union Functional descriptor */
0x05, /* 0 bLength */
USB_DESCTYPE_CS_INTERFACE,/* 1 bDescriptortype, CS_INTERFACE */
0x06, /* 2 bDescriptorsubtype, UNION */
0x00, /* 3 bControlInterface - Interface 0 */
0x05, /* 4 bSubordinateInterface0 - Interface 1 */

/* Call Management Functional descriptor */
0x05, /* 0 bLength */
USB_DESCTYPE_CS_INTERFACE,/* 1 bDescriptortype, CS_INTERFACE */
0x01, /* 2 bDescriptorsubtype, CALL MANAGEMENT */
0x03, /* 3 bmCapabilities, DIY */
0x05, /* 4 bDataInterface */

I hope this helps

Best Regards, Thomas
lorenzochiesi
Active Member
Posts: 34
Joined: Mon Sep 05, 2016 4:20 pm

Post by lorenzochiesi »

You are right Thomas!

Unfortunately I just discovered the bug by myself 2 days ago after a week of struggling :-)!

Now all is correctly working under linux and OSX: the tty port is correctly enumerated and can exchange data alongside the audio device that is still recognized and working with sound system.

Under window initially I can't find the way to get the device enumerate as composite device.
I realize digging in window documentation that number of device configuration should be necessarly 1 to have this happen. (In the code this was set to 2 and a comment say that this is for avoid windows to enumerate as composite device)

Restoring it to 1 (and uninstall audio driver) let window to see an audio device and a CDC device, at that point is possible to install XMOS CDC driver and the CDC COM port will work.
Unfortunately if the USB Audio driver is installed on audio device the CDC COM port disappear (probably the driver is made for hidden other device like HID and DFU)

Do you know some method to make working audio driver alongside CDC driver in window?

Lorenzo
MikePelton
Junior Member
Posts: 4
Joined: Wed Feb 22, 2017 4:03 pm

Post by MikePelton »

Hi Lorenzo - am just facing this exact issue - did you ever get to the bottom of it? Also if you are able to publish any of your code that at least ran under Linux that would save me some of the integration effort for which I'd be hugely grateful! If I get the Windows issue solved I will of course reciprocate. Thanks!
Post Reply