| @@ -45,6 +45,7 @@ uint16_t AudioInputUSB::incoming_count; | |||
| #define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4))) | |||
| uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR; | |||
| uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR; | |||
| uint32_t usb_audio_sync_feedback DMABUFATTR; | |||
| void AudioInputUSB::begin(void) | |||
| { | |||
| @@ -59,6 +60,7 @@ void AudioInputUSB::begin(void) | |||
| // but also because the PC may stop transmitting data, which | |||
| // means we no longer get receive callbacks from usb_dev. | |||
| update_responsibility = false; | |||
| usb_audio_sync_feedback = 722824; | |||
| } | |||
| static void copy_to_buffers(const uint32_t *src, int16_t *left, int16_t *right, unsigned int len) | |||
| @@ -81,8 +83,6 @@ void usb_audio_receive_callback(unsigned int len) | |||
| audio_block_t *left, *right; | |||
| const uint32_t *data; | |||
| //return; | |||
| len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right | |||
| data = (const uint32_t *)usb_audio_receive_buffer; | |||
| @@ -114,7 +114,7 @@ void usb_audio_receive_callback(unsigned int len) | |||
| copy_to_buffers(data, left->data + count, right->data + count, avail); | |||
| data += avail; | |||
| len -= avail; | |||
| if (AudioInputUSB::ready_left) | |||
| if (AudioInputUSB::ready_left) // buffer overrun, PC sending too fast | |||
| AudioStream::release(AudioInputUSB::ready_left); | |||
| AudioInputUSB::ready_left = left; | |||
| if (AudioInputUSB::ready_right) | |||
| @@ -154,12 +154,13 @@ void AudioInputUSB::update(void) | |||
| right = ready_right; | |||
| ready_right = NULL; | |||
| // TODO: use incoming_count for USB isochronous feedback | |||
| uint16_t c = incoming_count; | |||
| __enable_irq(); | |||
| //if (left && right) { | |||
| //serial_print("$"); | |||
| //} else { | |||
| //serial_print("#"); | |||
| //} | |||
| //serial_phex(c); | |||
| //serial_print("."); | |||
| if (!left || !right) { | |||
| //serial_print("#"); // buffer underrun - PC sending too slow | |||
| } | |||
| if (left) { | |||
| transmit(left, 0); | |||
| release(left); | |||
| @@ -11,6 +11,7 @@ extern uint16_t usb_audio_receive_buffer[]; | |||
| extern uint16_t usb_audio_transmit_buffer[]; | |||
| extern void usb_audio_receive_callback(unsigned int len); | |||
| extern unsigned int usb_audio_transmit_callback(void); | |||
| extern uint32_t usb_audio_sync_feedback; | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -409,7 +409,7 @@ static uint8_t flightsim_report_desc[] = { | |||
| #define AUDIO_INTERFACE_DESC_POS KEYMEDIA_INTERFACE_DESC_POS+KEYMEDIA_INTERFACE_DESC_SIZE | |||
| #ifdef AUDIO_INTERFACE | |||
| #define AUDIO_INTERFACE_DESC_SIZE 9+10+12+9+12+9 + 9+9+7+11+9+7 + 9+9+7+11+9+7 | |||
| #define AUDIO_INTERFACE_DESC_SIZE 9+10+12+9+12+9 + 9+9+7+11+9+7 + 9+9+7+11+9+7+9 | |||
| #else | |||
| #define AUDIO_INTERFACE_DESC_SIZE 0 | |||
| #endif | |||
| @@ -966,7 +966,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
| 1, // bSamFreqType = 1 frequency | |||
| LSB(44100), MSB(44100), 0, // tSamFreq | |||
| // Standard AS Isochronous Audio Data Endpoint Descriptor | |||
| // SB DCD for Audio Devices 1.0, Section 4.6.1.1, Table 4-20, page 61-62 | |||
| // USB DCD for Audio Devices 1.0, Section 4.6.1.1, Table 4-20, page 61-62 | |||
| 9, // bLength | |||
| 5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR | |||
| AUDIO_TX_ENDPOINT | 0x80, // bEndpointAddress | |||
| @@ -1000,7 +1000,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
| 4, // bDescriptorType = INTERFACE | |||
| AUDIO_INTERFACE+2, // bInterfaceNumber | |||
| 1, // bAlternateSetting | |||
| 1, // bNumEndpoints | |||
| 2, // bNumEndpoints | |||
| 1, // bInterfaceClass, 1 = AUDIO | |||
| 2, // bInterfaceSubclass, 2 = AUDIO_STREAMING | |||
| 0, // bInterfaceProtocol | |||
| @@ -1025,7 +1025,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
| 1, // bSamFreqType = 1 frequency | |||
| LSB(44100), MSB(44100), 0, // tSamFreq | |||
| // Standard AS Isochronous Audio Data Endpoint Descriptor | |||
| // SB DCD for Audio Devices 1.0, Section 4.6.1.1, Table 4-20, page 61-62 | |||
| // USB DCD for Audio Devices 1.0, Section 4.6.1.1, Table 4-20, page 61-62 | |||
| 9, // bLength | |||
| 5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR | |||
| AUDIO_RX_ENDPOINT, // bEndpointAddress | |||
| @@ -1033,7 +1033,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
| LSB(AUDIO_RX_SIZE), MSB(AUDIO_RX_SIZE), // wMaxPacketSize | |||
| 1, // bInterval, 1 = every frame | |||
| 0, // bRefresh | |||
| 0, // bSynchAddress | |||
| AUDIO_SYNC_ENDPOINT | 0x80, // bSynchAddress | |||
| // Class-Specific AS Isochronous Audio Data Endpoint Descriptor | |||
| // USB DCD for Audio Devices 1.0, Section 4.6.1.2, Table 4-21, page 62-63 | |||
| 7, // bLength | |||
| @@ -1042,6 +1042,16 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
| 0x01, // bmAttributes = Sampling Frequency | |||
| 1, // bLockDelayUnits, 1 = ms | |||
| 0x30, 0x00, // wLockDelay | |||
| // Standard AS Isochronous Audio Synch Endpoint Descriptor | |||
| // USB DCD for Audio Devices 1.0, Section 4.6.2.1, Table 4-22, page 63-64 | |||
| 9, // bLength | |||
| 5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR | |||
| AUDIO_SYNC_ENDPOINT | 0x80, // bEndpointAddress | |||
| 0x01, // bmAttributes = isochronous | |||
| 3, 0, // wMaxPacketSize, 3 bytes | |||
| 1, // bInterval, 1 = every frame | |||
| 1, // bRefresh, 1=2ms, 2=8ms | |||
| 0, // bSynchAddress | |||
| #endif | |||
| }; | |||
| @@ -350,7 +350,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define PRODUCT_NAME {'T','e','e','n','s','y',' ','A','u','d','i','o'} | |||
| #define PRODUCT_NAME_LEN 12 | |||
| #define EP0_SIZE 64 | |||
| #define NUM_ENDPOINTS 4 | |||
| #define NUM_ENDPOINTS 5 | |||
| #define NUM_USB_BUFFERS 16 | |||
| #define NUM_INTERFACE 4 | |||
| #define SEREMU_INTERFACE 3 // Serial emulation | |||
| @@ -365,10 +365,12 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define AUDIO_TX_SIZE 180 | |||
| #define AUDIO_RX_ENDPOINT 4 | |||
| #define AUDIO_RX_SIZE 180 | |||
| #define AUDIO_SYNC_ENDPOINT 5 | |||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||
| #define ENDPOINT3_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS | |||
| #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS | |||
| #define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS | |||
| #endif | |||
| @@ -253,6 +253,12 @@ static void usb_setup(void) | |||
| } | |||
| table[index(i, TX, EVEN)].desc = 0; | |||
| table[index(i, TX, ODD)].desc = 0; | |||
| #ifdef AUDIO_INTERFACE | |||
| if (i == AUDIO_SYNC_ENDPOINT) { | |||
| table[index(i, TX, EVEN)].addr = &usb_audio_sync_feedback; | |||
| table[index(i, TX, EVEN)].desc = (3<<16) | BDT_OWN; | |||
| } | |||
| #endif | |||
| } | |||
| break; | |||
| case 0x0880: // GET_CONFIGURATION | |||
| @@ -878,6 +884,11 @@ void usb_isr(void) | |||
| usb_audio_receive_callback(b->desc >> 16); | |||
| b->addr = usb_audio_receive_buffer; | |||
| b->desc = (AUDIO_RX_SIZE << 16) | BDT_OWN; | |||
| } else if ((endpoint == AUDIO_SYNC_ENDPOINT-1) && (stat & 0x08)) { | |||
| b = (bdt_t *)((uint32_t)b ^ 8); | |||
| b->addr = &usb_audio_sync_feedback; | |||
| b->desc = (3 << 16) | BDT_OWN; | |||
| tx_state[endpoint] ^= 1; | |||
| } else | |||
| #endif | |||
| if (stat & 0x08) { // transmit | |||
| @@ -101,6 +101,7 @@ extern void usb_flightsim_flush_callback(void); | |||
| #ifdef AUDIO_INTERFACE | |||
| extern uint16_t usb_audio_receive_buffer[]; | |||
| extern uint16_t usb_audio_transmit_buffer[]; | |||
| extern uint32_t usb_audio_sync_feedback; | |||
| extern void usb_audio_receive_callback(unsigned int len); | |||
| extern unsigned int usb_audio_transmit_callback(void); | |||
| #endif | |||