⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbd.c

📁 MTK平台绝密核心代码之 USB驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	
	USB_HCD_EP0_Setup_Req(8, &gUsbHost.ep0_status.setup_cmd);
} 

/* Set Feature request */
void USBD_Set_Feature(kal_uint16 feature_value)
{ 
	gUsbHost.ep0_status.setup_cmd.bmRequestType = USB_CMD_STDDEVOUT;
	gUsbHost.ep0_status.setup_cmd.bRequest = USB_SET_FEATURE;
	gUsbHost.ep0_status.setup_cmd.wValue = feature_value;
	gUsbHost.ep0_status.setup_cmd.wIndex = 0;
	gUsbHost.ep0_status.setup_cmd.wLength = 0;
	
	gUsbHost.ep0_state = USBD_EP0_SETUP;
	gUsbHost.ep0_status.data_ptr= NULL;
	gUsbHost.ep0_status.ep0_data_dir = USBD_EP0_DATA_SEND;
	gUsbHost.ep0_status.sofar = 0;
	gUsbHost.ep0_status.todo = 0;
	
	USB_HCD_EP0_Setup_Req(8, &gUsbHost.ep0_status.setup_cmd);
} 

/* Clear Stall request */
void USBD_Clear_Stall(kal_uint8 ep_num, USB_EP_TYPE ep_type)
{ 
	gUsbHost.ep0_status.setup_cmd.bmRequestType = USB_CMD_STDEPOUT;
	gUsbHost.ep0_status.setup_cmd.bRequest = USB_CLEAR_FEATURE;
	gUsbHost.ep0_status.setup_cmd.wValue = USB_FTR_EPHALT;
	gUsbHost.ep0_status.setup_cmd.wIndex = ep_num;
	if(ep_type==USB_IN_EP_TYPE)
		gUsbHost.ep0_status.setup_cmd.wIndex |= 0x80;
	gUsbHost.ep0_status.setup_cmd.wLength = 0;
	
	gUsbHost.ep0_state = USBD_EP0_SETUP;
	gUsbHost.ep0_status.data_ptr= NULL;
	gUsbHost.ep0_status.ep0_data_dir = USBD_EP0_DATA_NULL;
	gUsbHost.ep0_status.sofar = 0;
	gUsbHost.ep0_status.todo = 0;
	
	USB_HCD_EP0_Setup_Req(8, &gUsbHost.ep0_status.setup_cmd);
} 

kal_bool USBD_Get_HNP_Support(void)
{
	return gUsbHost.support_hnp;
}

