📄 m5373evb_host_mouse_test.c
字号:
/* * File: main.c * Purpose: Main process * */#include "common.h"#include "usb.h"#include "m5373evb.h"void latch_init (void);int hid_enum (USB_QH *, uint8 *,uint8 *,uint8 *,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 *, uint32);void get_interface_desc(USB_QH *, uint8 *,uint8 *, uint8 *, uint32);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 DEVICE_ADDRESS 0x2#define CONFIG_VALUE 0x1 /* This is the only valid config value for a USB mouse */#define FRAME_LIST_SIZE 32/********************************************************************/void main (void){ uint32 i, temp, periodic_base, usb_port_speed; uint8 device_descriptor[MAX_USB_DESC_SIZE]; uint8 config_descriptor[MAX_USB_DESC_SIZE]; uint8 interface_descriptor[MAX_USB_DESC_SIZE]; uint8 hid_descriptor[MAX_USB_DESC_SIZE]; uint8 ep_descriptor[MAX_USB_DESC_SIZE]; uint8 report_descriptor[MAX_USB_DESC_SIZE]; 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; /* Global interrupt enable */ mcf5xxx_irq_enable(); /* Enable bursts */ MCF_SCM_BCR = ( 0 | MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW ); printf("MCF532x Initialization Complete!\n"); printf("Starting USB test.\n\n"); /* Initialize the latch on the board */ latch_init(); /* Initiazlize the USB host */ usb_host_init(USB_MODULE); /* Wait for device connect */ while(!( MCF_USB_PORTSC(USB_MODULE) & MCF_USB_PORTSC_CCS)); printf("Connect detected.\n"); #ifdef DEBUG_PRINT printf("PORTSC = 0x%08x\n",MCF_USB_PORTSC(USB_MODULE)); #endif 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(USB_MODULE) = (uint32) usb_qh_ep0; /* Enable async schedule */ MCF_USB_USBCMD(USB_MODULE) |= 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, interface_descriptor, hid_descriptor, ep_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(USB_MODULE)&MCF_USB_USBSTS_UI) | (MCF_USB_USBSTS(USB_MODULE)&MCF_USB_USBSTS_UEI))); /* Check for errors */ if( MCF_USB_USBSTS(USB_MODULE) & MCF_USB_USBSTS_UEI) { printf("ERROR!!!\n"); temp = *(uint32 *)(MCF_USB_ASYNCLISTADDR(USB_MODULE) + 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(USB_MODULE) |= (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; } }/********************************************************************/voidlatch_init (void){ /* Initialization for the latch on the fire engine (U6) */ /* Initialize TIN3 as a GPIO output to enable the write half of the latch */ MCF_GPIO_PAR_TIMER = 0x00; MCF_GPIO_PDDR_TIMER = 0x08; MCF_GPIO_PCLRR_TIMER = 0x0; /* Initialize latch to drive signals to inactive states */ *((uint16 *)(LATCH_ADDRESS)) = 0xFFFF; }/********************************************************************//* 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 *interface_descriptor, uint8 *hid_descriptor,uint8 *ep_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(USB_MODULE) |= MCF_USB_PORTSC_PR; // Set Port Reset // Wait for reset to finish while (MCF_USB_PORTSC(USB_MODULE) & 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,DEVICE_ADDRESS); /* Read in the interface, HID, and endpoint descriptors */ get_interface_desc(usb_qh_ep0, interface_descriptor,hid_descriptor,ep_descriptor,DEVICE_ADDRESS); /* 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]; /* data for Set Address command */ buf0[0] = 0x00050000 | ((0x7F & device_address) <<8); buf0[1] = 0x00000000; usb_qtd1 = usb_qtd_init(0x8, 0, SETUP_PID, buf0); usb_qtd2 = usb_qtd_init(0x0, 1, IN_PID, 0); usb_qtd1->next_qtd = (uint32)usb_qtd2; /* Point the QH to the linked list of qTDs */ usb_qh_ep0->next_qtd = (uint32)usb_qtd1; /* Wait for transaction to complete */ while (!((MCF_USB_USBSTS(USB_MODULE)&MCF_USB_USBSTS_UI) | (MCF_USB_USBSTS(USB_MODULE)&MCF_USB_USBSTS_UEI))); /* Check for errors */ if( MCF_USB_USBSTS(USB_MODULE) & MCF_USB_USBSTS_UEI) { printf("ERROR!!!\n"); temp = *(uint32 *)(MCF_USB_ASYNCLISTADDR(USB_MODULE) + 0x18); printf("qTD status = 0x%08x\n",temp); } else { printf("Set address command complete!!\n\n"); #ifdef DEBUG_PRINT printf("USBSTS = 0x%08x\n",MCF_USB_USBSTS(USB_MODULE)); #endif } /* Clear the USB interrupt status bit */ MCF_USB_USBSTS(USB_MODULE) |= (MCF_USB_USBSTS_UI | MCF_USB_USBSTS_UEI); /* Change the device address in the QH to the new value */ usb_qh_ep0->ep_char |= USB_QH_EP_CHAR_DEV_ADDR(device_address); /* Return memory for descriptors to the heap */ free((void *)usb_qtd1->malloc_ptr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -