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