Commit dc83f73c authored by Dean Camera's avatar Dean Camera
Browse files

Added new GenericHID device demo application.

parent d83d87e1
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions.
*/
#include "Descriptors.h"
/** HID class report descriptor. This is a special descriptor constructed with values from the
* USBIF HID class specification to describe the reports and capabilities of the HID device. This
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
* the device will send, and what it may be sent back from the host. Refer to the HID specification for
* more details on HID report descriptors.
*/
USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
{
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
0x09, 0x01, /* Usage (Vendor Defined) */
0xa1, 0x01, /* Collection (Vendor Defined) */
0x09, 0x02, /* Usage (Vendor Defined) */
0x75, 0x08, /* Report Size (8) */
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0xff, /* Logical Maximum (255) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x09, 0x03, /* Usage (Vendor Defined) */
0x75, 0x08, /* Report Size (8) */
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0xff, /* Logical Maximum (255) */
0x91, 0x02, /* Output (Data, Variable, Absolute) */
0xc0 /* End Collection */
};
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins.
*/
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
Header: {Size: sizeof(USB_Descriptor_Device_t), Type: DTYPE_Device},
USBSpecification: VERSION_BCD(01.10),
Class: 0x00,
SubClass: 0x00,
Protocol: 0x00,
Endpoint0Size: 8,
VendorID: 0x03EB,
ProductID: 0x204F,
ReleaseNumber: 0x0000,
ManufacturerStrIndex: 0x01,
ProductStrIndex: 0x02,
SerialNumStrIndex: NO_DESCRIPTOR,
NumberOfConfigurations: 1
};
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device.
*/
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
Config:
{
Header: {Size: sizeof(USB_Descriptor_Configuration_Header_t), Type: DTYPE_Configuration},
TotalConfigurationSize: sizeof(USB_Descriptor_Configuration_t),
TotalInterfaces: 1,
ConfigurationNumber: 1,
ConfigurationStrIndex: NO_DESCRIPTOR,
ConfigAttributes: (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
MaxPowerConsumption: USB_CONFIG_POWER_MA(100)
},
Interface:
{
Header: {Size: sizeof(USB_Descriptor_Interface_t), Type: DTYPE_Interface},
InterfaceNumber: 0x00,
AlternateSetting: 0x00,
TotalEndpoints: 2,
Class: 0x03,
SubClass: 0x00,
Protocol: 0x00,
InterfaceStrIndex: NO_DESCRIPTOR
},
GenericHID:
{
Header: {Size: sizeof(USB_Descriptor_HID_t), Type: DTYPE_HID},
HIDSpec: VERSION_BCD(01.11),
CountryCode: 0x00,
TotalHIDReports: 0x01,
HIDReportType: DTYPE_Report,
HIDReportLength: sizeof(GenericReport)
},
GenericINEndpoint:
{
Header: {Size: sizeof(USB_Descriptor_Endpoint_t), Type: DTYPE_Endpoint},
EndpointAddress: (ENDPOINT_DESCRIPTOR_DIR_IN | GENERIC_IN_EPNUM),
Attributes: EP_TYPE_INTERRUPT,
EndpointSize: GENERIC_EPSIZE,
PollingIntervalMS: 0x02
},
GenericOUTEndpoint:
{
Header: {Size: sizeof(USB_Descriptor_Endpoint_t), Type: DTYPE_Endpoint},
EndpointAddress: (ENDPOINT_DESCRIPTOR_DIR_OUT | GENERIC_OUT_EPNUM),
Attributes: EP_TYPE_INTERRUPT,
EndpointSize: GENERIC_EPSIZE,
PollingIntervalMS: 0x02
}
};
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/
USB_Descriptor_String_t PROGMEM LanguageString =
{
Header: {Size: USB_STRING_LEN(1), Type: DTYPE_String},
UnicodeString: {LANGUAGE_ID_ENG}
};
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
USB_Descriptor_String_t PROGMEM ManufacturerString =
{
Header: {Size: USB_STRING_LEN(11), Type: DTYPE_String},
UnicodeString: L"Dean Camera"
};
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
USB_Descriptor_String_t PROGMEM ProductString =
{
Header: {Size: USB_STRING_LEN(13), Type: DTYPE_String},
UnicodeString: L"LUFA HID Demo"
};
/** This function is called by the library when in device mode, and must be overridden (see StdDescriptors.h
* documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device recieves a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host.
*/
uint16_t USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType)
{
case DTYPE_Device:
Address = DESCRIPTOR_ADDRESS(DeviceDescriptor);
Size = sizeof(USB_Descriptor_Device_t);
break;
case DTYPE_Configuration:
Address = DESCRIPTOR_ADDRESS(ConfigurationDescriptor);
Size = sizeof(USB_Descriptor_Configuration_t);
break;
case DTYPE_String:
switch (DescriptorNumber)
{
case 0x00:
Address = DESCRIPTOR_ADDRESS(LanguageString);
Size = pgm_read_byte(&LanguageString.Header.Size);
break;
case 0x01:
Address = DESCRIPTOR_ADDRESS(ManufacturerString);
Size = pgm_read_byte(&ManufacturerString.Header.Size);
break;
case 0x02:
Address = DESCRIPTOR_ADDRESS(ProductString);
Size = pgm_read_byte(&ProductString.Header.Size);
break;
}
break;
case DTYPE_HID:
Address = DESCRIPTOR_ADDRESS(ConfigurationDescriptor.GenericHID);
Size = sizeof(USB_Descriptor_HID_t);
break;
case DTYPE_Report:
Address = DESCRIPTOR_ADDRESS(GenericReport);
Size = sizeof(GenericReport);
break;
}
*DescriptorAddress = Address;
return Size;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for Descriptors.c.
*/
#ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include <avr/pgmspace.h>
/* Type Defines: */
/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
* specification for details on the structure elements.
*/
typedef struct
{
USB_Descriptor_Header_t Header;
uint16_t HIDSpec;
uint8_t CountryCode;
uint8_t TotalHIDReports;
uint8_t HIDReportType;
uint16_t HIDReportLength;
} USB_Descriptor_HID_t;
/** Type define for the data type used to store HID report descriptor elements. */
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
*/
typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t Interface;
USB_Descriptor_HID_t GenericHID;
USB_Descriptor_Endpoint_t GenericINEndpoint;
USB_Descriptor_Endpoint_t GenericOUTEndpoint;
} USB_Descriptor_Configuration_t;
/* Macros: */
/** Endpoint number of the Generic HID reporting IN endpoint. */
#define GENERIC_IN_EPNUM 1
/** Endpoint number of the Generic HID reporting OUT endpoint. */
#define GENERIC_OUT_EPNUM 2
/** Size in bytes of the Generic HID reporting endpoint. */
#define GENERIC_EPSIZE 8
/** Size in bytes of the Generic HID reports (including report ID byte). */
#define GENERIC_REPORT_SIZE 8
/** Descriptor header type value, to indicate a HID class HID descriptor. */
#define DTYPE_HID 0x21
/** Descriptor header type value, to indicate a HID class HID report descriptor. */
#define DTYPE_Report 0x22
/* Function Prototypes: */
uint16_t USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif
# Doxyfile 1.5.7.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = "LUFA Library - Generic HID Device Demo"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.0.0
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = ./Documentation/
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
# format and will distribute the generated files over these directories.
# Enabling this option can be useful when feeding doxygen a huge amount of
# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.
CREATE_SUBDIRS = YES
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene,
# Spanish, Swedish, and Ukrainian.
OUTPUT_LANGUAGE = English
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator
# that is used to form the text in various listings. Each string
# in this list, if found as the leading text of the brief description, will be
# stripped from the text and the result after processing the whole list, is
# used as the annotated text. Otherwise, the brief description is used as-is.
# If left blank, the following values are used ("$name" is automatically
# replaced with the name of the entity): "The $name class" "The $name widget"
# "The $name file" "is" "provides" "specifies" "contains"
# "represents" "a" "an" "the"
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells
# the reader which header file to include in order to use a class.
# If left blank only the name of the header file containing the class
# definition is used. Otherwise one should specify the include paths that
# are normally passed to the compiler using the -I flag.
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like regular Qt-style comments
# (thus requiring an explicit @brief command for a brief description.)
JAVADOC_AUTOBRIEF = NO
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
# interpret the first line (until the first dot) of a Qt-style
# comment as the brief description. If set to NO, the comments
# will behave just like regular Qt-style comments (thus requiring
# an explicit \brief command for a brief description.)
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
# comments) as a brief description. This used to be the default behaviour.
# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.
MULTILINE_CPP_IS_BRIEF = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# re-implements.
INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
# a new page for each member. If set to NO, the documentation of a member will
# be part of the file/class/namespace that contains it.
SEPARATE_MEMBER_PAGES = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 4
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
# sources only. Doxygen will then generate output that is more tailored for
# Java. For instance, namespaces will be presented as packages, qualified
# scopes will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources only. Doxygen will then generate output that is more tailored for
# Fortran.
OPTIMIZE_FOR_FORTRAN = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for
# VHDL.
OPTIMIZE_OUTPUT_VHDL = NO
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
# set this tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
# func(std::string) {}). This also make the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
BUILTIN_STL_SUPPORT = NO
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
# Doxygen will parse them like normal C++ but will assume all classes use public
# instead of private inheritance when no explicit protection keyword is present.
SIP_SUPPORT = NO
# For Microsoft's IDL there are propget and propput attributes to indicate getter
# and setter methods for a property. Setting this option to YES (the default)
# will make doxygen to replace the get and set methods by a property in the
# documentation. This will only work if the methods are indeed getting or
# setting a simple type. If this is not the case, or you want to show the
# methods anyway, you should set this option to NO.
IDL_PROPERTY_SUPPORT = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
# the same type (for instance a group of public functions) to be put as a
# subgroup of that type (e.g. under the Public Functions section). Set it to
# NO to prevent subgrouping. Alternatively, this can be done per class using
# the \nosubgrouping command.
SUBGROUPING = YES
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
# is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically
# be useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
TYPEDEF_HIDES_STRUCT = NO
# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
# determine which symbols to keep in memory and which to flush to disk.
# When the cache is full, less often used symbols will be written to disk.
# For small to medium size projects (<1000 input files) the default value is