Example #1
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_PTR                 devreq,

      /* buffer to send/receive */
      uchar_ptr                     buff_ptr,

      /* callback upon completion */
      tr_callback                   callback,

      /* [IN] the parameter to pass back to the callback function */
      pointer                       callback_param
   )
{ /* Body */

   DEV_INSTANCE_PTR           dev_ptr;
   _usb_pipe_handle           pipe_handle;
   TR_INIT_PARAM_STRUCT       tr;
   USB_STATUS                 error = USB_OK;

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

   if (error != USB_OK) {
      USB_unlock();
      return USBERR_DEVICE_NOT_FOUND;
   } /* Endif */
      

   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;
   if (dev_ptr->state < DEVSTATE_ENUM_OK) {
      USB_unlock();
      return 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 = utoh16(devreq->WLENGTH);
   } else {
      tr.TX_BUFFER = buff_ptr;
      tr.TX_LENGTH = utoh16(devreq->WLENGTH);
   } /* EndIf */

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

   USB_unlock();

   return error;
} /* EndBody */
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_audio_recv_data
* Returned Value : USB status
* Comments       :
*     Receive data on isochronous IN pipe.
*
*END*--------------------------------------------------------------------*/
USB_STATUS usb_audio_recv_data
(
    /* [IN] class-interface control pointer */
    CLASS_CALL_STRUCT_PTR   control_ptr,

    /* [IN] class-interface stream pointer */
    CLASS_CALL_STRUCT_PTR   stream_ptr,

    /* [IN] callback upon completion */
    tr_callback             callback,

    /* [IN] user parameter returned by callback */
    void                   *call_parm,

    /* [IN] data length */
    uint32_t                 buf_size,

    /* [IN] buffer pointer */
    unsigned char               *buffer
)
{ /* Body */
    AUDIO_STREAM_INTERFACE_STRUCT_PTR   stream_if_ptr;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR  control_if_ptr;
    TR_INIT_PARAM_STRUCT                tr;
    USB_STATUS                          status = USBERR_NO_INTERFACE;

    USB_lock();
    /* Validity checking, always needed when passing data to lower API */
    if (!usb_host_class_intf_validate(control_ptr)) {
        USB_unlock();
        return USBERR_NO_INTERFACE;
    }
    stream_if_ptr = (AUDIO_STREAM_INTERFACE_STRUCT_PTR) stream_ptr->class_intf_handle;
    control_if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR) control_ptr->class_intf_handle;

    /* Do the device use OUT pipe? */
    if (stream_if_ptr->iso_in_pipe == NULL) {
        USB_unlock();
        return USBERR_OPEN_PIPE_FAILED;
    }

    /* Validity checking, always needed when passing data to lower API */
    if (!usb_host_class_intf_validate(control_ptr)) {
        USB_unlock();
        return USBERR_NO_INTERFACE;
    }

    usb_hostdev_tr_init(&tr, (tr_callback) callback, (void *) call_parm);
    tr.G.RX_BUFFER = (unsigned char *) buffer;
    tr.G.RX_LENGTH = buf_size;

    status = _usb_host_recv_data(control_if_ptr->AUDIO_G.G.host_handle,
                                 stream_if_ptr->iso_in_pipe, &tr);

    USB_unlock();

    return status;
} /* Endbody */
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_init_ipipe
* Returned Value : Success as USB_OK
* Comments       :
*     Starts interrupt endpoint to poll for interrupt on specified device.
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_init_ipipe
(
    /* control interface instance */
    CLASS_CALL_STRUCT_PTR     audio_instance,

    /* Callback to application */
    tr_callback               user_callback,

    /* Callback parameter */
    void                     *user_callback_param
)
{ /* Body */
    TR_INIT_PARAM_STRUCT           tr;
    USB_STATUS                     status = USBERR_NO_INTERFACE;
    AUDIO_CONTROL_INTERFACE_STRUCT_PTR  if_ptr;

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

    USB_lock();
    /* Validity checking, always needed when passing data to lower API */
    if (usb_host_class_intf_validate(audio_instance)) {
        if_ptr = (AUDIO_CONTROL_INTERFACE_STRUCT_PTR) audio_instance->class_intf_handle;

        if_ptr->interrupt_callback = user_callback;
        if_ptr->interrupt_callback_param = user_callback_param;

        if (if_ptr->interrupt_pipe != NULL) {
            usb_hostdev_tr_init(&tr, (tr_callback) usb_class_audio_int_callback, (void *) audio_instance);
            tr.G.RX_BUFFER = (unsigned char *) &if_ptr->interrupt_buffer;
            tr.G.RX_LENGTH = sizeof(if_ptr->interrupt_buffer);

            if (USB_STATUS_TRANSFER_QUEUED == (status = _usb_host_recv_data(
                                                   if_ptr->AUDIO_G.G.host_handle,
                                                   if_ptr->interrupt_pipe,
                                                   &tr
                                               )))
            {
                status = USB_OK;
            }
        }
        else
            status = USBERR_OPEN_PIPE_FAILED;
    }/* Endif */

    USB_unlock();

#ifdef _HOST_DEBUG_
    if (!status)
        DEBUG_LOG_TRACE("usb_class_audio_init_ipipe, SUCCESSFUL");
    else
        DEBUG_LOG_TRACE("usb_class_audio_init_ipipe, FAILED");
#endif

    return status;
} /* End Body */
Example #4
0
USB_STATUS usb_printer_class_verify
   (
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR      cc_ptr,
      
      /* [IN] TR memory already allocated, initialized here */
      TR_INIT_PARAM_STRUCT_PTR   tr_ptr,
   
      /* [IN] callback for completion/status */
      tr_callback                callback,
   
      /* [IN] user parameter returned by callback */
      pointer                    call_parm
   )
{ /* Body */

   PRINTER_INTERFACE_STRUCT_PTR  pis_ptr;
   USB_STATUS                    error = USBERR_NO_INTERFACE;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_class_verify");
   #endif
   
   USB_lock ();

   if (usb_host_class_intf_validate (cc_ptr)) {
      pis_ptr = (PRINTER_INTERFACE_STRUCT_PTR)
         cc_ptr->class_intf_handle;
      error =  usb_hostdev_validate (pis_ptr->dev_handle);

      if (error == USB_OK) {
         if (callback == NULL) {
            error = USBERR_NULL_CALLBACK;
         } else {
            usb_hostdev_tr_init (tr_ptr, callback, call_parm);
         } /* Endif */
      } /* EndIf */
   } /* Endif */

   USB_unlock ();   

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_class_verify, SUCCESSFUL");
   #endif
   
   return error;   

} /* Endbody */
Example #5
0
USB_STATUS usb_class_cdc_init_ipipe
    (
        /* ACM interface instance */
        CLASS_CALL_STRUCT_PTR      acm_instance
    )
{ /* Body */
    TR_INIT_PARAM_STRUCT           tr;
    USB_STATUS                     status = USBERR_NO_INTERFACE;
    USB_ACM_CLASS_INTF_STRUCT_PTR  if_ptr;

    USB_lock();
    /* Validity checking, always needed when passing data to lower API */
    if (usb_host_class_intf_validate(acm_instance)) {
        if_ptr = (USB_ACM_CLASS_INTF_STRUCT_PTR) acm_instance->class_intf_handle;
    
        if (if_ptr->interrupt_pipe != NULL) {
            usb_hostdev_tr_init(&tr, (tr_callback)usb_class_cdc_int_acm_callback, (pointer) acm_instance);
            tr.RX_BUFFER = (uchar_ptr)&if_ptr->interrupt_buffer;
            tr.RX_LENGTH = sizeof(if_ptr->interrupt_buffer);
        	
            if (USB_STATUS_TRANSFER_QUEUED == (status = _usb_host_recv_data(
               	if_ptr->CDC_G.G.host_handle,
                if_ptr->interrupt_pipe,
                &tr
            )))
            {
                status = USB_OK;
            }
        }
        else
            status = USBERR_OPEN_PIPE_FAILED;
    }

    USB_unlock();

    return status;
}
Example #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_PTR                 devreq_ptr,
         
      /* buffer to send/receive */
      uchar_ptr                     buff_ptr
   )
{ /* Body */
  
   DEV_INSTANCE_PTR           dev_ptr;
   _usb_pipe_handle           pipe_handle;
   TR_INIT_PARAM_STRUCT       tr;
   USB_STATUS                 error;

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

   if (error != USB_OK) 
   {

      return USBERR_DEVICE_NOT_FOUND;
   } /* Endif */
     
   dev_ptr = (DEV_INSTANCE_PTR)dev_handle;
   pipe_handle = dev_ptr->control_pipe;
   
   /* Initialize the TR with TR index and default control callback 
   ** function if there is one registered 
   */
   usb_hostdev_tr_init(&tr, dev_ptr->control_callback, 
      dev_ptr->control_callback_param);
   
   /* Set buffer length if required */
   switch (devreq_ptr->BREQUEST) {
      case REQ_SET_DESCRIPTOR:
         tr.TX_BUFFER = buff_ptr;
         tr.TX_LENGTH = utoh16(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.RX_BUFFER = buff_ptr;
         tr.RX_LENGTH = utoh16(devreq_ptr->WLENGTH);
         break;
   } /* EndSwitch */

   tr.DEV_REQ_PTR = (uchar_ptr)(devreq_ptr);

   if ((dev_ptr->state < DEVSTATE_ENUM_OK) ||
      (tr.CALLBACK == NULL))
   {
      tr.CALLBACK = usb_host_cntrl_transaction_done;
      tr.CALLBACK_PARAM = NULL;
   } /* Endif */
   error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);
   
   return error;
} /* EndBody */
USB_STATUS usb_class_mass_pass_on_usb
   (
      /* [IN] Interface handle */
      USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr
   )
{ /* Body */
   COMMAND_OBJECT_PTR      cmd_ptr = NULL;
   TR_INIT_PARAM_STRUCT    tr_init;
   USB_STATUS              status = USB_OK;
   uint_8                  tmp;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb");
   #endif
   
   /* Nothing can be done if there is nothing pending */
   usb_class_mass_get_pending_request(intf_ptr, &cmd_ptr);
   if (cmd_ptr == NULL) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb, no matching request");
      #endif
      return (USB_STATUS)USB_MASS_NO_MATCHING_REQUEST;
   } /* Endif */

   /* Determine the appropriate action based on the phase */
   switch (cmd_ptr->STATUS) {
      case STATUS_QUEUED_IN_DRIVER:
         /* means that CBW needs to be sent.*/
         usb_hostdev_tr_init(&tr_init, usb_class_mass_call_back_cbw,
            (pointer2)intf_ptr);
         tr_init.TX_BUFFER = (uchar_ptr)cmd_ptr->CBW_PTR;
         tr_init.TX_LENGTH = sizeof(CBW_STRUCT);

         status = _usb_host_send_data(intf_ptr->G.host_handle,
            intf_ptr->BULK_OUT_PIPE, &tr_init);
         break;

      case STATUS_FINISHED_CBW_ON_USB:
         /* Determine next phase (DATA or STATUS), length and direction */
         if (utoh32(cmd_ptr->CBW_PTR->DCBWDATATRANSFERLENGTH) > 0) {

            /* Commen TR setup for IN or OUT direction */
            usb_hostdev_tr_init(&tr_init,usb_class_mass_call_back_dphase,
               (pointer2)intf_ptr);

            tmp = (uint_8)((cmd_ptr->CBW_PTR->BMCBWFLAGS) & MASK_NON_DIRECTION_BITS);
            switch(tmp) {
               case DIRECTION_OUT:
                  /* Make a TR with DATA Phase call back.*/
                  tr_init.TX_BUFFER = (uchar_ptr)cmd_ptr->DATA_BUFFER;
                  tr_init.TX_LENGTH = cmd_ptr->BUFFER_LEN;

                  status = _usb_host_send_data(intf_ptr->G.host_handle,
                     intf_ptr->BULK_OUT_PIPE, &tr_init);
                  break;

               case DIRECTION_IN:
                  /* Make a TR with DATA call back.*/
                  tr_init.RX_BUFFER = (uchar_ptr)cmd_ptr->DATA_BUFFER;
                  tr_init.RX_LENGTH = cmd_ptr->BUFFER_LEN;

                  status = _usb_host_recv_data(intf_ptr->G.host_handle,
                     intf_ptr->BULK_IN_PIPE, &tr_init);
                  break;

               default:
                  break;
            } /* Endswitch */
            break;
         } /* Endif */

         /*
         ** else case:
         ** No data transfer is expected of the request. Fall through to
         ** STATUS phase
         */

      case STATUS_FINISHED_DPHASE_ON_USB:
         /* Make a TR and send it with STATUS call back */
         usb_hostdev_tr_init(&tr_init,usb_class_mass_call_back_csw,
            (pointer2)intf_ptr);
         tr_init.RX_BUFFER = (uchar_ptr)cmd_ptr->CSW_PTR;
         tr_init.RX_LENGTH = sizeof(CSW_STRUCT);

         status = _usb_host_recv_data(intf_ptr->G.host_handle,
            intf_ptr->BULK_IN_PIPE, &tr_init);
            
         break;

      case STATUS_FINISHED_CSW_ON_USB: /* No action */
      case STATUS_FAILED_IN_CSW:       /* Should never happen */
      default:
         break;
   } /* Endswitch */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb, SUCCESSFUL");
   #endif
   
   return status;
} /* Endbody */
Example #8
0
void Mouse_Task( uint32_t param )
{
    USB_STATUS              status = USB_OK;
    TR_INIT_PARAM_STRUCT    tr;
    HID_COMMAND_PTR         hid_com;
    unsigned char               *buffer;
    PIPE_STRUCT_PTR         pipe;
    uint32_t                 e;
    _usb_host_handle        mouse_host_handle = (_usb_host_handle) param;
   
    hid_com = (HID_COMMAND_PTR) _mem_alloc(sizeof(HID_COMMAND));

    /* event for USB callback signaling */
    _lwevent_create(&USB_Mouse_Event, LWEVENT_AUTO_CLEAR);

    printf("\nMQX USB HID Mouse Demo\nWaiting for USB Mouse to be attached...\n");
    fflush(stdout);
   
    /*
    ** Infinite loop, waiting for events requiring action
    */
    for ( ; ; ) {
    
        // Wait for insertion or removal event
        _lwevent_wait_ticks(&USB_Mouse_Event, USB_EVENT_CTRL, FALSE, 0);
        
        switch ( mouse_hid_device.DEV_STATE ) {
            case USB_DEVICE_IDLE:
                break;
            case USB_DEVICE_ATTACHED:
                printf("\nMouse device attached\n");
                fflush(stdout);
                mouse_hid_device.DEV_STATE = USB_DEVICE_SET_INTERFACE_STARTED;
                status = _usb_hostdev_select_interface(mouse_hid_device.DEV_HANDLE, mouse_hid_device.INTF_HANDLE, (void *)&mouse_hid_device.CLASS_INTF);
                if (status != USB_OK) {
                    printf("\nError in _usb_hostdev_select_interface: %x", status);
                    fflush(stdout);
                    _task_block();
                } /* Endif */
                break;
            case USB_DEVICE_SET_INTERFACE_STARTED:
                break;

            case USB_DEVICE_INTERFACED:
                pipe = _usb_hostdev_find_pipe_handle(mouse_hid_device.DEV_HANDLE, mouse_hid_device.INTF_HANDLE, USB_INTERRUPT_PIPE, USB_RECV);
                if (pipe == NULL) {
                    printf("\nError getting interrupt pipe.");
                    fflush(stdout);
                    _task_block();
                }
                _usb_hostdev_get_buffer(mouse_hid_device.DEV_HANDLE, pipe->MAX_PACKET_SIZE, (void **) &buffer);
                if (buffer == NULL) {
                    printf("\nMemory allocation failed. STATUS: %x", status);
                    fflush(stdout);
                    _task_block();
                }

                printf("Mouse interfaced, setting protocol...\n");
                /* now we will set the USB Hid standard boot protocol */
                mouse_hid_device.DEV_STATE = USB_DEVICE_SETTING_PROTOCOL;
            
                hid_com->CLASS_PTR = (CLASS_CALL_STRUCT_PTR)&mouse_hid_device.CLASS_INTF;
                hid_com->CALLBACK_FN = usb_host_hid_mouse_ctrl_callback;
                hid_com->CALLBACK_PARAM = 0;
            
                status = usb_class_hid_set_protocol(hid_com, USB_PROTOCOL_HID_MOUSE);
         
                if (status != USB_STATUS_TRANSFER_QUEUED) {
                      printf("\nError in usb_class_hid_set_protocol: %x", status);
                      fflush(stdout);
                }
                break;
            case USB_DEVICE_INUSE:
                printf("Mouse device ready, try to move the mouse\n");
                while (1) {
                    /******************************************************************
                    Initiate a transfer request on the interrupt pipe
                    ******************************************************************/
                    usb_hostdev_tr_init(&tr, usb_host_hid_mouse_recv_callback, NULL);
                    tr.G.RX_BUFFER = buffer;
                    tr.G.RX_LENGTH = pipe->MAX_PACKET_SIZE;                     
                        
                    status = _usb_host_recv_data(mouse_host_handle, pipe, &tr);
                        
                    if (status != USB_STATUS_TRANSFER_QUEUED) {
                        printf("\nError in _usb_host_recv_data: %x", status);
                        fflush(stdout);
                    }
                    
                    /* Wait untill we get the data from keyboard. */
                    _lwevent_wait_ticks(&USB_Mouse_Event, USB_EVENT_CTRL | USB_EVENT_DATA | USB_EVENT_DATA_CORRUPTED, FALSE, 0);
                        
                    e = _lwevent_get_signalled();
                    if (USB_EVENT_DATA == e) {
                        if(mouse_hid_device.DEV_STATE == USB_DEVICE_INUSE) {
                            process_mouse_buffer((unsigned char *)buffer);
                        }
                    }
                    else if (USB_EVENT_CTRL == e) {
                        /* kick the outer loop again to handle the CTRL event */
                        _lwevent_set(&USB_Mouse_Event, USB_EVENT_CTRL);
                        break;
                    }
                }
                break;
            case USB_DEVICE_DETACHED:
                printf("Going to idle state\n");
                mouse_hid_device.DEV_STATE = USB_DEVICE_IDLE;
                break;
            case USB_DEVICE_OTHER:
                break;
             default:
                printf("Unknown Mouse Device State = %d\n", mouse_hid_device.DEV_STATE);
                fflush(stdout);
                break;
        } /* Endswitch */
    } /* Endfor */
} /* Endbody */
Example #9
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);
}
Example #10
0
void Mouse_Task( uint_32 param )
{
    USB_STATUS              status = USB_OK;
    _usb_pipe_handle        pipe;
    TR_INIT_PARAM_STRUCT    tr;
    HID_COMMAND_PTR         hid_com;
    uchar_ptr               buffer;
    _usb_host_handle        mouse_host_handle = (_usb_host_handle) param;
   
    /***************************************************************************
    ** Allocate memory for being able to send commands to HID class driver. Note 
    ** that USB_mem_alloc_uncached() allocates aligned buffers on cache line boundry.
        ** This  is required if program is running with data cache on system.
    ***************************************************************************/
    hid_com = (HID_COMMAND_PTR) USB_mem_alloc_uncached(sizeof(HID_COMMAND));

    /* event for USB callback signaling */
    _lwevent_create(&USB_Mouse_Event, LWEVENT_AUTO_CLEAR);

    /* Allocate buffer to receive data from interrupt. It must be created on uncached heap,
    ** since some USB host controllers use DMA to access those buffers.
    */
    buffer = USB_mem_alloc_uncached(HID_MOUSE_BUFFER_SIZE);
    if (!buffer) {
        printf("\nError allocating buffer!");
        fflush(stdout);
        exit(1);
    } /* Endif */

    printf("\nMQX USB HID Mouse Demo\nWaiting for USB Mouse to be attached...\n");
    fflush(stdout);
   
    /*
    ** Infinite loop, waiting for events requiring action
    */
    for ( ; ; ) {
    
        // Wait for insertion or removal event
        _lwevent_wait_ticks(&USB_Mouse_Event, USB_Mouse_Event_CTRL, FALSE, 0);
        
        switch ( mouse_hid_device.DEV_STATE ) {
            case USB_DEVICE_IDLE:
                break;
            case USB_DEVICE_ATTACHED:
                printf("\nMouse device attached\n");
                fflush(stdout);
                mouse_hid_device.DEV_STATE = USB_DEVICE_SET_INTERFACE_STARTED;
                status = _usb_hostdev_select_interface(mouse_hid_device.DEV_HANDLE, mouse_hid_device.INTF_HANDLE, (pointer)&mouse_hid_device.CLASS_INTF);
                if (status != USB_OK) {
                    printf("\nError in _usb_hostdev_select_interface: %x", status);
                    fflush(stdout);
                    exit(1);
                } /* Endif */
                break;
            case USB_DEVICE_SET_INTERFACE_STARTED:
                break;
            case USB_DEVICE_INTERFACED:
                printf("Mouse interfaced, setting protocol...\n");
                /* now we will set the USB Hid standard boot protocol */
                mouse_hid_device.DEV_STATE = USB_DEVICE_SETTING_PROTOCOL;
            
                hid_com->CLASS_PTR = (CLASS_CALL_STRUCT_PTR)&mouse_hid_device.CLASS_INTF;
                hid_com->CALLBACK_FN = usb_host_hid_mouse_ctrl_callback;
                hid_com->CALLBACK_PARAM = 0;
            
                status = usb_class_hid_set_protocol(hid_com, USB_PROTOCOL_HID_MOUSE);
         
                if (status != USB_STATUS_TRANSFER_QUEUED) {
                      printf("\nError in usb_class_hid_set_protocol: %x", status);
                      fflush(stdout);
                }
                break;
            case USB_DEVICE_INUSE:
                pipe = _usb_hostdev_find_pipe_handle(mouse_hid_device.DEV_HANDLE, mouse_hid_device.INTF_HANDLE, USB_INTERRUPT_PIPE, USB_RECV);
                if(pipe){
                    printf("Mouse device ready, try to move the mouse\n");
                
                    while(1){
                        /******************************************************************
                        Initiate a transfer request on the interrupt pipe
                        ******************************************************************/
                        usb_hostdev_tr_init(&tr, usb_host_hid_mouse_recv_callback, NULL);
                        tr.RX_BUFFER = buffer;
                        tr.RX_LENGTH = HID_MOUSE_BUFFER_SIZE;                       
                        
                        status = _usb_host_recv_data(mouse_host_handle, pipe, &tr);
                        
                        if (status != USB_STATUS_TRANSFER_QUEUED) {
                            printf("\nError in _usb_host_recv_data: %x", status);
                            fflush(stdout);
                        }
                    
                        /* Wait untill we get the data from keyboard. */
                        _lwevent_wait_ticks(&USB_Mouse_Event, USB_Mouse_Event_CTRL | USB_Mouse_Event_DATA, FALSE, 0);
                        
                        /* if not detached in the meanwhile */
                        if(mouse_hid_device.DEV_STATE == USB_DEVICE_INUSE) {
                            process_mouse_buffer((uchar *)buffer);
                        }
                        else {
                            /* kick the outer loop again to handle the CTRL event */
                            _lwevent_set(&USB_Mouse_Event, USB_Mouse_Event_CTRL);
                            break;
                        }
                    }
                }
                break;
            case USB_DEVICE_DETACHED:
                printf("Going to idle state\n");
                mouse_hid_device.DEV_STATE = USB_DEVICE_IDLE;
                break;
            case USB_DEVICE_OTHER:
                break;
             default:
                printf("Unknown Mouse Device State = %d\n", mouse_hid_device.DEV_STATE);
                fflush(stdout);
                break;
        } /* Endswitch */
    } /* Endfor */
} /* Endbody */
Example #11
0
void Mouse_Task ( uchar *buffer, HID_COMMAND_PTR hid_com  )
{
	USB_STATUS              status = USB_OK;
	static _usb_pipe_handle        pipe;
	static uint_32 check = 0, usb_event_flag = 1;
	static TR_INIT_PARAM_STRUCT    tr;
	uint_32                 result, test_buffer[4]; 
   	
		// Wait for insertion or removal event
        //result = _usb_event_wait_ticks(&USB_Event, USB_EVENT_CTRL, FALSE, 0);
        
        //if (USB_EVENT_NOT_SET == result) return;
      	switch ( hid_device.DEV_STATE ) {
         	case USB_DEVICE_IDLE:
            	break;
         	case USB_DEVICE_ATTACHED:
	            printf("\nMouse device attached");
	            //fflush(stdout);
	            hid_device.DEV_STATE = USB_DEVICE_SET_INTERFACE_STARTED;
	            status = _usb_hostdev_select_interface(hid_device.DEV_HANDLE, hid_device.INTF_HANDLE, (pointer2)&hid_device.CLASS_INTF);
	            if (status != USB_OK) {
               		printf("\nError in _usb_hostdev_select_interface: %x", status);
               		//fflush(stdout);
               		exit(1);
            	} /* Endif */
            	break;
         	case USB_DEVICE_SET_INTERFACE_STARTED:
            	break;
         	case USB_DEVICE_INTERFACED:
         		printf("Mouse interfaced, setting protocol...\n");
         		/* now we will set the USB Hid standard boot protocol */
            	hid_device.DEV_STATE = USB_DEVICE_SETTING_PROTOCOL;
            
	            hid_com->CLASS_PTR = (CLASS_CALL_STRUCT_PTR)&hid_device.CLASS_INTF;
	            hid_com->CALLBACK_FN = usb_host_hid_ctrl_callback;
	            hid_com->CALLBACK_PARAM = 0;
         	
	         	status = usb_class_hid_set_protocol(hid_com, USB_PROTOCOL_HID_MOUSE);
         
	         	if (status != USB_STATUS_TRANSFER_QUEUED) {
	                  printf("\nError in usb_class_hid_set_protocol: %x", status);
	                  //fflush(stdout);
	         	}
	            break;
			case USB_DEVICE_INUSE:
			    if(0 == check){
			      check = 1;
            pipe = _usb_hostdev_find_pipe_handle(hid_device.DEV_HANDLE, hid_device.INTF_HANDLE, USB_INTERRUPT_PIPE, USB_RECV);
         		if(pipe){
         			printf("Mouse device ready, try to move the mouse\n");
			      } 
			    }

   			/******************************************************************
              Initiate a transfer request on the interrupt pipe
              ******************************************************************/
              if (usb_event_flag == 1){
     			      usb_hostdev_tr_init(&tr, usb_host_hid_recv_callback, NULL);
              	tr.RX_BUFFER = buffer;
              	tr.RX_LENGTH = HID_BUFFER_SIZE;	                  	
              	
              	status = _usb_host_recv_data(host_handle, pipe, &tr);
              	
              	if (status != USB_STATUS_TRANSFER_QUEUED) {
                 	printf("\nError in _usb_host_recv_data: %x", status);
                 	//fflush(stdout);
                }
              }
            
              /* Wait untill we get the data from keyboard. */
              if(_usb_event_wait_ticks(&USB_Event,USB_EVENT_CTRL | USB_EVENT_DATA, FALSE, 0) == USB_EVENT_SET){
                usb_event_flag = 1;
                _usb_event_clear(&USB_Event, USB_EVENT_CTRL | USB_EVENT_DATA);
              } else {
                usb_event_flag = 0;
              }
              
              /* if not detached in the meanwhile */
              if((hid_device.DEV_STATE == USB_DEVICE_INUSE) && (usb_event_flag == 1)) {	                         
//              if((hid_device.DEV_STATE == USB_DEVICE_INUSE)) {	                         
                  process_mouse_buffer((uchar *)buffer);  
                  //_usb_event_clear(&USB_Event, USB_EVENT_CTRL | USB_EVENT_DATA);      
                                             	                
              }
              //else {
              //    /* kick the outer loop again to handle the CTRL event */
              //    _usb_event_set(&USB_Event, USB_EVENT_CTRL);
              //    break;
              //}
	         		
    	     	break;
         	case USB_DEVICE_DETACHED:
         	  check = 0;
         		printf("Going to idle state\n");
            	hid_device.DEV_STATE = USB_DEVICE_IDLE;
            	break;
         	case USB_DEVICE_OTHER:
	            break;
    	     default:
        	    printf("Unknown Mouse Device State = %d\n", hid_device.DEV_STATE);
            	//fflush(stdout);
            	break;
      	} /* Endswitch */
   
} /* Endbody */
Example #12
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_PTR                 devreq,

      /* buffer to send/receive */
      uchar_ptr                     buff_ptr,

      /* callback upon completion */
      tr_callback                   callback,

      /* [IN] the parameter to pass back to the callback function */
      pointer                       callback_param
   )
{ /* Body */

   DEV_INSTANCE_PTR           dev_ptr;
   _usb_pipe_handle           pipe_handle;
   TR_INIT_PARAM_STRUCT       tr;
   USB_STATUS                 error = USB_OK;

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request");
   #endif
   
   /* Verify that device handle is valid */
   USB_lock();
   error = usb_hostdev_validate(dev_handle);

   if (error != USB_OK) {
      USB_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_PTR)dev_handle;

   if (dev_ptr->state < DEVSTATE_ENUM_OK) {
      USB_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.G.RX_BUFFER = buff_ptr;
      tr.G.RX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq->WLENGTH);
   } else {
      tr.G.TX_BUFFER = buff_ptr;
      tr.G.TX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq->WLENGTH);
   } /* EndIf */

   tr.DEV_REQ_PTR = (uchar_ptr)devreq;

   error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);

   USB_unlock();

   #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request,SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */
