@@ -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 |