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

📄 usb_hwinterface_layer.c

📁 freescale atk source code
💻 C
📖 第 1 页 / 共 3 页
字号:
	       	buffer_addrs_page0 = alloc_buffer();				/* 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 << endpt_num );				/* Endpoint Configured for output */		g_out_endpoint= endpt_num;	    }	else	    {                total_bytes = 0x4 ;				qhead.dqh_base		= ipl_get_dqh(endpt_num,direction);		qhead.zlt 		= ZLT_DISABLE;		qhead.mps 		= config_data->max_pkt_size;		qhead.ios 		= IOS_SET;		qhead.next_link_ptr 	= ipl_get_dtd(endpt_num,direction);	        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 Configured for Input */	    	g_in_endpoint= endpt_num;    		/* Endpoint 2: MPS = 64, IN (Tx endpoint) */	     	*(VP_U32)(USB_OTG_ENDPTCTRL0 + (0x4*endpt_num)) = 0x00480008;		/* Enable EP2 IN */		*(VP_U32)(USB_OTG_ENDPTCTRL0 + (0x4*endpt_num)) |= EPIN_ENABLE;    		/* 3. prime endpoint by writing '1' in ENDPTPRIME */#ifndef SIMULATOR_TESTING		*(VP_U32)USB_OTG_ENDPTPRIME |= (EPIN_PRIME << g_in_endpoint);#endif	    }    }    else     {        /* error handling TBD */    }    }/*==================================================================================================FUNCTION: ipl_send_data DESCRIPTION:    	This function Send Data on the USB channel.ARGUMENTS PASSED: 	 U8 endptno			: Endpoint number on which data it to be send.	 usb_buffer_descriptor_t *bd 	: This is the pointer to the buffer descriptor. 	 BOOL zlt			: Boolean to decide whether Zero Length Packet is to					  be send or notRETURN VALUE:	USB_SUCCESS - The buffer was successfully processed by the USB device and data sent to the Host.	USB_FAILURE - Some failure occurred in transmitting the data.		IMPORTANT NOTES:	None		==================================================================================================*/usb_status_tipl_send_data(U8 endptno , usb_buffer_descriptor_t* bd,BOOL zlt){    struct dtd_t td;    U32 total_bytes ;    U32 dtd_address,dqh_address;    U32 buffer_addrs_page0;    U8* buffer_src_ptr = 0x0;    U32* buffer_dest_ptr = 0x0;    U32 size = 0x0;    usb_status_t status = USB_SUCCESS;       /* varify Endpoint Number and address */     if((endptno == EP0) ||(( endptno == g_in_endpoint) && ( bd->buffer != NULL)))    {        /* Get Device Transfer Descriptor of the requested endpoint */        dtd_address = ipl_get_dtd(endptno,IN);            /* Get Device Queue head of the requested endpoint */        dqh_address = ipl_get_dqh(endptno,IN);        /* Get Total Bytes to Be recieved */        total_bytes = bd->size;        switch(endptno)        {            case EP0 :	        td.dtd_base 		= dtd_address; 		td.next_link_ptr  	= 0;		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);	   	       	/* Enable ZLT when data size is in multiple of Maximum Packet Size  */		if(zlt)	       	{                    /* set ZLT enable */		    (*(VP_U32)(dqh_address)) &= ~0x20000000;	       	}	    		/* 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 |= BIT16;    	    		/* wait for complete set and clear */		while (!((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & EPIN_COMPLETE));			*(VP_U32)USB_OTG_ENDPTCOMPLETE = EPIN_COMPLETE;			status = USB_SUCCESS;                                break;		    default :            		/* allocate memory for data transfer */	       	buffer_addrs_page0 = alloc_buffer();	       	buffer_dest_ptr = (U32 *)buffer_addrs_page0 ;	   		/* Get the source data pointer */		buffer_src_ptr =(U8 *) bd->buffer;	    	       	if(buffer_addrs_page0 != NULL)	       	{		    while(total_bytes)		    {                        if(total_bytes < BULK_BUFFER_SIZE )		        {		            size = total_bytes;		        }		        else		        {		            size = BULK_BUFFER_SIZE;		        }		    			/* copy the data to the allocated buffer */    			copy_to_buffer(buffer_src_ptr,buffer_dest_ptr,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  	= buffer_addrs_page0;    			td.current_offset 	= (buffer_addrs_page0 & 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 = ( EPIN_PRIME << endptno);    			/* wait for complete set and clear */    			while (!((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & (EPIN_COMPLETE<<endptno)));    			*(VP_U32)USB_OTG_ENDPTCOMPLETE = ( EPIN_COMPLETE << endptno);    			total_bytes -= size;    			buffer_src_ptr += size;	    	    }	    	    	    /* Free the allocated buffer as transmitt is complete */	    	    free_buffer(buffer_addrs_page0);	    	    status = USB_SUCCESS;			}		else 		{			/* Return Error - TBD */		}	}    }    else    {        status = USB_INVALID ;    }    return status;}/*==================================================================================================FUNCTION: ipl_receive_dataDESCRIPTION:    	This function Handle the Status Token (IN/OUT) from USB HostARGUMENTS PASSED: 	 U8 endptno			: Endpoint number on which data it to be send.	 usb_buffer_descriptor_t *bd 	: This is the pointer to the buffer descriptor.   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_data(U8 endptno, usb_buffer_descriptor_t* bd){    struct dtd_t td;    usb_status_t status = USB_FAILURE;    U32 total_bytes;    U32 dtd_address;    U32 dqh_address;    U32 received_buffer_addrs = 0x0;    U32* buffer_ptr = 0x0;    U32 received_data_length = 0x0;    U32 data_size = 0x0;    U8* destination_ptr = 0x0;    U32* temp = 0x0;        U32 buffer_addrs_page0;    /* 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;#ifndef SIMULATOR_TESTING	    		    /* 3. prime endpoint by writing '1' in ENDPTPRIME */		    *(VP_U32)USB_OTG_ENDPTPRIME |= (  EPOUT_PRIME << endptno );#endif			    /* 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);	  //  printf("dqh_word->dqh_word10:0x%x\n", temp);                *((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);         // printf("dqh_word->dqh_word11:0x%x\n", temp);            *((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: 

⌨️ 快捷键说明

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