示例#1
0
文件: usbdbulk.c 项目: x893/OpenBLT
//*****************************************************************************
//
// Device instance specific handler.
//
//*****************************************************************************
static void
HandleDevice(void *pvBulkDevice, uint32_t ui32Request, void *pvRequestData)
{
    tBulkInstance *psInst;
    uint8_t *pui8Data;
    tUSBDBulkDevice *psBulkDevice;

    //
    // The bulk device structure pointer.
    //
    psBulkDevice = (tUSBDBulkDevice *)pvBulkDevice;

    //
    // Get a pointer to the bulk device instance data pointer
    //
    psInst = &psBulkDevice->sPrivateData;

    //
    // Create the 8-bit array used by the events supported by the USB Bulk
    // class.
    //
    pui8Data = (uint8_t *)pvRequestData;

    switch(ui32Request)
    {
        //
        // This was an interface change event.
        //
        case USB_EVENT_COMP_IFACE_CHANGE:
        {
            psInst->ui8Interface = pui8Data[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(pui8Data[0] & USB_EP_DESC_IN)
            {
                psInst->ui8INEndpoint = IndexToUSBEP((pui8Data[1] & 0x7f));
            }
            else
            {
                //
                // Extract the new endpoint number.
                //
                psInst->ui8OUTEndpoint = IndexToUSBEP(pui8Data[1] & 0x7f);
            }
            break;
        }

        default:
        {
            break;
        }
    }
}
示例#2
0
//*****************************************************************************
//
//! Configure the USB controller appropriately for the device whose
//! configuration descriptor is passed.
//!
//! \param psDevInst is a pointer to the device instance being configured.
//! \param psConfig is a pointer to the configuration descriptor that the
//! USB controller is to be set up to support.
//!
//! 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.
//!
//! \return Returns \b true on success or \b false on failure.
//
//*****************************************************************************
bool
USBDeviceConfig(tDCDInstance *psDevInst, const tConfigHeader *psConfig)
{
    uint32_t ui32Loop, ui32Count, ui32NumInterfaces, ui32EpIndex, ui32EpType,
             ui32MaxPkt, ui32NumEndpoints, ui32Flags, ui32BytesUsed,
             ui32Section;
    tInterfaceDescriptor *psInterface;
    tEndpointDescriptor *psEndpoint;
    tUSBEndpointInfo psEPInfo[NUM_USB_EP - 1];

    //
    // A valid device instance is required.
    //
    ASSERT(psDevInst != 0);

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

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

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

    //
    // How many interfaces are included?
    //
    ui32NumInterfaces = 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(ui32Loop = 0; ui32Loop < ui32NumEndpoints; ui32Loop++)
    {
        //
        // Get a pointer to the endpoint descriptor.
        //
        psEndpoint = (tEndpointDescriptor *)USBDCDConfigDescGet(
                                psConfig, USB_DTYPE_ENDPOINT, ui32Loop,
                                &ui32Section);

        //
        // Extract the endpoint number and whether it is an IN or OUT
        // endpoint.
        //
        ui32EpIndex = (uint32_t)
                        psEndpoint->bEndpointAddress & USB_EP_DESC_NUM_M;
        ui32EpType = (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((ui32EpIndex >= NUM_USB_EP) || (ui32EpIndex == 0))
        {
            return(false);
        }

        //
        // Does this endpoint have a max packet size requirement larger than
        // any previous use we have seen?
        //
        if(psEndpoint->wMaxPacketSize >
           psEPInfo[ui32EpIndex - 1].pui32Size[ui32EpType])
        {
            //
            // Yes - remember the new maximum packet size.
            //
            psEPInfo[ui32EpIndex - 1].pui32Size[ui32EpType] =
                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(ui32Loop = 0; ui32Loop < ui32NumInterfaces; ui32Loop++)
    {
        //
        // Get the next interface descriptor in the configuration descriptor.
        //
        psInterface = USBDCDConfigGetInterface(psConfig, ui32Loop,
                                               USB_DESC_ANY, &ui32Section);

        //
        // 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.
            //
            ui32NumEndpoints = (uint32_t)psInterface->bNumEndpoints;

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

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

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

                    //
                    // Set the endpoint configuration.
                    //
                    USBDevEndpointConfigSet(USB0_BASE,
                                            IndexToUSBEP(ui32EpIndex),
                                            ui32MaxPkt, ui32Flags);
                }
            }
        }
    }

    //
    // 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.
    //
    ui32Count = MAX_PACKET_SIZE_EP0;
    for(ui32Loop = 1; ui32Loop < NUM_USB_EP; ui32Loop++)
    {
        //
        // Configure the IN endpoint at this index if it is referred to
        // anywhere.
        //
        if(psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_IN])
        {
            //
            // What FIFO size flag do we use for this endpoint?
            //
            ui32MaxPkt = GetEndpointFIFOSize(
                                psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_IN],
                                &ui32BytesUsed);

            //
            // The FIFO space could not be allocated.
            //
            if(ui32BytesUsed == 0)
            {
                return(false);
            }

            //
            // Now actually configure the FIFO for this endpoint.
            //
            USBFIFOConfigSet(USB0_BASE, IndexToUSBEP(ui32Loop), ui32Count,
                             ui32MaxPkt, USB_EP_DEV_IN);
            ui32Count += ui32BytesUsed;
        }

        //
        // Configure the OUT endpoint at this index.
        //
        if(psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_OUT])
        {
            //
            // What FIFO size flag do we use for this endpoint?
            //
            ui32MaxPkt = GetEndpointFIFOSize(
                                psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_OUT],
                                &ui32BytesUsed);

            //
            // The FIFO space could not be allocated.
            //
            if(ui32BytesUsed == 0)
            {
                return(false);
            }

            //
            // Now actually configure the FIFO for this endpoint.
            //
            USBFIFOConfigSet(USB0_BASE, IndexToUSBEP(ui32Loop), ui32Count,
                             ui32MaxPkt, USB_EP_DEV_OUT);
            ui32Count += ui32BytesUsed;
        }

    }

    //
    // 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 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 ui8InterfaceNum 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 ui8AlternateSetting 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.
//
//*****************************************************************************
bool
USBDeviceConfigAlternate(tDCDInstance *psDevInst,
                         const tConfigHeader *psConfig,
                         uint8_t ui8InterfaceNum,
                         uint8_t ui8AlternateSetting)
{
    uint32_t ui32NumInterfaces, ui32NumEndpoints, ui32Loop, ui32Count,
             ui32MaxPkt, ui32Flags, ui32Section, ui32EpIndex;
    tInterfaceDescriptor *psInterface;
    tEndpointDescriptor *psEndpoint;

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

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

    for(ui32Loop = 0; ui32Loop < ui32NumInterfaces; ui32Loop++)
    {
        //
        // Get the next interface descriptor in the configuration descriptor.
        //
        psInterface = USBDCDConfigGetInterface(psConfig, ui32Loop,
                                               USB_DESC_ANY, &ui32Section);

        //
        // Is this the default interface (bAlternateSetting set to 0)?
        //
        if(psInterface &&
           (psInterface->bInterfaceNumber == ui8InterfaceNum) &&
           (psInterface->bAlternateSetting == ui8AlternateSetting))
        {
            //
            // 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?
            //
            ui32NumEndpoints = (uint32_t)psInterface->bNumEndpoints;

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

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

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

                    //
                    // Set the endpoint configuration.
                    //
                    USBDevEndpointConfigSet(USB0_BASE,
                                            IndexToUSBEP(ui32EpIndex),
                                            ui32MaxPkt, ui32Flags);
                }
            }

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

    return(false);
}
示例#4
0
文件: usbdaudio.c 项目: dvj/c2000-bin
//*****************************************************************************
//
// Device instance specific handler.
//
//*****************************************************************************
static void
HandleDevice(void *pvAudioDevice, uint32_t ui32Request, void *pvRequestData)
{
    tAudioInstance *psInst;
    uint8_t *pui8Data;
    tUSBDAudioDevice *psAudioDevice;

    //
    // The audio device structure pointer.
    //
    psAudioDevice = (tUSBDAudioDevice *)pvAudioDevice;

    //
    // Create a pointer to the audio instance data.
    //
    psInst = &psAudioDevice->sPrivateData;

    //
    // Create the 8-bit array used by the events supported by the USB CDC
    // serial class.
    //
    pui8Data = (uint8_t *)pvRequestData;

    switch(ui32Request)
    {
        //
        // This was an interface change event.
        //
        case USB_EVENT_COMP_IFACE_CHANGE:
        {
            //
            // Save the change to the appropriate interface number.
            //
            if(pui8Data[0] == AUDIO_INTERFACE_CONTROL)
            {
                psInst->ui8InterfaceControl = pui8Data[1];
            }
            else if(pui8Data[0] == AUDIO_INTERFACE_OUTPUT)
            {
                psInst->ui8InterfaceAudio = pui8Data[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((pui8Data[0] & USB_EP_DESC_IN) == 0)
            {
                //
                // Extract the new endpoint number without the DIR bit.
                //
                psInst->ui8OUTEndpoint = IndexToUSBEP(pui8Data[1] & 0x7f);

                //
                // If the DMA channel has already been allocated then clear
                // that channel and prepare to possibly use a new one.
                //
                if(psInst->ui8OUTDMA != 0)
                {
                    USBLibDMAChannelRelease(psInst->psDMAInstance,
                                            psInst->ui8OUTDMA);
                }

                //
                // Allocate a DMA channel to the endpoint.
                //
                psInst->ui8OUTDMA =
                    USBLibDMAChannelAllocate(psInst->psDMAInstance,
                                             psInst->ui8OUTEndpoint,
                                             ISOC_OUT_EP_MAX_SIZE,
                                             (USB_DMA_EP_RX |
                                              USB_DMA_EP_TYPE_ISOC |
                                              USB_DMA_EP_DEVICE));

                //
                // Set the DMA individual transfer size.
                //
                USBLibDMAUnitSizeSet(psInst->psDMAInstance, psInst->ui8OUTDMA,
                                     32);

                //
                // Set the DMA arbitration size.
                //
                USBLibDMAArbSizeSet(psInst->psDMAInstance, psInst->ui8OUTDMA,
                                    16);
            }
            break;
        }

        //
        // Handle class specific reconfiguring of the configuration descriptor
        // once the composite class has built the full descriptor.
        //
        case USB_EVENT_COMP_CONFIG:
        {
            //
            // This sets the bFirstInterface of the Interface Association
            // descriptor to the first interface which is the control
            // interface used by this instance.
            //
            pui8Data[2] = psInst->ui8InterfaceControl;

            break;
        }
        default:
        {
            break;
        }
    }
}