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
USBHostDac.cpp
00001 /******************************************************************************* 00002 * DISCLAIMER 00003 * This software is supplied by Renesas Electronics Corporation and is only 00004 * intended for use with Renesas products. No other uses are authorized. This 00005 * software is owned by Renesas Electronics Corporation and is protected under 00006 * all applicable laws, including copyright laws. 00007 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING 00008 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT 00009 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00010 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. 00011 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS 00012 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE 00013 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR 00014 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE 00015 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00016 * Renesas reserves the right, without notice, to make changes to this software 00017 * and to discontinue the availability of this software. By using this software, 00018 * you agree to the additional terms and conditions found by accessing the 00019 * following link: 00020 * http://www.renesas.com/disclaimer 00021 * Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved. 00022 *******************************************************************************/ 00023 00024 #include "USBHostDac.h" 00025 00026 #define SAMPLING (0x0100) 00027 #define SET_CUR (0x01) 00028 #define FRAME_COUNT (8) 00029 #define PACKET_SIZE (192) 00030 #define QUEUE_NUM (3) 00031 00032 USBHostDac::USBHostDac() { 00033 host = USBHost::getHostInst(); 00034 iso_send.m_isoEp = new IsochronousEp; 00035 iso_send.p_rest_data = NULL; 00036 00037 iso_recv.m_isoEp = new IsochronousEp; 00038 iso_recv.p_rest_data = NULL; 00039 00040 init(); 00041 } 00042 00043 USBHostDac::~USBHostDac() { 00044 delete iso_send.m_isoEp; 00045 delete iso_recv.m_isoEp; 00046 } 00047 00048 void USBHostDac::init() { 00049 dev = NULL; 00050 dev_connected = false; 00051 audio_device_found = false; 00052 audio_intf = -1; 00053 audio_intf_cnt = 0; 00054 iso_send.bEndpointAddress = 0; 00055 iso_send.rest_data_index = 0; 00056 iso_send.rest_data_size = 0; 00057 if (iso_send.p_rest_data != NULL) { 00058 delete iso_send.p_rest_data; 00059 iso_send.p_rest_data = NULL; 00060 } 00061 iso_recv.bEndpointAddress = 0; 00062 iso_recv.rest_data_index = 0; 00063 iso_recv.rest_data_size = 0; 00064 if (iso_recv.p_rest_data != NULL) { 00065 delete iso_recv.p_rest_data; 00066 iso_recv.p_rest_data = NULL; 00067 } 00068 } 00069 00070 bool USBHostDac::connected() { 00071 return dev_connected; 00072 } 00073 00074 bool USBHostDac::connect() { 00075 if (dev_connected) { 00076 return true; 00077 } 00078 00079 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { 00080 if ((dev = host->getDevice(i)) != NULL) { 00081 00082 if (host->enumerate(dev, this)) { 00083 break; 00084 } 00085 00086 if (audio_device_found) { 00087 USB_INFO("New UsbDac device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, audio_intf); 00088 dev->setName("UsbDac", audio_intf); 00089 host->registerDriver(dev, audio_intf, this, &USBHostDac::onDisconnect); 00090 00091 int addr = dev->getAddress(); 00092 00093 if (iso_send.bEndpointAddress != 0) { 00094 iso_send.p_rest_data = new uint8_t[PACKET_SIZE * FRAME_COUNT]; 00095 iso_send.m_isoEp->init(addr, iso_send.bEndpointAddress, PACKET_SIZE, FRAME_COUNT, QUEUE_NUM); 00096 setInterface(iso_send.bAlternateSetting, iso_send.bInterfaceNumber); 00097 setSamplingRate(iso_send.bEndpointAddress, 48000); 00098 } 00099 00100 if (iso_recv.bEndpointAddress != 0) { 00101 iso_recv.p_rest_data = new uint8_t[iso_recv.wMaxPacketSize * FRAME_COUNT]; 00102 iso_recv.m_isoEp->init(addr, iso_recv.bEndpointAddress, iso_recv.wMaxPacketSize, FRAME_COUNT, QUEUE_NUM); 00103 setInterface(iso_recv.bAlternateSetting, iso_recv.bInterfaceNumber); 00104 setSamplingRate(iso_recv.bEndpointAddress, 48000); 00105 } 00106 00107 dev_connected = true; 00108 return true; 00109 } 00110 } 00111 } 00112 init(); 00113 return false; 00114 } 00115 00116 uint32_t USBHostDac::send(uint8_t* buf, uint32_t len, bool flush) { 00117 uint32_t send_index = 0; 00118 uint32_t rest_size = len; 00119 uint32_t send_size; 00120 uint32_t copy_size; 00121 int result; 00122 00123 if (iso_send.bEndpointAddress == 0) { 00124 return 0; 00125 } 00126 00127 if (iso_send.rest_data_index != 0) { 00128 if (rest_size > iso_send.rest_data_size) { 00129 copy_size = iso_send.rest_data_size; 00130 } else { 00131 copy_size = rest_size; 00132 } 00133 memcpy(&iso_send.p_rest_data[iso_send.rest_data_index], &buf[send_index], copy_size); 00134 send_index += copy_size; 00135 rest_size -= copy_size; 00136 iso_send.rest_data_index += copy_size; 00137 if ((flush != false) || (iso_send.rest_data_index >= (PACKET_SIZE * FRAME_COUNT))) { 00138 if (iso_send.m_isoEp->getQueueNum() == 0) { 00139 iso_send.m_isoEp->reset(4); 00140 } 00141 result = iso_send.m_isoEp->isochronousSend(&iso_send.p_rest_data[0], iso_send.rest_data_index, 100); 00142 iso_send.rest_data_index = 0; 00143 } 00144 } 00145 00146 while ((dev_connected) && (rest_size > 0)) { 00147 if ((flush == false) && (rest_size < (PACKET_SIZE * FRAME_COUNT))) { 00148 memcpy(&iso_send.p_rest_data[0], &buf[send_index], rest_size); 00149 iso_send.rest_data_index = rest_size; 00150 iso_send.rest_data_size = (PACKET_SIZE * FRAME_COUNT) - rest_size; 00151 break; 00152 } else { 00153 if (rest_size >= (PACKET_SIZE * FRAME_COUNT)) { 00154 send_size = (PACKET_SIZE * FRAME_COUNT); 00155 } else { 00156 send_size = rest_size; 00157 } 00158 if (iso_send.m_isoEp->getQueueNum() == 0) { 00159 iso_send.m_isoEp->reset(4); 00160 } 00161 result = iso_send.m_isoEp->isochronousSend(&buf[send_index], send_size, 100); 00162 send_index += result; 00163 rest_size -= result; 00164 } 00165 } 00166 00167 return send_index; 00168 } 00169 00170 uint32_t USBHostDac::receive(uint8_t* buf, uint32_t len) { 00171 uint32_t recv_index = 0; 00172 uint32_t rest_size = len; 00173 uint32_t copy_size; 00174 00175 if (iso_recv.bEndpointAddress == 0) { 00176 return 0; 00177 } 00178 00179 if (iso_recv.rest_data_size != 0) { 00180 if (rest_size > iso_recv.rest_data_size) { 00181 copy_size = iso_recv.rest_data_size; 00182 } else { 00183 copy_size = rest_size; 00184 } 00185 memcpy(&buf[recv_index], &iso_recv.p_rest_data[iso_recv.rest_data_index], copy_size); 00186 recv_index += copy_size; 00187 rest_size -= copy_size; 00188 iso_recv.rest_data_index += copy_size; 00189 iso_recv.rest_data_size -= copy_size; 00190 } 00191 00192 while ((dev_connected) && (rest_size > 0)) { 00193 iso_recv.rest_data_index = 0; 00194 iso_recv.rest_data_size = 0; 00195 00196 if (iso_recv.m_isoEp->getQueueNum() == 0) { 00197 iso_recv.m_isoEp->reset(4); 00198 } 00199 HCITD* itd = iso_recv.m_isoEp->isochronousReceive(100); 00200 if (itd) { 00201 uint8_t cc = itd->ConditionCode(); 00202 if (cc == 0) { 00203 int fc = itd->FrameCount(); 00204 uint8_t* wk_buf = const_cast<uint8_t*>(itd->buf); 00205 int mps = iso_recv.m_isoEp->m_PacketSize; 00206 for (int i = 0; i < fc; i++) { 00207 uint16_t psw = itd->OffsetPSW[i]; 00208 cc = psw>>12; 00209 if (cc == 0 || cc == 9) { 00210 int wk_len = psw & 0x7ff; 00211 if (rest_size > 0) { 00212 if (rest_size > wk_len) { 00213 copy_size = wk_len; 00214 } else { 00215 copy_size = rest_size; 00216 } 00217 memcpy(&buf[recv_index], wk_buf, copy_size); 00218 recv_index += copy_size; 00219 rest_size -= copy_size; 00220 if (copy_size < wk_len) { 00221 memcpy(&iso_recv.p_rest_data[iso_recv.rest_data_size], &wk_buf[copy_size], (wk_len - copy_size)); 00222 iso_recv.rest_data_size += (wk_len - copy_size); 00223 } 00224 } else { 00225 memcpy(&iso_recv.p_rest_data[iso_recv.rest_data_size], &wk_buf[0], wk_len); 00226 iso_recv.rest_data_size += wk_len; 00227 } 00228 } 00229 wk_buf += mps; 00230 } 00231 } 00232 delete itd; 00233 } 00234 } 00235 00236 return recv_index; 00237 } 00238 00239 /*virtual*/ void USBHostDac::setVidPid(uint16_t vid, uint16_t pid) 00240 { 00241 // we don't check VID/PID for audio driver 00242 } 00243 00244 /*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 00245 { 00246 bool ret; 00247 00248 if (audio_intf_cnt >= 2) { 00249 ret = false; 00250 } else if ((intf_class == AUDIO_CLASS) && (intf_subclass == 2) && (intf_protocol == 0)) { 00251 // AUDIOSTREAMING Subclass 00252 ret = chkAudioStreaming(); 00253 if (ret != false) { 00254 audio_intf = intf_nb; 00255 audio_device_found = true; 00256 audio_intf_cnt++; 00257 } 00258 } else { 00259 ret = false; 00260 } 00261 00262 return false; 00263 } 00264 00265 /*virtual*/ bool USBHostDac::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used 00266 { 00267 return false; 00268 } 00269 00270 bool USBHostDac::chkAudioStreaming() { 00271 uint8_t * conf_descr = host->getConfDescrCurPtr(); 00272 uint16_t len = host->getConfDescrRestLen(); 00273 uint32_t index = 0; 00274 uint32_t len_desc = conf_descr[index]; 00275 uint32_t cnt; 00276 uint32_t wk_sampling; 00277 bool smpling_ok = false; 00278 bool loop_end = false; 00279 uint8_t channels = 0; 00280 uint8_t SubframeSize = 0; 00281 uint8_t id; 00282 uint16_t wk_wMaxPacketSize; 00283 uint8_t wk_bEndpointAddress; 00284 uint8_t wk_bInterfaceNumber; 00285 uint8_t wk_bAlternateSetting; 00286 00287 /* bNumEndpoints */ 00288 if (conf_descr[index + 4] >= 1) { 00289 wk_bInterfaceNumber = conf_descr[index + 2]; 00290 wk_bAlternateSetting = conf_descr[index + 3]; 00291 wk_wMaxPacketSize = 0; 00292 wk_bEndpointAddress = 0; 00293 00294 index += len_desc; 00295 while ((index < len) && (loop_end == false)) { 00296 len_desc = conf_descr[index]; 00297 id = conf_descr[index+1]; 00298 switch (id) { 00299 case INTERFACE_DESCRIPTOR: 00300 /* next interface descriptor */ 00301 loop_end = true; 00302 break; 00303 case ENDPOINT_DESCRIPTOR: 00304 if ((conf_descr[index + 3] & 0x03) == ISOCHRONOUS_ENDPOINT) { 00305 wk_bEndpointAddress = conf_descr[index + 2]; 00306 wk_wMaxPacketSize = (conf_descr[index + 5] << 8) + conf_descr[index + 4]; 00307 loop_end = true; 00308 } 00309 break; 00310 case 0x24: /* Audio Class Specific INTERFACE Descriptor */ 00311 if ((conf_descr[index + 2] == 2) && (conf_descr[index + 3] == 1)) { 00312 channels = conf_descr[index + 4]; 00313 SubframeSize = conf_descr[index + 5]; 00314 for (cnt = 8; (cnt + 3) <= len_desc; cnt += 3) { 00315 wk_sampling = ((uint32_t)conf_descr[index + cnt + 0] << 0) 00316 | ((uint32_t)conf_descr[index + cnt + 1] << 8) 00317 | ((uint32_t)conf_descr[index + cnt + 2] << 16); 00318 if (wk_sampling == 48000) { 00319 smpling_ok = true; 00320 } 00321 } 00322 } 00323 break; 00324 default: 00325 break; 00326 } 00327 index += len_desc; 00328 } 00329 00330 if (((wk_bEndpointAddress & 0x80) == 0) && (wk_wMaxPacketSize >= PACKET_SIZE) 00331 && (channels == 2) && (SubframeSize == 2) && (smpling_ok != false)) { 00332 iso_send.wMaxPacketSize = wk_wMaxPacketSize; 00333 iso_send.bEndpointAddress = wk_bEndpointAddress; 00334 iso_send.bInterfaceNumber = wk_bInterfaceNumber; 00335 iso_send.bAlternateSetting = wk_bAlternateSetting; 00336 return true; 00337 } 00338 00339 if (((wk_bEndpointAddress & 0x80) != 0) && (wk_wMaxPacketSize >= (PACKET_SIZE/2)) 00340 && (channels == 1) && (SubframeSize == 2) && (smpling_ok != false)) { 00341 iso_recv.wMaxPacketSize = wk_wMaxPacketSize; 00342 iso_recv.bEndpointAddress = wk_bEndpointAddress; 00343 iso_recv.bInterfaceNumber = wk_bInterfaceNumber; 00344 iso_recv.bAlternateSetting = wk_bAlternateSetting; 00345 return true; 00346 } 00347 } 00348 00349 return false; 00350 } 00351 00352 void USBHostDac::onDisconnect() { 00353 if (dev_connected) { 00354 if (iso_send.bEndpointAddress != 0) { 00355 iso_send.m_isoEp->disconnect(); 00356 } 00357 if (iso_recv.bEndpointAddress != 0) { 00358 iso_recv.m_isoEp->disconnect(); 00359 } 00360 init(); 00361 } 00362 } 00363 00364 USB_TYPE USBHostDac::setInterface(uint16_t alt, uint16_t index) { 00365 return host->controlWrite( dev, 00366 USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, 00367 SET_INTERFACE, 00368 alt, index, NULL, 0); 00369 } 00370 00371 void USBHostDac::setSamplingRate(uint8_t endpoint_adder, uint32_t sampling_rate) { 00372 uint8_t data[3]; 00373 00374 data[0] = (uint8_t)((sampling_rate >> 0) & 0xff); 00375 data[1] = (uint8_t)((sampling_rate >> 8) & 0xff); 00376 data[2] = (uint8_t)((sampling_rate >> 16) & 0xff); 00377 host->controlWrite( dev, 00378 USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS, 00379 SET_CUR, 00380 SAMPLING, endpoint_adder, data, 3); 00381 } 00382
Generated on Thu Jul 14 2022 01:13:33 by 1.7.2