📄 usb_hwinterface_layer.c
字号:
/*================================================================================================== Module Name: usb_hwinterface_layer.c General Description: This file contains all API's and functions of USB IP Layer . ==================================================================================================== Copyright (C) 2006, Freescale Semiconductor, Inc. All Rights Reserved THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF Freescale Semiconductor, Inc. Revision History: Modification TrackingAuthor Date Number Description of Changes------------------------- ------------ ---------- -------------------------------------------Siva Pothireddy 01/Dec/2007 engcm02041 Removed an invalid register write at offset 0x90.Mahima Verma 11/Sep/2007 TLSbo96294 Configure the USB to work in BURSTSIZE=UNSPECIFIED.Mahima Verma 13/Sep/2007 TLSbo96384 USB Enumeration fails for Device address set above 63. Mahima Verma 20/Aug/2007 TLSbo95872 Endianess change .Mahima Verma 19/Jul/2007 TLSbo94597 Changes in USB to support simulator testing.Mahima Verma 11/Jun/2007 TLSbo93857 Porting to Marley.Suresh Kumar 18/Oct/2006 TLSbo80774 Ported to Zappa.Bharat Bhushan 24-Aug-2006 TLSbo76463 Porting to SKYE+ .Bharat Bhushan 08/04/2006 TLSbo74988 Changes for handling setup commands after enumeration.Bharat Bhushan 04/08/2006 TLSbo74877 Maximum Packet Size changed from 0x08 to 0x40 for EP0Bharat Bhushan 05/10/2006 TLSbo68884 Initial Version ( USB Layer Architecture).------------------------- ------------ ---------- ------------------------------------------- Portability: Portable.==================================================================================================== INCLUDE FILES==================================================================================================*/#include <suapi.h>#include <usb_common.h>#include <usb_hwinterface_layer.h>#include <usb_ipl_tl_extern.h>#include <usb_ipl_al_extern.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_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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -