USB_STATUS _usb_host_iso_packet_desc_pool_create ( uint_32 num_descs ) { uchar_ptr mem_ptr; uint_32 pool_num_bytes; uint_32 i; pool_num_bytes = sizeof (USB_ISO_PACKET_DESC_STRUCT) * num_descs; mem_ptr = (uchar_ptr)USB_mem_alloc_zero(pool_num_bytes); if (mem_ptr == NULL) { return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC); } _mem_set_type(mem_ptr, MEM_TYPE_USB_ISO_PACKET_DESC_STRUCT); usb_host_iso_packet_desc_pool.mem_ptr = mem_ptr; _mqx_dll_list_init ((MQX_DLL_LIST_PTR)&usb_host_iso_packet_desc_pool.free_list); for (i = 0; i < num_descs; i++) { _mqx_dll_node_init (&((USB_ISO_PACKET_DESC_STRUCT_PTR)mem_ptr)[i].node); _mqx_dll_insert_at_tail ((MQX_DLL_LIST_PTR)&usb_host_iso_packet_desc_pool.free_list, &((USB_ISO_PACKET_DESC_STRUCT_PTR)mem_ptr)[i].node); ((USB_ISO_PACKET_DESC_STRUCT_PTR)mem_ptr)[i].buf_offset = 0; ((USB_ISO_PACKET_DESC_STRUCT_PTR)mem_ptr)[i].buf_length = 0; ((USB_ISO_PACKET_DESC_STRUCT_PTR)mem_ptr)[i].packet_status = USB_OK; } return USB_OK; }
/***************************************************************************** * * @name TestApp_Init * * @brief This function is the entry for mouse (or other usuage) * * @param None * * @return None ** *****************************************************************************/ void TestApp_Init(void) { //uint_8 error; CDC_CONFIG_STRUCT cdc_config; USB_CLASS_CDC_ENDPOINT * endPoint_ptr; g_curr_recv_buf = _mem_alloc_uncached(DATA_BUFF_SIZE); g_curr_send_buf = _mem_alloc_uncached(DATA_BUFF_SIZE); endPoint_ptr = USB_mem_alloc_zero(sizeof(USB_CLASS_CDC_ENDPOINT)*CDC_DESC_ENDPOINT_COUNT); cdc_config.comm_feature_data_size = COMM_FEATURE_DATA_SIZE; cdc_config.usb_ep_data = &usb_desc_ep; cdc_config.desc_endpoint_cnt = CDC_DESC_ENDPOINT_COUNT; cdc_config.cdc_class_cb.callback = USB_App_Callback; cdc_config.cdc_class_cb.arg = &g_app_handle; cdc_config.vendor_req_callback.callback = NULL; cdc_config.vendor_req_callback.arg = NULL; cdc_config.param_callback.callback = USB_Notif_Callback; cdc_config.param_callback.arg = &g_app_handle; cdc_config.desc_callback_ptr = &desc_callback; cdc_config.ep = endPoint_ptr; cdc_config.cic_send_endpoint = CIC_NOTIF_ENDPOINT; /* Always happend in control endpoint hence hard coded in Class layer*/ //cdc_config.cic_recv_endpoint = cdc_config.dic_send_endpoint = DIC_BULK_IN_ENDPOINT; cdc_config.dic_recv_endpoint = DIC_BULK_OUT_ENDPOINT; if (MQX_OK != _usb_device_driver_install(USBCFG_DEFAULT_DEVICE_CONTROLLER)) { printf("Driver could not be installed\n"); return; } /* Initialize the USB interface */ g_app_handle = USB_Class_CDC_Init(&cdc_config); g_recv_size = 0; g_send_size= 0; while (TRUE) { /* call the periodic task function */ USB_CDC_Periodic_Task(); /*check whether enumeration is complete or not */ if((start_app==TRUE) && (start_transactions==TRUE)) { Virtual_Com_App(); } }/* Endwhile */ }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_host_printer_pcl5_command * Returned Value : USB_OK or error code * Comments : * *END*--------------------------------------------------------------------*/ static USB_STATUS _usb_host_printer_pcl5_write_command( CLASS_CALL_STRUCT_PTR cc_ptr, uchar_ptr command ) { char_ptr buffer = NULL; buffer = (char_ptr)USB_mem_alloc_zero(strlen((char *)command)); if(buffer == NULL) { return USB_PRINTER_LANGUAGE_ERROR_OUT_OF_MEMORY; } sprintf(buffer,(char *)command); return usb_printer_send_data(cc_ptr, usb_host_printer_pcl5_write_callback, NULL,strlen(buffer),(uchar_ptr)buffer); }
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_dev_driver_install * Returned Value : None * Comments : * Installs the device *END*-----------------------------------------------------------------*/ uint_8 _usb_dev_driver_install ( /* [IN] device number */ uint_32 device_number, /* [IN] address if the callback functions structure */ pointer callback_struct_ptr ) { /* Body */ pointer callback_struct_table_ptr; callback_struct_table_ptr = _mqx_get_io_component_handle(IO_USB_COMPONENT); if (!callback_struct_table_ptr) { callback_struct_table_ptr = USB_mem_alloc_zero((BSP_MAX_USB_DRIVERS * sizeof(USB_DEV_CALLBACK_FUNCTIONS_STRUCT))); if (!callback_struct_table_ptr) { #if _DEBUG printf("memalloc failed in _usb_driver_install\n"); #endif return USBERR_DRIVER_INSTALL_FAILED; } /* Endif */ USB_mem_zero((uint_8_ptr)callback_struct_table_ptr, sizeof(callback_struct_table_ptr)); _mqx_set_io_component_handle(IO_USB_COMPONENT, callback_struct_table_ptr); } /* Endif */ *((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\ (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)callback_struct_table_ptr) + device_number)) = *((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)callback_struct_ptr); return USB_OK; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_host_printer_pcl5_write * Returned Value : USB_OK or error code * Comments : * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_host_printer_pcl5_write( CLASS_CALL_STRUCT_PTR cc_ptr, tr_callback callback, USB_PRINTER_COMMAND command, uint_32 buff_size, void* buffer_ptr ) { /* Register the pcl5 write callback */ g_printer_plc5_write_callback = callback; switch(command) { case USB_PRINTER_COMMAND_SET_POSITION: { if(NULL != buffer_ptr) { char * buffer = NULL; USB_PRINER_POSITION_STRUCT_PTR position_cursor_ptr = NULL; /* Prepare set position buffer */ buffer = (char *)USB_mem_alloc_zero(USB_PRINTER_PCL5_POSITION_MAX_BUFF); if(NULL == buffer) { return USB_PRINTER_LANGUAGE_ERROR_OUT_OF_MEMORY; } position_cursor_ptr = (USB_PRINER_POSITION_STRUCT_PTR)buffer_ptr; /* Combine set position buffer */ sprintf(buffer, USB_PRINTER_PCL5_CURSOR_HORIZONTAL_POSITION_H USB_PRINTER_PCL5_CURSOR_VERTICAL_POSITION_V, position_cursor_ptr->position_x, position_cursor_ptr->position_y); /* Send set position command */ return usb_printer_send_data(cc_ptr, usb_host_printer_pcl5_write_callback, NULL,strlen(buffer),(uchar_ptr)buffer); } break; } /* Set orientation */ case USB_PRINTER_COMMAND_ORIENTATION: { if(NULL != buffer_ptr) { char* buffer = NULL; buffer = (char*)USB_mem_alloc_zero(USB_PRINTER_PCL5_ORIENTATION_MAX_BUFF); if (NULL == buffer) { return USB_PRINTER_LANGUAGE_ERROR_OUT_OF_MEMORY; } /* Page orientation: Landscape */ if((boolean)(*(unsigned char*)buffer_ptr)) { sprintf(buffer,USB_PRINTER_PCL5_PAGE_LOGICAL_ORIENTATION,1); } /* Page orientation: Portrait */ else { sprintf(buffer,USB_PRINTER_PCL5_PAGE_LOGICAL_ORIENTATION,0); } /* Send page orientation command */ return usb_printer_send_data(cc_ptr, usb_host_printer_pcl5_write_callback, NULL,strlen(buffer),(uchar_ptr)buffer); } break; } /* Set font */ case USB_PRINTER_COMMAND_FONT: { if(NULL != buffer_ptr) { uint_8 font_index = 0; USB_PRINTER_FONT_STRUCT_PTR font_setup_ptr = NULL; char* buffer = (char*)USB_mem_alloc_zero(USB_PRINTER_PCL5_FONT_MAX_BUFF); if(NULL == buffer) { return USB_PRINTER_LANGUAGE_ERROR_OUT_OF_MEMORY; } font_setup_ptr = (USB_PRINTER_FONT_STRUCT_PTR)buffer_ptr; /* Search font type */ for(font_index = 0 ; font_index < USB_PRINTER_PCL5_MAX_FONT ; font_index++) { if(font_setup_ptr->font_ID == PCL5_FONT_NAME[font_index].font_id) { strcpy(buffer,PCL5_FONT_NAME[font_index].font_name); break; } } /* Invalid font type */ if(USB_PRINTER_PCL5_MAX_FONT == font_index) { return USB_PRINTER_LANGUAGE_ERROR_INVALID_FONT_TYPE; } strcat(buffer,USB_PRINTER_PCL5_FONT_ASCII); /* Set font size */ if(font_setup_ptr->font_size > 0) { /* Courier font */ if(font_setup_ptr->font_ID == COURIER_FONT) { sprintf(&buffer[strlen(buffer)],USB_PRINTER_PCL5_FONT_SPACING_P,0); strcat(buffer,Ec "(s"); sprintf(&buffer[strlen(buffer)],"%d",120/font_setup_ptr->font_size); strcat(buffer,"H"); } /* Other fonts */ else { sprintf(&buffer[strlen(buffer)],USB_PRINTER_PCL5_FONT_SPACING_P,1); strcat(buffer,Ec "(s"); sprintf(&buffer[strlen(buffer)],"%d",font_setup_ptr->font_size); strcat(buffer,"V"); } } else { return USB_PRINTER_LANGUAGE_ERROR_INVALID_FONT_SIZE; } /* Font style: Italic */ if(font_setup_ptr->Font_style.u.Italic) { sprintf(&buffer[strlen(buffer)],USB_PRINTER_PCL5_FONT_STYLE_P,1); } /* Font style: Bold */ if(font_setup_ptr->Font_style.u.Bold) { sprintf(&buffer[strlen(buffer)],USB_PRINTER_PCL5_FONT_STROKE_WEIGHT_P,3); } /* Font style: Underline */ if(font_setup_ptr->Font_style.u.UnderLine) { underline_font = TRUE; } else { underline_font = FALSE; } /* Send set font command */ return usb_printer_send_data(cc_ptr, usb_host_printer_pcl5_write_callback, NULL,strlen(buffer),(uchar_ptr)buffer); } break; } /* Start text */ case USB_PRINTER_COMMAND_TEXT_START: { char* buffer = (char*)USB_mem_alloc_zero(10); if (NULL == buffer) { return USB_PRINTER_LANGUAGE_ERROR_OUT_OF_MEMORY; } /* Font style: Underline */ if(TRUE == underline_font) { sprintf(buffer,USB_PRINTER_PCL5_FONT_UNDERLINE USB_PRINTER_PCL5_TEXT_START,2); } else { sprintf(buffer,USB_PRINTER_PCL5_TEXT_START); } return usb_printer_send_data(cc_ptr, usb_host_printer_pcl5_write_callback, NULL,strlen(buffer),(uchar_ptr)buffer); } /* Print text*/ case USB_PRINTER_COMMAND_PRINT_TEXT: { if(NULL != buffer_ptr) { char* buffer = (char*)USB_mem_alloc_zero(buff_size); strcpy(buffer,buffer_ptr); return usb_printer_send_data(cc_ptr, usb_host_printer_pcl5_write_callback, NULL,strlen(buffer),(uchar_ptr)buffer); } break; } /* Stop text */ case USB_PRINTER_COMMAND_TEXT_STOP: /* Eject page */ case USB_PRINTER_COMMAND_EJECT_PAGE: { return _usb_host_printer_pcl5_write_command(cc_ptr, (uchar_ptr)USB_PRINTER_PCL5_JOB_RESET USB_PRINTER_PCL5_JOB_UEL); } default: break; } return USB_PRINTER_LANGUAGE_ERROR_INVALID_PARAM; }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : Main_Task * Returned Value : None * Comments : * First function called. This function is the entry for * the PHDC Application * *END*--------------------------------------------------------------------*/ void Main_Task(uint_32 param) { /* Initialize Global Variable Structure */ PHDC_CONFIG_STRUCT phdc_config; phdc_config.phdc_callback.callback = USB_App_Callback; phdc_config.phdc_callback.arg = (void*)&g_bridge.handle; phdc_config.vendor_callback.callback = NULL; phdc_config.vendor_callback.arg = NULL; phdc_config.desc_callback_ptr = &desc_callback; phdc_config.info = &usb_desc_ep; USB_mem_zero(&g_bridge, sizeof(BRIDGE_GLOBAL_VARIABLE_STRUCT)); if (_lwevent_create(&lwevent,0) != MQX_OK) { #if _DEBUG printf("\nMake event failed : Main_Task"); #endif _task_block(); } g_usb_rx_buff_ptr = USB_mem_alloc_zero(PHDC_BULK_OUT_EP_SIZE); if(g_usb_rx_buff_ptr == NULL) { #if _DEBUG printf("g_usb_rx_buff_ptr malloc failed\n"); #endif } g_bridge_rx_buff_ptr = USB_mem_alloc_zero(PHDC_BULK_IN_EP_SIZE); if(g_bridge_rx_buff_ptr == NULL) { #if _DEBUG printf("g_bridge_rx_buff_ptr malloc failed\n"); #endif } _int_disable(); g_bridge.handle = USB_Class_PHDC_Init(&phdc_config); Bridge_Interface_Init(Bridge_Callback); _int_enable(); while(TRUE) { /* Block the task untill USB Enumeration is completed */ if(_lwevent_wait_for(&lwevent,USB_ENUM_COMPLETED,FALSE,NULL) != MQX_OK) { #if _DEBUG printf("USB_ENUM_COMPLETEDEvent Wait failed\n"); #endif _task_block(); } if(_lwevent_clear(&lwevent,USB_ENUM_COMPLETED) != MQX_OK) { #if _DEBUG printf("Enum Event Clear failed\n"); #endif _task_block(); } Bridge_Interface_Open(param); } }
/****************************************************************************** * * @name USB_App_Callback * * @brief This function handles the callback * * @param handle * @param event_tyoe : type of the event * @param val : val * * @return None * ***************************************************************************** * This function is called from the lower layer whenever an event occurs. * This sets a variable according to the event_type *****************************************************************************/ void USB_App_Callback(uint_8 event_type,void* val,pointer arg) { uint_32 handle = *((uint_32 *)arg); PTR_USB_APP_EVENT_DATA_RECIEVED event_struct = (PTR_USB_APP_EVENT_DATA_RECIEVED)val; switch(event_type) { case USB_APP_BUS_RESET: g_bridge.usb_enum_complete = FALSE; if(g_connection_present == TRUE) { /* close the previous connection if present */ Bridge_Interface_Close(); } break; case USB_APP_ENUM_COMPLETE: g_bridge.usb_enum_complete = TRUE; if(_lwevent_set(&lwevent,USB_ENUM_COMPLETED) != MQX_OK) { #if _DEBUG printf("\n 1 Set Event failed : USB_App_Callback"); #endif _task_block(); } break; case USB_APP_GET_TRANSFER_SIZE: { volatile PTR_USB_CLASS_PHDC_RX_BUFF usb_rx_buff = (PTR_USB_CLASS_PHDC_RX_BUFF)val; #if USB_METADATA_SUPPORTED if(usb_rx_buff->meta_data_packet) { PTR_USB_META_DATA_MSG_PREAMBLE metadata_preamble_ptr = (PTR_USB_META_DATA_MSG_PREAMBLE)usb_rx_buff->in_buff; usb_rx_buff->transfer_size = (uint_32) (metadata_preamble_ptr->opaque_data_size + METADATA_HEADER_SIZE); } else #endif { APDU *papdu = (APDU*)usb_rx_buff->in_buff; usb_rx_buff->transfer_size = (uint_32) (papdu->length + APDU_HEADER_SIZE); } } break; case USB_APP_GET_DATA_BUFF: { /* called by lower layer to get recv buffer */ volatile PTR_USB_CLASS_PHDC_RX_BUFF usb_rx_buff = (PTR_USB_CLASS_PHDC_RX_BUFF)val; usb_rx_buff->out_size = *((uint_16_ptr)usb_rx_buff->in_buff + 1) + APDU_HEADER_SIZE; usb_rx_buff->out_buff = USB_mem_alloc_zero(usb_rx_buff->out_size); if(usb_rx_buff->out_buff == NULL) { #if _DEBUG printf("\n usb_rx_buff->out_buff malloc failed in USB_App_Callback"); #endif } } break; case USB_APP_DATA_RECEIVED: { volatile PTR_USB_APP_EVENT_DATA_RECIEVED usb_rx_buff = (PTR_USB_APP_EVENT_DATA_RECIEVED)val; g_tx_buff_ptr = usb_rx_buff->buffer_ptr; g_bridge_tx_size = usb_rx_buff->size; /* Trigger send on Bridge Interface */ if(_lwevent_set(&lwevent,BRIDGE_SEND_EVENT) != MQX_OK) { #if _DEBUG printf("\n 2 Set Event failed : USB_App_Callback"); #endif _task_block(); } if(!(usb_rx_buff->size%PHDC_BULK_OUT_EP_SIZE)) { /* need to call zero byte of USB recv because total transfer size is multiple of PHDC_BULK_OUT_EP_SIZE */ (void)USB_Class_PHDC_Recv_Data(g_bridge.handle, PHDC_BULK_OUT_QOS, g_usb_rx_buff_ptr, 0); } } break; case USB_APP_SEND_COMPLETE: { volatile PTR_USB_APP_EVENT_SEND_COMPLETE send_buff = (PTR_USB_APP_EVENT_SEND_COMPLETE)val; if((g_bridge_rx_size != 0)||(send_buff->size == 0)) { /* break if g_bridge_rx_size is non-zero meaning entire data has not yet been received from Bridge interface, meaning that this callback is for partial send on USB bus. Also break if send_buff->size is zero, because this callback this corresponding to zero byte send data on USB bus. Already a REcv has been queued on Bridge Interface. So there's no point in doing that again */ break; } /* Queue another recv on Bridge Interface */ if(_lwevent_set(&lwevent,BRIDGE_RECV_EVENT) != MQX_OK) { #if _DEBUG printf("\n 3 Set Event failed : USB_App_Callback"); #endif _task_block(); } } break; case USB_APP_META_DATA_PARAMS_CHANGED: break; case USB_APP_ERROR: break; } return; }
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_ehci_add_interrupt_xfer_to_periodic_list * Returned Value : None * Comments : * Queue the transfer in the EHCI hardware Periodic schedule list *END*-----------------------------------------------------------------*/ uint_32 _usb_ehci_add_interrupt_xfer_to_periodic_list ( /* [IN] the USB Host state structure */ _usb_host_handle handle, /* The pipe descriptor to queue */ PIPE_DESCRIPTOR_STRUCT_PTR pipe_descr_ptr, /* [IN] the transfer parameters struct */ PIPE_TR_STRUCT_PTR pipe_tr_ptr ) { /* Body */ USB_HOST_STATE_STRUCT_PTR usb_host_ptr; //VUSB20_REG_STRUCT_PTR dev_ptr; ACTIVE_QH_MGMT_STRUCT_PTR active_list_member_ptr, temp_list_ptr; EHCI_QH_STRUCT_PTR QH_ptr = NULL; EHCI_QH_STRUCT_PTR prev_QH_ptr = NULL; EHCI_QTD_STRUCT_PTR first_QTD_ptr, temp_QTD_ptr; PIPE_DESCRIPTOR_STRUCT_PTR pipe_for_queue = NULL; uint_32 cmd_val,sts_val; uint_32 H_bit = 1; uint_32 interrupt_sched_mask = 1; boolean init_periodic_list = FALSE; boolean found_existing_q_head = FALSE; /* QH initialization fields */ uint_32 control_ep_flag = 0; uint_32 split_completion_mask = 1; uint_32 data_toggle_control = 0, item_type = 0; uint_8 mult = 0, period = 0; uint_32_ptr temp_frame_list_ptr = NULL; usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; /**************************************************************************** QTD MAKING ****************************************************************************/ /* Initialize the QTDs for the Queue Head */ first_QTD_ptr = (EHCI_QTD_STRUCT_PTR)_usb_ehci_init_Q_element( handle,pipe_descr_ptr, pipe_tr_ptr ); #ifdef DEBUG_INFO printf("QTD queued Top QTD Token=%x\n" " Status=%x,PID code=%x,error code=%x,page=%x,IOC=%x,Bytes=%x,Toggle=%x\n", first_QTD_ptr->TOKEN, ((first_QTD_ptr->TOKEN)&0xFF), ((first_QTD_ptr->TOKEN) >> 8)&0x3, ((first_QTD_ptr->TOKEN) >> 10) &0x3, ((first_QTD_ptr->TOKEN) >> 12)&0x7, ((first_QTD_ptr->TOKEN) >> 15)&0x1, ((first_QTD_ptr->TOKEN) >> 16)&0x7FFF, ((first_QTD_ptr->TOKEN)&EHCI_QTD_DATA_TOGGLE) >>31); #endif /**************************************************************************** Obtain the QH for this pipe ****************************************************************************/ QH_ptr = (EHCI_QH_STRUCT_PTR) pipe_descr_ptr->QH_FOR_THIS_PIPE; /**************************************************************************** Ensure that this QH is in the list of active QHs for interrupt pipe ****************************************************************************/ /****************************************************************** If active list does not exist, we make a new list and this is the first member of the list. Otherwise we append the list at the end. *******************************************************************/ if(usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR == NULL) { active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR)USB_mem_alloc_zero(sizeof(ACTIVE_QH_MGMT_STRUCT)); if (!active_list_member_ptr) { return USBERR_ALLOC; } usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR = active_list_member_ptr; /**************************************************************** Connect the QH with the active list ****************************************************************/ active_list_member_ptr->QH_PTR = (EHCI_QH_STRUCT_PTR)QH_ptr; active_list_member_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR)first_QTD_ptr; /**************************************************************** Connect the QH with the QTD ****************************************************************/ QH_ptr->ALT_NEXT_QTD_LINK_PTR = EHCI_QTD_T_BIT; QH_ptr->NEXT_QTD_LINK_PTR = (uint_32)first_QTD_ptr; } else { /**************************************************************** search the list to find if this QH aleady exists in the list. If not, allocate a new list member and add to the list or else move on with no action. ****************************************************************/ temp_list_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \ usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR; do { if(temp_list_ptr->QH_PTR == QH_ptr) { found_existing_q_head = TRUE; break; } if (temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR == NULL) break; temp_list_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \ temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR; }while (1); /**************************************************************** If no QH not found a new list memeber or connect QTDs to the existing one ****************************************************************/ if(!found_existing_q_head) { active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR)USB_mem_alloc_zero(sizeof(ACTIVE_QH_MGMT_STRUCT)); if (!active_list_member_ptr) { return USBERR_ALLOC; } temp_list_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR = active_list_member_ptr; /**************************************************************** Connect the QH with the active list ****************************************************************/ active_list_member_ptr->QH_PTR = (EHCI_QH_STRUCT_PTR)QH_ptr; active_list_member_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR)first_QTD_ptr; /**************************************************************** Connect the QH with the QTD ****************************************************************/ QH_ptr->ALT_NEXT_QTD_LINK_PTR = EHCI_QTD_T_BIT; QH_ptr->NEXT_QTD_LINK_PTR = (uint_32)first_QTD_ptr; } else { /**************************************************************** update the active interrupt list now. ****************************************************************/ temp_QTD_ptr = (EHCI_QTD_STRUCT_PTR)temp_list_ptr->FIRST_QTD_PTR; if((((uint_32)temp_QTD_ptr) & EHCI_QTD_T_BIT) || (temp_QTD_ptr == NULL)) { temp_list_ptr->FIRST_QTD_PTR = (EHCI_QTD_STRUCT_PTR)first_QTD_ptr; } else { while (!(temp_QTD_ptr->NEXT_QTD_PTR & EHCI_QTD_T_BIT)) { temp_QTD_ptr = (EHCI_QTD_STRUCT_PTR)temp_QTD_ptr->NEXT_QTD_PTR; } temp_QTD_ptr->NEXT_QTD_PTR = (uint_32)first_QTD_ptr; } /*else*/ /**************************************************************** This case is arrived when the QH is active and there is a possibility that it may also have active QTDs. ****************************************************************/ if(QH_ptr->NEXT_QTD_LINK_PTR & EHCI_QTD_T_BIT) { QH_ptr->ALT_NEXT_QTD_LINK_PTR = EHCI_QTD_T_BIT; QH_ptr->NEXT_QTD_LINK_PTR = (uint_32)first_QTD_ptr; } }/*else*/ } /*else */ #ifdef DEBUG_INFO printf("_usb_ehci_add_interrupt_xfer_to_periodic_list: QH =%x\n" " Status=%x,PID code=%x,error code=%x,page=%x,IOC=%x,Bytes=%x,Toggle=%x\n", first_QTD_ptr->TOKEN, ((first_QTD_ptr->TOKEN)&0xFF), ((first_QTD_ptr->TOKEN) >> 8)&0x3, ((first_QTD_ptr->TOKEN) >> 10) &0x3, ((first_QTD_ptr->TOKEN) >> 12)&0x7, ((first_QTD_ptr->TOKEN) >> 15)&0x1, ((first_QTD_ptr->TOKEN) >> 16)&0x7FFF, ((first_QTD_ptr->TOKEN)&EHCI_QTD_DATA_TOGGLE) >>31); #endif /**************************************************************************** if periodic schedule is not already enabled, enable it. ****************************************************************************/ sts_val = USBHS_USBSTS; if(!(sts_val & USBHS_USBSTS_PS_MASK)) { cmd_val = USBHS_USBCMD; /**************************************************************************** write the address of the periodic list in to the periodic base register ****************************************************************************/ USBHS_PERIODICLISTBASE = (uint_32) usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR; /**************************************************************************** wait until we can enable the periodic schedule. ****************************************************************************/ while((cmd_val & USBHS_USBCMD_PSE_MASK) != (USBHS_USBSTS & USBHS_USBSTS_PS_MASK)); /**************************************************************************** enable the schedule now. ****************************************************************************/ USBHS_USBCMD = (cmd_val | USBHS_USBCMD_PSE_MASK); } return USB_OK; } /* EndBody */
/**************************************************************************//*! * * @name USB_Framework_Init * * @brief The funtion initializes the Class Module * * @param handle : handle to Identify the controller * @param class_callback: event callback * @param other_req_callback: callback for vendor or usb framework class req * * @return status * USB_OK : When Successfull * Others : Errors * *****************************************************************************/ USB_CLASS_FW_HANDLE USB_Framework_Init ( _usb_device_handle handle, /*[IN]*/ USB_CLASS_CALLBACK class_callback,/*[IN]*/ USB_REQ_FUNC other_req_callback,/*[IN]*/ pointer callback_data,/*[IN]*/ int_32 data,/*[IN]*/ DESC_CALLBACK_FUNCTIONS_STRUCT_PTR desc_callback_ptr /*[IN]*/ ) { USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr = NULL; USB_CLASS_FW_HANDLE fw_handle; uint_8 error=USB_OK; usb_fw_ptr = (USB_CLASS_FW_OBJECT_STRUCT_PTR)USB_mem_alloc_zero( sizeof(USB_CLASS_FW_OBJECT_STRUCT)); if (NULL == usb_fw_ptr) { #ifdef _DEV_DEBUG printf("USB_Framework_Init: Memalloc failed\n"); #endif return USBERR_ALLOC; } if (USBERR_DEVICE_BUSY == USB_Class_Fw_Allocate_Handle(&fw_handle)) { USB_mem_free((void *)usb_fw_ptr); usb_fw_ptr = NULL; return USBERR_ERROR; } /* save input parameters */ usb_fw_ptr->class_handle = data; usb_fw_ptr->ext_req_to_host = NULL; /* reserve memory for setup token and data received */ usb_fw_ptr->ext_req_to_host = (uint_8*)USB_mem_alloc_zero(MAX_EXPECTED_CONTROL_OUT_SIZE); if (NULL == usb_fw_ptr->ext_req_to_host) { #ifdef _DEV_DEBUG printf("ext_req_to_host malloc failed: USB_Framework_Init\n"); #endif return USBERR_ALLOC; } usb_fw_ptr->controller_handle = handle; usb_fw_ptr->other_req_callback.callback = other_req_callback; usb_fw_ptr->other_req_callback.arg = callback_data; usb_fw_ptr->class_callback.callback = class_callback; usb_fw_ptr->class_callback.arg = callback_data; USB_mem_copy( desc_callback_ptr,&usb_fw_ptr->desc, sizeof(DESC_CALLBACK_FUNCTIONS_STRUCT)); /* Register CONTROL service */ error = _usb_device_register_service(handle, USB_SERVICE_EP0, #ifdef DELAYED_PROCESSING USB_Control_Service_Callback, #else USB_Control_Service, #endif (pointer)usb_fw_ptr ); usb_class_fw_object[fw_handle] = usb_fw_ptr; return fw_handle; }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_device_register_service * Returned Value : USB_OK or error code * Comments : * Registers a callback routine for a specified event or endpoint. * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_device_register_service ( /* [IN] Handle to the USB device */ _usb_device_handle handle, /* [IN] type of event or endpoint number to service */ uint_8 type, /* [IN] Pointer to the service's callback function */ void(_CODE_PTR_ service)(PTR_USB_EVENT_STRUCT, pointer), /*[IN] User Argument to be passed to Services when invoked.*/ pointer arg ) { /* Body */ USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; SERVICE_STRUCT_PTR service_ptr; SERVICE_STRUCT_PTR _PTR_ search_ptr; if (handle == NULL) { return USBERR_ERROR; } usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; /* Needs mutual exclusion */ USB_lock(); /* Search for an existing entry for type */ for (search_ptr = &usb_dev_ptr->SERVICE_HEAD_PTR; *search_ptr; search_ptr = &(*search_ptr)->NEXT) { if ((*search_ptr)->TYPE == type) { /* Found an existing entry */ USB_unlock(); return USBERR_OPEN_SERVICE; } /* Endif */ } /* Endfor */ /* No existing entry found - create a new one */ service_ptr = (SERVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(SERVICE_STRUCT)); if (!service_ptr) { USB_unlock(); #ifdef _DEV_DEBUG printf("memalloc failed in _usb_device_register_service\n"); #endif return USBERR_ALLOC; } /* Endif */ service_ptr->TYPE = type; service_ptr->SERVICE = service; service_ptr->arg = arg; service_ptr->NEXT = NULL; *search_ptr = service_ptr; USB_unlock(); return USB_OK; } /* 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 */
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 */
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 */
void main_usb(void) #endif { USB_STATUS status = USB_OK; _usb_host_handle host_handle; /* Initialize the current platform. Call for the _bsp_platform_init which is specific to each processor family */ _bsp_platform_init(); #if 0 /* << EST */ #ifdef MCU_MK70F12 sci2_init(); #else sci1_init(); #endif TimerInit(); #endif /* Init polling global variable */ POLL_init(); DisableInterrupts; #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) usb_int_dis(); #endif /* ** 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 ( HOST_CONTROLLER_NUMBER, /* Use value in header file */ MAX_FRAME_SIZE, /* Frame size per USB spec */ &host_handle); /* Returned pointer */ if (status != USB_OK) { #if 0 /* << EST */ printf("\nUSB Host Initialization failed. STATUS: %%x",(unsigned int) status); fflush(stdout); #endif exit(3); } status = _usb_host_driver_info_register ( host_handle, (void *)DriverInfoTable ); if (status != USB_OK) { #if 0 /* << EST */ printf("\nDriver Registration failed. STATUS: %%x", (unsigned int)status); fflush(stdout); #endif exit(4); } EnableInterrupts; #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) usb_int_en(); #endif #if 0 /* << EST */ printf("\fInitialization passed. Plug-in CDC device to USB port.\nUse ttyb: as the in/out port for CDC device data.\n"); #endif _usb_event_init(&device_registered); uart2usb_num = usb2uart_num = 0; /* reset number of bytes in buffers */ #if 0 /* << EST */ f_usb = (FILE_CDC_PTR)malloc(sizeof(FILE_CDC)); memset(f_usb, 0, sizeof(FILE_CDC)); #else f_usb = (FILE_CDC_PTR)USB_mem_alloc_zero(sizeof(FILE_CDC)); #endif f_usb->DEV_PTR = (IO_DEVICE_STRUCT_PTR)USB_mem_alloc_word_aligned(sizeof(IO_DEVICE_STRUCT)); for(;;) { Poll(); CDC_Task(); #if 0 /* << EST */ __RESET_WATCHDOG(); /* feeds the dog */ #endif } /* loop forever */ /* please make sure that you never leave main */ #ifdef __GNUC__ return 0; #endif }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_hub_device_sm * Returned Value : None * Comments : * called when a hub changes state; sm = state machine *END*--------------------------------------------------------------------*/ static void usb_host_hub_device_sm ( /* [IN] structure with USB pipe information on the interface */ PIPE_STRUCT_PTR pipe, /* [IN] parameters */ pointer param, /* [IN] buffer of data from IN stage */ pointer buffer, /* [IN] length of data from IN stage */ uint_32 len, /* [IN] status of transaction */ USB_STATUS status ) { /* Body */ register HUB_DEVICE_STRUCT_PTR hub_instance = (HUB_DEVICE_STRUCT_PTR) param; _mqx_int i; switch (hub_instance->STATE) { case HUB_GET_DESCRIPTOR_TINY_PROCESS: /* here we get number of ports from USB data */ hub_instance->HUB_PORT_NR = ((HUB_DESCRIPTOR_STRUCT_PTR) buffer)->BNRPORTS; hub_instance->STATE = HUB_GET_DESCRIPTOR_PROCESS; usb_class_hub_get_descriptor((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 7 + hub_instance->HUB_PORT_NR / 8 + 1); break; case HUB_GET_DESCRIPTOR_PROCESS: { /* here, we get information from the hub and fill info in hub_instance */ HUB_DESCRIPTOR_STRUCT_PTR hub_desc = (HUB_DESCRIPTOR_STRUCT_PTR) buffer; hub_instance->HUB_PORTS = USB_mem_alloc_zero(hub_instance->HUB_PORT_NR * sizeof(HUB_PORT_STRUCT)); for (i = 0; i < hub_instance->HUB_PORT_NR; i++) { /* get REMOVABLE bit from the desriptor for appropriate installed port */ (hub_instance->HUB_PORTS + i)->APP_STATUS = hub_desc->DEVICEREMOVABLE[(i + 1) / 8] & (0x01 << ((i + 1) % 8)) ? HUB_PORT_REMOVABLE : 0; } } /* pass fluently to HUB_SET_PORT_FEATURE_PROCESS */ hub_instance->STATE = HUB_SET_PORT_FEATURE_PROCESS; hub_instance->port_iterator = 0; case HUB_SET_PORT_FEATURE_PROCESS: // if (hub_instance->port_iterator) /* register, that the port is now powered */ // hub_instance->HUB_PORTS[hub_instance->port_iterator - 1].POWERED = 1; if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) { usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, PORT_POWER); break; } /* EndIf */ /* else */ /* pass fluently to HUB_CLEAR_PORT_FEATURE_PROCESS */ hub_instance->STATE = HUB_CLEAR_PORT_FEATURE_PROCESS; hub_instance->port_iterator = 0; case HUB_CLEAR_PORT_FEATURE_PROCESS: if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) { usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, C_PORT_CONNECTION); break; } /* EndIf */ /* else */ /* pass fluently to HUB_GET_PORT_STATUS_PROCESS */ hub_instance->STATE = HUB_GET_PORT_STATUS_PROCESS; hub_instance->port_iterator = 0; case HUB_GET_PORT_STATUS_PROCESS: if (hub_instance->port_iterator) /* register the current status of the port, do the conversion LSB -> MSB */ (hub_instance->HUB_PORTS + hub_instance->port_iterator - 1)->STATUS = SHORT_LE_TO_HOST(*(uint_16*)buffer); if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) { usb_class_hub_get_port_status((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, 4); break; } /* EndIf */ /* else */ /* test if device is attached since startup */ for (i = 0; i < hub_instance->HUB_PORT_NR; i++) if ((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) { /* if some device is attached since startup, then start session */ hub_instance->port_iterator = i; hub_instance->STATE = HUB_NONE; (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED; usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET); break; } usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); break; case HUB_RESET_DEVICE_PORT_PROCESS: hub_instance->STATE = HUB_NONE; usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET); usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); break; case HUB_ADDRESS_DEVICE_PORT_PROCESS: /* compute speed */ if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_HIGH_SPEED)) i = USB_SPEED_HIGH; else if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_LOW_SPEED)) i = USB_SPEED_LOW; else i = USB_SPEED_FULL; /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */ usb_dev_list_attach_device( ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle, i, /* port speed */ pipe->DEVICE_ADDRESS, /* hub address */ hub_instance->port_iterator + 1 /* hub port */ ); /* test if there is still device which was not reset */ for (i = 0; i < hub_instance->HUB_PORT_NR; i++) if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED)) { /* if some device is attached since startup, then start session */ hub_instance->port_iterator = i; hub_instance->STATE = HUB_NONE; (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED; usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET); break; } usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); break; case HUB_DETACH_DEVICE_PORT_PROCESS: /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */ usb_dev_list_detach_device( ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle, pipe->DEVICE_ADDRESS, /* hub address */ hub_instance->port_iterator + 1 /* hub port */ ); /* reset the app status */ (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS = 0x00; /* test if there is still device which was not reset */ for (i = 0; i < hub_instance->HUB_PORT_NR; i++) if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED)) { /* if some device is attached since startup, then start session */ hub_instance->port_iterator = i; hub_instance->STATE = HUB_NONE; (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED; usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET); break; } usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); break; case HUB_GET_PORT_STATUS_ASYNC: { uint_32 stat = LONG_LE_TO_HOST(*(uint_32*)buffer); /* register the current status of the port */ (hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS = stat; /* let's see what happened */ if ((1 << C_PORT_CONNECTION) & stat) { /* get if a device on port was attached or detached */ if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS & HUB_PORT_ATTACHED) { hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS; usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION); } else { hub_instance->STATE = HUB_RESET_DEVICE_PORT_PROCESS; usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION); } break; } else if ((1 << C_PORT_RESET) & stat) { hub_instance->STATE = HUB_ADDRESS_DEVICE_PORT_PROCESS; (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS |= HUB_PORT_ATTACHED; usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_RESET); break; } else if ((1 << C_PORT_ENABLE) & stat) { /* unexpected event (error), just ignore the port */ hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS; usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_ENABLE); break; } else if ((1 << C_PORT_OVER_CURRENT) & stat) { /* unexpected event (error), just ignore the port */ hub_instance->STATE = HUB_NONE; usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_OVER_CURRENT); usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); break; } else if ((1 << C_PORT_POWER) & stat) { /* unexpected event (error), just ignore the port */ hub_instance->STATE = HUB_NONE; usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_POWER); usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); break; } /* FIXME: handle more events */ break; } case HUB_GET_STATUS_ASYNC: { HUB_STATUS_STRUCT_PTR hub_stat = (HUB_STATUS_STRUCT_PTR) buffer; uint_32 change = SHORT_LE_TO_HOST(hub_stat->WHUBCHANGE); if ((1 << C_HUB_LOCAL_POWER) & change) { hub_instance->STATE = HUB_NONE; usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_LOCAL_POWER); usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); } else if ((1 << C_HUB_OVER_CURRENT) & change) { hub_instance->STATE = HUB_NONE; usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_OVER_CURRENT); usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1); } break; } } /* EndSwitch */ return; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_hub_device_event * Returned Value : None * Comments : * called when a hub has been attached, detached, etc. *END*--------------------------------------------------------------------*/ void usb_host_hub_device_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 ) { HUB_DEVICE_STRUCT_PTR hub_instance; switch (event_code) { case USB_CONFIG_EVENT: /* Drop through into attach, same processing */ case USB_ATTACH_EVENT: /* Create 'unsafe' application struct */ if (NULL != (hub_instance = USB_mem_alloc_zero(sizeof(HUB_DEVICE_STRUCT)))) { _usb_hostdev_select_interface(dev_handle, intf_handle, (pointer)&hub_instance->CCS); } break; case USB_INTF_EVENT: if (USB_OK != usb_class_hub_get_app(dev_handle, intf_handle, (CLASS_CALL_STRUCT_PTR *) &hub_instance)) break; /* set we are in process of getting hub descriptor */ hub_instance->STATE = HUB_GET_DESCRIPTOR_TINY_PROCESS; /* here, we should retrieve information from the hub */ usb_class_hub_get_descriptor(&hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 7); break; case USB_DETACH_EVENT: { DEV_INSTANCE_PTR dev_ptr; _mqx_int i; if (USB_OK != usb_class_hub_get_app(dev_handle, intf_handle, (CLASS_CALL_STRUCT_PTR *) &hub_instance)) break; dev_ptr = (DEV_INSTANCE_PTR) dev_handle; /* detach all the devices connected to all the ports of found hub */ for (i = 0; i < hub_instance->HUB_PORT_NR; i++) { if ((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED) /* We will access dev_ptr without validation process (usb_hostdev_validate), because ** USB_DETACH_EVENT is synced call, so we can do that. dev_ptr is still valid pointer to device. */ usb_dev_list_detach_device(dev_ptr->host, dev_ptr->address, i + 1); } if (hub_instance->HUB_PORTS != NULL) USB_mem_free(hub_instance->HUB_PORTS); } break; default: break; } /* EndSwitch */ } /* Enbbody */
/**************************************************************************//*! * * @name USB_Class_CDC_Init * * @brief The funtion initializes the Device and Controller layer * * @param *cdc_config_ptr[IN]: This structure contians configuration parameter * send by APP to configure CDC class. * * @return status * USB_OK : When Successfull * Others : Errors ****************************************************************************** * *This function initializes the CDC Class layer and layers it is dependednt on * *****************************************************************************/ uint_32 USB_Class_CDC_Init ( CDC_CONFIG_STRUCT_PTR cdc_config_ptr ) { #if IMPLEMENT_QUEUING uint_8 index; #endif uint_8 error; CDC_HANDLE cdc_handle; CDC_DEVICE_STRUCT_PTR devicePtr = NULL; USB_ENDPOINTS *usb_ep_data; if (NULL == (void *)cdc_config_ptr) return USBERR_ERROR; devicePtr = (CDC_DEVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(CDC_DEVICE_STRUCT)); if (NULL == devicePtr) { #if _DEBUG printf("memalloc failed in USB_Class_CDC_Init\n"); #endif return USBERR_ALLOC; } cdc_handle = USB_Cdc_Allocate_Handle(); if (USBERR_DEVICE_BUSY == cdc_handle) { USB_mem_free(devicePtr); devicePtr = NULL; return USBERR_INIT_FAILED; } /* initialize the Global Variable Structure */ USB_mem_zero(devicePtr, sizeof(CDC_DEVICE_STRUCT)); devicePtr->ep = cdc_config_ptr->ep; usb_ep_data = cdc_config_ptr->usb_ep_data; devicePtr->max_supported_interfaces = cdc_config_ptr->max_supported_interfaces; #if RNDIS_SUPPORT USB_mem_copy(cdc_config_ptr->mac_address, devicePtr->mac_address, sizeof(_enet_address)); devicePtr->ip_address = cdc_config_ptr->ip_address; devicePtr->rndis_max_frame_size = cdc_config_ptr->rndis_max_frame_size; #endif /* Initialize the device layer*/ error = _usb_device_init(USBCFG_DEFAULT_DEVICE_CONTROLLER, &devicePtr->controller_handle, (uint_8)(usb_ep_data->count+1)); /* +1 is for Control Endpoint */ if(error != USB_OK) { goto error1; } cdc_config_ptr->desc_callback_ptr->handle = cdc_handle; /* Initialize the generic class functions */ devicePtr->class_handle = USB_Class_Init(devicePtr->controller_handle, USB_Class_CDC_Event,USB_CDC_Other_Requests,(void *)devicePtr, cdc_config_ptr->desc_callback_ptr); /* Initialize the generic class functions */ #if PSTN_SUBCLASS_NOTIF_SUPPORT /* Initialize the pstn subclass functions */ error = USB_Pstn_Init(devicePtr,&cdc_config_ptr->param_callback); if(error != USB_OK) { goto error2; } #endif devicePtr->usb_ep_data = usb_ep_data; #if IMPLEMENT_QUEUING for(index = 0; index < usb_ep_data->count; index++) { devicePtr->ep[index].endpoint = usb_ep_data->ep[index].ep_num; devicePtr->ep[index].type = usb_ep_data->ep[index].type; devicePtr->ep[index].bin_consumer = 0x00; devicePtr->ep[index].bin_producer = 0x00; } #endif /* save the callback pointer */ devicePtr->cdc_class_cb.callback = cdc_config_ptr->cdc_class_cb.callback; devicePtr->cdc_class_cb.arg = cdc_config_ptr->cdc_class_cb.arg; /* save the callback pointer */ devicePtr->vendor_req_callback.callback = cdc_config_ptr->vendor_req_callback.callback; devicePtr->vendor_req_callback.arg = cdc_config_ptr->vendor_req_callback.arg; /* save the callback pointer */ devicePtr->param_callback.callback = cdc_config_ptr->param_callback.callback; devicePtr->param_callback.arg = cdc_config_ptr->param_callback.arg; devicePtr->comm_feature_data_size = cdc_config_ptr->comm_feature_data_size; devicePtr->cic_send_endpoint = cdc_config_ptr->cic_send_endpoint; devicePtr->cic_recv_endpoint = USB_CONTROL_ENDPOINT; devicePtr->dic_send_endpoint = cdc_config_ptr->dic_send_endpoint; devicePtr->dic_recv_endpoint = cdc_config_ptr->dic_recv_endpoint; devicePtr->dic_recv_pkt_size = cdc_config_ptr->dic_recv_pkt_size; devicePtr->dic_send_pkt_size = cdc_config_ptr->dic_send_pkt_size; devicePtr->cic_send_pkt_size = cdc_config_ptr->cic_send_pkt_size; devicePtr->cdc_handle = cdc_handle; cdc_device_array[cdc_handle] = devicePtr; return cdc_handle; error2: /* Implement Denit class and invoke here*/ error1: USB_Cdc_Free_Handle(cdc_handle); USB_mem_free(devicePtr); devicePtr = NULL; return error; }
/**************************************************************************//*! * * @name USB_Class_PHDC_Event * * @brief Initializes non control endpoints * * @param handle * @param event : event notified by the layer below * @param value : additional parameter used by the event * * @return : None ****************************************************************************** * Initializes non control endpoints when Enumeration complete event is * received. *****************************************************************************/ static void USB_Class_PHDC_Event(uint8_t event, void* val,void *arg) { uint8_t ep_count; USB_EP_STRUCT ep_struct; PHDC_STRUCT_PTR phdc_obj_ptr = (PHDC_STRUCT_PTR)arg; if (phdc_obj_ptr == NULL) { #if _DEBUG printf("USB_Class_PHDC_Event:phdc_object_ptr is NULL\n"); #endif return; } /* if enum is complete initialize non-control endpoints */ if(event == USB_APP_ENUM_COMPLETE) { /* initialize all receive endpoints */ for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_rx; ep_count++) { uint8_t component = (uint8_t)(phdc_obj_ptr->ep_data.ep_rx[ep_count].endpoint | (USB_RECV << COMPONENT_PREPARE_SHIFT)); /* initialize ep_struct */ ep_struct.ep_num = phdc_obj_ptr->ep_data.ep_rx[ep_count].endpoint; ep_struct.size = phdc_obj_ptr->ep_data.ep_rx[ep_count].size; ep_struct.type = phdc_obj_ptr->ep_data.ep_rx[ep_count].type; ep_struct.direction = USB_RECV; /* initialize endpoint */ (void)_usb_device_init_endpoint(phdc_obj_ptr->controller_handle, &ep_struct,TRUE); phdc_obj_ptr->service_buff_ptr = (uint8_t *)USB_mem_alloc_zero(ep_struct.size); if (NULL == phdc_obj_ptr->service_buff_ptr) { #if _DEBUG printf("USB_Class_PHDC_Event: Memalloc failed\n"); #endif return ; } /* set endpt status as idle in the device layer */ (void)_usb_device_set_status(phdc_obj_ptr->controller_handle, (uint8_t)(USB_STATUS_ENDPOINT |component), (uint16_t)USB_STATUS_IDLE); phdc_obj_ptr->ep_data.ep_rx[ep_count].buff_ptr = NULL; phdc_obj_ptr->ep_data.ep_rx[ep_count].buffer_size = 0; } /* initialize all transmit endpoints */ for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_tx; ep_count++) { uint8_t component = (uint8_t)(phdc_obj_ptr->ep_data.ep_tx[ep_count].endpoint | (USB_SEND << COMPONENT_PREPARE_SHIFT)); /* initialize ep_struct */ ep_struct.ep_num = phdc_obj_ptr->ep_data.ep_tx[ep_count].endpoint; ep_struct.size = phdc_obj_ptr->ep_data.ep_tx[ep_count].size; ep_struct.type = phdc_obj_ptr->ep_data.ep_tx[ep_count].type; ep_struct.direction = USB_SEND; /* initialize endpoint */ (void)_usb_device_init_endpoint(phdc_obj_ptr->controller_handle, &ep_struct, TRUE); /* set endpt status as idle in the device layer */ (void)_usb_device_set_status(phdc_obj_ptr->controller_handle, (uint8_t)(USB_STATUS_ENDPOINT |component), (uint16_t)USB_STATUS_IDLE); } } else if(event == USB_APP_BUS_RESET) { /* initialize producer and consumer to zero for transmit endpoints */ for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_tx; ep_count++) { phdc_obj_ptr->ep_data.ep_tx[ep_count].bin_consumer = (uint8_t)0x00; phdc_obj_ptr->ep_data.ep_tx[ep_count].bin_producer = (uint8_t)0x00; } } if(phdc_obj_ptr->phdc_callback.callback != NULL) { phdc_obj_ptr->phdc_callback.callback(event, val,phdc_obj_ptr->phdc_callback.arg); } }
void Main_Task ( uint_32 param ) { /* Body */ USB_STATUS status = USB_OK; _int_disable(); _int_install_unexpected_isr(); status = _usb_host_driver_install(HOST_CONTROLLER_NUMBER, (pointer)&_bsp_usb_host_callback_table); if (status) { _int_enable(); printf("ERROR: %ls", status); exit(1); } /* Endif */ status = _usb_host_init (HOST_CONTROLLER_NUMBER, /* Use value in header file */ MAX_FRAME_SIZE, /* Frame size per USB spec */ &host_handle); /* Returned pointer */ if (status != USB_OK) { _int_enable(); printf("\nUSB Host Initialization failed. STATUS: %x", status); fflush(stdout); goto Error_Cleanup; } /* Endif */ /* ** 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) { _int_enable(); printf("\nDriver Registration failed. STATUS: %x", status); fflush(stdout); goto Error_Cleanup; } _int_enable(); pCmd = (COMMAND_OBJECT_PTR) USB_mem_alloc_zero(sizeof(COMMAND_OBJECT_STRUCT)); if (pCmd == NULL) { printf ("\nUnable to allocate Command Object"); fflush (stdout); goto Error_Cleanup; } pCmd->CBW_PTR = (CBW_STRUCT_PTR) USB_mem_alloc_zero(sizeof(CBW_STRUCT)); if (pCmd->CBW_PTR == NULL) { printf ("\nUnable to allocate Command Block Wrapper"); fflush (stdout); goto Error_Cleanup; } pCmd->CSW_PTR = (CSW_STRUCT_PTR) USB_mem_alloc_zero(sizeof(CSW_STRUCT)); if (pCmd->CSW_PTR == NULL) { printf ("\nUnable to allocate Command Status Wrapper"); fflush (stdout); goto Error_Cleanup; } buff_in = (uchar_ptr)USB_mem_alloc_uncached(0x400C); if (buff_in == NULL) { printf ("\nUnable to allocate Input Buffer"); fflush (stdout); goto Error_Cleanup; } _mem_zero(buff_in, 0x400C); buff_out = (uchar_ptr) USB_mem_alloc_uncached(0x0F); if (buff_out == NULL) { printf ("\nUnable to allocate Output Buffer"); fflush (stdout); goto Error_Cleanup; } _mem_zero(buff_out, 0x0F); printf("\nPlease insert Mass Storage Device.\n"); /*----------------------------------------------------** ** Infinite loop, waiting for events requiring action ** **----------------------------------------------------*/ for ( ; ; ) { switch ( mass_device.dev_state ) { case USB_DEVICE_IDLE: break ; case USB_DEVICE_ATTACHED: printf( "Mass Storage Device Attached\n" ); fflush(stdout); mass_device.dev_state = USB_DEVICE_SET_INTERFACE_STARTED; status = _usb_hostdev_select_interface(mass_device.dev_handle, mass_device.intf_handle, (pointer)&mass_device.class_intf); break ; case USB_DEVICE_SET_INTERFACE_STARTED: break; case USB_DEVICE_INTERFACED: usb_host_mass_test_storage(); mass_device.dev_state = USB_DEVICE_OTHER; break ; case USB_DEVICE_DETACHED: printf ( "\nMass Storage Device Detached\n" ); fflush(stdout); mass_device.dev_state = USB_DEVICE_IDLE; break; case USB_DEVICE_OTHER: break ; default: printf ( "Unknown Mass Storage Device State = %d\n",\ mass_device.dev_state ); fflush(stdout); break ; } /* Endswitch */ } /* Endfor */ Error_Cleanup: { if (pCmd != NULL) { if (pCmd->CSW_PTR != NULL) { USB_mem_free(pCmd->CSW_PTR); } if (pCmd->CBW_PTR != NULL) { USB_mem_free(pCmd->CBW_PTR); } USB_mem_free(pCmd); } if (buff_in != NULL) { USB_mem_free(buff_in); } if (buff_out != NULL) { USB_mem_free(buff_out); } if (host_handle != NULL) { _usb_host_shutdown (host_handle); } } } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_host_register_service * Returned Value : USB_OK or error code * Comments : * Registers a callback routine for a specified event. * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_host_register_service ( /* [IN] Handle to the USB device */ _usb_host_handle handle, /* [IN] type of event or endpoint number to service */ uint_8 type, /* [IN] Pointer to the service's callback function */ void(_CODE_PTR_ service)(pointer, uint_32) ) { /* Body */ USB_HOST_STATE_STRUCT_PTR usb_host_ptr; USB_SERVICE_STRUCT_PTR service_ptr; USB_SERVICE_STRUCT_PTR _PTR_ search_ptr; usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_register_service"); #endif /* Needs mutual exclusion */ USB_lock(); /* Search for an existing entry for type */ for (search_ptr = &usb_host_ptr->SERVICE_HEAD_PTR; *search_ptr; search_ptr = &(*search_ptr)->NEXT) { if ((*search_ptr)->TYPE == type) { /* Found an existing entry */ USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_register_service USBERR_OPEN_SERVICE"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_OPEN_SERVICE); } /* Endif */ } /* Endfor */ /* No existing entry found - create a new one */ service_ptr = (USB_SERVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(USB_SERVICE_STRUCT)); if (!service_ptr) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_register_service memalloc failed"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC_SERVICE); } /* Endif */ _mem_set_type(service_ptr, MEM_TYPE_USB_HOST_SERVICE_STRUCT); service_ptr->TYPE = type; service_ptr->SERVICE = service; service_ptr->NEXT = NULL; *search_ptr = service_ptr; USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_register_service SUCCESSFUL"); #endif return USB_OK; } /* EndBody */
void TestApp_Init(void) { AUDIO_CONFIG_STRUCT audio_config; USB_CLASS_AUDIO_ENDPOINT * endPoint_ptr; /* Pointer to audio endpoint entry */ endPoint_ptr = USB_mem_alloc_zero(sizeof(USB_CLASS_AUDIO_ENDPOINT)*AUDIO_DESC_ENDPOINT_COUNT); /* USB descriptor endpoint */ audio_config.usb_ep_data = &usb_desc_ep; /* USB audio unit */ audio_config.usb_ut_data = &usb_audio_unit; /* Endpoint count */ audio_config.desc_endpoint_cnt = AUDIO_DESC_ENDPOINT_COUNT; /* Application callback */ audio_config.audio_class_callback.callback = USB_App_Callback; /* Application callback argurment */ audio_config.audio_class_callback.arg = &g_app_handle; /* Vendor callback */ audio_config.vendor_req_callback.callback = NULL; /* Vendor callback argurment */ audio_config.vendor_req_callback.arg = NULL; /* Param callback function */ audio_config.param_callback.callback = USB_Notif_Callback; /* Param callback argurment */ audio_config.param_callback.arg = &g_app_handle; /* Memory param callback */ audio_config.mem_param_callback.callback = NULL; /* Memory param callback argurment */ audio_config.mem_param_callback.arg = &g_app_handle; /* Descriptor callback pointer */ audio_config.desc_callback_ptr = &desc_callback; /* Audio enpoint pointer */ audio_config.ep = endPoint_ptr; /* Initialize timer module */ // audio_timer_init(); // _audio_timer_init_freq(AUDIO_TIMER, AUDIO_TIMER_CHANNEL, AUDIO_SPEAKER_FREQUENCY, AUDIO_TIMER_CLOCK, TRUE); if (MQX_OK != _usb_device_driver_install(USBCFG_DEFAULT_DEVICE_CONTROLLER)) { printf("Driver could not be installed\n"); return; } /* Initialize the USB interface */ g_app_handle = USB_Class_Audio_Init(&audio_config); if (MQX_OK != _lwevent_create(&app_event, LWEVENT_AUTO_CLEAR)) { printf("\n_lwevent_create app_event failed.\n"); _task_block(); } if (MQX_OK != _lwevent_wait_ticks(&app_event, USB_APP_ENUM_COMPLETE_EVENT_MASK, FALSE, 0)) { printf("\n_lwevent_wait_ticks app_event failed.\n"); _task_block(); } if (MQX_OK != _lwevent_clear(&app_event, USB_APP_ENUM_COMPLETE_EVENT_MASK)) { printf("\n_lwevent_clear app_event failed.\n"); _task_block(); } printf("Audio speaker is working ... \r\n"); /* Prepare buffer for first isochronous input */ USB_Class_Audio_Recv_Data(g_app_handle,AUDIO_ISOCHRONOUS_ENDPOINT, audio_data_buff0, DATA_BUFF_SIZE); _task_block(); }