Esempio n. 1
0
/*FUNCTION*----------------------------------------------------------------
 *
 * Function Name  : kbd_hid_get_buffer
 * Returned Value : none
 * Comments       :
 *     used to get the buffer to store the data transferred from device.
 *
 *END*--------------------------------------------------------------------*/
uint32_t kbd_hid_get_buffer(void)
{
    uint8_t ep_no;
    usb_device_ep_struct_t *lpEp;
    /* first get the max packet size from interface info */
    usb_device_interface_struct_t* lpHostIntf = (usb_device_interface_struct_t*) kbd_hid_get_interface();
    for (ep_no = 0; ep_no < lpHostIntf->ep_count; ep_no++)
    {
        lpEp = &lpHostIntf->ep[ep_no];
        if (((lpEp->lpEndpointDesc->bEndpointAddress & IN_ENDPOINT) != 0) && ((lpEp->lpEndpointDesc->bmAttributes & IRRPT_ENDPOINT) != 0))
        {
            kbd_size = (USB_SHORT_UNALIGNED_LE_TO_HOST(lpEp->lpEndpointDesc->wMaxPacketSize) & PACKET_SIZE_MASK);
            break;
        }
    }

    if ((kbd_size != 0) && (kbd_buffer == NULL))
    {
        kbd_buffer = (uint8_t*) OS_Mem_alloc_uncached_zero(kbd_size);
        if (kbd_buffer == NULL)
        {
            USB_PRINTF("allocate memory failed in hid_get_buffer\r\n");
            return (uint32_t)(-1);
        }
    }
    return 0;
}
Esempio n. 2
0
/*FUNCTION*----------------------------------------------------------------
 *
 * Function Name  : kbd_hid_get_buffer
 * Returned Value : none
 * Comments       :
 *     Find and parse the HID descriptor, then try to get the report descriptor.
 *
 *END*--------------------------------------------------------------------*/