/* CH9 state machine. Each time EP0 setup, data, status complete, this callback functio will be called */
static void USBD_Ch9_Callback(USB_HCD_STATUS result, kal_uint32 param)
{
	kal_uint32 data_size;
	kal_uint32 data_offset;
	kal_uint32 ep_index;
	kal_uint32 if_index;
	kal_uint32 index;
	kal_uint32 index2;
	Usb_If_Dscr *p_interface_desc;
	static kal_uint8 set_cfg_number = 0;
	static kal_uint8 get_cfg9_number = 0;
	static kal_uint8 get_cfg_number = 0;
	static kal_uint8 parse_cfg_number = 0;
		
	 if(((result==USB_HCD_NO_RESPONSE)||(result==USB_HCD_TIMEOUT) || (result==USB_HCD_STALL))
	 	&&(gUsbHost.ch9_state!=USBD_CH9_START))
	 {
	 	/* error handling */
	 	gUsbHost.ch9_error_count++;
	 	if(gUsbHost.ch9_state == USBD_CH9_SET_HNP_ENABLE)
	 	{
			USBD_Set_Configuration(1);
			gUsbHost.support_hnp = KAL_FALSE;
			gUsbHost.ch9_state = USBD_CH9_SET_CONF;
			return;
	 	}
	 	else if(gUsbHost.ch9_error_count>=3)
	 	{
			kal_mem_set(&gUsbHost.desc_info, 0, sizeof(gUsbHost.desc_info));

			//find matched driver, it will match to default driver
			for(index = 0; index< gUsbHost.total_class_driver; index++)
			{
				if((gUsbHost.class_driver_ptr[index]->match(&gUsbHost.desc_info, &set_cfg_number))==KAL_TRUE)
					break;
			}
			gUsbHost.current_class_driver = index;	

			// call the startup function
			gUsbHost.class_driver_ptr[gUsbHost.current_class_driver]->startup(set_cfg_number);

			return;
	 	}
	 	else
	 	{
	 		/* error count dose not exceed limitation, so restart enumeration*/
	 		USB_HCD_Set_UnMask_Irq(KAL_FALSE);
	 		/* re-start enumeration after delay timeout */
	 		USB_HCD_Delay_Reset_Device(result, USBD_ERROR_DELAY);
	 		return;
	 	}
	 }

	if(gUsbHost.ch9_state==USBD_CH9_START)
	{
		USB_HCD_Set_EP_Max_Pkt(0, gUsbHost.ep0_status.max_packet_size);
		USBD_Set_Address(1);
		gUsbHost.ch9_state = USBD_CH9_SET_ADDR;
	}
	else if(gUsbHost.ch9_state==USBD_CH9_SET_ADDR)
	{
		USB_HCD_SetAddress(1);
		USBD_Get_Descriptor(USB_DEVICE<<8, 0, 8, 
									(kal_uint8*)&gUsbHost.desc_info.dev_desc);
		get_cfg9_number = 0;
		get_cfg_number = 0;
		parse_cfg_number = 0;
		gUsbHost.ch9_state = USBD_CH9_GET_DEV_DESC_8;
	}
	else if(gUsbHost.ch9_state==USBD_CH9_GET_DEV_DESC_8)
	{
		gUsbHost.ep0_status.max_packet_size = gUsbHost.desc_info.dev_desc.bMaxPacketSize0;
		USB_HCD_Set_EP_Max_Pkt(0, gUsbHost.ep0_status.max_packet_size);
		USBD_Get_Descriptor(USB_DEVICE<<8, 0, sizeof(gUsbHost.desc_info.dev_desc), 
									(kal_uint8*)&gUsbHost.desc_info.dev_desc);
		gUsbHost.ch9_state = USBD_CH9_GET_DEV_DESC;
	}
	else if(gUsbHost.ch9_state==USBD_CH9_GET_DEV_DESC)
	{
		if(get_cfg9_number==0)
		{
			gUsbHost.desc_info.cfg_number = gUsbHost.desc_info.dev_desc.bNumConfigurations;
			if(gUsbHost.desc_info.cfg_number > USBD_MAX_CFG_NUM)
				gUsbHost.desc_info.cfg_number = USBD_MAX_CFG_NUM;
		}
		
		gUsbHost.desc_info.p_conf_data[get_cfg9_number] = (kal_uint8 *)get_ctrl_buffer(sizeof(Usb_Cfg_Dscr));
		USBD_Get_Descriptor((USB_CONFIG<<8)+get_cfg9_number, 0, 9, gUsbHost.desc_info.p_conf_data[get_cfg9_number]);
		
		get_cfg9_number++;
		if(get_cfg9_number>gUsbHost.desc_info.cfg_number)
			EXT_ASSERT(0, get_cfg9_number, gUsbHost.desc_info.cfg_number, 0);
		if(get_cfg9_number==gUsbHost.desc_info.cfg_number)
			gUsbHost.ch9_state = USBD_CH9_GET_CONF_DESC_9;
	}
	else if(gUsbHost.ch9_state==USBD_CH9_GET_CONF_DESC_9)
	{
		data_size = ((Usb_Cfg_Dscr*)gUsbHost.desc_info.p_conf_data[get_cfg_number])->wTotalLength;
		free_ctrl_buffer(gUsbHost.desc_info.p_conf_data[get_cfg_number]);
		gUsbHost.desc_info.p_conf_data[get_cfg_number] = (kal_uint8 *)get_ctrl_buffer(data_size);
		USBD_Get_Descriptor((USB_CONFIG<<8)+get_cfg_number, 0, data_size, gUsbHost.desc_info.p_conf_data[get_cfg_number]);
		get_cfg_number++;
		if(get_cfg_number>gUsbHost.desc_info.cfg_number)
			EXT_ASSERT(0, get_cfg_number, gUsbHost.desc_info.cfg_number, 0);
		if(get_cfg_number==gUsbHost.desc_info.cfg_number)
			gUsbHost.ch9_state = USBD_CH9_GET_CONF_DESC;
	}
	else if(gUsbHost.ch9_state==USBD_CH9_GET_CONF_DESC)
	{
		ep_index = 1;
		if_index = 0;
		for(parse_cfg_number=0; parse_cfg_number<gUsbHost.desc_info.cfg_number; parse_cfg_number++)
		{	
			/* reset otg descriptor*/
			gUsbHost.desc_info.p_otg_desc[parse_cfg_number] = NULL;
			/* configuration descriptor */
			gUsbHost.desc_info.cfg_info[parse_cfg_number].p_cfg_desc = (Usb_Cfg_Dscr*)gUsbHost.desc_info.p_conf_data[parse_cfg_number];
			/* interface descriptor */
			data_size = gUsbHost.desc_info.cfg_info[parse_cfg_number].p_cfg_desc->wTotalLength;
			data_offset = gUsbHost.desc_info.cfg_info[parse_cfg_number].p_cfg_desc->bLength;
			gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number= 0;
			while((data_offset<data_size)&&(gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number<USBD_MAX_IF_PER_CFG)
				&& ((gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number==0)||
					(gUsbHost.desc_info.cfg_info[parse_cfg_number].p_interface_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number-1]==NULL)||
					(gUsbHost.desc_info.cfg_info[parse_cfg_number].p_interface_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number-1]->ep_number<USBD_MAX_EP_PER_IF)))
			{
				if(ep_index>=USBD_MAX_EP_NUM)
					EXT_ASSERT(0, ep_index, USBD_MAX_EP_NUM, parse_cfg_number);
				if(if_index>=USBD_MAX_INTERFACE_NUM)
					EXT_ASSERT(0, if_index, USBD_MAX_INTERFACE_NUM, parse_cfg_number);	
					
				p_interface_desc = (Usb_If_Dscr*)&gUsbHost.desc_info.p_conf_data[parse_cfg_number][data_offset];
				if(p_interface_desc->bDescriptorType==USB_INTERFACE)
				{
					gUsbHost.desc_info.interface_info[if_index].p_interface_desc = (Usb_If_Dscr*)p_interface_desc;
					gUsbHost.desc_info.cfg_info[parse_cfg_number].p_interface_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number] = &gUsbHost.desc_info.interface_info[if_index];
					data_offset+=gUsbHost.desc_info.interface_info[if_index].p_interface_desc->bLength;
					if_index++;
					gUsbHost.desc_info.cfg_info[parse_cfg_number].p_interface_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number]->ep_number = 0;
					gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number++;
				}
				else if(p_interface_desc->bDescriptorType==USB_ENDPOINT)
				{
					if(gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number==0)
						EXT_ASSERT(0, parse_cfg_number, data_size, data_offset);
					gUsbHost.desc_info.ep_info[ep_index].p_stdep = (Usb_Ep_Dscr*)p_interface_desc;
					gUsbHost.desc_info.cfg_info[parse_cfg_number].p_interface_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number-1]->p_ep_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].p_interface_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number-1]->ep_number] = &gUsbHost.desc_info.ep_info[ep_index];
					data_offset+=gUsbHost.desc_info.ep_info[ep_index].p_stdep->bLength;
					ep_index++;
					gUsbHost.desc_info.cfg_info[parse_cfg_number].p_interface_info[gUsbHost.desc_info.cfg_info[parse_cfg_number].interface_number-1]->ep_number++;
				}
				else if(p_interface_desc->bDescriptorType==USB_OTG_DESC)
				{
					// 0520 temp not check
					gUsbHost.desc_info.p_otg_desc[parse_cfg_number] = (Usb_Otg_Dscr*)p_interface_desc;
					data_offset+=p_interface_desc->bLength;
				}
				else
				{
					data_offset+=p_interface_desc->bLength;
				}
			}
		}	

		//find matched friver
		for(index = 0; index< gUsbHost.total_class_driver; index++)
		{
			if((gUsbHost.class_driver_ptr[index]->match(&gUsbHost.desc_info, &set_cfg_number))==KAL_TRUE)
				break;
		}
		gUsbHost.current_class_driver = index;	

		if((gUsbHost.desc_info.p_otg_desc[set_cfg_number]!=NULL) && (gUsbHost.desc_info.p_otg_desc[set_cfg_number]->bAttribute&USB_OTG_HNP_SUPPORT))
		{
			USBD_Set_Feature(USB_FTR_B_HNP_ENB);
			gUsbHost.support_hnp = KAL_FALSE;
			gUsbHost.ch9_state = USBD_CH9_SET_HNP_ENABLE;
		}
		else
		{
			USBD_Set_Configuration(set_cfg_number);
			gUsbHost.support_hnp = KAL_FALSE;
			gUsbHost.ch9_state = USBD_CH9_SET_CONF;
		}				
	}
	else if(gUsbHost.ch9_state == USBD_CH9_SET_HNP_ENABLE)
	{
		USBD_Set_Configuration(set_cfg_number);
		gUsbHost.support_hnp = KAL_TRUE;
		gUsbHost.ch9_state = USBD_CH9_SET_CONF;
	}
	else if(gUsbHost.ch9_state==USBD_CH9_SET_CONF)
	{
		// call the startup function
		gUsbHost.class_driver_ptr[gUsbHost.current_class_driver]->startup(set_cfg_number);
		/* enumeration is completed. reset errot count to zero*/
		gUsbHost.ch9_error_count = 0;
		gUsbHost.ch9_state = USBD_CH9_ENUM_OK;
	}
}

