void usb_host_hid_ctrl_callback
   (
      /* [IN] pointer to pipe */
      _usb_pipe_handle  pipe_handle,

      /* [IN] user-defined parameter */
      pointer2           user_parm,

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

      /* [IN] length of data transferred */
      uint_32           buflen,

      /* [IN] status, hopefully USB_OK or USB_DONE */
      uint_32           status
   )
{ /* Body */
   if (status == USBERR_ENDPOINT_STALLED) {
      printf("\nHID Set_Protocol Request BOOT is not supported!\n");
      //fflush(stdout);
   }
   else if (status) {
      printf("\nHID Set_Protocol Request BOOT failed!: 0x%x ... END!\n", status);
      //fflush(stdout);
      exit(1);
   } /* Endif */

    if(hid_device.DEV_STATE == USB_DEVICE_SETTING_PROTOCOL)
        hid_device.DEV_STATE = USB_DEVICE_INUSE;
    
    /* notify application that status has changed */
    _usb_event_set(&USB_Event, USB_EVENT_CTRL);
   
} /* Endbody */
static void usb_class_cdc_ctrl_acm_callback
   (
      /* [IN] pointer to pipe */
      _usb_pipe_handle  pipe,

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

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

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

      /* [IN] status, hopefully USB_OK or USB_DONE */
      uint_32           status
   )
{ /* Body */
    CLASS_CALL_STRUCT_PTR         acm_instance = (CLASS_CALL_STRUCT_PTR) param;
    USB_ACM_CLASS_INTF_STRUCT_PTR if_ptr;
    
    UNUSED(pipe)
    UNUSED(buffer)
    UNUSED(len)
    UNUSED(status)

    if_ptr = (USB_ACM_CLASS_INTF_STRUCT_PTR) acm_instance->class_intf_handle;

    _usb_event_set(&if_ptr->acm_event, USB_ACM_CTRL_PIPE_FREE); /* mark we are not using interrupt pipe */

} /*EndBody */
static void usb_class_cdc_in_data_callback
   (
      /* [IN] pointer to pipe */
      _usb_pipe_handle  pipe,

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

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

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

      /* [IN] status, hopefully USB_OK or USB_DONE */
      uint_32           status
   )
{ /* Body */
    FILE_CDC_PTR                       fd_ptr = (FILE_CDC_PTR) param;
    CLASS_CALL_STRUCT_PTR          data_instance = (CLASS_CALL_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;
    
    USB_DATA_CLASS_INTF_STRUCT_PTR if_ptr;
    CLASS_CALL_STRUCT_PTR          acm_instance;
    USB_ACM_CLASS_INTF_STRUCT_PTR  acm_if_ptr;

    UNUSED(pipe)
    
    if_ptr = (USB_DATA_CLASS_INTF_STRUCT_PTR) data_instance->class_intf_handle;
    acm_instance = if_ptr->BOUND_CONTROL_INTERFACE;

    if ((acm_instance == NULL) || !usb_host_class_intf_validate(acm_instance))
        len = 0;
    else if (((CDC_SERIAL_INIT_PTR) fd_ptr->FLAGS)->FLAGS & USB_UART_HW_FLOW) {
        acm_if_ptr = (USB_ACM_CLASS_INTF_STRUCT_PTR) acm_instance->class_intf_handle;
        /* check the state of DCD signal for HW flow control files */
        if (!(acm_if_ptr->interrupt_buffer.bmStates & USB_ACM_STATE_RX_CARRIER))
           len = 0; /* ignore all received bytes is DCD is not set */
        /* check the state of DTR signal */
        if (!(acm_if_ptr->ctrl_state.bmStates[1] & USB_ACM_LINE_STATE_DTR))
           len = 0; /* ignore all sent bytes if DTR is not set */
    }
    
    /* in the case we have less data than expected, status is not USB_OK, but buffer is not NULL */
    if ((status != USB_OK) && (buffer == NULL)) /* if no data received */
        len = 0;
    if (if_ptr->RX_BUFFER_DRV != NULL)
        if_ptr->RX_BUFFER_DRV += len;
    if_ptr->RX_READ = len;

    _usb_event_set(&if_ptr->data_event, USB_DATA_READ_COMPLETE); /* signal that we have completed transfer on input pipe */

} /*EndBody */
void usb_class_cdc_acm_init
   (
      /* [IN]  structure with USB pipe information on the interface */
      PIPE_BUNDLE_STRUCT_PTR      pbs_ptr,

      /* [IN] acm call struct pointer2 */
      CLASS_CALL_STRUCT_PTR       ccs_ptr
   )
{ /* Body */
    USB_ACM_CLASS_INTF_STRUCT_PTR acm_anchor = NULL;
    USB_ACM_CLASS_INTF_STRUCT_PTR if_ptr = ccs_ptr->class_intf_handle;
    USB_STATUS                    status;
 
    /* Make sure the device is still attached */
    USB_lock();
    status = usb_host_class_intf_init(pbs_ptr, if_ptr, &acm_anchor_abstract);
    if (status == USB_OK) {
        /*
        ** We generate a code_key based on the attached device. This is used to
        ** verify that the device has not been detached and replaced with another.
        */
        ccs_ptr->code_key = 0;
        ccs_ptr->code_key = usb_host_class_intf_validate(ccs_ptr);
  
        if_ptr->CDC_G.IFNUM = ((INTERFACE_DESCRIPTOR_PTR)if_ptr->CDC_G.G.intf_handle)->bInterfaceNumber;
        if_ptr->interrupt_pipe = usb_hostdev_get_pipe_handle(pbs_ptr, USB_INTERRUPT_PIPE, 0);
  
        if (USB_OK != (status = _usb_event_init(&if_ptr->acm_event))) {
           status = USBERR_INIT_FAILED;
        }
        else {
            /* prepare events to be auto or manual */
            //_lwevent_set_auto_clear(&if_ptr->acm_event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_INT_PIPE_FREE);
            /* pre-set events */
            _usb_event_set(&if_ptr->acm_event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_INT_PIPE_FREE);
        }
    } /* Endif */
 
    /* Signal that an error has occured by setting the "code_key" */
    if (status) {
        ccs_ptr->code_key = 0;
    } /* Endif */
 
    USB_unlock();
    
} /* Endbody */
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : IRQ_ISR
* Returned Value : none
* Comments       : IRQ interrupt service routine
*     
*
*END*--------------------------------------------------------------------*/
void interrupt 64 IRQ_ISR(void)
{   
 	if(USB_DEVICE_INTERFACED == audio_stream.DEV_STATE)
 	{
		play = (boolean)(1 - play);
		/* play */
 		if (TRUE == play)
 		{
 			printf("Playing ...\r\n");
 			_usb_event_set(&USB_Event, USB_EVENT_RECEIVED_DATA);
 			EnableTimer1Interrupt();
 		}
 		/* stop */
 		else
 		{
 			printf("\nPaused.\n");
 			DisableTimer1Interrupt();
 		}
 	}
     IRQ_SC |= IRQ_SC_IRQF_MASK | IRQ_SC_IRQACK_MASK;     /* clear KBI interrupt */ 
}
void usb_host_hid_recv_callback
   (
      /* [IN] pointer to pipe */
      _usb_pipe_handle  pipe_handle,

      /* [IN] user-defined parameter */
      pointer2           user_parm,

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

      /* [IN] length of data transferred */
      uint_32           buflen,

      /* [IN] status, hopefully USB_OK or USB_DONE */
      uint_32           status
   )
{ /* Body */

   /* notify application that data are available */
    _usb_event_set(&USB_Event, USB_EVENT_DATA);

}
USB_STATUS usb_class_cdc_set_acm_ctrl_state
   (
      /* [IN] The communication device data instance structure */
      CLASS_CALL_STRUCT_PTR            ccs_ptr,
      /* [IN] DTR state to set */
      uint_8                           dtr,
      /* [IN] RTS state to set */
      uint_8                           rts
   )
{ /* Body */
    USB_DATA_CLASS_INTF_STRUCT_PTR if_data_ptr;
    USB_ACM_CLASS_INTF_STRUCT_PTR  if_acm_ptr;
    CLASS_CALL_STRUCT_PTR          acm_instance;
    USB_STATUS                     status = USBERR_NO_INTERFACE;
    USB_EVENT_STRUCT_PTR             event;
    CDC_COMMAND                    cmd;

    USB_lock();
    /* Validity checking: for data interface */
    if (usb_host_class_intf_validate(ccs_ptr)) {
        if_data_ptr = (USB_DATA_CLASS_INTF_STRUCT_PTR)ccs_ptr->class_intf_handle;
        acm_instance = if_data_ptr->BOUND_CONTROL_INTERFACE;
  
        if (usb_host_class_intf_validate(acm_instance)) {
            if_acm_ptr = (USB_ACM_CLASS_INTF_STRUCT_PTR) if_data_ptr->BOUND_CONTROL_INTERFACE->class_intf_handle;
   
            if (if_acm_ptr->acm_desc->bmCapabilities & USB_ACM_CAP_LINE_CODING) {
                event = &if_acm_ptr->acm_event;
   
                USB_unlock(); /* we must wait until ctrl pipe is used */
#if !HIGH_SPEED_DEVICE
                while(USB_EVENT_NOT_SET == _usb_event_wait_ticks(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH, FALSE, 0)){
                  _usb_khci_task();
                }
#endif
                _usb_event_clear(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH);
                
                USB_lock();
                if (usb_host_class_intf_validate(acm_instance)) {
                    cmd.CLASS_PTR = ccs_ptr;
                    cmd.CALLBACK_FN = (tr_callback)usb_class_cdc_ctrl_acm_callback;
                    cmd.CALLBACK_PARAM = acm_instance;
                    
                    if_acm_ptr->ctrl_state.bmStates[0]  = (uint_8)(dtr ? USB_ACM_LINE_STATE_DTR : 0);
                    if_acm_ptr->ctrl_state.bmStates[0] |= rts ? USB_ACM_LINE_STATE_RTS : 0;
                    status = usb_class_cdc_cntrl_common(&cmd, if_acm_ptr,
                        REQ_TYPE_OUT | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
                        USB_CDC_SET_CTRL_LINE_STATE, * ((uint_16 *) &if_acm_ptr->ctrl_state), 0, NULL);
                }
            }
            else
               status = USBERR_INVALID_BMREQ_TYPE;
        } /* Endif */
    } /* Endif */
    
 
    USB_unlock();
#if !HIGH_SPEED_DEVICE
                while(USB_EVENT_NOT_SET == _usb_event_wait_ticks(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH, FALSE, 0)){
                  _usb_khci_task();
                }
#endif
                _usb_event_clear(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH);
    _usb_event_set(event, USB_ACM_CTRL_PIPE_FREE);
 
    return status;
} /* Endbody */
USB_STATUS usb_class_cdc_get_acm_line_coding
   (
      /* [IN] The communication device data instance structure */
      CLASS_CALL_STRUCT_PTR            ccs_ptr,
      /* [IN] Where to store coding */
      USB_CDC_UART_CODING_PTR          uart_coding_ptr
   )
{ /* Body */
    USB_DATA_CLASS_INTF_STRUCT_PTR if_data_ptr;
    USB_ACM_CLASS_INTF_STRUCT_PTR  if_acm_ptr;
    CLASS_CALL_STRUCT_PTR          acm_instance;
    USB_STATUS                     status = USBERR_NO_INTERFACE;
    USB_EVENT_STRUCT_PTR             event;
    CDC_COMMAND                    cmd;
 
    USB_lock();
    /* Validity checking: for data interface */
    if (usb_host_class_intf_validate(ccs_ptr)) {
        if_data_ptr = (USB_DATA_CLASS_INTF_STRUCT_PTR)ccs_ptr->class_intf_handle;
        acm_instance = if_data_ptr->BOUND_CONTROL_INTERFACE;
  
        if (usb_host_class_intf_validate(if_data_ptr->BOUND_CONTROL_INTERFACE)) {
            if_acm_ptr = (USB_ACM_CLASS_INTF_STRUCT_PTR) if_data_ptr->BOUND_CONTROL_INTERFACE->class_intf_handle;
         
            if (if_acm_ptr->acm_desc->bmCapabilities & USB_ACM_CAP_LINE_CODING) {
                event = &if_acm_ptr->acm_event;
    
                USB_unlock(); /* we must wait until ctrl pipe is used */
#if !HIGH_SPEED_DEVICE   
                while(USB_EVENT_NOT_SET == _usb_event_wait_ticks(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH, FALSE, 0)){
                  _usb_khci_task();
                }
#endif
                _usb_event_clear(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH);
                
                USB_lock();
                if (usb_host_class_intf_validate(acm_instance)) {
                    cmd.CLASS_PTR = ccs_ptr;
                    cmd.CALLBACK_FN = (tr_callback)usb_class_cdc_ctrl_acm_callback;
                    cmd.CALLBACK_PARAM = acm_instance;
                    status = usb_class_cdc_cntrl_common(&cmd, if_acm_ptr,
                        REQ_TYPE_IN | REQ_TYPE_CLASS | REQ_TYPE_INTERFACE,
                        USB_CDC_GET_LINE_CODING, 0, 7 /* sizeof(USB_CDC_UART_CODING)*/, (uchar_ptr)uart_coding_ptr);
                }
            }
            else
               status = USBERR_INVALID_BMREQ_TYPE;
        } /* Endif */
    } /* Endif */
    
    USB_unlock();
#if !HIGH_SPEED_DEVICE
                while(USB_EVENT_NOT_SET == _usb_event_wait_ticks(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH, FALSE, 0)){
                  _usb_khci_task();
                }
#endif
                _usb_event_clear(event, USB_ACM_CTRL_PIPE_FREE | USB_ACM_DETACH);
    _usb_event_set(event, USB_ACM_CTRL_PIPE_FREE);
 
    return status;
} /* Endbody */
void usb_host_hid_mouse_event
   (
      /* [IN] pointer to device instance */
      _usb_device_instance_handle      dev_handle,

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

      /* [IN] code number for event causing callback */
      uint_32                          event_code
   )
{ /* Body */

   INTERFACE_DESCRIPTOR_PTR intf_ptr = (INTERFACE_DESCRIPTOR_PTR)intf_handle;
      
   switch (event_code) {
      case USB_ATTACH_EVENT:
      		printf("----- Attach Event -----\n");
      		/* Drop through into attach, same processing */
      case USB_CONFIG_EVENT:           
            printf("State = %d", hid_device.DEV_STATE);
            printf("  Class = %d", intf_ptr->bInterfaceClass);
            printf("  SubClass = %d", intf_ptr->bInterfaceSubClass);
            printf("  Protocol = %d\n", intf_ptr->bInterfaceProtocol);
            ////fflush(stdout);

         if (hid_device.DEV_STATE == USB_DEVICE_IDLE) {
            hid_device.DEV_HANDLE = dev_handle;
            hid_device.INTF_HANDLE = intf_handle;
            hid_device.DEV_STATE = USB_DEVICE_ATTACHED;
         } else {
            printf("HID device already attached - DEV_STATE = %d\n", hid_device.DEV_STATE);
            ////fflush(stdout);
         } /* Endif */
         
         break;
      case USB_INTF_EVENT:
      	 printf("----- Interfaced Event -----\n");
         hid_device.DEV_STATE = USB_DEVICE_INTERFACED;
         break ;
      case USB_DETACH_EVENT:
         /* Use only the interface with desired protocol */
         printf("----- Detach Event -----\n");
         printf("State = %d", hid_device.DEV_STATE);
         printf("  Class = %d", intf_ptr->bInterfaceClass);
         printf("  SubClass = %d", intf_ptr->bInterfaceSubClass);
         printf("  Protocol = %d\n", intf_ptr->bInterfaceProtocol);
         ////fflush(stdout);
         
    	 hid_device.DEV_HANDLE = NULL;
		 hid_device.INTF_HANDLE = NULL;
		 hid_device.DEV_STATE = USB_DEVICE_DETACHED;
         break;

      default:
         printf("HID Device state = %d??\n", hid_device.DEV_STATE);
         ////fflush(stdout);
         hid_device.DEV_STATE = USB_DEVICE_IDLE;
         break;
   } /* EndSwitch */

    /* notify application that status has changed */
    _usb_event_set(&USB_Event, USB_EVENT_CTRL);
   
} /* Endbody */
void usb_class_cdc_data_init
   (
      /* [IN]  structure with USB pipe information on the interface */
      PIPE_BUNDLE_STRUCT_PTR      pbs_ptr,

      /* [IN] acm call struct pointer */
      CLASS_CALL_STRUCT_PTR       ccs_ptr
   )
{ /* Body */
    USB_DATA_CLASS_INTF_STRUCT_PTR if_ptr = ccs_ptr->class_intf_handle;
    ENDPOINT_DESCRIPTOR_PTR        in_endpt, out_endpt;
    USB_STATUS                     status;
 
    /* Make sure the device is still attached */
    USB_lock();
    status = usb_host_class_intf_init(pbs_ptr, if_ptr, &data_anchor_abstract);
    if (status == USB_OK) {
        /*
        ** We generate a code_key based on the attached device. This is used to
        ** verify that the device has not been detached and replaced with another.
        */
        ccs_ptr->code_key = 0;
        ccs_ptr->code_key = usb_host_class_intf_validate(ccs_ptr);
  
        if_ptr->CDC_G.IFNUM = ((INTERFACE_DESCRIPTOR_PTR)if_ptr->CDC_G.G.intf_handle)->bInterfaceNumber;
        if_ptr->in_pipe = usb_hostdev_get_pipe_handle(pbs_ptr, USB_BULK_PIPE, USB_RECV);
        if_ptr->out_pipe = usb_hostdev_get_pipe_handle(pbs_ptr, USB_BULK_PIPE, USB_SEND);

        if ((if_ptr->in_pipe == NULL) && (if_ptr->out_pipe == NULL))
            status = USBERR_OPEN_PIPE_FAILED;
        else if (USB_OK != (status = _usb_event_init(&if_ptr->data_event)))
                status = USBERR_INIT_FAILED;
        else {
            /* prepare events to be auto or manual */
            //_lwevent_set_auto_clear(&if_ptr->data_event, USB_DATA_READ_PIPE_FREE | USB_DATA_SEND_PIPE_FREE);
            /* pre-set events */
            _usb_event_set(&if_ptr->data_event, USB_DATA_READ_PIPE_FREE | USB_DATA_SEND_PIPE_FREE);

            if (if_ptr->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_DESCRIPTOR_STRUCT_PTR) if_ptr->in_pipe)->NAK_COUNT > 3)
                    ((PIPE_DESCRIPTOR_STRUCT_PTR) if_ptr->in_pipe)->NAK_COUNT = 3; /* don't use host - predefined constant */
            }
            if (if_ptr->in_pipe) {
                /* The same as for OUT pipe applies here */
                if (((PIPE_DESCRIPTOR_STRUCT_PTR) if_ptr->out_pipe)->NAK_COUNT > 3)
                    ((PIPE_DESCRIPTOR_STRUCT_PTR) if_ptr->out_pipe)->NAK_COUNT = 3; /* don't use host - predefined constant */
            
                /* initialize buffer */
                /* size of buffer equals to the size of endpoint data size */
                if_ptr->RX_BUFFER_SIZE = ((PIPE_INIT_PARAM_STRUCT_PTR) (if_ptr->in_pipe))->MAX_PACKET_SIZE;
                if (NULL == (if_ptr->RX_BUFFER = USB_mem_alloc_zero(if_ptr->RX_BUFFER_SIZE))) {
                    status = USBERR_ALLOC;
                }
                else {
                    /* initialize members */
                    if_ptr->RX_BUFFER_APP = if_ptr->RX_BUFFER_DRV = if_ptr->RX_BUFFER;
                }
            }
        }
    } /* Endif */

    /* Signal that an error has occured by setting the "code_key" */
    if (status) {
        ccs_ptr->code_key = 0;
    } /* Endif */
 
    USB_unlock();
       
} /* Endbody */
Exemple #11
0
void usb_host_cdc_data_event
   (
      /* [IN] pointer to device instance */
      _usb_device_instance_handle      dev_handle,

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

      /* [IN] code number for event causing callback */
      uint_32                          event_code
   )
{ /* Body */
   INTERFACE_DESCRIPTOR_PTR   intf_ptr =
      (INTERFACE_DESCRIPTOR_PTR)intf_handle;
   DATA_DEVICE_STRUCT_PTR     data_device;

   fflush(stdout);
   switch (event_code) 
   {
      case USB_CONFIG_EVENT:
         /* Drop through into attach, same processing */
      case USB_ATTACH_EVENT: 
      {
         /* This data interface could be controlled by some control interface,
          * which could be already initialized (or not). We have to find 
          * that interface. Then we need to bind this interface with
          * found control interface. */
         INTERFACE_DESCRIPTOR_PTR   if_desc;
         
         if (USB_OK != usb_class_cdc_get_ctrl_descriptor(dev_handle,
            intf_handle,
            &if_desc))
            break;
         /* interface descriptor found, so we can allocate new data device */
         if (NULL == (data_device = USB_mem_alloc_zero(sizeof(DATA_DEVICE_STRUCT))))
            break;
         /* initializes interface members and selects it */
         if (USB_OK != _usb_hostdev_select_interface(dev_handle,
            intf_handle, (pointer)&data_device->CLASS_INTF))
         {
         	free(data_device);
         	break;
         }
         /* binds this data interface with its control interface, if possible */
         if (USB_OK != usb_class_cdc_bind_acm_interface((pointer)&data_device->CLASS_INTF,
            if_desc))
         {
            free(data_device);
         	break;
         }
         
#if 0 /* << EST */
         printf("----- CDC data interface attach event -----\n");
         fflush(stdout);
         printf("State = attached");
         printf("  Class = %%d", intf_ptr->bInterfaceClass);
         printf("  SubClass = %%d", intf_ptr->bInterfaceSubClass);
         printf("  Protocol = %%d\n", intf_ptr->bInterfaceProtocol);
         fflush(stdout);
#endif
         check_open = 0;

         break;
      }   
      case USB_INTF_EVENT: 
      {
         CLASS_CALL_STRUCT_PTR data_parser;
         //USB_CDC_UART_CODING uart_coding;
         
#if 0 /* << EST */
         fflush(stdout);
#endif         
         if (NULL == (data_parser = usb_class_cdc_get_data_interface(intf_handle)))
         	break;
         if (USB_OK == usb_class_cdc_install_driver(data_parser, device_name)) 
         {
             if (((USB_DATA_CLASS_INTF_STRUCT_PTR) (data_parser->class_intf_handle))->BOUND_CONTROL_INTERFACE != NULL) 
             {
                 if (reg_device == 0) 
                 {
                     reg_device = dev_handle;
                     _usb_event_set(&device_registered, 0x01);
                 }
             }
#if 0 /* << EST */
             printf("----- Device installed -----\n");
#endif
         }
#if 0 /* << EST */
         printf("----- CDC data interface selected -----\n");
#endif
         break;
      }
         
      case USB_DETACH_EVENT: 
      {
         CLASS_CALL_STRUCT_PTR data_parser;
         USB_DATA_CLASS_INTF_STRUCT_PTR if_ptr;
                          
         if (NULL == (data_parser = usb_class_cdc_get_data_interface(intf_handle)))
             break;
         if_ptr = (USB_DATA_CLASS_INTF_STRUCT_PTR) data_parser->class_intf_handle;

         if (if_ptr->in_pipe != NULL)
             _usb_event_set(&if_ptr->data_event, USB_DATA_DETACH); /* mark we are not using input pipe */

         /* Allow tasks waiting for data to be finished...
         ** This does have sense only if this task will not be active
         ** or scheduler switches to another task.
         ** For simplification, we dont use any semaphore to indicate that
         ** all tasks have finished its job with device. Instead, we have just
         ** informed them that device is detached and we rely on USB stack layer
         ** that it checking if the device is available returns false.
         ** The code that would synchronize tasks to be finished would look like:
         **
         **  _lwsem_wait(if_ptr->device_using_tasks);
         */

         /* unbind data interface */
         if (USB_OK != usb_class_cdc_unbind_acm_interface(data_parser))
             break;
         //if (USB_OK != usb_class_cdc_uninstall_driver(data_parser))
         //    break;
         
         if (if_ptr->in_pipe != NULL) 
         {
             free(if_ptr->RX_BUFFER);
         }
         
         if (reg_device == dev_handle) 
         {
             reg_device = 0;
             _usb_event_clear(&device_registered, 0x01);
         }

#if 0 /* << EST */
         printf("----- CDC data interface detach Event -----\n");
         fflush(stdout);
         printf("State = detached");
         printf("  Class = %%d", intf_ptr->bInterfaceClass);
         printf("  SubClass = %%d", intf_ptr->bInterfaceSubClass);
         printf("  Protocol = %%d\n", intf_ptr->bInterfaceProtocol);
         fflush(stdout);
#endif         
         break;
      }

      default:
#if 0 /* << EST */
         printf("CDC device: unknown data event\n");
         fflush(stdout);
#endif
         break;
   } /* EndSwitch */
} /* Endbody */
Exemple #12
0
void usb_host_cdc_acm_event
   (
      /* [IN] pointer to device instance */
      _usb_device_instance_handle      dev_handle,

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

      /* [IN] code number for event causing callback */
      uint_32                          event_code
   )
{ /* Body */
   INTERFACE_DESCRIPTOR_PTR   intf_ptr = (INTERFACE_DESCRIPTOR_PTR)intf_handle;
   ACM_DEVICE_STRUCT_PTR      acm_device;

#if 0 /* << EST */
   fflush(stdout);
#endif
   switch (event_code) 
   {
      case USB_CONFIG_EVENT:
         /* Drop through into attach, same processing */
      case USB_ATTACH_EVENT: 
      {
         USB_CDC_DESC_ACM_PTR     	acm_desc = NULL; 
         USB_CDC_DESC_CM_PTR      	cm_desc = NULL;
         USB_CDC_DESC_HEADER_PTR 	header_desc = NULL;
         USB_CDC_DESC_UNION_PTR 	union_desc = NULL;
         int_32                     external_data = 0;

         /* finds all the descriptors in the configuration */
         if (USB_OK != usb_class_cdc_get_acm_descriptors(dev_handle,
             intf_handle,
             &acm_desc, 
             &cm_desc, 
             &header_desc, 
             &union_desc)) 
            break;
         /* we can allocate new acm device */
         if (NULL == (acm_device = USB_mem_alloc_zero(sizeof(ACM_DEVICE_STRUCT))))
            break;
         /* initialize new interface members and select this interface */
         if (USB_OK != _usb_hostdev_select_interface(dev_handle,
            intf_handle, (pointer)&acm_device->CLASS_INTF))
         {
            free(acm_device);
            break;
         }
         /* set all info got from descriptors to the class interface struct */
         usb_class_cdc_set_acm_descriptors((pointer)&acm_device->CLASS_INTF,
            acm_desc, cm_desc, header_desc, union_desc);

         /* link all already registered data interfaces to this ACM control, if needed */
         if (USB_OK != usb_class_cdc_bind_data_interfaces(dev_handle, (pointer)&acm_device->CLASS_INTF)) 
         {
            free(acm_device);
            break;
         }
#if 0 /* << EST */
         printf("----- CDC control interface attach Event -----\n");
         fflush(stdout);
         printf("State = attached");
         printf("  Class = %%d", intf_ptr->bInterfaceClass);
         printf("  SubClass = %%d", intf_ptr->bInterfaceSubClass);
         printf("  Protocol = %%d\n", intf_ptr->bInterfaceProtocol);
         fflush(stdout);
#endif
         check_open = 0;
         break;
      }
      case USB_INTF_EVENT: 
      {
         CLASS_CALL_STRUCT_PTR   acm_parser;
         USB_STATUS              status;
         
         if (NULL == (acm_parser = usb_class_cdc_get_ctrl_interface(intf_handle)))
             break;
         status = usb_class_cdc_init_ipipe(acm_parser);
         if ((status != USB_OK) && (status != USBERR_OPEN_PIPE_FAILED))
             break;
         
#if 0 /* << EST */
         printf("----- CDC control interface selected -----\n");
#endif
         
         break;
      }
         
      case USB_DETACH_EVENT:
      {
         CLASS_CALL_STRUCT_PTR acm_parser;
         USB_ACM_CLASS_INTF_STRUCT_PTR if_ptr;
         
         if (NULL == (acm_parser = usb_class_cdc_get_ctrl_interface(intf_handle)))
             break;
         if_ptr = (USB_ACM_CLASS_INTF_STRUCT_PTR) acm_parser->class_intf_handle;
         
         _usb_event_set(&if_ptr->acm_event, USB_ACM_DETACH); /* mark we are not using input pipe */

         /* Allow tasks waiting for acm to be finished...
         ** This does have sense only if this task will not be active
         ** or scheduler switches to another task.
         ** For simplification, we dont use any semaphore to indicate that
         ** all tasks have finished its job with device. Instead, we have just
         ** informed them that device is detached and we rely on USB stack layer
         ** that it checking if the device is available returns false.
         ** The code that would synchronize tasks to be finished would look like:
         **
         **  _lwsem_wait(if_ptr->device_using_tasks);
         */

         usb_class_cdc_unbind_data_interfaces(acm_parser);

         USB_unlock();
         
         free(acm_parser);
         /* Use only the interface with desired protocol */
#if 0 /* << EST */
         printf("----- CDC control interface detach event -----\n");
         fflush(stdout);
         printf("State = detached");
         printf("  Class = %%d", intf_ptr->bInterfaceClass);
         printf("  SubClass = %%d", intf_ptr->bInterfaceSubClass);
         printf("  Protocol = %%d\n", intf_ptr->bInterfaceProtocol);
         fflush(stdout);
#endif
         
         break;
      }

         break;
      default:
#if 0 /* << EST */
         printf("CDC device: unknown control event\n");
         fflush(stdout);
#endif
         break;
   } /* EndSwitch */
} /* Endbody */