|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern volatile uint8_t usb_high_speed; |
|
|
extern volatile uint8_t usb_high_speed; |
|
|
static void rx_event(transfer_t *t); |
|
|
static void rx_event(transfer_t *t); |
|
|
static void rx_queue_transfer(void); |
|
|
|
|
|
|
|
|
static void tx_event(transfer_t *t); |
|
|
|
|
|
|
|
|
/*static*/ transfer_t rx_transfer __attribute__ ((used, aligned(32))); |
|
|
/*static*/ transfer_t rx_transfer __attribute__ ((used, aligned(32))); |
|
|
/*static*/ transfer_t sync_transfer __attribute__ ((used, aligned(32))); |
|
|
/*static*/ transfer_t sync_transfer __attribute__ ((used, aligned(32))); |
|
|
|
|
|
/*static*/ transfer_t tx_transfer __attribute__ ((used, aligned(32))); |
|
|
DMAMEM static uint8_t rx_buffer[AUDIO_RX_SIZE] __attribute__ ((aligned(32))); |
|
|
DMAMEM static uint8_t rx_buffer[AUDIO_RX_SIZE] __attribute__ ((aligned(32))); |
|
|
DMAMEM uint32_t usb_audio_sync_feedback; |
|
|
|
|
|
|
|
|
DMAMEM static uint8_t tx_buffer[AUDIO_RX_SIZE] __attribute__ ((aligned(32))); |
|
|
|
|
|
DMAMEM uint32_t usb_audio_sync_feedback __attribute__ ((aligned(32))); |
|
|
|
|
|
|
|
|
uint8_t usb_audio_receive_setting=0; |
|
|
uint8_t usb_audio_receive_setting=0; |
|
|
uint8_t usb_audio_transmit_setting=0; |
|
|
uint8_t usb_audio_transmit_setting=0; |
|
|
|
|
|
|
|
|
{ |
|
|
{ |
|
|
if (t) { |
|
|
if (t) { |
|
|
int len = AUDIO_RX_SIZE - ((rx_transfer.status >> 16) & 0x7FFF); |
|
|
int len = AUDIO_RX_SIZE - ((rx_transfer.status >> 16) & 0x7FFF); |
|
|
//printf("rx %u\n", len); |
|
|
|
|
|
|
|
|
printf("rx %u\n", len); |
|
|
usb_audio_receive_callback(len); |
|
|
usb_audio_receive_callback(len); |
|
|
} |
|
|
} |
|
|
usb_prepare_transfer(&rx_transfer, rx_buffer, AUDIO_RX_SIZE, 0); |
|
|
usb_prepare_transfer(&rx_transfer, rx_buffer, AUDIO_RX_SIZE, 0); |
|
|
|
|
|
|
|
|
//printf("sync %x\n", sync_transfer.status); // too slow, can't print this much |
|
|
//printf("sync %x\n", sync_transfer.status); // too slow, can't print this much |
|
|
usb_audio_sync_feedback = feedback_accumulator >> usb_audio_sync_rshift; |
|
|
usb_audio_sync_feedback = feedback_accumulator >> usb_audio_sync_rshift; |
|
|
usb_prepare_transfer(&sync_transfer, &usb_audio_sync_feedback, usb_audio_sync_nbytes, 0); |
|
|
usb_prepare_transfer(&sync_transfer, &usb_audio_sync_feedback, usb_audio_sync_nbytes, 0); |
|
|
arm_dcache_delete(&usb_audio_sync_feedback, usb_audio_sync_nbytes); |
|
|
|
|
|
|
|
|
arm_dcache_flush(&usb_audio_sync_feedback, usb_audio_sync_nbytes); |
|
|
usb_transmit(AUDIO_SYNC_ENDPOINT, &sync_transfer); |
|
|
usb_transmit(AUDIO_SYNC_ENDPOINT, &sync_transfer); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
memset(&rx_transfer, 0, sizeof(rx_transfer)); |
|
|
memset(&rx_transfer, 0, sizeof(rx_transfer)); |
|
|
usb_config_rx_iso(AUDIO_RX_ENDPOINT, AUDIO_RX_SIZE, 1, rx_event); |
|
|
usb_config_rx_iso(AUDIO_RX_ENDPOINT, AUDIO_RX_SIZE, 1, rx_event); |
|
|
//rx_queue_transfer(); |
|
|
|
|
|
rx_event(NULL); |
|
|
rx_event(NULL); |
|
|
memset(&sync_transfer, 0, sizeof(sync_transfer)); |
|
|
memset(&sync_transfer, 0, sizeof(sync_transfer)); |
|
|
usb_config_tx_iso(AUDIO_SYNC_ENDPOINT, usb_audio_sync_nbytes, 1, sync_event); |
|
|
usb_config_tx_iso(AUDIO_SYNC_ENDPOINT, usb_audio_sync_nbytes, 1, sync_event); |
|
|
sync_event(NULL); |
|
|
sync_event(NULL); |
|
|
|
|
|
memset(&tx_transfer, 0, sizeof(tx_transfer)); |
|
|
|
|
|
usb_config_tx_iso(AUDIO_TX_ENDPOINT, AUDIO_TX_SIZE, 1, tx_event); |
|
|
|
|
|
tx_event(NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void AudioInputUSB::begin(void) |
|
|
void AudioInputUSB::begin(void) |
|
|
|
|
|
|
|
|
__enable_irq(); |
|
|
__enable_irq(); |
|
|
if (f) { |
|
|
if (f) { |
|
|
int diff = AUDIO_BLOCK_SAMPLES/2 - (int)c; |
|
|
int diff = AUDIO_BLOCK_SAMPLES/2 - (int)c; |
|
|
feedback_accumulator += diff * 2; |
|
|
|
|
|
|
|
|
|
|
|
//__disable_irq(); |
|
|
|
|
|
//printf("fb:%x\n", feedback_accumulator); |
|
|
|
|
|
//__enable_irq(); |
|
|
|
|
|
|
|
|
feedback_accumulator += diff * 1; |
|
|
//uint32_t feedback = (feedback_accumulator >> 8) + diff * 100; |
|
|
//uint32_t feedback = (feedback_accumulator >> 8) + diff * 100; |
|
|
//usb_audio_sync_feedback = feedback; |
|
|
//usb_audio_sync_feedback = feedback; |
|
|
//if (diff > 0) { |
|
|
|
|
|
//serial_print("."); |
|
|
|
|
|
//} else if (diff < 0) { |
|
|
|
|
|
//serial_print("^"); |
|
|
|
|
|
//} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//printf(diff >= 0 ? "." : "^"); |
|
|
} |
|
|
} |
|
|
//serial_phex(c); |
|
|
//serial_phex(c); |
|
|
//serial_print("."); |
|
|
//serial_print("."); |
|
|
if (!left || !right) { |
|
|
if (!left || !right) { |
|
|
usb_audio_underrun_count++; |
|
|
usb_audio_underrun_count++; |
|
|
printf("#"); // buffer underrun - PC sending too slow |
|
|
|
|
|
//if (f) feedback_accumulator += 10 << 8; |
|
|
|
|
|
|
|
|
//printf("#"); // buffer underrun - PC sending too slow |
|
|
|
|
|
if (f) feedback_accumulator += 3500; |
|
|
} |
|
|
} |
|
|
if (left) { |
|
|
if (left) { |
|
|
transmit(left, 0); |
|
|
transmit(left, 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
|
#if 1 |
|
|
bool AudioOutputUSB::update_responsibility; |
|
|
bool AudioOutputUSB::update_responsibility; |
|
|
audio_block_t * AudioOutputUSB::left_1st; |
|
|
audio_block_t * AudioOutputUSB::left_1st; |
|
|
audio_block_t * AudioOutputUSB::left_2nd; |
|
|
audio_block_t * AudioOutputUSB::left_2nd; |
|
|
|
|
|
|
|
|
audio_block_t * AudioOutputUSB::right_2nd; |
|
|
audio_block_t * AudioOutputUSB::right_2nd; |
|
|
uint16_t AudioOutputUSB::offset_1st; |
|
|
uint16_t AudioOutputUSB::offset_1st; |
|
|
|
|
|
|
|
|
|
|
|
/*DMAMEM*/ uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] __attribute__ ((used, aligned(32))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void tx_event(transfer_t *t) |
|
|
|
|
|
{ |
|
|
|
|
|
int len = usb_audio_transmit_callback(); |
|
|
|
|
|
usb_audio_sync_feedback = feedback_accumulator >> usb_audio_sync_rshift; |
|
|
|
|
|
usb_prepare_transfer(&tx_transfer, usb_audio_transmit_buffer, len, 0); |
|
|
|
|
|
arm_dcache_flush_delete(usb_audio_transmit_buffer, len); |
|
|
|
|
|
usb_transmit(AUDIO_TX_ENDPOINT, &tx_transfer); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR; |
|
|
|
|
|
|
|
|
|
|
|
void AudioOutputUSB::begin(void) |
|
|
void AudioOutputUSB::begin(void) |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
uint32_t avail, num, target, offset, len=0; |
|
|
uint32_t avail, num, target, offset, len=0; |
|
|
audio_block_t *left, *right; |
|
|
audio_block_t *left, *right; |
|
|
|
|
|
|
|
|
if (++count < 9) { // TODO: dynamic adjust to match USB rate |
|
|
|
|
|
|
|
|
if (++count < 10) { // TODO: dynamic adjust to match USB rate |
|
|
target = 44; |
|
|
target = 44; |
|
|
} else { |
|
|
} else { |
|
|
count = 0; |
|
|
count = 0; |