Browse Source

Add usb audio asychronous feedback endpoint (fixed data for now)

teensy4-core
PaulStoffregen 8 years ago
parent
commit
fddf08842b
6 changed files with 40 additions and 14 deletions
  1. +9
    -8
      teensy3/usb_audio.cpp
  2. +1
    -0
      teensy3/usb_audio.h
  3. +15
    -5
      teensy3/usb_desc.c
  4. +3
    -1
      teensy3/usb_desc.h
  5. +11
    -0
      teensy3/usb_dev.c
  6. +1
    -0
      teensy3/usb_dev.h

+ 9
- 8
teensy3/usb_audio.cpp View File

#define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4))) #define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4)))
uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR; uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR;
uint16_t usb_audio_transmit_buffer[AUDIO_TX_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) void AudioInputUSB::begin(void)
{ {
// but also because the PC may stop transmitting data, which // but also because the PC may stop transmitting data, which
// means we no longer get receive callbacks from usb_dev. // means we no longer get receive callbacks from usb_dev.
update_responsibility = false; 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) static void copy_to_buffers(const uint32_t *src, int16_t *left, int16_t *right, unsigned int len)
audio_block_t *left, *right; audio_block_t *left, *right;
const uint32_t *data; const uint32_t *data;


//return;

len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right
data = (const uint32_t *)usb_audio_receive_buffer; data = (const uint32_t *)usb_audio_receive_buffer;


copy_to_buffers(data, left->data + count, right->data + count, avail); copy_to_buffers(data, left->data + count, right->data + count, avail);
data += avail; data += avail;
len -= avail; len -= avail;
if (AudioInputUSB::ready_left)
if (AudioInputUSB::ready_left) // buffer overrun, PC sending too fast
AudioStream::release(AudioInputUSB::ready_left); AudioStream::release(AudioInputUSB::ready_left);
AudioInputUSB::ready_left = left; AudioInputUSB::ready_left = left;
if (AudioInputUSB::ready_right) if (AudioInputUSB::ready_right)
right = ready_right; right = ready_right;
ready_right = NULL; ready_right = NULL;
// TODO: use incoming_count for USB isochronous feedback // TODO: use incoming_count for USB isochronous feedback
uint16_t c = incoming_count;
__enable_irq(); __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) { if (left) {
transmit(left, 0); transmit(left, 0);
release(left); release(left);

+ 1
- 0
teensy3/usb_audio.h View File

extern uint16_t usb_audio_transmit_buffer[]; extern uint16_t usb_audio_transmit_buffer[];
extern void usb_audio_receive_callback(unsigned int len); extern void usb_audio_receive_callback(unsigned int len);
extern unsigned int usb_audio_transmit_callback(void); extern unsigned int usb_audio_transmit_callback(void);
extern uint32_t usb_audio_sync_feedback;
#ifdef __cplusplus #ifdef __cplusplus
} }



+ 15
- 5
teensy3/usb_desc.c View File



#define AUDIO_INTERFACE_DESC_POS KEYMEDIA_INTERFACE_DESC_POS+KEYMEDIA_INTERFACE_DESC_SIZE #define AUDIO_INTERFACE_DESC_POS KEYMEDIA_INTERFACE_DESC_POS+KEYMEDIA_INTERFACE_DESC_SIZE
#ifdef AUDIO_INTERFACE #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 #else
#define AUDIO_INTERFACE_DESC_SIZE 0 #define AUDIO_INTERFACE_DESC_SIZE 0
#endif #endif
1, // bSamFreqType = 1 frequency 1, // bSamFreqType = 1 frequency
LSB(44100), MSB(44100), 0, // tSamFreq LSB(44100), MSB(44100), 0, // tSamFreq
// Standard AS Isochronous Audio Data Endpoint Descriptor // 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 9, // bLength
5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR 5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR
AUDIO_TX_ENDPOINT | 0x80, // bEndpointAddress AUDIO_TX_ENDPOINT | 0x80, // bEndpointAddress
4, // bDescriptorType = INTERFACE 4, // bDescriptorType = INTERFACE
AUDIO_INTERFACE+2, // bInterfaceNumber AUDIO_INTERFACE+2, // bInterfaceNumber
1, // bAlternateSetting 1, // bAlternateSetting
1, // bNumEndpoints
2, // bNumEndpoints
1, // bInterfaceClass, 1 = AUDIO 1, // bInterfaceClass, 1 = AUDIO
2, // bInterfaceSubclass, 2 = AUDIO_STREAMING 2, // bInterfaceSubclass, 2 = AUDIO_STREAMING
0, // bInterfaceProtocol 0, // bInterfaceProtocol
1, // bSamFreqType = 1 frequency 1, // bSamFreqType = 1 frequency
LSB(44100), MSB(44100), 0, // tSamFreq LSB(44100), MSB(44100), 0, // tSamFreq
// Standard AS Isochronous Audio Data Endpoint Descriptor // 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 9, // bLength
5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR 5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR
AUDIO_RX_ENDPOINT, // bEndpointAddress AUDIO_RX_ENDPOINT, // bEndpointAddress
LSB(AUDIO_RX_SIZE), MSB(AUDIO_RX_SIZE), // wMaxPacketSize LSB(AUDIO_RX_SIZE), MSB(AUDIO_RX_SIZE), // wMaxPacketSize
1, // bInterval, 1 = every frame 1, // bInterval, 1 = every frame
0, // bRefresh 0, // bRefresh
0, // bSynchAddress
AUDIO_SYNC_ENDPOINT | 0x80, // bSynchAddress
// Class-Specific AS Isochronous Audio Data Endpoint Descriptor // 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 // USB DCD for Audio Devices 1.0, Section 4.6.1.2, Table 4-21, page 62-63
7, // bLength 7, // bLength
0x01, // bmAttributes = Sampling Frequency 0x01, // bmAttributes = Sampling Frequency
1, // bLockDelayUnits, 1 = ms 1, // bLockDelayUnits, 1 = ms
0x30, 0x00, // wLockDelay 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 #endif
}; };



+ 3
- 1
teensy3/usb_desc.h View File

#define PRODUCT_NAME {'T','e','e','n','s','y',' ','A','u','d','i','o'} #define PRODUCT_NAME {'T','e','e','n','s','y',' ','A','u','d','i','o'}
#define PRODUCT_NAME_LEN 12 #define PRODUCT_NAME_LEN 12
#define EP0_SIZE 64 #define EP0_SIZE 64
#define NUM_ENDPOINTS 4
#define NUM_ENDPOINTS 5
#define NUM_USB_BUFFERS 16 #define NUM_USB_BUFFERS 16
#define NUM_INTERFACE 4 #define NUM_INTERFACE 4
#define SEREMU_INTERFACE 3 // Serial emulation #define SEREMU_INTERFACE 3 // Serial emulation
#define AUDIO_TX_SIZE 180 #define AUDIO_TX_SIZE 180
#define AUDIO_RX_ENDPOINT 4 #define AUDIO_RX_ENDPOINT 4
#define AUDIO_RX_SIZE 180 #define AUDIO_RX_SIZE 180
#define AUDIO_SYNC_ENDPOINT 5
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT3_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS #define ENDPOINT3_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS
#define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS


#endif #endif



+ 11
- 0
teensy3/usb_dev.c View File

} }
table[index(i, TX, EVEN)].desc = 0; table[index(i, TX, EVEN)].desc = 0;
table[index(i, TX, ODD)].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; break;
case 0x0880: // GET_CONFIGURATION case 0x0880: // GET_CONFIGURATION
usb_audio_receive_callback(b->desc >> 16); usb_audio_receive_callback(b->desc >> 16);
b->addr = usb_audio_receive_buffer; b->addr = usb_audio_receive_buffer;
b->desc = (AUDIO_RX_SIZE << 16) | BDT_OWN; 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 } else
#endif #endif
if (stat & 0x08) { // transmit if (stat & 0x08) { // transmit

+ 1
- 0
teensy3/usb_dev.h View File

#ifdef AUDIO_INTERFACE #ifdef AUDIO_INTERFACE
extern uint16_t usb_audio_receive_buffer[]; extern uint16_t usb_audio_receive_buffer[];
extern uint16_t usb_audio_transmit_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 void usb_audio_receive_callback(unsigned int len);
extern unsigned int usb_audio_transmit_callback(void); extern unsigned int usb_audio_transmit_callback(void);
#endif #endif

Loading…
Cancel
Save