Example #13
0
void Main_Task(uint_32 param)
{
    USB_STATUS status = USB_OK;
    _usb_pipe_handle pipe;
    TR_INIT_PARAM_STRUCT tr;
    HID_COMMAND hid_com;
    uchar *buffer;

    printf("\n** MQX USB Keyboard To Mouse Demo **\n");
    
    printf("\nDemo will allow you control mouse cursor on your PC using keyboard attached to TWR-SER2 board.");
    printf("\nThis demo requires TWR-SER2 card and correct BSP setting.");
    printf("\nSee FSL_MQX_getting_started.pdf chapter 7 for details.");
    fflush(stdout);

    MouseDev_Init();

    /* Allocate buffer to receive data from interrupt. It must be created on uncached heap,
    ** since some USB host controllers use DMA to access those buffers.
    */
    buffer = USB_mem_alloc_uncached(HID_BUFFER_SIZE);
    if (buffer == NULL) {
        printf("\nMemory allocation failed. STATUS: %x", status);
        fflush(stdout);
        _task_block();
    }
    
    /* _usb_otg_init needs to be done with interrupts disabled */
    _int_disable();

    /* event for USB callback signaling */
    _lwevent_create(&USB_Event, LWEVENT_AUTO_CLEAR);

    _int_install_unexpected_isr();

    /* Register USB interface and its settings from BSP */
    if (MQX_OK != _usb_host_driver_install(&_bsp_usb_host_khci0_if)) {
        printf("\n\nUSB Host Installation failed.");
        fflush(stdout);
        _task_block();
    }

    /*
     ** It means that we are going to act like host, so we initialize the
     ** host stack. This call will allow USB system to allocate memory for
     ** data structures, it uses later (e.g pipes etc.).
     */
    status = _usb_host_init(&_bsp_usb_host_khci0_if, &host_handle);

    if(status != USB_OK) {
        printf("\nUSB Host Initialization failed. STATUS: %x", status);
        fflush(stdout);
        _task_block();
    }

    /*
     ** since we are going to act as the host driver, register the driver
     ** information for wanted class/subclass/protocols
     */
    status = _usb_host_driver_info_register(host_handle, DriverInfoTable);
    if(status != USB_OK) {
        printf("\nDriver Registration failed. STATUS: %x", status);
        fflush(stdout);
        _task_block();
    }

    _int_enable();
    printf("\nHost initialization finished. Attach USB Keyboard to the board.");

    /*
     ** Infinite loop, waiting for events requiring action
     */
    for(;;) {

        // Wait for insertion or removal event
        _lwevent_wait_ticks(&USB_Event, USB_EVENT_CTRL, FALSE, 0);

        switch (hid_device.DEV_STATE) {

        case USB_DEVICE_IDLE:
            break;

        case USB_DEVICE_ATTACHED:
            hid_device.DEV_STATE = USB_DEVICE_SET_INTERFACE_STARTED;

            status = _usb_hostdev_select_interface(hid_device.DEV_HANDLE, hid_device.INTF_HANDLE, (pointer) & hid_device.CLASS_INTF);
            if(status != USB_OK) {
                printf("\nError in _usb_hostdev_select_interface: %x", status);
                fflush(stdout);
                _task_block();
            }
            break;

        case USB_DEVICE_SET_INTERFACE_STARTED:
            break;

        case USB_DEVICE_INTERFACED:
            printf("\nKeyboard device interfaced, setting protocol.");
            /* now we will set the USB Hid standard boot protocol */
            hid_device.DEV_STATE = USB_DEVICE_SETTING_PROTOCOL;

            hid_com.CLASS_PTR = (CLASS_CALL_STRUCT_PTR) & hid_device.CLASS_INTF;
            hid_com.CALLBACK_FN = usb_host_hid_ctrl_callback;
            hid_com.CALLBACK_PARAM = 0;

            /* Force the keyboard to behave as in USB Hid class standard boot protocol */
            status = usb_class_hid_set_protocol(&hid_com, USB_PROTOCOL_HID_KEYBOARD);

            if(status != USB_STATUS_TRANSFER_QUEUED) {
                printf("\nError in usb_class_hid_set_protocol: %x", status);
                fflush(stdout);
            }

            break;

        case USB_DEVICE_INUSE:
            pipe = _usb_hostdev_find_pipe_handle(hid_device.DEV_HANDLE, hid_device.INTF_HANDLE, USB_INTERRUPT_PIPE, USB_RECV);

            if(pipe) {
                printf("\n\nUse W, A, S or D to move the cursor.\nW = UP\nS = DOWN\nA = LEFT\nD = RIGHT\n");

                while(1) {
                  /******************************************************************
                    Initiate a transfer request on the interrupt pipe
                  ******************************************************************/
                    usb_hostdev_tr_init(&tr, usb_host_hid_recv_callback, NULL);
                    tr.G.RX_BUFFER = (uchar *) buffer;
                    tr.G.RX_LENGTH = HID_BUFFER_SIZE;

                    status = _usb_host_recv_data(host_handle, pipe, &tr);

                    if(status != USB_STATUS_TRANSFER_QUEUED) {
                        printf("\nError in _usb_host_recv_data: %x", status);
                        fflush(stdout);
                    }

                    /* Wait untill we get the data from keyboard. */
                    _lwevent_wait_ticks(&USB_Event, USB_EVENT_CTRL | USB_EVENT_DATA, FALSE, 0);

                    /* if not detached in the meanwhile */
                    if(hid_device.DEV_STATE == USB_DEVICE_INUSE) {
                        process_kbd_buffer((uchar *)buffer);
                    }
                    else {
                        /* kick the outer loop again to handle the CTRL event */
                        _lwevent_set(&USB_Event, USB_EVENT_CTRL);
                        break;
                    }

                    /* Slight delay to be nice to other processes. (Note that keyboards have its 
                       own autorepeat delay typically much longer than one would expect. In case 
                       the user holds the key (without any other keys changed), the USB response 
                       from keyboard is delayed (typ by 500ms). This is why the USB host should 
                       handle autorepeat feature by itself (not done in this example) */
                    _time_delay(1);

                    USB_HID_Periodic_Task(); //feed the USB device with the correct setup answers
                }
            }
            break;

        case USB_DEVICE_DETACHED:
            printf("Going to idle state\n");
            hid_device.DEV_STATE = USB_DEVICE_IDLE;
            break;
        }
    }
}