📄 usb_hcd.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:
* ---------
* usb_hcd.c
*
* Project:
* --------
* Maui_Software
*
* Description:
* ------------
* This file implements usb host 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!
*
*------------------------------------------------------------------------------
* 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 "gpio_sw.h"
#include "dma_hw.h"
#include "dma_sw.h"
#include "gpt_sw.h"
#include "usb_hw.h"
#include "usb_hcd.h"
#include "usb_hcd_pri.h"
#include "otg_drv.h"
#ifdef __OTG_ENABLE__
USB_HCD_Struct g_UsbHcdInfo;
static void USB_HCD_Reset_Recovery_Timeout(void *parameter);
static void USB_HCD_Reset_Timeout(void *parameter);
static void USB_HCD_Reset_Device(USB_HCD_STATUS reset_reason);
static void USB_HCD_Delay_Reset_Timeout(void *parameter);
static void USB_HCD_Debounce_Timeout(void *parameter);
static void USB_HCD_Debounce_Attach(void);
static void USB_HCD_Process_Attach(void);
static void USB_HCD_Process_Detach(void);
static void USB_HCD_Send_Setup (kal_uint8 index);
static void USB_HCD_Send_Data (kal_uint8 index);
static void USB_HCD_Recv_Data (kal_uint8 index);
static void USB_HCD_Queue_Pkt(kal_uint8 index);
static void USB_HCD_Remove_Pkt(kal_uint8 index);
static kal_int8 USB_HCD_Get_Pending_Pkts(void);
static void USB_HCD_Sched_Pending_Pkts(void);
static void USB_HCD_Update_Interval(void);
static void USB_HCD_DMA_Callback(void);
/************************************************************
driver info functions
*************************************************************/
void USB_HCD_Init_Drv_Info(void)
{
kal_uint32 index;
/* init BDT ptr and addr*/
/* BDT */
WRITE_EP0_BDT(USB_BDT_RX, USB_BDT_EVEN, (USB_BDT_PTR)USB_BDT_RX0_EVEN);
WRITE_EP0_BDT(USB_BDT_RX, USB_BDT_ODD, (USB_BDT_PTR)USB_BDT_RX0_ODD);
WRITE_EP0_BDT(USB_BDT_TX, USB_BDT_EVEN, (USB_BDT_PTR)USB_BDT_TX0_EVEN);
WRITE_EP0_BDT(USB_BDT_TX, USB_BDT_ODD, (USB_BDT_PTR)USB_BDT_TX0_ODD);
/* interrupt handler */
g_UsbHcdInfo.attach_hdlr = NULL;
g_UsbHcdInfo.detach_hdlr = NULL;
g_UsbHcdInfo.resume_hdlr = NULL;
for(index = 0; index < USB_HCD_MAX_EP_NUM; index++)
{
g_UsbHcdInfo.ep_hdlr[index] = NULL;
g_UsbHcdInfo.ep_info[index].b_in_use = KAL_FALSE;
g_UsbHcdInfo.ep_info[index].b_enable = KAL_FALSE;
}
g_UsbHcdInfo.ep0_setup = KAL_FALSE;
g_UsbHcdInfo.rx_even_odd = 0;
g_UsbHcdInfo.tx_even_odd = 0;
g_UsbHcdInfo.rx_curent_index = -1;
g_UsbHcdInfo.tx_curent_index = -1;
if (g_UsbHcdInfo.gpt_handle == 0)
GPTI_GetHandle(&g_UsbHcdInfo.gpt_handle);
/* may be omit */
g_UsbHcdInfo.resume_timer = 0;
g_UsbHcdInfo.processing_ep_id = -1;
g_UsbHcdInfo.iso_pipe_head = -1;
g_UsbHcdInfo.iso_pipe_tail = -1;
g_UsbHcdInfo.intr_pipe_head = -1;
g_UsbHcdInfo.intr_pipe_tail = -1;
g_UsbHcdInfo.ctrl_pipe_head = -1;
g_UsbHcdInfo.ctrl_pipe_tail = -1;
g_UsbHcdInfo.bulk_pipe_head = -1;
g_UsbHcdInfo.bulk_pipe_tail = -1;
g_UsbHcdInfo.dma_index = -1;
g_UsbHcdInfo.dma_port = 0;
g_UsbHcdInfo.dma_pktrdy = KAL_FALSE;
g_UsbHcdInfo.dma_running = KAL_FALSE;
g_UsbHcdInfo.dma_callback_upd_run = KAL_FALSE;
// g_UsbHcdInfo.dma_callback = NULL;
g_UsbHcdInfo.dma_pktlength = 0;
g_UsbHcdInfo.dma_tx_ep = 0;
g_UsbHcdInfo.dma_res_tx_ep = 0;
g_UsbHcdInfo.fast_mode_tx_ep= 0;
g_UsbHcdInfo.b_unmask_irq = KAL_TRUE;
}
void USB_HCD_Register_Drv_Info(USB_HCD_HDLR_TYPE type, kal_uint32 ep_num, usb_hcd_intr_handler_ptr hdlr)
{
if(ep_num > USB_HCD_MAX_EP_NUM)
EXT_ASSERT(0, ep_num, USB_HCD_MAX_EP_NUM, 0);
switch(type)
{
case USB_HCD_HDLR_ATTACH:
g_UsbHcdInfo.attach_hdlr = hdlr;
break;
case USB_HCD_HDLR_DETACH:
g_UsbHcdInfo.detach_hdlr = hdlr;
break;
case USB_HCD_HDLR_RESUME:
g_UsbHcdInfo.resume_hdlr = hdlr;
break;
case USB_HCD_HDLR_TOKEN_DONE:
g_UsbHcdInfo.ep_hdlr[ep_num] = hdlr;
break;
default:
ASSERT(0);
break;
}
}
kal_uint8 USB_HCD_Get_FM_Pkt_Size(void)
{
return USB_HCD_FASTMODE_PKT_SIZE;
}
/* set unmask variable to control if unmask USB interruput when leaving USB HISR*/
void USB_HCD_Set_UnMask_Irq(kal_bool set)
{
g_UsbHcdInfo.b_unmask_irq = set;
}
kal_bool USB_HCD_Get_UnMask_Irq(void)
{
return g_UsbHcdInfo.b_unmask_irq;
}
void USB_HCD_Dis_Attach(void)
{
g_UsbHcdInfo.b_disable_attach = KAL_TRUE;
}
void USB_HCD_En_Attach(void)
{
g_UsbHcdInfo.b_disable_attach = KAL_FALSE;
}
/************************************************************
system ctrl functions
*************************************************************/
void USB_HCD_Initialize_Drv(void)
{
DRV_WriteReg8(USB_ENDPT_CTL(0), VUSB_ENDPT_DISABLE);
DRV_WriteReg8(USB_CTL, 0x0); /* Disable VUSB */
DRV_WriteReg8(USB_INT_ENB, 0x0); /* Mask all interupts */
DRV_WriteReg8(USB_INT_STAT, 0xff); /* Clear all interupts */
DRV_WriteReg8(USB_CTL, VUSB_CTL_ODD_RST); /* Disable VUSB */
DRV_WriteReg8(USB_ADDR, 0x0);
/* initialize BDT */
DRV_WriteReg8(USB_BDT_PAGE_01, 0xBD);
DRV_WriteReg8(USB_BDT_PAGE_02, 0xBD);
DRV_WriteReg8(USB_BDT_PAGE_03, 0xBD);
/* Use 64 byts FIFO for host mode*/
WRITE_EP0_BDT_ADDR(USB_BDT_RX, USB_BDT_EVEN, USB_FIFO_RX1);
WRITE_EP0_BDT_ADDR(USB_BDT_RX, USB_BDT_ODD, USB_FIFO_RX1);
WRITE_EP0_BDT_ADDR(USB_BDT_TX, USB_BDT_EVEN, USB_FIFO_TX1);
WRITE_EP0_BDT_ADDR(USB_BDT_TX, USB_BDT_ODD, USB_FIFO_TX1);
/* Set all PID as 0. Unlike device mode, the receive PID is set just before host send IN token*/
WRITE_EP0_BDT_PID(USB_BDT_RX, USB_BDT_EVEN, 0);
WRITE_EP0_BDT_PID(USB_BDT_RX, USB_BDT_ODD, 0);
WRITE_EP0_BDT_PID(USB_BDT_TX, USB_BDT_EVEN, 0);
WRITE_EP0_BDT_PID(USB_BDT_TX, USB_BDT_ODD, 0);
/* Enable the host mode */
DRV_WriteReg8(USB_CTL, VUSB_CTL_HOST_MODE_EN);
/* Typical value for 64 bytes packets is 74 so we keep enough time for
** the transaction to complete
*/
DRV_WriteReg8(USB_SOF_THLD, 0x74);
/* Enable Attach interrupt only */
DRV_WriteReg8(USB_INT_ENB, VUSB_INT_ENB_ATTACH);
/* disable Fast mode*/
if(DRV_Reg8(USB_FM_CTL)&VUSB_FM_CTL_SUCERREN)
DRV_WriteReg8(USB_FM_CTL, (DRV_Reg8(USB_FM_CTL)&(~VUSB_FM_CTL_FMENB)&(~VUSB_FM_CTL_SUCERREN)));
else
DRV_WriteReg8(USB_FM_CTL, (DRV_Reg8(USB_FM_CTL)&(~VUSB_FM_CTL_FMENB)));
/* disable phy suspend*/
DRV_WriteReg8(USB_PHY_EXTRA, 0);
}
void USB_HCD_Release_Drv(void)
{
DRV_WriteReg8(USB_INT_ENB, 0);
DRV_WriteReg8(USB_INT_STAT, 0xff);
}
/* set address for hw*/
void USB_HCD_SetAddress(kal_uint8 addr)
{
DRV_WriteReg8(USB_ADDR, addr);
}
void USB_HCD_Resume(void)
{
/* Bus control*/
USB_HCD_Bus_Control(USB_HCD_BUS_ASSERT_RESUME);
// USB_Ms_Dbg_Trace(OTG_HOST_ASSERT_RESUME, 0);
/* Add for OTG function*/
if(OTG_Get_Plug_Type()==OTG_PLUG_A)
OTG_Set_Status(OTG_STATUS_A_DETECT_B_RESUME, KAL_TRUE);
else
OTG_Set_Status(OTG_STATUS_B_DETECT_A_RESUME, KAL_TRUE);
if(g_UsbHcdInfo.resume_hdlr!=NULL)
g_UsbHcdInfo.resume_hdlr(USB_HCD_OK, 0);
}
void USB_HCD_Suspend(void)
{
}
/* GPT timeout function*/
static void USB_HCD_Reset_Recovery_Timeout(void *parameter)
{
GPTI_StopItem(g_UsbHcdInfo.gpt_handle);
/* Enable the token done, SOF and reset interrupts */
DRV_WriteReg8(USB_INT_ENB, VUSB_INT_ENB_TOKEN_DONE | VUSB_INT_ENB_RESET |
VUSB_INT_ENB_SOF | VUSB_INT_ENB_STALL|VUSB_INT_ENB_ERROR);
/* Clear all interrupt. Note that token done has 4 fifo depth */
DRV_WriteReg8(USB_INT_STAT, 0xff);
DRV_WriteReg8(USB_INT_STAT, VUSB_INT_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_INT_STAT, VUSB_INT_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_INT_STAT, VUSB_INT_STAT_TOKEN_DONE);
/* reset even odd setting*/
g_UsbHcdInfo.rx_even_odd = 0;
g_UsbHcdInfo.tx_even_odd = 0;
/* Call the callback function of there was one register for the attach
** event
*/
if(g_UsbHcdInfo.attach_hdlr==NULL)
EXT_ASSERT(0, 0, 0, 0);
g_UsbHcdInfo.attach_hdlr(g_UsbHcdInfo.reset_reason, 0);
/* unmask USB IRQ*/
g_UsbHcdInfo.b_unmask_irq = KAL_TRUE;
IRQUnmask(IRQ_USB_CODE);
}
/* GPT timeout function*/
static void USB_HCD_Reset_Timeout(void *parameter)
{
GPTI_StopItem(g_UsbHcdInfo.gpt_handle);
/* End the reset */
DRV_WriteReg8(USB_CTL, VUSB_CTL_HOST_MODE_EN);
/* Enable host mode and start generating SOFs */
DRV_WriteReg8(USB_CTL, VUSB_CTL_HOST_MODE_EN |VUSB_CTL_SOF_EN);
/* Delay for the reset recovery period */
GPTI_StartItem(g_UsbHcdInfo.gpt_handle, USB_HCD_RESET_RECOVERY_DELAY,
USB_HCD_Reset_Recovery_Timeout, &g_UsbHcdInfo);
}
/* Send reset signal to device*/
static void USB_HCD_Reset_Device(USB_HCD_STATUS reset_reason)
{
/* reset addr as 0 */
DRV_WriteReg8(USB_ADDR, 0);
/* Set the ODD/EVEN BDT to even */
DRV_WriteReg8(USB_CTL, VUSB_CTL_ODD_RST);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -