Hello,
What could be causing failed packets
Connection Status Device connected Current Configuration 1 Speed Full Device Address 1 Number Of Open Pipes 0 Device Descriptor NXP LPC17xx Speaker Offset Field Size Value Description 0 bLength 1 12h 1 bDescriptorType 1 01h Device 2 bcdUSB 2 0200h USB Spec 2.0 4 bDeviceClass 1 00h Class info in Ifc Descriptors 5 bDeviceSubClass 1 00h 6 bDeviceProtocol 1 00h 7 bMaxPacketSize0 1 40h 64 bytes 8 idVendor 2 1FC7h 10 idProduct 2 4005h 12 bcdDevice 2 0100h 1.00 14 iManufacturer 1 01h "NXP Semicond " 15 iProduct 1 02h "NXP LPC17xx Speaker " 16 iSerialNumber 1 03h "DEMO00000000" 17 bNumConfigurations 1 01h Configuration Descriptor 1 Bus Powered, 100 mA Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 02h Configuration 2 wTotalLength 2 0076h 4 bNumInterfaces 1 02h 5 bConfigurationValue 1 01h 6 iConfiguration 1 00h 7 bmAttributes 1 80h Bus Powered 4..0: Reserved ...00000 5: Remote Wakeup ..0..... No 6: Self Powered .0...... No, Bus Powered 7: Reserved (set to one) (bus-powered for 1.0) 1....... 8 bMaxPower 1 32h 100 mA Interface Descriptor 0/0 Audio, 0 Endpoints Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 04h Interface 2 bInterfaceNumber 1 00h 3 bAlternateSetting 1 00h 4 bNumEndpoints 1 00h 5 bInterfaceClass 1 01h Audio 6 bInterfaceSubClass 1 01h Audio Control 7 bInterfaceProtocol 1 00h 8 iInterface 1 00h Audio Control Interface Header Descriptor Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 24h Audio Control Interface Header 2 7 01 00 01 27 00 01 01 Audio Control Input Terminal Descriptor Offset Field Size Value Description 0 bLength 1 0Ch 1 bDescriptorType 1 24h Audio Control Input Terminal 2 10 02 01 01 01 00 01 00 00 00 00 Audio Control Feature Unit Descriptor Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 24h Audio Control Feature Unit 2 7 06 02 01 01 03 00 00 Audio Control Output Terminal Descriptor Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 24h Audio Control Output Terminal 2 7 03 03 01 03 00 02 00 Interface Descriptor 1/0 Audio, 0 Endpoints Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 04h Interface 2 bInterfaceNumber 1 01h 3 bAlternateSetting 1 00h 4 bNumEndpoints 1 00h 5 bInterfaceClass 1 01h Audio 6 bInterfaceSubClass 1 02h Audio Streaming 7 bInterfaceProtocol 1 00h 8 iInterface 1 00h Interface Descriptor 1/1 Audio, 2 Endpoints Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 04h Interface 2 bInterfaceNumber 1 01h 3 bAlternateSetting 1 01h 4 bNumEndpoints 1 02h 5 bInterfaceClass 1 01h Audio 6 bInterfaceSubClass 1 02h Audio Streaming 7 bInterfaceProtocol 1 00h 8 iInterface 1 00h Audio Streaming Interface Descriptor Offset Field Size Value Description 0 bLength 1 07h 1 bDescriptorType 1 24h Audio Streaming Interface 2 5 01 01 01 01 00 Audio Streaming Format Type Descriptor Offset Field Size Value Description 0 bLength 1 0Bh 1 bDescriptorType 1 24h Audio Streaming Format Type 2 9 02 01 01 02 10 01 40 1F 00 Endpoint Descriptor 03 3 Out, Isochronous, 1 ms Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 05h Endpoint 2 bEndpointAddress 1 03h 3 Out 3 bmAttributes 1 05h Isochronous, Asynchronous, Data 1..0: Transfer Type ......01 Isochronous 3..2: Sync Type ....01.. Asynchronous 5..4: Usage Type ..00.... Data 7..6: Reserved 00...... 4 wMaxPacketSize 2 0012h 18 bytes 6 bInterval 1 01h 1 ms 7 bRefresh 1 00h 8 bSynchAddress 1 83h Audio Streaming Isochronous Audio Data Endpoint Descriptor Offset Field Size Value Description 0 bLength 1 07h 1 bDescriptorType 1 25h Audio Streaming Isochronous Audio Data Endpoint 2 5 01 00 02 00 00 Endpoint Descriptor 83 3 In, Isochronous, 1 ms Offset Field Size Value Description 0 bLength 1 09h 1 bDescriptorType 1 05h Endpoint 2 bEndpointAddress 1 83h 3 In 3 bmAttributes 1 01h Isochronous, No Sync, Data 1..0: Transfer Type ......01 Isochronous 3..2: Sync Type ....00.. No Sync 5..4: Usage Type ..00.... Data 7..6: Reserved 00...... 4 wMaxPacketSize 2 0003h 3 bytes 6 bInterval 1 01h 1 ms 7 bRefresh 1 01h 8 bSynchAddress 1 00h
http://pastebin.com/gbdKGnwQ
URB 0006-0003 4:11:41.526 6.746 ms 71 us Sync Reset Pipe and Clear Stall 01:01:83 83DEC6F0h USBPDO-5 usbhub 84E65E00h Success (Success) URB 0007-0002 4:11:41.526 6.749 ms 88 us Sync Reset Pipe and Clear Stall 01:01:83 83DC8C80h 0000007a usbccgp 84E65E00h Success (Success) URB 0008 4:11:41.526 6.758 ms Isoch Transfer 3 bytes buffer in 01:01:83 83DC8C80h 0000007a usbccgp 84FD5790h URB 0009 4:11:41.526 6.763 ms Isoch Transfer 3 bytes buffer in 01:01:83 83DEC6F0h USBPDO-5 usbhub 84FD5790h URB 0010-0009 4:11:41.526 6.831 ms 69 us Isoch Transfer in 01:01:83 83DEC6F0h USBPDO-5 usbhub 84FD5790h Unsuccessful (Internal HC Error) URB 0011-0008 4:11:41.526 6.834 ms 77 us Isoch Transfer in 01:01:83 83DC8C80h 0000007a usbccgp 84FD5790h Unsuccessful (Internal HC Error) URB 0012 4:11:41.526 6.847 ms Sync Reset Pipe and Clear Stall 01:01:83 83DC8C80h 0000007a usbccgp 83DD4008h URB 0013 4:11:41.526 6.853 ms Sync Reset Pipe and Clear Stall 01:01:83 83DEC6F0h USBPDO-5 usbhub 83DD4008h URB 0014-0013 4:11:41.526 6.889 ms 36 us Sync Reset Pipe and Clear Stall 01:01:83 83DEC6F0h USBPDO-5 usbhub 83DD4008h Success (Success) URB 0015-0012 4:11:41.526 6.892 ms 45 us Sync Reset Pipe and Clear Stall 01:01:83 83DC8C80h 0000007a usbccgp 83DD4008h Success (Success)
OK, I found a bug of the original Keil example.
BUG: USB_SOF_Event() is repeatedly called in the interval of around 3us It should be called in 1ms interval.
Solution: Clear SOF (FRAME) interrupt flag in ISR, as follows
MCB1700 Sample Code Bundle for LPC17xx Peripherals using Keil's MDK-ARM V2.00 (Jan 10, 2011) ics.nxp.com/.../mcb1700.code.bundle.lpc17xx.keil.zip keil_examples\USBAudio\usbhw.c void USB_IRQHandler (void) { ... ... #if USB_SOF_EVENT /* Start of Frame Interrupt */ if (disr & FRAME_INT) { LPC_USB->DevIntClr = FRAME_INT; // <---- bug fix USB_SOF_Event(); } #endif
Tsuneo
Nope did nothing, apart from hang the pc after a couple of seconds of audio.
What do these definitions do anyway where is the documentation. the same errors are still happing
usbreg.h
/* Device Interrupt Bit Definitions */ #define FRAME_INT 0x00000001 #define EP_FAST_INT 0x00000002 #define EP_SLOW_INT 0x00000004 #define DEV_STAT_INT 0x00000008 #define CCEMTY_INT 0x00000010 #define CDFULL_INT 0x00000020 #define RxENDPKT_INT 0x00000040 #define TxENDPKT_INT 0x00000080 #define EP_RLZED_INT 0x00000100 #define ERR_INT 0x00000200
Hmm, On my side, the mods work as we expect. Maybe, I didn't touch to all of modifications I made. I posted current modification, here. www.8052.com/.../MCB1700_USBAudio_Async_32k_r0.zip Try this one.
To run above firmware on MCB1700, touch this line.
usbdmain.c int main (void) { ... ... #define OLIMEX_LPC1766STK // <--- comment this line for MCB1700
At this stage, we have examined basic implementation of the feedback endpoint for Async Sink. To brush up above implementation, these issues still remain.
1) Feedback refresh interval In above implementation, Windows read out the feedback EP every 11 or 12 frames, Mac does every 8 frames. But our firmware refreshes it in every frame.
We have to change the refresh interval and bRefresh value on sync EP.
USB Audio Spec, www.usb.org/.../audio10.pdf 3.7.2.2 Isochronous Synch Endpoint The sample clock Fs is always derived from a master clock Fm in the device. P is related to the ratio between those clocks through the following relationship: Fm = Fs * 2^(P-1)
As indicated earlier, a new Ff value is available every 2^(10 – P) frames with P ranging from 1 to 9. The bRefresh field of the synch standard endpoint descriptor is used to report the exponent (10-P) to the Host. It can range from 9 down to 1. (512 ms down to 2 ms)
2) Variable number of samples per frame Async Sink results +/- 1 samples per frame occasionally, when the frequency ratio of the local sampling clock and SOF is apart from an integer number. But original Keil implementation assumes that the sample number per frame would be constant, and this number is power of 2, ie. 1, 2, 4, 8, 16, 32,... This assumption is fine for Adaptive/Synchronous Sink, but it is not approved for Async Sink.
- I touched to the mods for Keils's "mask" method, in this post http://www.keil.com/forum/19557/ Posted 30-Sep-2011 03:43 GMT
- The mods on above post has to be modified more for variable transferred data size on each frame.
3) Pop noise on Windows Windows irregularly put Set_Interface(0) / Set_Interface(1) pair to the device, while it plays sound. This makes pop noise. I'm not sure if this behavior is caused by the value of feedback or not.
Which one of these should I be changing the feild bInterval and bRefresh for. If you could explain how they both work together would help.
/* Endpoint - Standard Descriptor */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_OUT(3), /* bEndpointAddress */ USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */ // <------- WBVAL(66), /* wMaxPacketSize */ // <------- 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x83, /* bSynchAddress */ // <-------
/* Endpoint - Standard Descriptor - for feedback */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(3), /* bEndpointAddress */ USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */ WBVAL(3), /* wMaxPacketSize */ 0x01, /* bInterval */ 0x01, /* bRefresh */ 0x00, /* bSynchAddress */
If I set them like this
/* Endpoint - Standard Descriptor */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_OUT(3), /* bEndpointAddress */ USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */ // <------- WBVAL(66), /* wMaxPacketSize */ // <------- 0x01, /* bInterval */ <------------------------ Interval for polling endpoint for data transfers expressed in milliseconds 0x01 = 1 packet every frame 0x09, /* bRefresh */ <----------------------------- 512ms until synchronization pipe provides new synchronization feedback data. 0x83, /* bSynchAddress */ // <-------
would that mean I would get 1ms delay for polling data transfers of 1 packet every frame, and then 512ms before the endpoint provides new synchronization feedback data.
what do you feel they should be set at.
What are you suggesting to be changed when you wrote these comments, are you talking about audio.h and desc.c WBVAL(66), and P_S Packet Size
/* Audio Definitions */ #define DATA_FREQ 32000 /* Audio Data Frequency */ #define P_S 32 /* Packet Size */ #if USB_DMA #define P_C 4 /* Packet Count */ #else #define P_C 1 /* Packet Count */ #endif #define B_S (8*P_C*P_S) /* Buffer Size */
>> The mods on above post has to be modified more for variable transferred data size on each frame.
Could you give me details about what I am to do here
I could not get your code to work with MCB1700 after commenting out the line,
usb device is unrecognised
<<<<<<<<<<<<<<<<<<<<<<< Hmm, On my side, the mods work as we expect. Maybe, I didn't touch to all of modifications I made. I posted current modification, here. www.8052.com/.../MCB1700_USBAudio_Async_32k_r0.zip Try this one.
usbdmain.c
int main (void) { ... ... #define OLIMEX_LPC1766STK // <--- comment this line for MCB1700 <<<<<<<<<<<<<<<<<<<<
Do you know why
> Do you know why
I don't know :-) There aren't so many differences between MCB1700 and OLIMEX_LPC1766STK for this example. Just the analog port, to which a pod connects. I put the #define into the source, to cover this difference.
a) Is the original Keil example runs on your MCB1700? b) What is the version of Windows? c) How doesn't it "work"? Is it enumerated? No sound?, etc
Could you answer these comments first please. Much more important to me than getting the code you posted to work thankyou.
/* Endpoint - Standard Descriptor */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_OUT(3), /* bEndpointAddress */ USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */ // <------- WBVAL(66), /* wMaxPacketSize */ // <------- 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x83, /* bSynchAddress */ // <------- /* Endpoint - Standard Descriptor - for feedback */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(3), /* bEndpointAddress */ USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */ WBVAL(3), /* wMaxPacketSize */ 0x01, /* bInterval */ 0x01, /* bRefresh */ 0x00, /* bSynchAddress */
1) Feedback refresh interval > Which one of these should I be changing the feild bInterval and bRefresh for.
Both of bInterval fields of the OUT and IN endpoints are set to 1 (ms) I mean the bRefresh field of the feedback IN EP.
Host (Windows and Mac) polls the feedback IN endpoint in the interval specified by the bRefresh value, not in 1ms interval. USB Audio spec tells the shortest interval is 2 ms (bRefresh = 1) But there seems lower limit by OS audio driver implementation, MacOSX: 8 ms (bRefresh = 3), and Windows: 11 or 12 ms
In above implementation, the firmware calculates the feedback value on every SOF interrupt. We have to change this behavior. When bRefresh = 3, the firmware calculate feedback value in every 8 ms.
#define FEEDBACK_REFRESH_EXPONENT 3 // bRefresh value for the feedback IN EP (1..9) #define FEEDBACK_REFRESH_INTERVAL (1 << FEEDBACK_REFRESH_EXPONENT) uint8_t feedback_refresh_timer = FEEDBACK_REFRESH_INTERVAL; uint32_t last_timer_count; extern uint32_t sampling_interval; #if USB_SOF_EVENT void USB_SOF_Event (void) { uint32_t current_timer_count; uint32_t feedback_value; // feedback current_timer_count = LPC_TIM1->TC; // capture current SOF timing on the Timer1 if ( --feedback_refresh_timer == 0 ) { if ( USB_AltSetting[1] == 1 ) { // When interface 1 / alt 1 is enabled, // calculate master/SOF frequency ratio in 10.10 (10.14) format feedback_value = ((current_timer_count - last_timer_count) << 14) / FEEDBACK_REFRESH_INTERVAL / sampling_interval; // and send it to the feedback IN EP USB_WriteEP( 0x83, (uint8_t*)&feedback_value, 3 ); } last_timer_count = current_timer_count; // update the last SOF timing feedback_refresh_timer = FEEDBACK_REFRESH_INTERVAL; }
WBVAL(66) (wMaxPacketSize of isoc OUT EP)
The original example sets this value to WBVAL(64), ie. 32 samples for 32kHz monaural 16bits. But MacOSX doesn't put any feedback IN transaction for this value. To receive feedback IN transactions, at least WBVAL(66) (32 + 1 samples) is required.
2) Variable number of samples per frame
This modification is required not just for Async Sink, but also for support of fractional sampling rate, such as 44.1kHz
For DMA implementation of the isoc OUT EP, USB_EndPoint3() is called when packet counts (P_C) number of packets are received. Packet Info Buffer (InfoBuf array) holds received size of each packets (LSB 2 bytes) (refer to "11.15.6 Isochronous endpoint operation" of the LPC17xx manual)
For slave implementation of the isoc OUT EP, USB_ReadEP() in USB_SOF_Event() returns received packet size.
In these callbacks (DMA:USB_EndPoint3(), slave:USB_SOF_Event()) DataIn index increments by actual received packet size, instead of the constant value (P_C*P_S or P_S) of the original. A problem lies in the end of the cyclic buffer. It moves around by the extra (or less) sample(s). When DataIn reaches near the end of the cyclic buffer, this index is held in a current_end_of_buffer variable. And DataIn wraparounds to the top of the buffer.
In the playback routine (TIMER0_IRQHandler()), DataOut wraparounds to the top of the buffer, when it reaches to above current_end_of_buffer.
With mod you posted for usbuser.c, it does not work until I have to change the bRefresh to 0x03 before it will work.
/* Endpoint - Standard Descriptor */ // <-------- additional feedback EP AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(3), /* bEndpointAddress */ USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */ WBVAL(3), /* wMaxPacketSize */ 0x01, /* bInterval */ 0x03, /* bRefresh, */ //<------- every 8ms 0x00, /* bSynchAddress */
in vista for some reason not sure it is bug but it always trys for 2ms even when changes for 8ms, I do get 8ms transfers but for some reason some 2ms transfer do happen and fail:( and I made sure the vid pid were changed as well
USBlyzer Report Capture List Type Seq Time Elapsed Duration Request Request Details Raw Data I/O C:I:E Device Object Device Name Driver Name IRP Status URB 24534-24533 8:29:28.673 17.530532 s 1.383 ms Isoch Transfer in 01:01:83 86F4E6F0h USBPDO-5 usbhub 86E69E28h Unsuccessful (Iso Request Failed) URB 24535-24532 8:29:28.673 17.530538 s 1.395 ms Isoch Transfer in 01:01:83 86F57C80h 0000009e usbccgp 86E69E28h Unsuccessful (Iso Request Failed) URB 32498-32497 8:29:34.364 23.222458 s 1.806 ms Isoch Transfer in 01:01:83 86F4E6F0h USBPDO-5 usbhub 86E69E28h Unsuccessful (Iso Request Failed) URB 32499-32496 8:29:34.364 23.222461 s 1.813 ms Isoch Transfer in 01:01:83 86F57C80h 0000009e usbccgp 86E69E28h Unsuccessful (Iso Request Failed)
Now for win7 even with the bug fix you posted I get these us errors
URB 0047-0046 8:49:33.314 32.829 ms 53 us Isoch Transfer in 01:01:83 85057030h USBPDO-5 usbhub 94D72B00h Unsuccessful (Internal HC Error) URB 0048-0045 8:49:33.314 32.832 ms 59 us Isoch Transfer in 01:01:83 867F9A80h ACPI 94D72B00h Unsuccessful (Internal HC Error) URB 0049-0044 8:49:33.314 32.834 ms 66 us Isoch Transfer in 01:01:83 8699BC68h 00000068 usbccgp 94D72B00h Unsuccessful (Internal HC Error) URB 0191-0190 8:49:33.364 87.787 ms 60 us Isoch Transfer in 01:01:83 85057030h USBPDO-5 usbhub 94D72B00h Unsuccessful (Internal HC Error) URB 0192-0189 8:49:33.364 87.790 ms 68 us Isoch Transfer in 01:01:83 867F9A80h ACPI 94D72B00h Unsuccessful (Internal HC Error) URB 0193-0188 8:49:33.364 87.793 ms 78 us Isoch Transfer in 01:01:83 8699BC68h 00000068 usbccgp 94D72B00h Unsuccessful (Internal HC Error) URB 0329-0328 8:49:33.424 143.782 ms 57 us Isoch Transfer in 01:01:83 85057030h USBPDO-5 usbhub 94D72B00h Unsuccessful (Internal HC Error)
and I am getting some 0 packet transfers as well, but I think this is because of the new mods you made to usbuser.c
URB 0091-0084 9:25:52.942 2.192497 s 7.821 ms Isoch Transfer 0 bytes data in 01:01:83 84306030h USBPDO-5 usbhub 842D0670h Success (Success) URB 0092-0083 9:25:52.942 2.192501 s 7.831 ms Isoch Transfer 0 bytes data in 01:01:83 84396020h ACPI 842D0670h Success (Success) URB 0093-0082 9:25:52.942 2.192504 s 7.839 ms Isoch Transfer 0 bytes data in 01:01:83 82124990h 00000071 usbccgp 842D0670h Success (Succes
I made the changes for keils's mask method
- I touched to the mods for Keils's "mask" method, in this post http://www.keil.com/forum/19557/
you wrote
does the audio.h need to be modded
/* Audio Definitions */ #define DATA_FREQ 32000 /* Audio Data Frequency */ #define P_S 32 /* Packet Size */ <-------------32 + 1 samples #if USB_DMA #define P_C 4 /* Packet Count */ #else #define P_C 1 /* Packet Count */ #endif #define B_S (8*P_C*P_S) /* Buffer Size */
its a bug with
sync Reset Pipe and Clear Stall, do you know how to fix
After searching the internet, the best I have come with is that, it could have something to do with usb.h and adcuser.c
in windows 7 every 50 to 80 us SYNC_RESET_PIPE_AND_CLEAR_STALL is being issued and failing causing lost packets and out of sync audio packets
The _URB_PIPE_REQUEST structure is used by USB client drivers to clear a stall condition on an endpoint. Syntax struct _URB_PIPE_REQUEST { struct URB_HEADER Hdr; USBD_PIPE_HANDLE PipeHandle; ULONG Reserved; }; Members Hdr Pointer to the _URB_HEADER structure that specifies the URB header information. Hdr.Function must be one of the following: URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL URB_FUNCTION_SYNC_RESET_PIPE URB_FUNCTION_SYNC_CLEAR_STALL URB_FUNCTION_ABORT_PIPE URB_FUNCTION_CLOSE_STATIC_STREAMS The Hdr.Length member must be sizeof(_URB_PIPE_REQUEST). PipeHandle Specifies an opaque handle to the bulk or interrupt pipe. The host controller driver returns this handle when the client driver selects the device configuration with a URB of type URB_FUNCTION_SELECT_CONFIGURATION or when the client driver changes the settings for an interface with a URB of type URB_FUNCTION_SELECT_INTERFACE. Reserved Reserved. Do not use. Remarks The reserved members of this structure must be treated as opaque and are reserved for system use. Requirements Header Usb.h (include Usb.h)
/*---------------------------------------------------------------------------- * U S B - K e r n e l *---------------------------------------------------------------------------- * Name: usb.h * Purpose: USB Definitions * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC family microcontroller devices only. Nothing * else gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #ifndef __USB_H__ #define __USB_H__ typedef __packed union { uint16_t W; __packed struct { uint8_t L; uint8_t H; } WB; } WORD_BYTE; /* bmRequestType.Dir */ #define REQUEST_HOST_TO_DEVICE 0 #define REQUEST_DEVICE_TO_HOST 1 /* bmRequestType.Type */ #define REQUEST_STANDARD 0 #define REQUEST_CLASS 1 #define REQUEST_VENDOR 2 #define REQUEST_RESERVED 3 /* bmRequestType.Recipient */ #define REQUEST_TO_DEVICE 0 #define REQUEST_TO_INTERFACE 1 #define REQUEST_TO_ENDPOINT 2 #define REQUEST_TO_OTHER 3 /* bmRequestType Definition */ typedef __packed union _REQUEST_TYPE { __packed struct _BM { uint8_t Recipient : 5; uint8_t Type : 2; uint8_t Dir : 1; } BM; uint8_t B; } REQUEST_TYPE; /* USB Standard Request Codes */ #define USB_REQUEST_GET_STATUS 0 #define USB_REQUEST_CLEAR_FEATURE 1 #define USB_REQUEST_SET_FEATURE 3 #define USB_REQUEST_SET_ADDRESS 5 #define USB_REQUEST_GET_DESCRIPTOR 6 #define USB_REQUEST_SET_DESCRIPTOR 7 #define USB_REQUEST_GET_CONFIGURATION 8 #define USB_REQUEST_SET_CONFIGURATION 9 #define USB_REQUEST_GET_INTERFACE 10 #define USB_REQUEST_SET_INTERFACE 11 #define USB_REQUEST_SYNC_FRAME 12 /* USB GET_STATUS Bit Values */ #define USB_GETSTATUS_SELF_POWERED 0x01 #define USB_GETSTATUS_REMOTE_WAKEUP 0x02 #define USB_GETSTATUS_ENDPOINT_STALL 0x01 /* USB Standard Feature selectors */ #define USB_FEATURE_ENDPOINT_STALL 0 #define USB_FEATURE_REMOTE_WAKEUP 1 /* USB Default Control Pipe Setup Packet */ typedef __packed struct _USB_SETUP_PACKET { REQUEST_TYPE bmRequestType; uint8_t bRequest; WORD_BYTE wValue; WORD_BYTE wIndex; uint16_t wLength; } USB_SETUP_PACKET; /* USB Descriptor Types */ #define USB_DEVICE_DESCRIPTOR_TYPE 1 #define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 #define USB_STRING_DESCRIPTOR_TYPE 3 #define USB_INTERFACE_DESCRIPTOR_TYPE 4 #define USB_ENDPOINT_DESCRIPTOR_TYPE 5 #define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 #define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 #define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 #define USB_OTG_DESCRIPTOR_TYPE 9 #define USB_DEBUG_DESCRIPTOR_TYPE 10 #define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 /* USB Device Classes */ #define USB_DEVICE_CLASS_RESERVED 0x00 #define USB_DEVICE_CLASS_AUDIO 0x01 #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 #define USB_DEVICE_CLASS_MONITOR 0x04 #define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 #define USB_DEVICE_CLASS_POWER 0x06 #define USB_DEVICE_CLASS_PRINTER 0x07 #define USB_DEVICE_CLASS_STORAGE 0x08 #define USB_DEVICE_CLASS_HUB 0x09 #define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF #define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF /* bmAttributes in Configuration Descriptor */ #define USB_CONFIG_POWERED_MASK 0x40 #define USB_CONFIG_BUS_POWERED 0x80 #define USB_CONFIG_SELF_POWERED 0xC0 #define USB_CONFIG_REMOTE_WAKEUP 0x20 /* bMaxPower in Configuration Descriptor */ #define USB_CONFIG_POWER_MA(mA) ((mA)/2) /* bEndpointAddress in Endpoint Descriptor */ #define USB_ENDPOINT_DIRECTION_MASK 0x80 #define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) #define USB_ENDPOINT_IN(addr) ((addr) | 0x80) /* bmAttributes in Endpoint Descriptor */ #define USB_ENDPOINT_TYPE_MASK 0x03 #define USB_ENDPOINT_TYPE_CONTROL 0x00 #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 #define USB_ENDPOINT_TYPE_BULK 0x02 #define USB_ENDPOINT_TYPE_INTERRUPT 0x03 #define USB_ENDPOINT_SYNC_MASK 0x0C #define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 #define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 #define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 #define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C #define USB_ENDPOINT_USAGE_MASK 0x30 #define USB_ENDPOINT_USAGE_DATA 0x00 #define USB_ENDPOINT_USAGE_FEEDBACK 0x10 #define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 #define USB_ENDPOINT_USAGE_RESERVED 0x30
/* USB Standard Device Descriptor */ typedef __packed struct _USB_DEVICE_DESCRIPTOR { uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdUSB; uint8_t bDeviceClass; uint8_t bDeviceSubClass; uint8_t bDeviceProtocol; uint8_t bMaxPacketSize0; uint16_t idVendor; uint16_t idProduct; uint16_t bcdDevice; uint8_t iManufacturer; uint8_t iProduct; uint8_t iSerialNumber; uint8_t bNumConfigurations; } USB_DEVICE_DESCRIPTOR; /* USB 2.0 Device Qualifier Descriptor */ typedef __packed struct _USB_DEVICE_QUALIFIER_DESCRIPTOR { uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdUSB; uint8_t bDeviceClass; uint8_t bDeviceSubClass; uint8_t bDeviceProtocol; uint8_t bMaxPacketSize0; uint8_t bNumConfigurations; uint8_t bReserved; } USB_DEVICE_QUALIFIER_DESCRIPTOR; /* USB Standard Configuration Descriptor */ typedef __packed struct _USB_CONFIGURATION_DESCRIPTOR { uint8_t bLength; uint8_t bDescriptorType; uint16_t wTotalLength; uint8_t bNumInterfaces; uint8_t bConfigurationValue; uint8_t iConfiguration; uint8_t bmAttributes; uint8_t bMaxPower; } USB_CONFIGURATION_DESCRIPTOR; /* USB Standard Interface Descriptor */ typedef __packed struct _USB_INTERFACE_DESCRIPTOR { uint8_t bLength; uint8_t bDescriptorType; uint8_t bInterfaceNumber; uint8_t bAlternateSetting; uint8_t bNumEndpoints; uint8_t bInterfaceClass; uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; uint8_t iInterface; } USB_INTERFACE_DESCRIPTOR; /* USB Standard Endpoint Descriptor */ typedef __packed struct _USB_ENDPOINT_DESCRIPTOR { uint8_t bLength; uint8_t bDescriptorType; uint8_t bEndpointAddress; uint8_t bmAttributes; uint16_t wMaxPacketSize; uint8_t bInterval; } USB_ENDPOINT_DESCRIPTOR; /* USB String Descriptor */ typedef __packed struct _USB_STRING_DESCRIPTOR { uint8_t bLength; uint8_t bDescriptorType; uint16_t bString/*[]*/; } USB_STRING_DESCRIPTOR; /* USB Common Descriptor */ typedef __packed struct _USB_COMMON_DESCRIPTOR { uint8_t bLength; uint8_t bDescriptorType; } USB_COMMON_DESCRIPTOR; #endif /* __USB_H__ */
/*---------------------------------------------------------------------------- * U S B - K e r n e l *---------------------------------------------------------------------------- * Name: ADCUSER.C * Purpose: Audio Device Class Custom User Module * Version: V1.10 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC family microcontroller devices only. Nothing * else gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "type.h" #include "usb.h" #include "audio.h" #include "usbcfg.h" #include "usbcore.h" #include "adcuser.h" #include "usbaudio.h" uint16_t VolCur = 0x0100; /* Volume Current Value */ const uint16_t VolMin = 0x0000; /* Volume Minimum Value */ const uint16_t VolMax = 0x0100; /* Volume Maximum Value */ const uint16_t VolRes = 0x0004; /* Volume Resolution */ /* * Audio Device Class Interface Get Request Callback * Called automatically on ADC Interface Get Request * Parameters: None (global SetupPacket and EP0Buf) * Return Value: TRUE - Success, FALSE - Error */ uint32_t ADC_IF_GetRequest (void) { /* Interface = SetupPacket.wIndex.WB.L; EntityID = SetupPacket.wIndex.WB.H; Request = SetupPacket.bRequest; Value = SetupPacket.wValue.W; ... */ if (SetupPacket.wIndex.W == 0x0200) { /* Feature Unit: Interface = 0, ID = 2 */ if (SetupPacket.wValue.WB.L == 0) { /* Master Channel */ switch (SetupPacket.wValue.WB.H) { case AUDIO_MUTE_CONTROL: switch (SetupPacket.bRequest) { case AUDIO_REQUEST_GET_CUR: EP0Buf[0] = Mute; return (TRUE); } break; case AUDIO_VOLUME_CONTROL: switch (SetupPacket.bRequest) { case AUDIO_REQUEST_GET_CUR: *((__packed uint16_t *)EP0Buf) = VolCur; return (TRUE); case AUDIO_REQUEST_GET_MIN: *((__packed uint16_t *)EP0Buf) = VolMin; return (TRUE); case AUDIO_REQUEST_GET_MAX: *((__packed uint16_t *)EP0Buf) = VolMax; return (TRUE); case AUDIO_REQUEST_GET_RES: *((__packed uint16_t *)EP0Buf) = VolRes; return (TRUE); } break; } } } return (FALSE); /* Not Supported */ } /* * Audio Device Class Interface Set Request Callback * Called automatically on ADC Interface Set Request * Parameters: None (global SetupPacket and EP0Buf) * Return Value: TRUE - Success, FALSE - Error */ uint32_t ADC_IF_SetRequest (void) { /* Interface = SetupPacket.wIndex.WB.L; EntityID = SetupPacket.wIndex.WB.H; Request = SetupPacket.bRequest; Value = SetupPacket.wValue.W; ... */ if (SetupPacket.wIndex.W == 0x0200) { /* Feature Unit: Interface = 0, ID = 2 */ if (SetupPacket.wValue.WB.L == 0) { /* Master Channel */ switch (SetupPacket.wValue.WB.H) { case AUDIO_MUTE_CONTROL: switch (SetupPacket.bRequest) { case AUDIO_REQUEST_SET_CUR: Mute = EP0Buf[0]; return (TRUE); } break; case AUDIO_VOLUME_CONTROL: switch (SetupPacket.bRequest) { case AUDIO_REQUEST_SET_CUR: VolCur = *((__packed uint16_t *)EP0Buf); return (TRUE); } break; } } } return (FALSE); /* Not Supported */ } /* * Audio Device Class EndPoint Get Request Callback * Called automatically on ADC EndPoint Get Request * Parameters: None (global SetupPacket and EP0Buf) * Return Value: TRUE - Success, FALSE - Error */ uint32_t ADC_EP_GetRequest (void) { /* EndPoint = SetupPacket.wIndex.WB.L; Request = SetupPacket.bRequest; Value = SetupPacket.wValue.W; ... */ return (FALSE); /* Not Supported */ } /* * Audio Device Class EndPoint Set Request Callback * Called automatically on ADC EndPoint Set Request * Parameters: None (global SetupPacket and EP0Buf) * Return Value: TRUE - Success, FALSE - Error */ uint32_t ADC_EP_SetRequest (void) { /* EndPoint = SetupPacket.wIndex.WB.L; Request = SetupPacket.bRequest; Value = SetupPacket.wValue.W; ... */ return (FALSE); /* Not Supported */ }
in windows 7 every 50 to 80 us SYNC_RESET_PIPE_AND_CLEAR_STALL is being issued and failing causing lost packets and out of sequence audio packets
case URB_FUNCTION_SYNC_CLEAR_STALL and case case URB_FUNCTION_SYNC_RESET_PIPE. These allow client drivers to clear the ENDPOINT_HALT feature on the device, or reset the pipe on the host side, respectively, without affecting the data toggle on the host side. If the device does not reset the data toggle when it should, then the client driver can compensate for this defect by not resetting the host-side data toggle.
If the data toggle is reset on the host side but not on the device side, packets will get out of sequence, and the device might drop packets
???????