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

📄 usb_hwinterface_layer.c

📁 freescale atk source code
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* varify Endpoint Number and address */     if((endptno == EP0) ||(( endptno == g_out_endpoint) && ( bd->buffer != NULL)))    {        /* Get Device Device Queue Head of the requested endpoint */        dqh_address = ipl_get_dqh(endptno,OUT);        	/* Get Device Transfer Descriptor of the requested endpoint */        dtd_address = ipl_get_dtd(endptno,OUT);        switch (endptno)        {	    case EP0 :        		/* Get the total bytes to be received	*/		total_bytes = bd->size; 			        td.dtd_base		= dtd_address;	    	td.next_link_ptr	= dtd_address + 0x20;	       	td.terminate 		= TERMINATE;	      	td.total_bytes		= total_bytes;	       	td.ioc			= IOC_SET;	       	td.status		= ACTIVE;	       	td.buffer_ptr0		= g_buffer_map.ep0_buffer_addrs;	       	td.current_offset	= (g_buffer_map.ep0_buffer_addrs & 0xFFF);	       	td.buffer_ptr1		= 0;	       	td.buffer_ptr2		= 0;	       	td.buffer_ptr3		= 0;	       	td.buffer_ptr4		= 0;				/* Set the Transfer Descriptor	*/		ipl_setup_transfer_desc(&td);		/* 1. write dQH next ptr and dQH terminate bit to 0 */		*(VP_U32)(dqh_address+0x8)= dtd_address;	    		/* 2. clear active & halt bit in dQH */		*(VP_U32)(dqh_address+0xC) &= ~0xFF;	    		/* 3. prime endpoint by writing '1' in ENDPTPRIME */		*(VP_U32)USB_OTG_ENDPTPRIME |= (  EPOUT_PRIME << endptno );#ifndef SIMULATOR_TESTING		/* 4. Wait for the Complete Status */ 		while (!((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & ( EPOUT_COMPLETE << endptno)));	    		/*clear the complete status */		(*(VP_U32)USB_OTG_ENDPTCOMPLETE) = (EPOUT_COMPLETE << endptno);#endif	   		status = USB_SUCCESS;		break;	    	    default :                 if ((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & ( EPOUT_COMPLETE << endptno))                {		    /*clear the complete status */		    (*(VP_U32)USB_OTG_ENDPTCOMPLETE) = (EPOUT_COMPLETE << endptno);    	       	            /* get the address of the buffer in which data is received */			    received_buffer_addrs = get_rxd_buffer();		    if( received_buffer_addrs == NULL)		    {                        status = USB_INVALID;		        break;		    }		    buffer_ptr = (U32 *)received_buffer_addrs;		    /* calculate the received data length using number of bytes left in TD */		    temp =  (U32 *)dtd_address;		    temp++; /* pointer to total bytes in dtd */		    received_data_length = (BULK_BUFFER_SIZE - (((*temp) >> 16 )&0x7FFF));		    /* get the dTD buffer pointer */	            buffer_addrs_page0 = alloc_buffer();				    if( buffer_addrs_page0 == NULL)		    {                        status = USB_INVALID;		        break;		    }       	            /* Get the total bytes to be received	*/		    total_bytes = BULK_BUFFER_SIZE; 	                       /* OUT setup dTD */		    td.dtd_base 		= dtd_address;  		    td.next_link_ptr  	= dtd_address + 0x20;		    td.terminate 		= TERMINATE;		    td.total_bytes  	= total_bytes;	       	    td.ioc 			= IOC_SET;	       	    td.status 		= ACTIVE;	       	    td.buffer_ptr0  	= buffer_addrs_page0; 	       	    td.current_offset 	= ( buffer_addrs_page0 & 0xFFF ); 	       	    td.buffer_ptr1  	= 0x0;		    td.buffer_ptr2 		= 0x0;	       	    td.buffer_ptr3  	= 0x0;		    td.buffer_ptr4  	= 0x0;            		    /* Set the Transfer Descriptor	*/		    ipl_setup_transfer_desc(&td);		    /* 1. write dQH next ptr and dQH terminate bit to 0 */		    *(VP_U32)(dqh_address+0x8)= dtd_address;	    	    	    /* 2. clear active & halt bit in dQH */		    *(VP_U32)(dqh_address+0xC) &= ~0xFF;	    		    /* 3. prime endpoint by writing '1' in ENDPTPRIME */		    *(VP_U32)USB_OTG_ENDPTPRIME |= (  EPOUT_PRIME << endptno );				    /* Copy the data from buffer to destionation pointed by buffer descriptor */		    destination_ptr = ( U8 *)( bd->buffer);                    if(received_data_length < bd->size)		    {			        data_size = received_data_length ;	            }		    else		    {	                data_size = bd->size;		    }		    copy_from_buffer(buffer_ptr,destination_ptr,data_size);		    /* free the buffer after copying the data */		    free_buffer(received_buffer_addrs);		    /* update the total bytes received in buffer descriptor */		    bd->bytes_transfered = data_size ;		    status = USB_SUCCESS;	        }                else                {                     /* Endpoint Not complete is taken as 0 length data received and SUCCESS case */		    /* update the total bytes received in buffer descriptor */		    bd->bytes_transfered = 0x0 ;		    status = USB_SUCCESS;                }	                        break; 	}    }    else    {        status = USB_INVALID ;    }    return status;}/*==================================================================================================FUNCTION: ipl_receive_setup_dataDESCRIPTION: 	This function receive setupdata from host . ARGUMENTS PASSED:	BufferDesc - This is the pointer to the buffer descriptor. Caller provides storage for the 	             buffer and the data,		RETURN VALUE:	USB_SUCCESS - 	: The buffer was successfully processed by the USB device and 			  data is received from the host.	USB_FAILURE - 	: Some failure occurred in receiving the data.	USB_INVALID -: If the endpoint is invalid.	IMPORTANT NOTES:	None		==================================================================================================*/usb_status_tipl_receive_setup_data(usb_buffer_descriptor_t* bd){    volatile struct dqh_setup_t * dqh_word ;    U32 dqh_address;    usb_status_t status = USB_FAILURE;    U32 temp;    /* varify that the address passed is not NULL */    if( bd->buffer != NULL )    {        /* Get the Device Queue Head Address for EP0 OUT   */         dqh_address = ipl_get_dqh(EP0,OUT);        dqh_word = (volatile struct dqh_setup_t*)dqh_address;    	/* write '1' to clear corresponding bit in ENDPTSETUPSTAT */	*(VP_U32)USB_OTG_ENDPTSETUPSTAT = BIT0;	    		do         {	    /* write '1' to Setup Tripwire (SUTW) in USBCMD register */	    *(VP_U32)USB_OTG_USBCMD |= BIT13;			    /* Copy the SetupBuffer into local software byte array */	    temp  = (dqh_word->dqh_word10);/* This is due to the simulator bug for word variant access on EMI but actually design has word invariant access */                  *((U8 *)(bd->buffer)) = (U8 )(temp & 0x000000FF);            (bd->buffer) =(U8 *)(bd->buffer) + 1;            *((U8 *)(bd->buffer)) = (U8 )((temp & 0x0000FF00)>>8);            (bd->buffer) =(U8 *)(bd->buffer) + 1;            *((U8 *)(bd->buffer)) = (U8 )((temp & 0x00FF0000)>>16);            (bd->buffer) =(U8 *)(bd->buffer) + 1;            *((U8 *)(bd->buffer)) = (U8 )((temp & 0xFF000000)>>24);            (bd->buffer) =(U8 *)(bd->buffer) + 1;	              temp  = (dqh_word->dqh_word11);            *((U8 *)(bd->buffer)) = (U8 )(temp & 0x000000FF);            (bd->buffer) =(U8 *)(bd->buffer) + 1;            *((U8 *)(bd->buffer)) = (U8 )((temp & 0x0000FF00)>>8);            (bd->buffer) =(U8 *)(bd->buffer) + 1;            *((U8 *)(bd->buffer)) = (U8 )((temp & 0x00FF0000)>>16);            (bd->buffer) =(U8 *)(bd->buffer) + 1;            *((U8 *)(bd->buffer)) = (U8 )((temp & 0xFF000000)>>24);            (bd->buffer) =(U8 *)(bd->buffer) + 1;	}while (!(*(VP_U32)USB_OTG_USBCMD & BIT13));		        /* Write '0' to clear SUTW in USBCMD register */        *(VP_U32)USB_OTG_USBCMD &= ~BIT13;	        status = USB_SUCCESS;    }    else    {        status = USB_INVALID;    }    return status;}/*==================================================================================================FUNCTION: ipl_get_ep0_rxtx_bufferDESCRIPTION:    	This function returns the buffer address for EP0ARGUMENTS PASSED:	None  RETURN VALUE:	None	IMPORTANT NOTES:	None		==================================================================================================*/U32 ipl_get_ep0_rxtx_buffer(){    return (g_buffer_map.ep0_buffer_addrs) ;}/*==================================================================================================FUNCTION: ipl_setup_transfer_descDESCRIPTION:    	This function is used to setup the dTDARGUMENTS PASSED:	U32 dtd_base - Base Address of the dTD	U32 next_link_ptr - Next Link Pointer, 	U8 	terminate - terminate - TERMINATE; not terminate - NOT_TERMINATE	U16 total_bytes - Total Bytes to be transfered in this dQH	U8 	ioc - interrupt on complete, set - IOC_SET, not set - IOC_NOTSET	U8 	Status - Status 	U32 buffer_ptr0 - Buffer Pointer page 0	U16 current_offset - current offset	U32 buffer_ptr1 - Buffer Pointer page 1	U32 buffer_ptr2 - Buffer Pointer page 1	U32 buffer_ptr3 - Buffer Pointer page 1	U32 buffer_ptr4 - Buffer Pointer page 1	  RETURN VALUE:	None		IMPORTANT NOTES:	None		==================================================================================================*/void ipl_setup_transfer_desc(struct dtd_t* td){    volatile struct dtd_setup_t* dtd_word = (volatile struct dtd_setup_t *) td->dtd_base;    /* Bit31:5 Next Link Pointer ; Bit0 terminate */    dtd_word->dtd_word0 = ((td->next_link_ptr & 0xFFFFFFE0) | td->terminate);    /* Bit30:16 total_bytes, Bit15 ioc, Bit7:0 status */    dtd_word->dtd_word1 = ((((U32)td->total_bytes & 0x7FFF) << 16)| ((U32)td->ioc <<15) | (td->status));	    /* Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset */    dtd_word->dtd_word2 = ((td->buffer_ptr0 & 0xFFFFF000) | (td->current_offset & 0xFFF));	    /* Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number */    dtd_word->dtd_word3 = (td->buffer_ptr1 & 0xFFFFF000);    /* Bit31:12 Buffer Pointer Page 2 ; */    dtd_word->dtd_word4 = (td->buffer_ptr2 & 0xFFFFF000);    /* Bit31:12 Buffer Pointer Page 3 ; */    dtd_word->dtd_word5 = (td->buffer_ptr3 & 0xFFFFF000);    /* Bit31:12 Buffer Pointer Page 4 ; */    dtd_word->dtd_word6 = (td->buffer_ptr4 & 0xFFFFF000);}/*==================================================================================================FUNCTION: ipl_device_only_modeDESCRIPTION:    	This function is used to configure the USB OTG port to Device only modeARGUMENTS PASSED:	None	  RETURN VALUE:	None		IMPORTANT NOTES:	None		==================================================================================================*/void ipl_device_only_mode(void){    /* Set to Device only mode */    /* *(VP_U32)USB_OTG_MIRROR_REG |= 0x1; */#ifndef SIMULATOR_TESTING    /* Reset */    *(VP_U32)USB_OTG_USBCMD |= BIT1;    /* wait for the Reset complete */    while (*(VP_U32)USB_OTG_USBCMD & BIT1);#endif    /* set to device controller */    *(VP_U32)USB_OTG_USBMODE = 0x2;    /* check that device controller was configured to device mode only */    while (!(*(VP_U32)USB_OTG_USBMODE == 0x2));}/*==================================================================================================FUNCTION: ipl_clear_dqhDESCRIPTION:    	This function is used to Clear the DQH before initiateARGUMENTS PASSED:	None	  RETURN VALUE:	None		IMPORTANT NOTES:	None		==================================================================================================*/void ipl_clear_dqh(void){    U8 i = 0;    VP_U32 ep_q_hdr_base;    ep_q_hdr_base = ((VP_U32)g_buffer_map.ep_dqh_base_addrs);    /* Clear the dQH Memory */    for ( i = 0; i < (SIZE_OF_QHD*g_max_ep_supported*2)/sizeof(U32) ; i++)    {        *ep_q_hdr_base++ = 0;    }}/*==================================================================================================FUNCTION: ipl_setup_qheadDESCRIPTION:    	This function is used to setup the dQH	 ------------------------	|	EP2 IN	(64 bytes)	 |			|				 |	 ------------------------	dQH5	|	EP2 OUT	(64 bytes)	 |		| 			 	 |	 ------------------------	dQH4	|	EP1 IN	(64 bytes)	 |	| 				 |	 ------------------------	dQH3	|	EP1 OUT	(64 bytes)	 |	| 				 |	 ------------------------ 	dQH2	|	EP0 IN	(64 bytes)	 |	| 				 |	 ------------------------	dQH1	|	EP0 OUT	(64 bytes)	 |

⌨️ 快捷键说明

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