Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
Usb audio Asynchronous
Topic last updated 23 Jun 2015, by Aidan Walton.
3
replies
<<code>>
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ (3 * INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
+ (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
+ (1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
+ (1 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
+ (1 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \ // <------------ changed to + (2 *
+ (1 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
// Endpoint - Standard Descriptor
ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPISO_OUT), // bEndpointAddress
E_ISOCHRONOUS, // bmAttributes
LSB(PACKET_SIZE_ISO), // wMaxPacketSize
MSB(PACKET_SIZE_ISO), // wMaxPacketSize
0x01, // bInterval
0x00, // bRefresh
0x83, // bSynchAddress <----------- EP3IN
// Endpoint - Standard Descriptor // <-------- additional feedback EP
ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPISO_IN), // bEndpointAddress <---------EPISO_IN
E_ISOCHRONOUS | E_ASYNCHRONOUS, // bmAttributes <------ASYNC
0x03, // wMaxPacketSize <----- 3 bytes
0x03, // wMaxPacketSize
0x01, // bInterval <------- 1 packet every frame
0x01, // bRefresh <--------2ms
0x00, // bSynchAddress
<</code>>
<<code>>
// Called in ISR context on each start of frame
extern uint32_t sampling_interval;
void USBAudio::SOF(int frameNumber) {
uint16_t size = 0;
uint32_t current_timer_count;
uint32_t feedback_value;
uint32_t last_timer_count;
uint16_t interface;
uint8_t alternate;
// feedback
current_timer_count = LPC_TIM1->TC; // capture current SOF timing on the Timer1
if (interface == 1 & alternate == 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) / sampling_interval;
//feedback_value = 32 << 14; // test value for 32k sampling
USBDevice:: writeNB( EP3IN, (uint8_t *)&feedback_value, 3 ); // and send it to the feedback IN EP
}
last_timer_count = current_timer_count; // update the last SOF timing
<</code>>
<<code>>
uint32_t sampling_interval;
int main() {
int16_t buf[LENGTH_AUDIO_PACKET/2];
// attach a function executed each 1/FREQ s
tic.attach_us(tic_handler, 1000000.0/(float)FREQ);
sampling_interval = 1000000.0/FREQ;
LPC_SC->PCONP |= (1 << 2); // Power on Timer'
LPC_TIM1->TCR = 1; /* TC1 Enable */
while (1) {
// read an audio packet
USBaudio.read((uint8_t *)buf);
// put buffer in the circ buffer
for(int i = 0; i < LENGTH_AUDIO_PACKET/2; i++) {
cbuf.queue(buf[i]);
}
}
}
<</code>>
I am getting Too few arguments in function call
for USBDevice:: writeNB( EP3IN, (uint8_t *)&feedback_value, 3 );
How do I fix this.
Ok I change and but the maybe I should use update libs
USBDevice::writeNB(EP3IN, (uint8_t *)&feedback_value, 3, PACKET_SIZE_ISO);
but at the moment no in transfers are happing, is problem with this I think
Called in ISR context Set alternate setting. Return false if the alternate setting is not supported
USBAudio::USBAudio(uint32_t frequency_in, uint8_t channel_nb_in, uint32_t frequency_out, uint8_t channel_nb_out, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) { mute = 0; volCur = 0x0080; volMin = 0x0000; volMax = 0x0100; volRes = 0x0004; available = false; FREQ_IN = frequency_in; FREQ_OUT = frequency_out; this->channel_nb_in = channel_nb_in; this->channel_nb_out = channel_nb_out; // stereo -> *2, mono -> *1 PACKET_SIZE_ISO_IN = (FREQ_IN / 500) * channel_nb_in; PACKET_SIZE_ISO_OUT = (FREQ_OUT / 500) * channel_nb_out; // STEREO -> left and right channel_config_in = (channel_nb_in == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R; channel_config_out = (channel_nb_out == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R; SOF_handler = false; buf_stream_out = NULL; buf_stream_in = NULL; interruptOUT = false; writeIN = false; interruptIN = false; available = false; volume = 0; // connect the device USBDevice::connect(); } bool USBAudio::read(uint8_t * buf) { buf_stream_in = buf; SOF_handler = false; while (!available || !SOF_handler); available = false; return true; } bool USBAudio::readNB(uint8_t * buf) { buf_stream_in = buf; SOF_handler = false; while (!SOF_handler); if (available) { available = false; buf_stream_in = NULL; return true; } return false; } bool USBAudio::readWrite(uint8_t * buf_read, uint8_t * buf_write) { buf_stream_in = buf_read; SOF_handler = false; writeIN = false; if (interruptIN) { USBDevice::writeNB(EP3IN, buf_write, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT); } else { buf_stream_out = buf_write; } while (!available); if (interruptIN) { while (!writeIN); } while (!SOF_handler); return true; } bool USBAudio::write(uint8_t * buf) { writeIN = false; SOF_handler = false; if (interruptIN) { USBDevice::writeNB(EP3IN, buf, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT); } else { buf_stream_out = buf; } while (!SOF_handler); if (interruptIN) { while (!writeIN); } return true; } float USBAudio::getVolume() { return (mute) ? 0.0 : volume; } bool USBAudio::EP3_OUT_callback() { uint16_t size = 0; interruptOUT = true; if (buf_stream_in != NULL) { readEP(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN); available = true; buf_stream_in = NULL; } readStart(EP3OUT, PACKET_SIZE_ISO_IN); return false; } bool USBAudio::EP3_IN_callback() { interruptIN = true; writeIN = true; return true; } // Called in ISR context on each start of frame void USBAudio::SOF(int frameNumber) { uint16_t size = 0; if (!interruptOUT) { // read the isochronous endpoint if (buf_stream_in != NULL) { if (USBDevice::readEP_NB(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN)) { if (size) { available = true; readStart(EP3OUT, PACKET_SIZE_ISO_IN); buf_stream_in = NULL; } } } } if (!interruptIN) { // write if needed if (buf_stream_out != NULL) { USBDevice::writeNB(EP3IN, (uint8_t *)buf_stream_out, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT); buf_stream_out = NULL; } } SOF_handler = true; } // Called in ISR context // Set configuration. Return false if the configuration is not supported. bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) { if (configuration != DEFAULT_CONFIGURATION) { return false; } // Configure isochronous endpoint realiseEndpoint(EP3OUT, PACKET_SIZE_ISO_IN, ISOCHRONOUS); realiseEndpoint(EP3IN, PACKET_SIZE_ISO_OUT, ISOCHRONOUS); // activate readings on this endpoint readStart(EP3OUT, PACKET_SIZE_ISO_IN); return true; } // Called in ISR context // Set alternate setting. Return false if the alternate setting is not supported bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) { if (interface == 0 && alternate == 0) { return true; } if (interface == 1 && (alternate == 0 || alternate == 1)) { return true; } if (interface == 2 && (alternate == 0 || alternate == 1)) { return true; } return false;
and I think it should be change to this, with interrupt,it hard to for me to understand how this code is working, the interrupt is new to me, and the conflict with alternate.
// Called in ISR context on each start of frame extern uint32_t sampling_interval; void USBAudio::SOF(int frameNumber) { uint16_t size = 0; uint32_t current_timer_count; uint32_t feedback_value; uint32_t last_timer_count; // feedback current_timer_count = LPC_TIM1->TC; // capture current SOF timing on the Timer1 if (!interruptIN) { // write if needed if (buf_stream_out != NULL) { // If interruptIN, // calculate master/SOF frequency ratio in 10.10 (10.14) format feedback_value = ((current_timer_count - last_timer_count) << 14) / sampling_interval; //feedback_value = 32 << 14; // test value for 32k sampling USBDevice:: writeNB( EP3IN, (uint8_t *)&feedback_value, 3,PACKET_SIZE_ISO); // and send it to the feedback IN EP } last_timer_count = current_timer_count; // update the last SOF timing
Ok I change and but the maybe I should use update libs
** USBDevice::writeNB(EP3IN, (uint8_t *)&feedback_value, 3, PACKET_SIZE_ISO); **
but at the moment no in transfers are happing, is problem with this I think
**
// Called in ISR context
// Set alternate setting. Return false if the alternate setting is not supported**
<<code>>
USBAudio::USBAudio(uint32_t frequency_in, uint8_t channel_nb_in, uint32_t frequency_out, uint8_t channel_nb_out, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
mute = 0;
volCur = 0x0080;
volMin = 0x0000;
volMax = 0x0100;
volRes = 0x0004;
available = false;
FREQ_IN = frequency_in;
FREQ_OUT = frequency_out;
this->channel_nb_in = channel_nb_in;
this->channel_nb_out = channel_nb_out;
// stereo -> *2, mono -> *1
PACKET_SIZE_ISO_IN = (FREQ_IN / 500) * channel_nb_in;
PACKET_SIZE_ISO_OUT = (FREQ_OUT / 500) * channel_nb_out;
// STEREO -> left and right
channel_config_in = (channel_nb_in == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
channel_config_out = (channel_nb_out == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
SOF_handler = false;
buf_stream_out = NULL;
buf_stream_in = NULL;
interruptOUT = false;
writeIN = false;
interruptIN = false;
available = false;
volume = 0;
// connect the device
USBDevice::connect();
}
bool USBAudio::read(uint8_t * buf) {
buf_stream_in = buf;
SOF_handler = false;
while (!available || !SOF_handler);
available = false;
return true;
}
bool USBAudio::readNB(uint8_t * buf) {
buf_stream_in = buf;
SOF_handler = false;
while (!SOF_handler);
if (available) {
available = false;
buf_stream_in = NULL;
return true;
}
return false;
}
bool USBAudio::readWrite(uint8_t * buf_read, uint8_t * buf_write) {
buf_stream_in = buf_read;
SOF_handler = false;
writeIN = false;
if (interruptIN) {
USBDevice::writeNB(EP3IN, buf_write, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
} else {
buf_stream_out = buf_write;
}
while (!available);
if (interruptIN) {
while (!writeIN);
}
while (!SOF_handler);
return true;
}
bool USBAudio::write(uint8_t * buf) {
writeIN = false;
SOF_handler = false;
if (interruptIN) {
USBDevice::writeNB(EP3IN, buf, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
} else {
buf_stream_out = buf;
}
while (!SOF_handler);
if (interruptIN) {
while (!writeIN);
}
return true;
}
float USBAudio::getVolume() {
return (mute) ? 0.0 : volume;
}
bool USBAudio::EP3_OUT_callback() {
uint16_t size = 0;
interruptOUT = true;
if (buf_stream_in != NULL) {
readEP(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN);
available = true;
buf_stream_in = NULL;
}
readStart(EP3OUT, PACKET_SIZE_ISO_IN);
return false;
}
bool USBAudio::EP3_IN_callback() {
interruptIN = true;
writeIN = true;
return true;
}
// Called in ISR context on each start of frame
void USBAudio::SOF(int frameNumber) {
uint16_t size = 0;
if (!interruptOUT) {
// read the isochronous endpoint
if (buf_stream_in != NULL) {
if (USBDevice::readEP_NB(EP3OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN)) {
if (size) {
available = true;
readStart(EP3OUT, PACKET_SIZE_ISO_IN);
buf_stream_in = NULL;
}
}
}
}
if (!interruptIN) {
// write if needed
if (buf_stream_out != NULL) {
USBDevice::writeNB(EP3IN, (uint8_t *)buf_stream_out, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
buf_stream_out = NULL;
}
}
SOF_handler = true;
}
// Called in ISR context
// Set configuration. Return false if the configuration is not supported.
bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) {
if (configuration != DEFAULT_CONFIGURATION) {
return false;
}
// Configure isochronous endpoint
realiseEndpoint(EP3OUT, PACKET_SIZE_ISO_IN, ISOCHRONOUS);
realiseEndpoint(EP3IN, PACKET_SIZE_ISO_OUT, ISOCHRONOUS);
// activate readings on this endpoint
readStart(EP3OUT, PACKET_SIZE_ISO_IN);
return true;
}
// Called in ISR context
// Set alternate setting. Return false if the alternate setting is not supported
bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
if (interface == 0 && alternate == 0) {
return true;
}
if (interface == 1 && (alternate == 0 || alternate == 1)) {
return true;
}
if (interface == 2 && (alternate == 0 || alternate == 1)) {
return true;
}
return false;
<</code>>
and I think it should be change to this, with interrupt,it hard to for me to understand how this code is working, the interrupt is new to me, and the conflict with alternate.
<<code>>
// Called in ISR context on each start of frame
extern uint32_t sampling_interval;
void USBAudio::SOF(int frameNumber) {
uint16_t size = 0;
uint32_t current_timer_count;
uint32_t feedback_value;
uint32_t last_timer_count;
// feedback
current_timer_count = LPC_TIM1->TC; // capture current SOF timing on the Timer1
if (!interruptIN) {
// write if needed
if (buf_stream_out != NULL) {
// If interruptIN,
// calculate master/SOF frequency ratio in 10.10 (10.14) format
feedback_value = ((current_timer_count - last_timer_count) << 14) / sampling_interval;
//feedback_value = 32 << 14; // test value for 32k sampling
USBDevice:: writeNB( EP3IN, (uint8_t *)&feedback_value, 3,PACKET_SIZE_ISO); // and send it to the feedback IN EP
}
last_timer_count = current_timer_count; // update the last SOF timing
<</code>>
I am getting, when using new libs
"integer conversion resulted in truncation" in file "/main.cpp", Line: 19, Col: 40
USBAudio USBAudio USBaudio(FREQ, NB_CHA, 0x71aa, 0x7590);
I am getting, when using new libs
**"integer conversion resulted in truncation" in file "/main.cpp", Line: 19, Col: 40**
<<code>>
USBAudio
USBAudio USBaudio(FREQ, NB_CHA, 0x71aa, 0x7590);
<</code>>
I am getting Too few arguments in function call
for USBDevice:: writeNB( EP3IN, (uint8_t *)&feedback_value, 3 );
How do I fix this.