示例#1
0
//*****************************************************************************
//
// Device instance specific handler.
//
//*****************************************************************************
static void
HandleDevice(void *pvInstance, unsigned int ulRequest, void *pvRequestData)
{
    tBulkInstance *psInst;
    unsigned char *pucData;

    //
    // Create the serial instance data.
    //
    psInst = ((tUSBDBulkDevice *)pvInstance)->psPrivateBulkData;

    //
    // Create the char array used by the events supported by the USB CDC
    // serial class.
    //
    pucData = (unsigned char *)pvRequestData;

    switch(ulRequest)
    {
        //
        // This was an interface change event.
        //
        case USB_EVENT_COMP_IFACE_CHANGE:
        {
            psInst->ucInterface = pucData[1];
            break;
        }

        //
        // This was an endpoint change event.
        //
        case USB_EVENT_COMP_EP_CHANGE:
        {
            //
            // Determine if this is an IN or OUT endpoint that has changed.
            //
            if(pucData[0] & USB_EP_DESC_IN)
            {
                psInst->ucINEndpoint = INDEX_TO_USB_EP((pucData[1] & 0x7f));
            }
            else
            {
                //
                // Extract the new endpoint number.
                //
                psInst->ucOUTEndpoint = INDEX_TO_USB_EP(pucData[1] & 0x7f);
            }
            break;
        }
        default:
        {
            break;
        }
    }
}
示例#2
0
//*****************************************************************************
//
//! Configure the USB controller appropriately for the device whose config
//! descriptor is passed.
//!
//! \param ulIndex is the zero-based index of the USB controller which is to
//! be configured.
//! \param psConfig is a pointer to the configuration descriptor that the
//! USB controller is to be set up to support.
//! \param psFIFOConfig is a pointer to an array of NUM_USB_EP tFIFOConfig
//! structures detailing how the FIFOs are to be set up for each endpoint
//! used by the configuration.
//!
//! This function may be used to initialize a USB controller to operate as
//! the device whose configuration descriptor is passed.  The function
//! enables the USB controller, partitions the FIFO appropriately and
//! configures each endpoint required by the configuration.  If the supplied
//! configuration supports multiple alternate settings for any interface,
//! the USB FIFO is set up assuming the worst case use (largest packet size
//! for a given endpoint in any alternate setting using that endpoint) to
//! allow for on-the-fly alternate setting changes later.  On return from this
//! function, the USB controller is configured for correct operation of
//! the default configuration of the device described by the descriptor passed.
//!
//! The \e psFIFOConfig parameter allows the caller to provide additional
//! information on USB FIFO configuration that cannot be determined merely
//! by parsing the configuration descriptor.  The descriptor provides
//! information on the endpoints that are to be used and the maximum packet
//! size for each but cannot determine whether, for example, double buffering
//! is to be used or how many packets the application wants to be able to
//! store in a given endpoint's FIFO.
//!
//! USBDCDConfig() is an optional call and applications may chose to make
//! direct calls to SysCtlPeripheralEnable(), SysCtlUSBPLLEnable(),
//! USBDevEndpointConfigSet() and USBFIFOConfigSet() instead of using this
//! function.  If this function is used, it must be called prior to
//! USBDCDInit() since this call assumes that the low level hardware
//! configuration has been completed before it is made.
//!
//! \return Returns \b true on success or \b false on failure.
//
//*****************************************************************************
tBoolean
USBDeviceConfig(unsigned long ulIndex, const tConfigHeader *psConfig,
                const tFIFOConfig *psFIFOConfig)
{
    unsigned long ulLoop;
    unsigned long ulCount;
    unsigned long ulNumInterfaces;
    unsigned long ulEpIndex;
    unsigned long ulEpType;
    unsigned long ulMaxPkt;
    unsigned long ulNumEndpoints;
    unsigned long ulFlags;
    unsigned long ulBytesUsed;
    unsigned long ulSection;
    tInterfaceDescriptor *psInterface;
    tEndpointDescriptor *psEndpoint;
    tUSBEndpointInfo psEPInfo[NUM_USB_EP - 1];

    //
    // We only support 1 USB controller currently.
    //
    ASSERT(ulIndex == 0);

    //
    // Catch bad pointers in a debug build.
    //
    ASSERT(psConfig);
    ASSERT(psFIFOConfig);

    //
    // Clear out our endpoint info.
    //
    for(ulLoop = 0; ulLoop < (NUM_USB_EP - 1); ulLoop++)
    {
        psEPInfo[ulLoop].ulSize[EP_INFO_IN] = 0;
        psEPInfo[ulLoop].ulType[EP_INFO_IN] = 0;
        psEPInfo[ulLoop].ulSize[EP_INFO_OUT] = 0;
        psEPInfo[ulLoop].ulType[EP_INFO_OUT] = 0;
    }

    //
    // How many (total) endpoints does this configuration describe?
    //
    ulNumEndpoints = USBDCDConfigDescGetNum(psConfig,
                                            USB_DTYPE_ENDPOINT);

    //
    // How many interfaces are included?
    //
    ulNumInterfaces = USBDCDConfigDescGetNum(psConfig,
                                             USB_DTYPE_INTERFACE);

    //
    // Look at each endpoint and determine the largest max packet size for
    // each endpoint.  This will determine how we partition the USB FIFO.
    //
    for(ulLoop = 0; ulLoop < ulNumEndpoints; ulLoop++)
    {
        //
        // Get a pointer to the endpoint descriptor.
        //
        psEndpoint = (tEndpointDescriptor *)USBDCDConfigDescGet(
                                psConfig, USB_DTYPE_ENDPOINT, ulLoop,
                                &ulSection);

        //
        // Extract the endpoint number and whether it is an IN or OUT
        // endpoint.
        //
        ulEpIndex = (unsigned long)
                        psEndpoint->bEndpointAddress & USB_EP_DESC_NUM_M;
        ulEpType =  (psEndpoint->bEndpointAddress & USB_EP_DESC_IN) ?
                     EP_INFO_IN : EP_INFO_OUT;

        //
        // Make sure the endpoint number is valid for our controller.  If not,
        // return false to indicate an error.  Note that 0 is invalid since
        // you shouldn't reference endpoint 0 in the config descriptor.
        //
        if((ulEpIndex >= NUM_USB_EP) || (ulEpIndex == 0))
        {
            return(false);
        }

        //
        // Does this endpoint have a max packet size requirement larger than
        // any previous use we have seen?
        //
        if(psEndpoint->wMaxPacketSize >
           psEPInfo[ulEpIndex - 1].ulSize[ulEpType])
        {
            //
            // Yes - remember the new maximum packet size.
            //
            psEPInfo[ulEpIndex - 1].ulSize[ulEpType] =
                psEndpoint->wMaxPacketSize;
        }
    }

    //
    // At this point, we have determined the maximum packet size required
    // for each endpoint by any possible alternate setting of any interface
    // in this configuration.  Now determine the endpoint settings required
    // for the interface setting we are actually going to use.
    //
    for(ulLoop = 0; ulLoop < ulNumInterfaces; ulLoop++)
    {
        //
        // Get the next interface descriptor in the config descriptor.
        //
        psInterface = USBDCDConfigGetInterface(psConfig,
                                               ulLoop,
                                               USB_DESC_ANY,
                                               &ulSection);

        //
        // Is this the default interface (bAlternateSetting set to 0)?
        //
        if(psInterface && (psInterface->bAlternateSetting == 0))
        {
            //
            // This is an interface we are interested in so gather the
            // information on its endpoints.
            //
            ulNumEndpoints = (unsigned long)psInterface->bNumEndpoints;

            //
            // Walk through each endpoint in this interface and configure
            // it appropriately.
            //
            for(ulCount = 0; ulCount < ulNumEndpoints; ulCount++)
            {
                //
                // Get a pointer to the endpoint descriptor.
                //
                psEndpoint = USBDCDConfigGetInterfaceEndpoint(psConfig,
                                            psInterface->bInterfaceNumber,
                                            psInterface->bAlternateSetting,
                                            ulCount);

                //
                // Make sure we got a good pointer.
                //
                if(psEndpoint)
                {
                    //
                    // Determine maximum packet size and flags from the
                    // endpoint descriptor.
                    //
                    GetEPDescriptorType(psEndpoint, &ulEpIndex, &ulMaxPkt,
                                        &ulFlags);

                    //
                    // Make sure no-one is trying to configure endpoint 0.
                    //
                    if(!ulEpIndex)
                    {
                        return(false);
                    }

                    //
                    // Include any additional flags that the user wants.
                    //
                    if((ulFlags & (USB_EP_DEV_IN | USB_EP_DEV_OUT)) ==
                        USB_EP_DEV_IN)
                    {
                        //
                        // This is an IN endpoint.
                        //
                        ulFlags |= (unsigned long)(
                                  psFIFOConfig->sIn[ulEpIndex - 1].usEPFlags);
                        psEPInfo[ulEpIndex - 1].ulType[EP_INFO_IN] = ulFlags;
                    }
                    else
                    {
                        //
                        // This is an OUT endpoint.
                        //
                        ulFlags |= (unsigned long)(
                                  psFIFOConfig->sOut[ulEpIndex - 1].usEPFlags);
                        psEPInfo[ulEpIndex - 1].ulType[EP_INFO_OUT] = ulFlags;
                    }

                    //
                    // Set the endpoint configuration.
                    //
                    USBDevEndpointConfigSet(USB0_BASE,
                                            INDEX_TO_USB_EP(ulEpIndex),
                                            ulMaxPkt, ulFlags);
                }
            }
        }
    }

    //
    // At this point, we have configured all the endpoints that are to be
    // used by this configuration's alternate setting 0.  Now we go on and
    // partition the FIFO based on the maximum packet size information we
    // extracted earlier.  Endpoint 0 is automatically configured to use the
    // first MAX_PACKET_SIZE_EP0 bytes of the FIFO so we start from there.
    //
    ulCount = MAX_PACKET_SIZE_EP0;
    for(ulLoop = 1; ulLoop < NUM_USB_EP; ulLoop++)
    {
        //
        // Configure the IN endpoint at this index if it is referred to
        // anywhere.
        //
        if(psEPInfo[ulLoop - 1].ulSize[EP_INFO_IN])
        {
            //
            // What FIFO size flag do we use for this endpoint?
            //
            ulMaxPkt = GetEndpointFIFOSize(
                                     psEPInfo[ulLoop - 1].ulSize[EP_INFO_IN],
                                     &(psFIFOConfig->sIn[ulLoop - 1]),
                                     &ulBytesUsed);

            //
            // If we are told that 0 bytes of FIFO will be used, this implies
            // that there is an error in psFIFOConfig or the descriptor
            // somewhere so return an error indicator to the caller.
            //
            if(!ulBytesUsed)
            {
                return(false);
            }

            //
            // Now actually configure the FIFO for this endpoint.
            //
            USBFIFOConfigSet(USB0_BASE, INDEX_TO_USB_EP(ulLoop), ulCount,
                             ulMaxPkt, USB_EP_DEV_IN);
            ulCount += ulBytesUsed;
        }

        //
        // Configure the OUT endpoint at this index.
        //
        if(psEPInfo[ulLoop - 1].ulSize[EP_INFO_OUT])
        {
            //
            // What FIFO size flag do we use for this endpoint?
            //
            ulMaxPkt = GetEndpointFIFOSize(
                                     psEPInfo[ulLoop - 1].ulSize[EP_INFO_OUT],
                                     &(psFIFOConfig->sOut[ulLoop - 1]),
                                     &ulBytesUsed);

            //
            // If we are told that 0 bytes of FIFO will be used, this implies
            // that there is an error in psFIFOConfig or the descriptor
            // somewhere so return an error indicator to the caller.
            //
            if(!ulBytesUsed)
            {
                return(false);
            }

            //
            // Now actually configure the FIFO for this endpoint.
            //
            USBFIFOConfigSet(USB0_BASE, INDEX_TO_USB_EP(ulLoop), ulCount,
                             ulMaxPkt, USB_EP_DEV_OUT);
            ulCount += ulBytesUsed;
        }

    }

    //
    // If we get to the end, all is well.
    //
    return(true);
}
示例#3
0
//*****************************************************************************
//
//! Configure the affected USB endpoints appropriately for one alternate
//! interface setting.
//!
//! \param ulIndex is the zero-based index of the USB controller which is to
//! be configured.
//! \param psConfig is a pointer to the configuration descriptor that contains
//! the interface whose alternate settings is to be configured.
//! \param ucInterfaceNum is the number of the interface whose alternate
//! setting is to be configured.  This number corresponds to the
//! bInterfaceNumber field in the desired interface descriptor.
//! \param ucAlternateSetting is the alternate setting number for the desired
//! interface.  This number corresponds to the bAlternateSetting field in the
//! desired interface descriptor.
//!
//! This function may be used to reconfigure the endpoints of an interface
//! for operation in one of the interface's alternate settings.  Note that this
//! function assumes that the endpoint FIFO settings will not need to change
//! and only the endpoint mode is changed.  This assumption is valid if the
//! USB controller was initialized using a previous call to USBDCDConfig().
//!
//! In reconfiguring the interface endpoints, any additional configuration
//! bits set in the endpoint configuration other than the direction (\b
//! USB_EP_DEV_IN or \b USB_EP_DEV_OUT) and mode (\b USB_EP_MODE_MASK) are
//! preserved.
//!
//! \return Returns \b true on success or \b false on failure.
//
//*****************************************************************************
tBoolean
USBDeviceConfigAlternate(unsigned long ulIndex, const tConfigHeader *psConfig,
                         unsigned char ucInterfaceNum,
                         unsigned char ucAlternateSetting)
{
    unsigned long ulNumInterfaces;
    unsigned long ulNumEndpoints;
    unsigned long ulLoop;
    unsigned long ulCount;
    unsigned long ulMaxPkt;
    unsigned long ulOldMaxPkt;
    unsigned long ulFlags;
    unsigned long ulOldFlags;
    unsigned long ulSection;
    unsigned long ulEpIndex;
    tInterfaceDescriptor *psInterface;
    tEndpointDescriptor *psEndpoint;

    //
    // How many interfaces are included in the descriptor?
    //
    ulNumInterfaces = USBDCDConfigDescGetNum(psConfig,
                                             USB_DTYPE_INTERFACE);

    //
    // Find the interface descriptor for the supplied interface and alternate
    // setting numbers.
    //

    for(ulLoop = 0; ulLoop < ulNumInterfaces; ulLoop++)
    {
        //
        // Get the next interface descriptor in the config descriptor.
        //
        psInterface = USBDCDConfigGetInterface(psConfig, ulLoop, USB_DESC_ANY,
                                               &ulSection);

        //
        // Is this the default interface (bAlternateSetting set to 0)?
        //
        if(psInterface &&
           (psInterface->bInterfaceNumber == ucInterfaceNum) &&
           (psInterface->bAlternateSetting == ucAlternateSetting))
        {
            //
            // This is an interface we are interested in and the descriptor
            // representing the alternate setting we want so go ahead and
            // reconfigure the endpoints.
            //

            //
            // How many endpoints does this interface have?
            //
            ulNumEndpoints = (unsigned long)psInterface->bNumEndpoints;

            //
            // Walk through each endpoint in turn.
            //
            for(ulCount = 0; ulCount < ulNumEndpoints; ulCount++)
            {
                //
                // Get a pointer to the endpoint descriptor.
                //
                psEndpoint = USBDCDConfigGetInterfaceEndpoint(psConfig,
                                              psInterface->bInterfaceNumber,
                                              psInterface->bAlternateSetting,
                                              ulCount);

                //
                // Make sure we got a good pointer.
                //
                if(psEndpoint)
                {
                    //
                    // Determine maximum packet size and flags from the
                    // endpoint descriptor.
                    //
                    GetEPDescriptorType(psEndpoint, &ulEpIndex, &ulMaxPkt,
                                        &ulFlags);

                    //
                    // Make sure no-one is trying to configure endpoint 0.
                    //
                    if(!ulEpIndex)
                    {
                        return(false);
                    }

                    //
                    // Get the existing endpoint configuration and mask in the
                    // new mode and direction bits, leaving everything else
                    // unchanged.
                    //
                    ulOldFlags = ulFlags;
                    USBDevEndpointConfigGet(USB0_BASE,
                                            INDEX_TO_USB_EP(ulEpIndex),
                                            &ulOldMaxPkt,
                                            &ulOldFlags);

                    //
                    // Mask in the previous DMA and auto-set bits.
                    //
                    ulFlags = (ulFlags & EP_FLAGS_MASK) |
                              (ulOldFlags & ~EP_FLAGS_MASK);

                    //
                    // Set the endpoint configuration.
                    //
                    USBDevEndpointConfigSet(USB0_BASE,
                                            INDEX_TO_USB_EP(ulEpIndex),
                                            ulMaxPkt, ulFlags);
                }
            }

            //
            // At this point, we have reconfigured the desired interface so
            // return indicating all is well.
            //
            return(true);
        }
    }

    return(false);
}
示例#4
0
//*****************************************************************************
//
//! Configure the affected USB endpoints appropriately for one alternate
//! interface setting.
//!
//! \param psDevInst is a pointer to the device instance being configured.
//! \param psConfig is a pointer to the configuration descriptor that contains
//! the interface whose alternate settings is to be configured.
//! \param ucInterfaceNum is the number of the interface whose alternate
//! setting is to be configured.  This number corresponds to the
//! bInterfaceNumber field in the desired interface descriptor.
//! \param ucAlternateSetting is the alternate setting number for the desired
//! interface.  This number corresponds to the bAlternateSetting field in the
//! desired interface descriptor.
//!
//! This function may be used to reconfigure the endpoints of an interface
//! for operation in one of the interface's alternate settings.  Note that this
//! function assumes that the endpoint FIFO settings will not need to change
//! and only the endpoint mode is changed.  This assumption is valid if the
//! USB controller was initialized using a previous call to USBDCDConfig().
//!
//! In reconfiguring the interface endpoints, any additional configuration
//! bits set in the endpoint configuration other than the direction (\b
//! USB_EP_DEV_IN or \b USB_EP_DEV_OUT) and mode (\b USB_EP_MODE_MASK) are
//! preserved.
//!
//! \return Returns \b true on success or \b false on failure.
//
//*****************************************************************************
tBoolean
USBDeviceConfigAlternate(tDeviceInstance *psDevInst, const tConfigHeader *psConfig,
                         unsigned char ucInterfaceNum,
                         unsigned char ucAlternateSetting)
{
    unsigned long ulNumInterfaces;
    unsigned long ulNumEndpoints;
    unsigned long ulLoop;
    unsigned long ulCount;
    unsigned long ulMaxPkt;
    unsigned long ulFlags;
    unsigned long ulSection;
    unsigned long ulEpIndex;
    tInterfaceDescriptor *psInterface;
    tEndpointDescriptor *psEndpoint;
    tFIFOConfig const *psFIFOConfig;

    //
    // How many interfaces are included in the descriptor?
    //
    ulNumInterfaces = USBDCDConfigDescGetNum(psConfig,
                                             USB_DTYPE_INTERFACE);

    psFIFOConfig = psDevInst->psInfo->psFIFOConfig;

    //
    // Find the interface descriptor for the supplied interface and alternate
    // setting numbers.
    //

    for(ulLoop = 0; ulLoop < ulNumInterfaces; ulLoop++)
    {
        //
        // Get the next interface descriptor in the config descriptor.
        //
        psInterface = USBDCDConfigGetInterface(psConfig, ulLoop, USB_DESC_ANY,
                                               &ulSection);

        //
        // Is this the default interface (bAlternateSetting set to 0)?
        //
        if(psInterface &&
           (psInterface->bInterfaceNumber == ucInterfaceNum) &&
           (psInterface->bAlternateSetting == ucAlternateSetting))
        {
            //
            // This is an interface we are interested in and the descriptor
            // representing the alternate setting we want so go ahead and
            // reconfigure the endpoints.
            //

            //
            // How many endpoints does this interface have?
            //
            ulNumEndpoints = (unsigned long)psInterface->bNumEndpoints;

            //
            // Walk through each endpoint in turn.
            //
            for(ulCount = 0; ulCount < ulNumEndpoints; ulCount++)
            {
                //
                // Get a pointer to the endpoint descriptor.
                //
                psEndpoint = USBDCDConfigGetInterfaceEndpoint(psConfig,
                                              psInterface->bInterfaceNumber,
                                              psInterface->bAlternateSetting,
                                              ulCount);

                //
                // Make sure we got a good pointer.
                //
                if(psEndpoint)
                {
                    //
                    // Determine maximum packet size and flags from the
                    // endpoint descriptor.
                    //
                    GetEPDescriptorType(psEndpoint, &ulEpIndex, &ulMaxPkt,
                                        &ulFlags);

                    //
                    // Make sure no-one is trying to configure endpoint 0.
                    //
                    if(!ulEpIndex)
                    {
                        return(false);
                    }

                    //
                    // Include any additional flags that the user wants.
                    //
                    if((ulFlags & (USB_EP_DEV_IN | USB_EP_DEV_OUT)) ==
                        USB_EP_DEV_IN)
                    {
                        //
                        // This is an IN endpoint.
                        //
                        ulFlags |= (unsigned long)(
                                psFIFOConfig->sIn[ulEpIndex - 1].usEPFlags);
                    }
                    else
                    {
                        //
                        // This is an OUT endpoint.
                        //
                        ulFlags |= (unsigned long)(
                                psFIFOConfig->sOut[ulEpIndex - 1].usEPFlags);
                    }

                    //
                    // Set the endpoint configuration.
                    //
                    USBDevEndpointConfigSet(USB0_BASE,
                                            INDEX_TO_USB_EP(ulEpIndex),
                                            ulMaxPkt, ulFlags);
                }
            }

            //
            // At this point, we have reconfigured the desired interface so
            // return indicating all is well.
            //
            return(true);
        }
    }

    return(false);
}