Esempio n. 1
0
/*!
 * @brief cdc open control interface.
 *
 * @param cdcInstance     cdc instance pointer.
 *
 * @return kStatus_USB_Success or error codes.
 */
static usb_status_t USB_HostCdcOpenControlInterface(usb_host_cdc_instance_struct_t *cdcInstance)
{
    usb_status_t status;
    uint8_t ep_index = 0;
    usb_host_pipe_init_t pipeInit;
    usb_descriptor_endpoint_t *ep_desc = NULL;
    usb_host_interface_t *interfaceHandle;

    if (cdcInstance->interruptPipe != NULL)
    {
        status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->interruptPipe, NULL);
        status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->interruptPipe);

        if (status != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error when close pipe\r\n");
#endif
        }
        cdcInstance->interruptPipe = NULL;
    }

    status = USB_HostOpenDeviceInterface(cdcInstance->deviceHandle, cdcInstance->controlInterfaceHandle);
    /* open interface pipes */
    interfaceHandle = (usb_host_interface_t *)cdcInstance->controlInterfaceHandle;

    for (ep_index = 0; ep_index < interfaceHandle->epCount; ++ep_index)
    {
        ep_desc = interfaceHandle->epList[ep_index].epDesc;
        if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
             USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
            ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
        {
            pipeInit.devInstance = cdcInstance->deviceHandle;
            pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
            pipeInit.direction = USB_IN;
            pipeInit.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
            pipeInit.interval = ep_desc->bInterval;
            pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
                                                USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
            pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
                                        USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
            pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;

            cdcInstance->packetSize = pipeInit.maxPacketSize;

            status = USB_HostOpenPipe(cdcInstance->hostHandle, &cdcInstance->interruptPipe, &pipeInit);
            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("USB_HostCdcSetControlInterface fail to open pipe\r\n");
#endif
                return kStatus_USB_Error;
            }
        }
    }
    return kStatus_USB_Success;
}
Esempio n. 2
0
/*!
 * @brief de-initialize the cdc instance.
 *
 * This function release the resource for cdc instance.
 *
 * @param deviceHandle   the device handle.
 * @param classHandle    the class handle.
 *
 * @retval kStatus_USB_Success        The device is de-initialized successfully.
 */
usb_status_t USB_HostCdcDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
{
    usb_status_t status;
    usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;

    if (deviceHandle == NULL)
    {
        return kStatus_USB_InvalidHandle;
    }

    if (classHandle != NULL)
    {
        if (cdcInstance->interruptPipe != NULL)
        {
            status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->interruptPipe, NULL);
            status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->interruptPipe);

            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("error when close pipe\r\n");
#endif
            }
            cdcInstance->interruptPipe = NULL;
        }

        USB_HostCloseDeviceInterface(deviceHandle, cdcInstance->controlInterfaceHandle);

        if (cdcInstance->inPipe != NULL)
        {
            status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->inPipe, NULL);
            status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->inPipe);

            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("error when close pipe\r\n");
#endif
            }
            cdcInstance->inPipe = NULL;
        }
        if (cdcInstance->outPipe != NULL)
        {
            status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->outPipe, NULL);
            status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->outPipe);

            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("error when close pipe\r\n");
#endif
            }
            cdcInstance->outPipe = NULL;
        }
        if ((cdcInstance->controlPipe != NULL) && (cdcInstance->controlTransfer != NULL))
        {
            status =
                USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->controlPipe, cdcInstance->controlTransfer);
        }
        USB_HostCloseDeviceInterface(deviceHandle, cdcInstance->dataInterfaceHandle);

        USB_OsaMemoryFree(cdcInstance);
    }
    else
    {
        USB_HostCloseDeviceInterface(deviceHandle, NULL);
    }

    return kStatus_USB_Success;
}
Esempio n. 3
0
/*!
 * @brief set data interface.
 *
 * This function bind the control interface with the cdc instance.
 *
 * @param classHandle      the class handle.
 * @param interfaceHandle  the data interface handle.
 * @param alternateSetting the alternate setting value.
 * @param callbackFn       this callback is called after this function completes.
 * @param callbackParam    the first parameter in the callback function.
 *
 * @retval kStatus_USB_Success        The device is initialized successfully.
 * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
 * @retval kStatus_USB_Busy           There is no idle transfer.
 * @retval kStatus_USB_Error          send transfer fail, please reference to USB_HostSendSetup.
 * @retval kStatus_USB_Busy           callback return status, there is no idle pipe.
 * @retval kStatus_USB_TransferStall  callback return status, the transfer is stall by device.
 * @retval kStatus_USB_Error          callback return status, open pipe fail, please reference to USB_HostOpenPipe.
 */
usb_status_t USB_HostCdcSetDataInterface(usb_host_class_handle classHandle,
                                         usb_host_interface_handle interfaceHandle,
                                         uint8_t alternateSetting,
                                         transfer_callback_t callbackFn,
                                         void *callbackParam)
{
    usb_status_t status;
    usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
    usb_host_transfer_t *transfer;

    status = kStatus_USB_Success;
    if (classHandle == NULL)
    {
        return kStatus_USB_InvalidParameter;
    }

    cdcInstance->dataInterfaceHandle = interfaceHandle;

    /* cancel transfers */
    if (cdcInstance->inPipe != NULL)
    {
        status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->inPipe, NULL);

        if (status != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error when cancel pipe\r\n");
#endif
        }
    }

    if (cdcInstance->outPipe != NULL)
    {
        status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->outPipe, NULL);

        if (status != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error when cancel pipe\r\n");
#endif
        }
    }

    if (alternateSetting == 0)
    {
        if (callbackFn != NULL)
        {
            status = USB_HostCdcOpenDataInterface(cdcInstance);
            callbackFn(callbackParam, NULL, 0, status);
        }
    }
    else
    {
        if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error to get transfer\r\n");
#endif
            return kStatus_USB_Error;
        }
        cdcInstance->controlCallbackFn = callbackFn;
        cdcInstance->controlCallbackParam = callbackParam;
        /* initialize transfer */
        transfer->callbackFn = USB_HostCdcSetDataInterfaceCallback;
        transfer->callbackParam = cdcInstance;
        transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
        transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
        transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
            ((usb_host_interface_t *)cdcInstance->dataInterfaceHandle)->interfaceDesc->bInterfaceNumber);
        transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
        transfer->setupPacket.wLength = 0;
        transfer->transferBuffer = NULL;
        transfer->transferLength = 0;
        status = USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer);

        if (status == kStatus_USB_Success)
        {
            cdcInstance->controlTransfer = transfer;
        }
        else
        {
            USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
        }
    }

    return status;
}