/* EP0 hander. The SETUP, DATA, STATUS state is handled in this handler */
static void USBD_EP0_Hdlr(USB_HCD_STATUS result, kal_uint32 param)
{
	if(result==USB_HCD_OK)
	{
		if(gUsbHost.ep0_state==USBD_EP0_SETUP)
		{
			if(gUsbHost.ep0_status.todo!=0)
			{
				/* Have data to send/recv*/
				if(gUsbHost.ep0_status.ep0_data_dir==USBD_EP0_DATA_RECV)
					USB_HCD_EP0_Data_Req(USB_HCD_PIPE_DIR_IN, gUsbHost.ep0_status.todo, gUsbHost.ep0_status.data_ptr);
				else
					USB_HCD_EP0_Data_Req(USB_HCD_PIPE_DIR_OUT, gUsbHost.ep0_status.todo, gUsbHost.ep0_status.data_ptr);	

				gUsbHost.ep0_state = USBD_EP0_DATA;
			}
			else
			{
				/* request for the status*/
				USB_HCD_EP0_Status_Req(USB_HCD_PIPE_DIR_IN);
				gUsbHost.ep0_state = USBD_EP0_STATUS;
			}
		}
		else if(gUsbHost.ep0_state==USBD_EP0_DATA)
		{
			gUsbHost.ep0_status.sofar = param;
			/* request for the status*/
			if(gUsbHost.ep0_status.ep0_data_dir==USBD_EP0_DATA_RECV)
				USB_HCD_EP0_Status_Req(USB_HCD_PIPE_DIR_OUT);
			else
				USB_HCD_EP0_Status_Req(USB_HCD_PIPE_DIR_IN);	

			gUsbHost.ep0_state = USBD_EP0_STATUS;
		}
		else if(gUsbHost.ep0_state==USBD_EP0_STATUS)
		{
			gUsbHost.ep0_state = USBD_EP0_NONE;
			gUsbHost.ep0_callback(result, gUsbHost.ep0_status.sofar);
		}
		else
		{
			ASSERT(0);
		}
	} /* result==USB_HCD_OK */
	else if((result==USB_HCD_NO_RESPONSE) || (result==USB_HCD_TIMEOUT) || (result==USB_HCD_STALL))
	{
		// no matter it is in which state, return to NONE
		gUsbHost.ep0_state = USBD_EP0_NONE;
		gUsbHost.ep0_callback(result, param);
	}
}

#endif /* __OTG_ENABLE__*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -