//***************************************************************************** // // usbhSPECIFIC.c - This file contains the host SPECIFIC driver. // // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // // This is part of AM1808 StarterWare USB Library, resused from revision 6288 of the // stellaris USB Library // //***************************************************************************** #include "usbhspecific.h" extern tUSBHCD g_sUSBHCD[]; static void * SPECIFICDriverOpen(tUSBHostDevice *pDevice, unsigned int ulDeviceInst); static void SPECIFICDriverClose(void *pvInstance); //***************************************************************************** // //! \addtogroup usblib_host_class //! @{ // //***************************************************************************** //***************************************************************************** // // The instance data storage for attached SPECIFIC devices. // //***************************************************************************** tSPECIFICInstance g_SPECIFICDevice[] = { { false, 0, 0, 0, USBH_SPECIFIC_DEV_NONE, 0, 0, 0, 0 }, { false, 0, 0, 0, USBH_SPECIFIC_DEV_NONE, 0, 0, 0, 1 } }; tSPECIFICInstance g_SPECIFICInstance = { false, 0, 0, 0, USBH_SPECIFIC_DEV_NONE, 0, 0, 0, 0 }; //***************************************************************************** // //! This constant global structure defines the SPECIFIC Class Driver that is //! provided with the USB library. // //***************************************************************************** const tUSBHostClassDriver g_USBSPECIFICClassDriver = { USB_CLASS_CDC, SPECIFICDriverOpen, SPECIFICDriverClose, 0 }; //***************************************************************************** // //! This function is used to open an instance of a SPECIFIC device. //! //! \param eDeviceType is the type of device that should be loaded for this //! instance of the SPECIFIC device. //! \param pfnCallback is the function that will be called whenever changes //! are detected for this device. //! \param ulCBData is the data that will be returned in when the pfnCallback //! function is called. //! //! This function creates an instance of an specific type of SPECIFIC device. The //! \e eDeviceType parameter is one subclass/protocol values of the types //! specified in enumerated types tSPECIFICSubClassProtocol. Only devices that //! enumerate with this type will be called back via the \e pfnCallback //! function. The \e pfnCallback parameter is the callback function for any //! events that occur for this device type. The \e pfnCallback function must //! point to a valid function of type \e tUSBCallback for this call to complete //! successfully. To release this device instance the caller of USBHSPECIFICOpen() //! should call USBHSPECIFICClose() and pass in the value returned from the //! USBHSPECIFICOpen() call. //! //! \return This function returns and instance value that should be used with //! any other APIs that require an instance value. If a value of 0 is returned //! then the device instance could not be created. // //***************************************************************************** unsigned int USBHSPECIFICOpen(unsigned int ulIndex,tSPECIFICSubClassProtocol eDeviceType, tUSBCallback pfnCallback, unsigned int ulCBData) { // // Only one callback is supported. // if(g_SPECIFICDevice[ulIndex].pfnCallback) { return (0); } // // Save the instance data for this device. // g_SPECIFICDevice[ulIndex].ulIndex = ulIndex; g_SPECIFICDevice[ulIndex].pfnCallback = pfnCallback; g_SPECIFICDevice[ulIndex].eDeviceType = eDeviceType; g_SPECIFICDevice[ulIndex].ulCBData = ulCBData; // // Return the device instance pointer. // return((unsigned int)&g_SPECIFICDevice[ulIndex]); } //***************************************************************************** // //! This function is used to release an instance of a SPECIFIC device. //! //! \param ulSPECIFICInstance is the instance value for a SPECIFIC device to release. //! //! This function releases an instance of a SPECIFIC device that was created by a //! call to USBHSPECIFICOpen(). This call is required to allow other SPECIFIC devices //! to be enumerated after another SPECIFIC device has been disconnected. The //! \e ulSPECIFICInstance parameter should hold the value that was returned from the //! previous call to USBHSPECIFICOpen(). //! //! \return None. // //***************************************************************************** void USBHSPECIFICClose(unsigned int ulSPECIFICInstance) { tSPECIFICInstance *pSPECIFICInstance; pSPECIFICInstance = (tSPECIFICInstance *)ulSPECIFICInstance; // // Disable any more notification from the SPECIFIC layer. // pSPECIFICInstance->pfnCallback = 0; pSPECIFICInstance->eDeviceType = USBH_SPECIFIC_DEV_NONE; } //***************************************************************************** // // This function handles callbacks for the interrupt IN endpoint. // //***************************************************************************** #include #include "tr_queue.h" unsigned char pucBuffer[64]; static void SPECIFICIntINCallback(unsigned int ulIndex, unsigned int ulPipe, unsigned int ulEvent) { switch (ulEvent) { // // Handles a request to schedule a new request on the interrupt IN // pipe. // case USB_EVENT_SCHEDULER: { USBHCDPipeSchedule(ulIndex, ulPipe, 0, 1); break; } // // Called when new data is available on the interrupt IN pipe. // case USB_EVENT_RX_AVAILABLE: { // // Send the report data to the USB host SPECIFIC device class driver. // unsigned int ulSize = USBHCDPipeReadNonBlocking(ulIndex, ulPipe, pucBuffer, 64); if(enqueueFromUsb(pucBuffer, ulSize)){ // printf(",添加到队列"); } break; } } } unsigned int USBHSPECIFICWrite(unsigned char *pucData, unsigned int ulSize) { return USBHCDPipeWrite(g_SPECIFICInstance.ulIndex, g_SPECIFICInstance.ulBulkOutPipe, pucData, ulSize); } //***************************************************************************** // //! This function is used to open an instance of the SPECIFIC driver. //! //! \param pDevice is a pointer to the device information structure. //! //! This function will attempt to open an instance of the SPECIFIC driver based on //! the information contained in the pDevice structure. This call can fail if //! there are not sufficient resources to open the device. The function will //! return a value that should be passed back into USBSPECIFICClose() when the //! driver is no longer needed. //! //! \return The function will return a pointer to a SPECIFIC driver instance. // //***************************************************************************** #include unsigned char DataBuffer1[64] = {'\0'}; static void * SPECIFICDriverOpen(tUSBHostDevice *pDevice, unsigned int ulInstance) { printf("SPECIFICDriverOpen...\r\n"); unsigned int ulIndex = 0; // 端点2,中断,IN // g_SPECIFICInstance.ulIntInPipe = USBHCDPipeAlloc(ulIndex, USBHCD_PIPE_INTR_IN, 0x01, SPECIFICIntINCallback); // USBHCDPipeConfig(ulIndex, g_SPECIFICInstance.ulIntInPipe, 0x0A, 0xff, (0x82 & USB_EP_DESC_NUM_M)); // 端点1,批量,IN g_SPECIFICInstance.ulBulkInPipe = USBHCDPipeAllocSize(ulIndex, USBHCD_PIPE_BULK_IN, pDevice->ulAddress, 0x40, SPECIFICIntINCallback); USBHCDPipeConfig(ulIndex, g_SPECIFICInstance.ulBulkInPipe, 0x40, 0, (0x81 & USB_EP_DESC_NUM_M)); // 端点1,批量,OUT g_SPECIFICInstance.ulBulkOutPipe = USBHCDPipeAllocSize(ulIndex, USBHCD_PIPE_BULK_OUT, pDevice->ulAddress, 0x40, 0); USBHCDPipeConfig(ulIndex, g_SPECIFICInstance.ulBulkOutPipe, 0x40, 0, (0x01 & USB_EP_DESC_NUM_M)); g_SPECIFICInstance.isConnected = true; return ((void *)1); } //***************************************************************************** // //! This function is used to release an instance of the SPECIFIC driver. //! //! \param pvInstance is an instance pointer that needs to be released. //! //! This function will free up any resources in use by the SPECIFIC driver instance //! that is passed in. The \e pvInstance pointer should be a valid value that //! was returned from a call to USBSPECIFICOpen(). //! //! \return None. // //***************************************************************************** static void SPECIFICDriverClose(void *pvInstance) { g_SPECIFICInstance.isConnected = false; printf("SPECIFICDriverClose...\r\n"); // tSPECIFICInstance *pSPECIFICInstance; // pSPECIFICInstance = (tSPECIFICInstance *)pvInstance; // // No device so just exit. // // if(g_SPECIFICInstance->pDevice == 0) // { // return; // } // // Reset the device pointer. // g_SPECIFICInstance.pDevice = 0; // // Free the Interrupt IN pipe. // if(g_SPECIFICInstance.ulIntInPipe != 0) { USBHCDPipeFree(g_SPECIFICInstance.ulIndex, g_SPECIFICInstance.ulIntInPipe); } if(g_SPECIFICInstance.ulBulkInPipe != 0) { USBHCDPipeFree(g_SPECIFICInstance.ulIndex, g_SPECIFICInstance.ulBulkInPipe); } if(g_SPECIFICInstance.ulBulkOutPipe != 0) { USBHCDPipeFree(g_SPECIFICInstance.ulIndex, g_SPECIFICInstance.ulBulkOutPipe); } // // If the callback exists, call it with an Open event. // if(g_SPECIFICInstance.pfnCallback != 0) { g_SPECIFICInstance.pfnCallback((void *)g_SPECIFICInstance.ulCBData, USB_EVENT_DISCONNECTED, (unsigned int)&g_SPECIFICInstance, 0); } } //***************************************************************************** // //! This function is used to set the idle timeout for a SPECIFIC device. //! //! \param ulInstance is the value that was returned from the call to //! USBHSPECIFICOpen(). //! \param ucDuration is the duration of the timeout in milliseconds. //! \param ucReportID is the report identifier to set the timeout on. //! //! This function will send the Set Idle command to a SPECIFIC device to set the //! idle timeout for a given report. The length of the timeout is specified //! by the \e ucDuration parameter and the report the timeout for is in the //! \e ucReportID value. //! //! \return Always returns 0. // //***************************************************************************** unsigned int USBHSPECIFICSetIdle(unsigned int ulInstance, unsigned char ucDuration, unsigned char ucReportID) { return (0); } //***************************************************************************** // //! This function can be used to retrieve the report descriptor for a given //! device instance. //! //! \param ulInstance is the value that was returned from the call to //! USBHSPECIFICOpen(). //! \param pucBuffer is the memory buffer to use to store the report //! descriptor. //! \param ulSize is the size in bytes of the buffer pointed to by //! \e pucBuffer. //! //! This function is used to return a report descriptor from a SPECIFIC device //! instance so that it can determine how to interpret reports that are //! returned from the device indicated by the \e ulInstance parameter. //! This call is blocking and will return the number of bytes read into the //! \e pucBuffer. //! //! \return Returns the number of bytes read into the \e pucBuffer. // //***************************************************************************** unsigned int USBHSPECIFICGetReportDescriptor(unsigned int ulInstance, unsigned char *pucBuffer, unsigned int ulSize) { return (ulSize); } //***************************************************************************** // //! This function is used to set or clear the boot protocol state of a device. //! //! \param ulInstance is the value that was returned from the call to //! USBHSPECIFICOpen(). //! \param ulBootProtocol is either zero or non-zero to indicate which protocol //! to use for the device. //! //! A USB host device can use this function to set the protocol for a connected //! SPECIFIC device. This is commonly used to set keyboards and mice into their //! simplified boot protocol modes to fix the report structure to a know //! state. //! //! \return This function returns 0. // //***************************************************************************** unsigned int USBHSPECIFICSetProtocol(unsigned int ulInstance, unsigned int ulBootProtocol) { return (0); } //***************************************************************************** // //! This function is used to retrieve a report from a SPECIFIC device. //! //! \param ulInstance is the value that was returned from the call to //! USBHSPECIFICOpen(). //! \param ulInterface is the interface to retrieve the report from. //! \param pucData is the memory buffer to use to store the report. //! \param ulSize is the size in bytes of the buffer pointed to by //! \e pucBuffer. //! //! This function is used to retrieve a report from a USB pipe. It is usually //! called when the USB SPECIFIC layer has detected a new data available in a USB //! pipe. The USB SPECIFIC host device code will receive a //! \b USB_EVENT_RX_AVAILABLE event when data is available, allowing the //! callback function to retrieve the data. //! //! \return Returns the number of bytes read from report. // //***************************************************************************** unsigned int USBHSPECIFICGetReport(unsigned int ulInstance, unsigned int ulInterface, unsigned char *pucData, unsigned int ulSize) { tSPECIFICInstance *pSPECIFICInstance; // // Cast the instance pointer to the correct type for ease of use. // pSPECIFICInstance = (tSPECIFICInstance *)ulInstance; // // Read the Data out. // ulSize = USBHCDPipeReadNonBlocking(pSPECIFICInstance->ulIndex, pSPECIFICInstance ->ulIntInPipe, pucData, ulSize); // // Return the number of bytes read from the interrupt in pipe. // return(ulSize); } //***************************************************************************** // //! This function is used to send a report to a SPECIFIC device. //! //! \param ulInstance is the value that was returned from the call to //! USBHSPECIFICOpen(). //! \param ulInterface is the interface to send the report to. //! \param pucData is the memory buffer to use to store the report. //! \param ulSize is the size in bytes of the buffer pointed to by //! \e pucBuffer. //! //! This function is used to send a report to a USB SPECIFIC device. It can be //! only be called from outside the callback context as this function will not //! return from the call until the data has been sent successfully. //! //! \return Returns the number of bytes sent to the device. // //***************************************************************************** unsigned int USBHSPECIFICSetReport(unsigned int ulInstance, unsigned int ulInterface, unsigned char *pucData, unsigned int ulSize) { return (ulSize); } //***************************************************************************** // //! @} // //*****************************************************************************