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

📄 usb_hwinterface_layer.c

📁 freescale atk source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/*==================================================================================================                                                                                   Module Name:  usb_hwinterface_layer.c    General Description: This file contains all API's and functions of USB IP Layer .  ====================================================================================================Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.This file contains copyrighted material. Use of this file isrestricted by the provisions of a Freescale Software LicenseAgreement, which has either been electronically accepted byyou or has been expressly executed between the parties.  Revision History:====================================================================================================                                        INCLUDE FILES==================================================================================================*/#include "su_basictypes.h"#include <usb_common.h>#include <usb_hwinterface_layer.h>#include <usb_ipl_tl_extern.h>#include <usb_ipl_al_extern.h>#include <usb_global.h>/*==================================================================================================                                     GLOBAL VARIABLES==================================================================================================*//*==================================================================================================                                     LOCAL CONSTANTS==================================================================================================*//*=================================================================================================                                 LOCAL FUNCTION PROTOTYPES==================================================================================================*/static void ipl_clear_dqh(void);static void ipl_setup_qhead(struct dqh_t* );static void ipl_setup_transfer_desc(struct dtd_t* );static void ipl_device_only_mode(void);static U32  ipl_get_dqh(U8, U8);static U32 ipl_get_dtd(U8, U8 ) ;static void copy_to_buffer(U8* , U32* , U32 );static void copy_from_buffer(U32*, U8*, U32);static U32 get_rxd_buffer(void);static void free_buffer(U32 );static U32 alloc_buffer(void);static void ipl_init_hw(void);/*==================================================================================================                                      LOCAL VARIABLES==================================================================================================*/static U32 g_buffer_address_base; /* Base address of the buffer allocated to IP Layer */static U32 g_buffer_length;	/* length of the buffer */static buffer_map_t g_buffer_map; /* Buffer information used for data transfer */static U8  g_in_endpoint;         /* Number of Endpoint configured as IN */static U8  g_out_endpoint;        /* Number of Endpoint configured as OUT*/static U8  g_max_ep_supported;   /* Number of Endpoints configured in system *//*==================================================================================================                                        LOCAL MACROS==================================================================================================*//*==================================================================================================                                     LOCAL FUNCTIONS==================================================================================================*//*==================================================================================================FUNCTION: ipl_init_hwDESCRIPTION:    	This Function Initialise the USB Core .	ARGUMENTS PASSED:	None  RETURN VALUE:	None	IMPORTANT NOTES:	None		==================================================================================================*/void ipl_init_hw(void){    struct dqh_t qhead;    U32 total_bytes;	    /* Init to Device mode only */    ipl_device_only_mode();	    /* Clear the dQH before initialized */    ipl_clear_dqh();	    /******************************************************************************    / =================    / dQH0 for EP0OUT    / =================    / Initialize device queue heads in system memory    / 8 bytes for the 1st setup packet */           total_bytes 	= 0x8;    qhead.dqh_base 	= ipl_get_dqh(EP0,OUT);    qhead.zlt 		= ZLT_DISABLE;    qhead.mps 		= MPS_64;    qhead.ios 		= IOS_SET;    qhead.next_link_ptr = ipl_get_dtd(EP0,OUT);    qhead.terminate 	= NOT_TERMINATE;    qhead.total_bytes  	= total_bytes;    qhead.ioc 		= IOC_SET;    qhead.status 	= NO_STATUS;    qhead.buffer_ptr0  	= 0;    qhead.current_offset = 0;    qhead.buffer_ptr1  	= 0;    qhead.buffer_ptr2 	= 0;    qhead.buffer_ptr3  	= 0;    qhead.buffer_ptr4 	= 0;    /* Set Device Queue Head */    ipl_setup_qhead(&qhead);    /* ==================    END of dQH0 setup    ====================*/        /*=================    dQH1 for EP0IN    ================= */    total_bytes 	= 0x8;    qhead.dqh_base 	= ipl_get_dqh(EP0,IN);    qhead.zlt 		= ZLT_DISABLE;    qhead.mps 		= MPS_64;    qhead.ios 		= IOS_SET;    qhead.next_link_ptr = ipl_get_dtd(EP0,IN);    qhead.terminate 	= TERMINATE;    qhead.total_bytes  	= total_bytes;    qhead.ioc 		= IOC_SET;    qhead.status 	= NO_STATUS;    qhead.buffer_ptr0  	= g_buffer_map.ep0_buffer_addrs;    qhead.current_offset = (g_buffer_map.ep0_buffer_addrs & 0xFFF);    qhead.buffer_ptr1  	= 0;    qhead.buffer_ptr2 	= 0;    qhead.buffer_ptr3  	= 0;    qhead.buffer_ptr4 	= 0;    /* Set Device Queue Head */    ipl_setup_qhead(&qhead);    /* ==================    /  END of dQH1 setup    /  ================*/        /* Configure ENDPOINTLISTADDR Pointer */    *(VP_U32)USB_OTG_ENDPOINTLISTADDR = g_buffer_map.ep_dqh_base_addrs;    /* Set OTG termination, controls the pulldown on DM */    *(VP_U32)USB_OTG_OTGSC |= BIT3;    /* Disable Setup Lockout by writing '1' to SLOM in USBMODE */    *(VP_U32)USB_OTG_USBMODE |= BIT3;    /* Set Run/Stop bit to Run Mode */    *(VP_U32)USB_OTG_USBCMD |= BIT0;}/*==================================================================================================FUNCTION: ipl_initDESCRIPTION:    	This function does the IP Layer InitialisationARGUMENTS PASSED: 	usb_plat_config_data_t* config_data_ptrRETURN VALUE:	None	IMPORTANT NOTES:	        There are two buffers each of size 0x200 ( 512 ) will be used for bulk data       	transfer. So total 0x400(1k) will be used for bulk data transfer and this will be the 	last 1k of the allocated buffer.       	There is 0x40 ( 64 ) size of the buffer will be used for data transfer over control 	endpoint ( EP0 )	Rest of the buffer area will be used for endpoint data  structires ( device qhead and 	device transfer descriptor ). ==================================================================================================*/voidipl_init(usb_plat_config_data_t* config_data_ptr){    U32 temp;        /* Base address of the buffer allocated to IP Layer */    g_buffer_address_base =  config_data_ptr->buffer_address;        /* length of the buffer */    g_buffer_length = config_data_ptr->buffer_size;	        /* Maximum Number of EPs to be confiured */    g_max_ep_supported = (( g_buffer_length - TOTAL_DATA_BUFFER_SIZE)/(BUFFER_USED_PER_EP));        /* Base of queue Head Pointer */    g_buffer_map.ep_dqh_base_addrs = g_buffer_address_base;         /* Total size of qhead */    temp = (SIZE_OF_QHD * (g_max_ep_supported * 2));    /* Base Address of device transfer descriptor */    g_buffer_map.ep_dtd_base_addrs = (g_buffer_map.ep_dqh_base_addrs + temp);      /* Total size of transfer descriptor */     temp =  ((dTD_SIZE_EPIN * g_max_ep_supported) + (dTD_SIZE_EPOUT * g_max_ep_supported ));         /* Base Address of EP0 Buffer */    g_buffer_map.ep0_buffer_addrs = (g_buffer_map.ep_dtd_base_addrs + temp  );        /* transfer buffer 1 */    g_buffer_map.buffer1_address=(g_buffer_address_base + g_buffer_length -(BULK_BUFFER_SIZE*NUM_OF_BULK_BUFFER));    g_buffer_map.buffer1_status = BUFFER_FREE;    /* transfer buffer 2 */    g_buffer_map.buffer2_address = g_buffer_map.buffer1_address + BULK_BUFFER_SIZE;    g_buffer_map.buffer2_status = BUFFER_FREE;        ipl_init_hw();}/*==================================================================================================FUNCTION: ipl_check_bus_resetDESCRIPTION:    	This function check if reset event is received on USB bus.ARGUMENTS PASSED:	None  RETURN VALUE:	BOOL 	status 	TRUE	If reset received.			FALSE	If reset not received.	IMPORTANT NOTES:	None		==================================================================================================*/BOOLipl_check_bus_reset(void){    BOOL status=FALSE;    if ((*(VP_U32)USB_OTG_USBSTS) & BIT6)    {	status=TRUE;    }return status;}/*==================================================================================================FUNCTION:  ipl_check_setup_tokenDESCRIPTION: 	This function check if Setup Token is received on USB bus.ARGUMENTS PASSED:	None  RETURN VALUE:	U8 	status 	TRUE	If Setup Token received.			FALSE	If Setup Token not received.	IMPORTANT NOTES:	None==================================================================================================*/BOOLipl_check_setup_token(void){    BOOL status =  FALSE;    if ((*(VP_U32)USB_OTG_ENDPTSETUPSTAT) & BIT0)    {        status= TRUE;    }return status;}/*==================================================================================================FUNCTION: ipl_is_interface_high_speedDESCRIPTION: 	This function return the speed at which the selected interface working.ARGUMENTS PASSED:	None  RETURN VALUE:	U8 	interface_speed 	0	If interface is working at FS. 	 	 			1	If interface is working at HS.	IMPORTANT NOTES:	Note : Low Speed is not supported.==================================================================================================*/BOOLipl_is_interface_high_speed(void){    BOOL speed = FALSE; /* Full Speed by default */#ifndef SIMULATOR_TESTING    while(!((*(VP_U32)USB_OTG_USBSTS) & USB_OTG_PORT_OPERATIONAL ));#endif    if(((*(VP_U32)USB_OTG_PORTSC1) & USB_OTG_INF_SPEED_MASK) == USB_OTG_INF_SPEED_HS)    {        speed = TRUE;    }return speed;}/*==================================================================================================FUNCTION: ipl_handle_bus_resetDESCRIPTION:    	This function Handle the reset event from USB HostARGUMENTS PASSED:	None  RETURN VALUE:	None	IMPORTANT NOTES:	None		==================================================================================================*/voidipl_handle_bus_reset(void){    U32 temp,total_bytes;    struct dqh_t qhead;	    *(VP_U32)USB_OTG_USBCMD &= ~BIT0;    (*(VP_U32)USB_OTG_USBSTS) &= BIT6;	    /*Reading and writing back the ENDPTSETUPSTAT register      clears the setup token semaphores */    temp = (*(VP_U32)USB_OTG_ENDPTSETUPSTAT);    (*(VP_U32)USB_OTG_ENDPTSETUPSTAT) = temp;    /*Reading and writing back the ENDPTCOMPLETE register      clears the endpoint complete status bits */    temp = (*(VP_U32)USB_OTG_ENDPTCOMPLETE);     (*(VP_U32)USB_OTG_ENDPTCOMPLETE) = temp;    while((*(VP_U32)USB_OTG_ENDPTPRIME));	    (*(VP_U32)USB_OTG_ENDPTFLUSH) = 0xFFFFFFFF;	    ipl_clear_dqh();	    /* Initialize device queue heads in system memory for EP0OUT */    total_bytes = 0x8;        qhead.dqh_base	= ipl_get_dqh(EP0,OUT);    qhead.zlt		= ZLT_DISABLE;    qhead.mps		= MPS_64;    qhead.ios		= IOS_SET;    qhead.next_link_ptr	= 0;        qhead.terminate 	= TERMINATE;    qhead.total_bytes	= total_bytes;    qhead.ioc		= IOC_SET;    qhead.status 	= NO_STATUS;    qhead.buffer_ptr0	= 0;    qhead.current_offset = 0;    qhead.buffer_ptr1	= 0;    qhead.buffer_ptr2	= 0;    qhead.buffer_ptr3	= 0;    qhead.buffer_ptr4	= 0;	    ipl_setup_qhead(&qhead);    /* Initialize device queue heads in system memory for EP0IN */    qhead.dqh_base 	= ipl_get_dqh(EP0,IN);    qhead.zlt 		= ZLT_DISABLE;    qhead.mps 		= MPS_64;    qhead.ios 		= IOS_SET;    qhead.next_link_ptr  	= 0;        qhead.terminate 	= TERMINATE;    qhead.total_bytes  	= 0;     qhead.ioc 		= IOC_SET;    qhead.status 	= NO_STATUS;    qhead.buffer_ptr0  	= 0;       qhead.current_offset = 0;       qhead.buffer_ptr1  	= 0;    qhead.buffer_ptr2 	= 0;    qhead.buffer_ptr3  	= 0;    qhead.buffer_ptr4      = 0;    ipl_setup_qhead(&qhead);	    *(VP_U32)USB_OTG_ENDPOINTLISTADDR = g_buffer_map.ep_dqh_base_addrs; 	    *(VP_U32)USB_OTG_USBCMD |= BIT0;}/*==================================================================================================FUNCTION: ipl_set_device_addressDESCRIPTION:    	This function set the Device AddressARGUMENTS PASSED:	U8 Address	: Address of Device to be Set.  RETURN VALUE:	None	IMPORTANT NOTES:	None		==================================================================================================*/voidipl_set_device_address(U16 Address){    /* set the USB Device address */    *(VP_U32)USB_OTG_DEVICEADDR = ((U32)Address & 0x7F) << 25;}/*==================================================================================================FUNCTION: ipl_send_stall_handshakeDESCRIPTION:    	This function Send/Receive the STALL HANDSHAKE to  USB HostARGUMENTS PASSED:	U8 endpoint  -	Endpoint Number .		U8 direction -	IN/OUT :  direction of EndPoint.  RETURN VALUE:	None	IMPORTANT NOTES:	None		==================================================================================================*/voidipl_send_stall_handshake(U8 endpoint , U8 direction){    if( direction == OUT )    {     *(VP_U32)( USB_OTG_ENDPTCTRL0 + (4*endpoint) ) |= STALL_RX;    }		        else     {    *(VP_U32)( USB_OTG_ENDPTCTRL0 + (4*endpoint) ) |= STALL_TX;    }}/*==================================================================================================FUNCTION: ipl_set_configurationDESCRIPTION:    	This function Handle the SET CONFIGRATION Request.ARGUMENTS PASSED: 	 usb_end_pt_info_t* config_data;RETURN VALUE:	None	IMPORTANT NOTES:	None		==================================================================================================*/voidipl_set_configuration(usb_end_pt_info_t* config_data){    struct dtd_t td;    U32 total_bytes = 0x0;    U32 buffer_addrs_page0 = 0;    U32 dqh_address = 0;    U32 dtd_address = 0;    U8  endpt_num,direction;        struct dqh_t qhead;       /* get endpoint number to be configured and its direction */    endpt_num= config_data->end_pt_no;     direction= config_data->direction;        /* Check if the endpoint number and direction is withing the permitted range or not */    if (( endpt_num != EP0 ) && (endpt_num <= ( g_max_ep_supported - 1)) && 		    ( direction == OUT || direction == IN))    {	/* get the device q head and deice TD */	dqh_address = ipl_get_dqh(endpt_num,direction);         dtd_address = ipl_get_dtd(endpt_num,direction);        if ( direction ==  OUT )	    {                total_bytes = BULK_BUFFER_SIZE ;				qhead.dqh_base		= dqh_address;		qhead.zlt 		= ZLT_DISABLE;		qhead.mps 		= config_data->max_pkt_size;		qhead.ios 		= IOS_SET;		qhead.next_link_ptr 	= dtd_address ;	        qhead.terminate 	= TERMINATE;		qhead.total_bytes	= total_bytes;		qhead.ioc 		= IOC_SET;		qhead.status 		= NO_STATUS;		qhead.buffer_ptr0	= 0;		qhead.current_offset	= 0;		qhead.buffer_ptr1	= 0;		qhead.buffer_ptr2 	= 0;		qhead.buffer_ptr3	= 0;		qhead.buffer_ptr4 	= 0;		ipl_setup_qhead(&qhead);				/* Endpoint 1 : MPS = 64, OUT (Rx endpoint) */		*(VP_U32)(USB_OTG_ENDPTCTRL0 + (0x4*endpt_num))= 0x00080048;	   		/* Enable EP1 OUT */		*(VP_U32)(USB_OTG_ENDPTCTRL0 + ( 0x4 * endpt_num)) |= EPOUT_ENABLE;   	        /* allocate buffer for receiving data */	

⌨️ 快捷键说明

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