A class to communicate a USB dac (send:only 48kHz,16bit,2ch , receive:only 48kHz,16bit,1ch). Need "USBHost_AddIso" library.

Dependents:   USBHostDac_Audio_in_out

Fork of USBHostDac by GR-PEACH_producer_meeting

Committer:
dkato
Date:
Wed Sep 30 06:08:15 2015 +0000
Revision:
2:4afe26b3d48b
Parent:
1:9ff4cba6524d
Comments update.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:3a3146f89bcc 1 /*******************************************************************************
dkato 0:3a3146f89bcc 2 * DISCLAIMER
dkato 0:3a3146f89bcc 3 * This software is supplied by Renesas Electronics Corporation and is only
dkato 0:3a3146f89bcc 4 * intended for use with Renesas products. No other uses are authorized. This
dkato 0:3a3146f89bcc 5 * software is owned by Renesas Electronics Corporation and is protected under
dkato 0:3a3146f89bcc 6 * all applicable laws, including copyright laws.
dkato 0:3a3146f89bcc 7 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
dkato 0:3a3146f89bcc 8 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
dkato 0:3a3146f89bcc 9 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
dkato 0:3a3146f89bcc 10 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
dkato 0:3a3146f89bcc 11 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
dkato 0:3a3146f89bcc 12 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
dkato 0:3a3146f89bcc 13 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
dkato 0:3a3146f89bcc 14 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
dkato 0:3a3146f89bcc 15 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
dkato 0:3a3146f89bcc 16 * Renesas reserves the right, without notice, to make changes to this software
dkato 0:3a3146f89bcc 17 * and to discontinue the availability of this software. By using this software,
dkato 0:3a3146f89bcc 18 * you agree to the additional terms and conditions found by accessing the
dkato 0:3a3146f89bcc 19 * following link:
dkato 0:3a3146f89bcc 20 * http://www.renesas.com/disclaimer
dkato 0:3a3146f89bcc 21 * Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
dkato 0:3a3146f89bcc 22 *******************************************************************************/
dkato 0:3a3146f89bcc 23
dkato 0:3a3146f89bcc 24 #include "USBHostDac.h"
dkato 0:3a3146f89bcc 25
dkato 0:3a3146f89bcc 26 #define SAMPLING (0x0100)
dkato 0:3a3146f89bcc 27 #define SET_CUR (0x01)
dkato 0:3a3146f89bcc 28 #define FRAME_COUNT (8)
dkato 0:3a3146f89bcc 29 #define PACKET_SIZE (192)
dkato 0:3a3146f89bcc 30 #define QUEUE_NUM (3)
dkato 0:3a3146f89bcc 31
dkato 0:3a3146f89bcc 32 USBHostDac::USBHostDac() {
dkato 0:3a3146f89bcc 33 host = USBHost::getHostInst();
dkato 1:9ff4cba6524d 34 iso_send.m_isoEp = new IsochronousEp;
dkato 1:9ff4cba6524d 35 iso_send.p_rest_data = NULL;
dkato 1:9ff4cba6524d 36
dkato 1:9ff4cba6524d 37 iso_recv.m_isoEp = new IsochronousEp;
dkato 1:9ff4cba6524d 38 iso_recv.p_rest_data = NULL;
dkato 0:3a3146f89bcc 39
dkato 0:3a3146f89bcc 40 init();
dkato 0:3a3146f89bcc 41 }
dkato 0:3a3146f89bcc 42
dkato 1:9ff4cba6524d 43 USBHostDac::~USBHostDac() {
dkato 1:9ff4cba6524d 44 delete iso_send.m_isoEp;
dkato 1:9ff4cba6524d 45 delete iso_recv.m_isoEp;
dkato 1:9ff4cba6524d 46 }
dkato 1:9ff4cba6524d 47
dkato 0:3a3146f89bcc 48 void USBHostDac::init() {
dkato 0:3a3146f89bcc 49 dev = NULL;
dkato 0:3a3146f89bcc 50 dev_connected = false;
dkato 0:3a3146f89bcc 51 audio_device_found = false;
dkato 0:3a3146f89bcc 52 audio_intf = -1;
dkato 0:3a3146f89bcc 53 audio_intf_cnt = 0;
dkato 1:9ff4cba6524d 54 iso_send.bEndpointAddress = 0;
dkato 1:9ff4cba6524d 55 iso_send.rest_data_index = 0;
dkato 1:9ff4cba6524d 56 iso_send.rest_data_size = 0;
dkato 1:9ff4cba6524d 57 if (iso_send.p_rest_data != NULL) {
dkato 1:9ff4cba6524d 58 delete iso_send.p_rest_data;
dkato 1:9ff4cba6524d 59 iso_send.p_rest_data = NULL;
dkato 1:9ff4cba6524d 60 }
dkato 1:9ff4cba6524d 61 iso_recv.bEndpointAddress = 0;
dkato 1:9ff4cba6524d 62 iso_recv.rest_data_index = 0;
dkato 1:9ff4cba6524d 63 iso_recv.rest_data_size = 0;
dkato 1:9ff4cba6524d 64 if (iso_recv.p_rest_data != NULL) {
dkato 1:9ff4cba6524d 65 delete iso_recv.p_rest_data;
dkato 1:9ff4cba6524d 66 iso_recv.p_rest_data = NULL;
dkato 1:9ff4cba6524d 67 }
dkato 0:3a3146f89bcc 68 }
dkato 0:3a3146f89bcc 69
dkato 0:3a3146f89bcc 70 bool USBHostDac::connected() {
dkato 0:3a3146f89bcc 71 return dev_connected;
dkato 0:3a3146f89bcc 72 }
dkato 0:3a3146f89bcc 73
dkato 0:3a3146f89bcc 74 bool USBHostDac::connect() {
dkato 0:3a3146f89bcc 75 if (dev_connected) {
dkato 0:3a3146f89bcc 76 return true;
dkato 0:3a3146f89bcc 77 }
dkato 0:3a3146f89bcc 78
dkato 0:3a3146f89bcc 79 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
dkato 0:3a3146f89bcc 80 if ((dev = host->getDevice(i)) != NULL) {
dkato 0:3a3146f89bcc 81
dkato 0:3a3146f89bcc 82 if (host->enumerate(dev, this)) {
dkato 0:3a3146f89bcc 83 break;
dkato 0:3a3146f89bcc 84 }
dkato 0:3a3146f89bcc 85
dkato 0:3a3146f89bcc 86 if (audio_device_found) {
dkato 0:3a3146f89bcc 87 USB_INFO("New UsbDac device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, audio_intf);
dkato 0:3a3146f89bcc 88 dev->setName("UsbDac", audio_intf);
dkato 0:3a3146f89bcc 89 host->registerDriver(dev, audio_intf, this, &USBHostDac::onDisconnect);
dkato 0:3a3146f89bcc 90
dkato 0:3a3146f89bcc 91 int addr = dev->getAddress();
dkato 1:9ff4cba6524d 92
dkato 1:9ff4cba6524d 93 if (iso_send.bEndpointAddress != 0) {
dkato 1:9ff4cba6524d 94 iso_send.p_rest_data = new uint8_t[PACKET_SIZE * FRAME_COUNT];
dkato 1:9ff4cba6524d 95 iso_send.m_isoEp->init(addr, iso_send.bEndpointAddress, PACKET_SIZE, FRAME_COUNT, QUEUE_NUM);
dkato 1:9ff4cba6524d 96 setInterface(iso_send.bAlternateSetting, iso_send.bInterfaceNumber);
dkato 1:9ff4cba6524d 97 setSamplingRate(iso_send.bEndpointAddress, 48000);
dkato 1:9ff4cba6524d 98 }
dkato 1:9ff4cba6524d 99
dkato 1:9ff4cba6524d 100 if (iso_recv.bEndpointAddress != 0) {
dkato 1:9ff4cba6524d 101 iso_recv.p_rest_data = new uint8_t[iso_recv.wMaxPacketSize * FRAME_COUNT];
dkato 1:9ff4cba6524d 102 iso_recv.m_isoEp->init(addr, iso_recv.bEndpointAddress, iso_recv.wMaxPacketSize, FRAME_COUNT, QUEUE_NUM);
dkato 1:9ff4cba6524d 103 setInterface(iso_recv.bAlternateSetting, iso_recv.bInterfaceNumber);
dkato 1:9ff4cba6524d 104 setSamplingRate(iso_recv.bEndpointAddress, 48000);
dkato 1:9ff4cba6524d 105 }
dkato 0:3a3146f89bcc 106
dkato 0:3a3146f89bcc 107 dev_connected = true;
dkato 0:3a3146f89bcc 108 return true;
dkato 0:3a3146f89bcc 109 }
dkato 0:3a3146f89bcc 110 }
dkato 0:3a3146f89bcc 111 }
dkato 0:3a3146f89bcc 112 init();
dkato 0:3a3146f89bcc 113 return false;
dkato 0:3a3146f89bcc 114 }
dkato 0:3a3146f89bcc 115
dkato 0:3a3146f89bcc 116 uint32_t USBHostDac::send(uint8_t* buf, uint32_t len, bool flush) {
dkato 0:3a3146f89bcc 117 uint32_t send_index = 0;
dkato 0:3a3146f89bcc 118 uint32_t rest_size = len;
dkato 0:3a3146f89bcc 119 uint32_t send_size;
dkato 0:3a3146f89bcc 120 uint32_t copy_size;
dkato 1:9ff4cba6524d 121 int result;
dkato 0:3a3146f89bcc 122
dkato 1:9ff4cba6524d 123 if (iso_send.bEndpointAddress == 0) {
dkato 1:9ff4cba6524d 124 return 0;
dkato 1:9ff4cba6524d 125 }
dkato 1:9ff4cba6524d 126
dkato 1:9ff4cba6524d 127 if (iso_send.rest_data_index != 0) {
dkato 1:9ff4cba6524d 128 if (rest_size > iso_send.rest_data_size) {
dkato 1:9ff4cba6524d 129 copy_size = iso_send.rest_data_size;
dkato 0:3a3146f89bcc 130 } else {
dkato 0:3a3146f89bcc 131 copy_size = rest_size;
dkato 0:3a3146f89bcc 132 }
dkato 1:9ff4cba6524d 133 memcpy(&iso_send.p_rest_data[iso_send.rest_data_index], &buf[send_index], copy_size);
dkato 0:3a3146f89bcc 134 send_index += copy_size;
dkato 0:3a3146f89bcc 135 rest_size -= copy_size;
dkato 1:9ff4cba6524d 136 iso_send.rest_data_index += copy_size;
dkato 1:9ff4cba6524d 137 if ((flush != false) || (iso_send.rest_data_index >= (PACKET_SIZE * FRAME_COUNT))) {
dkato 1:9ff4cba6524d 138 if (iso_send.m_isoEp->getQueueNum() == 0) {
dkato 1:9ff4cba6524d 139 iso_send.m_isoEp->reset(4);
dkato 1:9ff4cba6524d 140 }
dkato 1:9ff4cba6524d 141 result = iso_send.m_isoEp->isochronousSend(&iso_send.p_rest_data[0], iso_send.rest_data_index, 100);
dkato 1:9ff4cba6524d 142 iso_send.rest_data_index = 0;
dkato 0:3a3146f89bcc 143 }
dkato 0:3a3146f89bcc 144 }
dkato 0:3a3146f89bcc 145
dkato 0:3a3146f89bcc 146 while ((dev_connected) && (rest_size > 0)) {
dkato 1:9ff4cba6524d 147 if ((flush == false) && (rest_size < (PACKET_SIZE * FRAME_COUNT))) {
dkato 1:9ff4cba6524d 148 memcpy(&iso_send.p_rest_data[0], &buf[send_index], rest_size);
dkato 1:9ff4cba6524d 149 iso_send.rest_data_index = rest_size;
dkato 1:9ff4cba6524d 150 iso_send.rest_data_size = (PACKET_SIZE * FRAME_COUNT) - rest_size;
dkato 0:3a3146f89bcc 151 break;
dkato 0:3a3146f89bcc 152 } else {
dkato 1:9ff4cba6524d 153 if (rest_size >= (PACKET_SIZE * FRAME_COUNT)) {
dkato 1:9ff4cba6524d 154 send_size = (PACKET_SIZE * FRAME_COUNT);
dkato 0:3a3146f89bcc 155 } else {
dkato 0:3a3146f89bcc 156 send_size = rest_size;
dkato 0:3a3146f89bcc 157 }
dkato 1:9ff4cba6524d 158 if (iso_send.m_isoEp->getQueueNum() == 0) {
dkato 1:9ff4cba6524d 159 iso_send.m_isoEp->reset(4);
dkato 1:9ff4cba6524d 160 }
dkato 1:9ff4cba6524d 161 result = iso_send.m_isoEp->isochronousSend(&buf[send_index], send_size, 100);
dkato 1:9ff4cba6524d 162 send_index += result;
dkato 1:9ff4cba6524d 163 rest_size -= result;
dkato 0:3a3146f89bcc 164 }
dkato 0:3a3146f89bcc 165 }
dkato 0:3a3146f89bcc 166
dkato 0:3a3146f89bcc 167 return send_index;
dkato 0:3a3146f89bcc 168 }
dkato 0:3a3146f89bcc 169
dkato 1:9ff4cba6524d 170 uint32_t USBHostDac::receive(uint8_t* buf, uint32_t len) {
dkato 1:9ff4cba6524d 171 uint32_t recv_index = 0;
dkato 1:9ff4cba6524d 172 uint32_t rest_size = len;
dkato 1:9ff4cba6524d 173 uint32_t copy_size;
dkato 1:9ff4cba6524d 174
dkato 1:9ff4cba6524d 175 if (iso_recv.bEndpointAddress == 0) {
dkato 1:9ff4cba6524d 176 return 0;
dkato 1:9ff4cba6524d 177 }
dkato 1:9ff4cba6524d 178
dkato 1:9ff4cba6524d 179 if (iso_recv.rest_data_size != 0) {
dkato 1:9ff4cba6524d 180 if (rest_size > iso_recv.rest_data_size) {
dkato 1:9ff4cba6524d 181 copy_size = iso_recv.rest_data_size;
dkato 1:9ff4cba6524d 182 } else {
dkato 1:9ff4cba6524d 183 copy_size = rest_size;
dkato 1:9ff4cba6524d 184 }
dkato 1:9ff4cba6524d 185 memcpy(&buf[recv_index], &iso_recv.p_rest_data[iso_recv.rest_data_index], copy_size);
dkato 1:9ff4cba6524d 186 recv_index += copy_size;
dkato 1:9ff4cba6524d 187 rest_size -= copy_size;
dkato 1:9ff4cba6524d 188 iso_recv.rest_data_index += copy_size;
dkato 1:9ff4cba6524d 189 iso_recv.rest_data_size -= copy_size;
dkato 1:9ff4cba6524d 190 }
dkato 1:9ff4cba6524d 191
dkato 1:9ff4cba6524d 192 while ((dev_connected) && (rest_size > 0)) {
dkato 1:9ff4cba6524d 193 iso_recv.rest_data_index = 0;
dkato 1:9ff4cba6524d 194 iso_recv.rest_data_size = 0;
dkato 1:9ff4cba6524d 195
dkato 1:9ff4cba6524d 196 if (iso_recv.m_isoEp->getQueueNum() == 0) {
dkato 1:9ff4cba6524d 197 iso_recv.m_isoEp->reset(4);
dkato 1:9ff4cba6524d 198 }
dkato 1:9ff4cba6524d 199 HCITD* itd = iso_recv.m_isoEp->isochronousReceive(100);
dkato 1:9ff4cba6524d 200 if (itd) {
dkato 1:9ff4cba6524d 201 uint8_t cc = itd->ConditionCode();
dkato 1:9ff4cba6524d 202 if (cc == 0) {
dkato 1:9ff4cba6524d 203 int fc = itd->FrameCount();
dkato 1:9ff4cba6524d 204 uint8_t* wk_buf = const_cast<uint8_t*>(itd->buf);
dkato 1:9ff4cba6524d 205 int mps = iso_recv.m_isoEp->m_PacketSize;
dkato 1:9ff4cba6524d 206 for (int i = 0; i < fc; i++) {
dkato 1:9ff4cba6524d 207 uint16_t psw = itd->OffsetPSW[i];
dkato 1:9ff4cba6524d 208 cc = psw>>12;
dkato 1:9ff4cba6524d 209 if (cc == 0 || cc == 9) {
dkato 1:9ff4cba6524d 210 int wk_len = psw & 0x7ff;
dkato 1:9ff4cba6524d 211 if (rest_size > 0) {
dkato 1:9ff4cba6524d 212 if (rest_size > wk_len) {
dkato 1:9ff4cba6524d 213 copy_size = wk_len;
dkato 1:9ff4cba6524d 214 } else {
dkato 1:9ff4cba6524d 215 copy_size = rest_size;
dkato 1:9ff4cba6524d 216 }
dkato 1:9ff4cba6524d 217 memcpy(&buf[recv_index], wk_buf, copy_size);
dkato 1:9ff4cba6524d 218 recv_index += copy_size;
dkato 1:9ff4cba6524d 219 rest_size -= copy_size;
dkato 1:9ff4cba6524d 220 if (copy_size < wk_len) {
dkato 1:9ff4cba6524d 221 memcpy(&iso_recv.p_rest_data[iso_recv.rest_data_size], &wk_buf[copy_size], (wk_len - copy_size));
dkato 1:9ff4cba6524d 222 iso_recv.rest_data_size += (wk_len - copy_size);
dkato 1:9ff4cba6524d 223 }
dkato 1:9ff4cba6524d 224 } else {
dkato 1:9ff4cba6524d 225 memcpy(&iso_recv.p_rest_data[iso_recv.rest_data_size], &wk_buf[0], wk_len);
dkato 1:9ff4cba6524d 226 iso_recv.rest_data_size += wk_len;
dkato 1:9ff4cba6524d 227 }
dkato 1:9ff4cba6524d 228 }
dkato 1:9ff4cba6524d 229 wk_buf += mps;
dkato 1:9ff4cba6524d 230 }
dkato 1:9ff4cba6524d 231 }
dkato 1:9ff4cba6524d 232 delete itd;
dkato 1:9ff4cba6524d 233 }
dkato 1:9ff4cba6524d 234 }
dkato 1:9ff4cba6524d 235
dkato 1:9ff4cba6524d 236 return recv_index;
dkato 1:9ff4cba6524d 237 }
dkato 1:9ff4cba6524d 238
dkato 0:3a3146f89bcc 239 /*virtual*/ void USBHostDac::setVidPid(uint16_t vid, uint16_t pid)
dkato 0:3a3146f89bcc 240 {
dkato 0:3a3146f89bcc 241 // we don't check VID/PID for audio driver
dkato 0:3a3146f89bcc 242 }
dkato 0:3a3146f89bcc 243
dkato 0:3a3146f89bcc 244 /*virtual*/ bool USBHostDac::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
dkato 0:3a3146f89bcc 245 {
dkato 0:3a3146f89bcc 246 bool ret;
dkato 0:3a3146f89bcc 247
dkato 1:9ff4cba6524d 248 if (audio_intf_cnt >= 2) {
dkato 0:3a3146f89bcc 249 ret = false;
dkato 0:3a3146f89bcc 250 } else if ((intf_class == AUDIO_CLASS) && (intf_subclass == 2) && (intf_protocol == 0)) {
dkato 0:3a3146f89bcc 251 // AUDIOSTREAMING Subclass
dkato 0:3a3146f89bcc 252 ret = chkAudioStreaming();
dkato 0:3a3146f89bcc 253 if (ret != false) {
dkato 0:3a3146f89bcc 254 audio_intf = intf_nb;
dkato 0:3a3146f89bcc 255 audio_device_found = true;
dkato 1:9ff4cba6524d 256 audio_intf_cnt++;
dkato 0:3a3146f89bcc 257 }
dkato 0:3a3146f89bcc 258 } else {
dkato 0:3a3146f89bcc 259 ret = false;
dkato 0:3a3146f89bcc 260 }
dkato 0:3a3146f89bcc 261
dkato 0:3a3146f89bcc 262 return false;
dkato 0:3a3146f89bcc 263 }
dkato 0:3a3146f89bcc 264
dkato 0:3a3146f89bcc 265 /*virtual*/ bool USBHostDac::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
dkato 0:3a3146f89bcc 266 {
dkato 0:3a3146f89bcc 267 return false;
dkato 0:3a3146f89bcc 268 }
dkato 0:3a3146f89bcc 269
dkato 0:3a3146f89bcc 270 bool USBHostDac::chkAudioStreaming() {
dkato 0:3a3146f89bcc 271 uint8_t * conf_descr = host->getConfDescrCurPtr();
dkato 0:3a3146f89bcc 272 uint16_t len = host->getConfDescrRestLen();
dkato 0:3a3146f89bcc 273 uint32_t index = 0;
dkato 0:3a3146f89bcc 274 uint32_t len_desc = conf_descr[index];
dkato 0:3a3146f89bcc 275 uint32_t cnt;
dkato 0:3a3146f89bcc 276 uint32_t wk_sampling;
dkato 0:3a3146f89bcc 277 bool smpling_ok = false;
dkato 0:3a3146f89bcc 278 bool loop_end = false;
dkato 0:3a3146f89bcc 279 uint8_t channels = 0;
dkato 0:3a3146f89bcc 280 uint8_t SubframeSize = 0;
dkato 0:3a3146f89bcc 281 uint8_t id;
dkato 1:9ff4cba6524d 282 uint16_t wk_wMaxPacketSize;
dkato 1:9ff4cba6524d 283 uint8_t wk_bEndpointAddress;
dkato 1:9ff4cba6524d 284 uint8_t wk_bInterfaceNumber;
dkato 1:9ff4cba6524d 285 uint8_t wk_bAlternateSetting;
dkato 0:3a3146f89bcc 286
dkato 0:3a3146f89bcc 287 /* bNumEndpoints */
dkato 0:3a3146f89bcc 288 if (conf_descr[index + 4] >= 1) {
dkato 1:9ff4cba6524d 289 wk_bInterfaceNumber = conf_descr[index + 2];
dkato 1:9ff4cba6524d 290 wk_bAlternateSetting = conf_descr[index + 3];
dkato 1:9ff4cba6524d 291 wk_wMaxPacketSize = 0;
dkato 1:9ff4cba6524d 292 wk_bEndpointAddress = 0;
dkato 0:3a3146f89bcc 293
dkato 0:3a3146f89bcc 294 index += len_desc;
dkato 0:3a3146f89bcc 295 while ((index < len) && (loop_end == false)) {
dkato 0:3a3146f89bcc 296 len_desc = conf_descr[index];
dkato 0:3a3146f89bcc 297 id = conf_descr[index+1];
dkato 0:3a3146f89bcc 298 switch (id) {
dkato 0:3a3146f89bcc 299 case INTERFACE_DESCRIPTOR:
dkato 0:3a3146f89bcc 300 /* next interface descriptor */
dkato 0:3a3146f89bcc 301 loop_end = true;
dkato 0:3a3146f89bcc 302 break;
dkato 0:3a3146f89bcc 303 case ENDPOINT_DESCRIPTOR:
dkato 0:3a3146f89bcc 304 if ((conf_descr[index + 3] & 0x03) == ISOCHRONOUS_ENDPOINT) {
dkato 1:9ff4cba6524d 305 wk_bEndpointAddress = conf_descr[index + 2];
dkato 1:9ff4cba6524d 306 wk_wMaxPacketSize = (conf_descr[index + 5] << 8) + conf_descr[index + 4];
dkato 0:3a3146f89bcc 307 loop_end = true;
dkato 0:3a3146f89bcc 308 }
dkato 0:3a3146f89bcc 309 break;
dkato 0:3a3146f89bcc 310 case 0x24: /* Audio Class Specific INTERFACE Descriptor */
dkato 0:3a3146f89bcc 311 if ((conf_descr[index + 2] == 2) && (conf_descr[index + 3] == 1)) {
dkato 0:3a3146f89bcc 312 channels = conf_descr[index + 4];
dkato 0:3a3146f89bcc 313 SubframeSize = conf_descr[index + 5];
dkato 0:3a3146f89bcc 314 for (cnt = 8; (cnt + 3) <= len_desc; cnt += 3) {
dkato 0:3a3146f89bcc 315 wk_sampling = ((uint32_t)conf_descr[index + cnt + 0] << 0)
dkato 0:3a3146f89bcc 316 | ((uint32_t)conf_descr[index + cnt + 1] << 8)
dkato 0:3a3146f89bcc 317 | ((uint32_t)conf_descr[index + cnt + 2] << 16);
dkato 0:3a3146f89bcc 318 if (wk_sampling == 48000) {
dkato 0:3a3146f89bcc 319 smpling_ok = true;
dkato 0:3a3146f89bcc 320 }
dkato 0:3a3146f89bcc 321 }
dkato 0:3a3146f89bcc 322 }
dkato 0:3a3146f89bcc 323 break;
dkato 0:3a3146f89bcc 324 default:
dkato 0:3a3146f89bcc 325 break;
dkato 0:3a3146f89bcc 326 }
dkato 0:3a3146f89bcc 327 index += len_desc;
dkato 0:3a3146f89bcc 328 }
dkato 0:3a3146f89bcc 329
dkato 1:9ff4cba6524d 330 if (((wk_bEndpointAddress & 0x80) == 0) && (wk_wMaxPacketSize >= PACKET_SIZE)
dkato 0:3a3146f89bcc 331 && (channels == 2) && (SubframeSize == 2) && (smpling_ok != false)) {
dkato 1:9ff4cba6524d 332 iso_send.wMaxPacketSize = wk_wMaxPacketSize;
dkato 1:9ff4cba6524d 333 iso_send.bEndpointAddress = wk_bEndpointAddress;
dkato 1:9ff4cba6524d 334 iso_send.bInterfaceNumber = wk_bInterfaceNumber;
dkato 1:9ff4cba6524d 335 iso_send.bAlternateSetting = wk_bAlternateSetting;
dkato 1:9ff4cba6524d 336 return true;
dkato 1:9ff4cba6524d 337 }
dkato 1:9ff4cba6524d 338
dkato 1:9ff4cba6524d 339 if (((wk_bEndpointAddress & 0x80) != 0) && (wk_wMaxPacketSize >= (PACKET_SIZE/2))
dkato 1:9ff4cba6524d 340 && (channels == 1) && (SubframeSize == 2) && (smpling_ok != false)) {
dkato 1:9ff4cba6524d 341 iso_recv.wMaxPacketSize = wk_wMaxPacketSize;
dkato 1:9ff4cba6524d 342 iso_recv.bEndpointAddress = wk_bEndpointAddress;
dkato 1:9ff4cba6524d 343 iso_recv.bInterfaceNumber = wk_bInterfaceNumber;
dkato 1:9ff4cba6524d 344 iso_recv.bAlternateSetting = wk_bAlternateSetting;
dkato 0:3a3146f89bcc 345 return true;
dkato 0:3a3146f89bcc 346 }
dkato 0:3a3146f89bcc 347 }
dkato 0:3a3146f89bcc 348
dkato 0:3a3146f89bcc 349 return false;
dkato 0:3a3146f89bcc 350 }
dkato 0:3a3146f89bcc 351
dkato 0:3a3146f89bcc 352 void USBHostDac::onDisconnect() {
dkato 0:3a3146f89bcc 353 if (dev_connected) {
dkato 1:9ff4cba6524d 354 if (iso_send.bEndpointAddress != 0) {
dkato 1:9ff4cba6524d 355 iso_send.m_isoEp->disconnect();
dkato 1:9ff4cba6524d 356 }
dkato 1:9ff4cba6524d 357 if (iso_recv.bEndpointAddress != 0) {
dkato 1:9ff4cba6524d 358 iso_recv.m_isoEp->disconnect();
dkato 1:9ff4cba6524d 359 }
dkato 0:3a3146f89bcc 360 init();
dkato 0:3a3146f89bcc 361 }
dkato 0:3a3146f89bcc 362 }
dkato 0:3a3146f89bcc 363
dkato 0:3a3146f89bcc 364 USB_TYPE USBHostDac::setInterface(uint16_t alt, uint16_t index) {
dkato 0:3a3146f89bcc 365 return host->controlWrite( dev,
dkato 0:3a3146f89bcc 366 USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
dkato 0:3a3146f89bcc 367 SET_INTERFACE,
dkato 0:3a3146f89bcc 368 alt, index, NULL, 0);
dkato 0:3a3146f89bcc 369 }
dkato 0:3a3146f89bcc 370
dkato 1:9ff4cba6524d 371 void USBHostDac::setSamplingRate(uint8_t endpoint_adder, uint32_t sampling_rate) {
dkato 0:3a3146f89bcc 372 uint8_t data[3];
dkato 0:3a3146f89bcc 373
dkato 0:3a3146f89bcc 374 data[0] = (uint8_t)((sampling_rate >> 0) & 0xff);
dkato 0:3a3146f89bcc 375 data[1] = (uint8_t)((sampling_rate >> 8) & 0xff);
dkato 0:3a3146f89bcc 376 data[2] = (uint8_t)((sampling_rate >> 16) & 0xff);
dkato 0:3a3146f89bcc 377 host->controlWrite( dev,
dkato 0:3a3146f89bcc 378 USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
dkato 0:3a3146f89bcc 379 SET_CUR,
dkato 1:9ff4cba6524d 380 SAMPLING, endpoint_adder, data, 3);
dkato 0:3a3146f89bcc 381 }
dkato 0:3a3146f89bcc 382