各位专家、您好!
我目前正在尝试使用 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