📄 otg_drv.c
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*****************************************************************************
*
* Filename:
* ---------
* otg_drv.c
*
* Project:
* --------
* Maui_Software
*
* Description:
* ------------
* This file implements otg hardware related functions
*
* Author:
* -------
* -------
*
*============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*============================================================================
****************************************************************************/
#include "drv_comm.h"
#include "reg_base.h"
#include "drvpdn.h"
#include "intrCtrl.h"
#include "drv_hisr.h"
#include "gpio_hw.h"
#include "gpio_sw.h"
#include "dma_hw.h"
#include "dma_sw.h"
#include "gpt_sw.h"
#include "stack_common.h"
#include "stack_msgs.h"
#include "app_ltlcom.h" /* Task message communiction */
#include "isrentry.h"
#include "bmt.h"
#include "usb_hw.h"
#include "otg_drv.h"
#include "otg_drv_pri.h"
#include "usb_hcd.h"
#include "usb_drv.h"
#ifdef __OTG_ENABLE__
static OTG_Drv_Info g_OtgInfo;
static kal_uint32 OTG_Get_VBUS_Volt(void);
static kal_bool OTG_Is_A_Bus_Valid(void);
static kal_bool OTG_Is_B_Session_Valid(void);
static kal_bool OTG_Is_B_Session_End(void);
static void OTG_Timeout_Hdlr(void *parameter);
static void OTG_Start_Timer(OTG_TIMER_TYPE type, kal_uint32 ticks);
static void OTG_Stop_Timer(void);
static kal_bool OTG_Check_Timer(void);
static kal_bool OTG_Is_TimerOut(OTG_TIMER_TYPE type);
static kal_bool OTG_Is_TimerActive(void);
static OTG_TIMER_TYPE OTG_Get_TimerType(void);
static void OTG_Process_A_Idle(void);
static void OTG_Process_A_Wait_VRise(void);
static void OTG_Process_A_Wait_BCon(void);
static void OTG_Process_A_Host(void);
static void OTG_Process_A_Suspend(void);
static void OTG_Process_A_Peripheral(void);
static void OTG_Process_A_Wait_VFall(void);
static void OTG_Process_B_Idle(void);
static void OTG_Process_B_Session_Valid(void);
static void OTG_Process_B_SRP_Init(void);
static void OTG_Process_B_Peripheral(void);
static void OTG_Process_B_Wait_ACon(void);
static void OTG_Process_B_Host(void);
static void OTG_State_Machine(void);
static void OTG_HISR(void);
static void OTG_LISR(void);
static void OTG_A_Plug_Timer_Callback(void *data);
static void OTG_A_Plug_HISR(void);
/************************************************************
driver info functions
*************************************************************/
void OTG_Init_Drv_Info(void)
{
g_OtgInfo.otg_state = OTG_STATE_START;
g_OtgInfo.host_up_hdlr = NULL;
g_OtgInfo.host_down_hdlr = NULL;
g_OtgInfo.device_up_hdlr = NULL;
g_OtgInfo.device_down_hdlr = NULL;
g_OtgInfo.a_host_stop_hdlr = NULL;
g_OtgInfo.b_hnp_fail_hdlr = NULL;
g_OtgInfo.a_vrise_fail_hdlr = NULL;
g_OtgInfo.b_srp_fail_hdlr = NULL;
g_OtgInfo.b_srp_stop_hdlr = NULL;
g_OtgInfo.a_bus_req = KAL_TRUE;
g_OtgInfo.a_detect_b_conn = KAL_FALSE;
g_OtgInfo.a_detect_b_suspend = KAL_FALSE;
g_OtgInfo.a_detect_b_resume = KAL_FALSE;
g_OtgInfo.a_suspend_req = KAL_FALSE;
g_OtgInfo.a_resume_req = KAL_FALSE;
g_OtgInfo.a_set_b_hnp_enable = KAL_FALSE;
g_OtgInfo.b_suspend_req = KAL_FALSE;
g_OtgInfo.b_detect_a_conn = KAL_FALSE;
g_OtgInfo.b_detect_a_suspend = KAL_FALSE;
g_OtgInfo.b_detect_a_resume = KAL_FALSE;
g_OtgInfo.b_srp_request = KAL_FALSE;
g_OtgInfo.b_hnp_enable = KAL_FALSE;
g_OtgInfo.b_check_session = KAL_FALSE;
g_OtgInfo.timer_on = KAL_FALSE;
g_OtgInfo.timer_out = KAL_FALSE;
g_OtgInfo.timer_type = OTG_TIMER_NONE;
g_OtgInfo.device_up = KAL_FALSE;
g_OtgInfo.host_up = KAL_FALSE;
g_OtgInfo.b_processing = KAL_FALSE;
g_OtgInfo.b_unmask_irq = KAL_TRUE;
g_OtgInfo.is_ProOTGHISR = KAL_FALSE;
if (g_OtgInfo.gpt_handle == 0)
GPTI_GetHandle(&g_OtgInfo.gpt_handle);
}
void OTG_Register_Drv_Info(OTG_DRV_HDLR_TYPE type, otg_intr_handler_ptr hdlr)
{
switch(type)
{
case OTG_DRV_HDLR_HOST_UP:
g_OtgInfo.host_up_hdlr = hdlr;
break;
case OTG_DRV_HDLR_HOST_DOWN:
g_OtgInfo.host_down_hdlr = hdlr;
break;
case OTG_DRV_HDLR_DEVICE_UP:
g_OtgInfo.device_up_hdlr = hdlr;
break;
case OTG_DRV_HDLR_DEVICE_DOWN:
g_OtgInfo.device_down_hdlr = hdlr;
break;
case OTG_DRV_HDLR_A_VRISE_FAIL:
g_OtgInfo.a_vrise_fail_hdlr = hdlr;
break;
case OTG_DRV_HDLR_A_HNP_FAIL:
g_OtgInfo.a_hnp_fail_hdlr = hdlr;
break;
case OTG_DRV_HDLR_A_HNP_STOP:
g_OtgInfo.a_hnp_stop_hdlr = hdlr;
break;
case OTG_DRV_HDLR_B_HNP_FAIL:
g_OtgInfo.b_hnp_fail_hdlr = hdlr;
break;
case OTG_DRV_HDLR_B_SRP_FAIL:
g_OtgInfo.b_srp_fail_hdlr = hdlr;
break;
case OTG_DRV_HDLR_B_SRP_STOP:
g_OtgInfo.b_srp_stop_hdlr = hdlr;
break;
case OTG_DRV_HDLR_A_HOST_STOP:
g_OtgInfo.a_host_stop_hdlr = hdlr;
break;
default:
ASSERT(0);
break;
}
}
void OTG_Drv_Create_ISR(void)
{
IRQ_Register_LISR(IRQ_USB_CODE, OTG_LISR,"OTG");
DRV_Register_HISR(DRV_USB_HISR_ID, OTG_HISR);
}
void OTG_Drv_Activate_ISR(void)
{
g_OtgInfo.b_unmask_irq = KAL_TRUE;
IRQSensitivity(IRQ_USB_CODE,LEVEL_SENSITIVE);
IRQUnmask(IRQ_USB_CODE);
}
/************************************************************
system ctrl functions
*************************************************************/
void OTG_Init_Drv(void)
{
kal_bool b_process_state_machine = KAL_FALSE;
kal_uint32 savedMask;
volatile kal_uint32 delay;
/* mask all OTG interupts */
DRV_WriteReg8(OTG_INT_EN, 0x0);
/* Clear all OTG interrupts */
DRV_WriteReg8(OTG_INT_STAT, 0x0);
/* enable OTG*/
DRV_WriteReg8(OTG_CTRL, OTG_CTL_OTG_ENABLE);
DRV_WriteReg8(OTG_INT_EN, 0);
// wait for stable
for(delay=0; delay<50000; delay++)
{}
savedMask = SaveAndSetIRQMask();
if(g_OtgInfo.b_processing == KAL_FALSE)
{
g_OtgInfo.b_processing = KAL_TRUE;
b_process_state_machine = KAL_TRUE;
}
RestoreIRQMask(savedMask);
if(b_process_state_machine==KAL_TRUE)
{
OTG_State_Machine();
g_OtgInfo.b_processing = KAL_FALSE;
}
}
void OTG_Set_Plug_Type(OTG_PLUG_TYPE type)
{
g_OtgInfo.plug_type = type;
}
OTG_PLUG_TYPE OTG_Get_Plug_Type(void)
{
return g_OtgInfo.plug_type;
}
/* A- host can request to suspend bus without setting HNP enable
Note that A should change to un-enumerate state when it suspend bus */
void OTG_A_Suspend_Req(void)
{
OTG_Set_Status(OTG_STATUS_A_SUSPEND_REQUEST, KAL_TRUE);
}
/* A - host request to resume bus
Note that A shoule re-enumerate after it resumr the bus*/
void OTG_A_Resume_Req(void)
{
OTG_Set_Status(OTG_STATUS_A_RESUME_REQUEST, KAL_TRUE);
}
/* This function should be called when B device is not recognized by A device
And B device dose not have HNP capability
Note that this should only be called when B dose not have HNP capability
*/
void OTG_A_Stop_Host(void)
{
OTG_Set_Status(OTG_STATUS_A_BUS_REQUEST, KAL_FALSE);
}
/* A device set HNP enable feature to B device, then call this function to start HNP procedure */
void OTG_A_Start_HNP(void)
{
OTG_Set_Status(OTG_STATUS_A_SET_B_HNP_ENABLE, KAL_TRUE);
}
/* This function should be called when B device is set HNP enabled by host */
void OTG_B_EnDis_HNP(kal_bool set)
{
OTG_Set_Status(OTG_STATUS_B_HNP_ENABLE, set);
}
void OTG_B_Start_SRP(void)
{
OTG_Set_Status(OTG_STATUS_B_SRP_REQUEST, KAL_TRUE);
}
void OTG_B_Stop_Host(void)
{
OTG_Set_Status(OTG_STATUS_B_SUSPEND_REQUEST, KAL_TRUE);
}
void OTG_B_Set_Session_Valid(kal_bool set)
{
OTG_Set_Status(OTG_STATUS_B_SESSION_VALID, set);
}
void OTG_Set_Status(OTG_STATUS_TYPE type, kal_bool set)
{
kal_bool b_process_state_machine = KAL_FALSE;
kal_uint32 savedMask;
// USB_Ms_Dbg_Trace(OTG_SET_STATUS, type);
// USB_Ms_Dbg_Trace(OTG_SET_STATUS, set);
switch(type)
{
case OTG_STATUS_A_BUS_REQUEST:
g_OtgInfo.a_bus_req = type;
break;
case OTG_STATUS_A_DETECT_B_CONN:
g_OtgInfo.a_detect_b_conn = set;
break;
case OTG_STATUS_A_DETECT_B_SUSPEND:
g_OtgInfo.a_detect_b_suspend = set;
break;
case OTG_STATUS_A_DETECT_B_RESUME:
g_OtgInfo.a_detect_b_resume = set;
break;
case OTG_STATUS_A_DETECT_B_DATA_PLS:
g_OtgInfo.a_detect_b_data_pls = set;
break;
case OTG_STATUS_A_SUSPEND_REQUEST:
g_OtgInfo.a_suspend_req = set;
break;
case OTG_STATUS_A_RESUME_REQUEST:
g_OtgInfo.a_resume_req = set;
break;
case OTG_STATUS_A_SET_B_HNP_ENABLE:
g_OtgInfo.a_set_b_hnp_enable = set;
break;
case OTG_STATUS_B_SESSION_VALID:
g_OtgInfo.b_session_valid = set;
break;
case OTG_STATUS_B_SUSPEND_REQUEST:
g_OtgInfo.b_suspend_req = set;
break;
case OTG_STATUS_B_DETECT_A_CONN:
g_OtgInfo.b_detect_a_conn = set;
break;
case OTG_STATUS_B_DETECT_A_SUSPEND:
g_OtgInfo.b_detect_a_suspend = set;
break;
case OTG_STATUS_B_DETECT_A_RESUME:
g_OtgInfo.b_detect_a_resume = set;
break;
case OTG_STATUS_B_SRP_REQUEST:
g_OtgInfo.b_srp_request = set;
break;
case OTG_STATUS_B_HNP_ENABLE:
g_OtgInfo.b_hnp_enable = set;
break;
default:
ASSERT(0);
break;
}
/* process OTG state machine*/
savedMask = SaveAndSetIRQMask();
if(g_OtgInfo.b_processing == KAL_FALSE)
{
g_OtgInfo.b_processing = KAL_TRUE;
b_process_state_machine = KAL_TRUE;
}
RestoreIRQMask(savedMask);
if(b_process_state_machine==KAL_TRUE)
{
OTG_State_Machine();
g_OtgInfo.b_processing = KAL_FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -