static struct vsfsm_state_t *vsfusbh_hub_evt_handler_init(struct vsfsm_t *sm, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)sm->user_data; switch (evt) { case VSFSM_EVT_INIT: hub->drv_init_pt.thread = hub_init_thread; hub->drv_init_pt.user_data = hub; hub->drv_init_pt.sm = sm; hub->drv_init_pt.state = 0; hub->drv_scan_pt.thread = hub_scan_thread; hub->drv_scan_pt.user_data = hub; hub->drv_scan_pt.sm = sm; hub->drv_scan_pt.state = 0; hub->drv_connect_pt.thread = hub_connect_thread; hub->drv_connect_pt.user_data = hub; hub->drv_connect_pt.sm = &hub->sm; hub->drv_connect_pt.state = 0; hub->drv_reset_pt.thread = hub_reset_thread; hub->drv_reset_pt.user_data = hub; hub->drv_reset_pt.sm = &hub->sm; hub->drv_reset_pt.state = 0; hub->inited = 0; case VSFSM_EVT_URB_COMPLETE: case VSFSM_EVT_DELAY_DONE: if (hub->inited == 0) { err = hub->drv_init_pt.thread(&hub->drv_init_pt, evt); if (err == 0) { hub->inited = 1; vsfsm_post_evt_pending(sm, VSFSM_EVT_DELAY_DONE); } if (err < 0) { vsfusbh_remove_interface(hub->usbh, hub->dev, hub->interface); } } else { err = hub->drv_scan_pt.thread(&hub->drv_scan_pt, evt); if (err < 0) { hub->drv_scan_pt.state = 0; vsfsm_post_evt_pending(sm, VSFSM_EVT_DELAY_DONE); } } break; default: break; } return NULL; }
vsf_err_t vsfusbh_uvc_set(void *dev_data, struct vsfusbh_uvc_param_t *param) { struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)dev_data; hdata->set_param = *param; vsfsm_post_evt_pending(&hdata->ctrl_sm, UAV_RESET_STREAM_PARAM); return VSFERR_NONE; }
static struct vsfsm_state_t *vsfusbh_init_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_t *usbh = (struct vsfusbh_t *)sm->user_data; switch (evt) { case VSFSM_EVT_ENTER: break; case VSFSM_EVT_INIT: usbh->dev_probe_pt.thread = NULL; sllist_init_node(usbh->drv_list); usbh->hcd_init_pt.thread = usbh->hcd->init_thread; usbh->hcd_init_pt.user_data = usbh; usbh->hcd_init_pt.state = 0; usbh->hcd_init_pt.sm = sm; default: err = usbh->hcd_init_pt.thread(&usbh->hcd_init_pt, evt); if (VSFERR_NONE == err) { // alloc probe urb usbh->probe_urb = usbh->hcd->alloc_urb(); if (usbh->probe_urb == NULL) { // error usbh->hcd_init_pt.thread = NULL; } sm->init_state.evt_handler = vsfusbh_probe_evt_handler; usbh->rh_dev = vsfusbh_alloc_device(usbh); if (NULL == usbh->rh_dev) { // error usbh->hcd_init_pt.thread = NULL; } else { usbh->rh_dev->speed = usbh->hcd_rh_speed; if (usbh->rh_dev->speed == USB_SPEED_LOW) usbh->rh_dev->slow = 1; usbh->new_dev = usbh->rh_dev; vsfsm_post_evt_pending(&usbh->sm, VSFSM_EVT_NEW_DEVICE); } } else if (err < 0) { // error usbh->hcd_init_pt.thread = NULL; } break; } return NULL; }
static vsf_err_t hub_connect_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = hub->vsfurb; struct vsfusbh_device_t *dev; vsfsm_pt_begin(pt); /* clear the cnnection change state */ vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_C_CONNECTION); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; if (hub->dev->children[hub->counter - 1] != NULL) { vsfusbh_disconnect_device(hub->usbh, &hub->dev->children[hub->counter - 1]); } if (!(hub->hub_portsts.wPortStatus & USB_PORT_STAT_CONNECTION)) { if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_ENABLE) { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_ENABLE); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; } return VSFERR_NONE; } if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_LOW_SPEED) { vsfsm_pt_delay(pt, 200); } vsfsm_pt_wfpt(pt, &hub->drv_reset_pt); vsfsm_pt_delay(pt, 200); // wait for new_dev free while (hub->usbh->new_dev != NULL) { vsfsm_pt_delay(pt, 200); } dev = vsfusbh_alloc_device(hub->usbh); if (NULL == dev) return VSFERR_FAIL; if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_LOW_SPEED) { dev->speed = USB_SPEED_LOW; dev->slow = 1; } else if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_HIGH_SPEED) dev->speed = USB_SPEED_HIGH; else dev->speed = USB_SPEED_FULL; hub->dev->children[hub->counter - 1] = dev; dev->parent = hub->dev; hub->usbh->new_dev = dev; vsfsm_post_evt_pending(&hub->usbh->sm, VSFSM_EVT_NEW_DEVICE); vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t vsfusbh_rh_submit_urb(struct vsfusbh_t *usbh, struct vsfusbh_urb_t *vsfurb) { uint16_t typeReq, wValue, wLength; struct usb_ctrlrequest_t *cmd = &vsfurb->setup_packet; uint32_t pipe = vsfurb->pipe; uint8_t data[32]; uint8_t len = 0; if (usb_pipeint(pipe)) { // WARNING: not support int transfer for HUB return VSFERR_NOT_SUPPORT; } vsfurb->actual_length = 0; typeReq = (cmd->bRequestType << 8) | cmd->bRequest; wValue = cmd->wValue; wLength = cmd->wLength; if (wLength > vsfurb->transfer_length) goto error; switch (typeReq) { case DeviceRequest | USB_REQ_GET_STATUS: data[0] = 1; data[1] = 0; len = 2; break; case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: case DeviceOutRequest | USB_REQ_SET_FEATURE: break; case DeviceRequest | USB_REQ_GET_CONFIGURATION: data[0] = 1; len = 1; break; case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: break; case DeviceRequest | USB_REQ_GET_DESCRIPTOR: switch (wValue & 0xff00) { case USB_DT_DEVICE << 8: switch (vsfurb->vsfdev->speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: memcpy (data, usb11_rh_dev_descriptor, 18); break; case USB_SPEED_HIGH: memcpy (data, usb2_rh_dev_descriptor, 18); break; //case USB_SPEED_VARIABLE: // break; //case USB_SPEED_SUPER: // break; default: goto error; } len = 18; break; case USB_DT_CONFIG << 8: switch (vsfurb->vsfdev->speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: len = sizeof(fs_rh_config_descriptor); memcpy (data, fs_rh_config_descriptor, len); break; case USB_SPEED_HIGH: case USB_SPEED_VARIABLE: \ len = sizeof(hs_rh_config_descriptor); memcpy (data, hs_rh_config_descriptor, len); break; //case USB_SPEED_SUPER: // break; default: goto error; } break; case USB_DT_STRING << 8: goto nongeneric; default: goto error; } break; case DeviceRequest | USB_REQ_GET_INTERFACE: data[0] = 0; len = 1; break; case DeviceOutRequest | USB_REQ_SET_INTERFACE: break; case DeviceOutRequest | USB_REQ_SET_ADDRESS: break; case EndpointRequest | USB_REQ_GET_STATUS: data[0] = 0; data[1] = 0; len = 2; break; case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: case EndpointOutRequest | USB_REQ_SET_FEATURE: break; default: nongeneric: return usbh->hcd->rh_control(usbh->hcd_data, vsfurb); } if (len) { if (vsfurb->transfer_length < len) len = vsfurb->transfer_length; vsfurb->actual_length = len; memcpy (vsfurb->transfer_buffer, data, len); } vsfurb->status = URB_OK; vsfsm_post_evt_pending(vsfurb->sm, VSFSM_EVT_URB_COMPLETE); return VSFERR_NONE; error: vsfurb->status = URB_FAIL; return VSFERR_FAIL; }
static void embflash_maldrv_oncb(void *param, vsf_err_t err) { struct embflash_mal_t *embflash = (struct embflash_mal_t *)param; embflash->err = err; vsfsm_post_evt_pending(embflash->notifier, VSFSM_EVT_USER); }
static void vsfusbd_CDCData_streamrx_on_rxconn(void *p) { struct vsfusbd_CDC_param_t *param = (struct vsfusbd_CDC_param_t *)p; vsfsm_post_evt_pending(¶m->iface->sm, VSFUSBD_CDC_EVT_STREAMRX_ONCONN); }
static vsf_err_t uvc_ctrl_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb; vsfsm_pt_begin(pt); // reset interfaces 1 (video) vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // reset interfaces 3 (audio) vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 3, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; if (hdata->set_param.connected == 0) { vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_DISABLE); vsfsm_post_evt_pending(&hdata->audio_sm, UAV_ISO_DISABLE); return VSFERR_NONE; } if (hdata->set_param.video_enable) { // negotiate hdata->video_iso_packet_len = 800; hdata->video_iso_ep = 1; // commit param vsfurb->transfer_buffer = hdata->ctrl_urb_buf; memcpy(vsfurb->transfer_buffer, negotiate_temp, 26); vsfurb->transfer_length = 26; vsfurb->pipe = usb_sndctrlpipe(vsfurb->vsfdev, 0); err = vsfusbh_control_msg(hdata->usbh, vsfurb, USB_RECIP_INTERFACE | USB_DIR_OUT, SET_CUR, 0x0200, 0x0001); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // set interfaces vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 3); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // enable video vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_ENABLE); } if (hdata->set_param.audio_enable) { // TODO // enable audio vsfsm_post_evt_pending(&hdata->audio_sm, UAV_ISO_ENABLE); } vsfsm_pt_end(pt); return VSFERR_NONE; }
static void vsf_malstream_on_inout(void *param) { struct vsf_malstream_t *malstream = (struct vsf_malstream_t *)param; vsfsm_post_evt_pending(&malstream->sm, VSF_MALSTREAM_ON_INOUT); }
static void vsfshell_streamtx_on_rxconn(void *p) { struct vsfshell_t *shell = (struct vsfshell_t *)p; vsfsm_post_evt_pending(&shell->sm, VSFSHELL_EVT_STREAMTX_ONCONN); }
static void vsfshell_streamrx_on_in(void *p) { struct vsfshell_t *shell = (struct vsfshell_t *)p; vsfsm_post_evt_pending(&shell->sm, VSFSHELL_EVT_STREAMRX_ONIN); }
static vsf_err_t uvc_ctrl_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb; vsfsm_pt_begin(pt); if (hdata->set_param.video_enable) { // negotiate hdata->video_iso_packet_len = 1024; hdata->video_iso_ep = 1; // commit param vsfurb->transfer_buffer = hdata->ctrl_urb_buf; memcpy(vsfurb->transfer_buffer, negotiate_temp, 26); vsfurb->transfer_length = 26; vsfurb->pipe = usb_sndctrlpipe(vsfurb->vsfdev, 0); err = vsfusbh_control_msg(hdata->usbh, vsfurb, USB_TYPE_CLASS |USB_RECIP_INTERFACE | USB_DIR_OUT, SET_CUR, 0x0200, 0x0001); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // set interfaces vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 4); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // enable video vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_ENABLE); } else { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; } vsf_bufmgr_free(hdata->ctrl_urb_buf); hdata->ctrl_urb_buf = NULL; memcpy(&hdata->cur_param, &hdata->set_param, sizeof(struct vsfusbh_uvc_param_t)); vsfusbh_uvc_report(hdata, &hdata->cur_param, NULL); vsfsm_pt_end(pt); return VSFERR_NONE; }