📄 usbd.c
字号:
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 + -