//***************************************************************************** // //! This function is used to release an instance of the CDC driver. //! //! \param pvInstance is an instance pointer that needs to be released. //! //! This function will free up any resources in use by the CDC driver instance //! that is passed in. The \e pvInstance pointer should be a valid value that //! was returned from a call to USBCDCOpen(). //! //! \return None. // //***************************************************************************** static void USBHCDCClose(void *pvInstance) { // // Do nothing if there is not a driver open. // if(g_USBHCDCDevice.psDevice == 0) { return; } // // Reset the device pointer. // g_USBHCDCDevice.psDevice = 0; // // Free the Bulk IN Interrupt pipe. // if(g_USBHCDCDevice.ui32IntInPipe != 0) { USBHCDPipeFree(g_USBHCDCDevice.ui32IntInPipe); } // // Free the Bulk IN pipe. // if(g_USBHCDCDevice.ui32BulkInPipe != 0) { USBHCDPipeFree(g_USBHCDCDevice.ui32BulkInPipe); } // // Free the Bulk OUT pipe. // if(g_USBHCDCDevice.ui32BulkOutPipe != 0) { USBHCDPipeFree(g_USBHCDCDevice.ui32BulkOutPipe); } // // If the callback exists then call it. // if(g_USBHCDCDevice.pfnCallback != 0) { //printf("USBHCDCClose: Callback Exists: Calling\n"); g_USBHCDCDevice.pfnCallback(&g_USBHCDCDevice, CDC_EVENT_CLOSE, 0, 0); } }
//***************************************************************************** // //! This function is used to release an instance of the HID driver. //! //! \param pvInstance is an instance pointer that needs to be released. //! //! This function will free up any resources in use by the HID driver instance //! that is passed in. The \e pvInstance pointer should be a valid value that //! was returned from a call to USBHIDOpen(). //! //! \return None. // //***************************************************************************** static void HIDDriverClose(void *pvInstance) { tHIDInstance *psInst; // // Get our instance pointer. // psInst = (tHIDInstance *)pvInstance; // // Reset the device pointer. // psInst->psDevice = 0; // // Free the Interrupt IN pipe. // if(psInst->ui32IntInPipe != 0) { USBHCDPipeFree(psInst->ui32IntInPipe); } // // If the callback exists, call it with a DISCONNECTED event. // if(psInst->pfnCallback != 0) { psInst->pfnCallback(psInst->pvCBData, USB_EVENT_DISCONNECTED, (uint32_t)pvInstance, 0); } }
//***************************************************************************** // //! This function is used to release an instance of the HID driver. //! //! \param pvInstance is an instance pointer that needs to be released. //! //! This function will free up any resources in use by the HID driver instance //! that is passed in. The \e pvInstance pointer should be a valid value that //! was returned from a call to USBHIDOpen(). //! //! \return None. // //***************************************************************************** static void HIDDriverClose(void *pvInstance) { // // No device so just exit. // if(g_HIDDevice.pDevice == 0) { return; } // // Reset the device pointer. // g_HIDDevice.pDevice = 0; // // Free the Interrupt IN pipe. // if(g_HIDDevice.ulIntInPipe != 0) { USBHCDPipeFree(g_HIDDevice.ulIntInPipe); } // // If the callback exists, call it with an Open event. // if(g_HIDDevice.pfnCallback != 0) { g_HIDDevice.pfnCallback((void *)g_HIDDevice.ulCBData, USB_EVENT_DISCONNECTED, (unsigned long)&g_HIDDevice, 0); } }
//***************************************************************************** // //! This function is used to release an instance of the MSC driver. //! //! \param pvInstance is an instance pointer that needs to be released. //! //! This function will free up any resources in use by the MSC driver instance //! that is passed in. The \e pvInstance pointer should be a valid value that //! was returned from a call to USBMSCOpen(). //! //! \return None. // //***************************************************************************** static void USBHMSCClose(void *pvInstance) { tUSBHMSCInstance *sUSBHMSCDevice; sUSBHMSCDevice = (tUSBHMSCInstance *)pvInstance; // // Do nothing if there is not a driver open. // if(sUSBHMSCDevice->pDevice == 0) { return; } // // Reset the device pointer. // sUSBHMSCDevice->pDevice = 0; // // Free the Bulk IN pipe. // if(sUSBHMSCDevice->ulBulkInPipe != 0) { USBHCDPipeFree(sUSBHMSCDevice->ulIndex, sUSBHMSCDevice->ulBulkInPipe); } // // Free the Bulk OUT pipe. // if(sUSBHMSCDevice->ulBulkOutPipe != 0) { USBHCDPipeFree(sUSBHMSCDevice->ulIndex, sUSBHMSCDevice->ulBulkOutPipe); } // // If the callback exists then call it. // if(sUSBHMSCDevice->pfnCallback != 0) { sUSBHMSCDevice->pfnCallback((unsigned int)sUSBHMSCDevice, MSC_EVENT_CLOSE, 0); } }
//***************************************************************************** // //! This function is used to release an instance of the ANDROID driver. //! //! \param pvInstance is an instance pointer that needs to be released. //! //! This function will free up any resources in use by the ANDROID driver instance //! that is passed in. The \e pvInstance pointer should be a valid value that //! was returned from a call to USBHANDROIDOpen(). //! //! \return None. // //***************************************************************************** static void USBHANDROIDClose(void *pvInstance) { UARTprintf("Start USBHANDROIDClose Time=%d\n", g_ulSysTickCount); // Do nothing if there is not a driver open. if(g_USBHANDROIDDevice.pDevice == 0) { return; } // Set Flag isConnected g_USBHANDROIDDevice.connected = false; // Reset the device pointer. g_USBHANDROIDDevice.pDevice = 0; // Free the Bulk IN pipe. if(g_USBHANDROIDDevice.ulBulkInPipe != 0) { UARTprintf("Endpoint Bulk In Free USB Pipe 0x%08X\n", g_USBHANDROIDDevice.ulBulkInPipe); USBHCDPipeFree(g_USBHANDROIDDevice.ulBulkInPipe); } // Free the Bulk OUT pipe. if(g_USBHANDROIDDevice.ulBulkOutPipe != 0) { UARTprintf("Endpoint Bulk OUT Free USB Pipe 0x%08X\n", g_USBHANDROIDDevice.ulBulkOutPipe); USBHCDPipeFree(g_USBHANDROIDDevice.ulBulkOutPipe); } // If the callback exists then call it. if(g_USBHANDROIDDevice.pfnCallback != 0) { g_USBHANDROIDDevice.pfnCallback((t_u32)&g_USBHANDROIDDevice, ANDROID_EVENT_CLOSE, 0); } // Clear the callback indicating that the device is now closed. g_USBHANDROIDDevice.pfnCallback = 0; UARTprintf("End USBHANDROIDClose Time=%d\n", g_ulSysTickCount); }
//***************************************************************************** // //! This function is used to release an instance of the MSC driver. //! //! \param pvInstance is an instance pointer that needs to be released. //! //! This function will free up any resources in use by the MSC driver instance //! that is passed in. The \e pvInstance pointer should be a valid value that //! was returned from a call to USBMSCOpen(). //! //! \return None. // //***************************************************************************** static void USBHMSCClose(void *pvInstance) { // // Do nothing if there is not a driver open. // if(g_USBHMSCDevice.pDevice == 0) { return; } // // Reset the device pointer. // g_USBHMSCDevice.pDevice = 0; // // Free the Bulk IN pipe. // if(g_USBHMSCDevice.ulBulkInPipe != 0) { USBHCDPipeFree(g_USBHMSCDevice.ulBulkInPipe); } // // Free the Bulk OUT pipe. // if(g_USBHMSCDevice.ulBulkOutPipe != 0) { USBHCDPipeFree(g_USBHMSCDevice.ulBulkOutPipe); } // // If the callback exists then call it. // if(g_USBHMSCDevice.pfnCallback != 0) { g_USBHMSCDevice.pfnCallback((unsigned long)&g_USBHMSCDevice, MSC_EVENT_CLOSE, 0); } }
//***************************************************************************** // // Close an instance of the hub driver. // //***************************************************************************** static void HubDriverClose(void *pvHubDevice) { uint32_t ui32Loop; // // No device so just exit. // if(g_sRootHub.psDevice == 0) { return; } // // Disconnect any devices that are currently connected to the hub. // for(ui32Loop = 0; ui32Loop < MAX_USB_DEVICES; ui32Loop++) { // // Does this port have a device connected to it that we have previously // reported to the host control layer?h // if((g_sRootHub.psPorts[ui32Loop].iState == ePortActive) || (g_sRootHub.psPorts[ui32Loop].iState == ePortResetWait) || (g_sRootHub.psPorts[ui32Loop].iState == ePortEnumerated) || (g_sRootHub.psPorts[ui32Loop].iState == ePortError)) { // // Yes - tell the host controller to disconnect the device. // USBHCDHubDeviceDisconnected(0, g_sRootHub.psPorts[ui32Loop].ui32DevHandle); } // // Make sure that the state returns to idle. // g_sRootHub.psPorts[ui32Loop].iState = ePortIdle; } // // Reset the device pointer. // g_sRootHub.psDevice = 0; // // Mark the hub as absent. // g_sRootHub.ui32Flags &= ~USBLIB_HUB_ACTIVE; // // Note that we are not in the middle of enumerating anything. // g_sRootHub.bEnumerationBusy = false; // // Free the Interrupt IN pipe. // if(g_sRootHub.ui32IntInPipe != 0) { USBHCDPipeFree(g_sRootHub.ui32IntInPipe); } // // If the callback exists, call it with a DISCONNECTED event. // if(g_sRootHub.pfnCallback != 0) { g_sRootHub.pfnCallback((void *)g_sRootHub.ui32CBData, USB_EVENT_DISCONNECTED, (uint32_t)&g_sRootHub, 0); } }
//***************************************************************************** // // Open an instance of the hub driver. This is called when the USB host // has enumerated a new hub device. // //***************************************************************************** static void * HubDriverOpen(tUSBHostDevice *psDevice) { tEndpointDescriptor *psEndpointDescriptor; tInterfaceDescriptor *psInterface; tUsbHubDescriptor sHubDesc; bool bRetcode; uint32_t ui32Loop; // // If we are already talking to a hub, fail the call. We only support // a single hub. // if(g_sRootHub.ui32Flags & USBLIB_HUB_ACTIVE) { return(0); } // // Get pointers to the device descriptors we need to look at. // psInterface = USBDescGetInterface(psDevice->psConfigDescriptor, 0, 0); psEndpointDescriptor = USBDescGetInterfaceEndpoint(psInterface, 0, psDevice->ui32ConfigDescriptorSize); // // If there are no endpoints, something is wrong since a hub must have // a single INT endpoint for signaling. // if(psEndpointDescriptor == 0) { return 0; } // // Make sure we really are talking to a hub. // if((psInterface->bInterfaceClass != USB_CLASS_HUB) || (psInterface->bInterfaceSubClass != 0)) { // // Something is wrong - this isn't a hub or, if it is, we don't // understand the protocol it is using. // return(0); } // // Remember that this is a high speed hub with either single or multiple // transaction translators. // if(psInterface->bInterfaceProtocol == USB_HUB_PROTOCOL_SINGLE) { g_sRootHub.ui32Flags |= USBLIB_HUB_HS; } else if(psInterface->bInterfaceProtocol == USB_HUB_PROTOCOL_MULTI) { g_sRootHub.ui32Flags |= USBLIB_HUB_HS | USBLIB_HUB_MULTI_TT; } // // Remember the device information for later. // g_sRootHub.psDevice = psDevice; // // A hub must support an interrupt endpoint so check this. // if((psEndpointDescriptor->bmAttributes & USB_EP_ATTR_TYPE_M) == USB_EP_ATTR_INT) { // // The endpoint is the correct type. Is it an IN endpoint? // if(psEndpointDescriptor->bEndpointAddress & USB_EP_DESC_IN) { // // Yes - all is well with the hub endpoint so allocate a pipe to // handle traffic from the hub. // g_sRootHub.ui32IntInPipe = USBHCDPipeAlloc(0, USBHCD_PIPE_INTR_IN, psDevice, HubIntINCallback); USBHCDPipeConfig(g_sRootHub.ui32IntInPipe, psEndpointDescriptor->wMaxPacketSize, psEndpointDescriptor->bInterval, psEndpointDescriptor->bEndpointAddress & USB_EP_DESC_NUM_M); } } // // Did we allocate the endpoint successfully? // if(!g_sRootHub.ui32IntInPipe) { // // No - return an error. // return 0; } // // Assuming we have a callback, call it to tell the owner that a hub is // now connected. // if(g_sRootHub.pfnCallback != 0) { g_sRootHub.pfnCallback((void *)g_sRootHub.ui32CBData, USB_EVENT_CONNECTED, (uint32_t)&g_sRootHub, 0); } // // Get the hub descriptor and store information we'll need for later. // bRetcode = GetHubDescriptor(&sHubDesc); if(bRetcode) { // // We read the descriptor successfully so extract the parts we need. // g_sRootHub.ui8NumPorts = sHubDesc.bNbrPorts; g_sRootHub.ui16HubCharacteristics = sHubDesc.wHubCharacteristics; g_sRootHub.ui8NumPortsInUse = (sHubDesc.bNbrPorts > MAX_USB_DEVICES) ? MAX_USB_DEVICES : sHubDesc.bNbrPorts; // // The size of the status change report that the hub sends is dependent // upon the number of ports that the hub supports. Calculate this by // adding 1 to the number of ports (bit 0 of the report is the hub // status, higher bits are one per port) then dividing by 8 (bits per // byte) and rounding up. // g_sRootHub.ui8ReportSize = ((sHubDesc.bNbrPorts + 1) + 7) / 8; // // Enable power to all ports on the hub. // for(ui32Loop = 1; ui32Loop <= sHubDesc.bNbrPorts; ui32Loop++) { // // Turn on power to this port. // HubSetPortFeature(&g_sRootHub, ui32Loop, HUB_FEATURE_PORT_POWER); } // // Clear out our port state structures. // for(ui32Loop = 0; ui32Loop < MAX_USB_DEVICES; ui32Loop++) { g_sRootHub.psPorts[ui32Loop].bChanged = false; g_sRootHub.psPorts[ui32Loop].iState = ePortIdle; } } else { // // Oops - we can't read the hub descriptor! Tidy up and return // an error. // USBHCDPipeFree(g_sRootHub.ui32IntInPipe); g_sRootHub.pfnCallback = 0; g_sRootHub.ui32Flags &= ~USBLIB_HUB_ACTIVE; return(0); } // // If we get here, all is well so remember that the hub is connected and // active. // g_sRootHub.ui32Flags |= USBLIB_HUB_ACTIVE; // // Return our instance data pointer to the caller to use as a handle. // return((void *)&g_sRootHub); }