00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <AUDDSpeakerPhone.h>
00044
00045 #include <USBDescriptors.h>
00046 #include <USBRequests.h>
00047 #include <AUDDescriptors.h>
00048 #include <AUDRequests.h>
00049
00050 #include <USBD_HAL.h>
00051
00052 #include <USBLib_Trace.h>
00053
00054
00055
00056
00057
00058
00059 typedef struct _AUDDParseData {
00060
00061 AUDDSpeakerPhone * pAudf;
00062
00063 USBInterfaceDescriptor * pIfDesc;
00064
00065 } AUDDParseData;
00066
00067
00068 typedef struct _AUDDXfrExt {
00069
00070 AUDDStream *pStream;
00071
00072 uint16_t usbBuffer;
00073
00074 uint8_t bEntity;
00075
00076 uint8_t bCh;
00077 } AUDDXfrExt;
00078
00079
00080
00081
00082
00083
00084 static AUDDXfrExt auddXfrData;
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 static uint32_t AUDDSpeakerPhone_Parse(USBGenericDescriptor *pDesc,
00096 AUDDParseData * pArg)
00097 {
00098 AUDDStream *pSpeaker = pArg->pAudf->pSpeaker;
00099 AUDDStream *pMic = pArg->pAudf->pMicrophone;
00100 USBEndpointDescriptor* pEp = (USBEndpointDescriptor*)pDesc;
00101 uint8_t bSpeakerDone = 0, bMicDone = 0;
00102
00103
00104 if (pDesc->bLength == 0)
00105 return USBRC_PARAM_ERR;
00106
00107
00108 if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00109 USBInterfaceDescriptor* pIf = (USBInterfaceDescriptor*)pDesc;
00110
00111 if (pIf->bInterfaceClass ==
00112 AUDControlInterfaceDescriptor_CLASS
00113 && pIf->bInterfaceSubClass ==
00114 AUDControlInterfaceDescriptor_SUBCLASS) {
00115 pArg->pIfDesc = pIf;
00116
00117 if (pSpeaker) pSpeaker->bAcInterface = pIf->bInterfaceNumber;
00118 if (pMic) pMic->bAcInterface = pIf->bInterfaceNumber;
00119 }
00120
00121 else if (pIf->bInterfaceClass ==
00122 AUDStreamingInterfaceDescriptor_CLASS
00123 && pIf->bInterfaceSubClass ==
00124 AUDStreamingInterfaceDescriptor_SUBCLASS) {
00125 pArg->pIfDesc = pIf;
00126 }
00127
00128 else if (pArg->pIfDesc){
00129 return USBRC_PARTIAL_DONE;
00130 }
00131 }
00132
00133 if (pArg->pIfDesc) {
00134
00135
00136
00137 if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT
00138 && (pEp->bmAttributes & 0x3) == USBEndpointDescriptor_ISOCHRONOUS) {
00139 if (pEp->bEndpointAddress & 0x80
00140 && pMic) {
00141 pMic->bEndpointIn = pEp->bEndpointAddress & 0x7F;
00142 pMic->bAsInterface = pArg->pIfDesc->bInterfaceNumber;
00143
00144 pMic->bFeatureUnitIn = AUDD_ID_MicrophoneFU;
00145 }
00146 else if (pSpeaker) {
00147 pSpeaker->bEndpointOut = pEp->bEndpointAddress;
00148 pSpeaker->bAsInterface = pArg->pIfDesc->bInterfaceNumber;
00149
00150 pSpeaker->bFeatureUnitOut = AUDD_ID_SpeakerFU;
00151 }
00152 }
00153 }
00154
00155 if (pSpeaker) {
00156 if (pSpeaker->bAcInterface != 0xFF
00157 && pSpeaker->bAsInterface != 0xFF
00158 && pSpeaker->bFeatureUnitOut != 0xFF
00159 && pSpeaker->bEndpointOut != 0) {
00160 bSpeakerDone = 1;
00161 }
00162 }
00163 else bSpeakerDone = 1;
00164
00165 if (pMic) {
00166 if (pMic->bAcInterface != 0xFF
00167 && pMic->bAsInterface != 0xFF
00168 && pMic->bFeatureUnitIn != 0xFF
00169 && pMic->bEndpointIn != 0) {
00170 bMicDone = 1;
00171 }
00172 }
00173 else bMicDone = 1;
00174
00175 if (bSpeakerDone && bMicDone)
00176 return USBRC_FINISHED;
00177
00178 return USBRC_SUCCESS;
00179 }
00180
00181
00182
00183
00184
00185
00186 static void AUDD_MuteReceived(AUDDXfrExt *pData)
00187 {
00188 AUDDStream_ChangeMute(pData->pStream,
00189 pData->bCh,
00190 (uint8_t)pData->usbBuffer);
00191 USBD_Write(0, 0, 0, 0, 0);
00192 }
00193
00194
00195
00196
00197
00198
00199 static void AUDD_VolumeReceived(AUDDXfrExt *pData)
00200 {
00201 AUDDStream_SetVolume(pData->pStream,
00202 pData->bCh,
00203 pData->usbBuffer);
00204 USBD_Write(0, 0, 0, 0, 0);
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 static AUDDStream *AUDD_GetCtlStream(
00216 AUDDSpeakerPhone *pAudf,
00217 uint8_t bAcInterface,
00218 uint8_t bEntity,
00219 uint8_t bChannel)
00220 {
00221 AUDDStream *pAuds = 0;
00222
00223 if (bEntity == pAudf->pSpeaker->bFeatureUnitOut
00224 || bEntity == pAudf->pSpeaker->bFeatureUnitIn)
00225 pAuds = pAudf->pSpeaker;
00226 else if (bEntity == pAudf->pMicrophone->bFeatureUnitIn
00227 || bEntity == pAudf->pMicrophone->bFeatureUnitOut)
00228 pAuds = pAudf->pMicrophone;
00229
00230 if (pAuds != 0
00231 && bAcInterface == pAuds->bAcInterface
00232 && bChannel <= pAuds->bNumChannels) {
00233 return pAuds;
00234 }
00235
00236 return 0;
00237 }
00238
00239
00240
00241
00242
00243
00244 static void AUDD_SetCUR(
00245 AUDDSpeakerPhone *pAudf,
00246 const USBGenericRequest* pReq)
00247 {
00248 uint8_t bIf = AUDGenericRequest_GetInterface(pReq);
00249 uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00250 uint8_t bLength = USBGenericRequest_GetLength(pReq);
00251 uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq);
00252 uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq);
00253 uint8_t bSet = 1;
00254 AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);
00255 TransferCallback fCallback;
00256
00257 TRACE_INFO_WP("sCUR ");
00258 TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);
00259
00260
00261 if (bCtrl == AUDFeatureUnitRequest_MUTE
00262 && bLength == 1
00263 && pAuds) {
00264 fCallback = (TransferCallback) AUDD_MuteReceived;
00265 }
00266 else if (bCtrl == AUDFeatureUnitRequest_VOLUME
00267 && bLength == 2
00268 && pAuds && pAuds->pwVolumes) {
00269 fCallback = (TransferCallback) AUDD_VolumeReceived;
00270 }
00271 else
00272 bSet = 0;
00273
00274 if (bSet) {
00275
00276 auddXfrData.pStream = pAuds;
00277 auddXfrData.bEntity = bEntity;
00278 auddXfrData.bCh = bCh;
00279 USBD_Read(0,
00280 &auddXfrData.usbBuffer,
00281 bLength,
00282 fCallback,
00283 (void *) &auddXfrData);
00284 }
00285 else {
00286
00287 USBD_Stall(0);
00288 }
00289
00290 }
00291
00292
00293
00294
00295
00296
00297 static void AUDD_GetCUR(
00298 AUDDSpeakerPhone *pAudf,
00299 const USBGenericRequest *pReq)
00300 {
00301 uint8_t bIf = AUDGenericRequest_GetInterface(pReq);
00302 uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00303 uint8_t bLength = USBGenericRequest_GetLength(pReq);
00304 uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq);
00305 uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq);
00306 uint8_t bGet = 1;
00307 AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);
00308
00309 TRACE_INFO_WP("gCUR ");
00310 TRACE_INFO_WP("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);
00311
00312
00313 if (bCtrl == AUDFeatureUnitRequest_MUTE
00314 && bLength == 1
00315 && pAuds) {
00316 auddXfrData.usbBuffer = ((pAuds->bmMute & (1<<bCh)) > 0);
00317 }
00318 else if (bCtrl == AUDFeatureUnitRequest_VOLUME
00319 && bLength == 2
00320 && pAuds && pAuds->pwVolumes) {
00321 auddXfrData.usbBuffer = pAuds->pwVolumes[bCh];
00322 }
00323 else
00324 bGet = 0;
00325
00326 if (bGet) {
00327
00328 USBD_Write(0, &auddXfrData.usbBuffer, bLength, 0, 0);
00329 }
00330 else {
00331
00332 USBD_Stall(0);
00333 }
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 void AUDDStream_Initialize(AUDDStream *pAuds,
00351 uint8_t numChannels,
00352 uint16_t wChannelVolumes[],
00353 AUDDStreamEventCallback fCallback,
00354 void* pArg)
00355 {
00356 pAuds->bAcInterface = 0xFF;
00357 pAuds->bFeatureUnitOut = 0xFF;
00358 pAuds->bFeatureUnitIn = 0xFF;
00359 pAuds->bAsInterface = 0xFF;
00360 pAuds->bEndpointOut = 0;
00361 pAuds->bEndpointIn = 0;
00362
00363 pAuds->bNumChannels = numChannels;
00364 pAuds->bmMute = 0;
00365 pAuds->pwVolumes = wChannelVolumes;
00366
00367 pAuds->fCallback = fCallback;
00368 pAuds->pArg = pArg;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377 uint32_t AUDDStream_IsRequestAccepted(
00378 AUDDStream *pAuds,
00379 const USBGenericRequest *pReq)
00380 {
00381 uint8_t bIf = AUDGenericRequest_GetInterface(pReq);
00382 uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00383 uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq);
00384
00385 if (bIf == pAuds->bAcInterface) {
00386 if (bCh > pAuds->bNumChannels)
00387 return 0;
00388 if (bEntity != pAuds->bFeatureUnitIn
00389 && bEntity != pAuds->bFeatureUnitOut)
00390 return 0;
00391 }
00392
00393 else {
00394 return 0;
00395 }
00396 return 1;
00397 }
00398
00399
00400
00401
00402
00403
00404
00405 uint32_t AUDDStream_ChangeMute(AUDDStream *pAuds,
00406 uint8_t bChannel,
00407 uint8_t bMute)
00408 {
00409 uint32_t bmMute = (bMute << bChannel);
00410
00411 if (pAuds->bNumChannels < bChannel)
00412 return USBRC_PARAM_ERR;
00413
00414 pAuds->bmMute = bMute;
00415
00416 if (pAuds->fCallback)
00417 pAuds->fCallback(AUDD_EC_MuteChanged,
00418 bChannel,
00419 pAuds->pArg);
00420
00421 return USBRC_SUCCESS;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430 uint32_t AUDDStream_SetVolume(AUDDStream *pAuds,
00431 uint8_t bChannel,
00432 uint16_t wVolume)
00433 {
00434 if (pAuds->pwVolumes == 0)
00435 return USBRC_PARAM_ERR;
00436 if (bChannel > pAuds->bNumChannels)
00437 return USBRC_PARAM_ERR;
00438
00439 pAuds->pwVolumes[bChannel] = wVolume;
00440 if (pAuds->fCallback) {
00441 pAuds->fCallback(AUDD_EC_VolumeChanged,
00442 bChannel,
00443 pAuds->pArg);
00444 }
00445
00446 return USBRC_SUCCESS;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 uint32_t AUDDStream_Read(
00462 AUDDStream *pAuds,
00463 void * pData,uint32_t dwSize,
00464 TransferCallback fCallback,void * pArg)
00465 {
00466 if (pAuds->bEndpointOut == 0)
00467 return USBRC_PARAM_ERR;
00468 return USBD_Read(pAuds->bEndpointOut,
00469 pData, dwSize,
00470 fCallback, pArg);
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 uint32_t AUDDStream_SetupWrite(
00486 AUDDStream *pAuds,
00487 void * pListInit,
00488 void * pDmaInit,
00489 uint16_t listSize,
00490 uint16_t delaySize,
00491 TransferCallback callback,
00492 void * argument)
00493 {
00494 uint32_t error;
00495
00496 pDmaInit = pDmaInit;
00497
00498 if (pAuds->bEndpointIn == 0)
00499 return USBRC_STATE_ERR;
00500
00501 error = USBD_HAL_SetupMblTransfer(pAuds->bEndpointIn,
00502 pListInit,
00503 listSize,
00504 delaySize);
00505 if (error) return error;
00506
00507 error = USBD_HAL_SetTransferCallback(pAuds->bEndpointIn,
00508 callback, argument);
00509 return error;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 uint32_t AUDDStream_Write(AUDDStream *pAuds, void* pBuffer, uint16_t wLength)
00522 {
00523 if (pAuds->bEndpointIn == 0)
00524 return USBRC_STATE_ERR;
00525
00526 return USBD_HAL_Write(pAuds->bEndpointIn,
00527 pBuffer, wLength);
00528 }
00529
00530
00531
00532
00533
00534 uint32_t AUDDStream_Close(AUDDStream *pStream)
00535 {
00536 uint32_t bmEPs = 0;
00537
00538
00539 if (pStream->bEndpointIn) {
00540 bmEPs |= 1 << pStream->bEndpointIn;
00541 }
00542
00543 if (pStream->bEndpointOut) {
00544 bmEPs |= 1 << pStream->bEndpointOut;
00545 }
00546 USBD_HAL_ResetEPs(bmEPs, USBRC_CANCELED, 1);
00547
00548 return USBRC_SUCCESS;
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 void AUDDSpeakerPhone_InitializeStream(
00567 AUDDStream *pAuds,
00568 uint8_t numChannels,
00569 uint16_t wChannelVolumes[],
00570 AUDDStreamEventCallback fCallback,
00571 void* pArg)
00572 {
00573 pAuds->bAcInterface = 0xFF;
00574 pAuds->bFeatureUnitOut = 0xFF;
00575 pAuds->bFeatureUnitIn = 0xFF;
00576 pAuds->bAsInterface = 0xFF;
00577 pAuds->bEndpointOut = 0;
00578 pAuds->bEndpointIn = 0;
00579
00580 pAuds->bNumChannels = numChannels;
00581 pAuds->bmMute = 0;
00582 pAuds->pwVolumes = wChannelVolumes;
00583
00584 pAuds->fCallback = fCallback;
00585 pAuds->pArg = pArg;
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595 void AUDDSpeakerPhone_Initialize(
00596 AUDDSpeakerPhone *pAudf,
00597 USBDDriver *pUsbd,
00598 AUDDStream *pSpeaker,
00599 AUDDStream *pMicrophone)
00600 {
00601 pAudf->pUsbd = pUsbd;
00602 pAudf->pSpeaker = pSpeaker;
00603 pAudf->pMicrophone = pMicrophone;
00604 }
00605
00606
00607
00608
00609
00610
00611
00612 USBGenericDescriptor *AUDDSpeakerPhone_ParseInterfaces(
00613 AUDDSpeakerPhone *pAudf,
00614 USBGenericDescriptor *pDescriptors,
00615 uint32_t dwLength)
00616 {
00617 AUDDParseData data;
00618
00619 data.pAudf = pAudf;
00620 data.pIfDesc = 0;
00621
00622 return USBGenericDescriptor_Parse(pDescriptors,
00623 dwLength,
00624 (USBDescriptorParseFunction)AUDDSpeakerPhone_Parse,
00625 (void*)&data);
00626 }
00627
00628
00629
00630
00631
00632
00633 uint32_t AUDDSpeakerPhone_CloseStream(
00634 AUDDSpeakerPhone *pAudf,
00635 uint32_t bInterface)
00636 {
00637 if (pAudf->pSpeaker->bAsInterface == bInterface) {
00638
00639
00640
00641 }
00642 else if (pAudf->pMicrophone->bAsInterface == bInterface) {
00643
00644
00645
00646 }
00647
00648 return USBRC_SUCCESS;
00649 }
00650
00651
00652
00653
00654
00655
00656
00657 uint32_t AUDDSpeakerPhone_RequestHandler(
00658 AUDDSpeakerPhone *pAudf,
00659 const USBGenericRequest* pRequest)
00660 {
00661
00662
00663 if (USBGenericRequest_GetType(pRequest) != USBGenericRequest_CLASS)
00664 return USBRC_PARAM_ERR;
00665
00666 TRACE_INFO_WP("Aud ");
00667 switch (USBGenericRequest_GetRequest(pRequest)) {
00668 case AUDGenericRequest_SETCUR:
00669 AUDD_SetCUR(pAudf, pRequest);
00670 break;
00671 case AUDGenericRequest_GETCUR:
00672 AUDD_GetCUR(pAudf, pRequest);
00673 break;
00674
00675 default:
00676 return USBRC_PARAM_ERR;
00677 }
00678
00679 return USBRC_SUCCESS;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 uint32_t AUDDSpeakerPhone_Read(
00695 AUDDSpeakerPhone *pAudf,
00696 void * pData,uint32_t dwSize,
00697 TransferCallback fCallback,void * pArg)
00698 {
00699 if (pAudf->pSpeaker == 0)
00700 return USBRC_PARAM_ERR;
00701 if (pAudf->pSpeaker->bEndpointOut == 0)
00702 return USBRC_PARAM_ERR;
00703 return USBD_Read(pAudf->pSpeaker->bEndpointOut,
00704 pData, dwSize,
00705 fCallback, pArg);
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 uint32_t AUDDSpeakerPhone_SetupWrite(
00721 AUDDSpeakerPhone *pAudf,
00722 void * pListInit,
00723 void * pDmaInit,
00724 uint16_t listSize,
00725 uint16_t delaySize,
00726 TransferCallback callback,
00727 void * argument)
00728 {
00729 uint32_t error;
00730
00731 pDmaInit = pDmaInit;
00732
00733 if (pAudf->pMicrophone == 0)
00734 return USBRC_PARAM_ERR;
00735 if (pAudf->pMicrophone->bEndpointIn == 0)
00736 return USBRC_STATE_ERR;
00737
00738 error = USBD_HAL_SetupMblTransfer(pAudf->pMicrophone->bEndpointIn,
00739 pListInit,
00740 listSize,
00741 delaySize);
00742 if (error) return error;
00743
00744 error = USBD_HAL_SetTransferCallback(
00745 pAudf->pMicrophone->bEndpointIn,
00746 callback, argument);
00747 return error;
00748 }
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 uint32_t AUDDSpeakerPhone_Write(AUDDSpeakerPhone *pAudf, void* pBuffer, uint16_t wLength)
00760 {
00761 if (pAudf->pSpeaker == 0)
00762 return USBRC_PARAM_ERR;
00763 if (pAudf->pSpeaker->bEndpointIn == 0)
00764 return USBRC_STATE_ERR;
00765
00766 return USBD_HAL_Write(pAudf->pSpeaker->bEndpointIn,
00767 pBuffer, wLength);
00768 }
00769
00770
00771