void kbd_hid_get_report_descriptor(void)
{
    usb_status status = USB_OK;
    usb_device_interface_struct_t* interfaceDescriptor = (usb_device_interface_struct_t*) kbd_hid_get_interface();
    descriptor_union_t ptr1, ptr2;
    ptr1.pntr = interfaceDescriptor->interfaceEx;
    ptr2.word = ptr1.word + interfaceDescriptor->interfaceExlength;

    while (ptr1.cfig->bDescriptorType != USB_DESC_TYPE_HID)
    {
        ptr1.word += ptr1.cfig->bLength;
        if (ptr1.word >= ptr2.word)
        {
            break;
        }
    }

    if (ptr1.word < ptr2.word)
    {
        hid_descriptor_struct_t* hidDescriptor = (hid_descriptor_struct_t*) ptr1.pntr;
        hid_class_descriptor_struct_t* hidClassDescriptor = (hid_class_descriptor_struct_t*) &(hidDescriptor->bclassdescriptortype);
        uint8_t index;
        kbd_reportLength = 0;
        for (index = 0; index < hidDescriptor->bnumdescriptor; index++)
        {
            hid_class_descriptor_struct_t* temp;
            temp = hidClassDescriptor + index;
            if (temp->classdescriptortype == USB_DESC_TYPE_REPORT)
            {
                kbd_reportLength = USB_SHORT_UNALIGNED_LE_TO_HOST(temp->descriptorlength);
                break;
            }
        }
        if (kbd_reportLength != 0)
        {

            if (kbd_reportDescriptor != NULL)
            {
                OS_Mem_free(kbd_reportDescriptor);
            }
            kbd_reportDescriptor = (uint8_t*) OS_Mem_alloc_uncached_zero(kbd_reportLength);
            if (kbd_reportDescriptor == NULL)
            {
                USB_PRINTF("allocate memory failed in hid_get_buffer\r\n");
                return;
            }

            kbd_hid_device.DEV_STATE = USB_DEVICE_GET_REPORT_DESCRIPTOR;
            kbd_hid_com->class_ptr = kbd_hid_device.CLASS_HANDLE;
            kbd_hid_com->callback_fn = usb_host_hid_keyboard_ctrl_callback;
            kbd_hid_com->callback_param = 0;

            status = usb_class_hid_get_descriptor(kbd_hid_com, (uint8_t) USB_DESC_TYPE_REPORT, kbd_reportDescriptor, kbd_reportLength);

            if (status != USB_OK)
            {
                USB_PRINTF("\r\nError in usb_class_hid_get_descriptor: %x\r\n", status);
            }
        }
    }
    else
    {
        USB_PRINTF("Can't find HID_DESCRIPTOR\r\n");
    }
    return;
}
Esempio n. 3
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_cntrl_transaction_done
* Returned Value : none
* Comments       :
*     Callback function to process transaction-done events
*     State machine for enumeration/subsequent transactions
*     Between states, the 8-byte buffer in device_instance
*        is used to save the first part of the configuration.
*     Pointer desc in various flavors (uint8_t *, cfig_ptr)
*        is used to parse this buffer in various ways. 
* 
*END*--------------------------------------------------------------------*/
static void  usb_host_cntrl_transaction_done
(
    /* [IN] Unused */
    void*           tr_ptr,
    /* [IN] The user parameter */
    void*           user_parm,
    /* [IN] the buffer */
    uint8_t *         buffer,
    /* [IN] The length of the transfer */
    uint32_t           length,
    /* [IN] status of the transfer */
    usb_status        status
)
{
    usb_host_state_struct_t*    usb_host_ptr;
    dev_instance_t*             dev_inst_ptr = (dev_instance_t*)user_parm;
    pipe_struct_t*              pipe_ptr = dev_inst_ptr->control_pipe;
    descriptor_union_t          desc;
    int32_t                     config_size = 0;

    uint32_t                   aligned_config_size = 0;
	usb_host_api_functions_struct_t* host_api;
#ifdef USBCFG_OTG
    static bool                otg_hnp_support;
#endif
    usb_host_ptr = (usb_host_state_struct_t*)dev_inst_ptr->host;

	host_api = (usb_host_api_functions_struct_t*)usb_host_ptr->host_controller_api;


    if (usb_host_release_tr(usb_host_ptr, tr_ptr) != USB_OK)
    {
        printf("_usb_host_release_tr failed\n");
    }

    switch (status)
    {
        case USB_OK:
            dev_inst_ptr->ctrl_retries = USBCFG_HOST_CTRL_RETRY;
            dev_inst_ptr->stall_retries = USBCFG_HOST_CTRL_RETRY;
            break;
  
        case USBERR_TR_FAILED:
        case USBERR_ENDPOINT_STALLED:
        
            //printf("TR failed buffer : %x\n\r", buffer);
            dev_inst_ptr->ctrl_retries--;
            dev_inst_ptr->stall_retries--;
            if ((status == USBERR_ENDPOINT_STALLED)&&(dev_inst_ptr->stall_retries))
            {
               printf("USBERR_ENDPOINT_STALLED\n");
               status = _usb_host_ch9_clear_feature((usb_device_instance_handle)dev_inst_ptr, REQ_TYPE_ENDPOINT, 0, ENDPOINT_HALT);
            }
            else if ((dev_inst_ptr->stall_retries == 0) || ((dev_inst_ptr->ctrl_retries)&&(status == USBERR_TR_FAILED)))
            {
                /* if hub level is 1 will do port reset */
				if(dev_inst_ptr->level == 1)
                {
                    host_api = (usb_host_api_functions_struct_t*)usb_host_ptr->host_controller_api;

                    if (host_api->host_bus_control != NULL)
                    {
                        host_api->host_bus_control(usb_host_ptr->controller_handle, 1);
                    }
                    status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
                                                              USB_DESC_TYPE_DEV << 8, 0, 8, 
                                                              (uint8_t *)buffer);
                    dev_inst_ptr->state = DEVSTATE_DEVDESC8;
                }
                else  
                {
#if USBCFG_HOST_HUB                   
                    usb_host_hub_Port_Reset(dev_inst_ptr->hub_instance, dev_inst_ptr->port_no);
                    usb_host_dev_mng_detach(dev_inst_ptr->host, dev_inst_ptr->hub_no, dev_inst_ptr->port_no);
#endif
                }
            }

            break;
  
        
        default:
            break;
    }

    if (status != USB_OK)
    {
        return;
    }

    /*----------------------------------------------------**
    ** Enumeration state machine -- cases are named after **
    ** the just-completed transactions.                   **
    **----------------------------------------------------*/

    switch (dev_inst_ptr->state)
    {
        case DEVSTATE_INITIAL:      /* initial device state = forever error state */
            break;   
        case DEVSTATE_DEVDESC8:     /* device descriptor [0..7]*/
            /* We must have received the first 8 bytes in 
                    * dev_inst_ptr->dev_descriptor which contains the 
                    * max packet size for this control endpoint 
                    */
            //printf("dev8\n");
            pipe_ptr->max_packet_size = dev_inst_ptr->dev_descriptor.bMaxPacketSize;
            //printf("DEVSTATE_DEVDESC8 %d\n",dev_inst_ptr->dev_descriptor.bMaxPacketSize);
              
            /* Notify device driver of MaxPacketSize0 for this device */
            status = _usb_host_update_max_packet_size_call_interface (usb_host_ptr, pipe_ptr);
           
            if (status != USB_OK)
            {
                printf("update max packet size error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
            else
            {
                dev_inst_ptr->state = DEVSTATE_ADDR_SET;
            }
  
            /* Now set the address that we assigned when we initialized 
                    * the device instance struct for this device 
                    */
            status = _usb_host_ch9_set_address((usb_device_instance_handle)dev_inst_ptr);
            
            if (status != USB_OK)
            {
                printf("set address error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
   
            break;
       case DEVSTATE_ADDR_SET:     /* address set */
            //pipe_ptr->DEVICE_ADDRESS = dev_inst_ptr->address;
         //   printf("add set %d\n", dev_inst_ptr->target_address);
            dev_inst_ptr->address = dev_inst_ptr->target_address;
            /* Notify device driver of USB device's new address */
            status = _usb_host_update_device_address_call_interface (usb_host_ptr, pipe_ptr);
            
            if (status != USB_OK)
            {
                printf("update device address error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
            dev_inst_ptr->state = DEVSTATE_DEV_DESC;
            //printf("descriptor address 0x%x\n", &dev_inst_ptr->dev_descriptor);
            /* Now get the full descriptor */
            status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
                USB_DESC_TYPE_DEV << 8, 
                0, 
                USB_DESC_LEN_DEV,
                (uint8_t *)&dev_inst_ptr->dev_descriptor);
               
            if (status != USB_OK)
            {
                printf("get device descriptor error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
   
            break;   
       case DEVSTATE_DEV_DESC:     /* full device descriptor received */
            /* Now lets get the first 9 bytes of the configuration descriptor 
                    */
            desc.pntr = &dev_inst_ptr->buffer;
            //printf("dev %d cfg, c %d 0x%x\n", dev_inst_ptr->dev_descriptor.bNumConfigurations, dev_inst_ptr->cfg_value, desc.pntr);
            dev_inst_ptr->state = DEVSTATE_GET_CFG9;
            status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
               USB_DESC_TYPE_CFG << 8 | dev_inst_ptr->cfg_value, 
               0, 
               sizeof(dev_inst_ptr->buffer),
               desc.bufr);
               
            if (status != USB_OK)
            {
                printf("get 9 byte configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
   
            break;
      case DEVSTATE_GET_CFG9:     /* Read 9 bytes of config descriptor */
          
            /* Now select the configuration as specified in the 
                    * descriptor 
                    */
            desc.cfig = (usb_configuration_descriptor_t*)dev_inst_ptr->buffer;
            config_size = USB_SHORT_UNALIGNED_LE_TO_HOST(desc.cfig->wTotalLength);
            
            /* for KHCI, the start address and the length should be 4 byte align */
            if ((config_size && 0x3) != 0)
            {
                aligned_config_size = (config_size & 0xFFFFFFFC) + 4;
            }

            if (dev_inst_ptr->lpConfiguration != NULL)
            {
                OS_Mem_free(dev_inst_ptr->lpConfiguration);
                dev_inst_ptr->lpConfiguration = NULL;
            }

            dev_inst_ptr->lpConfiguration = (void*)OS_Mem_alloc_uncached(aligned_config_size);
       
            if (dev_inst_ptr->lpConfiguration == NULL)
            {
                printf("get memory for full configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
           
            //printf("Get CFG9 %d %d %d\n",dev_inst_ptr->cfg_value, config_size,dev_inst_ptr->dev_descriptor.bNumConfigurations);
       
            /* We can only read one config descriptor at a time */
            status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
               (USB_DESC_TYPE_CFG << 8) | dev_inst_ptr->cfg_value, 
               0, 
               (uint16_t)config_size,
               dev_inst_ptr->lpConfiguration);
               
            if (status != USB_OK)
            {
                printf("get full configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }    
#ifdef USBCFG_OTG
            dev_inst_ptr->state = DEVSTATE_CHK_OTG;
#else
            /*dev_inst_ptr->state = DEVSTATE_SET_CFG;*/
            dev_inst_ptr->state = DEVSTATE_CFG_READ;
#endif
           break;  

#ifdef USBCFG_OTG
        case DEVSTATE_CHK_OTG:
            otg_hnp_support = FALSE;
            /* Point to the memory owned by this device */
            /* FIXME: it is presumed that memlist points to the config descriptor */
            desc.pntr = dev_inst_ptr->lpConfiguration;

            /* We will always start with config desc so update the search pointer */
            config_size = USB_SHORT_UNALIGNED_LE_TO_HOST(desc.cfig->wTotalLength);
            config_size -= desc.cfig->bLength;
            desc.word += desc.cfig->bLength;
       
            while (config_size)
            {
                if (desc.otg->bDescriptorType == USB_DESC_TYPE_OTG)
                {
                    /* Found the OTG descriptor */
                    break;
                }
                config_size -= desc.intf->bLength;
                desc.word += desc.intf->bLength;
            }

            /* Check for an OTG descriptor */
            dev_inst_ptr->state = DEVSTATE_CFG_READ;
       
            if (config_size && desc.otg->bDescriptorType == USB_DESC_TYPE_OTG &&
               (desc.otg->bmAttributes & OTG_HNP_SUPPORT))
            {
                otg_hnp_support = TRUE;
                if(_usb_otg_host_get_otg_attribute(usb_host_ptr->otg_handle,desc.otg->bmAttributes) == USB_OK)
                {
                    if(_usb_otg_host_set_feature_required(usb_host_ptr->otg_handle))
                    {
                        status = _usb_host_ch9_set_feature(dev_inst_ptr, 0, 0, OTG_A_HNP_SUPPORT);
                       
                        if (status != USB_OK)
                        {
                            printf("set feature for otg error\n");
                            usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                            break;
                        }
                        
                        else
                        {
                            dev_inst_ptr->state = DEVSTATE_SET_HNP;  
                            break;
                        }
                    }
                }
            }
        case DEVSTATE_SET_HNP:
            if (otg_hnp_support)
            {
                status = _usb_host_ch9_set_feature(dev_inst_ptr, 0, 0, OTG_B_HNP_ENABLE);
                if (status != USB_OK)
                {
                    dev_inst_ptr->state = DEVSTATE_INITIAL;
                }
                else
                {
                    dev_inst_ptr->state = DEVSTATE_SET_HNP_OK;
                }
                break; 
            }
        case  DEVSTATE_SET_HNP_OK:
            if(dev_inst_ptr->state == DEVSTATE_SET_HNP_OK)
            {
                _usb_otg_host_a_set_b_hnp_en(usb_host_ptr->otg_handle, TRUE);
            }
#endif  
        case DEVSTATE_CFG_READ:
            dev_inst_ptr->cfg_value++;
            //printf("cfg %d, %d\n", dev_inst_ptr->cfg_value,dev_inst_ptr->dev_descriptor.bNumConfigurations);
            if (usb_host_dev_mng_parse_configuration_descriptor(dev_inst_ptr) == USB_OK)
            {
                //printf("parse cfg\n");
                if (usb_host_dev_mng_check_configuration(dev_inst_ptr))
                {
                    //printf("check cfg\n");
                    usb_host_dev_notify(dev_inst_ptr, USB_ATTACH_EVENT);
                    /* enumeration done */
                    dev_inst_ptr->state = DEVSTATE_SET_CFG;
                    /* send set_configuration */
                    status = _usb_host_ch9_set_configuration(dev_inst_ptr, dev_inst_ptr->configuration.lpconfigurationDesc->bConfigurationValue);
                    if (status != USB_OK)
                    {
                        printf("set configuration(%d) error\n", dev_inst_ptr->cfg_value);
                        usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                        break;
                    }
                }
                else
                {
                    //printf("cfg %d %d\n", dev_inst_ptr->cfg_value,dev_inst_ptr->dev_descriptor.bNumConfigurations);
                    /* get next configuration */
                    if (dev_inst_ptr->cfg_value < dev_inst_ptr->dev_descriptor.bNumConfigurations)
                    {
                        //printf("invalid cfg re\n");
                        desc.pntr = &dev_inst_ptr->buffer;
                        dev_inst_ptr->state = DEVSTATE_GET_CFG9;
                        status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
                            USB_DESC_TYPE_CFG << 8 | dev_inst_ptr->cfg_value, 
                            0, 
                            sizeof(dev_inst_ptr->buffer),
                            desc.bufr);
                        if (status != USB_OK)
                        {
                            printf("get 9 byte configuration(%d) error\n", dev_inst_ptr->cfg_value);
                            usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                            break;
                        }
                   }
                   else
                   {
                       printf("unsupported device attached\n");
                       usb_host_dev_notify(dev_inst_ptr, USB_ATTACH_DEVICE_NOT_SUPPORT);
                       usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                       break;
                   }
               }
            }
            else
            {
                printf("parse configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
            break;
        case DEVSTATE_SET_CFG:     /* config descriptor [0..8] */
            dev_inst_ptr->state = DEVSTATE_ENUM_OK;
            usb_host_dev_notify(dev_inst_ptr, USB_CONFIG_EVENT);
#ifdef USBCFG_OTG
            _usb_otg_host_on_interface_event(usb_host_ptr->otg_handle, dev_inst_ptr);
#endif
            break;

        case DEVSTATE_SET_INTF:    /* Select interface done */
            dev_inst_ptr->state = DEVSTATE_ENUM_OK;
            usb_host_dev_notify(dev_inst_ptr, USB_INTF_OPENED_EVENT);
            break;
        case DEVSTATE_ENUM_OK:   /* enumeration complete */
            if ((dev_inst_ptr->control_callback != NULL))
            {
                dev_inst_ptr->control_callback(tr_ptr, dev_inst_ptr->control_callback_param, buffer, length, status);
            }
            break;
        default:
            break;
    } /* EndSwitch */
} /* EndBody */
Esempio n. 4
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_dev_mng_parse_configuration_descriptor
* Returned Value : USB_OK or error
* Comments       :
*     parse the configuration descriptor of device
*
*END*--------------------------------------------------------------------*/
usb_status usb_host_dev_mng_parse_configuration_descriptor(usb_device_instance_handle dev_handle)//, uint8_t desc_index)
{
    dev_instance_t*                 dev_ptr;
    descriptor_union_t                 ptr1, ptr2;
    //uint8_t                          interface_count = 0;
    //uint8_t                          ep_count = 0;
    usb_device_ep_struct_t *           pEndpoint = NULL;
    usb_device_interface_struct_t *    pInterface = NULL;
    usb_device_configuration_struct_t* pConfiguration = NULL;
    usb_status                       ret = USB_OK;

    /* Check that device handle points to a device */
    dev_ptr = (dev_instance_t*)dev_handle;

    if (dev_ptr->state < DEVSTATE_CFG_READ)
    {
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_hostdev_get_descriptor device busy");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_BUSY);
    } /* Endif */

  
      /*--------------------------------------------------------**
      ** If descriptor type is Configuration, the pointer is    **
      **    found in ptr1.  Other types of descriptor need      **
      **    to be found by stepping through the config one      **
      **    descriptor at a time.                               **
      ** To prevent parsing past the config buffer, ptr2 is     **
      **    set to the starting address plus its total size.    **
      **--------------------------------------------------------*/

    ptr1.pntr = dev_ptr->lpConfiguration; /* offset for alignment */
    if (ptr1.cfig->bNumInterfaces > USBCFG_HOST_MAX_INTERFACE_PER_CONFIGURATION)
    {
        return USBERR_ERROR;
    }

    /* for the configuration descriptor, the first descriptor must be configuration descriptor */
    if ((ptr1.cfig->bLength == USB_DESC_LEN_CFG) && (ptr1.cfig->bDescriptorType == USB_DESC_TYPE_CFG))
    {
        ptr2.word = ptr1.word + USB_SHORT_UNALIGNED_LE_TO_HOST(ptr1.cfig->wTotalLength);
        pConfiguration = &dev_ptr->configuration;//(usb_device_configuration_struct_t*)OS_Mem_alloc(sizeof(USB_HOST_CONFIGURATION_STRUCT));
        
        pConfiguration->lpconfigurationDesc = (usb_configuration_descriptor_t*)ptr1.cfig;
        pConfiguration->configurationExlength = 0;
        pConfiguration->configurationEx = NULL;
        pConfiguration->interface_count = 0;

        ptr1.word += ptr1.cfig->bLength;
        while (ptr1.word < ptr2.word)
        {
            if (ptr1.common->bDescriptorType != USB_DESC_TYPE_IF)
            {
                if (pConfiguration->configurationEx == NULL)
                {
                    pConfiguration->configurationEx = (uint8_t*)ptr1.bufr;
                }
                pConfiguration->configurationExlength += ptr1.common->bLength;
                ptr1.word += ptr1.common->bLength;
            }
            else
            {
                break;
            }
        }
        while (ptr1.word < ptr2.word)
        {
            /* the first interface descriptor found */
            if (ptr1.common->bDescriptorType == USB_DESC_TYPE_IF)
            {
                if (ptr1.intf->bNumEndpoints > USBCFG_HOST_MAX_EP_PER_INTERFACE)
                {
                    printf("too many endpoints in one interface, please increase the USBCFG_HOST_MAX_EP_PER_INTERFACE value\n");
                    ret = USBERR_ERROR;
                    break;
                }

                if (pConfiguration->interface_count >= USBCFG_HOST_MAX_INTERFACE_PER_CONFIGURATION)
                {
                    printf("too many interfaces in one configuration, please increase the USBCFG_HOST_MAX_INTERFACE_PER_CONFIGURATION value\n");
                    ret = USBERR_ERROR;
                    break;
                }

                /* now ptr1 point to interface descriptor */
                pInterface = (usb_device_interface_struct_t*)&pConfiguration->interface[pConfiguration->interface_count];//OS_Mem_alloc_zero(sizeof(USB_HOST_INTF_STRUCT));
                pConfiguration->interface_count++;
                pInterface->lpinterfaceDesc = ptr1.intf;
                pInterface->interfaceExlength = 0;
                pInterface->interfaceEx = NULL;
                pInterface->ep_count = 0;

                ptr1.word += ptr1.common->bLength;

                while(ptr1.word < ptr2.word)
                {
                    if ((ptr1.common->bDescriptorType != USB_DESC_TYPE_IF) &&
                        (ptr1.common->bDescriptorType != USB_DESC_TYPE_EP))
                    {
                        if (pInterface->interfaceEx == NULL)
                        {
                            pInterface->interfaceEx = (uint8_t*)ptr1.bufr;
                        }
                        pInterface->interfaceExlength += ptr1.common->bLength;
                        ptr1.word += ptr1.common->bLength;
                    }
                    else
                    {
                        break;
                    }
                }

                /* now try to get the endpoint information */
                if (pInterface->lpinterfaceDesc->bNumEndpoints == 0)
                    continue;

                /* now the ptr1 should point to endpoint descriptor */
                if (ptr1.common->bDescriptorType != USB_DESC_TYPE_EP)
                {
                    printf("interface descriptor error\n");
                    ret = USBERR_ERROR;
                    break;
                }

                for (; pInterface->ep_count < pInterface->lpinterfaceDesc->bNumEndpoints; (pInterface->ep_count)++)
                {
                    if ((ptr1.ndpt->bDescriptorType != USB_DESC_TYPE_EP) ||
                        (ptr1.word >= ptr2.word))
                    {
                        printf("endpoint descriptor error\n");
                        ret = USBERR_ERROR;
                        break;
                    }
                    pEndpoint = (usb_device_ep_struct_t*)&pInterface->ep[pInterface->ep_count];
                    pEndpoint->lpEndpointDesc = ptr1.ndpt;
                    ptr1.word += ptr1.common->bLength;

                    while(ptr1.word < ptr2.word)
                    {
                        if ((ptr1.common->bDescriptorType != USB_DESC_TYPE_EP) &&
                            (ptr1.common->bDescriptorType != USB_DESC_TYPE_IF))
                        {
                            if (pEndpoint->endpointEx == NULL)
                            {
                                pEndpoint->endpointEx = (uint8_t*)ptr1.bufr;
                            }
                            pEndpoint->endpointExlength += ptr1.common->bLength;
                            ptr1.word += ptr1.common->bLength;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (ret != USB_OK)
                    break;
            }
            else
            {
                ret = USBERR_ERROR;
                break;
            }
        }
        
        dev_ptr->num_of_interfaces = pConfiguration->interface_count;
        return ret;
    } /* EndIf */
    else
    {
        return USBERR_INVALID_CFIG_NUM;
    }
} /* Endbody */
Esempio n. 5
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_cntrl_request
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process class- or vendor-specific control pipe device
*     requests.
*
*END*--------------------------------------------------------------------*/
usb_status  _usb_hostdev_cntrl_request
(
    /* usb device */
    usb_device_instance_handle    dev_handle,
    /* Device Request to send */
    usb_setup_t*                  devreq,
    /* buffer to send/receive */
    uint8_t *                     buff_ptr,
    /* callback upon completion */
    tr_callback                   callback,
    /* [IN] the parameter to pass back to the callback function */
    void*                         callback_param
)
{ /* Body */
    dev_instance_t*           dev_ptr;
    usb_pipe_handle           pipe_handle;
    tr_struct_t                  tr;
    usb_status                 error = USB_OK;

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request");
    #endif

    /* Verify that device handle is valid */
    OS_Lock();
    error = usb_hostdev_validate(dev_handle);

    if (error != USB_OK) 
    {
        OS_Unlock();
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
    } /* Endif */

    dev_ptr = (dev_instance_t*)dev_handle;

    if (dev_ptr->state < DEVSTATE_ENUM_OK) 
    {
        OS_Unlock();
        #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, no device found");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */

    pipe_handle = dev_ptr->control_pipe;
    usb_hostdev_tr_init(&tr, callback, callback_param);

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & devreq->bmrequesttype) != 0) 
    {
        tr.rx_buffer = buff_ptr;
        tr.rx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq->wlength);
    } 
    else 
    {
        tr.TX_BUFFER = buff_ptr;
        tr.tx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq->wlength);
    } /* EndIf */

    tr.setup_packet = *devreq;
    error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);

    OS_Unlock();

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request,SUCCESSFUL");
    #endif

    return USB_log_error(__FILE__,__LINE__,error);
}
Esempio n. 6
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_ch9_dev_req
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device requests in Chapter 9.
*        See Table 9-3 p. 250 of USB 2.0 specification.
*     This code does minimal error checking, on the assumption
*        that it is called only from wrappers in this file.
*     It is presumed that this function is called with USB interrupts disabled
* 
*END*--------------------------------------------------------------------*/
static usb_status  usb_host_ch9_dev_req
(
    /* usb device */
    usb_device_instance_handle   dev_handle,
    /* Device Request to send */
    usb_setup_t*                 devreq_ptr,
    /* buffer to send/receive */
    uint8_t *                    buff_ptr
)
{
    dev_instance_t*           dev_ptr;
    usb_pipe_handle           pipe_handle;
    tr_struct_t*              tr_ptr;
    usb_status                 error;

    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_host_ch9_dev_req");
    #endif
    
    /* Verify that device handle is valid */
    error = usb_hostdev_validate(dev_handle);
    if (error != USB_OK) 
    {
        #ifdef _HOST_DEBUG_
          DEBUG_LOG_TRACE("usb_host_ch9_dev_req device not found");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
    } /* Endif */

    dev_ptr = (dev_instance_t*)dev_handle;
    pipe_handle = dev_ptr->control_pipe;

    if (usb_host_get_tr(dev_ptr->host, dev_ptr->control_callback, dev_ptr->control_callback_param, &tr_ptr) != USB_OK)
    {
        printf("error to get tr ch9\n");
        return USBERR_ERROR;
    }

    /* Set buffer length if required */
    switch (devreq_ptr->brequest)
    {
        case REQ_SET_DESCRIPTOR:
            tr_ptr->tx_buffer = buff_ptr;
            tr_ptr->tx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->wlength);
            break;
        case REQ_GET_CONFIGURATION:
        case REQ_GET_DESCRIPTOR:
        case REQ_GET_INTERFACE:
        case REQ_GET_STATUS:
        case REQ_SYNCH_FRAME:
            tr_ptr->rx_buffer = buff_ptr;
            tr_ptr->rx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->wlength);
            break;
    } /* EndSwitch */

    tr_ptr->setup_packet = *devreq_ptr;

    if ((dev_ptr->state < DEVSTATE_ENUM_OK) ||
        (tr_ptr->callback == NULL))
    {
        tr_ptr->callback = usb_host_cntrl_transaction_done;
        tr_ptr->callback_param = dev_ptr;
    } /* Endif */

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_host_ch9_dev_req SUCCESSFUL");
    #endif
    error = usb_host_send_setup(dev_ptr->host, pipe_handle, tr_ptr);

    return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */
Esempio n. 7
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_set_stream_inf
* Returned Value : None
* Comments       :
*     This function is called by common class to initialize the class driver. It
*     is called in response to a select interface call by application
*
*END*--------------------------------------------------------------------*/
usb_status usb_class_video_set_stream_inf
(
    class_handle                    class_handle,
    uint8_t                          inf_alternate
)
{ /* Body */
    usb_video_stream_struct_t*      video_stream_ptr = NULL;
    endpoint_descriptor_t*          ep_desc = NULL;
    uint8_t                         ep_num = 0;
    pipe_init_struct_t              pipe_init;
    usb_status                      status;
    
    video_stream_ptr = (usb_video_stream_struct_t*)class_handle;
    if (video_stream_ptr == NULL)
    {
        return USBERR_ERROR;
    }

    if(video_stream_ptr->current_stream_interface_ptr->bAlternateSetting == inf_alternate)
    {
        return USBERR_ERROR;
    }

    if(video_stream_ptr->stream_interface_ptr->alternate_setting_num < inf_alternate)
    {
        return USBERR_ERROR;
    }

    if (video_stream_ptr->stream_iso_in_pipe != NULL)
    {
        usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_in_pipe, NULL);
        usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_in_pipe);
    }
    if (video_stream_ptr->stream_iso_out_pipe != NULL)
    {
        usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_out_pipe, NULL);
        usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_out_pipe);
    }
    if (video_stream_ptr->stream_bulk_in_pipe != NULL)
    {
        usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_in_pipe, NULL);
        usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_in_pipe);
    }
    if (video_stream_ptr->stream_bulk_out_pipe != NULL)
    {
        usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_out_pipe, NULL);
        usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_out_pipe);
    }
    usb_class_video_fill_endpoint_descriptor(video_stream_ptr, inf_alternate);

    for (ep_num = 0; ep_num < video_stream_ptr->altrnate_if_ep_num; ep_num++)
    {
        ep_desc = video_stream_ptr->altrnate_if_ep_descriptor_list[ep_num].lpEndpointDesc;
        if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_RECV;
            pipe_init.pipetype         = USB_ISOCHRONOUS_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = video_stream_ptr->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_in_pipe, &pipe_init);
            if (status != USB_OK)
            {
#ifdef _DEBUG
                USB_PRINTF("usb_class_video_set_stream_inf fail to open in pipe\n");
#endif
                return USBERR_ERROR;
            }
        }
        else if ((ep_desc->bEndpointAddress & OUT_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_SEND;
            pipe_init.pipetype         = USB_ISOCHRONOUS_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = video_stream_ptr->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_out_pipe, &pipe_init);
            if (status != USB_OK)
            {
#ifdef _DEBUG
                USB_PRINTF("usb_class_video_set_stream_inf fail to open in pipe\n");
#endif
                return USBERR_ERROR;
            }
        }
    }
    //USB_PRINTF("usb_class_video_set_stream_inf\n");
    
    return USB_OK;
   
} /* Endbody */
Esempio n. 8
0
usb_status usb_class_hub_init
   (
      /* [IN]  the device handle related to the class driver */
        usb_device_instance_handle      dev_handle,
        /* [IN]  the interface handle related to the class driver */
        usb_interface_descriptor_handle intf_handle,
        /* [OUT] printer call struct pointer */
        class_handle*                    class_handle_ptr
   )
{ /* Body */
    usb_hub_class_struct_t*       hub_class = NULL;
    usb_device_interface_struct_t*   pDeviceIntf = NULL;
    //interface_descriptor_t*       intf = NULL;
    endpoint_descriptor_t*        ep_desc = NULL;
    uint8_t                         ep_num;
    usb_status                     status = USB_OK;
    pipe_init_struct_t               pipe_init;
    uint8_t                        level = 0xFF;
 
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_init");
    #endif

    level = usb_host_dev_mng_get_level(dev_handle);

    if (level > 5)
    {
        USB_PRINTF("Too many level of hub attached\n");
        *class_handle_ptr = NULL;
        return USBERR_ERROR;
    }
    
    hub_class = (usb_hub_class_struct_t*)OS_Mem_alloc_zero(sizeof(usb_hub_class_struct_t));
    if (hub_class == NULL)
    {
        USB_PRINTF("usb_class_hub_init fail on memory allocation\n");
        *class_handle_ptr = NULL;
        return USBERR_ERROR;
    }

    hub_class->dev_handle  = dev_handle;
    hub_class->intf_handle = intf_handle;
    hub_class->host_handle = usb_host_dev_mng_get_host(hub_class->dev_handle);
    hub_class->level = usb_host_dev_mng_get_level(hub_class->dev_handle);

    pDeviceIntf = (usb_device_interface_struct_t*)intf_handle;
    //intf = pDeviceIntf->lpinterfaceDesc;

    for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++)
    {
        ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc;
        if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == IRRPT_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_RECV;
            pipe_init.pipetype         = USB_INTERRUPT_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = hub_class->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(hub_class->host_handle, &hub_class->interrupt_pipe, &pipe_init);
            if (status != USB_OK)
            {
                USB_PRINTF("usb_class_hid_init fail to open in pipe\n");
                *class_handle_ptr = (class_handle)hub_class;
                return USBERR_ERROR;
            }
        }
    }
    hub_class->control_pipe = usb_host_dev_mng_get_control_pipe(hub_class->dev_handle);
    *class_handle_ptr = hub_class;
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_init, SUCCESSFUL");
    #endif
    return USB_OK;
} /* Endbody */
Esempio n. 9
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_control_init
* Returned Value : None
* Comments       :
*     This function is called by common class to initialize the class driver. It
*     is called in response to a select interface call by application
*
*END*--------------------------------------------------------------------*/
usb_status usb_class_video_control_init
(
    /* [IN]  the device handle related to the class driver */
    usb_device_instance_handle      dev_handle,
    /* [IN]  the interface handle related to the class driver */
    usb_interface_descriptor_handle intf_handle,
    /* [OUT] printer call struct pointer */
    class_handle*                    class_handle_ptr
)
{ /* Body */
    usb_video_control_struct_t*      video_control_ptr = NULL;
    usb_device_interface_struct_t*  pDeviceIntf = NULL;
    //interface_descriptor_t*      intf = NULL;
    endpoint_descriptor_t*       ep_desc = NULL;
    uint8_t                       ep_num;
    usb_status                    status = USB_OK;
    pipe_init_struct_t              pipe_init;

    video_control_ptr = (usb_video_control_struct_t*)OS_Mem_alloc_zero(sizeof(usb_video_control_struct_t));
    if (video_control_ptr == NULL)
    {
#ifdef _DEBUG
        USB_PRINTF("usb_class_video_control_init fail on memory allocation\n");
#endif
        return USBERR_ERROR;
    }
    
    video_control_ptr->dev_handle  = dev_handle;
    video_control_ptr->intf_handle = intf_handle;
    video_control_ptr->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(video_control_ptr->dev_handle);
    
    pDeviceIntf = (usb_device_interface_struct_t*)intf_handle;

    video_control_ptr->control_interface_ptr = pDeviceIntf;
    video_control_ptr->vc_interface_header_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_HEADER);
    video_control_ptr->vc_input_terminal_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_INPUT_TERMINAL);
    video_control_ptr->vc_output_terminal_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_OUTPUT_TERMINAL);
    video_control_ptr->vc_processing_unit_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_PROCESSING_UNIT);
    video_control_ptr->vc_extension_unit_list_ptr.extension_descriptor_list_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_EXTENSION_UNIT);
    video_control_ptr->vc_extension_unit_list_ptr.extension_num = usb_class_video_find_descriptor_count(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_EXTENSION_UNIT);
    //intf = pDeviceIntf->lpinterfaceDesc;

    for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++)
    {
        ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc;
        if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == IRRPT_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_RECV;
            pipe_init.pipetype         = USB_INTERRUPT_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = video_control_ptr->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(video_control_ptr->host_handle, &video_control_ptr->control_interrupt_in_pipe, &pipe_init);
            if (status != USB_OK)
            {
#ifdef _DEBUG
                USB_PRINTF("usb_class_video_init fail to open in pipe\n");
#endif
                *class_handle_ptr = (class_handle)video_control_ptr;
                return USBERR_ERROR;
            }
        }
    }
    
    video_control_ptr->in_setup = FALSE;
    video_control_ptr->ctrl_callback = NULL;
    video_control_ptr->ctrl_param = NULL;
    video_control_ptr->recv_callback = NULL;
    video_control_ptr->recv_param = NULL;
    
    *class_handle_ptr = (class_handle)video_control_ptr;

    //USB_PRINTF("Video class driver initialized\n");
    
    return USB_OK;
   
} /* Endbody */
Esempio n. 10
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_stream_init
* Returned Value : None
* Comments       :
*     This function is called by common class to initialize the class driver. It
*     is called in response to a select interface call by application
*
*END*--------------------------------------------------------------------*/
usb_status usb_class_video_stream_init
(
    /* [IN]  the device handle related to the class driver */
    usb_device_instance_handle      dev_handle,
    /* [IN]  the interface handle related to the class driver */
    usb_interface_descriptor_handle intf_handle,
    /* [OUT] printer call struct pointer */
    class_handle*                    class_handle_ptr
)
{ /* Body */
    usb_video_stream_struct_t*      video_stream_ptr = NULL;
    usb_device_interface_struct_t*  pDeviceIntf = NULL;
    //interface_descriptor_t*      intf = NULL;
    endpoint_descriptor_t*       ep_desc = NULL;
    uint8_t                       ep_num;
    usb_status                    status = USB_OK;
    pipe_init_struct_t              pipe_init;

    video_stream_ptr = (usb_video_stream_struct_t*)OS_Mem_alloc_zero(sizeof(usb_video_stream_struct_t));
    if (video_stream_ptr == NULL)
    {
#ifdef _DEBUG
        USB_PRINTF("usb_class_video_stream_init fail on memory allocation\n");
#endif
        return USBERR_ERROR;
    }
    
    video_stream_ptr->dev_handle  = dev_handle;
    video_stream_ptr->intf_handle = intf_handle;
    video_stream_ptr->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(video_stream_ptr->dev_handle);

    video_stream_ptr->altrnate_if_ep_num = 0;
    video_stream_ptr->altrnate_if_ep_descriptor_list = NULL;
    
    pDeviceIntf = (usb_device_interface_struct_t*)intf_handle;

    video_stream_ptr->stream_interface_ptr = pDeviceIntf;
    video_stream_ptr->current_stream_interface_ptr = pDeviceIntf->lpinterfaceDesc;
    video_stream_ptr->vs_input_header_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_INPUT_HEADER);
    video_stream_ptr->vs_mjpeg_format_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_FORMAT_MJPEG);
    video_stream_ptr->vs_mjpeg_frame_list.frame_descriptor_list_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_FRAME_MJPEG);
    video_stream_ptr->vs_mjpeg_frame_list.frame_num = usb_class_video_find_descriptor_count(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_FRAME_MJPEG);
    //intf = pDeviceIntf->lpinterfaceDesc;

    for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++)
    {
        ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc;
        if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_RECV;
            pipe_init.pipetype         = USB_ISOCHRONOUS_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = video_stream_ptr->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_in_pipe, &pipe_init);
            if (status != USB_OK)
            {
#ifdef _DEBUG
                USB_PRINTF("usb_class_video_init fail to open in pipe\n");
#endif
                *class_handle_ptr = (class_handle)video_stream_ptr;
                return USBERR_ERROR;
            }
        }
        else if ((ep_desc->bEndpointAddress & OUT_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_SEND;
            pipe_init.pipetype         = USB_ISOCHRONOUS_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = video_stream_ptr->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_out_pipe, &pipe_init);
            if (status != USB_OK)
            {
#ifdef _DEBUG
                USB_PRINTF("usb_class_video_init fail to open in pipe\n");
#endif
                *class_handle_ptr = (class_handle)video_stream_ptr;
                return USBERR_ERROR;
            }
        }

    }
    
    video_stream_ptr->recv_callback = NULL;
    video_stream_ptr->recv_param = NULL;
    
    *class_handle_ptr = (class_handle)video_stream_ptr;

    //USB_PRINTF("Video class driver initialized\n");
    
    return USB_OK;
   
} /* Endbody */
Esempio n. 11
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_driver_info_match
* Returned Value : TRUE for driver match, else FALSE
* Comments       :
*     Match device driver info with class etc. in device/interface
*     following the ordering in "USB Common Class Specification"
*     Rev. 1.0, August 18, 1998, p. 7
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
bool  usb_host_driver_info_match
(
    /* [IN] USB device */
    dev_instance_t*           dev_ptr,
    /* [IN] Configuration number */
    interface_descriptor_t*   intf_ptr,
    /* [IN] TRUE=attach, FALSE=detach */
    usb_host_driver_info_t*   info_ptr
)
{ /* Body */
    uint16_t  info_Vendor, info_Product, dev_Vendor, dev_Product;

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_host_driver_info_match");
    #endif

    info_Vendor = USB_SHORT_UNALIGNED_LE_TO_HOST(info_ptr->idVendor);
    info_Product = USB_SHORT_UNALIGNED_LE_TO_HOST(info_ptr->idProduct);

    /* If vendor and product are listed in table (non-zero) */
    if ((info_Vendor | info_Product) != 0)
    {
        dev_Vendor = USB_SHORT_UNALIGNED_LE_TO_HOST(dev_ptr->dev_descriptor.idVendor);
        dev_Product = USB_SHORT_UNALIGNED_LE_TO_HOST(dev_ptr->dev_descriptor.idProduct);
 
        if ((info_Vendor == dev_Vendor) &&
            (info_Product == dev_Product))
        {
            #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match PID, VID match");
            #endif
            return TRUE;
        } /* Endif */
    }

   /* note: zero value class in the device descriptor means
   ** that the class is defined in interface descriptor
   */
    if ((info_ptr->bDeviceClass == 0xFF) || /* if the device class is any OR */
      ((info_ptr->bDeviceClass ==             /* or the device class matches */
      dev_ptr->dev_descriptor.bDeviceClass) && 
      (dev_ptr->dev_descriptor.bDeviceClass != 0x00))) /* but it is not zero-value match */
    {
        if ((info_ptr->bDeviceSubClass ==
             dev_ptr->dev_descriptor.bDeviceSubClass) &&
             (info_ptr->bDeviceProtocol ==
             dev_ptr->dev_descriptor.bDeviceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class, match subclass, match protocol");
            #endif
            return TRUE;
        } /* Endif */

        if ((info_ptr->bDeviceSubClass ==
             dev_ptr->dev_descriptor.bDeviceSubClass) &&
             (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class, match subclass");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol ==
            dev_ptr->dev_descriptor.bDeviceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class, match protocol");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class");
            #endif
            return TRUE;
        }
    }

    /* No Device match, try Interface */
    if ((info_ptr->bDeviceClass == 0xFF) || /* if the device class is any OR */
        ((info_ptr->bDeviceClass == /* or the class matches interface class */
        intf_ptr->bInterfaceClass)))
    {
        if ((info_ptr->bDeviceSubClass ==
             intf_ptr->bInterfaceSubClass) &&
            (info_ptr->bDeviceProtocol ==
             intf_ptr->bInterfaceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface subclass, match interface protocol");
            #endif
            return TRUE;
        } /* Endif */

        if ((info_ptr->bDeviceSubClass ==
             intf_ptr->bInterfaceSubClass) &&
            (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface subclass, match interface protocol");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol ==
            intf_ptr->bInterfaceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface protocol");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class");
            #endif
            return TRUE;
        }
   }

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_host_driver_info_match interface No Match");
    #endif
    return FALSE;
} /* EndBody */
Esempio n. 12
0
usb_status usb_class_cdc_get_ctrl_descriptor
    (
      /* [IN] pointer to device instance */
      usb_device_instance_handle      dev_handle,

      /* [IN] pointer to interface descriptor */
      usb_interface_descriptor_handle intf_handle,
      
      interface_descriptor_t* *   if_desc_ptr
    )
{
    dev_instance_t*           dev_ptr;
    descriptor_union_t           ptr1, ptr2;
    usb_cdc_func_desc_t *      fd_desc;
    interface_descriptor_t*   if_desc;
    interface_descriptor_t*   intf_ptr =
        ((usb_device_interface_struct_t*)intf_handle)->lpinterfaceDesc;
    usb_status                 status;
    int32_t i, j;
    int32_t ctrl_intf = -1; /* assume not found */
    
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_get_ctrl_descriptor");
    #endif

    status = USBERR_INIT_FAILED; 
    *if_desc_ptr = NULL; /* presume not found */
    
    dev_ptr = (dev_instance_t*)dev_handle;
    ptr1.pntr = dev_ptr->lpConfiguration; /* offset for alignment */
	ptr2.word = ptr1.word + USB_SHORT_UNALIGNED_LE_TO_HOST(ptr1.cfig->wTotalLength);
	
	while (ptr1.word < ptr2.word)
	{
		if (USB_DESC_TYPE_CS_INTERFACE == (ptr1.common->bDescriptorType))
		{
			fd_desc = (usb_cdc_func_desc_t *)ptr1.pntr;
            if (USB_DESC_SUBTYPE_CS_UNION == fd_desc->header.bDescriptorSubtype)
            {
				/* Here we get only when union descriptor found */
				/* Find if there is this data interface in the found union descriptor */
				for (j = 0; j < fd_desc->uni.bFunctionLength - 3; j++) {
					if (intf_ptr->bInterfaceNumber == fd_desc->uni.bSlaveInterface[j]) {
						/* Union descriptor containing our data interface found */
						ctrl_intf = fd_desc->uni.bMasterInterface; /* copy control interface number */
						break;
					}
				}
				if (ctrl_intf != -1) /* when control interface was already found */
					break; /* finish any next search for union descriptors */
            }
		}
		ptr1.word += ptr1.common->bLength;
	}

    if (ctrl_intf != -1) {
        for(i = 0; i < dev_ptr->configuration.interface_count; i++)
        {
			if_desc = dev_ptr->configuration.interface[i].lpinterfaceDesc;
			if (if_desc->bInterfaceNumber == ctrl_intf) {
				/* Interface descriptor of control interface found */
				*if_desc_ptr = if_desc;
				status = USB_OK;
				break;
			}
		}

    }
    #ifdef _HOST_DEBUG_
    if (!status) {
        DEBUG_LOG_TRACE("usb_class_cdc_get_ctrl_descriptor, SUCCESSFULL");
    }
    else {
        DEBUG_LOG_TRACE("usb_class_cdc_get_ctrl_descriptor, FAILED");
    }
    #endif

    return status;
}
Esempio n. 13
0
usb_status usb_class_cdc_acm_init
   (
	/* [IN]  the device handle related to the class driver */
	usb_device_instance_handle 	 dev_handle,
	/* [IN]  the interface handle related to the class driver */
	usb_interface_descriptor_handle intf_handle,
	/* [OUT] printer call struct pointer */
	class_handle*					 class_handle_ptr
   )
{ /* Body */
    usb_acm_class_intf_struct_t * acm_class_intf = NULL;
    usb_device_interface_struct_t*  pDeviceIntf = NULL;
    interface_descriptor_t*      intf = NULL;
    endpoint_descriptor_t*       ep_desc = NULL;
    uint8_t                        ep_num;
    usb_status                    status = USB_OK;
    pipe_init_struct_t              pipe_init;

    acm_class_intf = (usb_acm_class_intf_struct_t *)OS_Mem_alloc_zero(sizeof(usb_acm_class_intf_struct_t));
    if (acm_class_intf == NULL)
    {
        printf("usb_class_cdc_acm_init fail on memory allocation\n");
        return USBERR_ERROR;
    }
    
    acm_class_intf->dev_handle  = dev_handle;
    acm_class_intf->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(acm_class_intf->dev_handle);

    pDeviceIntf = (usb_device_interface_struct_t*)intf_handle;
    intf = pDeviceIntf->lpinterfaceDesc;
    acm_class_intf->intf_handle = intf;
	acm_class_intf->intf_num = intf->bInterfaceNumber;
    acm_class_intf->mutex = OS_Mutex_create();
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_acm_init");
    #endif
    
    for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++)
    {
        ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc;
        if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == IRRPT_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_RECV;
            pipe_init.pipetype         = USB_INTERRUPT_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = acm_class_intf->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(acm_class_intf->host_handle, &acm_class_intf->interrupt_pipe, &pipe_init);
            if (status != USB_OK)
            {
                printf("usb_class_cdc_acm_init fail to open in pipe\n");
                *class_handle_ptr = (class_handle)acm_class_intf;
                return USBERR_ERROR;
            }
        }
    }
    /* Make sure the device is still attached */
    #ifdef _HOST_DEBUG_
    if (status) {
        DEBUG_LOG_TRACE("usb_class_cdc_acm_init, SUCCESSFUL");
    }
    else {
        DEBUG_LOG_TRACE("usb_class_cdc_acm_init, FAILED");
    }
    #endif
    *class_handle_ptr = (class_handle)acm_class_intf;
    return status;
} /* Endbody */
Esempio n. 14
0
usb_status usb_class_cdc_get_acm_descriptors
(
      /* [IN] pointer to device instance */
      usb_device_instance_handle      dev_handle,

      /* [IN] pointer to interface descriptor */
      usb_interface_descriptor_handle intf_handle,

      usb_cdc_desc_acm_t * *       acm_desc,
      usb_cdc_desc_cm_t * *        cm_desc,
      usb_cdc_desc_header_t * *    header_desc,
      usb_cdc_desc_union_t * *     union_desc
) 
{
    dev_instance_t*                 dev_ptr;
    descriptor_union_t                 ptr1, ptr2;
    usb_device_interface_struct_t*   intf_ptr =
        (usb_device_interface_struct_t*)intf_handle;
    usb_status                 status;
    //int32_t i;
    usb_cdc_func_desc_t *      fd;

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_get_acm_descriptors");
    #endif

    status = USB_OK;
    
    dev_ptr = (dev_instance_t*)dev_handle;
    ptr1.pntr = dev_ptr->lpConfiguration; /* offset for alignment */
	ptr2.word = ptr1.word + USB_SHORT_UNALIGNED_LE_TO_HOST(ptr1.cfig->wTotalLength);
	
	while (ptr1.word < ptr2.word)
	{
		if (USB_DESC_TYPE_CS_INTERFACE == (ptr1.common->bDescriptorType))
		{
			fd = (usb_cdc_func_desc_t *)ptr1.pntr;
			
			switch (fd->header.bDescriptorSubtype) {
				case USB_DESC_SUBTYPE_CS_HEADER:
					*header_desc = &fd->header;
					if (USB_SHORT_LE_TO_HOST(*(uint16_t*)((*header_desc)->bcdCDC)) > 0x0110)
						status = USBERR_INIT_FAILED;
					break;
				case USB_DESC_SUBTYPE_CS_UNION:
					/* Check if this union descriptor describes master for this interface */
					if (fd->uni.bMasterInterface == intf_ptr->lpinterfaceDesc->bInterfaceNumber) {
						/* Check if another union descriptor has not been already assigned */
						if (*union_desc == NULL)
							*union_desc = &fd->uni;
						else
							status = USBERR_INIT_FAILED;
				  }
				  break;
				case USB_DESC_SUBTYPE_CS_ACM:
					*acm_desc = &fd->acm;
					break;
				case USB_DESC_SUBTYPE_CS_CM:
					*cm_desc = &fd->cm;
					break;
			}
		}
        if (status != USB_OK)
            break;
		ptr1.word += ptr1.common->bLength;
	}

    #ifdef _HOST_DEBUG_
    if (!status) {
        DEBUG_LOG_TRACE("usb_class_cdc_get_acm_descriptors, SUCCESSFULL");
    }
    else {
        DEBUG_LOG_TRACE("usb_class_cdc_get_acm_descriptors, FAILED");
    }
    #endif

    return status;
}
Esempio n. 15
0
usb_status usb_class_cdc_data_init
   (
	/* [IN]  the device handle related to the class driver */
	usb_device_instance_handle 	 dev_handle,
	/* [IN]  the interface handle related to the class driver */
	usb_interface_descriptor_handle intf_handle,
	/* [OUT] printer call struct pointer */
	class_handle*					 class_handle_ptr
   )
{ /* Body */
    usb_data_class_intf_struct_t * data_class_intf = NULL;
    usb_device_interface_struct_t*  pDeviceIntf = NULL;
    interface_descriptor_t*      intf = NULL;
    endpoint_descriptor_t*       ep_desc = NULL;
    uint8_t                        ep_num;
    usb_status                    status = USB_OK;
    pipe_init_struct_t              pipe_init;

    data_class_intf = (usb_data_class_intf_struct_t *)OS_Mem_alloc_zero(sizeof(usb_data_class_intf_struct_t));
    if (data_class_intf == NULL)
    {
        printf("usb_class_cdc_data_init fail on memory allocation\n");
        return USBERR_ERROR;
    }
    
    data_class_intf->dev_handle  = dev_handle;
    data_class_intf->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(data_class_intf->dev_handle);

    pDeviceIntf = (usb_device_interface_struct_t*)intf_handle;
    intf = pDeviceIntf->lpinterfaceDesc;
    data_class_intf->intf_handle = intf;
	data_class_intf->intf_num = intf->bInterfaceNumber;
    data_class_intf->mutex = OS_Mutex_create();
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_data_init");
    #endif
    
	for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++)
	{
		 ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc;
		 if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == BULK_ENDPOINT))
		 {
			 pipe_init.endpoint_number	= (ep_desc->bEndpointAddress & ENDPOINT_MASK);
			 pipe_init.direction		= USB_RECV;
			 pipe_init.pipetype 		= USB_BULK_PIPE;
			 pipe_init.max_packet_size	= (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
			 pipe_init.interval 		= ep_desc->iInterval;
			 pipe_init.flags			= 0;
			 pipe_init.dev_instance 	= data_class_intf->dev_handle;
			 pipe_init.nak_count		= 30;
			 status = usb_host_open_pipe(data_class_intf->host_handle, (usb_pipe_handle *)&data_class_intf->in_pipe, &pipe_init);
		 }
		 else if(!(ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == BULK_ENDPOINT))
		 {
			 pipe_init.endpoint_number	= (ep_desc->bEndpointAddress & ENDPOINT_MASK);
			 pipe_init.direction		= USB_SEND;
			 pipe_init.pipetype 		= USB_BULK_PIPE;
			 pipe_init.max_packet_size	= (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
			 pipe_init.interval 		= ep_desc->iInterval;
			 pipe_init.flags			= 0;
			 pipe_init.dev_instance 	= data_class_intf->dev_handle;
			 pipe_init.nak_count		= 3000;
			 status = usb_host_open_pipe(data_class_intf->host_handle, (usb_pipe_handle *)&data_class_intf->out_pipe, &pipe_init);
		 }
		 if (status != USB_OK)
		 {
			 printf("usb_class_cdc_data_init fail to open in pipe\n");
			 *class_handle_ptr = (class_handle)data_class_intf;
			 return USBERR_ERROR;
		 }
	 }
	 
    /* Make sure the device is still attached */

	if ((data_class_intf->in_pipe == NULL) && (data_class_intf->out_pipe == NULL))
	    status = USBERR_OPEN_PIPE_FAILED;

	if (data_class_intf->out_pipe) {
	    /* Don't use host - predefined constant for nak_count...
	    ** NOTE!!!
	    ** This hack is not very clean. We need to maximize number of retries to minimize the time of
	    ** transaction (minimize task's time while waiting for 1 transaction to be done (with or without data))
	    ** The time depends on user expecatation of the read() latency, on the delay between 2 NAKs and on number
	    ** of NAKs to be performed.
	    ** The workaround is to limit amount of retries for the pipe maximally to 3.
	    ** Number 3 is hard-coded here for now.
	    */
	//	if (((pipe_struct_t*)(data_class_intf->in_pipe))->nak_count > 3)
	//		((pipe_struct_t*)data_class_intf->in_pipe)->nak_count = 3; /* don't use host - predefined constant */
	}
	if (data_class_intf->in_pipe) {
	    /* The same as for OUT pipe applies here */
	//    if (((pipe_struct_t*)data_class_intf->out_pipe)->nak_count > 3)
	//        ((pipe_struct_t*)data_class_intf->out_pipe)->nak_count = 3; /* don't use host - predefined constant */

	    /* initialize buffer */
	    /* size of buffer equals to the size of endpoint data size */
	    data_class_intf->RX_BUFFER_SIZE = ((pipe_struct_t*)data_class_intf->in_pipe)->max_packet_size;
	    if (NULL == (data_class_intf->rx_buffer = (uint8_t *)OS_Mem_alloc_zero(data_class_intf->RX_BUFFER_SIZE))) {
	        status = USBERR_ALLOC;
	    }
	    else {
	        /* initialize members */
	        data_class_intf->RX_BUFFER_APP = data_class_intf->RX_BUFFER_DRV = data_class_intf->rx_buffer;
	    }
	}
        
    #ifdef _HOST_DEBUG_
    if (status) {
        DEBUG_LOG_TRACE("usb_class_cdc_data_init, SUCCESSFUL");
    }
    else {
        DEBUG_LOG_TRACE("usb_class_cdc_data_init, FAILED");
    }
    #endif
    *class_handle_ptr = (class_handle)data_class_intf;
    return status;
} /* Endbody */