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 + -
显示快捷键?