Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBAudio.cpp Source File

USBAudio.cpp

00001 /*
00002  * Copyright (c) 2018-2019, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "stdint.h"
00019 #include "USBAudio.h"
00020 #include "USBAudio_Types.h"
00021 #include "EndpointResolver.h"
00022 #include "usb_phy_api.h"
00023 
00024 #define SAMPLE_SIZE                 2
00025 #define XFER_FREQUENCY_HZ           1000
00026 #define WRITE_READY_UNBLOCK         (1 << 0)
00027 #define READ_READY_UNBLOCK          (1 << 1)
00028 
00029 class USBAudio::AsyncWrite: public AsyncOp {
00030 public:
00031     AsyncWrite(USBAudio *audio, uint8_t *buf, uint32_t size):
00032         audio(audio), tx_buf(buf), tx_size(size), result(false)
00033     {
00034 
00035     }
00036 
00037     virtual ~AsyncWrite()
00038     {
00039 
00040     }
00041 
00042     virtual bool process()
00043     {
00044         if (audio->_tx_state != Opened) {
00045             result = false;
00046             return true;
00047         }
00048 
00049         uint32_t actual_size = 0;
00050         audio->write_nb(tx_buf, tx_size, &actual_size);
00051         tx_size -= actual_size;
00052         tx_buf += actual_size;
00053         if (tx_size == 0) {
00054             result = true;
00055             return true;
00056         }
00057 
00058         return false;
00059     }
00060 
00061     USBAudio *audio;
00062     uint8_t *tx_buf;
00063     uint32_t tx_size;
00064     bool result;
00065 };
00066 
00067 class USBAudio::AsyncRead: public AsyncOp {
00068 public:
00069     AsyncRead(USBAudio *audio, uint8_t *buf, uint32_t size, uint32_t *size_read, bool read_all)
00070         :   audio(audio), rx_buf(buf), rx_size(size), rx_actual(size_read), all(read_all), result(false)
00071     {
00072 
00073     }
00074 
00075     virtual ~AsyncRead()
00076     {
00077 
00078     }
00079 
00080     virtual bool process()
00081     {
00082         if (audio->_rx_state != Opened) {
00083             result = false;
00084             return true;
00085         }
00086 
00087         uint32_t actual_size = 0;
00088         audio->read_nb(rx_buf, rx_size, &actual_size);
00089         rx_buf += actual_size;
00090         *rx_actual += actual_size;
00091         rx_size -= actual_size;
00092         if ((!all && *rx_actual > 0) || (rx_size == 0)) {
00093             // Wake thread if request is done
00094             result = true;
00095             return true;
00096         }
00097 
00098         return false;
00099     }
00100 
00101     USBAudio *audio;
00102     uint8_t *rx_buf;
00103     uint32_t rx_size;
00104     uint32_t *rx_actual;
00105     bool all;
00106     bool result;
00107 };
00108 
00109 static void stub_volume()
00110 {
00111 
00112 }
00113 
00114 static void stub_handler(USBAudio::AudioEvent event)
00115 {
00116     (void)event;
00117 }
00118 
00119 USBAudio::USBAudio(bool connect, uint32_t frequency_rx, uint8_t channel_count_rx, uint32_t frequency_tx, uint8_t channel_count_tx, uint32_t buffer_ms, uint16_t vendor_id, uint16_t product_id, uint16_t product_release):
00120     USBDevice(get_usb_phy(), vendor_id, product_id, product_release)
00121 {
00122     _init(frequency_rx, channel_count_rx, frequency_tx, channel_count_tx, buffer_ms);
00123 
00124     // connect or init device
00125     if (connect) {
00126         USBDevice::connect();
00127     } else {
00128         USBDevice::init();
00129     }
00130 }
00131 
00132 USBAudio::USBAudio(USBPhy *phy, uint32_t frequency_rx, uint8_t channel_count_rx, uint32_t frequency_tx, uint8_t channel_count_tx, uint32_t buffer_ms, uint16_t vendor_id, uint16_t product_id, uint16_t product_release):
00133     USBDevice(phy, vendor_id, product_id, product_release)
00134 {
00135     _init(frequency_rx, channel_count_rx, frequency_tx, channel_count_tx, buffer_ms);
00136 }
00137 
00138 void USBAudio::_init(uint32_t frequency_rx, uint8_t channel_count_rx, uint32_t frequency_tx, uint8_t channel_count_tx, uint32_t buffer_ms)
00139 {
00140     _connected = false;
00141 
00142     _volume = 0;
00143     _mute = 0;
00144     _vol_cur = 0x0080;
00145     _vol_min = 0x0000;
00146     _vol_max = 0x0100;
00147     _vol_res = 0x0004;
00148 
00149     _update_vol = mbed::callback(stub_volume);
00150     _tx_done = mbed::callback(stub_handler);
00151     _rx_done = mbed::callback(stub_handler);
00152 
00153     _rx_overflow = 0;
00154     _tx_underflow = 0;
00155 
00156     _tx_freq = frequency_tx;
00157     _rx_freq = frequency_rx;
00158 
00159     _tx_channel_count = channel_count_tx;
00160     _rx_channel_count = channel_count_rx;
00161 
00162     _tx_idle = true;
00163     _tx_frame_fract = 0;
00164     _tx_whole_frames_per_xfer = _tx_freq / XFER_FREQUENCY_HZ;
00165     _tx_fract_frames_per_xfer = _tx_freq % XFER_FREQUENCY_HZ;
00166 
00167     uint32_t max_frames = _tx_whole_frames_per_xfer + (_tx_fract_frames_per_xfer ? 1 : 0);
00168     _tx_packet_size_max = max_frames * SAMPLE_SIZE * _tx_channel_count;
00169     _rx_packet_size_max = (_rx_freq + 1000 - 1) / 1000 * _rx_channel_count * 2;
00170 
00171     _tx_packet_buf = new uint8_t[_tx_packet_size_max]();
00172     _rx_packet_buf = new uint8_t[_rx_packet_size_max]();
00173 
00174     _tx_queue.resize(buffer_ms * _tx_channel_count * SAMPLE_SIZE * _tx_freq / XFER_FREQUENCY_HZ);
00175     _rx_queue.resize(buffer_ms * _rx_channel_count * SAMPLE_SIZE * _rx_freq / XFER_FREQUENCY_HZ);
00176 
00177     _tx_state = Closed;
00178     _rx_state = Closed;
00179 
00180     EndpointResolver resolver(endpoint_table());
00181     resolver.endpoint_ctrl(64);
00182     _episo_out = resolver.endpoint_out(USB_EP_TYPE_ISO, _tx_packet_size_max);
00183     _episo_in = resolver.endpoint_in(USB_EP_TYPE_ISO, _rx_packet_size_max);
00184     MBED_ASSERT(resolver.valid());
00185 
00186     _channel_config_rx = (_rx_channel_count == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
00187     _channel_config_tx = (_tx_channel_count == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
00188 
00189     _build_configuration_desc();
00190 }
00191 
00192 USBAudio::~USBAudio()
00193 {
00194     disconnect();
00195     deinit();
00196 
00197     delete[] _tx_packet_buf;
00198     delete[] _rx_packet_buf;
00199 }
00200 
00201 void USBAudio::connect()
00202 {
00203     lock();
00204 
00205     if (!_connected) {
00206         USBDevice::connect();
00207         _connected = true;
00208         _receive_change(Closed);
00209         _send_change(Closed);
00210     }
00211 
00212     unlock();
00213 }
00214 
00215 void USBAudio::disconnect()
00216 {
00217     lock();
00218 
00219     if (_connected) {
00220         _connected = false;
00221         USBDevice::disconnect();
00222         _receive_change(Powerdown);
00223         _send_change(Powerdown);
00224     }
00225 
00226     unlock();
00227 }
00228 
00229 bool USBAudio::read(uint8_t *buf, uint32_t size)
00230 {
00231     lock();
00232 
00233     uint32_t actual;
00234     AsyncRead read(this, buf, size, &actual, true);
00235     _read_list.add(&read);
00236 
00237     unlock();
00238 
00239     read.wait(NULL);
00240     return read.result;
00241 }
00242 
00243 void USBAudio::read_nb(uint8_t *buf, uint32_t size, uint32_t *actual)
00244 {
00245 
00246     lock();
00247 
00248     uint32_t available = _rx_queue.size();
00249     uint32_t copy_size = available > size ? size : available;
00250     _rx_queue.read(buf, copy_size);
00251     *actual = copy_size;
00252 
00253     unlock();
00254 }
00255 
00256 uint32_t USBAudio::read_overflows(bool clear)
00257 {
00258     lock();
00259 
00260     uint32_t overflows = _rx_overflow;
00261     if (clear) {
00262         _rx_overflow = 0;
00263     }
00264 
00265     unlock();
00266     return overflows;
00267 }
00268 
00269 
00270 bool USBAudio::read_ready()
00271 {
00272     lock();
00273 
00274     bool ready = _rx_state == Opened;
00275 
00276     unlock();
00277 
00278     return ready;
00279 }
00280 
00281 void USBAudio::read_wait_ready()
00282 {
00283     _flags.wait_any(READ_READY_UNBLOCK, osWaitForever, false);
00284 }
00285 
00286 bool USBAudio::write(uint8_t *buf, uint32_t size)
00287 {
00288     lock();
00289 
00290     AsyncWrite write(this, buf, size);
00291     _write_list.add(&write);
00292 
00293     unlock();
00294 
00295     write.wait(NULL);
00296     return write.result;
00297 }
00298 
00299 void USBAudio::write_nb(uint8_t *buf, uint32_t size, uint32_t *actual)
00300 {
00301     lock();
00302 
00303     uint32_t available = _tx_queue.free();
00304     uint32_t copy_size = available > size ? size : available;
00305     _tx_queue.write(buf, copy_size);
00306     *actual = copy_size;
00307     _send_isr_start();
00308 
00309     unlock();
00310 }
00311 
00312 uint32_t USBAudio::write_underflows(bool clear)
00313 {
00314     lock();
00315 
00316     uint32_t underflows = _tx_underflow;
00317     if (clear) {
00318         _tx_underflow = 0;
00319     }
00320 
00321     unlock();
00322     return underflows;
00323 }
00324 
00325 bool USBAudio::write_ready()
00326 {
00327     lock();
00328 
00329     bool ready = _tx_state == Opened;
00330 
00331     unlock();
00332 
00333     return ready;
00334 }
00335 
00336 void USBAudio::write_wait_ready()
00337 {
00338     _flags.wait_any(WRITE_READY_UNBLOCK, osWaitForever, false);
00339 }
00340 
00341 
00342 float USBAudio::get_volume()
00343 {
00344     lock();
00345 
00346     float ret = _mute ? 0.0f : _volume;
00347 
00348     unlock();
00349     return ret;
00350 }
00351 
00352 void USBAudio::attach(mbed::Callback<void()> &cb)
00353 {
00354     lock();
00355 
00356     _update_vol = cb;
00357     if (!_update_vol) {
00358         _update_vol = stub_volume;
00359     }
00360 
00361     unlock();
00362 }
00363 
00364 void USBAudio::attach_tx(mbed::Callback<void(AudioEvent)> &cb)
00365 {
00366     lock();
00367 
00368     _tx_done = cb;
00369     if (!_tx_done) {
00370         _tx_done = mbed::callback(stub_handler);
00371     }
00372 
00373     unlock();
00374 }
00375 
00376 void USBAudio::attach_rx(mbed::Callback<void(AudioEvent)> &cb)
00377 {
00378     lock();
00379 
00380     _rx_done = cb;
00381     if (!_rx_done) {
00382         _rx_done = mbed::callback(stub_handler);
00383     }
00384 
00385     unlock();
00386 }
00387 
00388 void USBAudio::callback_state_change(DeviceState new_state)
00389 {
00390     assert_locked();
00391 
00392     if (_connected && (new_state != Configured)) {
00393         _receive_change(Closed);
00394         _send_change(Closed);
00395     }
00396 }
00397 
00398 void USBAudio::callback_request(const setup_packet_t *setup)
00399 {
00400     assert_locked();
00401 
00402     RequestResult result = PassThrough;
00403     uint8_t *data = NULL;
00404     uint32_t size = 0;
00405 
00406     // Process class-specific requests
00407     if (setup->bmRequestType.Type == CLASS_TYPE) {
00408 
00409         // Feature Unit: Interface = 0, ID = 2
00410         if (setup->wIndex == 0x0200) {
00411 
00412             // Master Channel
00413             if ((setup->wValue & 0xff) == 0) {
00414 
00415                 switch (setup->wValue >> 8) {
00416                     case MUTE_CONTROL:
00417                         switch (setup->bRequest) {
00418                             case REQUEST_GET_CUR:
00419                                 size = 1;
00420                                 data = &_mute;
00421                                 result = Send;
00422                                 break;
00423 
00424                             case REQUEST_SET_CUR:
00425                                 size = 1;
00426                                 data = _control_receive;
00427                                 result = Receive;
00428                                 break;
00429                             default:
00430                                 break;
00431                         }
00432                         break;
00433                     case VOLUME_CONTROL:
00434                         switch (setup->bRequest) {
00435                             case REQUEST_GET_CUR:
00436                                 size = 2;
00437                                 data = (uint8_t *)&_vol_cur;
00438                                 result = Send;
00439                                 break;
00440                             case REQUEST_GET_MIN:
00441                                 size = 2;
00442                                 data = (uint8_t *)&_vol_min;
00443                                 result = Send;
00444                                 break;
00445                             case REQUEST_GET_MAX:
00446                                 size = 2;
00447                                 data = (uint8_t *)&_vol_max;
00448                                 result = Send;
00449                                 break;
00450                             case REQUEST_GET_RES:
00451                                 size = 2;
00452                                 data = (uint8_t *)&_vol_res;
00453                                 result = Send;
00454                                 break;
00455 
00456                             case REQUEST_SET_CUR:
00457                                 size = 2;
00458                                 data = _control_receive;
00459                                 result = Receive;
00460                                 break;
00461                             case REQUEST_SET_MIN:
00462                                 size = 2;
00463                                 data = _control_receive;
00464                                 result = Receive;
00465                                 break;
00466                             case REQUEST_SET_MAX:
00467                                 size = 2;
00468                                 data = _control_receive;
00469                                 result = Receive;
00470                                 break;
00471                             case REQUEST_SET_RES:
00472                                 size = 2;
00473                                 data = _control_receive;
00474                                 result = Receive;
00475                                 break;
00476                         }
00477                         break;
00478                     default:
00479                         break;
00480                 }
00481             }
00482         }
00483     }
00484     complete_request(result, data, size);
00485 }
00486 
00487 void USBAudio::callback_request_xfer_done(const setup_packet_t *setup, bool aborted)
00488 {
00489     assert_locked();
00490 
00491     if (aborted) {
00492         complete_request_xfer_done(false);
00493         return;
00494     }
00495 
00496     if (setup->bmRequestType.dataTransferDirection == DEVICE_TO_HOST) {
00497         complete_request_xfer_done(true);
00498         return;
00499     }
00500 
00501     if ((setup->wLength == 1) || (setup->wLength == 2)) {
00502         uint16_t data = (_control_receive[0] << 0) | (_control_receive[1] << 8);
00503         data &= ((setup->wLength == 1) ? 0xFF : 0xFFFF);
00504         switch (setup->wValue >> 8) {
00505             case MUTE_CONTROL:
00506                 switch (setup->bRequest) {
00507                     case REQUEST_SET_CUR:
00508                         _mute = data & 0xff;
00509                         _update_vol.call();
00510                         break;
00511                     default:
00512                         break;
00513                 }
00514                 break;
00515             case VOLUME_CONTROL:
00516                 switch (setup->bRequest) {
00517                     case REQUEST_SET_CUR:
00518                         _vol_cur = data;
00519                         _volume = (float)_vol_cur / (float)_vol_max;
00520                         _update_vol.call();
00521                         break;
00522                     default:
00523                         break;
00524                 }
00525                 break;
00526             default:
00527                 break;
00528         }
00529         complete_request_xfer_done(true);
00530         return;
00531     }
00532 
00533     complete_request_xfer_done(false);
00534 }
00535 
00536 void USBAudio::callback_set_configuration(uint8_t configuration)
00537 {
00538     assert_locked();
00539 
00540     bool ret = false;
00541     if (configuration == DEFAULT_CONFIGURATION) {
00542         endpoint_remove_all();
00543 
00544         // Configure isochronous endpoint
00545         endpoint_add(_episo_out, _rx_packet_size_max, USB_EP_TYPE_ISO,  static_cast<ep_cb_t>(&USBAudio::_receive_isr));
00546         endpoint_add(_episo_in, _tx_packet_size_max, USB_EP_TYPE_ISO,  static_cast<ep_cb_t>(&USBAudio::_send_isr));
00547 
00548         // activate readings on this endpoint
00549         read_start(_episo_out, _rx_packet_buf, _rx_packet_size_max);
00550         ret = true;
00551     }
00552     complete_set_configuration(ret);
00553 }
00554 
00555 void USBAudio::callback_set_interface(uint16_t interface, uint8_t alternate)
00556 {
00557     assert_locked();
00558 
00559     bool ret = false;
00560     if (interface == 0 && alternate == 0) {
00561         ret = true;
00562     }
00563     if (interface == 1 && (alternate == 0 || alternate == 1)) {
00564         _receive_change(alternate == 1 ? Opened : Closed);
00565         ret = true;
00566     }
00567     if (interface == 2 && (alternate == 0 || alternate == 1)) {
00568         _send_change(alternate == 1 ? Opened : Closed);
00569         ret = true;
00570     }
00571     complete_set_interface(ret);
00572 }
00573 
00574 const uint8_t *USBAudio::configuration_desc(uint8_t index)
00575 {
00576     if (index != 0) {
00577         return NULL;
00578     }
00579     return _config_descriptor;
00580 }
00581 
00582 const uint8_t *USBAudio::string_iinterface_desc()
00583 {
00584     static const uint8_t stringIinterfaceDescriptor[] = {
00585         0x0c,                           //bLength
00586         STRING_DESCRIPTOR,              //bDescriptorType 0x03
00587         'A', 0, 'u', 0, 'd', 0, 'i', 0, 'o', 0 //bString iInterface - Audio
00588     };
00589     return stringIinterfaceDescriptor;
00590 }
00591 
00592 const uint8_t *USBAudio::string_iproduct_desc()
00593 {
00594     static const uint8_t stringIproductDescriptor[] = {
00595         0x16,                                                       //bLength
00596         STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
00597         'M', 0, 'b', 0, 'e', 0, 'd', 0, ' ', 0, 'A', 0, 'u', 0, 'd', 0, 'i', 0, 'o', 0 //bString iProduct - Mbed Audio
00598     };
00599     return stringIproductDescriptor;
00600 }
00601 
00602 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
00603                                + (5 * INTERFACE_DESCRIPTOR_LENGTH) \
00604                                + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1) \
00605                                + (2 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
00606                                + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
00607                                + (2 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
00608                                + (2 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
00609                                + (2 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
00610                                + (2 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
00611                                + (2 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
00612 
00613 #define TOTAL_CONTROL_INTF_LENGTH    (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1 + \
00614                                       2*INPUT_TERMINAL_DESCRIPTOR_LENGTH     + \
00615                                       FEATURE_UNIT_DESCRIPTOR_LENGTH    + \
00616                                       2*OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
00617 
00618 void USBAudio::_build_configuration_desc()
00619 {
00620     uint8_t config_descriptor_temp[] = {
00621         // Configuration 1
00622         CONFIGURATION_DESCRIPTOR_LENGTH,        // bLength
00623         CONFIGURATION_DESCRIPTOR,               // bDescriptorType
00624         LSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (LSB)
00625         MSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (MSB)
00626         0x03,                                   // bNumInterfaces
00627         DEFAULT_CONFIGURATION,                  // bConfigurationValue
00628         0x00,                                   // iConfiguration
00629         0x80,                                   // bmAttributes
00630         50,                                     // bMaxPower
00631 
00632         // Interface 0, Alternate Setting 0, Audio Control
00633         INTERFACE_DESCRIPTOR_LENGTH,            // bLength
00634         INTERFACE_DESCRIPTOR,                   // bDescriptorType
00635         0x00,                                   // bInterfaceNumber
00636         0x00,                                   // bAlternateSetting
00637         0x00,                                   // bNumEndpoints
00638         AUDIO_CLASS,                            // bInterfaceClass
00639         SUBCLASS_AUDIOCONTROL,                  // bInterfaceSubClass
00640         0x00,                                   // bInterfaceProtocol
00641         0x00,                                   // iInterface
00642 
00643 
00644         // Audio Control Interface
00645         CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1,// bLength
00646         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00647         CONTROL_HEADER,                         // bDescriptorSubtype
00648         LSB(0x0100),                            // bcdADC (LSB)
00649         MSB(0x0100),                            // bcdADC (MSB)
00650         LSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
00651         MSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
00652         0x02,                                   // bInCollection
00653         0x01,                                   // baInterfaceNr
00654         0x02,                                   // baInterfaceNr
00655 
00656         // Audio Input Terminal (Speaker)
00657         INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
00658         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00659         CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
00660         0x01,                                   // bTerminalID
00661         LSB(TERMINAL_USB_STREAMING),            // wTerminalType
00662         MSB(TERMINAL_USB_STREAMING),            // wTerminalType
00663         0x00,                                   // bAssocTerminal
00664         _rx_channel_count,                      // bNrChannels
00665         (uint8_t)(LSB(_channel_config_rx)),             // wChannelConfig
00666         (uint8_t)(MSB(_channel_config_rx)),             // wChannelConfig
00667         0x00,                                   // iChannelNames
00668         0x00,                                   // iTerminal
00669 
00670         // Audio Feature Unit (Speaker)
00671         FEATURE_UNIT_DESCRIPTOR_LENGTH,         // bLength
00672         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00673         CONTROL_FEATURE_UNIT,                   // bDescriptorSubtype
00674         0x02,                                   // bUnitID
00675         0x01,                                   // bSourceID
00676         0x01,                                   // bControlSize
00677         CONTROL_MUTE |
00678         CONTROL_VOLUME,                         // bmaControls(0)
00679         0x00,                                   // bmaControls(1)
00680         0x00,                                   // iTerminal
00681 
00682         // Audio Output Terminal (Speaker)
00683         OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
00684         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00685         CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
00686         0x03,                                   // bTerminalID
00687         LSB(TERMINAL_SPEAKER),                  // wTerminalType
00688         MSB(TERMINAL_SPEAKER),                  // wTerminalType
00689         0x00,                                   // bAssocTerminal
00690         0x02,                                   // bSourceID
00691         0x00,                                   // iTerminal
00692 
00693 
00694         // Audio Input Terminal (Microphone)
00695         INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
00696         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00697         CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
00698         0x04,                                   // bTerminalID
00699         LSB(TERMINAL_MICROPHONE),               // wTerminalType
00700         MSB(TERMINAL_MICROPHONE),               // wTerminalType
00701         0x00,                                   // bAssocTerminal
00702         _tx_channel_count,                      // bNrChannels
00703         (uint8_t)(LSB(_channel_config_tx)),             // wChannelConfig
00704         (uint8_t)(MSB(_channel_config_tx)),             // wChannelConfig
00705         0x00,                                   // iChannelNames
00706         0x00,                                   // iTerminal
00707 
00708         // Audio Output Terminal (Microphone)
00709         OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
00710         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00711         CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
00712         0x05,                                   // bTerminalID
00713         LSB(TERMINAL_USB_STREAMING),            // wTerminalType
00714         MSB(TERMINAL_USB_STREAMING),            // wTerminalType
00715         0x00,                                   // bAssocTerminal
00716         0x04,                                   // bSourceID
00717         0x00,                                   // iTerminal
00718 
00719 
00720 
00721 
00722 
00723 
00724         // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
00725         INTERFACE_DESCRIPTOR_LENGTH,            // bLength
00726         INTERFACE_DESCRIPTOR,                   // bDescriptorType
00727         0x01,                                   // bInterfaceNumber
00728         0x00,                                   // bAlternateSetting
00729         0x00,                                   // bNumEndpoints
00730         AUDIO_CLASS,                            // bInterfaceClass
00731         SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
00732         0x00,                                   // bInterfaceProtocol
00733         0x00,                                   // iInterface
00734 
00735         // Interface 1, Alternate Setting 1, Audio Streaming - Operational
00736         INTERFACE_DESCRIPTOR_LENGTH,            // bLength
00737         INTERFACE_DESCRIPTOR,                   // bDescriptorType
00738         0x01,                                   // bInterfaceNumber
00739         0x01,                                   // bAlternateSetting
00740         0x01,                                   // bNumEndpoints
00741         AUDIO_CLASS,                            // bInterfaceClass
00742         SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
00743         0x00,                                   // bInterfaceProtocol
00744         0x00,                                   // iInterface
00745 
00746         // Audio Streaming Interface
00747         STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
00748         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00749         STREAMING_GENERAL,                      // bDescriptorSubtype
00750         0x01,                                   // bTerminalLink
00751         0x00,                                   // bDelay
00752         LSB(FORMAT_PCM),                        // wFormatTag
00753         MSB(FORMAT_PCM),                        // wFormatTag
00754 
00755         // Audio Type I Format
00756         FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
00757         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00758         STREAMING_FORMAT_TYPE,                  // bDescriptorSubtype
00759         FORMAT_TYPE_I,                          // bFormatType
00760         _rx_channel_count,                      // bNrChannels
00761         0x02,                                   // bSubFrameSize
00762         16,                                     // bBitResolution
00763         0x01,                                   // bSamFreqType
00764         (uint8_t)(LSB(_rx_freq)),               // tSamFreq
00765         (uint8_t)((_rx_freq >> 8) & 0xff),      // tSamFreq
00766         (uint8_t)((_rx_freq >> 16) & 0xff),     // tSamFreq
00767 
00768         // Endpoint - Standard Descriptor
00769         ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
00770         ENDPOINT_DESCRIPTOR,                    // bDescriptorType
00771         _episo_out,                             // bEndpointAddress
00772         E_ISOCHRONOUS,                          // bmAttributes
00773         (uint8_t)(LSB(_rx_packet_size_max)),    // wMaxPacketSize
00774         (uint8_t)(MSB(_rx_packet_size_max)),    // wMaxPacketSize
00775         0x01,                                   // bInterval
00776         0x00,                                   // bRefresh
00777         0x00,                                   // bSynchAddress
00778 
00779         // Endpoint - Audio Streaming
00780         STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
00781         ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
00782         ENDPOINT_GENERAL,                       // bDescriptor
00783         0x00,                                   // bmAttributes
00784         0x00,                                   // bLockDelayUnits
00785         LSB(0x0000),                            // wLockDelay
00786         MSB(0x0000),                            // wLockDelay
00787 
00788 
00789         // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
00790         INTERFACE_DESCRIPTOR_LENGTH,            // bLength
00791         INTERFACE_DESCRIPTOR,                   // bDescriptorType
00792         0x02,                                   // bInterfaceNumber
00793         0x00,                                   // bAlternateSetting
00794         0x00,                                   // bNumEndpoints
00795         AUDIO_CLASS,                            // bInterfaceClass
00796         SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
00797         0x00,                                   // bInterfaceProtocol
00798         0x00,                                   // iInterface
00799 
00800         // Interface 1, Alternate Setting 1, Audio Streaming - Operational
00801         INTERFACE_DESCRIPTOR_LENGTH,            // bLength
00802         INTERFACE_DESCRIPTOR,                   // bDescriptorType
00803         0x02,                                   // bInterfaceNumber
00804         0x01,                                   // bAlternateSetting
00805         0x01,                                   // bNumEndpoints
00806         AUDIO_CLASS,                            // bInterfaceClass
00807         SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
00808         0x00,                                   // bInterfaceProtocol
00809         0x00,                                   // iInterface
00810 
00811         // Audio Streaming Interface
00812         STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
00813         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00814         SUBCLASS_AUDIOCONTROL,                  // bDescriptorSubtype
00815         0x05,                                   // bTerminalLink (output terminal microphone)
00816         0x01,                                   // bDelay
00817         0x01,                                   // wFormatTag
00818         0x00,                                   // wFormatTag
00819 
00820         // Audio Type I Format
00821         FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
00822         INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
00823         SUBCLASS_AUDIOSTREAMING,                // bDescriptorSubtype
00824         FORMAT_TYPE_I,                          // bFormatType
00825         _tx_channel_count,                      // bNrChannels
00826         0x02,                                   // bSubFrameSize
00827         0x10,                                   // bBitResolution
00828         0x01,                                   // bSamFreqType
00829         (uint8_t)(LSB(_tx_freq)),               // tSamFreq
00830         (uint8_t)((_tx_freq >> 8) & 0xff),      // tSamFreq
00831         (uint8_t)((_tx_freq >> 16) & 0xff),     // tSamFreq
00832 
00833         // Endpoint - Standard Descriptor
00834         ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
00835         ENDPOINT_DESCRIPTOR,                    // bDescriptorType
00836         _episo_in,                              // bEndpointAddress
00837         E_ISOCHRONOUS,                          // bmAttributes
00838         (uint8_t)(LSB(_tx_packet_size_max)),    // wMaxPacketSize
00839         (uint8_t)(MSB(_tx_packet_size_max)),    // wMaxPacketSize
00840         0x01,                                   // bInterval
00841         0x00,                                   // bRefresh
00842         0x00,                                   // bSynchAddress
00843 
00844         // Endpoint - Audio Streaming
00845         STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
00846         ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
00847         ENDPOINT_GENERAL,                       // bDescriptor
00848         0x00,                                   // bmAttributes
00849         0x00,                                   // bLockDelayUnits
00850         LSB(0x0000),                            // wLockDelay
00851         MSB(0x0000),                            // wLockDelay
00852     };
00853 
00854     MBED_ASSERT(sizeof(config_descriptor_temp) == sizeof(_config_descriptor));
00855     memcpy(_config_descriptor, config_descriptor_temp, sizeof(_config_descriptor));
00856 }
00857 
00858 void USBAudio::_receive_change(ChannelState new_state)
00859 {
00860     assert_locked();
00861 
00862     ChannelState prev_state = _rx_state;
00863     _rx_state = new_state;
00864     if (prev_state == new_state) {
00865         // no change
00866         return;
00867     }
00868 
00869     if (prev_state == Opened) {
00870         // Leaving the opened state
00871         _read_list.process();
00872         _rx_done.call(End);
00873     }
00874     if (new_state == Opened) {
00875         // Entering the opened state
00876         _read_list.process();
00877         _rx_done.call(Start);
00878     }
00879     if (new_state == Closed) {
00880         // Only block if the channel is closed
00881         _flags.clear(READ_READY_UNBLOCK);
00882     } else {
00883         _flags.set(READ_READY_UNBLOCK);
00884     }
00885 }
00886 
00887 void USBAudio::_receive_isr()
00888 {
00889     assert_locked();
00890 
00891     uint32_t size = read_finish(_episo_out);
00892 
00893     if (size > _rx_queue.free()) {
00894         _rx_overflow++;
00895     } else {
00896 
00897         // Copy data over
00898         _rx_queue.write(_rx_packet_buf, size);
00899 
00900         // Signal that there is more data available
00901         _read_list.process();
00902         if (_rx_done) {
00903             _rx_done.call(Transfer);
00904         }
00905     }
00906 
00907     read_start(_episo_out, _rx_packet_buf, _rx_packet_size_max);
00908 }
00909 
00910 void USBAudio::_send_change(ChannelState new_state)
00911 {
00912     assert_locked();
00913 
00914     ChannelState prev_state = _tx_state;
00915     _tx_state = new_state;
00916     if (prev_state == new_state) {
00917         // no change
00918         return;
00919     }
00920 
00921     if (prev_state == Opened) {
00922         // Leaving the opened state
00923         _write_list.process();
00924         _tx_done.call(End);
00925     }
00926     if (new_state == Opened) {
00927         // Entering the opened state
00928         _write_list.process();
00929         _tx_done.call(Start);
00930     }
00931     if (new_state == Closed) {
00932         // Only block if the channel is closed
00933         _flags.clear(WRITE_READY_UNBLOCK);
00934     } else {
00935         _flags.set(WRITE_READY_UNBLOCK);
00936     }
00937 }
00938 void USBAudio::_send_isr_start()
00939 {
00940     assert_locked();
00941 
00942     if (!_tx_idle) {
00943         return;
00944     }
00945 
00946     _send_isr_next_sync();
00947 }
00948 
00949 void USBAudio::_send_isr_next_sync()
00950 {
00951     // Compute size to send
00952     uint32_t fames = _tx_whole_frames_per_xfer;
00953     if (_tx_frame_fract >= XFER_FREQUENCY_HZ) {
00954         _tx_frame_fract -= XFER_FREQUENCY_HZ;
00955         fames += 1;
00956     }
00957     uint32_t send_size = fames * _tx_channel_count * 2;
00958 
00959     // Check if this is the initial TX packet
00960     if (_tx_idle && !_tx_queue.full()) {
00961         // Don't start until the TX buffer is full
00962         return;
00963     }
00964 
00965     // Check if this stream was closed
00966     if (_tx_state != Opened) {
00967         _tx_idle = true;
00968         return;
00969     }
00970 
00971     // Check for enough data to send
00972     if (_tx_queue.size() < send_size) {
00973         _tx_underflow++;
00974         _tx_idle = true;
00975         return;
00976     }
00977 
00978     // Copy data over
00979     _tx_queue.read(_tx_packet_buf, send_size);
00980 
00981     // Start the write
00982     write_start(_episo_in, _tx_packet_buf, send_size);
00983     _tx_idle = false;
00984     _tx_frame_fract += _tx_fract_frames_per_xfer;
00985 }
00986 
00987 void USBAudio::_send_isr()
00988 {
00989     assert_locked();
00990 
00991     write_finish(_episo_in);
00992 
00993     _send_isr_next_sync();
00994 
00995     // Signal that there is space for more data
00996     _write_list.process();
00997     if (_tx_done) {
00998         _tx_done.call(Transfer);
00999     }
01000 }