Example #1
0
//*****************************************************************************
//
// This function is called by the USB device stack whenever a request for a
// non-standard descriptor is received.
//
// \param pvDFUInstance is the instance data for this request.
// \param psUSBRequest points to the request received.
//
// This call parses the provided request structure and determines which
// descriptor is being requested.  Assuming the descriptor can be found, it is
// scheduled for transmission via endpoint zero.  If the descriptor cannot be
// found, the endpoint is stalled to indicate an error to the host.
//
//*****************************************************************************
static void
HandleGetDescriptor(void *pvDFUInstance, tUSBRequest *psUSBRequest)
{
    uint32_t ui32Size;

    ASSERT(pvDFUInstance != 0);

    //
    // Which type of class descriptor are we being asked for?  We only support
    // 1 type - the DFU functional descriptor.
    //
    if(((readusb16_t(&(psUSBRequest->wValue)) >> 8) == USB_DFU_FUNC_DESCRIPTOR_TYPE) &&
       ((readusb16_t(&(psUSBRequest->wValue)) & 0xFF) == 0))
    {
        //
        // If there is more data to send than the host requested then just
        // send the requested amount of data.
        //
        if((uint16_t)g_pui8DFUFunctionalDesc[0] > readusb16_t(&(psUSBRequest->wLength)))
        {
            ui32Size = (uint32_t)readusb16_t(&(psUSBRequest->wLength));
        }
        else
        {
            ui32Size = (uint32_t)g_pui8DFUFunctionalDesc[0];
        }

        //
        // Send the data via endpoint 0.
        //
        USBDCDSendDataEP0(0, g_pui8DFUFunctionalDesc, ui32Size);
    }
    else
    {
Example #2
0
//*****************************************************************************
//
// This function is called by the USB device stack whenever a request for a
// non-standard descriptor is received.
//
// \param pvInstance is the instance data for this request.
// \param pUSBRequest points to the request received.
//
// This call parses the provided request structure and determines which
// descriptor is being requested.  Assuming the descriptor can be found, it is
// scheduled for transmission via endpoint zero.  If the descriptor cannot be
// found, the endpoint is stalled to indicate an error to the host.
//
//*****************************************************************************
static void
HandleGetDescriptor(void *pvInstance, tUSBRequest *pUSBRequest)
{
    unsigned long ulSize;

    ASSERT(pvInstance != 0);

    //
    // Which type of class descriptor are we being asked for?  We only support
    // 1 type - the DFU functional descriptor.
    //
    if(((pUSBRequest->wValue >> 8) == USB_DFU_FUNC_DESCRIPTOR_TYPE) &&
       ((pUSBRequest->wValue & 0xFF) == 0))
    {
        //
        // If there is more data to send than the host requested then just
        // send the requested amount of data.
        //
        if((unsigned short)g_pDFUFunctionalDesc[0] > pUSBRequest->wLength)
        {
            ulSize = (unsigned long)pUSBRequest->wLength;
        }
        else
        {
            ulSize = (unsigned long)g_pDFUFunctionalDesc[0];
        }

        //
        // Send the data via endpoint 0.
        //
        USBDCDSendDataEP0(0, g_pDFUFunctionalDesc, ulSize);
    }
    else
    {
//*****************************************************************************
//
// Get the communication parameters in use on the UART.
//
//*****************************************************************************
static void
GetLineCoding(tLineCoding *psLineCoding)
{
    //
    // Always report 115,200, 8-N-1.
    //
    psLineCoding->ulRate = 115200;
    psLineCoding->ucDatabits = 8;
    psLineCoding->ucParity = USB_CDC_PARITY_NONE;
    psLineCoding->ucStop = USB_CDC_STOP_BITS_1;

    //
    // Send the information back to the host.
    //
    USBDCDSendDataEP0(0, (unsigned char *)psLineCoding, sizeof(tLineCoding));
}
Example #4
0
//*****************************************************************************
//
// This function is called by the USB device stack whenever a request for a
// non-standard descriptor is received.
//
// \param pvInstance is the instance data for this request.
// \param pUSBRequest points to the request received.
//
// This call parses the provided request structure and determines which
// descriptor is being requested.  Assuming the descriptor can be found, it is
// scheduled for transmission via endpoint zero.  If the descriptor cannot be
// found, the endpoint is stalled to indicate an error to the host.
//
//*****************************************************************************
static void
HandleGetDescriptor(void *pvInstance, tUSBRequest *pUSBRequest)
{
    unsigned long ulSize;
    const tUSBDDFUDevice *psDevice;
    tDFUInstance *psInst;

    ASSERT(pvInstance != 0);

    //
    // Which device are we dealing with?
    //
    psDevice = pvInstance;

    //
    // Get a pointer to our instance data.
    //
    psInst = psDevice->psPrivateDFUData;

    //
    // Which type of class descriptor are we being asked for?  We only support
    // 1 type - the DFU functional descriptor.
    //
    if(((pUSBRequest->wValue >> 8) == USB_DFU_FUNC_DESCRIPTOR_TYPE) &&
       ((pUSBRequest->wValue & 0xFF) == 0))
    {
        //
        // If there is more data to send than the host requested then just
        // send the requested amount of data.
        //
        if((unsigned short)g_pDFUFunctionalDesc[0] > pUSBRequest->wLength)
        {
            ulSize = (unsigned long)pUSBRequest->wLength;
        }
        else
        {
            ulSize = (unsigned long)g_pDFUFunctionalDesc[0];
        }

        //
        // Send the data via endpoint 0.
        //
        USBDCDSendDataEP0(USB_BASE_TO_INDEX(psInst->ulUSBBase),
                          g_pDFUFunctionalDesc, ulSize);
    }
    else
    {
Example #5
0
//*****************************************************************************
//
// This function is called by the USB device stack whenever a non-standard
// request is received.
//
// \param pvAudioDevice is the instance data for this request.
// \param psUSBRequest points to the request received.
//
// This call parses the provided request structure to the type of request and
// will respond to all commands that are understood by the class.
//
// \return None.
//
//*****************************************************************************
static void
HandleRequests(void *pvAudioDevice, tUSBRequest *psUSBRequest)
{
    uint32_t ui32Control, ui32Recipient, ui32Stall;
    tAudioInstance *psInst;
    tUSBDAudioDevice *psAudioDevice;

    ASSERT(pvAudioDevice != 0);

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

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

    //
    // Make sure to acknowledge that the data was read, this will not send and
    // ACK that has already been done at this point.  This just tells the
    // hardware that the data was read.
    //
    MAP_USBDevEndpointDataAck(USB0_BASE, USB_EP_0, false);

    //
    // Don't stall by default.
    //
    ui32Stall = 0;

    //
    // Get the request type.
    //
    ui32Recipient = psUSBRequest->bmRequestType & USB_RTYPE_RECIPIENT_M;

    //
    // Save the request type and request value.
    //
    psInst->ui16RequestType = psUSBRequest->bmRequestType;
    psInst->ui8Request = psUSBRequest->bRequest;

    //
    // Check if this is an endpoint request to the audio streaming endpoint.
    //
    if((ui32Recipient == USB_RTYPE_ENDPOINT) &&
       (readusb16_t(&(psUSBRequest->wIndex)) == USBEPToIndex(psInst->ui8OUTEndpoint)))
    {
        //
        // Determine the type of request.
        //
        switch(psInst->ui8Request)
        {
            case USB_AC_SET_CUR:
            {
                //
                // Handle retrieving the sample rate.
                //
                if(readusb16_t(&(psUSBRequest->wValue)) == SAMPLING_FREQ_CONTROL)
                {
                    //
                    // Retrieve the requested sample rate.
                    //
                    USBDCDRequestDataEP0(0,
                                         (uint8_t *)&psInst->ui32SampleRate,
                                         3);

                    //
                    // Save what we are updating.
                    //
                    psInst->ui16Update = SAMPLING_FREQ_CONTROL;
                }
                break;
            }
            case USB_AC_GET_CUR:
            {
                //
                // Handle retrieving the sample rate.
                //
                if(readusb16_t(&(psUSBRequest->wValue)) == SAMPLING_FREQ_CONTROL)
                {
                    //
                    // Send back the current sample rate.
                    //
                    USBDCDSendDataEP0(0,
                                      (uint8_t *)&psInst->ui32SampleRate,
                                      3);
                }
                break;
            }
            default:
            {
                //
                // Stall on unknown commands.
                //
                ui32Stall = 1;
                break;
            }
        }
    }
    else if(ui32Recipient == USB_RTYPE_INTERFACE)
    {
        //
        // Make sure the request was for the control interface.
        //
        if((uint8_t)readusb16_t(&(psUSBRequest->wIndex)) != psInst->ui8InterfaceControl)
        {
            return;
        }

        //
        // Extract the control value from the message.
        //
        ui32Control = readusb16_t(&(psUSBRequest->wValue)) & USB_CS_CONTROL_M;

        //
        // Handle an audio control request to the feature control unit.
        //
        if(((uint32_t)AUDIO_CONTROL_ID << 8) ==
           (readusb16_t(&(psUSBRequest->wIndex)) & USB_CS_CONTROL_M))
        {
            //
            // Determine the type of request.
            //
            switch(psInst->ui8Request)
            {
                case USB_AC_GET_MAX:
                {
                    if(ui32Control == VOLUME_CONTROL)
                    {
                        //
                        // Return the maximum volume setting.
                        //
                        USBDCDSendDataEP0(0,
                                          (uint8_t *)&psInst->i16VolumeMax,
                                          2);
                    }
                    else
                    {
                        //
                        // Stall on unknown commands.
                        //
                        ui32Stall = 1;
                    }
                    break;
                }
                case USB_AC_GET_MIN:
                {
                    if(ui32Control == VOLUME_CONTROL)
                    {
                        //
                        // Return the minimum volume setting.
                        //
                        USBDCDSendDataEP0(0,
                                          (uint8_t *)&psInst->i16VolumeMin,
                                          2);
                    }
                    else
                    {
                        //
                        // Stall on unknown commands.
                        //
                        ui32Stall = 1;
                    }
                    break;
                }
                case USB_AC_GET_RES:
                {
                    if(ui32Control == VOLUME_CONTROL)
                    {
                        //
                        // Return the volume step setting.
                        //
                        USBDCDSendDataEP0(0,
                                          (uint8_t *)&psInst->i16VolumeStep,
                                          2);
                    }
                    else
                    {
                        //
                        // Stall on unknown commands.
                        //
                        ui32Stall = 1;
                    }
                    break;
                }
                case USB_AC_GET_CUR:
                {
                    if(ui32Control == VOLUME_CONTROL)
                    {
                        //
                        // Send back the current volume level.
                        //
                        USBDCDSendDataEP0(0,
                                          (uint8_t *)&psInst->i16Volume,
                                          2);
                    }
                    else if(ui32Control == MUTE_CONTROL)
                    {
                        //
                        // Send back the current mute value.
                        //
                        USBDCDSendDataEP0(0,
                                          (uint8_t *)&psInst->ui8Mute, 1);
                    }
                    else
                    {
                        //
                        // Stall on unknown commands.
                        //
                        ui32Stall = 1;
                    }
                    break;
                }
                case USB_AC_SET_CUR:
                {
                    if(ui32Control == VOLUME_CONTROL)
                    {
                        //
                        // Read the new volume level.
                        //
                        USBDCDRequestDataEP0(0,
                                             (uint8_t *)&psInst->i16Volume,
                                             2);

                        //
                        // Save what we are updating.
                        //
                        psInst->ui16Update = VOLUME_CONTROL;
                    }
                    else if(ui32Control == MUTE_CONTROL)
                    {
                        //
                        // Read the new mute setting.
                        //
                        USBDCDRequestDataEP0(0,
                                             (uint8_t *)&psInst->ui8Mute,
                                             1);

                        //
                        // Save what we are updating.
                        //
                        psInst->ui16Update = MUTE_CONTROL;
                    }
                    else
                    {
                        //
                        // Stall on unknown commands.
                        //
                        ui32Stall = 1;
                    }
                    break;
                }
                case USB_AC_SET_RES:
                {
                    if(ui32Control == VOLUME_CONTROL)
                    {
                        //
                        // Read the new volume step setting.
                        //
                        USBDCDRequestDataEP0(0,
                            (uint8_t *)&psInst->i16VolumeStep, 2);

                        //
                        // Save what we are updating.
                        //
                        psInst->ui16Update = VOLUME_CONTROL;
                    }
                    else
                    {
                        //
                        // Stall on unknown commands.
                        //
                        ui32Stall = 1;
                    }
                    break;
                }
                default:
                {
                    //
                    // Stall on unknown commands.
                    //
                    ui32Stall = 1;
                    break;
                }
            }
        }
    }

    //
    // Stall on all unknown commands.
    //
    if(ui32Stall)
    {
        USBDCDStallEP0(0);
    }
}