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

📄 usb.c

📁 Freescale ColdFire MCF537x 家族的参考代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  		case MCF_USB_PORTSC_PSPD_HIGH:	  		printf("Connected at high-speed\n");		    break;	  	default:	  		printf("Invalid port speed\n");		    break;		}    	printf("PORTSC = 0x%08x\n",MCF_USB_PORTSC(port));		    #endif	return speed;    }/********************************************************************//* * Disable the asynchronous and periodic lists. * * Parameters: *  port      USB module to send reset */void disable_async_per_schedules(int port){	/* Disable the asynchronous schedule */		MCF_USB_USBCMD(port) &= ~MCF_USB_USBCMD_ASE;		/* Wait for asynchronous enable bit to clear */	while (MCF_USB_USBCMD(port) & MCF_USB_USBCMD_ASE);	/* Disable the periodic schedule schedule */		MCF_USB_USBCMD(port) &= ~MCF_USB_USBCMD_PSE;		/* Wait for periodic schedule enable bit to clear */	while (MCF_USB_USBCMD(port) & MCF_USB_USBCMD_PSE);}/********************************************************************//* * Function to send an IN packet to the host while in USB device mode. * * Parameters: *  eplistaddr	pointer to the device endpoint list *  epnum		endpoint number to use *  buf     	data to be sent to host *  size		amount of data to be transferred in bytes */void usb_device_send_control_packet(uint32 eplistaddr, uint32 epnum, uint8* buf, uint32 size){	int port = USB_OTG;	USB_DTD * usb_dtd1, * usb_dtd2;	uint8 * recv_buf[MAX_USB_DESC_SIZE];	/* Initialize dTD to send device descriptor */	usb_dtd1 = usb_dtd_init(size, 0, 0, (uint32*) buf);		/* Point the endpoint IN QH to the dTD */	((USB_EP_QH*)(eplistaddr + EP_QH_IN(epnum)))->next_dtd = (uint32)usb_dtd1;        /* Prime Tx buffer for control endpoint */    MCF_USB_EPPRIME(port) |= MCF_USB_EPPRIME_PETB(1<<epnum);        /* Wait for prime to complete *///    while (MCF_USB_EPPRIME(port) & MCF_USB_EPPRIME_PETB(1<<epnum));    	/* Initialize dTD for receive. The host won't actually send anything,	   but a dTD needs to be setup to correctly deal with the 0 byte OUT	   packet the host sends after receiving the IN data. */	usb_dtd2 = usb_dtd_init(0x40, 1, 0, (uint32*) recv_buf);		/* Point the endpoint OUT QH to the dTD */	((USB_EP_QH*)(eplistaddr + EP_QH_OUT(epnum)))->next_dtd = (uint32)usb_dtd2;    /* Prime Rx buffer for control endpoint */    MCF_USB_EPPRIME(port) |= MCF_USB_EPPRIME_PERB(1<<epnum);        /* Wait for prime to complete *///    while (MCF_USB_EPPRIME(port) & MCF_USB_EPPRIME_PERB(1<<epnum));        /* Wait for OUT to complete */    while (!(MCF_USB_USBSTS(port) & MCF_USB_USBSTS_UI ));	/* Clear interrupt */	MCF_USB_USBSTS(port) |= MCF_USB_USBSTS_UI;   		/* Return memory for dTDs to heap */    free((void *)usb_dtd1->malloc_ptr);    free((void *)usb_dtd2->malloc_ptr);	 }/********************************************************************//* * Function to send an zero length IN packet to the host while in USB device mode. * * Parameters: *  eplistaddr	pointer to the device endpoint list *  epnum		endpoint number to use */void usb_device_send_zero_len_packet(uint32 eplistaddr, uint32 epnum){	int port = USB_OTG;	USB_DTD * usb_dtd1;	uint8 * empty_buf[1];	/* Set up dTD for zero length packet */		/* Initialize dTD */	usb_dtd1 = usb_dtd_init(0, 1, 0, (uint32*) empty_buf);		/* Point the endpoint IN QH to the dTD */	((USB_EP_QH*)(eplistaddr + EP_QH_IN(epnum)))->next_dtd = (uint32)usb_dtd1;    /* Prime Tx buffer for control endpoint */    MCF_USB0_EPPRIME |= MCF_USB_EPPRIME_PETB(1<<epnum);        /* Wait for prime to complete */    while (MCF_USB_EPPRIME(port) & MCF_USB_EPPRIME_PETB(1<<epnum));    /* Wait for IN to complete */    while (!(MCF_USB_USBSTS(port) & MCF_USB_USBSTS_UI ));	/* Clear interrupt */	MCF_USB_USBSTS(port) |= MCF_USB_USBSTS_UI;    	/* Return memory for dTDs to heap */    free((void *)usb_dtd1->malloc_ptr);}/********************************************************************//* * Allocate memory for a qTD and initialize the qTD. * This function assumes the qTD is the last in the list so  * the next qTD pointer is not initialized.  * * Parameters: * 	trans_sz		number of bytes to be transferred *	ioc				interrupt on complete flag *	pid				PID code for the transfer ( *	buffer_ptr		pointer to the data buffer  */USB_QTD *usb_qtd_init(uint32 trans_sz, uint32 ioc, uint32 pid, uint32 * buffer_ptr){	USB_QTD *usb_qtd;	uint32 token;	uint32 malloc_addr;   /*	* The USB requires qTDs to be aligned on a 64 byte boundary. 	* In order to accomplish this, the data is over-allocated and 	* adjusted.  	*/	malloc_addr = (uint32)malloc(sizeof(USB_QTD)*2);    usb_qtd = (USB_QTD *)((malloc_addr + 32) & 0xFFFFFFE0);	usb_qtd->next_qtd = 0xDEAD0001;	usb_qtd->alt_qtd = 0x1;		switch (pid)	{		case SETUP_PID:			token = USB_QTD_TOKEN_PID_SETUP;			break;		case OUT_PID:			token = (USB_QTD_TOKEN_DT | USB_QTD_TOKEN_PID_OUT);			break;		case IN_PID:			token = (USB_QTD_TOKEN_DT | USB_QTD_TOKEN_PID_IN);			break;	  	default:	  		#ifdef DEBUG_PRINT	  			printf("ERR!! Invalid PID\n");	  		#endif		    break;	}		if (trans_sz > MAX_QTD_TRANS_SIZE)  		#ifdef DEBUG_PRINT  			printf("ERR!! Invalid transfer size.\n");  		#endif  	  	if (ioc)  		token |= USB_QTD_TOKEN_IOC;    	usb_qtd->qtd_token = (token  							| USB_QTD_TOKEN_TRANS_SIZE(trans_sz)  							| USB_QTD_TOKEN_CERR(0x3)  							| USB_QTD_TOKEN_STAT_ACTIVE );  								usb_qtd->qtd_buf0 = (uint32) buffer_ptr;	usb_qtd->qtd_buf1 = 0;	usb_qtd->qtd_buf2 = 0;	usb_qtd->qtd_buf3 = 0;	usb_qtd->qtd_buf4 = 0;	usb_qtd->malloc_ptr = malloc_addr;	return usb_qtd;}/********************************************************************//* * Allocate memory for a QH and initialize the QH. * This function assumes the QH is the only one in the horizontoal list so  * the horizontal link pointer points to the queue head. This function * doesn't initialize the qTD pointer either. This must be done later.  * * Parameters: * 	max_packet		maximum packet length for the endpoint *  head			used to mark the QH as the first in the linked list (not used for interrupt QHs)			 *	eps				end point speed *  epnum			end pont number				 *  dev_addr		device address *  smask			interrupt schedule mask (only used for periodic schedule QHs) */USB_QH *usb_qh_init(uint32 max_packet, uint32 head, uint32 eps, uint32 epnum, 			uint32 dev_addr, uint32 smask){	USB_QH *usb_qh;	uint32 token;	uint32 malloc_addr;   /*	* The USB requires queue heads to be aligned on a 64 byte boundary. 	* In order to accomplish this, the data is over-allocated and 	* adjusted.   	*/	malloc_addr = (uint32)malloc(sizeof(USB_QH)*2);    usb_qh = (USB_QH *)((malloc_addr + 32) & 0xFFFFFFE0);    	usb_qh->qh_link_ptr = (((uint32) usb_qh) 								| USB_QH_LINK_PTR_TYP_QH );	if (max_packet > MAX_QH_PACKET_SIZE )  		#ifdef DEBUG_PRINT  			printf("ERR!! Invalid packet size.\n");  		#endif	switch (eps)	{		case EPS_FULL:			token = USB_QH_EP_CHAR_EPS_FULL;			break;		case EPS_LOW:			token = USB_QH_EP_CHAR_EPS_LOW;			break;		case EPS_HIGH:			token = USB_QH_EP_CHAR_EPS_HIGH;			break;	  	default:	  		#ifdef DEBUG_PRINT	  			printf("ERR!! Invalid EPS\n");	  		#endif		    break;	}		if (head)		token |= USB_QH_EP_CHAR_H;  			  		  	usb_qh->ep_char = ( token  						 | USB_QH_EP_CHAR_MAX_PACKET(max_packet)  						 | USB_QH_EP_CHAR_DTC  						 | USB_QH_EP_CHAR_EP(epnum)  						 | USB_QH_EP_CHAR_DEV_ADDR(dev_addr) );		    /* Set interrupt to occur every 8ms */    usb_qh->ep_cap = (USB_QH_EP_CAP_MULT_ONE    					| USB_QH_EP_CAP_UFRAME_SMASK(smask));    			usb_qh->curr_qtd = 0;	usb_qh->next_qtd = 1;	usb_qh->alt_qtd = 0;	usb_qh->qtd_token = 0;	usb_qh->qtd_buf0 = 0;	usb_qh->qtd_buf1 = 0;	usb_qh->qtd_buf2 = 0;	usb_qh->qtd_buf3 = 0;	usb_qh->qtd_buf4 = 0;		usb_qh->malloc_ptr = malloc_addr;	return usb_qh;}/********************************************************************//* * Initialize an endpoint QH. The space for the endpoint queue heads is  * allocated when the endpoint list is created, so this function does not * call malloc.  * * Parameters: *  eplistaddr		location of the endpoint list *  offset			offset within the endpoint list for the EP_QH (there are macros for this) *  mult			number of packets per transcation, should be 0 for non-ISO endpoints * 	max_packet		maximum packet length for the endpoint			 *  ios				flag to enable interrupts on incoming setup packets *	next_dtd		ponter to the first dtd for the ep_qh */void usb_ep_qh_init(uint32 eplistaddr, uint32 offset, uint32 mult, uint32 max_packet, 					uint32 ios, uint32 next_dtd){	USB_EP_QH* usb_ep_qh;	uint32 token;		/* Create a pointer to the endpoint queue head being initialized */	usb_ep_qh = (USB_EP_QH*) (eplistaddr + offset);		if (max_packet > MAX_QH_PACKET_SIZE )  		#ifdef DEBUG_PRINT  			printf("ERR!! Invalid packet size.\n");  		#endif  	if (ios)  		token = USB_EP_QH_EP_CHAR_IOS;  	else  		token = 0;  			  		  	usb_ep_qh->ep_char = ( token  							| USB_EP_QH_EP_CHAR_MULT(mult)  							  						 	| USB_EP_QH_EP_CHAR_MAX_PACKET(max_packet));    			usb_ep_qh->curr_dtd = 0;	usb_ep_qh->next_dtd = next_dtd;	usb_ep_qh->dtd_token = 0;	usb_ep_qh->dtd_buf0 = 0;	usb_ep_qh->dtd_buf1 = 0;	usb_ep_qh->dtd_buf2 = 0;	usb_ep_qh->dtd_buf3 = 0;	usb_ep_qh->dtd_buf4 = 0;}/********************************************************************//* * Allocate memory for a device transfer descriptor (dTD) and initialize * the dTD. This function assumes the dTD is the last in the list so  * the next dTD pointer is marked as invalid.  * * Parameters: * 	trans_sz		number of bytes to be transferred *	ioc				interrupt on complete flag *	pid				PID code for the transfer ( *	buffer_ptr		pointer to the data buffer  */USB_DTD *usb_dtd_init(uint32 trans_sz, uint32 ioc, uint32 multo, uint32 * buffer_ptr){	USB_DTD *usb_dtd;	uint32 token;	uint32 malloc_addr;   /*	* The USB requires dTDs to be aligned on a 64 byte boundary. 	* In order to accomplish this, the data is over-allocated and 	* adjusted.  	*/	malloc_addr = (uint32)malloc(sizeof(USB_DTD)*2);    usb_dtd = (USB_DTD *)((malloc_addr + 32) & 0xFFFFFFE0);	usb_dtd->next_dtd = 0xDEAD0001;			if (trans_sz > MAX_DTD_TRANS_SIZE)  		#ifdef DEBUG_PRINT  			printf("ERR!! Invalid transfer size.\n");  		#endif  	  	if (ioc)  		token = USB_DTD_TOKEN_IOC;  	else  		token = 0;    	usb_dtd->dtd_token = (token  							| USB_DTD_TOKEN_TOTAL_BYTES(trans_sz)  							| USB_DTD_TOKEN_MULTO(multo)  							| USB_DTD_TOKEN_STAT_ACTIVE );  								usb_dtd->dtd_buf0 = (uint32) buffer_ptr;	usb_dtd->dtd_buf1 = 0;	usb_dtd->dtd_buf2 = 0;	usb_dtd->dtd_buf3 = 0;	usb_dtd->dtd_buf4 = 0;	usb_dtd->malloc_ptr = malloc_addr;	return usb_dtd;}/********************************************************************/

⌨️ 快捷键说明

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