예제 #1
0
/**
 * Returns configuration descriptor list.
 * \param pDriver  Pointer to a USBDDriver instance.
 * \param cfgNum   Reserved.
 */
USBConfigurationDescriptor *USBDDriver_GetCfgDescriptors(
    USBDDriver *pDriver, uint8_t cfgNum)
{
    USBDDriverDescriptors *pDescList = (USBDDriverDescriptors *)pDriver->pDescriptors;
    USBConfigurationDescriptor *pCfg;

    if (USBD_HAL_IsHighSpeed() && pDescList->pHsConfiguration)
        pCfg = (USBConfigurationDescriptor *)pDescList->pHsConfiguration;
    else
        pCfg = (USBConfigurationDescriptor *)pDescList->pFsConfiguration;

    return pCfg;
}
예제 #2
0
/**
 * Configures the device by setting it into the Configured state and
 * initializing all endpoints.
 * \param pDriver  Pointer to a USBDDriver instance.
 * \param cfgnum  Configuration number to set.
 */
static void SetConfiguration(USBDDriver *pDriver, uint8_t cfgnum)
{
    USBEndpointDescriptor *pEndpoints[17];
    const USBConfigurationDescriptor *pConfiguration;

    /* Use different descriptor depending on device speed */
    if (   USBD_HAL_IsHighSpeed()
        && pDriver->pDescriptors->pHsConfiguration) {

        pConfiguration = pDriver->pDescriptors->pHsConfiguration;
    }
    else {

        pConfiguration = pDriver->pDescriptors->pFsConfiguration;
    }

    /* Set & save the desired configuration */
    USBD_SetConfiguration(cfgnum);

    pDriver->cfgnum = cfgnum;
    pDriver->isRemoteWakeUpEnabled =
        ((pConfiguration->bmAttributes & 0x20) > 0);

    /* If the configuration is not 0, configure endpoints */
    if (cfgnum != 0) {

        /* Parse configuration to get endpoint descriptors */
        USBConfigurationDescriptor_Parse(pConfiguration, 0, pEndpoints, 0);

        /* Configure endpoints */
        int i = 0;
        while (pEndpoints[i] != 0) {

            USBD_ConfigureEndpoint(pEndpoints[i]);
            i++;
        }
    }
    /* Should be done before send the ZLP */
    if (NULL != USBDDriverCallbacks_ConfigurationChanged)
        USBDDriverCallbacks_ConfigurationChanged(cfgnum);

    /* Acknowledge the request */
    USBD_Write(0, /* Endpoint #0 */
               0, /* No data buffer */
               0, /* No data buffer */
               (TransferCallback) 0,
               (void *)  0);
}
예제 #3
0
/**
 * Invoked whenever the active configuration of device is changed by the
 * host.
 * \param cfgnum Configuration number.
 */
void AUDDSpeakerDriver_ConfigurationChangeHandler(uint8_t cfgnum)
{
    AUDDSpeakerDriver *pAudd = &auddSpeakerDriver;
    AUDDSpeakerPhone *pAudf = &pAudd->fun;
    const USBDDriverDescriptors *pDescriptors = pAudf->pUsbd->pDescriptors;
    USBConfigurationDescriptor *pDesc;

    if (cfgnum > 0) {

        /* Parse endpoints for data & notification */
        if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration)
            pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration;
        else
            pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration;

        AUDDSpeakerPhone_ParseInterfaces(pAudf,
                                         (USBGenericDescriptor*)pDesc,
                                         pDesc->wTotalLength);
    }
}
예제 #4
0
/**
 * Handles configureation changed event.
 * \param cfgnum New configuration number
 */
void HIDDTransferDriver_ConfigurationChangedHandler(uint8_t cfgnum)
{
    const USBDDriverDescriptors * pDescriptors = USBD_GetDriver()->pDescriptors;
    HIDDTransferDriver * pDrv = &hiddTransferDriver;
    HIDDFunction * pHidd = &pDrv->hidFunction;

    USBConfigurationDescriptor *pDesc;

    if (cfgnum > 0) {

        /* Parse endpoints for reports */
        if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration)
            pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration;
        else
            pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration;
        HIDDFunction_ParseInterface(pHidd,
                                    (USBGenericDescriptor*)pDesc,
                                    pDesc->wTotalLength);

        /* Start polling for Output Reports */
        HIDDFunction_StartPollingOutputs(pHidd);
    }
}
예제 #5
0
파일: USBD.c 프로젝트: makerpc/bricklib
/**
 * Indicates if the device is running in high or full-speed. Always returns 0
 * since UDP does not support high-speed mode.
 */
