This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
各位专家、您好!
我目前正在尝试使用 USB-HID 在 Windows 10上模拟游戏手柄/游戏手柄。 MSP430将采用7-14个模拟输入并将其发送到 Windows、在 Windows 中它们将被视为 USB-HID 游戏控制器输入。
我正在处理 MSP430 USB API 中的 H7_Mouse 示例、因为没有用于传统游戏控制器的示例代码。 描述符是使用 USB-IF 的 HID 描述符工具创建的,然后粘贴到 TI USB 描述符工具中,以在 USB_config 文件夹中创建必要的描述符.c/h。 我正在使用 USB 描述符(如下所示)作为简单的4轴16按钮游戏手柄开始使用。
0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x05, // USAGE (Game Pad) 0xA1, 0x01, // COLLECTION (Application) 0xA1, 0x00, // COLLECTION (Physical) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x10, // USAGE_MAXIMUM (Button 16) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x10, // REPORT_COUNT (16) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x09, 0x32, // USAGE (Z) 0x09, 0x33, // USAGE (Rx) 0x15, 0x81, // LOGICAL_MINIMUM (-127) 0x25, 0x7F, // LOGICAL_MAXIMUM (127) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x04, // REPORT_COUNT (4) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xC0, // END COLLECTION 0xC0 // END COLLECTION
main.c 文件(通过鼠标示例进行了细微编辑、以适应新的 HID 报告结构)如下所示:
* ======== main.c ======== * Mouse HID Demo: * * This example functions as a mouse on the host. It causes the mouse pointer * to move in a circular pattern on the screen. Simply build and run the * example. To re-gain control of the mouse, unplug USB. * Unlike the HID-Datapipe examples, this one does not communicate with the * HID Demo Application * +----------------------------------------------------------------------------+ * Please refer to the Examples Guide for more details. *----------------------------------------------------------------------------*/ #include <string.h> #include "driverlib.h" #include "USB_config/descriptors.h" #include "USB_API/USB_Common/device.h" #include "USB_API/USB_Common/usb.h" // USB-specific functions #include "USB_API/USB_HID_API/UsbHid.h" /* * NOTE: Modify hal.h to select a specific evaluation board and customize for * your own board. */ #include "hal.h" #define LED_PORT GPIO_PORT_P1 #define LED_PIN GPIO_PIN0 #define BUTTON_PORT GPIO_PORT_P1 #define BUTTON_PIN GPIO_PIN1 typedef struct { uint16_t buttons; int8_t lx; int8_t ly; int8_t rx; int8_t ry; } CONTROL_REPORT; CONTROL_REPORT controlReport = { 0, 0, 0, 0, 0 }; // HID report, to be sent to the PC. //const int16_t tableSinCosLookUp[93][2]; // Lookup table for mouse data; #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) uint8_t index = 1; // Index for lookup table #endif volatile uint8_t sendNewMousePosition = FALSE; // Flag by which timer tells main // loop to send a new report Timer_A_initUpModeParam Timer_A_params = {0}; void initTimer (void); volatile uint8_t buttonPressed = FALSE; /* * ======== main ======== */ void main (void) { #if defined(__GNUC__) && (__MSP430__) uint8_t index = 1; #endif WDT_A_hold(WDT_A_BASE); // Stop watchdog timer // Minumum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 . PMM_setVCore(PMM_CORE_LEVEL_2); USBHAL_initPorts(); // Config GPIOS for low-power (output low) USBHAL_initClocks(8000000); // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz initTimer(); USB_setup(TRUE, TRUE); // Init USB & events; if a host is present, connect ///additional input button in dev kit P2.1 GPIO_setAsInputPin(BUTTON_PORT, BUTTON_PIN); GPIO_setAsOutputPin(LED_PORT, LED_PIN); P1IES |= BIT1; P1IFG &= ~BIT1; P1IE |= BIT1; /// __enable_interrupt(); // Enable interrupts globally while (1) { // Check the USB state and directly main loop accordingly switch (USB_getConnectionState()) { // This case is executed while your device is enumerated on the // USB host case ST_ENUM_ACTIVE: // Start Timer Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE); // Enter LPM0, until the timer wakes the CPU __bis_SR_register(LPM0_bits + GIE); // Timer has awakened the CPU. Proceed with main loop... if (sendNewMousePosition){ controlReport.ry += 1; controlReport.buttons += 1; controlReport.lx += 1; controlReport.ly += 1; controlReport.rx += 1; // Send the report USBHID_sendReport((void *)&controlReport, HID0_INTFNUM); // Toggle LED on P1.0 GPIO_toggleOutputOnPin(LED_PORT, LED_PIN); } break; // These cases are executed while your device is disconnected from // the host (meaning, not enumerated); enumerated but suspended // by the host, or connected to a powered hub without a USB host // present. case ST_PHYS_DISCONNECTED: case ST_ENUM_SUSPENDED: case ST_PHYS_CONNECTED_NOENUM_SUSP: TA0CTL &= ~MC_1; P1OUT &= ~BIT0; __bis_SR_register(LPM3_bits + GIE); _NOP(); break; // The default is executed for the momentary state // ST_ENUM_IN_PROGRESS. Usually, this state only last a few // seconds. Be sure not to enter LPM3 in this state; USB // communication is taking place here, and therefore the mode must // be LPM0 or active-CPU. case ST_ENUM_IN_PROGRESS: default:; } } //while(1) } //main() /* * ======== UNMI_ISR ======== */ #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) #pragma vector = UNMI_VECTOR __interrupt void UNMI_ISR (void) #elif defined(__GNUC__) && (__MSP430__) void __attribute__ ((interrupt(UNMI_VECTOR))) UNMI_ISR (void) #else #error Compiler not found! #endif { switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG )) { case SYSUNIV_NONE: __no_operation(); break; case SYSUNIV_NMIIFG: __no_operation(); break; case SYSUNIV_OFIFG: UCS_clearFaultFlag(UCS_XT2OFFG); UCS_clearFaultFlag(UCS_DCOFFG); SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); break; case SYSUNIV_ACCVIFG: __no_operation(); break; case SYSUNIV_BUSIFG: // If the CPU accesses USB memory while the USB module is // suspended, a "bus error" can occur. This generates an NMI. If // USB is automatically disconnecting in your software, set a // breakpoint here and see if execution hits it. See the // Programmer's Guide for more information. SYSBERRIV = 0; //clear bus error flag USB_disable(); //Disable } } /* * ======== TIMER0_A0_ISR ======== */ #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR (void) #elif defined(__GNUC__) && (__MSP430__) void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void) #else #error Compiler not found! #endif { sendNewMousePosition = TRUE; // Set flag telling main loop to send a report __bic_SR_register_on_exit(LPM0_bits); // Keep CPU awake after returning; // enables a run through the main loop } /* * ======== setTimer_A_Parameters ======== */ // This function sets the timer A parameters void setTimer_A_Parameters() { Timer_A_params.clockSource = TIMER_A_CLOCKSOURCE_ACLK; Timer_A_params.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1; Timer_A_params.timerPeriod = 547; // 547/32768 = a period of 16.7ms Timer_A_params.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; Timer_A_params.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE; Timer_A_params.timerClear = TIMER_A_DO_CLEAR; Timer_A_params.startTimer = false; } /* * ======== initTimer ======== */ void initTimer (void) { setTimer_A_Parameters(); // Start timer Timer_A_clearTimerInterrupt(TIMER_A0_BASE); Timer_A_initUpMode(TIMER_A0_BASE, &Timer_A_params); } //Released_Version_5_20_06_03
使用上述代码和描述符、Windows 使用正确的输入将 MSP430正确识别为游戏 epad -可在"控制面板\设置 USB 游戏控制器"下看到。 但是、当单击同一页上的"属性"并测试输入时(代码会定期将每个输入值递增1)、Windows 不会从控制器记录可见的按钮按压/操纵杆响应。 我尝试使用 USB API 中的 Java_HID_Demo 工具来查看是否可以通过查看发送的原始数据来调试问题、但软件无法连接到传统的 USB-HID 设备、即使 Windows 将其识别为游戏 epad。
描述符文件也在此处提供完整参考:
descriptors.h
/* --COPYRIGHT--,BSD * Copyright (c) 2015, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ // Generated by MSP USB Descriptor Tool: Fri Jul 09 10:27:06 BST 2021 #include <stdint.h> #include "USB_API/USB_Common/usb.h" #ifndef _DESCRIPTORS_H_ #define _DESCRIPTORS_H_ #ifdef __cplusplus extern "C" { #endif /*-----------------------------------------------------------------------------+ | Include files | |-----------------------------------------------------------------------------*/ //*********************************************************************************************** // CDC or HID - Define both for composite support //*********************************************************************************************** #define _HID_ // Needed for HID interface //*********************************************************************************************** // CONFIGURATION CONSTANTS //*********************************************************************************************** // These constants configure the API stack and help define the USB descriptors. // Refer to Sec. 6 of the MSP430 USB CDC API Programmer's Guide for descriptions of these constants. // Configuration Constants that can change // #define that relates to Device Descriptor #define USB_VID 0x2047 // Vendor ID (VID) #define USB_PID 0x0302 // Product ID (PID) /*----------------------------------------------------------------------------+ | Firmware Version | | How to detect version number of the FW running on MSP430? | | on Windows Open ControlPanel->Systems->Hardware->DeviceManager->Ports-> | | Msp430->ApplicationUART->Details | +----------------------------------------------------------------------------*/ #define VER_FW_H 0x02 // Device release number, in binary-coded decimal #define VER_FW_L 0x00 // Device release number, in binary-coded decimal // If a serial number is to be reported, set this to the index within the string descriptor //of the dummy serial number string. It will then be automatically handled by the API. // If no serial number is to be reported, set this to 0. #define USB_STR_INDEX_SERNUM 3 #define PHDC_ENDPOINTS_NUMBER 2 // bulk in, bulk out #define DESCRIPTOR_TOTAL_LENGTH 41 // wTotalLength, This is the sum of configuration descriptor length + CDC descriptor length + HID descriptor length #define USB_NUM_INTERFACES 1 //Number of implemented interfaces. #define HID0_REPORT_INTERFACE 0 // Report interface number of HID0 #define HID0_OUTEP_ADDR 0x01 // Output Endpoint number of HID0 #define HID0_INEP_ADDR 0x81 // Input Endpoint number of HID0 #define CDC_NUM_INTERFACES 0 // Total Number of CDCs implemented. should set to 0 if there are no CDCs implemented. #define HID_NUM_INTERFACES 1 // Total Number of HIDs implemented. should set to 0 if there are no HIDs implemented. #define MSC_NUM_INTERFACES 0 // Total Number of MSCs implemented. should set to 0 if there are no MSCs implemented. #define PHDC_NUM_INTERFACES 0 // Total Number of PHDCs implemented. should set to 0 if there are no PHDCs implemented. // Interface numbers for the implemented CDSs and HIDs, This is to use in the Application(main.c) and in the interupt file(UsbIsr.c). #define HID0_INTFNUM 0 #define MSC_MAX_LUN_NUMBER 1 // Maximum number of LUNs supported #define PUTWORD(x) ((x)&0xFF),((x)>>8) #define USB_OUTEP_INT_EN BIT0 | BIT1 #define USB_INEP_INT_EN BIT0 | BIT1 #define USB_USE_INTERNAL_3V3LDO TRUE #define USB_XT2_BYPASS_MODE FALSE // MCLK frequency of MCU, in Hz // For running higher frequencies the Vcore voltage adjustment may required. // Please refer to Data Sheet of the MSP430 device you use #define USB_PLL_XT 2 // Defines which XT is used by the PLL (1=XT1, 2=XT2) #define USB_DISABLE_XT_SUSPEND 1 // If non-zero, then USB_suspend() will disable the oscillator // that is designated by USB_PLL_XT; if zero, USB_suspend won't // affect the oscillator #define USB_DMA_CHAN DMA_CHANNEL_0 // Set to 0xFF if no DMA channel will be used 0..7 for selected DMA channel // Controls whether the remote wakeup feature is supported by this device. // A value of 0x20 indicates that is it supported (this value is the mask for // the bmAttributes field in the configuration descriptor). // A value of zero indicates remote wakeup is not supported. // Other values are undefined, as they will interfere with bmAttributes. #define USB_SUPPORT_REM_WAKE 0x00 // Controls whether the application is self-powered to any degree. Should be // set to 0x40, unless the USB device is fully supplied by the bus. #define USB_SUPPORT_SELF_POWERED 0x80 // Controls what the device reports to the host regarding how much power it will // consume from VBUS. Expressed in 2mA units; that is, the number of mA // communicated is twice the value of this field. #define USB_MAX_POWER 0x32 //Configuration constants that can not change ( Fixed Values) #define CDC_CLASS 2 #define HID_CLASS 3 #define MSC_CLASS 4 #define PHDC_CLASS 5 #define MAX_PACKET_SIZE 0x40 // Max size of the USB packets. //*********************************************************************************************** // DESCRIPTOR CONSTANTS //*********************************************************************************************** #define SIZEOF_DEVICE_DESCRIPTOR 0x12 #define MAX_STRING_DESCRIPTOR_INDEX 5 #define report_desc_size_HID0 46 //#define SIZEOF_REPORT_DESCRIPTOR 36 //#define USBHID_REPORT_LENGTH 64 // length of whole HID report (including Report ID) #define CONFIG_STRING_INDEX 4 #define INTF_STRING_INDEX 5 #define USB_CONFIG_VALUE 0x01 //*********************************************************************************************** // OUTWARD DECLARATIONS //*********************************************************************************************** //Calculates the endpoint descriptor block number from given address #define EDB(addr) ((addr&0x07)-1) /* Structure for generic part of configuration descriptor */ struct abromConfigurationDescriptorGenric { uint8_t sizeof_config_descriptor; // bLength uint8_t desc_type_config; // bDescriptorType: 2 uint8_t sizeof_configuration_descriptor1; // wTotalLength uint8_t sizeof_configuration_descriptor2; uint8_t usb_num_configurations; // bNumInterfaces uint8_t bconfigurationvalue; // bConfigurationValue uint8_t config_string_index; // iConfiguration Description offset uint8_t mattributes; // bmAttributes, bus power, remote wakeup uint8_t usb_max_power; // Max. Power Consumption at 2mA unit }; /************************************************CDC Descriptor**************************/ struct abromConfigurationDescriptorCdc { // interface descriptor (9 bytes) uint8_t blength_intf; // blength: interface descriptor size uint8_t desc_type_interface; // bdescriptortype: interface uint8_t interface_number_cdc; // binterfacenumber uint8_t balternatesetting; // balternatesetting: alternate setting uint8_t bnumendpoints; // bnumendpoints: three endpoints used uint8_t binterfaceclass; // binterfaceclass: communication interface class uint8_t binterfacesubclass; // binterfacesubclass: abstract control model uint8_t binterfaceprotocol; // binterfaceprotocol: common at commands uint8_t intf_string_index; // interface: //header functional descriptor uint8_t blength_header; // blength: endpoint descriptor size uint8_t bdescriptortype_header; // bdescriptortype: cs_interface uint8_t bdescriptorsubtype_header; // bdescriptorsubtype: header func desc uint8_t bcdcdc1; uint8_t bcdcdc2; // bcdcdc: spec release number //call managment functional descriptor uint8_t bfunctionlength; // bfunctionlength uint8_t bdescriptortype_c; // bdescriptortype: cs_interface uint8_t bdescriptorsubtype_c; // bdescriptorsubtype: call management func desc uint8_t bmcapabilities; // bmcapabilities: d0+d1 uint8_t intf_number_cdc; // bdatainterface: 0 //acm functional descriptor uint8_t bfunctionlength_acm; // bfunctionlength uint8_t bdescriptortype_acm; // bdescriptortype: cs_interface uint8_t bdescriptorsubtype_acm; // bdescriptorsubtype: abstract control management desc uint8_t bmcapabilities_acm; // bmcapabilities // Union Functional Descriptor uint8_t bLength_ufd; // Size, in bytes uint8_t bdescriptortype_ufd; // bDescriptorType: CS_INTERFACE uint8_t bdescriptorsubtype_ufd; // bDescriptorSubtype: Union Functional Desc uint8_t bmasterinterface_ufd; // bMasterInterface -- the controlling intf for the union uint8_t bslaveinterface_ufd; // bSlaveInterface -- the controlled intf for the union //Interrupt end point related fields uint8_t sizeof_epintep_descriptor; // blength: endpoint descriptor size uint8_t desc_type_epintep; // bdescriptortype: endpoint uint8_t cdc_intep_addr; // bendpointaddress: (in2) uint8_t epintep_desc_attr_type_int; // bmattributes: interrupt uint8_t epintep_wmaxpacketsize1; uint8_t epintep_wmaxpacketsize; // wmaxpacketsize, 64 bytes uint8_t epintep_binterval; // binterval // Data interface descriptor (9 bytes) uint8_t blength_slaveintf; // blength: interface descriptor size uint8_t desc_type_slaveinterface; // bdescriptortype: interface uint8_t interface_number_slavecdc; // binterfacenumber uint8_t balternatesetting_slave; // balternatesetting: alternate setting uint8_t bnumendpoints_slave; // bnumendpoints: three endpoints used uint8_t binterfaceclass_slave; // binterfaceclass: data interface class uint8_t binterfacesubclass_slave; // binterfacesubclass: abstract control model uint8_t binterfaceprotocol_slave; // binterfaceprotocol: common at commands uint8_t intf_string_index_slave; // interface: // Bulk out end point related fields uint8_t sizeof_outep_descriptor; // blength: endpoint descriptor size uint8_t desc_type_outep; // bdescriptortype: endpoint uint8_t cdc_outep_addr; // bendpointaddress: (out3) uint8_t outep_desc_attr_type_bulk; // bmattributes: bulk uint8_t outep_wmaxpacketsize1; uint8_t outep_wmaxpacketsize2; // wmaxpacketsize, 64 bytes uint8_t outep_binterval; // binterval: ignored for bulk transfer // Bulk in related fields uint8_t sizeof_inep_descriptor; // blength: endpoint descriptor size uint8_t desc_type_inep; // bdescriptortype: endpoint uint8_t cdc_inep_addr; // bendpointaddress: (in3) uint8_t inep_desc_attr_type_bulk; // bmattributes: bulk uint8_t inep_wmaxpacketsize1; uint8_t inep_wmaxpacketsize2; // wmaxpacketsize, 64 bytes uint8_t inep_binterval; // binterval: ignored for bulk transfer } ; /**************************************HID descriptor structure *************************/ struct abromConfigurationDescriptorHid { //INTERFACE DESCRIPTOR (9 bytes) uint8_t sizeof_interface_descriptor; // Desc Length uint8_t desc_type_interface; // DescriptorType uint8_t interface_number_hid; // Interface number uint8_t balternatesetting; // Any alternate settings if supported uint8_t bnumendpoints; // Number of end points required uint8_t binterfaceclass; // Class ID uint8_t binterfacesubclass; // Sub class ID uint8_t binterfaceprotocol; // Protocol uint8_t intf_string_index; // String Index //hid descriptor (9 bytes) uint8_t blength_hid_descriptor; // HID Desc length uint8_t hid_descriptor_type; // HID Desc Type uint8_t hidrevno1; // Rev no uint8_t hidrevno2; // Rev no - 2nd part uint8_t tcountry; // Country code uint8_t numhidclasses; // Number of HID classes to follow uint8_t report_descriptor_type; // Report desc type uint8_t tlength; // Total length of report descriptor uint8_t size_rep_desc; //input end point descriptor (7 bytes) uint8_t size_inp_endpoint_descriptor; // End point desc size uint8_t desc_type_inp_endpoint; // Desc type uint8_t hid_inep_addr; // Input end point address uint8_t ep_desc_attr_type_inp_int; // Type of end point uint8_t inp_wmaxpacketsize1; // Max packet size uint8_t inp_wmaxpacketsize2; uint8_t inp_binterval; // bInterval in ms // Output end point descriptor; (7 bytes) uint8_t size_out_endpoint_descriptor; // Output endpoint desc size uint8_t desc_type_out_endpoint; // Desc type uint8_t hid_outep_addr; // Output end point address uint8_t ep_desc_attr_type_out_int; // End point type uint8_t out_wmaxpacketsize1; // Max packet size uint8_t out_wmaxpacketsize2; uint8_t out_binterval; // bInterval in ms }; /**************************************MSC descriptor structure *************************/ struct abromConfigurationDescriptorMsc { // INTERFACE DESCRIPTOR (9 bytes) uint8_t sizeof_interface_descriptor; // Desc Length uint8_t desc_type_interface; // DescriptorType uint8_t interface_number_hid; // Interface number uint8_t balternatesetting; // Any alternate settings if supported uint8_t bnumendpoints; // Number of end points required uint8_t binterfaceclass; // Class ID uint8_t binterfacesubclass; // Sub class ID uint8_t binterfaceprotocol; // Protocol uint8_t intf_string_index; // String Index // input end point descriptor (7 bytes) uint8_t size_inp_endpoint_descriptor; // End point desc size uint8_t desc_type_inp_endpoint; // Desc type uint8_t hid_inep_addr; // Input end point address uint8_t ep_desc_attr_type_inp_int; // Type of end point uint8_t inp_wmaxpacketsize1; // Max packet size uint8_t inp_wmaxpacketsize2; uint8_t inp_binterval; // bInterval in ms // Output end point descriptor; (7 bytes) uint8_t size_out_endpoint_descriptor; // Output endpoint desc size uint8_t desc_type_out_endpoint; // Desc type uint8_t hid_outep_addr; // Output end point address uint8_t ep_desc_attr_type_out_int; // End point type uint8_t out_wmaxpacketsize1; // Max packet size uint8_t out_wmaxpacketsize2; uint8_t out_binterval; // bInterval in ms }; /* Global structure having Generic,CDC,HID, MSC structures */ struct abromConfigurationDescriptorGroup { /* Generic part of config descriptor */ const struct abromConfigurationDescriptorGenric abromConfigurationDescriptorGenric; #ifdef _MSC_ /* MSC descriptor structure */ const struct abromConfigurationDescriptorMsc stMsc[MSC_NUM_INTERFACES]; #endif #ifdef _CDC_ /* CDC descriptor structure */ const struct abromConfigurationDescriptorCdc stCdc[CDC_NUM_INTERFACES]; #endif #ifdef _HID_ /* HID descriptor structure */ const struct abromConfigurationDescriptorHid stHid[HID_NUM_INTERFACES]; #endif #ifdef _PHDC_ /* PDC descriptor structure */ const struct abromConfigurationDescriptorPhdc stPhdc[PHDC_NUM_INTERFACES]; #endif }; extern const struct abromConfigurationDescriptorGroup abromConfigurationDescriptorGroup; extern uint8_t const abromDeviceDescriptor[SIZEOF_DEVICE_DESCRIPTOR]; extern uint8_t const abromStringDescriptor[]; //extern uint8_t const abromReportDescriptor[SIZEOF_REPORT_DESCRIPTOR]; /* Handle Structure - Will be populated in descriptors.c based on number of CDC,HID interfaces */ struct tUsbHandle { uint8_t ep_In_Addr; // Input EP Addr uint8_t ep_Out_Addr; // Output EP Addr uint8_t edb_Index; // The EDB index uint8_t dev_Class; // Device Class- 2 for CDC, 3 for HID uint16_t intepEP_X_Buffer; // Interupt X Buffer Addr uint16_t intepEP_Y_Buffer; // Interupt Y Buffer Addr uint16_t oep_X_Buffer; // Output X buffer Addr uint16_t oep_Y_Buffer; // Output Y buffer Addr uint16_t iep_X_Buffer; // Input X Buffer Addr uint16_t iep_Y_Buffer; // Input Y Buffer Addr }; extern const struct tUsbHandle stUsbHandle[CDC_NUM_INTERFACES + HID_NUM_INTERFACES + MSC_NUM_INTERFACES + PHDC_NUM_INTERFACES]; extern const tDEVICE_REQUEST_COMPARE tUsbRequestList[]; #ifdef __cplusplus } #endif #endif /*------------------------ Nothing Below This Line --------------------------*/ //Released_Version_5_20_06_03
-描述符.c
/* --COPYRIGHT--,BSD * Copyright (c) 2015, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ // Generated by MSP USB Descriptor Tool: Fri Jul 09 10:27:06 BST 2021 /*-----------------------------------------------------------------------------+ | Include files |-----------------------------------------------------------------------------*/ #include <USB_API/USB_Common/device.h> #include <USB_API/USB_Common/defMSP430USB.h> #include <USB_API/USB_Common/usb.h> // USB-specific Data Structures #include "descriptors.h" #include <USB_API/USB_CDC_API/UsbCdc.h> #include <USB_API/USB_HID_API/UsbHidReq.h> uint16_t const report_desc_size[HID_NUM_INTERFACES] = { 46 }; uint8_t const report_len_input[HID_NUM_INTERFACES] = { 48 }; /*-----------------------------------------------------------------------------+ | Device Descriptor |-----------------------------------------------------------------------------*/ uint8_t const abromDeviceDescriptor[SIZEOF_DEVICE_DESCRIPTOR] = { SIZEOF_DEVICE_DESCRIPTOR, // Length of this descriptor DESC_TYPE_DEVICE, // Type code of this descriptor 0x00, 0x02, // Release of USB spec 0x00, // Device's base class code 0x00, // Device's sub class code 0x00, // Device's protocol type code EP0_PACKET_SIZE, // End point 0's packet size USB_VID&0xFF, USB_VID>>8, // Vendor ID for device, TI=0x0451 // You can order your own VID at www.usb.org" USB_PID&0xFF, USB_PID>>8, // Product ID for device, // this ID is to only with this example VER_FW_L, VER_FW_H, // Revision level of device 1, // Index of manufacturer name string desc 2, // Index of product name string desc USB_STR_INDEX_SERNUM, // Index of serial number string desc 1 // Number of configurations supported }; /*-----------------------------------------------------------------------------+ | Configuration Descriptor | |-----------------------------------------------------------------------------*/ const struct abromConfigurationDescriptorGroup abromConfigurationDescriptorGroup= { /* Generic part */ { // CONFIGURATION DESCRIPTOR (9 bytes) SIZEOF_CONFIG_DESCRIPTOR, // bLength DESC_TYPE_CONFIG, // bDescriptorType DESCRIPTOR_TOTAL_LENGTH, 0x00, // wTotalLength USB_NUM_INTERFACES, // bNumInterfaces USB_CONFIG_VALUE, // bConfigurationvalue CONFIG_STRING_INDEX, // iConfiguration Description offset USB_SUPPORT_SELF_POWERED | USB_SUPPORT_REM_WAKE, // bmAttributes, bus power, remote wakeup USB_MAX_POWER // Max. Power Consumption }, /******************************************************* start of HID*************************************/ { /*start HID[0] Here */ { //-------- Descriptor for HID class device ------------------------------------- // INTERFACE DESCRIPTOR (9 bytes) SIZEOF_INTERFACE_DESCRIPTOR, // bLength DESC_TYPE_INTERFACE, // bDescriptorType: 4 HID0_REPORT_INTERFACE, // bInterfaceNumber 0x00, // bAlternateSetting 2, // bNumEndpoints 0x03, // bInterfaceClass: 3 = HID Device 0, // bInterfaceSubClass: 0, // bInterfaceProtocol: INTF_STRING_INDEX + 0, // iInterface:1 // HID DESCRIPTOR (9 bytes) 0x09, // bLength of HID descriptor 0x21, // HID Descriptor Type: 0x21 0x01,0x01, // HID Revision number 1.01 0x00, // Target country, nothing specified (00h) 0x01, // Number of HID classes to follow 0x22, // Report descriptor type (report_desc_size_HID0 & 0x0ff), // Total length of report descriptor (report_desc_size_HID0 >> 8), SIZEOF_ENDPOINT_DESCRIPTOR, // bLength DESC_TYPE_ENDPOINT, // bDescriptorType HID0_INEP_ADDR, // bEndpointAddress; bit7=1 for IN, bits 3-0=1 for ep1 EP_DESC_ATTR_TYPE_INT, // bmAttributes, interrupt transfers 0x40, 0x00, // wMaxPacketSize, 64 bytes 25, // bInterval, ms SIZEOF_ENDPOINT_DESCRIPTOR, // bLength DESC_TYPE_ENDPOINT, // bDescriptorType HID0_OUTEP_ADDR, // bEndpointAddress; bit7=1 for IN, bits 3-0=1 for ep1 EP_DESC_ATTR_TYPE_INT, // bmAttributes, interrupt transfers 0x40, 0x00, // wMaxPacketSize, 64 bytes 25, // bInterval, ms /* end of HID[0]*/ } } /******************************************************* end of HID**************************************/ }; /*-----------------------------------------------------------------------------+ | String Descriptor | |-----------------------------------------------------------------------------*/ uint8_t const abromStringDescriptor[] = { // String index0, language support 4, // Length of language descriptor ID 3, // LANGID tag 0x09, 0x04, // 0x0409 for English // String index1, Manufacturer 36, // Length of this string descriptor 3, // bDescriptorType 'T',0x00,'e',0x00,'x',0x00,'a',0x00,'s',0x00,' ',0x00, 'I',0x00,'n',0x00,'s',0x00,'t',0x00,'r',0x00,'u',0x00, 'm',0x00,'e',0x00,'n',0x00,'t',0x00,'s',0x00, // String index2, Product 38, // Length of this string descriptor 3, // bDescriptorType 'M',0x00,'S',0x00,'P',0x00,'4',0x00,'3',0x00,'0',0x00, '-',0x00,'U',0x00,'S',0x00,'B',0x00,' ',0x00,'E',0x00, 'x',0x00,'a',0x00,'m',0x00,'p',0x00,'l',0x00,'e',0x00, // String index3, Serial Number 4, // Length of this string descriptor 3, // bDescriptorType '0',0x00, // String index4, Configuration String 22, // Length of this string descriptor 3, // bDescriptorType 'M',0x00,'S',0x00,'P',0x00,'4',0x00,'3',0x00,'0',0x00, ' ',0x00,'U',0x00,'S',0x00,'B',0x00, // String index5, Interface String 28, // Length of this string descriptor 3, // bDescriptorType 'H',0x00,'I',0x00,'D',0x00,' ',0x00,'I',0x00,'n',0x00, 't',0x00,'e',0x00,'r',0x00,'f',0x00,'a',0x00,'c',0x00, 'e',0x00 }; uint8_t const report_desc_HID0[]= { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x05, // USAGE (Game Pad) 0xA1, 0x01, // COLLECTION (Application) 0xA1, 0x00, // COLLECTION (Physical) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x10, // USAGE_MAXIMUM (Button 16) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x10, // REPORT_COUNT (16) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x09, 0x32, // USAGE (Z) 0x09, 0x33, // USAGE (Rx) 0x15, 0x81, // LOGICAL_MINIMUM (-127) 0x25, 0x7F, // LOGICAL_MAXIMUM (127) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x04, // REPORT_COUNT (4) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xC0, // END COLLECTION 0xC0 // END COLLECTION }; const uint8_t* report_desc[HID_NUM_INTERFACES] = { (uint8_t*)&report_desc_HID0 }; /**** Populating the endpoint information handle here ****/ const struct tUsbHandle stUsbHandle[]= { { HID0_INEP_ADDR, HID0_OUTEP_ADDR, 0, HID_CLASS, 0, 0, OEP1_X_BUFFER_ADDRESS, OEP1_Y_BUFFER_ADDRESS, IEP1_X_BUFFER_ADDRESS, IEP1_Y_BUFFER_ADDRESS } }; //-------------DEVICE REQUEST LIST--------------------------------------------- const tDEVICE_REQUEST_COMPARE tUsbRequestList[] = { { //---- HID 0 Class Requests -----// USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_GET_REPORT, 0xff,0xff, HID0_REPORT_INTERFACE,0x00, 0xff,0xff, 0xcc,&usbGetReport, }, { // SET REPORT USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_SET_REPORT, 0xff,0xFF, // bValueL is index and bValueH is type HID0_REPORT_INTERFACE,0x00, 0xff,0xff, 0xcc,&usbSetReport, }, { // GET REPORT DESCRIPTOR USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_GET_DESCRIPTOR, 0xff,DESC_TYPE_REPORT, // bValueL is index and bValueH is type HID0_REPORT_INTERFACE,0x00, 0xff,0xff, 0xdc,&usbGetReportDescriptor, }, { // GET HID DESCRIPTOR USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_GET_DESCRIPTOR, 0xff,DESC_TYPE_HID, // bValueL is index and bValueH is type HID0_REPORT_INTERFACE,0x00, 0xff,0xff, 0xdc,&usbGetHidDescriptor, }, { //---- USB Standard Requests -----// // clear device feature USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_CLEAR_FEATURE, FEATURE_REMOTE_WAKEUP,0x00, // feature selector 0x00,0x00, 0x00,0x00, 0xff,&usbClearDeviceFeature, }, { // clear endpoint feature USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT, USB_REQ_CLEAR_FEATURE, FEATURE_ENDPOINT_STALL,0x00, 0xff,0x00, 0x00,0x00, 0xf7,&usbClearEndpointFeature, }, { // get configuration USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_GET_CONFIGURATION, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0xff,&usbGetConfiguration, }, { // get device descriptor USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_GET_DESCRIPTOR, 0xff,DESC_TYPE_DEVICE, // bValueL is index and bValueH is type 0xff,0xff, 0xff,0xff, 0xd0,&usbGetDeviceDescriptor, }, { // get configuration descriptor USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_GET_DESCRIPTOR, 0xff,DESC_TYPE_CONFIG, // bValueL is index and bValueH is type 0xff,0xff, 0xff,0xff, 0xd0,&usbGetConfigurationDescriptor, }, { // get string descriptor USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_GET_DESCRIPTOR, 0xff,DESC_TYPE_STRING, // bValueL is index and bValueH is type 0xff,0xff, 0xff,0xff, 0xd0,&usbGetStringDescriptor, }, { // get interface USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_GET_INTERFACE, 0x00,0x00, 0xff,0xff, 0x01,0x00, 0xf3,&usbGetInterface, }, { // get device status USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_GET_STATUS, 0x00,0x00, 0x00,0x00, 0x02,0x00, 0xff,&usbGetDeviceStatus, }, { // get interface status USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_GET_STATUS, 0x00,0x00, 0xff,0x00, 0x02,0x00, 0xf7,&usbGetInterfaceStatus, }, { // get endpoint status USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT, USB_REQ_GET_STATUS, 0x00,0x00, 0xff,0x00, 0x02,0x00, 0xf7,&usbGetEndpointStatus, }, { // set address USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_SET_ADDRESS, 0xff,0x00, 0x00,0x00, 0x00,0x00, 0xdf,&usbSetAddress, }, { // set configuration USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_SET_CONFIGURATION, 0xff,0x00, 0x00,0x00, 0x00,0x00, 0xdf,&usbSetConfiguration, }, { // set device feature USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, USB_REQ_SET_FEATURE, 0xff,0x00, // feature selector 0x00,0x00, 0x00,0x00, 0xdf,&usbSetDeviceFeature, }, { // set endpoint feature USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT, USB_REQ_SET_FEATURE, 0xff,0x00, // feature selector 0xff,0x00, // endpoint number <= 127 0x00,0x00, 0xd7,&usbSetEndpointFeature, }, { // set interface USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_SET_INTERFACE, 0xff,0x00, // feature selector 0xff,0x00, // interface number 0x00,0x00, 0xd7,&usbSetInterface, }, { // end of usb descriptor -- this one will be matched to any USB request // since bCompareMask is 0x00. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,&usbInvalidRequest // end of list } }; /*-----------------------------------------------------------------------------+ | END OF Descriptor.c FILE |-----------------------------------------------------------------------------*/ //Released_Version_5_20_06_03
-使用实例
/* --COPYRIGHT--,BSD * Copyright (c) 2015, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ // Generated by MSP USB Descriptor Tool: Fri Jul 09 10:27:06 BST 2021 /*-----------------------------------------------------------------------------+ | Include files | |-----------------------------------------------------------------------------*/ #include <USB_API/USB_Common/device.h> // Basic Type declarations #include <USB_API/USB_Common/defMSP430USB.h> #include "descriptors.h" #include <USB_API/USB_Common/usb.h> //USB-specific Data Structures #include <USB_API/USB_Common/UsbIsr.h> #include <string.h> #include <USB_API/USB_HID_API/UsbHid.h> #include <USB_API/USB_HID_API/UsbHidReq.h> /*----------------------------------------------------------------------------+ | External Variables | +----------------------------------------------------------------------------*/ extern uint8_t bFunctionSuspended; extern __no_init tEDB0 __data16 tEndPoint0DescriptorBlock; extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[]; extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[]; extern volatile uint8_t bHostAsksUSBData; extern volatile uint8_t bTransferInProgress; extern volatile uint8_t bSecondUartTxDataCounter[]; extern volatile uint8_t* pbSecondUartTxData; extern uint8_t bStatusAction; extern uint16_t wUsbEventMask; int16_t CdcToHostFromBuffer(uint8_t); int16_t CdcToBufferFromHost(uint8_t); int16_t CdcIsReceiveInProgress(uint8_t); int16_t HidToHostFromBuffer(uint8_t); int16_t HidToBufferFromHost(uint8_t); int16_t HidIsReceiveInProgress(uint8_t); extern uint16_t wUsbHidEventMask; int16_t PHDCToHostFromBuffer(uint8_t); int16_t PHDCToBufferFromHost(uint8_t); int16_t PHDCIsReceiveInProgress(uint8_t); uint16_t USB_determineFreq(void); /*----------------------------------------------------------------------------+ | General Subroutines | +----------------------------------------------------------------------------*/ #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) #pragma vector=USB_UBM_VECTOR __interrupt void iUsbInterruptHandler(void) #elif defined(__GNUC__) && (__MSP430__) void __attribute__ ((interrupt(USB_UBM_VECTOR))) iUsbInterruptHandler(void) #endif { uint8_t bWakeUp = FALSE; //Check if the setup interrupt is pending. //We need to check it before other interrupts, //to work around that the Setup Int has lower priority then Input Endpoint 0 if (USBIFG & SETUPIFG) { bWakeUp = SetupPacketInterruptHandler(); #ifdef USB10_WORKAROUND tEndPoint0DescriptorBlock.bIEPCNFG &= ~EPCNF_UBME; // Clear ME to gate off SETUPIFG clear event tEndPoint0DescriptorBlock.bOEPCNFG &= ~EPCNF_UBME; // Clear ME to gate off SETUPIFG clear event #endif USBIFG &= ~SETUPIFG; // clear the interrupt bit #ifdef USB10_WORKAROUND tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_UBME; // Set ME to continue with normal operation tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_UBME; // Set ME to continue with normal operation #endif } switch (__even_in_range(USBVECINT & 0x3f, USBVECINT_OUTPUT_ENDPOINT7)) { case USBVECINT_NONE: break; case USBVECINT_PWR_DROP: __no_operation(); break; case USBVECINT_PLL_LOCK: break; case USBVECINT_PLL_SIGNAL: break; case USBVECINT_PLL_RANGE: if (wUsbEventMask & USB_CLOCK_FAULT_EVENT) { bWakeUp = USB_handleClockEvent(); } break; case USBVECINT_PWR_VBUSOn: PWRVBUSonHandler(); if (wUsbEventMask & USB_VBUS_ON_EVENT) { bWakeUp = USB_handleVbusOnEvent(); } break; case USBVECINT_PWR_VBUSOff: PWRVBUSoffHandler(); if (wUsbEventMask & USB_VBUS_OFF_EVENT) { bWakeUp = USB_handleVbusOffEvent(); } break; case USBVECINT_USB_TIMESTAMP: break; case USBVECINT_INPUT_ENDPOINT0: IEP0InterruptHandler(); break; case USBVECINT_OUTPUT_ENDPOINT0: OEP0InterruptHandler(); break; case USBVECINT_RSTR: USB_reset(); if (wUsbEventMask & USB_RESET_EVENT) { bWakeUp = USB_handleResetEvent(); } break; case USBVECINT_SUSR: USB_suspend(); if (wUsbEventMask & USB_SUSPENDED_EVENT) { bWakeUp = USB_handleSuspendEvent(); } break; case USBVECINT_RESR: USB_resume(); if (wUsbEventMask & USB_RESUME_EVENT) { bWakeUp = USB_handleResumeEvent(); } //-- after resume we will wake up! Independ what event handler says. bWakeUp = TRUE; break; case USBVECINT_SETUP_PACKET_RECEIVED: // NAK both IEP and OEP enpoints tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK; tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK; SetupPacketInterruptHandler(); break; case USBVECINT_STPOW_PACKET_RECEIVED: break; case USBVECINT_INPUT_ENDPOINT1: //send saved bytes from buffer... bWakeUp = HidToHostFromBuffer(HID0_INTFNUM); break; case USBVECINT_INPUT_ENDPOINT2: break; case USBVECINT_INPUT_ENDPOINT3: break; case USBVECINT_INPUT_ENDPOINT4: break; case USBVECINT_INPUT_ENDPOINT5: break; case USBVECINT_INPUT_ENDPOINT6: break; case USBVECINT_INPUT_ENDPOINT7: break; case USBVECINT_OUTPUT_ENDPOINT1: //call callback function if no receive operation is underway if (!HidIsReceiveInProgress(HID0_INTFNUM)) { if (wUsbEventMask & USB_DATA_RECEIVED_EVENT) { bWakeUp = USBHID_handleDataReceived(HID0_INTFNUM); } } else { //complete receive opereation - copy data to user buffer bWakeUp = HidToBufferFromHost(HID0_INTFNUM); } break; case USBVECINT_OUTPUT_ENDPOINT2: break; case USBVECINT_OUTPUT_ENDPOINT3: break; case USBVECINT_OUTPUT_ENDPOINT4: break; case USBVECINT_OUTPUT_ENDPOINT5: break; case USBVECINT_OUTPUT_ENDPOINT6: break; case USBVECINT_OUTPUT_ENDPOINT7: break; default: break; } if (bWakeUp) { __bic_SR_register_on_exit(LPM3_bits); // Exit LPM0-3 __no_operation(); // Required for debugger } } /*----------------------------------------------------------------------------+ | Interrupt Sub-routines | +----------------------------------------------------------------------------*/ uint8_t SetupPacketInterruptHandler(void) { uint8_t bTemp; uint8_t bWakeUp = FALSE; USBCTL |= FRSTE; // Function Reset Connection Enable - set enable after first setup packet was received usbProcessNewSetupPacket: // copy the MSB of bmRequestType to DIR bit of USBCTL if((tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT) == USB_REQ_TYPE_INPUT) { USBCTL |= DIR; } else { USBCTL &= ~DIR; } bStatusAction = STATUS_ACTION_NOTHING; // clear out return data buffer for(bTemp=0; bTemp<USB_RETURN_DATA_LENGTH; bTemp++) { abUsbRequestReturnData[bTemp] = 0x00; } // decode and process the request bWakeUp = usbDecodeAndProcessUsbRequest(); // check if there is another setup packet pending // if it is, abandon current one by NAKing both data endpoint 0 if((USBIFG & STPOWIFG) != 0x00) { USBIFG &= ~(STPOWIFG | SETUPIFG); goto usbProcessNewSetupPacket; } return bWakeUp; } //---------------------------------------------------------------------------- void PWRVBUSoffHandler(void) { uint16_t MCLKFreq = USB_determineFreq(); uint16_t DelayConstant_250us = ((MCLKFreq >> 6) + (MCLKFreq >> 7) + (MCLKFreq >> 9)); volatile uint16_t i, j; //wait 1 ms till enable USB for(j = 0; j < 4; j++) { for (i = 0; i < (DelayConstant_250us); i++){ _NOP(); } } if (!(USBPWRCTL & USBBGVBV)) { USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled bEnumerationStatus = 0x00; // device is not enumerated bFunctionSuspended = FALSE; // device is not suspended USBCNF = 0; // disable USB module USBPLLCTL &= ~UPLLEN; // disable PLL USBPWRCTL &= ~(VBOFFIE + VBOFFIFG + SLDOEN); // disable interrupt VBUSoff USBKEYPID = 0x9600; // access to configuration registers disabled } } //---------------------------------------------------------------------------- void PWRVBUSonHandler(void) { uint16_t MCLKFreq = USB_determineFreq(); uint16_t DelayConstant_250us = ((MCLKFreq >> 6) + (MCLKFreq >> 7) + (MCLKFreq >> 9)); volatile uint16_t i, j; //wait 1 ms till enable USB for(j = 0; j < 4; j++) { for (i = 0; i < (DelayConstant_250us); i++){ _NOP(); } } if (USBPWRCTL & USBBGVBV) //Checking for USB Bandgap and VBUS valid before modifying USBPWRCTL { USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled USBPWRCTL |= VBOFFIE; // enable interrupt VBUSoff USBPWRCTL &= ~ (VBONIFG + VBOFFIFG); // clean int flag (bouncing) USBKEYPID = 0x9600; // access to configuration registers disabled } } //---------------------------------------------------------------------------- void IEP0InterruptHandler(void) { USBCTL |= FRSTE; // Function Reset Connection Enable tEndPoint0DescriptorBlock.bOEPBCNT = 0x00; if(bStatusAction == STATUS_ACTION_DATA_IN) { usbSendNextPacketOnIEP0(); } else { tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL; // no more data } } //---------------------------------------------------------------------------- uint8_t OEP0InterruptHandler(void) { uint8_t bWakeUp = FALSE; USBCTL |= FRSTE; // Function Reset Connection Enable tEndPoint0DescriptorBlock.bIEPBCNT = 0x00; if(bStatusAction == STATUS_ACTION_DATA_OUT) { usbReceiveNextPacketOnOEP0(); if(bStatusAction == STATUS_ACTION_NOTHING) { # ifdef _CDC_ if(tSetupPacket.bRequest == USB_CDC_SET_LINE_CODING) { bWakeUp = Handler_SetLineCoding(); } # endif #ifdef _HID_ if (tSetupPacket.bRequest == USB_REQ_SET_REPORT) { bWakeUp = USBHID_handleEP0SetReportDataAvailable(tSetupPacket.wIndex); } #endif } } else { tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL; // no more data } return (bWakeUp); } /*----------------------------------------------------------------------------+ | End of source file | +----------------------------------------------------------------------------*/ /*------------------------ Nothing Below This Line --------------------------*/ //Released_Version_5_20_06_03
您好,Hishan,
让我看看我是否能找到能够提供帮助的人。
您好,Hishan,
我对这个没有运气、所以让我看看我是否可以设置一些东西来模拟您尝试的东西。
器件型号:MSP430F5529
各位专家、您好!
几周前、我尝试使用具有7-14个模拟输入的 MSP430来模拟 USB-HID 游戏。 我在为定制的 USB-HID 设备获取描述符时遇到问题。 我发布了我的代码、但没有人能帮助我。
幸运 的是、我在网上看到了这个代码:GitHub - TI-FIRST /MSP430-Gamead:适用于 FRC 的 MSP430F5529 Gamead 代码、它帮助我启动 MSP430并将其作为具有8个模拟输入的游戏 epad 运行。
main.c 文件包含更改报告结构的说明:
*此示例在主机上充当游戏 epad。 游戏手柄具有 HID 报告、如所述
* descriptors.c 中的 REPORT_desc_HID0变量 请注意、如果是此报告结构
*已更改、则需要更新以下长度-
* 1. descriptors.h 中的#define REPORT_desc_size_HID0需要使用描述符大小进行更新
* 2. 需要在描述符.c 中更新 REPORT_desc_size 和 REPORT_len_input
*本演示将枚举18个字节的输入报告和2个字节的输出报告
*游戏 epad 的输入和输出报告结构,如 USB_gamepad.h 中所述
*输入报告用于报告 ADC 值和按钮状态(GPIO)
*输出报告用于设置/复位指示器(GPIO)
目前在 descriptors.c 文件中的描述符是:
UsagePage(USB_HID_GENERIC_DESKTOP), Usage(USB_HID_JOYSTICK), Collection(USB_HID_APPLICATION), // // The axis for the controller. // UsagePage(USB_HID_GENERIC_DESKTOP), Usage (USB_HID_POINTER), Collection (USB_HID_PHYSICAL), // // The X, Y and Z values which are specified as 8-bit absolute // position values. // Usage (USB_HID_X), Usage (USB_HID_Y), Usage (USB_HID_Z), Usage (USB_HID_RX), Usage (USB_HID_RY), Usage (USB_HID_RZ), Usage (USB_HID_SLIDER), Usage (USB_HID_DIAL), // // 8 16-bit absolute values. // ReportSize(16), ReportCount(8), Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS), // // Max 32 buttons. // UsagePage(USB_HID_BUTTONS), UsageMinimum(1), UsageMaximum(NUM_BUTTONS), LogicalMinimum(0), LogicalMaximum(1), PhysicalMinimum(0), PhysicalMaximum(1), // // 8 - 1 bit values for the buttons. // ReportSize(1), ReportCount(32), Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS), // // Max 16 indicator bits // UsagePage(USB_HID_BUTTONS), UsageMinimum(1), UsageMaximum(NUM_INDICATORS), LogicalMinimum(0), LogicalMaximum(1), PhysicalMinimum(0), PhysicalMaximum(1), // // 8 - 1 bit values for the leds. // ReportSize(1), ReportCount(16), Output(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS), EndCollection, EndCollection
我想将其更改为14个16位模拟输入、如下所示:
UsagePage(USB_HID_GENERIC_DESKTOP), Usage(USB_HID_JOYSTICK), Collection(USB_HID_APPLICATION), // // The axis for the controller. // UsagePage(USB_HID_GENERIC_DESKTOP), Usage (USB_HID_POINTER), Collection (USB_HID_PHYSICAL), // // The X, Y and Z values which are specified as 8-bit absolute // position values. // Usage (USB_HID_X), Usage (USB_HID_Y), Usage (USB_HID_Z), Usage (USB_HID_RX), Usage (USB_HID_RY), Usage (USB_HID_RZ), Usage (USB_HID_SLIDER), Usage (USB_HID_DIAL), Usage (USB_HID_VX), Usage (USB_HID_VY), Usage (USB_HID_VZ), Usage (USB_HID_VRX), Usage (USB_HID_VRY), Usage (USB_HID_VRZ), // // 8 16-bit absolute values. // ReportSize(16), ReportCount(14), Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS), // // Max 32 buttons. // UsagePage(USB_HID_BUTTONS), UsageMinimum(1), UsageMaximum(6), LogicalMinimum(0), LogicalMaximum(1), PhysicalMinimum(0), PhysicalMaximum(1), // // 8 - 1 bit values for the buttons. // ReportSize(1), ReportCount(32), Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS), // // Max 16 indicator bits // UsagePage(USB_HID_BUTTONS), UsageMinimum(1), UsageMaximum(6), LogicalMinimum(0), LogicalMaximum(1), PhysicalMinimum(0), PhysicalMaximum(1), // // 8 - 1 bit values for the leds. // ReportSize(1), ReportCount(16), Output(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS), EndCollection, EndCollection
但是、我不知道如何计算描述符的长度/大小/字节。 我尝试了 USB-HID 规范(HID 1.11的器件类定义| USB-IF)、该规范指出项目具有字节前缀、但我无法确定要计数的项目以及它们的累加方式。 抱歉、我在 USB 方面经验不足。
我认为描述符的大小是32字节? 但计算机在插入时未检测到游戏手柄、因为我认为 我在 report_len_input 中得到的值是错误的。
是否有人能够查看代码、并让我知道 描述符文件中 REPORT_desc_size、REPORT_len_input 以及我需要更改的任何其他值、以扩展14个16位模拟输入的代码功能。
P.S.要复制和查看正在工作的游戏 epad、只需将代码上传到开发套件并在 Windows 上搜索"设置 USB 游戏控制器"、如果一切运行正常且报告被接受、则应将其识别为游戏 epad。
谢谢!
您好,Hishan,
我将您的帖子合并在一起、因为它们实际上与同一个主题有关。
对于 HID、我们的 USB 开发包和描述符工具本身仅支持一些 HID 类型、即键盘、鼠标和数据擦除。 任何其他"传统"HID 类型都需要通过描述符工具中的"自定义"功能来完成、您需要在该工具中输入原始报告描述符。 我们目前无法支持您创建此自定义描述符以满足您的需求。 我建议查看第三方资源或指南、了解描述符报告对于您所选 HID 类型的外观。
大家好、
我正在加入本次对话、因为我们遇到了与此非常类似的问题。
由于这个 USB 描述符工具是 TI 特有的、所以我很难理解如果您无法帮助我们、我们如何获得支持? 您能否向我介绍有关第三方资源、推荐阅读或指南、以了解我们如何在该问题上获得额外支持?
谢谢
垫
大家好、
USB 描述符工具是 TI 制作的、用于帮助您在使用的 PC 上正确获取支持的 HID 类型。 我们允许自定义类别扩展到本机不支持的 HID 类类型。 游戏手柄/游戏手柄属于此类别。 您可以通过 USB HID 规范或其他在线论坛找到此类的正确描述符字段。 stackexchange 是一个查看一般知识的好论坛、430h.com 是一个独立的 MSP430特定论坛、您可以在其中找到所需的内容。