usb_hid_host.c

来自「Freescale MCF5445evb 参考测试代码」· C语言 代码 · 共 534 行 · 第 1/2 页

C
534
字号
/* * File:		main.c * Purpose:		Main process * */#include "common.h"#include "usb.h"void latch_init (void);int hid_enum (USB_QH *, uint8 *,uint8 *,uint8 *);void set_device_address(USB_QH *, uint32); void get_dev_desc(USB_QH *, uint8 *, uint32);void get_config_desc(USB_QH *, uint8 *, int);void set_configuration(USB_QH *, uint32, uint32);void get_report_desc(USB_QH *, uint8 *, uint32);#define USB_MODULE		USB_HOST//#define USB_MODULE		USB_OTG//#define USB_XCVR	USB_PHY_ULPI#define USB_XCVR	USB_PHY_FSLS#define DEVICE_ADDRESS	0x2#define CONFIG_VALUE	0x1	/* This is the only valid config value for a USB mouse */#define FRAME_LIST_SIZE 32uint8 *device_descriptor;uint8 *config_descriptor;uint8 *interface_descriptor;uint8 *hid_descriptor;uint8 *ep_descriptor;uint8 *report_descriptor;/********************************************************************/void main (void){	uint32 i, temp, periodic_base, usb_port_speed;	USB_QH * usb_qh_ep0, * usb_qh_ep1;	USB_QTD * int_qtd;		uint8 buf0[MAX_USB_BUFFER_SIZE];	uint32 int_transfer_size, int_packet_size, bytes_received;			device_descriptor = malloc(18);	ASSERT(device_descriptor != NULL);	config_descriptor = malloc(1024);	ASSERT(config_descriptor != NULL);	report_descriptor = malloc(1024);	ASSERT(report_descriptor != NULL);		interface_descriptor = &config_descriptor[9];	hid_descriptor = &config_descriptor[18];	ep_descriptor = &config_descriptor[27];	/* Turn on instruction cache */    /*mcf5xxx_wr_cacr(0        | MCF5XXX_CACR_BEC        | MCF5XXX_CACR_BCINVA        | MCF5XXX_CACR_IEC        | MCF5XXX_CACR_ICINVA);    */	printf("Running USB HID Host Test\n");	    /* Global interrupt enable */	mcf5xxx_irq_enable();		/* Enable bursts across XBS */	MCF_SCM_BCR = 0x3FF;							/* Initialize the USB Clock */	MCF_GPIO_PAR_DMA = MCF_GPIO_PAR_DMA	    & MCF_GPIO_PAR_DMA_DREQ1_MASK	    | MCF_GPIO_PAR_DMA_DREQ1_USB_CLKIN;	/* Initialize the USB host */	usb_host_init(USB_XCVR);									/* Wait for device connect */	printf("Waiting for device connection...");	while(!( MCF_USB_PORTSC & 1));//MCF_USB_PORTSC_CCS));	printf("done\n");		#ifdef DEBUG_PRINT	    	printf("PORTSC = 0x%08x\n",MCF_USB_PORTSC);			#endif			send_usb_reset(USB_MODULE);	{	    int k;	    for (k = 0; k < 100000; k++);	}	usb_port_speed = get_port_speed(USB_MODULE);	/* Create a QH to use for EP0. This single QH will be the 	 * asynchronous schedule during enumeration. 	 */    if (usb_port_speed == MCF_USB_PORTSC_PSPD_FULL)	    usb_qh_ep0 = usb_qh_init(0x40, 1, EPS_FULL, 0, 0, 0);	else    	usb_qh_ep0 = usb_qh_init(0x40, 1, EPS_LOW, 0, 0, 0);        MCF_USB_ASYNCLISTADDR = (uint32) usb_qh_ep0;        /* Enable async schedule */	MCF_USB_USBCMD |= MCF_USB_USBCMD_ASE;	 	   		/* Enumerate the attached device. An error will be returned if 	 * the attached device is not a USB mouse. 	 */	 	if (hid_enum(usb_qh_ep0, device_descriptor, config_descriptor, report_descriptor))    	printf("\nUSB mouse enumerated!!\n");    else    	printf("\nERR!!! During USB mouse enumeration.\n");				/* Initialize the periodic schedule */	periodic_base = periodic_schedule_init(USB_MODULE, FRAME_LIST_SIZE);		/* Create a QH for endpoint 1 */		usb_qh_ep1 = usb_qh_init(0x8,0, EPS_LOW,1,DEVICE_ADDRESS,1);		/* Invalidate the QH horizontal pointer since the init function will point	 * the QH back to itself.	 */	usb_qh_ep1->qh_link_ptr |= USB_QH_LINK_PTR_T;  	/* This version of the code just polls the mouse once per iteration of	 * the frame list. The polling rate can be adjusted changing the size	 * of the frame list and/or pointing more of the frame list entries	 * to the interrupt QH.	 */	/* Point the periodic list directly to the QH */	*(uint32 *)(periodic_base) = (uint32)usb_qh_ep1 + 0x002;	/* Point the periodic list directly to the QH *///	*(uint32 *)(periodic_base + (0x40)) = (uint32)usb_qh_ep1 + 0x002;		/* Initialize the amount of data to receive. In this case we will	 * receive 20 packets per loop. ep_desc[04] inidicates the size of 	 * each packet. So transfer_size = 20 * ep_desc[04].	 */	int_packet_size = ep_descriptor[04];	int_transfer_size = 20 * int_packet_size;		/* Create a qTD to transfer 20 packets worth of data */	int_qtd = usb_qtd_init(int_transfer_size, 1, IN_PID, (uint32*) buf0);								/* This while(1) loop will allow for continuously receiving mouse data. Some * packets could be lost due to the time needed to reinitialize the qTD for the * next batch of transfers. So a more correct way to do this would be to create * multiple qTDs and rotate them for each iteration of the loop. For a mouse * application some data loss is acceptable, so only one qTD is used.  */										while(1)	{											/* Point the QH to the qTD */		usb_qh_ep1->next_qtd = (uint32) int_qtd;   													/* Initialize bytes received counter */		bytes_received = 0;				while (bytes_received < int_transfer_size)		{			/* Wait for transaction to complete */			while (!((MCF_USB_USBSTS&MCF_USB_USBSTS_UI) |					(MCF_USB_USBSTS&MCF_USB_USBSTS_UEI)));			    /* Check for errors */		  	if( MCF_USB_USBSTS & MCF_USB_USBSTS_UEI)		    {		    	printf("ERROR!!!\n");			    temp = *(uint32 *)(MCF_USB_ASYNCLISTADDR + 0x18);		        printf("qTD status = 0x%08x\n",temp);			    }		    else 	/* Display data if no error occurred. */		    {		     	printf("IN = ");		     	for(i=0; i < int_packet_size; i++)		     		printf("0x%02x  ",buf0[bytes_received + i]);		     	printf("\n"); 		    }		            			/* Clear the USB interrupt status bit */			MCF_USB_USBSTS |= (MCF_USB_USBSTS_UI | MCF_USB_USBSTS_UEI);				/* Increment bytes received counter */					bytes_received = bytes_received + int_packet_size;			/* Set the active bit in the QH to ensure that it can accept			 * more data if we aren't done yet. 	     	 */	     	if (bytes_received != int_transfer_size) 				*(uint32 *)((uint32)usb_qh_ep1+0x18) |= 0x00000080;			}				/* Re-initialize the qTD to accept the next 20 packets*/		int_qtd->qtd_token |= USB_QTD_TOKEN_TRANS_SIZE(int_transfer_size) | USB_QTD_TOKEN_STAT_ACTIVE;				int_qtd->qtd_buf0 = (uint32) buf0;	}		}/********************************************************************//* This enumeration routine is specifc for a HID class mouse device. The code * code be used as a starting for enumerating other devices. If drivers need * to be able to detect different types of devices (for example a keyboard or * a mouse could be attached), then some level of descriptor parsing would need * to be added to determine what the attached device is. This code verifies * that a mouse is attached and returns an error if the device is not a HID * class mouse. */inthid_enum(USB_QH * usb_qh_ep0, uint8 *device_descriptor,uint8 *config_descriptor,uint8 *report_descriptor ){//	send_usb_reset(USB_MODULE);//	get_port_speed(USB_MODULE);					/* Read the first 8 bytes of the device descriptor */	get_dev_desc(usb_qh_ep0, device_descriptor, DEVICE_ADDRESS);			        	/* Issue another bus reset after reading first 8 bytes of descriptor */	MCF_USB_PORTSC |= MCF_USB_PORTSC_PR;  // Set Port Reset	// Wait for reset to finish	while (MCF_USB_PORTSC & 0x100)//MCF_USB_PORTSC_PR);	printf("Second USB bus reset complete.\n");		/* Send set address command */   	set_device_address(usb_qh_ep0, DEVICE_ADDRESS); 			/* Read in the full device descriptor */	get_dev_desc(usb_qh_ep0, device_descriptor, DEVICE_ADDRESS);		/* Read in the configuration descriptor */    get_config_desc(usb_qh_ep0, config_descriptor, 9);   	/* Read in the interface, HID, and endpoint descriptors */    get_config_desc(usb_qh_ep0, config_descriptor, 255);           /* Test the interface descriptor parameters to make sure the attached     * device is in the HID class and that it is also a mouse.      */    if( (interface_descriptor[5] != 0x3) | (interface_descriptor[7] != 0x2))    {   		printf("ERR!! Attached device is not a USB mouse.\n");   		return 0;   	}   		/* Set the configuration for the device */	/* We already know the device is a USB mouse, so there is only one possible	 * configuration for the device.	 */     set_configuration(usb_qh_ep0, CONFIG_VALUE,DEVICE_ADDRESS);       	get_report_desc(usb_qh_ep0, report_descriptor,DEVICE_ADDRESS);		return 1;}/********************************************************************/void set_device_address(USB_QH * usb_qh_ep0, uint32 device_address) {	USB_QTD * usb_qtd1, *usb_qtd2;	uint32 temp;	uint32 buf0[MAX_USB_BUFFER_SIZE];

⌨️ 快捷键说明

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