/* Function: void _USB_DEVICE_AUDIO_SetupPacketHandler ( USB_DEVICE_AUDIO_INDEX iAudio , USB_SETUP_PACKET * setupPkt ) Summary: Handles a fresh SETUP packet received from Host. Description: Handles a fresh SETUP packet received from Host. Returns: This is a local function and should not be called directly by the application. */ void _USB_DEVICE_AUDIO_SetupPacketHandler ( USB_DEVICE_AUDIO_INDEX iAudio , USB_SETUP_PACKET * setupPkt ) { uint8_t audioControlInterfaceId; uint8_t interfaceId; uint8_t curAlternateSetting; uint8_t prevAlternateSetting; uint8_t streamIntfcIndex; uint8_t noOfEndpoints; USB_ENDPOINT ep; uint16_t maxPacketSize; USB_DEVICE_HANDLE usbDeviceHandle; USB_DEVICE_AUDIO_EVENT event; USB_DEVICE_AUDIO_EVENT_DATA_INTERFACE_SETTING_CHANGED interfaceInfo; USB_ERROR endpointEnableResult; USB_DEVICE_AUDIO_STREAMING_INTERFACE_ALTERNATE_SETTING *pCurAlternateStng; USB_DEVICE_AUDIO_STREAMING_INTERFACE_ALTERNATE_SETTING *pPrevAlternateStng; USB_DEVICE_AUDIO_STREAMING_INTERFACE *pStreamingInterface; uint16_t adjustedMaxPacketSize =1; /* Obtain pointer to the Audio Instance that is being addressed*/ USB_DEVICE_AUDIO_INSTANCE* audioInstance = &gUsbDeviceAudioInstance[iAudio]; /* Obtain pointer to the Audio Interface collection*/ USB_DEVICE_AUDIO_INTERFACE_COLLECTION *curInfCollection = &(audioInstance->infCollection); /* Get the Device Layer handle */ usbDeviceHandle = gUsbDeviceAudioInstance[iAudio].devLayerHandle; /* Check if the request is a standard interface request*/ if ( (setupPkt->RequestType == USB_SETUP_REQUEST_TYPE_STANDARD) && (setupPkt->Recipient == USB_SETUP_REQUEST_RECIPIENT_INTERFACE)) { /* We have received Standard Set request */ /* retrieve interface number from the Setup packet */ interfaceId = setupPkt->bIntfID; /* retrieve audio Control interface number*/ audioControlInterfaceId = curInfCollection->bControlInterfaceNum; switch(setupPkt->bRequest) { case USB_REQUEST_SET_INTERFACE: curAlternateSetting = setupPkt->bAltID; if (interfaceId == audioControlInterfaceId) { /*SET INTERFACE command was received to Audio Control Interface */ curInfCollection->bControlAltSetng = curAlternateSetting; } else { /*An Audio Streaming interface has received SET INTERFACE command */ streamIntfcIndex = interfaceId - audioControlInterfaceId - 1; /* Get pointer to the current audio streaming interface */ pStreamingInterface = &(curInfCollection->streamInf[streamIntfcIndex]); /* Get pointer to the Interface Alternate setting. */ pCurAlternateStng = &(pStreamingInterface->alterntSetting[curAlternateSetting]); /* Find out how many endpoint are present for this Interface * Alternate setting */ noOfEndpoints = pCurAlternateStng->numEndPoints; if ((noOfEndpoints) && (curAlternateSetting)) { /* We have to enable the endpoint only if this alternate setting has at least one endpoint and the alternate setting is a non zero value */ /*Retrieve endpoint size */ ep = pCurAlternateStng->isoDataEp.epAddr; /* retrieve max packet size. */ maxPacketSize = pCurAlternateStng->isoDataEp.epMaxPacketSize; /* maxpacket size should be adjusted to upper power of two. As per the PIC32MZ USB module requirement.*/ if (maxPacketSize) { while(adjustedMaxPacketSize < maxPacketSize) adjustedMaxPacketSize <<= 1; } else adjustedMaxPacketSize = 0; /* Enable Isochronous Data Endpoint */ endpointEnableResult = USB_DEVICE_EndpointEnable ( usbDeviceHandle , 0, ep , USB_TRANSFER_TYPE_ISOCHRONOUS , adjustedMaxPacketSize ); if (endpointEnableResult != USB_ERROR_NONE) { SYS_ASSERT (false, "Endpoint not Enabled"); } if (noOfEndpoints == 2) { /* If number of Endpoints is Two, then it is sure * that this alternate setting reports a Isochronous * Sync Endpoint. Enable the Sync Endpoint. */ } //Change Audio Instance object state to Initialized. pStreamingInterface->state = USB_DEVICE_AUDIO_STRMNG_INTFC_INITIALIZED; } else //alternateSetting = 0 { if (pStreamingInterface->state == USB_DEVICE_AUDIO_STRMNG_INTFC_INITIALIZED) { //Disable the Endpoint in the previous Active Alternate setting. prevAlternateSetting = pStreamingInterface->activeSetting; //get a pointer to the previous alternate setting. pPrevAlternateStng = &(pStreamingInterface->alterntSetting[prevAlternateSetting]); //Get endpoint no of the previous alternate setting ep = pPrevAlternateStng->isoDataEp.epAddr; //Disable the Endpoint USB_DEVICE_EndpointDisable(usbDeviceHandle ,ep); if (noOfEndpoints == 2) { /* If number of Endpoints is Two, then it is sure * that this alternate setting reports a Isochronous * Sync Endpoint. Disable the Sync Endpoint. */ } curInfCollection->streamInf[streamIntfcIndex].state = USB_DEVICE_AUDIO_STRMNG_INTFC_NOT_INITIALIZED; USB_DEVICE_IRPCancelAll(usbDeviceHandle, ep); } } /* Remember the new alternate setting received */ curInfCollection->streamInf[streamIntfcIndex].activeSetting = curAlternateSetting; /* Notify application about the SET_INTERFACE request */ interfaceInfo.interfaceNumber = interfaceId; interfaceInfo.interfaceAlternateSetting = curAlternateSetting; audioInstance->appEventCallBack ( iAudio, USB_DEVICE_AUDIO_EVENT_INTERFACE_SETTING_CHANGED, &interfaceInfo, 0 ); } /* Send an Acknowledgement to the Host */ USB_DEVICE_ControlStatus( usbDeviceHandle, USB_DEVICE_CONTROL_STATUS_OK); break; case USB_REQUEST_GET_INTERFACE: if (interfaceId == audioControlInterfaceId) { curAlternateSetting = curInfCollection->bControlAltSetng; } else { streamIntfcIndex = interfaceId - audioControlInterfaceId - 1; curAlternateSetting = curInfCollection->streamInf[streamIntfcIndex].activeSetting; } USB_DEVICE_ControlSend( usbDeviceHandle, (void *)&curAlternateSetting, 1); break; default: break; } }//end of if((setupPkt->bmRequestType == else if ( (setupPkt->RequestType == USB_SETUP_REQUEST_TYPE_CLASS ) && (setupPkt->Recipient == USB_SETUP_REQUEST_RECIPIENT_INTERFACE)) { /* We have recived a Audio Class specific Interface request */ switch (setupPkt->bRequest) { case USB_AUDIO_CS_SET_CUR: event = USB_DEVICE_AUDIO_EVENT_CONTROL_SET_CUR; break; case USB_AUDIO_CS_GET_CUR: event = USB_DEVICE_AUDIO_EVENT_CONTROL_GET_CUR; break; case USB_AUDIO_CS_SET_MIN: event = USB_DEVICE_AUDIO_EVENT_CONTROL_SET_MIN; break; case USB_AUDIO_CS_GET_MIN: event = USB_DEVICE_AUDIO_EVENT_CONTROL_GET_MIN; break; case USB_AUDIO_CS_SET_MAX: event = USB_DEVICE_AUDIO_EVENT_CONTROL_SET_MAX; break; case USB_AUDIO_CS_GET_MAX: event = USB_DEVICE_AUDIO_EVENT_CONTROL_GET_MAX; break; case USB_AUDIO_CS_SET_RES: event = USB_DEVICE_AUDIO_EVENT_CONTROL_SET_RES; break; case USB_AUDIO_CS_GET_RES: event = USB_DEVICE_AUDIO_EVENT_CONTROL_GET_RES; break; case USB_AUDIO_CS_SET_MEM: event = USB_DEVICE_AUDIO_EVENT_ENTITY_SET_MEM; break; case USB_AUDIO_CS_GET_MEM: event = USB_DEVICE_AUDIO_EVENT_ENTITY_GET_MEM; break; case USB_AUDIO_CS_GET_STAT: event = USB_DEVICE_AUDIO_EVENT_ENTITY_GET_STAT; break; default: /* Unknown request. Stall the request */ event = 0; USB_DEVICE_ControlStatus(audioInstance->devLayerHandle, USB_DEVICE_CONTROL_STATUS_ERROR); } if (( audioInstance->appEventCallBack) && (event)) { /* inform the application about the request */ /* the application needs to handle both EP and entity specific requests */ audioInstance->appEventCallBack ( iAudio, event, setupPkt, 0); } }// end of else if }//end of function _USB_DEVICE_AUDIO_SetupPacketHandler
void _USB_DEVICE_CDC_Initialization ( SYS_MODULE_INDEX iCDC , USB_DEVICE_HANDLE deviceHandle , void* initData , uint8_t infNum , uint8_t altSetting , uint8_t descType , uint8_t * pDesc ) { /* Avoid unused warning */ ( void ) ( altSetting ); ( void ) ( initData ); uint8_t epAddress; uint8_t epDir; uint16_t maxPacketSize; USB_DEVICE_CDC_INSTANCE * thisCDCInstance; USB_DEVICE_CDC_INIT * cdcInit; USB_ENDPOINT_DESCRIPTOR *pEPDesc; USB_INTERFACE_DESCRIPTOR *pInfDesc; USB_DEVICE_CDC_ENDPOINT * deviceCDCEndpoint; /* Check the validity of the function driver index */ if (iCDC >= USB_DEVICE_CDC_INSTANCES_NUMBER) { /* Assert on invalid CDC index */ SYS_DEBUG(0, "USB Device CDC: Invalid index"); return; } thisCDCInstance = &gUSBDeviceCDCInstance[iCDC]; /* Initialize the queue sizes. This code may run several times * but then we dont expect the queue sizes to change.*/ cdcInit = ((USB_DEVICE_CDC_INIT *)initData); thisCDCInstance->queueSizeWrite = cdcInit->queueSizeWrite; thisCDCInstance->queueSizeRead = cdcInit->queueSizeRead; thisCDCInstance->queueSizeSerialStateNotification = cdcInit->queueSizeSerialStateNotification; thisCDCInstance->currentQSizeWrite = 0; thisCDCInstance->currentQSizeRead = 0; thisCDCInstance->currentQSizeSerialStateNotification = 0; /* check the type of descriptor passed by device layer */ switch ( descType ) { /* Interface descriptor passed */ case USB_DESCRIPTOR_INTERFACE: { pInfDesc = ( USB_INTERFACE_DESCRIPTOR * )pDesc; /* Preserve the device layer handle */ thisCDCInstance->deviceHandle = deviceHandle; /* check if this is notification(communication) interface */ if ( ( pInfDesc->bInterfaceClass == USB_CDC_COMMUNICATIONS_INTERFACE_CLASS_CODE ) && ( pInfDesc->bInterfaceSubClass == USB_CDC_SUBCLASS_ABSTRACT_CONTROL_MODEL ) ) { /* Save the notification interface number */ thisCDCInstance->notificationInterface.interfaceNum = infNum; } /* data interface */ else if ( ( pInfDesc->bInterfaceClass == USB_CDC_DATA_INTERFACE_CLASS_CODE ) ) { /* save the data interface number */ thisCDCInstance->dataInterface.interfaceNum = infNum; } else { /* Ignore anything else */ SYS_DEBUG(0, "USB Device CDC: Invalid interface presented to CDC " ); } break; } /* Endpoint descriptor passed */ case USB_DESCRIPTOR_ENDPOINT: { pEPDesc = ( USB_ENDPOINT_DESCRIPTOR* ) pDesc; /* Save the ep address */ epAddress = pEPDesc->bEndpointAddress; /* Get the direction */ epDir = ( epAddress & 0x80 ) ? ( USB_DEVICE_CDC_ENDPOINT_TX ) : ( USB_DEVICE_CDC_ENDPOINT_RX ); /* Save max packet size */ maxPacketSize = ( ( USB_ENDPOINT_DESCRIPTOR* ) pDesc )->wMaxPacketSize; if ( pEPDesc->transferType == USB_TRANSFER_TYPE_BULK ) { /* This is a data interface endpoint */ deviceCDCEndpoint = &thisCDCInstance->dataInterface.endpoint[epDir]; } else if( pEPDesc->transferType == USB_TRANSFER_TYPE_INTERRUPT) { /* This is notification endpoint */ deviceCDCEndpoint = &thisCDCInstance->notificationInterface.endpoint[epDir]; } else { /* We cannot support ny other type of endpoint for now */ SYS_DEBUG(0, "USB Device CDC: Cannot handle this endpoint type" ); break; } /* Save ep address to the data interface */ deviceCDCEndpoint->address = epAddress; /* Save max packet size to the data interface */ deviceCDCEndpoint->maxPacketSize = maxPacketSize; /* Enable the endpoint */ USB_DEVICE_EndpointEnable ( deviceHandle , 0, epAddress , pEPDesc->transferType , maxPacketSize ); /* Indicate that the endpoint is configured */ deviceCDCEndpoint->isConfigured = true; break; } case USB_CDC_DESC_CS_INTERFACE: { break; } default: /* Unsupported descriptor type */ break; } }
void APP_USBDeviceEventHandler ( USB_DEVICE_EVENT event, void * eventData, uintptr_t context ) { USB_DEVICE_EVENT_DATA_CONFIGURED* configuredEventData; switch(event) { case USB_DEVICE_EVENT_RESET: U1TXREG = 'R'; //break; case USB_DEVICE_EVENT_DECONFIGURED: { appData.state = APP_STATE_USB_OPENED; appData.reading = 0; appData.audio_play = false; USB_DEVICE_EndpointDisable(appData.usbDevHandle, AUDIO_EP); if(appData.tunnel_write_handle != USB_DEVICE_TRANSFER_HANDLE_INVALID) USB_DEVICE_EndpointTransferCancel(appData.usbDevHandle, TUNNEL_EP_IN, appData.tunnel_write_handle); USB_DEVICE_EndpointDisable(appData.usbDevHandle, TUNNEL_EP_IN); USB_DEVICE_EndpointDisable(appData.usbDevHandle, TUNNEL_EP_OUT); break; } case USB_DEVICE_EVENT_CONFIGURED: U1TXREG = '+'; /* check the configuration */ configuredEventData = (USB_DEVICE_EVENT_DATA_CONFIGURED *)eventData; if(configuredEventData->configurationValue == 1) { } USB_DEVICE_EndpointEnable(appData.usbDevHandle, AUDIO_STREAMING_INTERFACE_ID, AUDIO_EP, USB_TRANSFER_TYPE_ISOCHRONOUS, PACKET_SIZE); USB_DEVICE_EndpointEnable(appData.usbDevHandle, TUNER_CONTROL_INTERFACE_ID, TUNNEL_EP_IN, USB_TRANSFER_TYPE_BULK, 32); USB_DEVICE_EndpointEnable(appData.usbDevHandle, TUNER_CONTROL_INTERFACE_ID, TUNNEL_EP_OUT, USB_TRANSFER_TYPE_BULK, 32); appData.state = APP_STATE_CONFIGURED; break; case USB_DEVICE_EVENT_SUSPENDED: U1TXREG = 'S'; //appData.suspended = true; break; case USB_DEVICE_EVENT_RESUMED: U1TXREG = 's'; appData.suspended = false; break; case USB_DEVICE_EVENT_POWER_DETECTED: #ifndef NO_USB_ATTACH USB_DEVICE_Attach (appData.usbDevHandle); #else #warning "USB ATTACH DISABLED" #endif break; case USB_DEVICE_EVENT_POWER_REMOVED: USB_DEVICE_Detach (appData.usbDevHandle); break; case USB_DEVICE_EVENT_ERROR: U1TXREG = 'E'; break; case USB_DEVICE_EVENT_CONTROL_TRANSFER_SETUP_REQUEST: { USB_SETUP_PACKET * sp = eventData; if(sp->bRequest == 0x0b && sp->wIndex == 0x0001) //set interace on if 1 { //USB_DEVICE_ControlReceive(appData.usbDevHandle, &controlData, sizeof(controlData)); if(sp->wValue == 0) { int i; appData.audio_play = false; USB_DEVICE_ControlStatus(appData.usbDevHandle, USB_DEVICE_CONTROL_STATUS_OK); U1TXREG = 'C'; } else if(sp->wValue == 1) { appData.audio_play = true; USB_DEVICE_ControlStatus(appData.usbDevHandle, USB_DEVICE_CONTROL_STATUS_OK); appData.noAudioData = 1; U1TXREG = 'p'; } else USB_DEVICE_ControlStatus(appData.usbDevHandle, USB_DEVICE_CONTROL_STATUS_ERROR); } else USB_DEVICE_ControlStatus(appData.usbDevHandle, USB_DEVICE_CONTROL_STATUS_ERROR); break; } case USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_RECEIVED: case USB_DEVICE_EVENT_CONTROL_TRANSFER_ABORTED: case USB_DEVICE_EVENT_CONTROL_TRANSFER_DATA_SENT: //debughalt(); break; case USB_DEVICE_EVENT_ENDPOINT_READ_COMPLETE: { appData.tunnel_read_count = ((USB_DEVICE_EVENT_DATA_ENDPOINT_WRITE_COMPLETE*)eventData)->length; if(appData.tunnel_read_data[0]&TUNNEL_PING_MASK) appData.pingRequest = 1; else appData.tuner_request = 1; //appData.reading = 0; U1TXREG = 'I'; break; } case USB_DEVICE_EVENT_ENDPOINT_WRITE_COMPLETE: { USB_DEVICE_EVENT_DATA_ENDPOINT_WRITE_COMPLETE* ed = (USB_DEVICE_EVENT_DATA_ENDPOINT_WRITE_COMPLETE*)eventData; if(appData.tunnel_write_handle == ed->transferHandle) { appData.tunnel_write_handle = USB_DEVICE_TRANSFER_HANDLE_INVALID; U1TXREG = 'W'; } else { int i=0; for(;i<AUDIO_HANDLES;i++) if(ed->transferHandle == audio_handle[i]) audio_handle[i] = HANDLE_INVALID; } break; } default: debughalt(); break; } }