usb_status usb_class_hub_init ( /* [IN] the device handle related to the class driver */ usb_device_instance_handle dev_handle, /* [IN] the interface handle related to the class driver */ usb_interface_descriptor_handle intf_handle, /* [OUT] printer call struct pointer */ class_handle* class_handle_ptr ) { /* Body */ usb_hub_class_struct_t* hub_class = NULL; usb_device_interface_struct_t* pDeviceIntf = NULL; //interface_descriptor_t* intf = NULL; endpoint_descriptor_t* ep_desc = NULL; uint8_t ep_num; usb_status status = USB_OK; pipe_init_struct_t pipe_init; uint8_t level = 0xFF; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_hub_init"); #endif level = usb_host_dev_mng_get_level(dev_handle); if (level > 5) { USB_PRINTF("Too many level of hub attached\n"); *class_handle_ptr = NULL; return USBERR_ERROR; } hub_class = (usb_hub_class_struct_t*)OS_Mem_alloc_zero(sizeof(usb_hub_class_struct_t)); if (hub_class == NULL) { USB_PRINTF("usb_class_hub_init fail on memory allocation\n"); *class_handle_ptr = NULL; return USBERR_ERROR; } hub_class->dev_handle = dev_handle; hub_class->intf_handle = intf_handle; hub_class->host_handle = usb_host_dev_mng_get_host(hub_class->dev_handle); hub_class->level = usb_host_dev_mng_get_level(hub_class->dev_handle); pDeviceIntf = (usb_device_interface_struct_t*)intf_handle; //intf = pDeviceIntf->lpinterfaceDesc; for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++) { ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc; if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == IRRPT_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_RECV; pipe_init.pipetype = USB_INTERRUPT_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = hub_class->dev_handle; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; status = usb_host_open_pipe(hub_class->host_handle, &hub_class->interrupt_pipe, &pipe_init); if (status != USB_OK) { USB_PRINTF("usb_class_hid_init fail to open in pipe\n"); *class_handle_ptr = (class_handle)hub_class; return USBERR_ERROR; } } } hub_class->control_pipe = usb_host_dev_mng_get_control_pipe(hub_class->dev_handle); *class_handle_ptr = hub_class; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_hub_init, SUCCESSFUL"); #endif return USB_OK; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_dev_mng_attach * Returned Value : * Comments : * This function will be called when attach interrupt happens, to * add onto the device list and do common initialization. * *END*--------------------------------------------------------------------*/ usb_status usb_host_dev_mng_attach ( usb_host_handle handle, hub_device_struct_t* hub_instance, uint8_t speed, uint8_t hub_no, uint8_t port_no, uint8_t level, usb_device_instance_handle* handle_ptr ) { usb_status status; dev_instance_t* new_instance_ptr; dev_instance_t* dev_instance_ptr; dev_instance_t* dev_instance_prev_ptr; usb_host_state_struct_t* usb_host_ptr; //dev_instance_t* device_root = NULL; pipe_init_struct_t pipe_init; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device attach device"); #endif usb_host_ptr = (usb_host_state_struct_t*)handle; //printf("a %d %d %d\n", hub_no, port_no, level); /* Allocate new device instance */ new_instance_ptr = (dev_instance_t*) OS_Mem_alloc_uncached_zero(sizeof(dev_instance_t)); if (new_instance_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device failed to malloc device handle"); #endif printf("memory allocation failed in usb_host_dev_mng_attach\n"); return USB_log_error(__FILE__,__LINE__, USBERR_GET_MEMORY_FAILED); } /* EndIf */ new_instance_ptr->host = handle; new_instance_ptr->speed = speed; new_instance_ptr->hub_instance = hub_instance; new_instance_ptr->hub_no = hub_no; new_instance_ptr->port_no = port_no; new_instance_ptr->level = level; new_instance_ptr->cfg_value = 0; /* We don't know yet what the device's default configuration is */ new_instance_ptr->attached = (uint8_t)TRUE; new_instance_ptr->pre_detached = (uint8_t)FALSE; //printf("l1\n"); USB_Host_lock(); //printf("l2\n"); dev_instance_ptr = usb_host_ptr->device_list_ptr; while (dev_instance_ptr != NULL) { if ((dev_instance_ptr->hub_no == hub_no) && (dev_instance_ptr->port_no == port_no)) { USB_Host_unlock(); OS_Mem_free((void*)new_instance_ptr); printf("invalidate attach\n"); *handle_ptr = NULL; return USBERR_ERROR; } else { dev_instance_ptr = dev_instance_ptr->next; } } //printf("l3\n"); /* Find unused address from 1 - 127 for this host */ dev_instance_ptr = usb_host_ptr->device_list_ptr; if ((dev_instance_ptr == NULL) || (dev_instance_ptr->address != 1)) { /* Insert at the beginning of list */ new_instance_ptr->target_address = 1; new_instance_ptr->next = dev_instance_ptr; usb_host_ptr->device_list_ptr = new_instance_ptr; } else { dev_instance_prev_ptr = dev_instance_ptr; /* Searching for a 'hole' in devices instance adresses */ while (dev_instance_ptr->target_address <= (dev_instance_prev_ptr->target_address + 1)) { new_instance_ptr->target_address = dev_instance_ptr->target_address; dev_instance_prev_ptr = dev_instance_ptr; dev_instance_ptr = dev_instance_ptr->next; if (dev_instance_ptr == NULL) break; } /* EndWhile */ if (new_instance_ptr->target_address >= 127) { /* If all 127 addresses used up, delete instance & bail out */ USB_Host_unlock(); OS_Mem_free((void*)new_instance_ptr); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device out of addresses"); #endif printf("no valid address for the device\n"); *handle_ptr = NULL; return USB_log_error(__FILE__,__LINE__, USBERR_ADDRESS_ALLOC_FAILED); } /* EndIf */ new_instance_ptr->target_address++; new_instance_ptr->next = dev_instance_ptr; dev_instance_prev_ptr->next = new_instance_ptr; }; //printf("l4\n"); USB_Host_unlock(); /*-----------------------------------------------------------** ** Open control pipe, get first 8 bytes of device descriptor ** ** The host_ch9 routine internally sets the callback to ** ** usb_host_cntrl_transaction_done (in usb_host_ch9.c) ** ** where the action resumes on completion of the get. ** **-----------------------------------------------------------*/ pipe_init.endpoint_number = 0; pipe_init.direction = 0; pipe_init.pipetype = USB_CONTROL_PIPE; pipe_init.max_packet_size = 64; pipe_init.interval = 0; pipe_init.flags = 0; pipe_init.dev_instance = new_instance_ptr; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; if (USB_OK != usb_host_open_pipe(new_instance_ptr->host, &new_instance_ptr->control_pipe, &pipe_init)) { OS_Mem_free((void*)new_instance_ptr); *handle_ptr = NULL; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device open pipe failed"); #endif printf("can't open control pipe\n"); return USB_log_error(__FILE__,__LINE__, USBERR_PIPE_OPENED_FAILED); } /* Endif */ /* Set state to enter after transaction completion */ new_instance_ptr->state = DEVSTATE_DEVDESC8; status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)new_instance_ptr, USB_DESC_TYPE_DEV << 8, 0, 8, (uint8_t *)&new_instance_ptr->dev_descriptor); if (status != USB_OK) { new_instance_ptr->state = DEVSTATE_INITIAL; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device FAILED"); #endif printf("get descriptor error\n"); *handle_ptr = (usb_device_instance_handle)new_instance_ptr; return USB_log_error(__FILE__,__LINE__, USBERR_NO_DESCRIPTOR); } #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device SUCCESSFUL"); #endif *handle_ptr = (usb_device_instance_handle)new_instance_ptr; //printf("attach done\n"); return USB_OK; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_class_video_set_stream_inf * Returned Value : None * Comments : * This function is called by common class to initialize the class driver. It * is called in response to a select interface call by application * *END*--------------------------------------------------------------------*/ usb_status usb_class_video_set_stream_inf ( class_handle class_handle, uint8_t inf_alternate ) { /* Body */ usb_video_stream_struct_t* video_stream_ptr = NULL; endpoint_descriptor_t* ep_desc = NULL; uint8_t ep_num = 0; pipe_init_struct_t pipe_init; usb_status status; video_stream_ptr = (usb_video_stream_struct_t*)class_handle; if (video_stream_ptr == NULL) { return USBERR_ERROR; } if(video_stream_ptr->current_stream_interface_ptr->bAlternateSetting == inf_alternate) { return USBERR_ERROR; } if(video_stream_ptr->stream_interface_ptr->alternate_setting_num < inf_alternate) { return USBERR_ERROR; } if (video_stream_ptr->stream_iso_in_pipe != NULL) { usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_in_pipe, NULL); usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_in_pipe); } if (video_stream_ptr->stream_iso_out_pipe != NULL) { usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_out_pipe, NULL); usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_iso_out_pipe); } if (video_stream_ptr->stream_bulk_in_pipe != NULL) { usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_in_pipe, NULL); usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_in_pipe); } if (video_stream_ptr->stream_bulk_out_pipe != NULL) { usb_host_cancel(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_out_pipe, NULL); usb_host_close_pipe(video_stream_ptr->host_handle, video_stream_ptr->stream_bulk_out_pipe); } usb_class_video_fill_endpoint_descriptor(video_stream_ptr, inf_alternate); for (ep_num = 0; ep_num < video_stream_ptr->altrnate_if_ep_num; ep_num++) { ep_desc = video_stream_ptr->altrnate_if_ep_descriptor_list[ep_num].lpEndpointDesc; if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_RECV; pipe_init.pipetype = USB_ISOCHRONOUS_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = video_stream_ptr->dev_handle; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_in_pipe, &pipe_init); if (status != USB_OK) { #ifdef _DEBUG USB_PRINTF("usb_class_video_set_stream_inf fail to open in pipe\n"); #endif return USBERR_ERROR; } } else if ((ep_desc->bEndpointAddress & OUT_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_SEND; pipe_init.pipetype = USB_ISOCHRONOUS_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = video_stream_ptr->dev_handle; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_out_pipe, &pipe_init); if (status != USB_OK) { #ifdef _DEBUG USB_PRINTF("usb_class_video_set_stream_inf fail to open in pipe\n"); #endif return USBERR_ERROR; } } } //USB_PRINTF("usb_class_video_set_stream_inf\n"); return USB_OK; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_class_video_stream_init * Returned Value : None * Comments : * This function is called by common class to initialize the class driver. It * is called in response to a select interface call by application * *END*--------------------------------------------------------------------*/ usb_status usb_class_video_stream_init ( /* [IN] the device handle related to the class driver */ usb_device_instance_handle dev_handle, /* [IN] the interface handle related to the class driver */ usb_interface_descriptor_handle intf_handle, /* [OUT] printer call struct pointer */ class_handle* class_handle_ptr ) { /* Body */ usb_video_stream_struct_t* video_stream_ptr = NULL; usb_device_interface_struct_t* pDeviceIntf = NULL; //interface_descriptor_t* intf = NULL; endpoint_descriptor_t* ep_desc = NULL; uint8_t ep_num; usb_status status = USB_OK; pipe_init_struct_t pipe_init; video_stream_ptr = (usb_video_stream_struct_t*)OS_Mem_alloc_zero(sizeof(usb_video_stream_struct_t)); if (video_stream_ptr == NULL) { #ifdef _DEBUG USB_PRINTF("usb_class_video_stream_init fail on memory allocation\n"); #endif return USBERR_ERROR; } video_stream_ptr->dev_handle = dev_handle; video_stream_ptr->intf_handle = intf_handle; video_stream_ptr->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(video_stream_ptr->dev_handle); video_stream_ptr->altrnate_if_ep_num = 0; video_stream_ptr->altrnate_if_ep_descriptor_list = NULL; pDeviceIntf = (usb_device_interface_struct_t*)intf_handle; video_stream_ptr->stream_interface_ptr = pDeviceIntf; video_stream_ptr->current_stream_interface_ptr = pDeviceIntf->lpinterfaceDesc; video_stream_ptr->vs_input_header_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_INPUT_HEADER); video_stream_ptr->vs_mjpeg_format_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_FORMAT_MJPEG); video_stream_ptr->vs_mjpeg_frame_list.frame_descriptor_list_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_FRAME_MJPEG); video_stream_ptr->vs_mjpeg_frame_list.frame_num = usb_class_video_find_descriptor_count(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VS_FRAME_MJPEG); //intf = pDeviceIntf->lpinterfaceDesc; for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++) { ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc; if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_RECV; pipe_init.pipetype = USB_ISOCHRONOUS_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = video_stream_ptr->dev_handle; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_in_pipe, &pipe_init); if (status != USB_OK) { #ifdef _DEBUG USB_PRINTF("usb_class_video_init fail to open in pipe\n"); #endif *class_handle_ptr = (class_handle)video_stream_ptr; return USBERR_ERROR; } } else if ((ep_desc->bEndpointAddress & OUT_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == ISOCH_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_SEND; pipe_init.pipetype = USB_ISOCHRONOUS_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = video_stream_ptr->dev_handle; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; status = usb_host_open_pipe(video_stream_ptr->host_handle, &video_stream_ptr->stream_iso_out_pipe, &pipe_init); if (status != USB_OK) { #ifdef _DEBUG USB_PRINTF("usb_class_video_init fail to open in pipe\n"); #endif *class_handle_ptr = (class_handle)video_stream_ptr; return USBERR_ERROR; } } } video_stream_ptr->recv_callback = NULL; video_stream_ptr->recv_param = NULL; *class_handle_ptr = (class_handle)video_stream_ptr; //USB_PRINTF("Video class driver initialized\n"); return USB_OK; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_class_video_control_init * Returned Value : None * Comments : * This function is called by common class to initialize the class driver. It * is called in response to a select interface call by application * *END*--------------------------------------------------------------------*/ usb_status usb_class_video_control_init ( /* [IN] the device handle related to the class driver */ usb_device_instance_handle dev_handle, /* [IN] the interface handle related to the class driver */ usb_interface_descriptor_handle intf_handle, /* [OUT] printer call struct pointer */ class_handle* class_handle_ptr ) { /* Body */ usb_video_control_struct_t* video_control_ptr = NULL; usb_device_interface_struct_t* pDeviceIntf = NULL; //interface_descriptor_t* intf = NULL; endpoint_descriptor_t* ep_desc = NULL; uint8_t ep_num; usb_status status = USB_OK; pipe_init_struct_t pipe_init; video_control_ptr = (usb_video_control_struct_t*)OS_Mem_alloc_zero(sizeof(usb_video_control_struct_t)); if (video_control_ptr == NULL) { #ifdef _DEBUG USB_PRINTF("usb_class_video_control_init fail on memory allocation\n"); #endif return USBERR_ERROR; } video_control_ptr->dev_handle = dev_handle; video_control_ptr->intf_handle = intf_handle; video_control_ptr->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(video_control_ptr->dev_handle); pDeviceIntf = (usb_device_interface_struct_t*)intf_handle; video_control_ptr->control_interface_ptr = pDeviceIntf; video_control_ptr->vc_interface_header_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_HEADER); video_control_ptr->vc_input_terminal_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_INPUT_TERMINAL); video_control_ptr->vc_output_terminal_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_OUTPUT_TERMINAL); video_control_ptr->vc_processing_unit_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_PROCESSING_UNIT); video_control_ptr->vc_extension_unit_list_ptr.extension_descriptor_list_ptr = usb_class_video_find_descriptor_index(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_EXTENSION_UNIT); video_control_ptr->vc_extension_unit_list_ptr.extension_num = usb_class_video_find_descriptor_count(pDeviceIntf->interfaceEx, pDeviceIntf->interfaceExlength, CS_INTERFACE, VC_EXTENSION_UNIT); //intf = pDeviceIntf->lpinterfaceDesc; for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++) { ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc; if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == IRRPT_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_RECV; pipe_init.pipetype = USB_INTERRUPT_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = video_control_ptr->dev_handle; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; status = usb_host_open_pipe(video_control_ptr->host_handle, &video_control_ptr->control_interrupt_in_pipe, &pipe_init); if (status != USB_OK) { #ifdef _DEBUG USB_PRINTF("usb_class_video_init fail to open in pipe\n"); #endif *class_handle_ptr = (class_handle)video_control_ptr; return USBERR_ERROR; } } } video_control_ptr->in_setup = FALSE; video_control_ptr->ctrl_callback = NULL; video_control_ptr->ctrl_param = NULL; video_control_ptr->recv_callback = NULL; video_control_ptr->recv_param = NULL; *class_handle_ptr = (class_handle)video_control_ptr; //USB_PRINTF("Video class driver initialized\n"); return USB_OK; } /* Endbody */
usb_status usb_class_cdc_acm_init ( /* [IN] the device handle related to the class driver */ usb_device_instance_handle dev_handle, /* [IN] the interface handle related to the class driver */ usb_interface_descriptor_handle intf_handle, /* [OUT] printer call struct pointer */ class_handle* class_handle_ptr ) { /* Body */ usb_acm_class_intf_struct_t * acm_class_intf = NULL; usb_device_interface_struct_t* pDeviceIntf = NULL; interface_descriptor_t* intf = NULL; endpoint_descriptor_t* ep_desc = NULL; uint8_t ep_num; usb_status status = USB_OK; pipe_init_struct_t pipe_init; acm_class_intf = (usb_acm_class_intf_struct_t *)OS_Mem_alloc_zero(sizeof(usb_acm_class_intf_struct_t)); if (acm_class_intf == NULL) { printf("usb_class_cdc_acm_init fail on memory allocation\n"); return USBERR_ERROR; } acm_class_intf->dev_handle = dev_handle; acm_class_intf->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(acm_class_intf->dev_handle); pDeviceIntf = (usb_device_interface_struct_t*)intf_handle; intf = pDeviceIntf->lpinterfaceDesc; acm_class_intf->intf_handle = intf; acm_class_intf->intf_num = intf->bInterfaceNumber; acm_class_intf->mutex = OS_Mutex_create(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_cdc_acm_init"); #endif for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++) { ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc; if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == IRRPT_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_RECV; pipe_init.pipetype = USB_INTERRUPT_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = acm_class_intf->dev_handle; pipe_init.nak_count = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT; status = usb_host_open_pipe(acm_class_intf->host_handle, &acm_class_intf->interrupt_pipe, &pipe_init); if (status != USB_OK) { printf("usb_class_cdc_acm_init fail to open in pipe\n"); *class_handle_ptr = (class_handle)acm_class_intf; return USBERR_ERROR; } } } /* Make sure the device is still attached */ #ifdef _HOST_DEBUG_ if (status) { DEBUG_LOG_TRACE("usb_class_cdc_acm_init, SUCCESSFUL"); } else { DEBUG_LOG_TRACE("usb_class_cdc_acm_init, FAILED"); } #endif *class_handle_ptr = (class_handle)acm_class_intf; return status; } /* Endbody */
usb_status usb_class_cdc_data_init ( /* [IN] the device handle related to the class driver */ usb_device_instance_handle dev_handle, /* [IN] the interface handle related to the class driver */ usb_interface_descriptor_handle intf_handle, /* [OUT] printer call struct pointer */ class_handle* class_handle_ptr ) { /* Body */ usb_data_class_intf_struct_t * data_class_intf = NULL; usb_device_interface_struct_t* pDeviceIntf = NULL; interface_descriptor_t* intf = NULL; endpoint_descriptor_t* ep_desc = NULL; uint8_t ep_num; usb_status status = USB_OK; pipe_init_struct_t pipe_init; data_class_intf = (usb_data_class_intf_struct_t *)OS_Mem_alloc_zero(sizeof(usb_data_class_intf_struct_t)); if (data_class_intf == NULL) { printf("usb_class_cdc_data_init fail on memory allocation\n"); return USBERR_ERROR; } data_class_intf->dev_handle = dev_handle; data_class_intf->host_handle = (usb_host_handle)usb_host_dev_mng_get_host(data_class_intf->dev_handle); pDeviceIntf = (usb_device_interface_struct_t*)intf_handle; intf = pDeviceIntf->lpinterfaceDesc; data_class_intf->intf_handle = intf; data_class_intf->intf_num = intf->bInterfaceNumber; data_class_intf->mutex = OS_Mutex_create(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_cdc_data_init"); #endif for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++) { ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc; if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == BULK_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_RECV; pipe_init.pipetype = USB_BULK_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = data_class_intf->dev_handle; pipe_init.nak_count = 30; status = usb_host_open_pipe(data_class_intf->host_handle, (usb_pipe_handle *)&data_class_intf->in_pipe, &pipe_init); } else if(!(ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == BULK_ENDPOINT)) { pipe_init.endpoint_number = (ep_desc->bEndpointAddress & ENDPOINT_MASK); pipe_init.direction = USB_SEND; pipe_init.pipetype = USB_BULK_PIPE; pipe_init.max_packet_size = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK); pipe_init.interval = ep_desc->iInterval; pipe_init.flags = 0; pipe_init.dev_instance = data_class_intf->dev_handle; pipe_init.nak_count = 3000; status = usb_host_open_pipe(data_class_intf->host_handle, (usb_pipe_handle *)&data_class_intf->out_pipe, &pipe_init); } if (status != USB_OK) { printf("usb_class_cdc_data_init fail to open in pipe\n"); *class_handle_ptr = (class_handle)data_class_intf; return USBERR_ERROR; } } /* Make sure the device is still attached */ if ((data_class_intf->in_pipe == NULL) && (data_class_intf->out_pipe == NULL)) status = USBERR_OPEN_PIPE_FAILED; if (data_class_intf->out_pipe) { /* Don't use host - predefined constant for nak_count... ** NOTE!!! ** This hack is not very clean. We need to maximize number of retries to minimize the time of ** transaction (minimize task's time while waiting for 1 transaction to be done (with or without data)) ** The time depends on user expecatation of the read() latency, on the delay between 2 NAKs and on number ** of NAKs to be performed. ** The workaround is to limit amount of retries for the pipe maximally to 3. ** Number 3 is hard-coded here for now. */ // if (((pipe_struct_t*)(data_class_intf->in_pipe))->nak_count > 3) // ((pipe_struct_t*)data_class_intf->in_pipe)->nak_count = 3; /* don't use host - predefined constant */ } if (data_class_intf->in_pipe) { /* The same as for OUT pipe applies here */ // if (((pipe_struct_t*)data_class_intf->out_pipe)->nak_count > 3) // ((pipe_struct_t*)data_class_intf->out_pipe)->nak_count = 3; /* don't use host - predefined constant */ /* initialize buffer */ /* size of buffer equals to the size of endpoint data size */ data_class_intf->RX_BUFFER_SIZE = ((pipe_struct_t*)data_class_intf->in_pipe)->max_packet_size; if (NULL == (data_class_intf->rx_buffer = (uint8_t *)OS_Mem_alloc_zero(data_class_intf->RX_BUFFER_SIZE))) { status = USBERR_ALLOC; } else { /* initialize members */ data_class_intf->RX_BUFFER_APP = data_class_intf->RX_BUFFER_DRV = data_class_intf->rx_buffer; } } #ifdef _HOST_DEBUG_ if (status) { DEBUG_LOG_TRACE("usb_class_cdc_data_init, SUCCESSFUL"); } else { DEBUG_LOG_TRACE("usb_class_cdc_data_init, FAILED"); } #endif *class_handle_ptr = (class_handle)data_class_intf; return status; } /* Endbody */