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

📄 usb.c

📁 Freescale ColdFire MCF537x 家族的参考代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File:        usb.c * Purpose:     Provide common USB routines * * Notes:        *               */#include "usb.h"/********************************************************************//* * Initialize the USB host for operation. This initialization sets * up the USB host to detect when a device is connected. * * Parameters: *  port      USB module to initialize */void usb_host_init(int port){	/* Initialize the clock divider for the USB */	MCF_CCM_MISCCR |= MCF_CCM_MISCCR_USBDIV;		/* --- Start HOST controller --- */    #ifdef DEBUG_PRINT		printf("Set host mode.\n");		#endif			MCF_USB_USBMODE(port) = (MCF_USB_USBMODE_ES | MCF_USB_USBMODE_CM_HOST);	MCF_USB_USBCMD(port) = ( 0							| MCF_USB_USBCMD_ASP(3)							| MCF_USB_USBCMD_ITC(0) );    #ifdef DEBUG_PRINT		printf("Set RUN bit.\n");		#endif	MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_RS;		/* Apply port power. This does not initialize the transceiver.	 * If ULPI is being used it should be initialized before this point. */	MCF_USB_PORTSC(port) = ( MCF_USB_PORTSC(port)								| MCF_USB_PORTSC_PP );    #ifdef DEBUG_PRINT					printf("USB host initialized. Waiting for device connect.\n\n");								#endif							}/********************************************************************//* * Initialize the USB device for operation. This initialization performs * basic configuration to prepare the device for connection to a host. * Since currently only one USB port supports device operation, the port * for the device init is set at the beginning of this function. If future  * devices implement more than one USB device port then this can be changed * to a passed in parameter. * * Parameters: */uint32 usb_device_init(void){	uint32 ep_list_addr;	int port = USB_OTG;	/* Initialize the clock divider for the USB */	MCF_CCM_MISCCR |= MCF_CCM_MISCCR_USBDIV;			  	//--- Set Device Mode ---//    #ifdef DEBUG_PRINT		printf("Set device mode.\n");		#endif			MCF_USB_USBMODE(port) = (MCF_USB_USBMODE_ES | MCF_USB_USBMODE_CM_DEVICE);  	/*--- Intial Configuration ---*/  	MCF_USB_USBCMD(port) &= ~( MCF_USB_USBCMD_ITC(0xFF));	// Set interrupt threshold control = 0    MCF_USB_USBMODE(port) |= MCF_USB_USBMODE_SLOM;	// Setup Lockouts Off      	/* Initialize EP0 to handle enumeration. This function will also allocate  	 * memory to be used for the device endpoint list. */  	ep_list_addr = usb_device_ep0_init();	/* Initialize queue head for EP0 IN (device to host)  */	usb_ep_qh_init(ep_list_addr, EP_QH0_IN, 0, 0x40, 0, 1); 		/* Initialize queue head for EP0 OUT (host to device)  */	usb_ep_qh_init(ep_list_addr, EP_QH0_OUT, 0, 0x40, 0, 1); 	MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_RS;	// RUN controller	/* Enable  a valid B session to allow device to connect to a host. */	MCF_CCM_UOCSR = ( 0						| MCF_CCM_UOCSR_BVLD );    #ifdef DEBUG_PRINT					printf("USB device initialized.\n");								#endif		return ep_list_addr;							}/********************************************************************//* * This function allocates memory in the heap to use as the device * endpoint list. Then the function will initialize endpoint 0 so that * it is ready to respond to the host for enumeration.  * Since currently only one USB port supports device operation, the port * for the device init is set at the beginning of this function. If future  * devices implement more than one USB device port then this can be changed * to a passed in parameter. * * Parameters: *  eplistaddr      return a pointer to the device endpoint list */uint32 usb_device_ep0_init(void){	int i, port = USB_OTG;	uint32 eplistaddr;	/* Allocate space for the device endpoint list*/   /*	* The USB requires the endpoint listb to be aligned on a 2kbyte boundary. 	* In order to accomplish this, the data is over-allocated and 	* adjusted.  	*/	eplistaddr = (uint32)malloc(sizeof(2048)*2);    eplistaddr = (eplistaddr + 2048) & 0xFFFFF800;	/* Set the device endpoint list address */  	MCF_USB_EPLISTADDR(port) = eplistaddr;  	  	/* Clear the entire ep list */  	for ( i =0; i < 0x10; i++)		*((uint32 *)(eplistaddr + (i*4))) = 0;  			   	/* Configure EP0. Only the required EP0 for control traffic is initialized at this time. */  	MCF_USB_EPCR0(port) |= (MCF_USB_EPCR_TXE | MCF_USB_EPCR_RXE);	// Enable TX/RX of EP0	return eplistaddr;}/********************************************************************//* * Initialize the periodic schedule. This function creates an empty * frame list for the periodic schedule, points the periodic base * address to the empty frame list, and enables the periodic schedule. * * Parameters: *  port      			USB module to initialize *  frame_list_size		size of the frame list for the periodic schedule *  periodic_base		pointer to the start of the allocated frame list */uint32 periodic_schedule_init(int port, uint32 frame_list_size){	uint32 i;	uint32 periodic_base; 	uint32 malloc_addr;    /* Disable the asynchronous schedule *///    MCF_USB_USBCMD(port) &= ~MCF_USB_USBCMD_ASE;	/* Initialize the USBCMD register for the desired size of the frame list */	switch (frame_list_size)	{ case 1024:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_1024;	   	break;	  case 512:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_512;	   	break;	  case 256:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_256;	   	break;	  case 128:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_128;	   	break;	  case 64:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_64;	   	break;	  case 32:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_32;	   	break;	  case 16:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_16;	   	break;	  case 8:		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_8;	   	break;  	default:  		printf("ERR!! Invalid frame list size\n");		MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_FS_1024; /* Use the max size by default */  			    break;	}	   /*	* The USB requires the frame list to be aligned on an 8Kbyte boundary. 	* In order to accomplish this, the data is over-allocated according to 	* the largest possible frame list size and adjusted.   	*/	/* Allocate memory for the frame list */	malloc_addr = (uint32)malloc(1024*4);    periodic_base = (uint32)((malloc_addr + 0x1000) & 0xFFFFF000);			/* Fill the frame list with link pointers marked as invalid	 * since we don't have any traffic to send yet.	 */    for ( i=0; i<(frame_list_size*4); i=i+4)		*(uint32 *)(periodic_base+i) = 1;			/* Initialize the Periodic base address register */	MCF_USB_PERIODICLISTBASE(port) = periodic_base;		/* Enable the periodic schedule */	MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_PSE;		/* Wait for periodic schedule to enable */	while (!(MCF_USB_USBSTS(port) & MCF_USB_USBSTS_PS));        #ifdef DEBUG_PRINT				   	printf("Periodic schedule is enabled.\n");    #endif        return periodic_base;}/********************************************************************//* * Issue a USB reset to the specified port. * * Parameters: *  port      USB module to send reset */void send_usb_reset(int port){	MCF_USB_PORTSC(port) |= MCF_USB_PORTSC_PR;  // Set Port Reset	#ifdef DEBUG_PRINT		printf("Start reset.\n");    	printf("PORTSC = 0x%08x\n",MCF_USB_PORTSC(port));		    #endif    	/* Wait for reset to finish */	while (MCF_USB_PORTSC(port) & MCF_USB_PORTSC_PR);    #ifdef DEBUG_PRINT					printf("USB reset complete.\n\n");								#endif							}/********************************************************************//* * USB device response to a USB bus reset. * * Parameters: */void usb_bus_reset(void){	int port = USB_OTG;	uint32 temp;	//	printf("USBSTS = 0x%08x\n",MCF_USB_USBSTS(port));		    /* Clear all setup token semaphores */    temp = MCF_USB_EPSETUPSR(port);    MCF_USB_EPSETUPSR(port) = temp;    #ifdef DEBUG_PRINT	    printf("EPSETUPSR = 0x%08x\n",MCF_USB_EPSETUPSR(port));    #endif        /* Clear all complete status bits */    temp = MCF_USB_EPCOMPLETE(port);    MCF_USB_EPCOMPLETE(port) = temp;    #ifdef DEBUG_PRINT    			    printf("EPCOMPLETE = 0x%08x\n",MCF_USB_EPCOMPLETE(port));    #endif    	/* Wait for all primed status to clear */	while (MCF_USB_EPPRIME(port));    #ifdef DEBUG_PRINT		printf("EPPRIME = 0x%08x\n",MCF_USB_EPPRIME(port));	#endif    /* Flush all endpoints */    MCF_USB_EPFLUSH(port) = 0xFFFFFFFF;       	/* Wait for host to stop signalling reset */	while (MCF_USB_PORTSC(port) & MCF_USB_PORTSC_PR);		/* Clear reset status bit */	MCF_USB_USBSTS(port) |= MCF_USB_USBSTS_URI | MCF_USB_USBSTS_UI;	    #ifdef DEBUG_PRINT	    printf("\n\nUSB Bus Reset Complete!!!\n");		printf("USBSTS = 0x%08x\n",MCF_USB_USBSTS(port));			#endif}/********************************************************************//* * USB device function to return the data from a setup packet. * * Parameters: * ep_list_addr	pointer to the device endpoint list address * setup03		bytes 0-3 of the setup packet * setup47 		bytes 4-7 of the setup packet */void get_setup_packet(uint32 ep_list_addr, uint32* setup03, uint32* setup47){	int port = USB_OTG;    /* Wait for setup *///    while (!(MCF_USB_USBSTS(port) & MCF_USB_USBSTS_UI ));	while(!(MCF_USB_EPSETUPSR(port) & MCF_USB_EPSETUPSR_EPSETUPSTAT(1)));			/* Verify that transaction is a SETUP on EP0 *///	if (MCF_USB_EPSETUPSR(port) != 1)//	    printf("\nERR!!! Expected SETUP on EP0 not received!\n");        /* Clear setup identification */    MCF_USB_EPSETUPSR(port) |= MCF_USB_EPSETUPSR_EPSETUPSTAT(1);        /* Set setup tripwire */    MCF_USB_USBCMD(port) |= MCF_USB_USBCMD_SUTW;    	/* Get the actual setup data. The data is returned little endian	 * so it needs to be byte swapped.	 */	*(uint32 *)setup03 = swap32(*(uint32 *)(ep_list_addr+0x28));	*(uint32 *)setup47 = swap32(*(uint32 *)(ep_list_addr+0x2C));        /* Wait for SUTW bit to set */    while ( !(MCF_USB_USBCMD(port) & MCF_USB_USBCMD_SUTW));        /* Clear SUTW bit */    MCF_USB_USBCMD(port) &= ~MCF_USB_USBCMD_SUTW;        /* Wait for EPSETUP to clear */    while (MCF_USB_EPSETUPSR(port) & MCF_USB_EPSETUPSR_EPSETUPSTAT(1));}/********************************************************************/int swap32(int data){    uint32 swapped = 0;    swapped |= data & 0x000000ff;    swapped <<= 8;    data >>= 8;    swapped |= data & 0x000000ff;    swapped <<= 8;    data >>= 8;    swapped |= data & 0x000000ff;    swapped <<= 8;    data >>= 8;    swapped |= data & 0x000000ff;    return(swapped);}/********************************************************************//* * Return the speed of the USB port. * * Parameters: *  port      USB module to send reset */int get_port_speed(int port){	int speed;		/* Wait for connect */	while(!( MCF_USB_PORTSC(port) & MCF_USB_PORTSC_CCS));	/* Determine the speed we are connected at. */	speed = (MCF_USB_PORTSC(port) & MCF_USB_PORTSC_PSPD(0x3));	#ifdef DEBUG_PRINT		switch (speed)		{ case MCF_USB_PORTSC_PSPD_FULL:			printf("Connected at full-speed\n");    		break;  		case MCF_USB_PORTSC_PSPD_LOW:	  		printf("Connected at low-speed\n");    		break;

⌨️ 快捷键说明

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