예제 #1
0
usb_status usb_class_audio_send_data
(
/* [IN] audio control class interface pointer  */
audio_command_t* audio_ptr,

/* [IN] buffer pointer */
uint8_t * buffer,

/* [IN] data length */
uint32_t buf_size
)
{ /* Body */

    audio_stream_struct_t* audio_class;
    usb_status status = USBERR_ERROR;
    //uint16_t request_value;
    tr_struct_t* tr_ptr;
    //usb_audio_command_t* p_endpoint_command;

    if ((audio_ptr == NULL) || (audio_ptr->class_stream_handle == NULL))
    {
        USB_PRINTF("input parameter error\n");
        return USBERR_ERROR;
    }

    audio_class = (audio_stream_struct_t*)audio_ptr->class_stream_handle;
    if ((audio_class == NULL) || (buffer == NULL))
    {
        USB_PRINTF("get audio class parameter error\n");
        return USBERR_ERROR;
    }

    audio_class->send_callback = audio_ptr->callback_fn;
    audio_class->send_param = audio_ptr->callback_param;

    if (audio_class->dev_handle == NULL)
    {
        USB_PRINTF("get audio class dev handle error\n");
        return USBERR_ERROR;
    }
    if (usb_host_get_tr(audio_class->host_handle, usb_class_audio_send_callback, audio_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr\n");
        return USBERR_ERROR;
    }

    tr_ptr->tx_buffer = buffer;
    tr_ptr->tx_length = buf_size;
    status = usb_host_send_data(audio_class->host_handle, audio_class->iso_out_pipe, tr_ptr);
    if (status != USB_OK)
    {
        USB_PRINTF("\nError in _usb_host_send_data: %x", (unsigned int)status);
        usb_host_release_tr(audio_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }

    return USB_OK;

} /* Endbody */
예제 #2
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_control_recv_data
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to recv interrupt data
*
*END*--------------------------------------------------------------------*/
usb_status usb_class_video_control_recv_data
(
    /* [IN] Class Interface structure pointer */
    video_command_t*         com_ptr,
    /* [IN] The buffer address */
    uint8_t *               buffer,
    /* [IN] The buffer address */
    uint16_t                length
)
{
    usb_video_control_struct_t*  video_control_ptr;
    tr_struct_t*             tr_ptr;
    usb_status                status;

    if ((com_ptr == NULL) || (com_ptr->class_control_handle == NULL))
    {
        return USBERR_ERROR;
    }

    video_control_ptr = (usb_video_control_struct_t*)com_ptr->class_control_handle;
    
    if ((video_control_ptr == NULL) || (buffer == NULL))
    {
#ifdef _DEBUG
        USB_PRINTF("input parameter error\n");
#endif
        return USBERR_ERROR;
    }

    video_control_ptr->recv_callback = com_ptr->callback_fn;
    video_control_ptr->recv_param = com_ptr->callback_param;

    if (video_control_ptr->dev_handle == NULL)
    {
        return USBERR_ERROR;
    }

    if (usb_host_get_tr(video_control_ptr->host_handle, usb_class_video_control_recv_callback, video_control_ptr, &tr_ptr) != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("error to get tr\n");
#endif
        return USBERR_ERROR;
    }
    
    tr_ptr->rx_buffer = buffer;
    tr_ptr->rx_length = length;
    status = usb_host_recv_data(video_control_ptr->host_handle, video_control_ptr->control_interrupt_in_pipe, tr_ptr);
    if (status != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("\nError in usb_class_video_recv_data: %x", status);
#endif
        usb_host_release_tr(video_control_ptr->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    return USB_OK;
}
예제 #3
0
usb_status usb_class_cdc_init_ipipe
    (
        /* ACM interface instance */
        cdc_class_call_struct_t *      acm_instance
    )
{ /* Body */
    usb_status                     status = USBERR_NO_INTERFACE;
    usb_acm_class_intf_struct_t *  if_acm_ptr;
    tr_struct_t*                  tr_ptr;
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_init_ipipe");
    #endif

    /* Validity checking, always needed when passing data to lower API */
    if (usb_class_cdc_intf_validate(acm_instance)) {
        if_acm_ptr = (usb_acm_class_intf_struct_t *) acm_instance->class_intf_handle;
        USB_CDC_ACM_lock();
        if (if_acm_ptr->interrupt_pipe != NULL) {
        
            if (usb_host_get_tr(if_acm_ptr->host_handle, usb_class_cdc_int_acm_callback, if_acm_ptr, &tr_ptr) != USB_OK)
            {
                printf("usb_class_cdc_init_ipipe: error to get tr\n");
                return USBERR_ERROR;
            }
            
            tr_ptr->rx_buffer = (uint8_t *) &if_acm_ptr->interrupt_buffer;
            tr_ptr->rx_length = sizeof(if_acm_ptr->interrupt_buffer);
            status = usb_host_recv_data(if_acm_ptr->host_handle, if_acm_ptr->interrupt_pipe, tr_ptr);
            if (status != USB_OK)
            {
                printf("\nError in usb_class_cdc_init_ipipe: %x", status);
                usb_host_release_tr(if_acm_ptr->host_handle, tr_ptr);
                return USBERR_ERROR;
            }
        }
        else{
            status = USBERR_OPEN_PIPE_FAILED;
        }
        USB_CDC_ACM_unlock();
    }

    #ifdef _HOST_DEBUG_
    if (!status) {
         DEBUG_LOG_TRACE("usb_class_cdc_init_ipipe, SUCCESSFUL");
    }
    else {
         DEBUG_LOG_TRACE("usb_class_cdc_init_ipipe, FAILED");
    }
    #endif
   
    return status;
}
예제 #4
0
static void usb_class_cdc_int_acm_callback
   (
      /* [IN] pointer to pipe */
      void *     tr_ptr,

      /* [IN] user-defined parameter */
      void *           param,

      /* [IN] buffer address */
      uint8_t *           buffer,

      /* [IN] length of data transferred */
      uint32_t           len,

      /* [IN] status, hopefully USB_OK or USB_DONE */
      uint32_t           status
   )
{ /* Body */
    //cdc_class_call_struct_t *	acm_parser;
    tr_struct_t*                  tr_int_ptr;
    usb_acm_class_intf_struct_t *  if_acm_ptr = (usb_acm_class_intf_struct_t *)param;
    
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_int_acm_callback");
    #endif
    if(USB_OK == status)
    {
        if (usb_host_release_tr(if_acm_ptr->host_handle, tr_ptr) != USB_OK)
        {
            printf("usb_class_cdc_int_acm_callback: _usb_host_release_tr failed\n");
        }
    }
    else
    {
    	/* In case of error, e.g. KHCI_ATOM_TR_TO, need to re-issue tr for interrupt pipe */
		USB_CDC_ACM_lock();
        if (if_acm_ptr->interrupt_pipe != NULL) {
        
			if (usb_host_get_tr(if_acm_ptr->host_handle, usb_class_cdc_int_acm_callback, if_acm_ptr, &tr_int_ptr) != USB_OK)
			{
				printf("usb_class_cdc_int_acm_callback: error to get tr\n");
			}
			
			tr_int_ptr->rx_buffer = (uint8_t *) &if_acm_ptr->interrupt_buffer;
			tr_int_ptr->rx_length = sizeof(if_acm_ptr->interrupt_buffer);								   
			status = usb_host_recv_data(if_acm_ptr->host_handle, if_acm_ptr->interrupt_pipe, tr_int_ptr);
			if (status != USB_OK)
			{
				printf("\nError in usb_class_cdc_int_acm_callback: %x", status);
				usb_host_release_tr(if_acm_ptr->host_handle, tr_int_ptr);
			}
        }
        else{
            status = USBERR_OPEN_PIPE_FAILED;
		}
		USB_CDC_ACM_unlock();
    }
    /* we do not use USB_ACM_INT_PIPE_FREE in this version at all */
//    _lwevent_set(if_ptr->acm_event, USB_ACM_INT_PIPE_FREE); 

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

} /*EndBody */
예제 #5
0
static usb_status usb_class_cdc_cntrl_common
   (
      /* [IN] The communication device common command structure */
      cdc_command_t *           com_ptr,
      /* [IN] The communication device control interface */
      usb_acm_class_intf_struct_t * if_ctrl_ptr,
      /* [IN] Bitmask of the request type */
      uint8_t                    bmrequesttype,
      /* [IN] Request code */
      uint8_t                    brequest,
      /* [IN] Value to copy into wvalue field of the REQUEST */
      uint16_t                   wvalue,
      /* [IN] Length of the data associated with REQUEST */
      uint16_t                   wlength,
      /* [IN] Pointer to data buffer used to send/recv */
      uint8_t *                 data
   )
{ /* Body */
    usb_data_class_intf_struct_t *        if_ptr;
    //usb_setup_t                        req;
    usb_status                       status = USBERR_NO_INTERFACE;
    usb_pipe_handle                 pipe_handle;
    tr_struct_t*                    tr_ptr;
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_common");
    #endif
    
    if_ptr = (usb_data_class_intf_struct_t *) com_ptr->CLASS_PTR->class_intf_handle;
    
    /* Save the higher level callback and ID */
    if_ptr->ctrl_callback = com_ptr->CALLBACK_FN;
    if_ptr->ctrl_callback_param = com_ptr->CALLBACK_PARAM;
 
    pipe_handle = (usb_pipe_handle)usb_host_dev_mng_get_control_pipe(if_ptr->dev_handle);
    if (usb_host_get_tr(if_ptr->host_handle, usb_class_cdc_cntrl_callback, if_ptr, &tr_ptr) != USB_OK)
    {
        printf("usb_class_cdc_cntrl_common: error to get tr cdc\n");
        return USBERR_ERROR;
    }
    
    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }
 
    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest      = brequest;
    *(uint16_t*)tr_ptr->setup_packet.wvalue = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)tr_ptr->setup_packet.windex = USB_HOST_TO_LE_SHORT(if_ctrl_ptr->intf_num);
    *(uint16_t*)tr_ptr->setup_packet.wlength = USB_HOST_TO_LE_SHORT(wlength);
    /* Since this function is general, we must distinguish here interface class to perform
    ** appropriate action.
    ** Only ACM devices are supported now.
    */
    switch (((interface_descriptor_t*) if_ctrl_ptr->intf_handle)->bInterfaceSubClass) 
    {
        case USB_SUBCLASS_COM_DIRECT:
            break;
        case USB_SUBCLASS_COM_ABSTRACT:
			if (USB_OK == (status =
			usb_host_send_setup(if_ptr->host_handle, pipe_handle, tr_ptr)))	
			{
				status = USB_OK;
			}
			else
			{
				printf("\nError in usb_class_hid_cntrl_common: %x", status);
				usb_host_release_tr(if_ptr->host_handle, tr_ptr);
				status = USBERR_ERROR;
			}
            break;
        case USB_SUBCLASS_COM_TELEPHONE:
            break;
        case USB_SUBCLASS_COM_MULTICHAN:
            break;
        case USB_SUBCLASS_COM_CAPI:
            break;
        case USB_SUBCLASS_COM_ETHERNET:
            break;
        case USB_SUBCLASS_COM_ATM_NET:
            break;  
    }
 
    #ifdef _HOST_DEBUG_
    if (!status) {
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_common, SUCCESSFUL");
    }
    else {
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_common, FAILED");
    }
    #endif
    
    return status;
} /* Endbody */
예제 #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 */
예제 #7
0
파일: usb_host_hub.c 프로젝트: NeoXiong/UVC
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_recv_bitmap
* Returned Value : None
* Comments       :
*     Starts interrupt endpoint to poll for interrupt on specified hub
*END*--------------------------------------------------------------------*/
usb_status usb_class_hub_recv_bitmap
    (
      /* [IN] Class Interface structure pointer */
      hub_command_t*            com_ptr,
       /* [IN] The buffer address */
      uint8_t *                  buffer,
      /* size of buffer to be used */
      uint8_t                      length
    )
{
    usb_hub_class_struct_t*       hub_class;
    tr_struct_t*                  tr_ptr;
    usb_status                     status = USBERR_NO_INTERFACE;

    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_recv_bitmap");
    #endif
    //USB_PRINTF("r \n");

    if ((com_ptr == NULL) || (com_ptr->class_ptr == NULL))
    {
        return USBERR_ERROR;
    }

    hub_class = (usb_hub_class_struct_t*)com_ptr->class_ptr;
    
    if ((hub_class == NULL) || (buffer == NULL))
    {
        USB_PRINTF("input parameter error\n");
        return USBERR_ERROR;
    }

    hub_class->interrupt_callback = com_ptr->callback_fn;
    hub_class->interrupt_param = com_ptr->callback_param;

    if (hub_class->dev_handle == NULL)
    {
        return USBERR_ERROR;
    }

    if (hub_class->in_interrupt)
    {
        return USBERR_ERROR;
    }

    if (usb_host_get_tr(hub_class->host_handle, usb_class_hub_int_callback, hub_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr\n");
        return USBERR_ERROR;
    }
    
    tr_ptr->rx_buffer = buffer;
    tr_ptr->rx_length = length;                                            
    status = usb_host_recv_data(hub_class->host_handle, hub_class->interrupt_pipe, tr_ptr);
    if (status != USB_OK)
    {
        USB_PRINTF("\nError in usb_class_hub_recv_bitmap: %x", (unsigned int)status);
        usb_host_release_tr(hub_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    hub_class->in_interrupt = TRUE;
    return USB_OK;
}
예제 #8
0
파일: usb_host_hub.c 프로젝트: NeoXiong/UVC
usb_status usb_class_hub_cntrl_common
   (
      /* [IN] Class Interface structure pointer */
      hub_command_t*         com_ptr,
      /* [IN] Bitmask of the request type */
      uint8_t                  bmrequesttype,
      /* [IN] Request code */
      uint8_t                  brequest,
      /* [IN] Value to copy into wvalue field of the REQUEST */
      uint16_t                 wvalue,
      /* [IN] Length of the data associated with REQUEST */
      uint16_t                 windex,
      /* [IN] Index field of CTRL packet */
      uint16_t                 wlength,
      /* [IN] the buffer to be transfered */
      uint8_t *               data
   )
{
    usb_hub_class_struct_t*         hub_class = NULL;
    //usb_setup_t                        req;
    usb_status                       status = USB_OK;
    tr_struct_t*                    tr_ptr;

    if ((com_ptr == NULL) || (com_ptr->class_ptr == NULL))
    {
        return USBERR_ERROR;
    }

    hub_class = (usb_hub_class_struct_t*)com_ptr->class_ptr;
    if (hub_class->in_setup)
    {
        return USBERR_TRANSFER_IN_PROGRESS;
    }

    if (hub_class->dev_handle == NULL)
    {
        #ifdef _HOST_DEBUG_
           DEBUG_LOG_TRACE("usb_class_hub_cntrl_common, invalid device handle");
        #endif
        return USBERR_DEVICE_NOT_FOUND;
    }
    
    hub_class->ctrl_callback = com_ptr->callback_fn;
    hub_class->ctrl_param = com_ptr->callback_param;

    if (usb_host_get_tr(hub_class->host_handle, usb_class_hub_cntrl_callback, hub_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr hub\n");
        return USBERR_ERROR;
    }

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }
 
    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest      = brequest;
    *(uint16_t*)tr_ptr->setup_packet.wvalue = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)tr_ptr->setup_packet.windex = USB_HOST_TO_LE_SHORT(windex);
    *(uint16_t*)tr_ptr->setup_packet.wlength = USB_HOST_TO_LE_SHORT(wlength);
 
    status = usb_host_send_setup(hub_class->host_handle, hub_class->control_pipe, tr_ptr);  
    if (status != USB_OK)
    {
        usb_host_release_tr(hub_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    hub_class->in_setup = TRUE;
    return USB_OK;
} /* Endbody */
예제 #9
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_cntrl_common
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to send a control request
*
*END*--------------------------------------------------------------------*/
static usb_status usb_class_video_cntrl_common
(
    /* [IN] The communication device common command structure */
    video_command_t*         com_ptr,
    /* [IN] Bitmask of the request type */
    uint8_t                  bmrequesttype,
    /* [IN] Request code */
    uint8_t                  brequest,
    /* [IN] Value to copy into wvalue field of the REQUEST */
    uint16_t                 wvalue,
    /* [IN] Value to copy into windex field of the REQUEST */
    uint16_t                 windex,
    /* [IN] Length of the data associated with REQUEST */
    uint16_t                 wlength,
    /* [IN] Pointer to data buffer used to send/recv */
    uint8_t*                 data
)
{ /* Body */
    usb_video_control_struct_t*         video_control = NULL;
    //usb_setup_t                        req;
    usb_status                       status = USB_OK;
    usb_pipe_handle                 pipe_handle;
    tr_struct_t*                    tr_ptr; 
      
    if ((com_ptr == NULL) || (com_ptr->class_control_handle == NULL))
    {
        return USBERR_ERROR;
    }

    video_control = (usb_video_control_struct_t*)com_ptr->class_control_handle;
    if (video_control->in_setup)
    {
        return USBERR_TRANSFER_IN_PROGRESS;
    }

    if (video_control->dev_handle == NULL)
    {
        #ifdef _HOST_DEBUG_
           DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle");
        #endif
        return USBERR_DEVICE_NOT_FOUND;
    }
    
    video_control->ctrl_callback = com_ptr->callback_fn;
    video_control->ctrl_param = com_ptr->callback_param;
     
    pipe_handle = usb_host_dev_mng_get_control_pipe(video_control->dev_handle);

    if (usb_host_get_tr(video_control->host_handle, usb_class_video_cntrl_callback, video_control, &tr_ptr) != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("error to get tr video\n");
#endif
        return USBERR_ERROR;
    }

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }
 
    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest      = brequest;
    *(uint16_t*)tr_ptr->setup_packet.wvalue = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)tr_ptr->setup_packet.windex = USB_HOST_TO_LE_SHORT(windex);
    *(uint16_t*)tr_ptr->setup_packet.wlength = USB_HOST_TO_LE_SHORT(wlength);

    video_control->in_setup = TRUE;
    status = usb_host_send_setup(video_control->host_handle, pipe_handle, tr_ptr);  
    if (status != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("\nError in usb_class_video_cntrl_common: %x", status);
#endif
        video_control->in_setup = FALSE;
        usb_host_release_tr(video_control->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    return status;
} /* Endbody */
예제 #10
0
/*FUNCTION*----------------------------------------------------------------
 *
 * Function Name  : usb_class_audio_cntrl_common
 * Returned Value : USB_OK if command has been passed on USB.
 * Comments       :
 *     This function is used to send a control request.
 *     It must be run with USB locked.
 *
 *END*--------------------------------------------------------------------*/
static usb_status usb_class_audio_cntrl_common
(
/* [IN] The communication device common command structure */
audio_command_t* com_ptr,

/* [IN] The audio control interface */
//audio_control_struct_t* if_ctrl_ptr,
/* [IN] Bitmask of the request type */
uint8_t bmrequesttype,

/* [IN] Request code */
uint8_t brequest,

/* [IN] Value to copy into wvalue field of the REQUEST */
uint16_t wvalue,

/* [IN] Value to copy into windex field of the REQUEST */
uint16_t windex,

/* [IN] Length of the data associated with REQUEST */
uint16_t wlength,

/* [IN] Pointer to data buffer used to send/recv */
uint8_t * data
)
{ /* Body */
    audio_control_struct_t* audio_class = NULL;
    //usb_setup_t                       req;
    usb_status status = USB_OK;
    usb_pipe_handle pipe_handle;
    tr_struct_t* tr_ptr;

    if ((com_ptr == NULL) || (com_ptr->class_control_handle == NULL))
    {
        return USBERR_ERROR;
    }
    audio_class = (audio_control_struct_t*)com_ptr->class_control_handle;

    if (audio_class->in_setup)
    {
        return USBERR_TRANSFER_IN_PROGRESS;
    }
    if (audio_class->dev_handle == NULL)
    {
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
    }

    audio_class->ctrl_callback = com_ptr->callback_fn;
    audio_class->ctrl_param = com_ptr->callback_param;
    pipe_handle = usb_host_dev_mng_get_control_pipe(audio_class->dev_handle);

    if (usb_host_get_tr(audio_class->host_handle, usb_class_audio_cntrl_callback, audio_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr audio \r\n");
        return USBERR_ERROR;
    }

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }

    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest = brequest;
    *(uint16_t*)&(tr_ptr->setup_packet.wvalue[0]) = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)&(tr_ptr->setup_packet.windex[0]) = USB_HOST_TO_LE_SHORT(windex);  //USB_HOST_TO_LE_SHORT(((interface_descriptor_t*)(audio_class->intf_handle))->bInterfaceNumber);
    *(uint16_t*)&(tr_ptr->setup_packet.wlength[0]) = USB_HOST_TO_LE_SHORT(wlength);

    audio_class->in_setup = TRUE;
    status = usb_host_send_setup(audio_class->host_handle, pipe_handle, tr_ptr);
    if (status != USB_OK)
    {
        audio_class->in_setup = FALSE;
        USB_PRINTF("\nError in usb_class_audio_cntrl_common: %x", (unsigned int)status);
        usb_host_release_tr(audio_class->host_handle, tr_ptr);
    }
    return status;
} /* Endbody */