//***************************************************************************** // //! Initializes bulk device operation for a given USB controller. //! //! \param ulIndex is the index of the USB controller which is to be //! initialized for bulk device operation. //! \param psDevice points to a structure containing parameters customizing //! the operation of the bulk device. //! //! An application wishing to make use of a USB bulk communication channel //! must call this function to initialize the USB controller and attach the //! device to the USB bus. This function performs all required USB //! initialization. //! //! On successful completion, this function will return the \e psDevice pointer //! passed to it. This must be passed on all future calls to the device driver //! related to this device. //! //! The USBDBulk interface offers packet-based transmit and receive operation. //! If the application would rather use block based communication with //! transmit and receive buffers, USB buffers may be used above the bulk //! transmit and receive channels to offer this functionality. //! //! Transmit Operation: //! //! Calls to USBDBulkPacketWrite must send no more than 64 bytes of data at a //! time and may only be made when no other transmission is currently //! outstanding. //! //! Once a packet of data has been acknowledged by the USB host, a //! USB_EVENT_TX_COMPLETE event is sent to the application callback to inform //! it that another packet may be transmitted. //! //! Receive Operation: //! //! An incoming USB data packet will result in a call to the application //! callback with event USBD_EVENT_RX_AVAILABLE. The application must then //! call USBDBulkPacketRead(), passing a buffer capable of holding 64 bytes, to //! retrieve the data and acknowledge reception to the USB host. //! //! \note The application must not make any calls to the low level USB Device //! API if interacting with USB via the USB bulk device class API. Doing so //! will cause unpredictable (though almost certainly unpleasant) behavior. //! //! \return Returns NULL on failure or the psDevice pointer on success. // //***************************************************************************** void * USBDBulkInit(unsigned int ulIndex, const tUSBDBulkDevice *psDevice) { void *pvInstance; // // Check parameter validity. // ASSERT(ulIndex == 0); ASSERT(psDevice); pvInstance = USBDBulkCompositeInit(ulIndex, psDevice); if(pvInstance) { // // All is well so now pass the descriptors to the lower layer and put // the bulk device on the bus. // USBDCDInit(ulIndex, psDevice->psPrivateBulkData->psDevInfo); } // // Return the pointer to the instance indicating that everything went well. // return(pvInstance); }
//***************************************************************************** // //! This function should be called once for the audio class device to //! initialized basic operation and prepare for enumeration. //! //! \param ui32Index is the index of the USB controller to initialize for //! audio class device operation. //! \param psAudioDevice points to a structure containing parameters //! customizing the operation of the audio device. //! //! In order for an application to initialize the USB audio device class, it //! must first call this function with the a valid audio device class structure //! in the \e psAudioDevice parameter. This allows this function to initialize //! the USB controller and device code to be prepared to enumerate and function //! as a USB audio device. //! //! This function returns a void pointer that must be passed in to all other //! APIs used by the audio class. //! //! See the documentation on the tUSBDAudioDevice structure for more //! information on how to properly fill the structure members. //! //! \return Returns 0 on failure or a non-zero void pointer on success. // //***************************************************************************** void * USBDAudioInit(uint32_t ui32Index, tUSBDAudioDevice *psAudioDevice) { tConfigDescriptor *psConfigDesc; tDeviceDescriptor *psDevDesc; // // Check parameter validity. // ASSERT(ui32Index == 0); ASSERT(psAudioDevice); ASSERT(psAudioDevice->ppui8StringDescriptors); // // Composite Init handles all initialization that is not specific to a // multiple instance device. // USBDAudioCompositeInit(ui32Index, psAudioDevice, 0); // // Fix up the device descriptor with the client-supplied values. // psDevDesc = (tDeviceDescriptor *)g_pui8AudioDeviceDescriptor; writeusb16_t(&(psDevDesc->idVendor), psAudioDevice->ui16VID); writeusb16_t(&(psDevDesc->idProduct), psAudioDevice->ui16PID); // // Fix up the configuration descriptor with client-supplied values. // psConfigDesc = (tConfigDescriptor *)g_pui8AudioDescriptor; psConfigDesc->bmAttributes = psAudioDevice->ui8PwrAttributes; psConfigDesc->bMaxPower = (uint8_t)(psAudioDevice->ui16MaxPowermA / 2); // // All is well so now pass the descriptors to the lower layer and put // the bulk device on the bus. // USBDCDInit(ui32Index, &psAudioDevice->sPrivateData.sDevInfo, (void *)psAudioDevice); // // Configure the DMA for the OUT endpoint. // psAudioDevice->sPrivateData.ui8OUTDMA = USBLibDMAChannelAllocate(psAudioDevice->sPrivateData.psDMAInstance, psAudioDevice->sPrivateData.ui8OUTEndpoint, ISOC_OUT_EP_MAX_SIZE, USB_DMA_EP_RX | USB_DMA_EP_TYPE_ISOC | USB_DMA_EP_DEVICE); USBLibDMAUnitSizeSet(psAudioDevice->sPrivateData.psDMAInstance, psAudioDevice->sPrivateData.ui8OUTDMA, 32); USBLibDMAArbSizeSet(psAudioDevice->sPrivateData.psDMAInstance, psAudioDevice->sPrivateData.ui8OUTDMA, 16); // // Return the pointer to the instance indicating that everything went well. // return((void *)psAudioDevice); }
//***************************************************************************** // //! Initializes bulk device operation for a given USB controller. //! //! \param ui32Index is the index of the USB controller which is to be //! initialized for bulk device operation. //! \param psBulkDevice points to a structure containing parameters customizing //! the operation of the bulk device. //! //! An application wishing to make use of a USB bulk communication channel //! must call this function to initialize the USB controller and attach the //! device to the USB bus. This function performs all required USB //! initialization. //! //! On successful completion, this function will return the \e psBulkDevice //! pointer passed to it. This must be passed on all future calls to the //! device driver related to this device. //! //! The USBDBulk interface offers packet-based transmit and receive operation. //! If the application would rather use block based communication with //! transmit and receive buffers, USB buffers may be used above the bulk //! transmit and receive channels to offer this functionality. //! //! Transmit Operation: //! //! Calls to USBDBulkPacketWrite must send no more than 64 bytes of data at a //! time and may only be made when no other transmission is currently //! outstanding. //! //! Once a packet of data has been acknowledged by the USB host, a //! \b USB_EVENT_TX_COMPLETE event is sent to the application callback to //! inform it that another packet may be transmitted. //! //! Receive Operation: //! //! An incoming USB data packet will result in a call to the application //! callback with event \b USBD_EVENT_RX_AVAILABLE. The application must then //! call USBDBulkPacketRead(), passing a buffer capable of holding 64 bytes, to //! retrieve the data and acknowledge reception to the USB host. //! //! \note The application must not make any calls to the low level USB Device //! API if interacting with USB via the USB bulk device class API. Doing so //! will cause unpredictable (though almost certainly unpleasant) behavior. //! //! \return Returns NULL on failure or void pointer that should be used with //! the remaining USB bulk class APSs. // //***************************************************************************** void * USBDBulkInit(uint32_t ui32Index, tUSBDBulkDevice *psBulkDevice) { void *pvBulkDevice; tDeviceDescriptor *psDevDesc; tConfigDescriptor *psConfigDesc; // // Check parameter validity. // ASSERT(ui32Index == 0); ASSERT(psBulkDevice); pvBulkDevice = USBDBulkCompositeInit(ui32Index, psBulkDevice, 0); if(pvBulkDevice) { // // Fix up the device descriptor with the client-supplied values. // psDevDesc = (tDeviceDescriptor *)g_pui8BulkDeviceDescriptor; psDevDesc->idVendor = psBulkDevice->ui16VID; psDevDesc->idProduct = psBulkDevice->ui16PID; // // Fix up the configuration descriptor with client-supplied values. // psConfigDesc = (tConfigDescriptor *)g_pui8BulkDescriptor; psConfigDesc->bmAttributes = psBulkDevice->ui8PwrAttributes; psConfigDesc->bMaxPower = (uint8_t)(psBulkDevice->ui16MaxPowermA / 2); // // All is well so now pass the descriptors to the lower layer and put // the bulk device on the bus. // USBDCDInit(ui32Index, &psBulkDevice->sPrivateData.sDevInfo, (void *)psBulkDevice); } // // Return the pointer to the instance indicating that everything went well. // return(pvBulkDevice); }
//**************************************************************************** // //! This function should be called once for the composite class device to //! initialize basic operation and prepare for enumeration. //! //! \param ulIndex is the index of the USB controller to initialize for //! composite device operation. //! \param psDevice points to a structure containing parameters customizing //! the operation of the composite device. //! \param ulSize is the size in bytes of the data pointed to by the //! \e pucData parameter. //! \param pucData is the data area that the composite class can use to build //! up descriptors. //! //! In order for an application to initialize the USB composite device class, //! it must first call this function with the a valid composite device class //! structure in the \e psDevice parameter. This allows this function to //! initialize the USB controller and device code to be prepared to enumerate //! and function as a USB composite device. The \e ulSize and \e pucData //! parameters should be large enough to hold all of the class instances //! passed in via the psDevice structure. This is typically the full size of //! the configuration descriptor for a device minus its configuration //! header(9 bytes). //! //! This function returns a void pointer that must be passed in to all other //! APIs used by the composite class. //! //! See the documentation on the tUSBDCompositeDevice structure for more //! information on how to properly fill the structure members. //! //! \return This function returns 0 on failure or a non-zero void pointer on //! success. // //**************************************************************************** void * USBDCompositeInit(unsigned long ulIndex, tUSBDCompositeDevice *psDevice, unsigned long ulSize, unsigned char *pucData) { tCompositeInstance *psInst; long lIdx; unsigned char *pucTemp; // // Check parameter validity. // ASSERT(ulIndex == 0); ASSERT(psDevice); ASSERT(psDevice->ppStringDescriptors); ASSERT(psDevice->psPrivateData); // // Initialize the work space in the passed instance structure. // psInst = psDevice->psPrivateData; psInst->ulDataSize = ulSize; psInst->pucData = pucData; // // Save the base address of the USB controller. // psInst->ulUSBBase = USB_INDEX_TO_BASE(ulIndex); // // No device is currently transfering data on EP0. // psInst->ulEP0Owner = INVALID_DEVICE_INDEX; // // Set the device information for the composite device. // psInst->psDevInfo = &g_sCompositeDeviceInfo; g_pCompConfigDescriptors[0] = &psInst->sCompConfigHeader; g_pCompConfigDescriptors[0]->ucNumSections = 0; g_pCompConfigDescriptors[0]->psSections = (const tConfigSection * const *)psDevice->psPrivateData->ppsCompSections; // // Create a byte pointer to use with the copy. // pucTemp = (unsigned char *)&psInst->sConfigDescriptor; // // Copy the default configuration descriptor into the instance data. // for(lIdx = 0; lIdx < g_pCompConfigDescriptor[0]; lIdx++) { pucTemp[lIdx] = g_pCompConfigDescriptor[lIdx]; } // // Create a byte pointer to use with the copy. // pucTemp = (unsigned char *)&psInst->sDeviceDescriptor; // // Copy the default configuration descriptor into the instance data. // for(lIdx = 0; lIdx < g_pCompDeviceDescriptor[0]; lIdx++) { pucTemp[lIdx] = g_pCompDeviceDescriptor[lIdx]; } // // Fix up the device descriptor with the client-supplied values. // psInst->sDeviceDescriptor.idVendor = psDevice->usVID; psInst->sDeviceDescriptor.idProduct = psDevice->usPID; // // Fix up the configuration descriptor with client-supplied values. // psInst->sConfigDescriptor.bmAttributes = psDevice->ucPwrAttributes; psInst->sConfigDescriptor.bMaxPower = (unsigned char)(psDevice->usMaxPowermA>>1); g_sCompositeDeviceInfo.pDeviceDescriptor = (const unsigned char *)&psInst->sDeviceDescriptor; // // Plug in the client's string table to the device information // structure. // psInst->psDevInfo->ppStringDescriptors = psDevice->ppStringDescriptors; psInst->psDevInfo->ulNumStringDescriptors = psDevice->ulNumStringDescriptors; // // Enable Clocking to the USB controller so that changes to the USB // controller can be made in the BuildCompositeDescriptor() function. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); // // Create the combined descriptors. // if(BuildCompositeDescriptor(psDevice)) { return(0); } // // Set the instance data for this device. // psInst->psDevInfo->pvInstance = (void *)psDevice; // // All is well so now pass the descriptors to the lower layer and put // the bulk device on the bus. // USBDCDInit(ulIndex, psInst->psDevInfo); // // Return the pointer to the instance indicating that everything went // well. // return((void *)psDevice); }
//***************************************************************************** // // This function is called by the USB library to inform us of the mode that // we are operating in, USB_MODE_DEVICE or USB_MODE_HOST. // //***************************************************************************** void ScopeUSBModeCallback(unsigned long ulIndex, tUSBMode eMode) { // // What is the new operating mode? // switch(eMode) { // // We are switching to USB device mode. // case USB_MODE_DEVICE: { // // Perform additional setup required for operation as a USB // device. // ScopeUSBDeviceConfigureEndpoints(); // // Pass our device information to the USB library. // USBDCDInit(0, &g_sScopeDeviceInfo); // // Clear the flag used by other modules in the application to // indicate which mode we are in. // g_bUSBModeIsHost = false; break; } // // We are switching to USB host mode. // case USB_MODE_HOST: { // // Register the host class drivers. // USBHCDRegisterDrivers(0, g_ppHostClassDrivers, g_ulNumHostClassDrivers); // // Set our Mass Storage Class driver callback. // g_ulMSCInstance = USBHMSCDriveOpen(0, MSCCallback); // // Initialize the host controller and give it the memory we have // set aside for it to use for descriptor storage. // USBHCDInit(0, g_pcUSBHostHeap, USB_HOST_HEAP_SIZE); // // Set the flag used by other modules in the application to // indicate which mode we are in. // g_bUSBModeIsHost = true; break; } default: { // // This callback will only ever be called to tell us we are // operating as a host or a device. Any other value indicates // something has gone horribly wrong. // break; } } }
//**************************************************************************** // //! This function should be called once for the composite class device to //! initialized basic operation and prepare for enumeration. //! //! \param ulIndex is the index of the USB controller to initialize for //! composite device operation. //! \param psDevice points to a structure containing parameters customizing //! the operation of the composite device. //! \param ulSize is the size in bytes of the data pointed to by the //! \e pucData parameter. //! \param pucData is the data area that the composite class can use to build //! up descriptors. //! //! In order for an application to initialize the USB composite device class, //! it must first call this function with the a valid composite device class //! structure in the \e psDevice parameter. This allows this function to //! initialize the USB controller and device code to be prepared to enumerate //! and function as a USB composite device. The \e ulSize and \e pucData //! parameters should be large enough to hold all of the class instances //! passed in via the psDevice structure. This is typically the full size of //! the configuration descriptor for a device minus its configuration //! header(9 bytes). //! //! This function returns a void pointer that must be passed in to all other //! APIs used by the composite class. //! //! See the documentation on the tUSBDCompositeDevice structure for more //! information on how to properly fill the structure members. //! //! \return This function returns 0 on failure or a non-zero void pointer on //! success. // //**************************************************************************** void * USBDCompositeInit(unsigned int ulIndex, tUSBDCompositeDevice *psDevice, unsigned int ulSize, unsigned char *pucData) { tCompositeInstance *psInst; int iIdx; unsigned char *pucTemp; // // Check parameter validity. // ASSERT(ulIndex == 0); ASSERT(psDevice); ASSERT(psDevice->ppStringDescriptors); ASSERT(psDevice->psPrivateData); // // Initialize the work space in the passed instance structure. // psInst = psDevice->psPrivateData; psInst->ulDataSize = ulSize; psInst->pucData = pucData; // // Set the device information for the composite device. // psInst->psDevInfo = &g_sCompositeDeviceInfo; g_pCompConfigDescriptors[0] = &psInst->sCompConfigHeader; g_pCompConfigDescriptors[0]->ucNumSections = 0; g_pCompConfigDescriptors[0]->psSections = (const tConfigSection * const *)psDevice->psPrivateData->ppsCompSections; // // Create a byte pointer to use with the copy. // pucTemp = (unsigned char *)&psInst->sConfigDescriptor; // // Copy the default configuration descriptor into the instance data. // for(iIdx = 0; iIdx < g_pCompConfigDescriptor[0]; iIdx++) { pucTemp[iIdx] = g_pCompConfigDescriptor[iIdx]; } // // Create a byte pointer to use with the copy. // pucTemp = (unsigned char *)&psInst->sDeviceDescriptor; // // Copy the default configuration descriptor into the instance data. // for(iIdx = 0; iIdx < g_pCompDeviceDescriptor[0]; iIdx++) { pucTemp[iIdx] = g_pCompDeviceDescriptor[iIdx]; } // // Fix up the device descriptor with the client-supplied values. // psInst->sDeviceDescriptor.idVendor = psDevice->usVID; psInst->sDeviceDescriptor.idProduct = psDevice->usPID; // // Fix up the configuration descriptor with client-supplied values. // psInst->sConfigDescriptor.bmAttributes = psDevice->ucPwrAttributes; psInst->sConfigDescriptor.bMaxPower = (unsigned char)(psDevice->usMaxPowermA>>1); g_sCompositeDeviceInfo.pDeviceDescriptor = (const unsigned char *)&psInst->sDeviceDescriptor; // // Plug in the client's string stable to the device information // structure. // psInst->psDevInfo->ppStringDescriptors = psDevice->ppStringDescriptors; psInst->psDevInfo->ulNumStringDescriptors = psDevice->ulNumStringDescriptors; // // Create the combined descriptors. // if(BuildCompositeDescriptor(psDevice)) { return(0); } // // Set the instance data for this device. // psInst->psDevInfo->pvInstance = (void *)psDevice; // // All is well so now pass the descriptors to the lower layer and put // the bulk device on the bus. // USBDCDInit(ulIndex, psInst->psDevInfo); // // Return the pointer to the instance indicating that everything went // well. // return ((void *)psDevice); }