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

📄 usb.c

📁 coldfire的mcf5329的程序
💻 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 + -