/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_otg_khci_isr * Returned Value : None * Comments : * Service all the interrupts in the kirin usb hardware *END*-----------------------------------------------------------------*/ static void _usb_otg_khci_isr ( void* otg_khci_call_ptr ) { usb_otg_state_struct_t * usb_otg_struct_ptr = ((usb_otg_khci_call_struct_t *)otg_khci_call_ptr)->otg_handle_ptr; if (usb_otg_struct_ptr != NULL) { uint8_t otg_int_stat = (uint8_t)usb_hal_khci_get_otg_interrupt_status(g_usb_instance.instance); uint8_t otg_stat = usb_hal_khci_get_otg_status(g_usb_instance.instance); usb_otg_status_t *otg_status = &usb_otg_struct_ptr->otg_status; /* Handle otg interrupt*/ if (otg_int_stat != 0) { /* Clear the OTG relevant interrupts */ usb_hal_khci_clr_otg_interrupt(g_usb_instance.instance,otg_int_stat); if (otg_int_stat & USB_OTGISTAT_ONEMSEC_MASK) { otg_status->tmr_1ms = TRUE; if ( otg_status->ms_since_line_changed < 0xffff ) { otg_status->ms_since_line_changed++; } if ( otg_status->host_req_poll_timer < 0xffff ) { otg_status->host_req_poll_timer++; } /* Decrement timeouts */ if (otg_status->b_timeout_en && otg_status->b_timeout) { otg_status->b_timeout--; if (!otg_status->b_timeout) { otg_status->b_timeout_en = FALSE; } } } if ((otg_int_stat & USB_OTGISTAT_LINE_STATE_CHG_MASK) || (!(otg_stat & USB_OTGSTAT_LINESTATESTABLE_MASK))) { otg_status->ms_since_line_changed = 0; } } /* Check active stack*/ if (otg_status->active_stack == USB_ACTIVE_STACK_HOST) { /* Host stack is current active stack */ /* Call function to handle host interrupt*/ _usb_host_khci_isr(NULL); } else if (otg_status->active_stack == USB_ACTIVE_STACK_DEVICE) { /* Device stack is current active stack */ /* Call function to handle device interrupt*/ if (usb_otg_struct_ptr->dev_inst_ptr != NULL) { _usb_dev_khci_isr(usb_otg_struct_ptr->dev_inst_ptr); } } else { /* Clear all pending USB interrupt*/ usb_hal_khci_clr_all_interrupts(g_usb_instance.instance); } OS_Event_set(usb_otg_struct_ptr->otg_isr_event, USB_OTG_KHCI_ISR_EVENT); } }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : App_OtgCallback * Returned Value : none * Comments : * * *END*--------------------------------------------------------------------*/ void App_OtgCallback(usb_otg_handle handle, uint32_t event) { (void)handle; /* not used */ if (event & OTG_B_IDLE) { g_dev_type = dev_b; /* Device type: B */ g_sess_vld = FALSE; /* session not valid */ g_otg_state = OTG_B_IDLE; } if (event & OTG_B_IDLE_SRP_READY) { g_otg_state = OTG_B_IDLE_SRP_READY; } if (event & OTG_B_PERIPHERAL) { g_otg_state = OTG_B_PERIPHERAL; if (g_sess_vld == FALSE) { g_sess_vld = TRUE; /* session valid */ } } if (event & OTG_B_HOST) { g_otg_state = OTG_B_HOST; } if (event & OTG_B_A_HNP_REQ) { (void)_usb_otg_bus_release(g_otg_handle); } if (event & OTG_A_WAIT_BCON_TMOUT) { _usb_otg_set_a_bus_req(g_otg_handle , FALSE); } if (event & OTG_A_BIDL_ADIS_TMOUT) { _usb_otg_set_a_bus_req(g_otg_handle, TRUE); } if (event & OTG_A_B_HNP_REQ) { _usb_otg_set_a_bus_req( handle , FALSE); } if (event & OTG_A_IDLE) { g_dev_type = dev_a; /* Device type: A */ g_sess_vld = FALSE; g_otg_state = OTG_A_IDLE; } if (event & OTG_A_WAIT_VRISE) { g_otg_state = OTG_A_WAIT_VRISE; _usb_otg_set_a_bus_req( handle , TRUE); } if (event & OTG_A_WAIT_BCON) { g_sess_vld = TRUE; g_otg_state = OTG_A_WAIT_BCON; } if (event & OTG_A_HOST) { g_otg_state = OTG_A_HOST; } if (event & OTG_A_SUSPEND) { g_otg_state = OTG_A_SUSPEND; } if (event & OTG_A_PERIPHERAL) { g_otg_state = OTG_A_PERIPHERAL; } if (event & OTG_A_WAIT_VFALL) { if (g_vbus_err == TRUE) { g_vbus_err = FALSE; } g_otg_state = OTG_A_WAIT_VFALL; } if (event & OTG_A_VBUS_ERR) { g_vbus_err = TRUE; g_otg_state = OTG_A_VBUS_ERR; } OS_Event_set(g_otg_app_event_handle, event); }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_hid_keyboard_event * Returned Value : None * Comments : * Called when HID device has been attached, detached, etc. *END*--------------------------------------------------------------------*/ void usb_host_hid_keyboard_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 */ uint32_t event_code) { usb_device_interface_struct_t* pHostIntf = (usb_device_interface_struct_t*)intf_handle; interface_descriptor_t* intf_ptr = pHostIntf->lpinterfaceDesc; usb_status status = USB_OK; //fflush(stdout); switch (event_code) { case USB_ATTACH_EVENT: g_interface_info[g_interface_number] = pHostIntf; g_interface_number++; printf("HID State = %d", g_kbd_hid_device.dev_state); printf("HID Class = %d", intf_ptr->bInterfaceClass); printf("HID SubClass = %d", intf_ptr->bInterfaceSubClass); printf("HID Protocol = %d\n", intf_ptr->bInterfaceProtocol); break; /* Drop through config event for the same processing */ case USB_CONFIG_EVENT: //fflush(stdout); printf("HID State = USB_CONFIG_EVENT"); if(g_kbd_hid_device.dev_state == USB_DEVICE_IDLE) { g_kbd_hid_device.dev_handle = dev_handle; g_kbd_hid_device.intf_handle = hid_get_interface();; g_kbd_hid_device.dev_state = USB_DEVICE_CONFIGURED; } else { printf("HID device already attached\n"); //fflush(stdout); } break; case USB_INTF_OPENED_EVENT: printf("HID State = USB_INTF_OPENED_EVENT"); g_kbd_hid_device.dev_state = USB_DEVICE_INTERFACED; OS_Event_set(usb_keyboard_event, USB_Keyboard_Event_CTRL); break; case USB_DETACH_EVENT: /* Use only the interface with desired protocol */ g_interface_number = 0; if (g_kbd_hid_device.dev_state < USB_DEVICE_INTERFACED) { g_kbd_hid_device.dev_handle = NULL; g_kbd_hid_device.intf_handle = NULL; g_kbd_hid_device.dev_state = USB_DEVICE_IDLE; return; } printf("\n----- Detach Event -----\n"); printf("State = %d", g_kbd_hid_device.dev_state); printf(" Class = %d", intf_ptr->bInterfaceClass); printf(" SubClass = %d", intf_ptr->bInterfaceSubClass); printf(" Protocol = %d\n", intf_ptr->bInterfaceProtocol); //fflush(stdout); status = usb_host_close_dev_interface(host_handle, g_kbd_hid_device.dev_handle, g_kbd_hid_device.intf_handle, g_kbd_hid_device.class_handle); if (status != USB_OK) { printf("error in _usb_hostdev_close_interface %x\n", status); } g_kbd_hid_device.dev_handle = NULL; g_kbd_hid_device.intf_handle = NULL; g_kbd_hid_device.dev_state = USB_DEVICE_IDLE; OS_Event_set(usb_keyboard_event, USB_Keyboard_Event_CTRL); break; } }
void APP_init(void) { usb_status status = USB_OK; uint32_t opt = 0; status = usb_host_init(CONTROLLER_ID, usb_host_board_init, &g_host_handle); if (status != USB_OK) { USB_PRINTF("\r\nUSB Host Initialization failed! STATUS: 0x%x", status); return; } /* ** since we are going to act as the host driver, register the driver ** information for wanted class/subclass/protocols */ status = usb_host_register_driver_info(g_host_handle, (void *) DriverInfoTable); if (status != USB_OK) { USB_PRINTF("\r\nUSB Initialization driver info failed! STATUS: 0x%x", status); return; } status = usb_host_register_unsupported_device_notify(g_host_handle, usb_host_hid_unsupported_device_event); if (status != USB_OK) { USB_PRINTF("\r\nUSB Initialization driver info failed! STATUS: 0x%x", status); return; } mouse_usb_event = OS_Event_create(0);/* manually clear */ if (mouse_usb_event == NULL) { USB_PRINTF("mouse_usb_event create failed\r\n"); return; } mouse_hid_com = (hid_command_t*) OS_Mem_alloc_zero(sizeof(hid_command_t)); if (mouse_hid_com == NULL) { USB_PRINTF("mouse_hid_com create failed\r\n"); return; } kbd_usb_event = OS_Event_create(0);/* manually clear */ if (kbd_usb_event == NULL) { USB_PRINTF("kbd_usb_event create failed\r\n"); return; } OS_Event_set(kbd_usb_event, USB_EVEN_INIT); kbd_hid_com = (hid_command_t*) OS_Mem_alloc_zero(sizeof(hid_command_t)); if (kbd_hid_com == NULL) { USB_PRINTF("kbd_hid_com create failed\r\n"); return; } if ((uint32_t) OS_TASK_ERROR == OS_Task_create(USB_KEYBOARD_TASK_ADDRESS, (void*) g_host_handle, (uint32_t) USB_KEYBOARD_TASK_PRIORITY, USB_KEYBOARD_TASK_STACKSIZE, USB_KEYBOARD_TASK_NAME, &opt)) { USB_PRINTF("keyboard task create failed\r\n"); return; } if ((uint32_t) OS_TASK_ERROR == OS_Task_create(USB_MOUSE_TASK_ADDRESS, (void*) g_host_handle, (uint32_t) USB_MOUSE_TASK_PRIORITY, USB_MOUSE_TASK_STACKSIZE, USB_MOUSE_TASK_NAME, &opt)) { USB_PRINTF("mouse task create failed\r\n"); return; } time_init(); USB_PRINTF("\fUSB HID Mouse+Keyboard\r\nWaiting for USB Mouse or Keyboard to be attached...\r\n"); }
/* usb_host_video_stream_event */ void usb_host_video_stream_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 */ uint32_t event_code ) { usb_device_interface_struct_t* pHostIntf = (usb_device_interface_struct_t*)intf_handle; interface_descriptor_t* intf_ptr = pHostIntf->lpinterfaceDesc; switch (event_code) { case USB_ATTACH_EVENT: g_video_camera.interface_ptr[g_video_camera.interface_number] = pHostIntf; g_video_camera.interface_type[g_video_camera.interface_number] = USB_SUBCLASS_VIDEO_STREAMING; g_video_camera.interface_number++; USB_PRINTF("----- Attach Event -----\r\n"); USB_PRINTF("State = %d", g_video_camera.stream_state); USB_PRINTF(" Interface Number = %d", intf_ptr->bInterfaceNumber); USB_PRINTF(" Alternate Setting = %d", intf_ptr->bAlternateSetting); USB_PRINTF(" Class = %d", intf_ptr->bInterfaceClass); USB_PRINTF(" SubClass = %d", intf_ptr->bInterfaceSubClass); USB_PRINTF(" Protocol = %d\r\n", intf_ptr->bInterfaceProtocol); break; case USB_CONFIG_EVENT: if(g_video_camera.stream_state == USB_DEVICE_IDLE) { if ((NULL != g_video_camera.dev_handle) && (g_video_camera.dev_handle != dev_handle)) { USB_PRINTF("Video device already attached - Control DEV_STATE = %d\r\n", g_video_camera.control_state); USB_PRINTF("Video device already attached - Stream DEV_STATE = %d\r\n", g_video_camera.stream_state); return; } g_video_camera.dev_handle = dev_handle; for(int i = 0;i < g_video_camera.interface_number;i++) { if(g_video_camera.interface_type[i] == USB_SUBCLASS_VIDEO_STREAMING) { g_video_camera.stream_intf_handle = g_video_camera.interface_ptr[i]; break; } } g_video_camera.stream_state = USB_DEVICE_ATTACHED; } else { USB_PRINTF("Video device already attached - Stream DEV_STATE = %d\r\n", g_video_camera.stream_state); } break; case USB_INTF_OPENED_EVENT: USB_PRINTF("----- Interfaced Event -----\r\n"); g_video_camera.stream_state = USB_DEVICE_INTERFACE_OPENED; break; case USB_DETACH_EVENT: /* Use only the interface with desired protocol */ USB_PRINTF("\r\n----- Detach Event -----\r\n"); USB_PRINTF("State = %d", g_video_camera.stream_state); USB_PRINTF(" Interface Number = %d", intf_ptr->bInterfaceNumber); USB_PRINTF(" Alternate Setting = %d", intf_ptr->bAlternateSetting); USB_PRINTF(" Class = %d", intf_ptr->bInterfaceClass); USB_PRINTF(" SubClass = %d", intf_ptr->bInterfaceSubClass); USB_PRINTF(" Protocol = %d\r\n", intf_ptr->bInterfaceProtocol); g_video_camera.interface_number --; g_video_camera.stream_state = USB_DEVICE_DETACHED; break; default: USB_PRINTF("Video Device state = %d??\r\n", g_video_camera.stream_state); g_video_camera.stream_state = USB_DEVICE_IDLE; break; } /* notify application that status has changed */ OS_Event_set(g_video_camera.video_camera_stream_event, USB_EVENT_CTRL); }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : _usb_otg_sm_b * Returned Value : * Comments : This function handles the substates of the B-state machine * * *END*----------------------------------------------------------------------*/ void _usb_otg_sm_b ( usb_otg_handle otg_handle ) { usb_otg_state_struct_t * usb_otg_struct_ptr = (usb_otg_state_struct_t *)otg_handle; usb_otg_status_t *otg_status = &usb_otg_struct_ptr->otg_status; if (!otg_status->id) { _usb_otg_id_chg_a(otg_handle); return; } switch (usb_otg_struct_ptr->sub_state) { case USB_OTG_SM_B_IDLE_SESS_DETECT: usb_otg_struct_ptr->hnp_enabled = FALSE; if (otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL); } else { /* Disable pull-up. The B-Device is now in the B-Idle state */ _usb_otg_callback_set_dp_pull_up(otg_handle, FALSE); if (otg_status->sess_end) { usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SESS_END_DETECT; otg_status->b_timeout = TB_SESSEND_SRP; /* Program the SRP detect timeout as SESSEND SRP */ } } break; case USB_OTG_SM_B_IDLE_SESS_END_DETECT: if (otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL); } else { /* Read the Live SE0 bit */ if ((otg_status->live_se0) && (otg_status->line_stable)) { otg_status->b_timeout_en = TRUE; usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SE0_STABLE_WAIT; } } break; case USB_OTG_SM_B_IDLE_SE0_STABLE_WAIT: if (otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL); } else { /* Line state change. restart SE0 detection */ if (!otg_status->line_stable) { otg_status->b_timeout_en = TRUE; otg_status->b_timeout = TB_SE0_SRP; /* reinitialize the the SE0 detect timer */ /* Keep the current state */ } else { if (otg_status->b_timeout == 0) { /* The timeout expired during stable SE0 */ _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SRP_START_ARMED, OTG_B_IDLE_SRP_READY); } } } break; case USB_OTG_SM_B_IDLE_SRP_START_ARMED: if (otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL); } else { /* Line state change. restart SE0 detection */ if (!otg_status->line_stable) { otg_status->b_timeout = TB_SE0_SRP; /* reinitialize the the SE0 detect timer */ usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SESS_END_DETECT; } else { if (usb_otg_struct_ptr->srp_request || usb_otg_struct_ptr->power_up) { usb_otg_struct_ptr->power_up = FALSE; usb_otg_struct_ptr->srp_request = FALSE; /* Start SRP */ /* Start the D+ pulsing timeout */ otg_status->b_timeout = TB_DATA_PLS; /* reinitialize the the SE0 detect timer */ otg_status->b_timeout_en = TRUE; /* Enable D+ pullup */ _usb_otg_callback_set_dp_pull_up(otg_handle, TRUE); usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_SRP_PULSE; } } } break; case USB_OTG_SM_B_SRP_PULSE: if (otg_status->b_timeout == 0) { /* The timeout expired. Remove the D+ pullup */ _usb_otg_callback_set_dp_pull_up(otg_handle, FALSE); /* Wait for VBUS */ otg_status->b_timeout = (TB_SRP_FAIL - TB_DATA_PLS); otg_status->b_timeout_en = TRUE; usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_SRP_VBUS_WAIT; /* Signal the event to the application */ OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_SRP_INIT); } break; case USB_OTG_SM_B_SRP_VBUS_WAIT: if (otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL); } else { if (otg_status->b_timeout == 0) { /* The timeout expired during VBUS wait */ /* Inform the application about the failed SRP and return to idle state */ /* and wait for SE0 condition on the bus to be able to restart the SRP */ usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SE0_STABLE_WAIT; otg_status->b_timeout_en = TRUE; otg_status->b_timeout = TB_SE0_SRP; /* reinitialize the the SE0 detect timer */ /* Signal the event to the application */ OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_SRP_FAIL); } } break; case USB_OTG_SM_B_PERI_BUS_SUSP_DETECT: if (!otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); } else { /* Enable the D+ pull-up. the B device is in the peripheral state */ _usb_otg_callback_set_dp_pull_up(otg_handle, TRUE); usb_otg_struct_ptr->power_up = FALSE; /* Start monitoring the data lines. * If the bus has inactivity for more than TB_AIDL_BDIS, then the A is considered disconnected and B can start HNP */ usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_BUS_SUSP_WAIT; otg_status->b_timeout_en = TRUE; otg_status->b_timeout = TB_AIDL_BDIS; /* reinitialize the IDLE detect timer */ } break; case USB_OTG_SM_B_PERI_BUS_SUSP_WAIT: if (!otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); } else { if (!otg_status->line_stable) { /* Restart detection */ otg_status->b_timeout_en = TRUE; otg_status->b_timeout = TB_AIDL_BDIS; /* reinitialize the IDLE detect timer */ } else { if ((usb_otg_struct_ptr->hnp_enabled) && (otg_status->b_timeout == 0)) { usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_HNP_ARMED; /* Signal the event to the application */ OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_PERIPHERAL_HNP_READY); } } } break; case USB_OTG_SM_B_PERI_HNP_ARMED: if (!otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); } else { if ((!otg_status->line_stable) || (!usb_otg_struct_ptr->hnp_enabled)) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL_HNP_FAIL); } else { if ((usb_otg_struct_ptr->bus_request) && (usb_otg_struct_ptr->hnp_enabled)) { usb_otg_struct_ptr->bus_request = FALSE; /* Clear the Status at the USB device level */ _usb_device_set_status(usb_otg_struct_ptr->dev_inst_ptr, USB_STATUS_OTG, USB_STATUS_IDLE); /* Start HNP. Turn off Pull-Up on D+ for the Host to detect SE0 */ _usb_otg_callback_set_dp_pull_up(otg_handle, FALSE); /* Wait for data line to discharge (25us) */ otg_status->b_timeout = 1; otg_status->b_timeout_en = TRUE; usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_HNP_START; /* Signal the event to the application */ OS_Event_set ((usb_otg_struct_ptr->otg_app_event), OTG_B_PERIPHERAL_HNP_START); } } } break; case USB_OTG_SM_B_PERI_HNP_START: if (!otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); } else { if (otg_status->b_timeout == 0) { /* Line should have discharged by now */ /* Start the host disconnect detect */ otg_status->b_timeout = TB_ASE0_BRST; otg_status->b_timeout_en = TRUE; usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_HNP_ACONN; } } break; case USB_OTG_SM_B_PERI_HNP_ACONN: if (!otg_status->sess_valid) { _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); } else { if (otg_status->b_timeout == 0) { /* A connect timeout detected. Go back to peripheral state */ _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL_HNP_FAIL); } else { /* Check the Data line state */ if ((!otg_status->live_se0) && (otg_status->live_jstate) && (otg_status->line_stable)) { /* J-STATE. Host has been released */ /* Enter the B-Host state */ usb_otg_struct_ptr->hnp_enabled = FALSE; otg_status->a_conn = TRUE; _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_HOST, OTG_B_HOST); } else { if ((!otg_status->live_se0) && (!otg_status->live_jstate) && (otg_status->line_stable)) { /* Host has retained the bus */ _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL_HNP_FAIL); } } } } break; case USB_OTG_SM_B_HOST: if (!otg_status->sess_valid) { otg_status->a_conn = FALSE; _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); } else { if ((otg_status->a_conn == FALSE) || usb_otg_struct_ptr->bus_release) { usb_otg_struct_ptr->bus_release = FALSE; otg_status->a_conn = FALSE; /* A-device disconnected or B has finished using the bus */ _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL); } else { if ( usb_otg_struct_ptr->dev_inst_ptr != NULL ) { if (otg_status->hnp_req) { OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_A_HNP_REQ); } if (otg_status->hnp_support && (otg_status->host_req_poll_timer >= T_HOST_REQ_POLL)) { otg_status->host_req_poll_timer = 0; _usb_otg_hnp_poll_req(usb_otg_struct_ptr); } } } } break; default: break; } }