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

📄 otg_fsm.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 3 页
字号:
				otg_fsm_state_change(fsm_data,A_HOST);				} else {		        	fsm_data->tcb.err_code = OTG_STATUS_TIMEOUT;					fsm_data->tcb.bus_req = 0;					otgfsm_stop_timer(fsm_data);					otg_fsm_state_change(fsm_data,A_WAIT_VFALL);				}			} else if( fsm_data->tcb.id == 1 ||  fsm_data->tcb.bus_drop == 1) {				fsm_data->tcb.bus_req = 0;				otgfsm_stop_timer(fsm_data);				otg_fsm_state_change(fsm_data,A_WAIT_VFALL);							} else if ( fsm_data->tcb.a_vbus_vld == 0 ) {				/* SW patch for VA_VBUS_VLD Bit going to low suddenly */				isp1362_mdelay(10);					otg_reg_read16(REG_OTG_STATUS, &data);				fsm_data->tcb.a_vbus_vld = (data & 0x02) ? 1: 0;				if ( fsm_data->tcb.a_vbus_vld == 0 ) {					otg_fsm_state_change(fsm_data,A_VBUS_ERR);				}			} else if (fsm_data->tcb.b_conn == 1) {									if(fsm_data->tcb.TimerId != A_BCON_DEBOUNCE_TIMER_ID) {					otgfsm_stop_timer(fsm_data);					otgfsm_start_timer(fsm_data, A_BCON_DEBOUNCE_TIMER_ID, A_BCON_DEBOUNCE_TIMER);				}			}			break;		case A_HOST:			otgfsm_local_vbus(fsm_data, TRUE);			otgfsm_local_pullup(FALSE);			otgfsm_hc_dc_sel(FALSE);			if(	fsm_data->tcb.id == 1 || fsm_data->tcb.bus_drop == 1 || 				fsm_data->tcb.b_conn == 0) {				otgfsm_start_timer(fsm_data,A_WAIT_BCON_TIMER_ID, A_WAIT_BCON_TIMER);				phci_otg_port_control(fsm_data->hcd_priv, OTG_PORT_DISCONNECT_PORT, NULL);				otg_fsm_state_change(fsm_data,A_WAIT_BCON);			} else if( fsm_data->tcb.a_vbus_vld == 0) {				/* SW patch for VA_VBUS_VLD Bit going to low suddenly */				isp1362_mdelay(10);					otg_reg_read16(REG_OTG_STATUS, &data);				fsm_data->tcb.a_vbus_vld = (data & 0x02) ? 1: 0;				if ( fsm_data->tcb.a_vbus_vld == 0 ) {					phci_otg_port_control(fsm_data->hcd_priv, OTG_PORT_DISCONNECT_PORT, NULL);					otg_fsm_state_change(fsm_data,A_VBUS_ERR);				}			} else if((fsm_data->tcb.bus_req == 0 && 					fsm_data->tcb.AllowStateChange == 1) 					|| fsm_data->tcb.a_suspend_req == 1) {					otgfsm_rdis_lcon_en(TRUE); 	// if B-device disconnected, then A-device assert pull-up immediately				otgfsm_start_timer(fsm_data, A_AIDL_BDIS_TIMER_ID, A_AIDL_BDIS_TIMER);				phci_otg_port_control(fsm_data->hcd_priv, OTG_PORT_SUSPEND, NULL);				phci_otg_port_control( fsm_data->hcd_priv, 					OTG_PORT_DISCONNECT_PORT, NULL);				otg_fsm_state_change(fsm_data,A_SUSPEND);			}			break;		case A_SUSPEND:			otgfsm_local_vbus(fsm_data, TRUE);			otgfsm_local_pullup(FALSE);			otgfsm_hc_dc_sel(FALSE);			fsm_data->tcb.a_suspend_req = 0;			if(	fsm_data->tcb.id == 1 || fsm_data->tcb.bus_drop == 1 || 				fsm_data->tcb.TimeOut == 1) {				fsm_data->tcb.TimeOut = 0;				otgfsm_rdis_lcon_en(FALSE);				otg_fsm_state_change(fsm_data,A_WAIT_VFALL);			} else if (fsm_data->tcb.a_vbus_vld == 0 ) {				/* SW patch for VA_VBUS_VLD Bit going to low suddenly */				isp1362_mdelay(10);					otg_reg_read16(REG_OTG_STATUS, &data);				fsm_data->tcb.a_vbus_vld = (data & 0x02) ? 1: 0;				if ( fsm_data->tcb.a_vbus_vld == 0 ) {					otg_fsm_state_change(fsm_data,A_VBUS_ERR);				}			} else if ( fsm_data->tcb.b_conn == 0 && fsm_data->tcb.a_set_b_hnp_en == 1) {				//A-device starts to detect suspend condition after 5ms delay				otgfsm_start_timer(fsm_data, A_SUSPEND_DET_TIMER_ID, A_SUSPEND_DET_TIMER);     				pdc_otg_control(NULL, PDC_ENABLE);				fsm_data->tcb.b_bus_suspend = 0;				otg_fsm_state_change(fsm_data,A_PERIPHERAL);			} else if ( fsm_data->tcb.b_conn == 0 && fsm_data->tcb.a_set_b_hnp_en == 0) {				otgfsm_rdis_lcon_en(FALSE);				otgfsm_start_timer(fsm_data,A_WAIT_BCON_TIMER_ID,A_WAIT_BCON_TIMER);				otg_fsm_state_change(fsm_data,A_WAIT_BCON);			} else if(fsm_data->tcb.bus_req == 1 || fsm_data->tcb.b_bus_resume == 1) {				otgfsm_rdis_lcon_en(FALSE);				fsm_data->tcb.AllowStateChange = 0;				otg_fsm_state_change(fsm_data,A_HOST);			}			break;		case A_PERIPHERAL:			otgfsm_local_vbus(fsm_data, TRUE);			otgfsm_local_pullup(TRUE);			otgfsm_hc_dc_sel(TRUE);			if( fsm_data->tcb.id == 1|| fsm_data->tcb.bus_drop == 1 )						// 0 == RmtSOF is IDLE for at least 3 ms			{				pdc_otg_control(NULL,PDC_DISABLE);				otg_fsm_state_change(fsm_data,A_WAIT_VFALL);			} else if (fsm_data->tcb.a_vbus_vld == 0 ) {				/* SW patch for VA_VBUS_VLD Bit going to low suddenly */				isp1362_mdelay(10);					otg_reg_read16(REG_OTG_STATUS, &data);				fsm_data->tcb.a_vbus_vld = (data & 0x02) ? 1: 0;				if ( fsm_data->tcb.a_vbus_vld == 0 ) {					pdc_otg_control(NULL,PDC_DISABLE);					otg_fsm_state_change(fsm_data,A_VBUS_ERR);				}			}			else if (fsm_data->tcb.b_bus_suspend == 1 && fsm_data->tcb.TimeOut == 1	) // suspend			{		        fsm_data->tcb.err_code = OTG_STATUS_NONE;				otgfsm_start_timer(fsm_data,A_WAIT_BCON_TIMER_ID,A_WAIT_BCON_TIMER);				fsm_data->tcb.b_bus_suspend = 0;				pdc_otg_control(NULL,PDC_DISABLE);				otg_fsm_state_change(fsm_data,A_WAIT_BCON);			}			break;		case A_WAIT_VFALL:			otgfsm_local_vbus(fsm_data, FALSE);			otgfsm_local_pullup(FALSE);			otgfsm_hc_dc_sel(FALSE);			if(fsm_data->tcb.bus_req == 1 || fsm_data->tcb.a_sess_vld == 0 ||				fsm_data->tcb.id == 1) {				otgfsm_init_fsm_data(fsm_data);				otg_fsm_state_change(fsm_data,A_IDLE);			}			break;		case A_VBUS_ERR:			otgfsm_local_vbus(fsm_data, FALSE);			otgfsm_local_pullup(FALSE);			fsm_data->tcb.err_code = OTG_STATUS_VBUS_ERR;		/* Set the VBUS error status */			otgfsm_hc_dc_sel(FALSE);			if(fsm_data->tcb.id == 1 || fsm_data->tcb.bus_drop == 1) {				fsm_data->tcb.bus_drop = 0;				otg_fsm_state_change(fsm_data,A_WAIT_VFALL);			}			break;		default:			break;	}}/*----------------------------------------------*//* Run the OTG 	FSM								*//* ---------------------------------------------*/void otgfsm_run(otg_fsm_t	*fsm_data) {	__u8	prev_state = INV_STATE;	// Get inputs for the FSM	otgfsm_status_probe(fsm_data);	// Run the A device FSM until its stebilized	while(prev_state != fsm_data->tcb.state) {		prev_state = fsm_data->tcb.state;		otgfsm_run_Adevice(fsm_data);	}		prev_state = INV_STATE;	// Run the B device FSM until its stebilized	while(prev_state != fsm_data->tcb.state) {		prev_state = fsm_data->tcb.state;		otgfsm_run_Bdevice(fsm_data);	}}/*----------------------------------------------*//* Init	fsm data variables						*//* ---------------------------------------------*/void otgfsm_init_fsm_data(otg_fsm_t	*fsm_data) {	/* Reset all the fields of fsm_data */	fsm_data->tcb.bus_req = 0;	fsm_data->tcb.a_suspend_req = 0;	fsm_data->tcb.a_bus_resume = 0;	fsm_data->tcb.a_bus_suspend = 0;	fsm_data->tcb.a_bus_reset = 0;	fsm_data->tcb.b_bus_resume = 0;	fsm_data->tcb.b_bus_suspend = 0;	fsm_data->tcb.b_hnp_en = 0;	fsm_data->tcb.a_set_b_hnp_en = 0;	fsm_data->tcb.b_hnp_support = 1;	fsm_data->tcb.a_hnp_support = 0;	fsm_data->tcb.a_alt_hnp_support = 0;	/* Stop if any timer is running */	if(fsm_data->tcb.TimerRunning == 1) otgfsm_stop_timer(fsm_data);	fsm_data->tcb.TimerRunning = 0;	fsm_data->tcb.TimeOut = 0;	fsm_data->tcb.TimerTick = 0;	fsm_data->tcb.Req4StateChange = 0;	fsm_data->tcb.AllowStateChange = 0;	fsm_data->tcb.bus_drop = 0;	fsm_data->tcb.TimerId = 0;	isp1362_otg_dev = fsm_data->dev;	/* Clear all the interrupts in the OTG interrupt register */	otg_reg_write16(REG_OTG_INT, 0xFFFF);}/*----------------------------------------------*//* Init	fsm 									*//* ---------------------------------------------*/void otgfsm_init(otg_fsm_t	*fsm_data ) {	otgfsm_init_fsm_data(fsm_data);	otgfsm_status_probe(fsm_data);	/* Enable all possible OTG interrupt sources */	otg_reg_write16(REG_OTG_INT_ENABLE, OTG_IRQ_MASK);	switch(fsm_data->tcb.id) {		case 0:			fsm_data->tcb.state = A_IDLE;			fsm_data->tcb.app_state = A_IDLE;			otgfsm_hc_dc_sel(FALSE);	//default HC			break;		case 1:			fsm_data->tcb.state = B_IDLE;			fsm_data->tcb.app_state = B_IDLE;			otgfsm_hc_dc_sel(TRUE);	//default DC			break;		default:			break;	}	otgfsm_run(fsm_data);}void otgfsm_deinit(otg_fsm_t	*fsm_data ) {	/* Disable all OTG interrupts */	otg_reg_write16(REG_OTG_INT_ENABLE, OTG_IRQ_MASK);	otg_reg_write16(REG_OTG_CONTROL, 0x00C0);		switch (fsm_data->tcb.state) {		case A_HOST:		case B_HOST:			phci_otg_port_control(fsm_data->hcd_priv, OTG_PORT_DISCONNECT_PORT, NULL);		break;		case A_PERIPHERAL:		case B_PERIPHERAL:				pdc_otg_control(NULL, PDC_DISCONNECT);				break;	}	return;	}/*----------------------------------------------*//* Change the FSM state (request from application *//* ---------------------------------------------*/void otgfsm_set_state(otg_fsm_t	*fsm_data, __u8	cmd) {	// Change the FSM variables		fsm_data->tcb.err_code = OTG_STATUS_NONE;	/* Set the FSM variables based on the command received */	switch(cmd) {		case HOST:			/* Change the state of the FSM to HOST (open OTG session) */			fsm_data->tcb.bus_req = 1;			fsm_data->tcb.bus_drop = 0;			fsm_data->tcb.b_srp_done = 0;			fsm_data->tcb.a_suspend_req = 0;			break;				case BUS_DROP:					/* Drop the VBUS */			fsm_data->tcb.bus_req = 0;			fsm_data->tcb.bus_drop = 1;			break;		case BUS_OPEN:			/* Allow VBUS to go when required */			fsm_data->tcb.bus_drop = 0;			break;		case IDLE:			/* Change the state to IDLE (close OTG session) */			fsm_data->tcb.bus_req = 0;			if(fsm_data->tcb.id == 0) {				fsm_data->tcb.a_suspend_req = 1;			} else {				fsm_data->tcb.AllowStateChange = 1;			}						break;		case PERIPHERAL:			/* This releases the mastership to other remote OTG device			 * if applicable otherwise closes the session */			fsm_data->tcb.bus_req = 0;			if(fsm_data->tcb.id == 1) {				fsm_data->tcb.AllowStateChange = 1;			}			break;	}	// Run the fsm	otgfsm_run(fsm_data);}

⌨️ 快捷键说明

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