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

📄 usb_hcd.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
*  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 + -