Increase ITD queue count.

Committer:
dokunewon
Date:
Sun Oct 18 08:16:39 2015 +0000
Revision:
3:5006f79eb589
Change a little.

Who changed what in which revision?

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