uint8_t USBD_IsHighSpeed(void)
{
    return USBD_HAL_IsHighSpeed();
}
예제 #6
0
/**
 * Sends the requested USB descriptor to the host if available, or STALLs  the
 * request.
 * \param pDriver  Pointer to a USBDDriver instance.
 * \param type  Type of the requested descriptor
 * \param index  Index of the requested descriptor.
 * \param length  Maximum number of bytes to return.
 */
static void GetDescriptor(
    const USBDDriver *pDriver,
    uint8_t type,
    uint8_t indexRDesc,
    uint32_t length)
{
    const USBDeviceDescriptor *pDevice;
    const USBConfigurationDescriptor *pConfiguration;
    const USBDeviceQualifierDescriptor *pQualifier;
    const USBConfigurationDescriptor *pOtherSpeed;
    const USBGenericDescriptor **pStrings =
        (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings;
    const USBGenericDescriptor *pString;
    uint8_t numStrings = pDriver->pDescriptors->numStrings;
    uint8_t terminateWithNull = 0;

    /* Use different set of descriptors depending on device speed */

    /* By default, we uses full speed values */
    pDevice = pDriver->pDescriptors->pFsDevice;
    pConfiguration = pDriver->pDescriptors->pFsConfiguration;

    /* HS, we try HS values */
    if (USBD_HAL_IsHighSpeed()) {

        TRACE_DEBUG_WP("HS ");
        if (pDriver->pDescriptors->pHsDevice)
            pDevice = pDriver->pDescriptors->pHsDevice;
        if (pDriver->pDescriptors->pHsConfiguration)
            pConfiguration = pDriver->pDescriptors->pHsConfiguration;
        pQualifier = pDriver->pDescriptors->pHsQualifier;
        pOtherSpeed = pDriver->pDescriptors->pHsOtherSpeed;
    }
    else {

        TRACE_DEBUG_WP("FS ");
        pQualifier = pDriver->pDescriptors->pFsQualifier;
        pOtherSpeed = pDriver->pDescriptors->pFsOtherSpeed;
    }

    /* Check the descriptor type */

    switch (type) {

        case USBGenericDescriptor_DEVICE:
            TRACE_INFO_WP("Dev ");

            /* Adjust length and send descriptor */

            if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) {

                length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice);
            }
            USBD_Write(0, pDevice, length, 0, 0);
            break;

        case USBGenericDescriptor_CONFIGURATION:
            TRACE_INFO_WP("Cfg ");

            /* Adjust length and send descriptor */

            if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) {

                length = USBConfigurationDescriptor_GetTotalLength(pConfiguration);
                terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
            }
            USBD_Write(0,
                       pConfiguration,
                       length,
                       terminateWithNull ? TerminateCtrlInWithNull : 0,
                       0);
            break;

        case USBGenericDescriptor_DEVICEQUALIFIER:
            TRACE_INFO_WP("Qua ");

            /* Check if descriptor exists */

            if (!pQualifier) {

                USBD_Stall(0);
            }
            else {

                /* Adjust length and send descriptor */

                if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier)) {

                    length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier);
                }
                USBD_Write(0, pQualifier, length, 0, 0);
            }
            break;

        case USBGenericDescriptor_OTHERSPEEDCONFIGURATION:
            TRACE_INFO_WP("OSC ");

            /* Check if descriptor exists */

            if (!pOtherSpeed) {

                USBD_Stall(0);
            }
            else {

                /* Adjust length and send descriptor */

                if (length > USBConfigurationDescriptor_GetTotalLength(pOtherSpeed)) {

                    length = USBConfigurationDescriptor_GetTotalLength(pOtherSpeed);
                    terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
                }
                USBD_Write(0,
                           pOtherSpeed,
                           length,
                           terminateWithNull ? TerminateCtrlInWithNull : 0,
                           0);
            }
            break;

        case USBGenericDescriptor_STRING:
            TRACE_INFO_WP("Str%d ", indexRDesc);

            /* Check if descriptor exists */

            if (indexRDesc >= numStrings) {

                USBD_Stall(0);
            }
            else {

                pString = pStrings[indexRDesc];

                /* Adjust length and send descriptor */

                if (length > USBGenericDescriptor_GetLength(pString)) {

                    length = USBGenericDescriptor_GetLength(pString);
                    terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
                }
                USBD_Write(0,
                           pString,
                           length,
                           terminateWithNull ? TerminateCtrlInWithNull : 0,
                           0);
            }
            break;

        default:
            TRACE_WARNING(
                      "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r",
                      type);
            USBD_Stall(0);
    }
}