Add svn:eol-style property to source files, so that the line endings are correctly converted to the target system's native end of line style.

This commit is contained in:
Dean Camera 2010-05-08 03:12:14 +00:00
parent e331b531c6
commit 071e02c6b6
839 changed files with 274562 additions and 274562 deletions

View file

@ -1,78 +1,78 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Audio Class driver.
*
* Master include file for the library USB Audio Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassAudio Audio Class Driver - LUFA/Drivers/Class/Audio.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/Audio.c
*
* \section Module Description
* Audio Class Driver module. This module contains an internal implementation of the USB Audio Class, for Device
* USB mode only. User applications can use this class driver instead of implementing the Audio class manually via
* the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB Audio Class.
*
* @{
*/
#ifndef _AUDIO_CLASS_H_
#define _AUDIO_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_AUDIO_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/Audio.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Audio Class driver.
*
* Master include file for the library USB Audio Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassAudio Audio Class Driver - LUFA/Drivers/Class/Audio.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/Audio.c
*
* \section Module Description
* Audio Class Driver module. This module contains an internal implementation of the USB Audio Class, for Device
* USB mode only. User applications can use this class driver instead of implementing the Audio class manually via
* the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB Audio Class.
*
* @{
*/
#ifndef _AUDIO_CLASS_H_
#define _AUDIO_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_AUDIO_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/Audio.h"
#endif
#endif
/** @} */

View file

@ -1,83 +1,83 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB CDC-ACM Class driver.
*
* Master include file for the library USB CDC Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassCDC CDC-ACM (Virtual Serial) Class Driver - LUFA/Drivers/Class/CDC.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/CDC.c
* - LUFA/Drivers/USB/Class/Host/CDC.c
*
* \section Module Description
* CDC Class Driver module. This module contains an internal implementation of the USB CDC-ACM class Virtual Serial
* Ports, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
* CDC class manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB CDC Class.
*
* @{
*/
#ifndef _CDC_CLASS_H_
#define _CDC_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_CDC_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/CDC.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/CDC.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB CDC-ACM Class driver.
*
* Master include file for the library USB CDC Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassCDC CDC-ACM (Virtual Serial) Class Driver - LUFA/Drivers/Class/CDC.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/CDC.c
* - LUFA/Drivers/USB/Class/Host/CDC.c
*
* \section Module Description
* CDC Class Driver module. This module contains an internal implementation of the USB CDC-ACM class Virtual Serial
* Ports, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
* CDC class manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB CDC Class.
*
* @{
*/
#ifndef _CDC_CLASS_H_
#define _CDC_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_CDC_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/CDC.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/CDC.h"
#endif
#endif
/** @} */

View file

@ -1,406 +1,406 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Audio Class driver.
*
* Common definitions and declarations for the library USB Audio Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Audio.h.
*/
/** \ingroup Group_USBClassAudio
* @defgroup Group_USBClassAudioCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Audio Class.
*
* @{
*/
#ifndef _AUDIO_CLASS_COMMON_H_
#define _AUDIO_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Audio.h instead.
#endif
/* Macros: */
#if !defined(AUDIO_TOTAL_SAMPLE_RATES) || defined(__DOXYGEN__)
/** Total number of discrete audio sample rates supported by the device. This value can be overridden by defining this
* token in the project makefile to the desired value, and passing it to the compiler via the -D switch.
*/
#define AUDIO_TOTAL_SAMPLE_RATES 1
#endif
/** Descriptor header constant to indicate a Audio class interface descriptor. */
#define DTYPE_AudioInterface 0x24
/** Descriptor header constant to indicate a Audio class endpoint descriptor. */
#define DTYPE_AudioEndpoint 0x25
/** Audio class descriptor subtype value for a Audio class specific header descriptor. */
#define DSUBTYPE_Header 0x01
/** Audio class descriptor subtype value for an Output Terminal Audio class specific descriptor. */
#define DSUBTYPE_InputTerminal 0x02
/** Audio class descriptor subtype value for an Input Terminal Audio class specific descriptor. */
#define DSUBTYPE_OutputTerminal 0x03
/** Audio class descriptor subtype value for a Feature Unit Audio class specific descriptor. */
#define DSUBTYPE_FeatureUnit 0x06
/** Audio class descriptor subtype value for a general Audio class specific descriptor. */
#define DSUBTYPE_General 0x01
/** Audio class descriptor subtype value for an Audio class specific descriptor indicating the format of an audio stream. */
#define DSUBTYPE_Format 0x02
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LEFT_FRONT (1 << 0)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_RIGHT_FRONT (1 << 1)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_CENTER_FRONT (1 << 2)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LOW_FREQ_ENHANCE (1 << 3)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LEFT_SURROUND (1 << 4)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_RIGHT_SURROUND (1 << 5)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LEFT_OF_CENTER (1 << 6)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_RIGHT_OF_CENTER (1 << 7)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_SURROUND (1 << 8)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_SIDE_LEFT (1 << 9)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_SIDE_RIGHT (1 << 10)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_TOP (1 << 11)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_MUTE (1 << 0)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_VOLUME (1 << 1)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_BASS (1 << 2)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_MID (1 << 3)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_TREBLE (1 << 4)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_GRAPHIC_EQUALIZER (1 << 5)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_AUTOMATIC_GAIN (1 << 6)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_DELAY (1 << 7)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_BASS_BOOST (1 << 8)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_BASS_LOUDNESS (1 << 9)
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_UNDEFINED 0x0100
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_STREAMING 0x0101
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_VENDOR 0x01FF
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_UNDEFINED 0x0200
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_MIC 0x0201
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_DESKTOP_MIC 0x0202
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_PERSONAL_MIC 0x0203
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_OMNIDIR_MIC 0x0204
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_MIC_ARRAY 0x0205
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_PROCESSING_MIC 0x0206
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_OUT_UNDEFINED 0x0300
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_SPEAKER 0x0301
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_HEADPHONES 0x0302
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_HEAD_MOUNTED 0x0303
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_DESKTOP 0x0304
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_ROOM 0x0305
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_COMMUNICATION 0x0306
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_LOWFREQ 0x0307
/** Convenience macro, to fill a 24-bit AudioSampleFreq_t structure with the given sample rate as a 24-bit number.
*
* \param[in] freq Required audio sampling frequency in HZ
*/
#define AUDIO_SAMPLE_FREQ(freq) {LowWord: ((uint32_t)freq & 0x00FFFF), HighByte: (((uint32_t)freq >> 16) & 0x0000FF)}
/** Mask for the attributes parameter of an Audio class specific Endpoint descriptor, indicating that the endpoint
* accepts only filled endpoint packets of audio samples.
*/
#define EP_ACCEPTS_ONLY_FULL_PACKETS (1 << 7)
/** Mask for the attributes parameter of an Audio class specific Endpoint descriptor, indicating that the endpoint
* will accept partially filled endpoint packets of audio samples.
*/
#define EP_ACCEPTS_SMALL_PACKETS (0 << 7)
/* Type Defines: */
/** \brief Audio Class Specific Interface Descriptor.
*
* Type define for an Audio class specific interface descriptor. This follows a regular interface descriptor to
* supply extra information about the audio device's layout to the host. See the USB Audio specification for more
* details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint16_t ACSpecification; /**< Binary coded decimal value, indicating the supported Audio Class specification version */
uint16_t TotalLength; /**< Total length of the Audio class specific descriptors, including this descriptor */
uint8_t InCollection; /**< Total number of audio class interfaces within this device */
uint8_t InterfaceNumbers[1]; /**< Interface numbers of each audio interface */
} USB_Audio_Interface_AC_t;
/** \brief Audio Class Specific Feature Unit Descriptor.
*
* Type define for an Audio class specific Feature Unit descriptor. This indicates to the host what features
* are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio
* specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t UnitID; /**< ID value of this feature unit - must be a unique value within the device */
uint8_t SourceID; /**< Source ID value of the audio source input into this feature unit */
uint8_t ControlSize; /**< Size of each element in the ChanelControlls array */
uint8_t ChannelControls[3]; /**< Feature masks for the control channel, and each separate audio channel */
uint8_t FeatureUnitStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_Audio_FeatureUnit_t;
/** \brief Audio Class Specific Input Terminal Descriptor.
*
* Type define for an Audio class specific input terminal descriptor. This indicates to the host that the device
* contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example,
* a USB endpoint). See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device */
uint16_t TerminalType; /**< Type of terminal, a TERMINAL_* mask */
uint8_t AssociatedOutputTerminal; /**< ID of associated output terminal, for physically grouped terminals
* such as the speaker and microphone of a phone handset
*/
uint8_t TotalChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */
uint16_t ChannelConfig; /**< CHANNEL_* masks indicating what channel layout is supported by this terminal */
uint8_t ChannelStrIndex; /**< Index of a string descriptor describing this channel within the device */
uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_Audio_InputTerminal_t;
/** \brief Audio Class Specific Output Terminal Descriptor.
*
* Type define for an Audio class specific output terminal descriptor. This indicates to the host that the device
* contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example,
* a USB endpoint). See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device */
uint16_t TerminalType; /**< Type of terminal, a TERMINAL_* mask */
uint8_t AssociatedInputTerminal; /**< ID of associated input terminal, for physically grouped terminals
* such as the speaker and microphone of a phone handset
*/
uint8_t SourceID; /**< ID value of the unit this terminal's audio is sourced from */
uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_Audio_OutputTerminal_t;
/** \brief Audio Class Specific Streaming Audio Interface Descriptor.
*
* Type define for an Audio class specific streaming interface descriptor. This indicates to the host
* how audio streams within the device are formatted. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TerminalLink; /**< ID value of the output terminal this descriptor is describing */
uint8_t FrameDelay; /**< Delay in frames resulting from the complete sample processing from input to output */
uint16_t AudioFormat; /**< Format of the audio stream, see Audio Device Formats specification */
} USB_Audio_Interface_AS_t;
/** \brief 24-Bit Audio Frequency Structure.
*
* Type define for a 24bit audio sample frequency structure. GCC does not contain a built in 24bit datatype,
* this this structure is used to build up the value instead. Fill this structure with the SAMPLE_FREQ() macro.
*/
typedef struct
{
uint16_t LowWord; /**< Low 16 bits of the 24-bit value */
uint8_t HighByte; /**< Upper 8 bits of the 24-bit value */
} USB_Audio_SampleFreq_t;
/** \brief Audio Class Specific Format Descriptor.
*
* Type define for an Audio class specific audio format descriptor. This is used to give the host full details
* about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used
* in the device's audio streams. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t FormatType; /**< Format of the audio stream, see Audio Device Formats specification */
uint8_t Channels; /**< Total number of discrete channels in the stream */
uint8_t SubFrameSize; /**< Size in bytes of each channel's sample data in the stream */
uint8_t BitResolution; /**< Bits of resolution of each channel's samples in the stream */
uint8_t SampleFrequencyType; /**< Total number of sample frequencies supported by the device */
USB_Audio_SampleFreq_t SampleFrequencies[AUDIO_TOTAL_SAMPLE_RATES]; /**< Sample frequencies supported by the device */
} USB_Audio_Format_t;
/** \brief Audio Class Specific Streaming Endpoint Descriptor.
*
* Type define for an Audio class specific endpoint descriptor. This contains a regular endpoint
* descriptor with a few Audio-class specific extensions. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Endpoint_t Endpoint; /**< Standard endpoint descriptor describing the audio endpoint */
uint8_t Refresh; /**< Always set to zero */
uint8_t SyncEndpointNumber; /**< Endpoint address to send synchronization information to, if needed (zero otherwise) */
} USB_Audio_StreamEndpoint_Std_t;
/** \brief Audio Class Specific Extended Endpoint Descriptor.
*
* Type define for an Audio class specific extended endpoint descriptor. This contains extra information
* on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio
* class specific extended endpoint descriptor. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t Attributes; /**< Audio class specific endpoint attributes, such as ACCEPTS_SMALL_PACKETS */
uint8_t LockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification */
uint16_t LockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry */
} USB_Audio_StreamEndpoint_Spc_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Audio Class driver.
*
* Common definitions and declarations for the library USB Audio Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Audio.h.
*/
/** \ingroup Group_USBClassAudio
* @defgroup Group_USBClassAudioCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Audio Class.
*
* @{
*/
#ifndef _AUDIO_CLASS_COMMON_H_
#define _AUDIO_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Audio.h instead.
#endif
/* Macros: */
#if !defined(AUDIO_TOTAL_SAMPLE_RATES) || defined(__DOXYGEN__)
/** Total number of discrete audio sample rates supported by the device. This value can be overridden by defining this
* token in the project makefile to the desired value, and passing it to the compiler via the -D switch.
*/
#define AUDIO_TOTAL_SAMPLE_RATES 1
#endif
/** Descriptor header constant to indicate a Audio class interface descriptor. */
#define DTYPE_AudioInterface 0x24
/** Descriptor header constant to indicate a Audio class endpoint descriptor. */
#define DTYPE_AudioEndpoint 0x25
/** Audio class descriptor subtype value for a Audio class specific header descriptor. */
#define DSUBTYPE_Header 0x01
/** Audio class descriptor subtype value for an Output Terminal Audio class specific descriptor. */
#define DSUBTYPE_InputTerminal 0x02
/** Audio class descriptor subtype value for an Input Terminal Audio class specific descriptor. */
#define DSUBTYPE_OutputTerminal 0x03
/** Audio class descriptor subtype value for a Feature Unit Audio class specific descriptor. */
#define DSUBTYPE_FeatureUnit 0x06
/** Audio class descriptor subtype value for a general Audio class specific descriptor. */
#define DSUBTYPE_General 0x01
/** Audio class descriptor subtype value for an Audio class specific descriptor indicating the format of an audio stream. */
#define DSUBTYPE_Format 0x02
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LEFT_FRONT (1 << 0)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_RIGHT_FRONT (1 << 1)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_CENTER_FRONT (1 << 2)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LOW_FREQ_ENHANCE (1 << 3)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LEFT_SURROUND (1 << 4)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_RIGHT_SURROUND (1 << 5)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_LEFT_OF_CENTER (1 << 6)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_RIGHT_OF_CENTER (1 << 7)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_SURROUND (1 << 8)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_SIDE_LEFT (1 << 9)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_SIDE_RIGHT (1 << 10)
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define CHANNEL_TOP (1 << 11)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_MUTE (1 << 0)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_VOLUME (1 << 1)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_BASS (1 << 2)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_MID (1 << 3)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_TREBLE (1 << 4)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_GRAPHIC_EQUALIZER (1 << 5)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_AUTOMATIC_GAIN (1 << 6)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_DELAY (1 << 7)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_BASS_BOOST (1 << 8)
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
#define FEATURE_BASS_LOUDNESS (1 << 9)
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_UNDEFINED 0x0100
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_STREAMING 0x0101
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_VENDOR 0x01FF
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_UNDEFINED 0x0200
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_MIC 0x0201
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_DESKTOP_MIC 0x0202
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_PERSONAL_MIC 0x0203
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_OMNIDIR_MIC 0x0204
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_MIC_ARRAY 0x0205
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_PROCESSING_MIC 0x0206
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_IN_OUT_UNDEFINED 0x0300
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_SPEAKER 0x0301
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_HEADPHONES 0x0302
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_HEAD_MOUNTED 0x0303
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_DESKTOP 0x0304
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_ROOM 0x0305
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_COMMUNICATION 0x0306
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
#define TERMINAL_OUT_LOWFREQ 0x0307
/** Convenience macro, to fill a 24-bit AudioSampleFreq_t structure with the given sample rate as a 24-bit number.
*
* \param[in] freq Required audio sampling frequency in HZ
*/
#define AUDIO_SAMPLE_FREQ(freq) {LowWord: ((uint32_t)freq & 0x00FFFF), HighByte: (((uint32_t)freq >> 16) & 0x0000FF)}
/** Mask for the attributes parameter of an Audio class specific Endpoint descriptor, indicating that the endpoint
* accepts only filled endpoint packets of audio samples.
*/
#define EP_ACCEPTS_ONLY_FULL_PACKETS (1 << 7)
/** Mask for the attributes parameter of an Audio class specific Endpoint descriptor, indicating that the endpoint
* will accept partially filled endpoint packets of audio samples.
*/
#define EP_ACCEPTS_SMALL_PACKETS (0 << 7)
/* Type Defines: */
/** \brief Audio Class Specific Interface Descriptor.
*
* Type define for an Audio class specific interface descriptor. This follows a regular interface descriptor to
* supply extra information about the audio device's layout to the host. See the USB Audio specification for more
* details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint16_t ACSpecification; /**< Binary coded decimal value, indicating the supported Audio Class specification version */
uint16_t TotalLength; /**< Total length of the Audio class specific descriptors, including this descriptor */
uint8_t InCollection; /**< Total number of audio class interfaces within this device */
uint8_t InterfaceNumbers[1]; /**< Interface numbers of each audio interface */
} USB_Audio_Interface_AC_t;
/** \brief Audio Class Specific Feature Unit Descriptor.
*
* Type define for an Audio class specific Feature Unit descriptor. This indicates to the host what features
* are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio
* specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t UnitID; /**< ID value of this feature unit - must be a unique value within the device */
uint8_t SourceID; /**< Source ID value of the audio source input into this feature unit */
uint8_t ControlSize; /**< Size of each element in the ChanelControlls array */
uint8_t ChannelControls[3]; /**< Feature masks for the control channel, and each separate audio channel */
uint8_t FeatureUnitStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_Audio_FeatureUnit_t;
/** \brief Audio Class Specific Input Terminal Descriptor.
*
* Type define for an Audio class specific input terminal descriptor. This indicates to the host that the device
* contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example,
* a USB endpoint). See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device */
uint16_t TerminalType; /**< Type of terminal, a TERMINAL_* mask */
uint8_t AssociatedOutputTerminal; /**< ID of associated output terminal, for physically grouped terminals
* such as the speaker and microphone of a phone handset
*/
uint8_t TotalChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */
uint16_t ChannelConfig; /**< CHANNEL_* masks indicating what channel layout is supported by this terminal */
uint8_t ChannelStrIndex; /**< Index of a string descriptor describing this channel within the device */
uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_Audio_InputTerminal_t;
/** \brief Audio Class Specific Output Terminal Descriptor.
*
* Type define for an Audio class specific output terminal descriptor. This indicates to the host that the device
* contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example,
* a USB endpoint). See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device */
uint16_t TerminalType; /**< Type of terminal, a TERMINAL_* mask */
uint8_t AssociatedInputTerminal; /**< ID of associated input terminal, for physically grouped terminals
* such as the speaker and microphone of a phone handset
*/
uint8_t SourceID; /**< ID value of the unit this terminal's audio is sourced from */
uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_Audio_OutputTerminal_t;
/** \brief Audio Class Specific Streaming Audio Interface Descriptor.
*
* Type define for an Audio class specific streaming interface descriptor. This indicates to the host
* how audio streams within the device are formatted. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TerminalLink; /**< ID value of the output terminal this descriptor is describing */
uint8_t FrameDelay; /**< Delay in frames resulting from the complete sample processing from input to output */
uint16_t AudioFormat; /**< Format of the audio stream, see Audio Device Formats specification */
} USB_Audio_Interface_AS_t;
/** \brief 24-Bit Audio Frequency Structure.
*
* Type define for a 24bit audio sample frequency structure. GCC does not contain a built in 24bit datatype,
* this this structure is used to build up the value instead. Fill this structure with the SAMPLE_FREQ() macro.
*/
typedef struct
{
uint16_t LowWord; /**< Low 16 bits of the 24-bit value */
uint8_t HighByte; /**< Upper 8 bits of the 24-bit value */
} USB_Audio_SampleFreq_t;
/** \brief Audio Class Specific Format Descriptor.
*
* Type define for an Audio class specific audio format descriptor. This is used to give the host full details
* about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used
* in the device's audio streams. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t FormatType; /**< Format of the audio stream, see Audio Device Formats specification */
uint8_t Channels; /**< Total number of discrete channels in the stream */
uint8_t SubFrameSize; /**< Size in bytes of each channel's sample data in the stream */
uint8_t BitResolution; /**< Bits of resolution of each channel's samples in the stream */
uint8_t SampleFrequencyType; /**< Total number of sample frequencies supported by the device */
USB_Audio_SampleFreq_t SampleFrequencies[AUDIO_TOTAL_SAMPLE_RATES]; /**< Sample frequencies supported by the device */
} USB_Audio_Format_t;
/** \brief Audio Class Specific Streaming Endpoint Descriptor.
*
* Type define for an Audio class specific endpoint descriptor. This contains a regular endpoint
* descriptor with a few Audio-class specific extensions. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Endpoint_t Endpoint; /**< Standard endpoint descriptor describing the audio endpoint */
uint8_t Refresh; /**< Always set to zero */
uint8_t SyncEndpointNumber; /**< Endpoint address to send synchronization information to, if needed (zero otherwise) */
} USB_Audio_StreamEndpoint_Std_t;
/** \brief Audio Class Specific Extended Endpoint Descriptor.
*
* Type define for an Audio class specific extended endpoint descriptor. This contains extra information
* on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio
* class specific extended endpoint descriptor. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t Attributes; /**< Audio class specific endpoint attributes, such as ACCEPTS_SMALL_PACKETS */
uint8_t LockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification */
uint16_t LockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry */
} USB_Audio_StreamEndpoint_Spc_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,179 +1,179 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB CDC Class driver.
*
* Common definitions and declarations for the library USB CDC Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/CDC.h.
*/
/** \ingroup Group_USBClassCDC
* @defgroup Group_USBClassCDCCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* CDC Class.
*
* @{
*/
#ifndef _CDC_CLASS_COMMON_H_
#define _CDC_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/CDC.h instead.
#endif
/* Macros: */
/** CDC Class specific request to get the current virtual serial port configuration settings. */
#define REQ_GetLineEncoding 0x21
/** CDC Class specific request to set the current virtual serial port configuration settings. */
#define REQ_SetLineEncoding 0x20
/** CDC Class specific request to set the current virtual serial port handshake line states. */
#define REQ_SetControlLineState 0x22
/** CDC Class specific request to send a break to the receiver via the carrier channel. */
#define REQ_SendBreak 0x23
/** CDC Class specific request to send an encapsulated command to the device. */
#define REQ_SendEncapsulatedCommand 0x00
/** CDC Class specific request to retrieve an encapsulated command response from the device. */
#define REQ_GetEncapsulatedResponse 0x01
/** Notification type constant for a change in the virtual serial port handshake line states, for
* use with a USB_Notification_Header_t notification structure when sent to the host via the CDC
* notification endpoint.
*/
#define NOTIF_SerialState 0x20
/** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
* from the host, to indicate that the DTR line state should be high.
*/
#define CDC_CONTROL_LINE_OUT_DTR (1 << 0)
/** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
* from the host, to indicate that theRTS line state should be high.
*/
#define CDC_CONTROL_LINE_OUT_RTS (1 << 1)
/** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the DCD line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_DCD (1 << 0)
/** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the DSR line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_DSR (1 << 1)
/** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the BREAK line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_BREAK (1 << 2)
/** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the RING line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_RING (1 << 3)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a framing error has occurred on the virtual serial port.
*/
#define CDC_CONTROL_LINE_IN_FRAMEERROR (1 << 4)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a parity error has occurred on the virtual serial port.
*/
#define CDC_CONTROL_LINE_IN_PARITYERROR (1 << 5)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a data overrun error has occurred on the virtual serial port.
*/
#define CDC_CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
* uniform structure but variable sized data payloads, thus cannot be represented accurately by
* a single typedef struct. A macro is used instead so that functional descriptors can be created
* easily by specifying the size of the payload. This allows sizeof() to work correctly.
*
* \param[in] DataSize Size in bytes of the CDC functional descriptor's data payload
*/
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
struct \
{ \
USB_Descriptor_Header_t Header; \
uint8_t SubType; \
uint8_t Data[DataSize]; \
}
/* Enums: */
/** Enum for the possible line encoding formats of a virtual serial port. */
enum CDC_LineCodingFormats_t
{
CDC_LINEENCODING_OneStopBit = 0, /**< Each frame contains one stop bit */
CDC_LINEENCODING_OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
CDC_LINEENCODING_TwoStopBits = 2, /**< Each frame contains two stop bits */
};
/** Enum for the possible line encoding parity settings of a virtual serial port. */
enum CDC_LineCodingParity_t
{
CDC_PARITY_None = 0, /**< No parity bit mode on each frame */
CDC_PARITY_Odd = 1, /**< Odd parity bit mode on each frame */
CDC_PARITY_Even = 2, /**< Even parity bit mode on each frame */
CDC_PARITY_Mark = 3, /**< Mark parity bit mode on each frame */
CDC_PARITY_Space = 4, /**< Space parity bit mode on each frame */
};
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB CDC Class driver.
*
* Common definitions and declarations for the library USB CDC Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/CDC.h.
*/
/** \ingroup Group_USBClassCDC
* @defgroup Group_USBClassCDCCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* CDC Class.
*
* @{
*/
#ifndef _CDC_CLASS_COMMON_H_
#define _CDC_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/CDC.h instead.
#endif
/* Macros: */
/** CDC Class specific request to get the current virtual serial port configuration settings. */
#define REQ_GetLineEncoding 0x21
/** CDC Class specific request to set the current virtual serial port configuration settings. */
#define REQ_SetLineEncoding 0x20
/** CDC Class specific request to set the current virtual serial port handshake line states. */
#define REQ_SetControlLineState 0x22
/** CDC Class specific request to send a break to the receiver via the carrier channel. */
#define REQ_SendBreak 0x23
/** CDC Class specific request to send an encapsulated command to the device. */
#define REQ_SendEncapsulatedCommand 0x00
/** CDC Class specific request to retrieve an encapsulated command response from the device. */
#define REQ_GetEncapsulatedResponse 0x01
/** Notification type constant for a change in the virtual serial port handshake line states, for
* use with a USB_Notification_Header_t notification structure when sent to the host via the CDC
* notification endpoint.
*/
#define NOTIF_SerialState 0x20
/** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
* from the host, to indicate that the DTR line state should be high.
*/
#define CDC_CONTROL_LINE_OUT_DTR (1 << 0)
/** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
* from the host, to indicate that theRTS line state should be high.
*/
#define CDC_CONTROL_LINE_OUT_RTS (1 << 1)
/** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the DCD line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_DCD (1 << 0)
/** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the DSR line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_DSR (1 << 1)
/** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the BREAK line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_BREAK (1 << 2)
/** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the RING line state is currently high.
*/
#define CDC_CONTROL_LINE_IN_RING (1 << 3)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a framing error has occurred on the virtual serial port.
*/
#define CDC_CONTROL_LINE_IN_FRAMEERROR (1 << 4)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a parity error has occurred on the virtual serial port.
*/
#define CDC_CONTROL_LINE_IN_PARITYERROR (1 << 5)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a data overrun error has occurred on the virtual serial port.
*/
#define CDC_CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
* uniform structure but variable sized data payloads, thus cannot be represented accurately by
* a single typedef struct. A macro is used instead so that functional descriptors can be created
* easily by specifying the size of the payload. This allows sizeof() to work correctly.
*
* \param[in] DataSize Size in bytes of the CDC functional descriptor's data payload
*/
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
struct \
{ \
USB_Descriptor_Header_t Header; \
uint8_t SubType; \
uint8_t Data[DataSize]; \
}
/* Enums: */
/** Enum for the possible line encoding formats of a virtual serial port. */
enum CDC_LineCodingFormats_t
{
CDC_LINEENCODING_OneStopBit = 0, /**< Each frame contains one stop bit */
CDC_LINEENCODING_OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
CDC_LINEENCODING_TwoStopBits = 2, /**< Each frame contains two stop bits */
};
/** Enum for the possible line encoding parity settings of a virtual serial port. */
enum CDC_LineCodingParity_t
{
CDC_PARITY_None = 0, /**< No parity bit mode on each frame */
CDC_PARITY_Odd = 1, /**< Odd parity bit mode on each frame */
CDC_PARITY_Even = 2, /**< Even parity bit mode on each frame */
CDC_PARITY_Mark = 3, /**< Mark parity bit mode on each frame */
CDC_PARITY_Space = 4, /**< Space parity bit mode on each frame */
};
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,195 +1,195 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB HID Class driver.
*
* Common definitions and declarations for the library USB HID Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/HID.h.
*/
/** \ingroup Group_USBClassHID
* @defgroup Group_USBClassHIDCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* HID Class.
*
* @{
*/
#ifndef _HID_CLASS_COMMON_H_
#define _HID_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_HID_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/HID.h instead.
#endif
/* Macros: */
/** HID Class Specific Request to get the current HID report from the device. */
#define REQ_GetReport 0x01
/** HID Class Specific Request to get the current device idle count. */
#define REQ_GetIdle 0x02
/** HID Class Specific Request to set the current HID report to the device. */
#define REQ_SetReport 0x09
/** HID Class Specific Request to set the device's idle count. */
#define REQ_SetIdle 0x0A
/** HID Class Specific Request to get the current HID report protocol mode. */
#define REQ_GetProtocol 0x03
/** HID Class Specific Request to set the current HID report protocol mode. */
#define REQ_SetProtocol 0x0B
/** 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
/** Constant for the protocol value of a HID interface descriptor, indicating that the interface does not support
* any HID class boot protocol (see HID Class Specification).
*/
#define HID_NON_BOOT_PROTOCOL 0x00
/** Constant for the protocol value of a HID interface descriptor, indicating that the interface supports the
* HID class Keyboard boot protocol (see HID Class Specification).
*/
#define HID_BOOT_KEYBOARD_PROTOCOL 0x01
/** Constant for the protocol value of a HID interface descriptor, indicating that the interface supports the
* HID class Mouse boot protocol (see HID Class Specification).
*/
#define HID_BOOT_MOUSE_PROTOCOL 0x02
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left control key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTCTRL (1 << 0)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left shift key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTSHIFT (1 << 1)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left alt key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTALT (1 << 2)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left GUI key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTGUI (1 << 3)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right control key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTCTRL (1 << 4)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right shift key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTSHIFT (1 << 5)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right alt key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTALT (1 << 6)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right GUI key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTGUI (1 << 7)
/** Constant for a keyboard output report LED byte, indicating that the host's NUM LOCK mode is currently set. */
#define HID_KEYBOARD_LED_NUMLOCK (1 << 0)
/** Constant for a keyboard output report LED byte, indicating that the host's CAPS LOCK mode is currently set. */
#define HID_KEYBOARD_LED_CAPSLOCK (1 << 1)
/** Constant for a keyboard output report LED byte, indicating that the host's SCROLL LOCK mode is currently set. */
#define HID_KEYBOARD_LED_SCROLLLOCK (1 << 2)
/** Constant for a keyboard output report LED byte, indicating that the host's KATANA mode is currently set. */
#define HID_KEYBOARD_LED_KATANA (1 << 3)
/* Type Defines: */
/** Enum for the different types of HID reports. */
enum HID_ReportItemTypes_t
{
REPORT_ITEM_TYPE_In = 0, /**< Indicates that the item is an IN report type. */
REPORT_ITEM_TYPE_Out = 1, /**< Indicates that the item is an OUT report type. */
REPORT_ITEM_TYPE_Feature = 2, /**< Indicates that the item is a FEATURE report type. */
};
/** \brief HID Class Specific HID Descriptor.
*
* 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 TotalReportDescriptors;
uint8_t HIDReportType;
uint16_t HIDReportLength;
} USB_HID_Descriptor_t;
/** \brief Standard HID Boot Protocol Mouse Report.
*
* Type define for a standard Boot Protocol Mouse report
*/
typedef struct
{
uint8_t Button; /**< Button mask for currently pressed buttons in the mouse */
int8_t X; /**< Current delta X movement of the mouse */
int8_t Y; /**< Current delta Y movement on the mouse */
} USB_MouseReport_Data_t;
/** \brief Standard HID Boot Protocol Keyboard Report.
*
* Type define for a standard Boot Protocol Keyboard report
*/
typedef struct
{
uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of
* HID_KEYBOARD_MODIFER_* masks)
*/
uint8_t Reserved; /**< Reserved for OEM use, always set to 0 */
uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys */
} USB_KeyboardReport_Data_t;
/** Type define for the data type used to store HID report descriptor elements. */
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB HID Class driver.
*
* Common definitions and declarations for the library USB HID Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/HID.h.
*/
/** \ingroup Group_USBClassHID
* @defgroup Group_USBClassHIDCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* HID Class.
*
* @{
*/
#ifndef _HID_CLASS_COMMON_H_
#define _HID_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_HID_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/HID.h instead.
#endif
/* Macros: */
/** HID Class Specific Request to get the current HID report from the device. */
#define REQ_GetReport 0x01
/** HID Class Specific Request to get the current device idle count. */
#define REQ_GetIdle 0x02
/** HID Class Specific Request to set the current HID report to the device. */
#define REQ_SetReport 0x09
/** HID Class Specific Request to set the device's idle count. */
#define REQ_SetIdle 0x0A
/** HID Class Specific Request to get the current HID report protocol mode. */
#define REQ_GetProtocol 0x03
/** HID Class Specific Request to set the current HID report protocol mode. */
#define REQ_SetProtocol 0x0B
/** 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
/** Constant for the protocol value of a HID interface descriptor, indicating that the interface does not support
* any HID class boot protocol (see HID Class Specification).
*/
#define HID_NON_BOOT_PROTOCOL 0x00
/** Constant for the protocol value of a HID interface descriptor, indicating that the interface supports the
* HID class Keyboard boot protocol (see HID Class Specification).
*/
#define HID_BOOT_KEYBOARD_PROTOCOL 0x01
/** Constant for the protocol value of a HID interface descriptor, indicating that the interface supports the
* HID class Mouse boot protocol (see HID Class Specification).
*/
#define HID_BOOT_MOUSE_PROTOCOL 0x02
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left control key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTCTRL (1 << 0)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left shift key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTSHIFT (1 << 1)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left alt key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTALT (1 << 2)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left GUI key is currently pressed. */
#define HID_KEYBOARD_MODIFER_LEFTGUI (1 << 3)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right control key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTCTRL (1 << 4)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right shift key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTSHIFT (1 << 5)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right alt key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTALT (1 << 6)
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right GUI key is currently pressed. */
#define HID_KEYBOARD_MODIFER_RIGHTGUI (1 << 7)
/** Constant for a keyboard output report LED byte, indicating that the host's NUM LOCK mode is currently set. */
#define HID_KEYBOARD_LED_NUMLOCK (1 << 0)
/** Constant for a keyboard output report LED byte, indicating that the host's CAPS LOCK mode is currently set. */
#define HID_KEYBOARD_LED_CAPSLOCK (1 << 1)
/** Constant for a keyboard output report LED byte, indicating that the host's SCROLL LOCK mode is currently set. */
#define HID_KEYBOARD_LED_SCROLLLOCK (1 << 2)
/** Constant for a keyboard output report LED byte, indicating that the host's KATANA mode is currently set. */
#define HID_KEYBOARD_LED_KATANA (1 << 3)
/* Type Defines: */
/** Enum for the different types of HID reports. */
enum HID_ReportItemTypes_t
{
REPORT_ITEM_TYPE_In = 0, /**< Indicates that the item is an IN report type. */
REPORT_ITEM_TYPE_Out = 1, /**< Indicates that the item is an OUT report type. */
REPORT_ITEM_TYPE_Feature = 2, /**< Indicates that the item is a FEATURE report type. */
};
/** \brief HID Class Specific HID Descriptor.
*
* 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 TotalReportDescriptors;
uint8_t HIDReportType;
uint16_t HIDReportLength;
} USB_HID_Descriptor_t;
/** \brief Standard HID Boot Protocol Mouse Report.
*
* Type define for a standard Boot Protocol Mouse report
*/
typedef struct
{
uint8_t Button; /**< Button mask for currently pressed buttons in the mouse */
int8_t X; /**< Current delta X movement of the mouse */
int8_t Y; /**< Current delta Y movement on the mouse */
} USB_MouseReport_Data_t;
/** \brief Standard HID Boot Protocol Keyboard Report.
*
* Type define for a standard Boot Protocol Keyboard report
*/
typedef struct
{
uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of
* HID_KEYBOARD_MODIFER_* masks)
*/
uint8_t Reserved; /**< Reserved for OEM use, always set to 0 */
uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys */
} USB_KeyboardReport_Data_t;
/** Type define for the data type used to store HID report descriptor elements. */
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
#endif
/** @} */

View file

@ -1,189 +1,189 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB MIDI Class driver.
*
* Common definitions and declarations for the library USB MIDI Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MIDI.h.
*/
/** \ingroup Group_USBClassMIDI
* @defgroup Group_USBClassMIDICommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* MIDI Class.
*
* @{
*/
#ifndef _MIDI_CLASS_COMMON_H_
#define _MIDI_CLASS_COMMON_H_
/* Macros: */
#define __INCLUDE_FROM_AUDIO_DRIVER
/* Includes: */
#include "../../USB.h"
#include "Audio.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MIDI.h instead.
#endif
/* Macros: */
/** Audio class descriptor subtype value for a Audio class specific MIDI input jack descriptor. */
#define DSUBTYPE_InputJack 0x02
/** Audio class descriptor subtype value for a Audio class specific MIDI output jack descriptor. */
#define DSUBTYPE_OutputJack 0x03
/** Audio class descriptor jack type value for an embedded (logical) MIDI input or output jack. */
#define MIDI_JACKTYPE_EMBEDDED 0x01
/** Audio class descriptor jack type value for an external (physical) MIDI input or output jack. */
#define MIDI_JACKTYPE_EXTERNAL 0x02
/** MIDI command for a note on (activation) event */
#define MIDI_COMMAND_NOTE_ON 0x90
/** MIDI command for a note off (deactivation) event */
#define MIDI_COMMAND_NOTE_OFF 0x80
/** Standard key press velocity value used for all note events */
#define MIDI_STANDARD_VELOCITY 64
/** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel
* addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address.
*
* \param[in] channel MIDI channel number to address
*/
#define MIDI_CHANNEL(channel) ((channel) - 1)
/* Type Defines: */
/** \brief MIDI Class Specific Streaming Interface Descriptor.
*
* Type define for an Audio class specific MIDI streaming interface descriptor. This indicates to the host
* how MIDI the specification compliance of the device and the total length of the Audio class specific descriptors.
* See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint16_t AudioSpecification; /**< Binary coded decimal value, indicating the supported Audio Class specification version */
uint16_t TotalLength; /**< Total length of the Audio class specific descriptors, including this descriptor */
} USB_MIDI_AudioInterface_AS_t;
/** \brief MIDI Class Specific Input Jack Descriptor.
*
* Type define for an Audio class specific MIDI IN jack. This gives information to the host on a MIDI input, either
* a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint).
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t JackType; /**< Type of jack, one of the JACKTYPE_* mask values */
uint8_t JackID; /**< ID value of this jack - must be a unique value within the device */
uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_MIDI_In_Jack_t;
/** \brief MIDI Class Specific Output Jack Descriptor.
*
* Type define for an Audio class specific MIDI OUT jack. This gives information to the host on a MIDI output, either
* a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint).
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t JackType; /**< Type of jack, one of the JACKTYPE_* mask values */
uint8_t JackID; /**< ID value of this jack - must be a unique value within the device */
uint8_t NumberOfPins; /**< Number of output channels within the jack, either physical or logical */
uint8_t SourceJackID[1]; /**< ID of each output pin's source data jack */
uint8_t SourcePinID[1]; /**< Pin number in the input jack of each output pin's source data */
uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_MIDI_Out_Jack_t;
/** \brief Audio Class Specific Jack Endpoint Descriptor.
*
* Type define for an Audio class specific extended MIDI jack endpoint descriptor. This contains extra information
* on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio
* class specific extended MIDI endpoint descriptor. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TotalEmbeddedJacks; /**< Total number of jacks inside this endpoint */
uint8_t AssociatedJackID[1]; /**< IDs of each jack inside the endpoint */
} USB_MIDI_Jack_Endpoint_t;
/** \brief MIDI Class Driver Event Packet.
*
* Type define for a USB MIDI event packet, used to encapsulate sent and received MIDI messages from a USB MIDI interface.
*/
typedef struct
{
unsigned char Command : 4; /**< Upper nibble of the MIDI command being sent or received in the event packet */
unsigned char CableNumber : 4; /**< Virtual cable number of the event being sent or received in the given MIDI interface */
uint8_t Data1; /**< First byte of data in the MIDI event */
uint8_t Data2; /**< Second byte of data in the MIDI event */
uint8_t Data3; /**< Third byte of data in the MIDI event */
} MIDI_EventPacket_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB MIDI Class driver.
*
* Common definitions and declarations for the library USB MIDI Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MIDI.h.
*/
/** \ingroup Group_USBClassMIDI
* @defgroup Group_USBClassMIDICommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* MIDI Class.
*
* @{
*/
#ifndef _MIDI_CLASS_COMMON_H_
#define _MIDI_CLASS_COMMON_H_
/* Macros: */
#define __INCLUDE_FROM_AUDIO_DRIVER
/* Includes: */
#include "../../USB.h"
#include "Audio.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MIDI.h instead.
#endif
/* Macros: */
/** Audio class descriptor subtype value for a Audio class specific MIDI input jack descriptor. */
#define DSUBTYPE_InputJack 0x02
/** Audio class descriptor subtype value for a Audio class specific MIDI output jack descriptor. */
#define DSUBTYPE_OutputJack 0x03
/** Audio class descriptor jack type value for an embedded (logical) MIDI input or output jack. */
#define MIDI_JACKTYPE_EMBEDDED 0x01
/** Audio class descriptor jack type value for an external (physical) MIDI input or output jack. */
#define MIDI_JACKTYPE_EXTERNAL 0x02
/** MIDI command for a note on (activation) event */
#define MIDI_COMMAND_NOTE_ON 0x90
/** MIDI command for a note off (deactivation) event */
#define MIDI_COMMAND_NOTE_OFF 0x80
/** Standard key press velocity value used for all note events */
#define MIDI_STANDARD_VELOCITY 64
/** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel
* addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address.
*
* \param[in] channel MIDI channel number to address
*/
#define MIDI_CHANNEL(channel) ((channel) - 1)
/* Type Defines: */
/** \brief MIDI Class Specific Streaming Interface Descriptor.
*
* Type define for an Audio class specific MIDI streaming interface descriptor. This indicates to the host
* how MIDI the specification compliance of the device and the total length of the Audio class specific descriptors.
* See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint16_t AudioSpecification; /**< Binary coded decimal value, indicating the supported Audio Class specification version */
uint16_t TotalLength; /**< Total length of the Audio class specific descriptors, including this descriptor */
} USB_MIDI_AudioInterface_AS_t;
/** \brief MIDI Class Specific Input Jack Descriptor.
*
* Type define for an Audio class specific MIDI IN jack. This gives information to the host on a MIDI input, either
* a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint).
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t JackType; /**< Type of jack, one of the JACKTYPE_* mask values */
uint8_t JackID; /**< ID value of this jack - must be a unique value within the device */
uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_MIDI_In_Jack_t;
/** \brief MIDI Class Specific Output Jack Descriptor.
*
* Type define for an Audio class specific MIDI OUT jack. This gives information to the host on a MIDI output, either
* a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint).
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t JackType; /**< Type of jack, one of the JACKTYPE_* mask values */
uint8_t JackID; /**< ID value of this jack - must be a unique value within the device */
uint8_t NumberOfPins; /**< Number of output channels within the jack, either physical or logical */
uint8_t SourceJackID[1]; /**< ID of each output pin's source data jack */
uint8_t SourcePinID[1]; /**< Pin number in the input jack of each output pin's source data */
uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
} USB_MIDI_Out_Jack_t;
/** \brief Audio Class Specific Jack Endpoint Descriptor.
*
* Type define for an Audio class specific extended MIDI jack endpoint descriptor. This contains extra information
* on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio
* class specific extended MIDI endpoint descriptor. See the USB Audio specification for more details.
*/
typedef struct
{
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length */
uint8_t Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
uint8_t TotalEmbeddedJacks; /**< Total number of jacks inside this endpoint */
uint8_t AssociatedJackID[1]; /**< IDs of each jack inside the endpoint */
} USB_MIDI_Jack_Endpoint_t;
/** \brief MIDI Class Driver Event Packet.
*
* Type define for a USB MIDI event packet, used to encapsulate sent and received MIDI messages from a USB MIDI interface.
*/
typedef struct
{
unsigned char Command : 4; /**< Upper nibble of the MIDI command being sent or received in the event packet */
unsigned char CableNumber : 4; /**< Virtual cable number of the event being sent or received in the given MIDI interface */
uint8_t Data1; /**< First byte of data in the MIDI event */
uint8_t Data2; /**< Second byte of data in the MIDI event */
uint8_t Data3; /**< Third byte of data in the MIDI event */
} MIDI_EventPacket_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,318 +1,318 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Mass Storage Class driver.
*
* Common definitions and declarations for the library USB Mass Storage Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MassStorage.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassMSCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Mass Storage Class.
*
* @{
*/
#ifndef _MS_CLASS_COMMON_H_
#define _MS_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MassStorage.h instead.
#endif
/* Macros: */
/** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */
#define REQ_MassStorageReset 0xFF
/** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */
#define REQ_GetMaxLUN 0xFE
/** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
#define MS_CBW_SIGNATURE 0x43425355UL
/** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
#define MS_CSW_SIGNATURE 0x53425355UL
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
#define MS_COMMAND_DIR_DATA_OUT (0 << 7)
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
#define MS_COMMAND_DIR_DATA_IN (1 << 7)
/** SCSI Command Code for an INQUIRY command. */
#define SCSI_CMD_INQUIRY 0x12
/** SCSI Command Code for a REQUEST SENSE command. */
#define SCSI_CMD_REQUEST_SENSE 0x03
/** SCSI Command Code for a TEST UNIT READY command. */
#define SCSI_CMD_TEST_UNIT_READY 0x00
/** SCSI Command Code for a READ CAPACITY (10) command. */
#define SCSI_CMD_READ_CAPACITY_10 0x25
/** SCSI Command Code for a SEND DIAGNOSTIC command. */
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
/** SCSI Command Code for a PREVENT ALLOW MEDIUM REMOVAL command. */
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
/** SCSI Command Code for a WRITE (10) command. */
#define SCSI_CMD_WRITE_10 0x2A
/** SCSI Command Code for a READ (10) command. */
#define SCSI_CMD_READ_10 0x28
/** SCSI Command Code for a WRITE (6) command. */
#define SCSI_CMD_WRITE_6 0x0A
/** SCSI Command Code for a READ (6) command. */
#define SCSI_CMD_READ_6 0x08
/** SCSI Command Code for a VERIFY (10) command. */
#define SCSI_CMD_VERIFY_10 0x2F
/** SCSI Command Code for a MODE SENSE (6) command. */
#define SCSI_CMD_MODE_SENSE_6 0x1A
/** SCSI Command Code for a MODE SENSE (10) command. */
#define SCSI_CMD_MODE_SENSE_10 0x5A
/** SCSI Sense Code to indicate no error has occurred. */
#define SCSI_SENSE_KEY_GOOD 0x00
/** SCSI Sense Code to indicate that the device has recovered from an error. */
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
/** SCSI Sense Code to indicate that the device is not ready for a new command. */
#define SCSI_SENSE_KEY_NOT_READY 0x02
/** SCSI Sense Code to indicate an error whilst accessing the medium. */
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
/** SCSI Sense Code to indicate a hardware has occurred. */
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
/** SCSI Sense Code to indicate that an illegal request has been issued. */
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
/** SCSI Sense Code to indicate that the unit requires attention from the host to indicate
* a reset event, medium removal or other condition.
*/
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
/** SCSI Sense Code to indicate that a write attempt on a protected block has been made. */
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
/** SCSI Sense Code to indicate an error while trying to write to a write-once medium. */
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
/** SCSI Sense Code to indicate a vendor specific error has occurred. */
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
/** SCSI Sense Code to indicate that an EXTENDED COPY command has aborted due to an error. */
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
/** SCSI Sense Code to indicate that the device has aborted the issued command. */
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
/** SCSI Sense Code to indicate an attempt to write past the end of a partition has been made. */
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
/** SCSI Sense Code to indicate that the source data did not match the data read from the medium. */
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
/** SCSI Additional Sense Code to indicate no additional sense information is available. */
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
/** SCSI Additional Sense Code to indicate that the logical unit (LUN) addressed is not ready. */
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
/** SCSI Additional Sense Code to indicate an invalid field was encountered while processing the issued command. */
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
/** SCSI Additional Sense Code to indicate that an attempt to write to a protected area was made. */
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
/** SCSI Additional Sense Code to indicate an error whilst formatting the device medium. */
#define SCSI_ASENSE_FORMAT_ERROR 0x31
/** SCSI Additional Sense Code to indicate an invalid command was issued. */
#define SCSI_ASENSE_INVALID_COMMAND 0x20
/** SCSI Additional Sense Code to indicate a write to a block out outside of the medium's range was issued. */
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
/** SCSI Additional Sense Code to indicate that no removable medium is inserted into the device. */
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
/** SCSI Additional Sense Qualifier Code to indicate no additional sense qualifier information is available. */
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
/** SCSI Additional Sense Qualifier Code to indicate that a medium format command failed to complete. */
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
/** SCSI Additional Sense Qualifier Code to indicate that an initializing command must be issued before the issued
* command can be executed.
*/
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
/** SCSI Additional Sense Qualifier Code to indicate that an operation is currently in progress. */
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
/* Type defines: */
/** \brief Mass Storage Class Command Block Wrapper.
*
* Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
typedef struct
{
uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */
uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */
uint8_t Flags; /**< Command block flags, indicating command data direction */
uint8_t LUN; /**< Logical Unit number this command is issued to */
uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */
uint8_t SCSICommandData[16]; /**< Issued SCSI command in the Command Block */
} MS_CommandBlockWrapper_t;
/** \brief Mass Storage Class Command Status Wrapper.
*
* Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol.
*/
typedef struct
{
uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */
uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */
uint8_t Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */
} MS_CommandStatusWrapper_t;
/** \brief Mass Storage Class SCSI Sense Structure
*
* Type define for a SCSI Sense structure. Structures of this type are filled out by the
* device via the MassStore_RequestSense() function, indicating the current sense data of the
* device (giving explicit error codes for the last issued command). For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/** \brief Mass Storage Class SCSI Inquiry Structure.
*
* Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
* device via the MassStore_Inquiry() function, retrieving the attached device's information.
* For details of the structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/* Enums: */
/** Enum for the possible command status wrapper return status codes. */
enum MassStorage_CommandStatusCodes_t
{
SCSI_Command_Pass = 0, /**< Command completed with no error */
SCSI_Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
SCSI_Phase_Error = 2 /**< Command failed due to being invalid in the current phase */
};
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Mass Storage Class driver.
*
* Common definitions and declarations for the library USB Mass Storage Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MassStorage.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassMSCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Mass Storage Class.
*
* @{
*/
#ifndef _MS_CLASS_COMMON_H_
#define _MS_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MassStorage.h instead.
#endif
/* Macros: */
/** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */
#define REQ_MassStorageReset 0xFF
/** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */
#define REQ_GetMaxLUN 0xFE
/** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
#define MS_CBW_SIGNATURE 0x43425355UL
/** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
#define MS_CSW_SIGNATURE 0x53425355UL
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
#define MS_COMMAND_DIR_DATA_OUT (0 << 7)
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
#define MS_COMMAND_DIR_DATA_IN (1 << 7)
/** SCSI Command Code for an INQUIRY command. */
#define SCSI_CMD_INQUIRY 0x12
/** SCSI Command Code for a REQUEST SENSE command. */
#define SCSI_CMD_REQUEST_SENSE 0x03
/** SCSI Command Code for a TEST UNIT READY command. */
#define SCSI_CMD_TEST_UNIT_READY 0x00
/** SCSI Command Code for a READ CAPACITY (10) command. */
#define SCSI_CMD_READ_CAPACITY_10 0x25
/** SCSI Command Code for a SEND DIAGNOSTIC command. */
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
/** SCSI Command Code for a PREVENT ALLOW MEDIUM REMOVAL command. */
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
/** SCSI Command Code for a WRITE (10) command. */
#define SCSI_CMD_WRITE_10 0x2A
/** SCSI Command Code for a READ (10) command. */
#define SCSI_CMD_READ_10 0x28
/** SCSI Command Code for a WRITE (6) command. */
#define SCSI_CMD_WRITE_6 0x0A
/** SCSI Command Code for a READ (6) command. */
#define SCSI_CMD_READ_6 0x08
/** SCSI Command Code for a VERIFY (10) command. */
#define SCSI_CMD_VERIFY_10 0x2F
/** SCSI Command Code for a MODE SENSE (6) command. */
#define SCSI_CMD_MODE_SENSE_6 0x1A
/** SCSI Command Code for a MODE SENSE (10) command. */
#define SCSI_CMD_MODE_SENSE_10 0x5A
/** SCSI Sense Code to indicate no error has occurred. */
#define SCSI_SENSE_KEY_GOOD 0x00
/** SCSI Sense Code to indicate that the device has recovered from an error. */
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
/** SCSI Sense Code to indicate that the device is not ready for a new command. */
#define SCSI_SENSE_KEY_NOT_READY 0x02
/** SCSI Sense Code to indicate an error whilst accessing the medium. */
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
/** SCSI Sense Code to indicate a hardware has occurred. */
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
/** SCSI Sense Code to indicate that an illegal request has been issued. */
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
/** SCSI Sense Code to indicate that the unit requires attention from the host to indicate
* a reset event, medium removal or other condition.
*/
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
/** SCSI Sense Code to indicate that a write attempt on a protected block has been made. */
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
/** SCSI Sense Code to indicate an error while trying to write to a write-once medium. */
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
/** SCSI Sense Code to indicate a vendor specific error has occurred. */
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
/** SCSI Sense Code to indicate that an EXTENDED COPY command has aborted due to an error. */
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
/** SCSI Sense Code to indicate that the device has aborted the issued command. */
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
/** SCSI Sense Code to indicate an attempt to write past the end of a partition has been made. */
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
/** SCSI Sense Code to indicate that the source data did not match the data read from the medium. */
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
/** SCSI Additional Sense Code to indicate no additional sense information is available. */
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
/** SCSI Additional Sense Code to indicate that the logical unit (LUN) addressed is not ready. */
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
/** SCSI Additional Sense Code to indicate an invalid field was encountered while processing the issued command. */
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
/** SCSI Additional Sense Code to indicate that an attempt to write to a protected area was made. */
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
/** SCSI Additional Sense Code to indicate an error whilst formatting the device medium. */
#define SCSI_ASENSE_FORMAT_ERROR 0x31
/** SCSI Additional Sense Code to indicate an invalid command was issued. */
#define SCSI_ASENSE_INVALID_COMMAND 0x20
/** SCSI Additional Sense Code to indicate a write to a block out outside of the medium's range was issued. */
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
/** SCSI Additional Sense Code to indicate that no removable medium is inserted into the device. */
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
/** SCSI Additional Sense Qualifier Code to indicate no additional sense qualifier information is available. */
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
/** SCSI Additional Sense Qualifier Code to indicate that a medium format command failed to complete. */
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
/** SCSI Additional Sense Qualifier Code to indicate that an initializing command must be issued before the issued
* command can be executed.
*/
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
/** SCSI Additional Sense Qualifier Code to indicate that an operation is currently in progress. */
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
/* Type defines: */
/** \brief Mass Storage Class Command Block Wrapper.
*
* Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
typedef struct
{
uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */
uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */
uint8_t Flags; /**< Command block flags, indicating command data direction */
uint8_t LUN; /**< Logical Unit number this command is issued to */
uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */
uint8_t SCSICommandData[16]; /**< Issued SCSI command in the Command Block */
} MS_CommandBlockWrapper_t;
/** \brief Mass Storage Class Command Status Wrapper.
*
* Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol.
*/
typedef struct
{
uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */
uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */
uint8_t Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */
} MS_CommandStatusWrapper_t;
/** \brief Mass Storage Class SCSI Sense Structure
*
* Type define for a SCSI Sense structure. Structures of this type are filled out by the
* device via the MassStore_RequestSense() function, indicating the current sense data of the
* device (giving explicit error codes for the last issued command). For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/** \brief Mass Storage Class SCSI Inquiry Structure.
*
* Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
* device via the MassStore_Inquiry() function, retrieving the attached device's information.
* For details of the structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/* Enums: */
/** Enum for the possible command status wrapper return status codes. */
enum MassStorage_CommandStatusCodes_t
{
SCSI_Command_Pass = 0, /**< Command completed with no error */
SCSI_Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
SCSI_Phase_Error = 2 /**< Command failed due to being invalid in the current phase */
};
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,85 +1,85 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Printer Class driver.
*
* Common definitions and declarations for the library USB Printer Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Printer.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassPrinterCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Printer Class.
*
* @{
*/
#ifndef _PRINTER_CLASS_COMMON_H_
#define _PRINTER_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Printer.h instead.
#endif
/* Macros: */
/** Port status mask for a printer device, indicating that an error has *not* occurred. */
#define PRNT_PORTSTATUS_NOTERROR (1 << 3)
/** Port status mask for a printer device, indicating that the device is currently selected. */
#define PRNT_PORTSTATUS_SELECT (1 << 4)
/** Port status mask for a printer device, indicating that the device is currently out of paper. */
#define PRNT_PORTSTATUS_PAPEREMPTY (1 << 5)
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Printer Class driver.
*
* Common definitions and declarations for the library USB Printer Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Printer.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassPrinterCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Printer Class.
*
* @{
*/
#ifndef _PRINTER_CLASS_COMMON_H_
#define _PRINTER_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Printer.h instead.
#endif
/* Macros: */
/** Port status mask for a printer device, indicating that an error has *not* occurred. */
#define PRNT_PORTSTATUS_NOTERROR (1 << 3)
/** Port status mask for a printer device, indicating that the device is currently selected. */
#define PRNT_PORTSTATUS_SELECT (1 << 4)
/** Port status mask for a printer device, indicating that the device is currently out of paper. */
#define PRNT_PORTSTATUS_PAPEREMPTY (1 << 5)
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,303 +1,303 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB RNDIS Class driver.
*
* Common definitions and declarations for the library USB RNDIS Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/RNDIS.h.
*/
/** \ingroup Group_USBClassRNDIS
* @defgroup Group_USBClassRNDISCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* RNDIS Class.
*
* @{
*/
#ifndef _RNDIS_CLASS_COMMON_H_
#define _RNDIS_CLASS_COMMON_H_
/* Macros: */
#define __INCLUDE_FROM_CDC_DRIVER
/* Includes: */
#include "../../USB.h"
#include "RNDISConstants.h"
#include "CDC.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/RNDIS.h instead.
#endif
/* Macros: */
/** Implemented RNDIS Version Major */
#define REMOTE_NDIS_VERSION_MAJOR 0x01
/** Implemented RNDIS Version Minor */
#define REMOTE_NDIS_VERSION_MINOR 0x00
/** RNDIS request to issue a host-to-device NDIS command */
#define REQ_SendEncapsulatedCommand 0x00
/** RNDIS request to issue a device-to-host NDIS response */
#define REQ_GetEncapsulatedResponse 0x01
/** Maximum size in bytes of a RNDIS control message which can be sent or received */
#define RNDIS_MESSAGE_BUFFER_SIZE 128
/** Maximum size in bytes of an Ethernet frame according to the Ethernet standard */
#define ETHERNET_FRAME_SIZE_MAX 1500
/** Notification request value for a RNDIS Response Available notification */
#define NOTIF_ResponseAvailable 1
/* Enums: */
/** Enum for the possible NDIS adapter states. */
enum RNDIS_States_t
{
RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized */
RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers */
RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */
};
/** Enum for the NDIS hardware states */
enum NDIS_Hardware_Status_t
{
NDIS_HardwareStatus_Ready, /**< Hardware Ready to accept commands from the host */
NDIS_HardwareStatus_Initializing, /**< Hardware busy initializing */
NDIS_HardwareStatus_Reset, /**< Hardware reset */
NDIS_HardwareStatus_Closing, /**< Hardware currently closing */
NDIS_HardwareStatus_NotReady /**< Hardware not ready to accept commands from the host */
};
/* Type Defines: */
/** \brief MAC Address Structure.
*
* Type define for a physical MAC address of a device on a network
*/
typedef struct
{
uint8_t Octets[6]; /**< Individual bytes of a MAC address */
} MAC_Address_t;
/** \brief RNDIS Ethernet Frame Packet Information Structure.
*
* Type define for an Ethernet frame buffer data and information structure.
*/
typedef struct
{
uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
} Ethernet_Frame_Info_t;
/** \brief RNDIS Common Message Header Structure.
*
* Type define for a RNDIS message header, sent before RNDIS messages.
*/
typedef struct
{
uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */
uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
} RNDIS_Message_Header_t;
/** \brief RNDIS Message Structure.
*
* Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t DataOffset;
uint32_t DataLength;
uint32_t OOBDataOffset;
uint32_t OOBDataLength;
uint32_t NumOOBDataElements;
uint32_t PerPacketInfoOffset;
uint32_t PerPacketInfoLength;
uint32_t VcHandle;
uint32_t Reserved;
} RNDIS_Packet_Message_t;
/** \brief RNDIS Initialization Message Structure.
*
* Type define for a RNDIS Initialize command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t MajorVersion;
uint32_t MinorVersion;
uint32_t MaxTransferSize;
} RNDIS_Initialize_Message_t;
/** \brief RNDIS Initialize Complete Message Structure.
*
* Type define for a RNDIS Initialize Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
uint32_t MajorVersion;
uint32_t MinorVersion;
uint32_t DeviceFlags;
uint32_t Medium;
uint32_t MaxPacketsPerTransfer;
uint32_t MaxTransferSize;
uint32_t PacketAlignmentFactor;
uint32_t AFListOffset;
uint32_t AFListSize;
} RNDIS_Initialize_Complete_t;
/** \brief RNDIS Keep Alive Message Structure.
*
* Type define for a RNDIS Keep Alive command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
} RNDIS_KeepAlive_Message_t;
/** \brief RNDIS Keep Alive Complete Message Structure.
*
* Type define for a RNDIS Keep Alive Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
} RNDIS_KeepAlive_Complete_t;
/** \brief RNDIS Reset Complete Message Structure.
*
* Type define for a RNDIS Reset Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t Status;
uint32_t AddressingReset;
} RNDIS_Reset_Complete_t;
/** \brief RNDIS OID Property Set Message Structure.
*
* Type define for a RNDIS OID Property Set command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Oid;
uint32_t InformationBufferLength;
uint32_t InformationBufferOffset;
uint32_t DeviceVcHandle;
} RNDIS_Set_Message_t;
/** \brief RNDIS OID Property Set Complete Message Structure.
*
* Type define for a RNDIS OID Property Set Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
} RNDIS_Set_Complete_t;
/** \brief RNDIS OID Property Query Message Structure.
*
* Type define for a RNDIS OID Property Query command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Oid;
uint32_t InformationBufferLength;
uint32_t InformationBufferOffset;
uint32_t DeviceVcHandle;
} RNDIS_Query_Message_t;
/** \brief RNDIS OID Property Query Complete Message Structure.
*
* Type define for a RNDIS OID Property Query Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
uint32_t InformationBufferLength;
uint32_t InformationBufferOffset;
} RNDIS_Query_Complete_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB RNDIS Class driver.
*
* Common definitions and declarations for the library USB RNDIS Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/RNDIS.h.
*/
/** \ingroup Group_USBClassRNDIS
* @defgroup Group_USBClassRNDISCommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* RNDIS Class.
*
* @{
*/
#ifndef _RNDIS_CLASS_COMMON_H_
#define _RNDIS_CLASS_COMMON_H_
/* Macros: */
#define __INCLUDE_FROM_CDC_DRIVER
/* Includes: */
#include "../../USB.h"
#include "RNDISConstants.h"
#include "CDC.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/RNDIS.h instead.
#endif
/* Macros: */
/** Implemented RNDIS Version Major */
#define REMOTE_NDIS_VERSION_MAJOR 0x01
/** Implemented RNDIS Version Minor */
#define REMOTE_NDIS_VERSION_MINOR 0x00
/** RNDIS request to issue a host-to-device NDIS command */
#define REQ_SendEncapsulatedCommand 0x00
/** RNDIS request to issue a device-to-host NDIS response */
#define REQ_GetEncapsulatedResponse 0x01
/** Maximum size in bytes of a RNDIS control message which can be sent or received */
#define RNDIS_MESSAGE_BUFFER_SIZE 128
/** Maximum size in bytes of an Ethernet frame according to the Ethernet standard */
#define ETHERNET_FRAME_SIZE_MAX 1500
/** Notification request value for a RNDIS Response Available notification */
#define NOTIF_ResponseAvailable 1
/* Enums: */
/** Enum for the possible NDIS adapter states. */
enum RNDIS_States_t
{
RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized */
RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers */
RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */
};
/** Enum for the NDIS hardware states */
enum NDIS_Hardware_Status_t
{
NDIS_HardwareStatus_Ready, /**< Hardware Ready to accept commands from the host */
NDIS_HardwareStatus_Initializing, /**< Hardware busy initializing */
NDIS_HardwareStatus_Reset, /**< Hardware reset */
NDIS_HardwareStatus_Closing, /**< Hardware currently closing */
NDIS_HardwareStatus_NotReady /**< Hardware not ready to accept commands from the host */
};
/* Type Defines: */
/** \brief MAC Address Structure.
*
* Type define for a physical MAC address of a device on a network
*/
typedef struct
{
uint8_t Octets[6]; /**< Individual bytes of a MAC address */
} MAC_Address_t;
/** \brief RNDIS Ethernet Frame Packet Information Structure.
*
* Type define for an Ethernet frame buffer data and information structure.
*/
typedef struct
{
uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
} Ethernet_Frame_Info_t;
/** \brief RNDIS Common Message Header Structure.
*
* Type define for a RNDIS message header, sent before RNDIS messages.
*/
typedef struct
{
uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */
uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
} RNDIS_Message_Header_t;
/** \brief RNDIS Message Structure.
*
* Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t DataOffset;
uint32_t DataLength;
uint32_t OOBDataOffset;
uint32_t OOBDataLength;
uint32_t NumOOBDataElements;
uint32_t PerPacketInfoOffset;
uint32_t PerPacketInfoLength;
uint32_t VcHandle;
uint32_t Reserved;
} RNDIS_Packet_Message_t;
/** \brief RNDIS Initialization Message Structure.
*
* Type define for a RNDIS Initialize command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t MajorVersion;
uint32_t MinorVersion;
uint32_t MaxTransferSize;
} RNDIS_Initialize_Message_t;
/** \brief RNDIS Initialize Complete Message Structure.
*
* Type define for a RNDIS Initialize Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
uint32_t MajorVersion;
uint32_t MinorVersion;
uint32_t DeviceFlags;
uint32_t Medium;
uint32_t MaxPacketsPerTransfer;
uint32_t MaxTransferSize;
uint32_t PacketAlignmentFactor;
uint32_t AFListOffset;
uint32_t AFListSize;
} RNDIS_Initialize_Complete_t;
/** \brief RNDIS Keep Alive Message Structure.
*
* Type define for a RNDIS Keep Alive command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
} RNDIS_KeepAlive_Message_t;
/** \brief RNDIS Keep Alive Complete Message Structure.
*
* Type define for a RNDIS Keep Alive Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
} RNDIS_KeepAlive_Complete_t;
/** \brief RNDIS Reset Complete Message Structure.
*
* Type define for a RNDIS Reset Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t Status;
uint32_t AddressingReset;
} RNDIS_Reset_Complete_t;
/** \brief RNDIS OID Property Set Message Structure.
*
* Type define for a RNDIS OID Property Set command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Oid;
uint32_t InformationBufferLength;
uint32_t InformationBufferOffset;
uint32_t DeviceVcHandle;
} RNDIS_Set_Message_t;
/** \brief RNDIS OID Property Set Complete Message Structure.
*
* Type define for a RNDIS OID Property Set Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
} RNDIS_Set_Complete_t;
/** \brief RNDIS OID Property Query Message Structure.
*
* Type define for a RNDIS OID Property Query command message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Oid;
uint32_t InformationBufferLength;
uint32_t InformationBufferOffset;
uint32_t DeviceVcHandle;
} RNDIS_Query_Message_t;
/** \brief RNDIS OID Property Query Complete Message Structure.
*
* Type define for a RNDIS OID Property Query Complete response message.
*/
typedef struct
{
uint32_t MessageType;
uint32_t MessageLength;
uint32_t RequestId;
uint32_t Status;
uint32_t InformationBufferLength;
uint32_t InformationBufferOffset;
} RNDIS_Query_Complete_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,121 +1,121 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common RNDIS class constant definitions.
*
* Common RNDIS class constant definitions.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Audio.h.
*/
/** \file
*
* RNDIS specification related constants. For more information on these
* constants, please refer to the Microsoft RNDIS specification.
*/
#ifndef _RNDIS_CONSTANTS_DEVICE_H_
#define _RNDIS_CONSTANTS_DEVICE_H_
/* Macros: */
#define REMOTE_NDIS_PACKET_MSG 0x00000001UL
#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL
#define REMOTE_NDIS_HALT_MSG 0x00000003UL
#define REMOTE_NDIS_QUERY_MSG 0x00000004UL
#define REMOTE_NDIS_SET_MSG 0x00000005UL
#define REMOTE_NDIS_RESET_MSG 0x00000006UL
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL
#define REMOTE_NDIS_SET_CMPLT 0x80000005UL
#define REMOTE_NDIS_RESET_CMPLT 0x80000006UL
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL
#define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL
#define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL
#define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL
#define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
#define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
#define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
#define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
#define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
#define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
#define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
#define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
#define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL
#define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL
#define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL
#define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL
#define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL
#define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL
#define REMOTE_NDIS_PACKET_SMT 0x00000040UL
#define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL
#define REMOTE_NDIS_PACKET_GROUP 0x00001000UL
#define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
#define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL
#define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL
#define OID_GEN_SUPPORTED_LIST 0x00010101UL
#define OID_GEN_HARDWARE_STATUS 0x00010102UL
#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
#define OID_GEN_MEDIA_IN_USE 0x00010104UL
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
#define OID_GEN_LINK_SPEED 0x00010107UL
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
#define OID_GEN_VENDOR_ID 0x0001010CUL
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
#define OID_GEN_XMIT_OK 0x00020101UL
#define OID_GEN_RCV_OK 0x00020102UL
#define OID_GEN_XMIT_ERROR 0x00020103UL
#define OID_GEN_RCV_ERROR 0x00020104UL
#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
#define OID_802_3_MULTICAST_LIST 0x01010103UL
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common RNDIS class constant definitions.
*
* Common RNDIS class constant definitions.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Audio.h.
*/
/** \file
*
* RNDIS specification related constants. For more information on these
* constants, please refer to the Microsoft RNDIS specification.
*/
#ifndef _RNDIS_CONSTANTS_DEVICE_H_
#define _RNDIS_CONSTANTS_DEVICE_H_
/* Macros: */
#define REMOTE_NDIS_PACKET_MSG 0x00000001UL
#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL
#define REMOTE_NDIS_HALT_MSG 0x00000003UL
#define REMOTE_NDIS_QUERY_MSG 0x00000004UL
#define REMOTE_NDIS_SET_MSG 0x00000005UL
#define REMOTE_NDIS_RESET_MSG 0x00000006UL
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL
#define REMOTE_NDIS_SET_CMPLT 0x80000005UL
#define REMOTE_NDIS_RESET_CMPLT 0x80000006UL
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL
#define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL
#define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL
#define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL
#define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
#define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
#define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
#define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
#define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
#define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
#define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
#define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
#define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL
#define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL
#define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL
#define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL
#define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL
#define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL
#define REMOTE_NDIS_PACKET_SMT 0x00000040UL
#define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL
#define REMOTE_NDIS_PACKET_GROUP 0x00001000UL
#define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
#define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL
#define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL
#define OID_GEN_SUPPORTED_LIST 0x00010101UL
#define OID_GEN_HARDWARE_STATUS 0x00010102UL
#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
#define OID_GEN_MEDIA_IN_USE 0x00010104UL
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
#define OID_GEN_LINK_SPEED 0x00010107UL
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
#define OID_GEN_VENDOR_ID 0x0001010CUL
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
#define OID_GEN_XMIT_OK 0x00020101UL
#define OID_GEN_RCV_OK 0x00020102UL
#define OID_GEN_XMIT_ERROR 0x00020103UL
#define OID_GEN_RCV_ERROR 0x00020104UL
#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
#define OID_802_3_MULTICAST_LIST 0x01010103UL
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
#endif

View file

@ -1,146 +1,146 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Still Image Class driver.
*
* Common definitions and declarations for the library USB Still Image Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/StillImage.h.
*/
/** \ingroup Group_USBClassSI
* @defgroup Group_USBClassSICommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Still Image Class.
*
* @{
*/
#ifndef _SI_CLASS_COMMON_H_
#define _SI_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_SI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/StillImage.h instead.
#endif
/* Macros: */
/** Length in bytes of a given Unicode string's character length
*
* \param[in] chars Total number of Unicode characters in the string
*
* \return Number of bytes of the given unicode string
*/
#define UNICODE_STRING_LENGTH(chars) ((chars) << 1)
/** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
* a command container.
*
* \param[in] params Number of parameters which are to be sent in the Param field of the container
*/
#define PIMA_COMMAND_SIZE(params) ((sizeof(SI_PIMA_Container_t) - 12) + \
((params) * sizeof(uint32_t)))
/** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
* a data container.
*
* \param[in] datalen Length in bytes of the data in the container
*/
#define PIMA_DATA_SIZE(datalen) ((sizeof(SI_PIMA_Container_t) - 12) + \
(datalen))
/* Enums: */
/** Enum for the possible PIMA contains types. */
enum SI_PIMA_Container_Types_t
{
CType_Undefined = 0, /**< Undefined container type */
CType_CommandBlock = 1, /**< Command Block container type */
CType_DataBlock = 2, /**< Data Block container type */
CType_ResponseBlock = 3, /**< Response container type */
CType_EventBlock = 4, /**< Event Block container type */
};
/* Enums: */
/** Enums for the possible status codes of a returned Response Block from an attached PIMA compliant Still Image device. */
enum SI_PIMA_ResponseCodes_t
{
PIMA_RESPONSE_OK = 1, /**< Response code indicating no error in the issued command */
PIMA_RESPONSE_GeneralError = 2, /**< Response code indicating a general error while processing the
* issued command
*/
PIMA_RESPONSE_SessionNotOpen = 3, /**< Response code indicating that the sent command requires an open
* session before being issued
*/
PIMA_RESPONSE_InvalidTransaction = 4, /**< Response code indicating an invalid transaction occurred */
PIMA_RESPONSE_OperationNotSupported = 5, /**< Response code indicating that the issued command is not supported
* by the attached device
*/
PIMA_RESPONSE_ParameterNotSupported = 6, /**< Response code indicating that one or more of the issued command's
* parameters are not supported by the device
*/
};
/* Type Defines: */
/** \brief PIMA Still Image Device Command/Response Container.
*
* Type define for a PIMA container, use to send commands and receive responses to and from an
* attached Still Image device.
*/
typedef struct
{
uint32_t DataLength; /**< Length of the container and data, in bytes */
uint16_t Type; /**< Container type, a value from the PIMA_Container_Types_t enum */
uint16_t Code; /**< Command, event or response code of the container */
uint32_t TransactionID; /**< Unique container ID to link blocks together */
uint32_t Params[3]; /**< Block parameters to be issued along with the block code (command blocks only) */
} SI_PIMA_Container_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Common definitions and declarations for the library USB Still Image Class driver.
*
* Common definitions and declarations for the library USB Still Image Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/StillImage.h.
*/
/** \ingroup Group_USBClassSI
* @defgroup Group_USBClassSICommon Common Class Definitions
*
* \section Module Description
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
* Still Image Class.
*
* @{
*/
#ifndef _SI_CLASS_COMMON_H_
#define _SI_CLASS_COMMON_H_
/* Includes: */
#include "../../USB.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_SI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/StillImage.h instead.
#endif
/* Macros: */
/** Length in bytes of a given Unicode string's character length
*
* \param[in] chars Total number of Unicode characters in the string
*
* \return Number of bytes of the given unicode string
*/
#define UNICODE_STRING_LENGTH(chars) ((chars) << 1)
/** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
* a command container.
*
* \param[in] params Number of parameters which are to be sent in the Param field of the container
*/
#define PIMA_COMMAND_SIZE(params) ((sizeof(SI_PIMA_Container_t) - 12) + \
((params) * sizeof(uint32_t)))
/** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
* a data container.
*
* \param[in] datalen Length in bytes of the data in the container
*/
#define PIMA_DATA_SIZE(datalen) ((sizeof(SI_PIMA_Container_t) - 12) + \
(datalen))
/* Enums: */
/** Enum for the possible PIMA contains types. */
enum SI_PIMA_Container_Types_t
{
CType_Undefined = 0, /**< Undefined container type */
CType_CommandBlock = 1, /**< Command Block container type */
CType_DataBlock = 2, /**< Data Block container type */
CType_ResponseBlock = 3, /**< Response container type */
CType_EventBlock = 4, /**< Event Block container type */
};
/* Enums: */
/** Enums for the possible status codes of a returned Response Block from an attached PIMA compliant Still Image device. */
enum SI_PIMA_ResponseCodes_t
{
PIMA_RESPONSE_OK = 1, /**< Response code indicating no error in the issued command */
PIMA_RESPONSE_GeneralError = 2, /**< Response code indicating a general error while processing the
* issued command
*/
PIMA_RESPONSE_SessionNotOpen = 3, /**< Response code indicating that the sent command requires an open
* session before being issued
*/
PIMA_RESPONSE_InvalidTransaction = 4, /**< Response code indicating an invalid transaction occurred */
PIMA_RESPONSE_OperationNotSupported = 5, /**< Response code indicating that the issued command is not supported
* by the attached device
*/
PIMA_RESPONSE_ParameterNotSupported = 6, /**< Response code indicating that one or more of the issued command's
* parameters are not supported by the device
*/
};
/* Type Defines: */
/** \brief PIMA Still Image Device Command/Response Container.
*
* Type define for a PIMA container, use to send commands and receive responses to and from an
* attached Still Image device.
*/
typedef struct
{
uint32_t DataLength; /**< Length of the container and data, in bytes */
uint16_t Type; /**< Container type, a value from the PIMA_Container_Types_t enum */
uint16_t Code; /**< Command, event or response code of the container */
uint32_t TransactionID; /**< Unique container ID to link blocks together */
uint32_t Params[3]; /**< Block parameters to be issued along with the block code (command blocks only) */
} SI_PIMA_Container_t;
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,89 +1,89 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_AUDIO_DRIVER
#include "Audio.h"
void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_SetInterface:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
Endpoint_ClearStatusStage();
}
break;
}
}
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo)
{
memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
if (AudioInterfaceInfo->Config.DataINEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
ENDPOINT_DIR_IN, AudioInterfaceInfo->Config.DataINEndpointSize,
ENDPOINT_BANK_DOUBLE)))
{
return false;
}
}
if (AudioInterfaceInfo->Config.DataOUTEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
ENDPOINT_DIR_OUT, AudioInterfaceInfo->Config.DataOUTEndpointSize,
ENDPOINT_BANK_DOUBLE)))
{
return false;
}
}
return true;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_AUDIO_DRIVER
#include "Audio.h"
void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_SetInterface:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
Endpoint_ClearStatusStage();
}
break;
}
}
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* AudioInterfaceInfo)
{
memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
if (AudioInterfaceInfo->Config.DataINEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
ENDPOINT_DIR_IN, AudioInterfaceInfo->Config.DataINEndpointSize,
ENDPOINT_BANK_DOUBLE)))
{
return false;
}
}
if (AudioInterfaceInfo->Config.DataOUTEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
ENDPOINT_DIR_OUT, AudioInterfaceInfo->Config.DataOUTEndpointSize,
ENDPOINT_BANK_DOUBLE)))
{
return false;
}
}
return true;
}
#endif

View file

@ -1,319 +1,319 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB Audio Class driver.
*
* Device mode driver for the library USB Audio Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Audio.h.
*/
/** \ingroup Group_USBClassAudio
* @defgroup Group_USBClassAudioDevice Audio Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/Audio.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the Audio USB Class driver.
*
* @{
*/
#ifndef _AUDIO_CLASS_DEVICE_H_
#define _AUDIO_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/Audio.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Audio.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief Audio Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each Audio interface
* within the user application, and passed to each of the Audio class driver functions as the
* AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this
* structure controls
*/
uint8_t DataINEndpointNumber; /**< Endpoint number of the incoming Audio Streaming data, if available
* (zero if unused)
*/
uint16_t DataINEndpointSize; /**< Size in bytes of the incoming Audio Streaming data endpoint, if available
* (zero if unused)
*/
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing Audio Streaming data, if available
* (zero if unused)
*/
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing Audio Streaming data endpoint, if available
* (zero if unused)
*/
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
* of the Audio Streaming interface.
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_Audio_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
* given Audio interface is selected.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*/
void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Inline Functions: */
/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*/
static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
(void)AudioInterfaceInfo;
}
/** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming
* OUT endpoint ready for reading.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Boolean true if the given Audio interface has a sample to be read, false otherwise
*/
static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
return false;
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber);
return Endpoint_IsOUTReceived();
}
/** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects
* the streaming IN endpoint ready for writing.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Boolean true if the given Audio interface is ready to accept the next sample, false otherwise
*/
static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
return false;
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber);
return Endpoint_IsINReady();
}
/** Reads the next 8-bit audio sample from the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsSampleReceived() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Signed 8-bit audio sample from the audio interface
*/
static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_ALWAYS_INLINE;
static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
int8_t Sample;
(void)AudioInterfaceInfo;
Sample = Endpoint_Read_Byte();
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return Sample;
}
/** Reads the next 16-bit audio sample from the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsSampleReceived() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Signed 16-bit audio sample from the audio interface
*/
static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_ALWAYS_INLINE;
static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
int16_t Sample;
(void)AudioInterfaceInfo;
Sample = (int16_t)Endpoint_Read_Word_LE();
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return Sample;
}
/** Reads the next 24-bit audio sample from the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsSampleReceived() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Signed 24-bit audio sample from the audio interface
*/
static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_ALWAYS_INLINE;
static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
int32_t Sample;
(void)AudioInterfaceInfo;
Sample = (((uint32_t)Endpoint_Read_Byte() << 16) | Endpoint_Read_Word_LE());
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return Sample;
}
/** Writes the next 8-bit audio sample to the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsReadyForNextSample() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
* \param[in] Sample Signed 8-bit audio sample
*/
static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int8_t Sample) ATTR_ALWAYS_INLINE;
static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int8_t Sample)
{
Endpoint_Write_Byte(Sample);
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
Endpoint_ClearIN();
}
/** Writes the next 16-bit audio sample to the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsReadyForNextSample() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
* \param[in] Sample Signed 16-bit audio sample
*/
static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int16_t Sample) ATTR_ALWAYS_INLINE;
static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int16_t Sample)
{
Endpoint_Write_Word_LE(Sample);
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
Endpoint_ClearIN();
}
/** Writes the next 24-bit audio sample to the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsReadyForNextSample() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
* \param[in] Sample Signed 24-bit audio sample
*/
static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int32_t Sample) ATTR_ALWAYS_INLINE;
static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int32_t Sample)
{
Endpoint_Write_Byte(Sample >> 16);
Endpoint_Write_Word_LE(Sample);
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
Endpoint_ClearIN();
}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB Audio Class driver.
*
* Device mode driver for the library USB Audio Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Audio.h.
*/
/** \ingroup Group_USBClassAudio
* @defgroup Group_USBClassAudioDevice Audio Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/Audio.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the Audio USB Class driver.
*
* @{
*/
#ifndef _AUDIO_CLASS_DEVICE_H_
#define _AUDIO_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/Audio.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Audio.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief Audio Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each Audio interface
* within the user application, and passed to each of the Audio class driver functions as the
* AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this
* structure controls
*/
uint8_t DataINEndpointNumber; /**< Endpoint number of the incoming Audio Streaming data, if available
* (zero if unused)
*/
uint16_t DataINEndpointSize; /**< Size in bytes of the incoming Audio Streaming data endpoint, if available
* (zero if unused)
*/
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing Audio Streaming data, if available
* (zero if unused)
*/
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing Audio Streaming data endpoint, if available
* (zero if unused)
*/
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
* of the Audio Streaming interface.
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_Audio_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
* given Audio interface is selected.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*/
void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Inline Functions: */
/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*/
static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
(void)AudioInterfaceInfo;
}
/** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming
* OUT endpoint ready for reading.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Boolean true if the given Audio interface has a sample to be read, false otherwise
*/
static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
return false;
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber);
return Endpoint_IsOUTReceived();
}
/** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects
* the streaming IN endpoint ready for writing.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Boolean true if the given Audio interface is ready to accept the next sample, false otherwise
*/
static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
return false;
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber);
return Endpoint_IsINReady();
}
/** Reads the next 8-bit audio sample from the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsSampleReceived() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Signed 8-bit audio sample from the audio interface
*/
static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_ALWAYS_INLINE;
static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
int8_t Sample;
(void)AudioInterfaceInfo;
Sample = Endpoint_Read_Byte();
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return Sample;
}
/** Reads the next 16-bit audio sample from the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsSampleReceived() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Signed 16-bit audio sample from the audio interface
*/
static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_ALWAYS_INLINE;
static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
int16_t Sample;
(void)AudioInterfaceInfo;
Sample = (int16_t)Endpoint_Read_Word_LE();
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return Sample;
}
/** Reads the next 24-bit audio sample from the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsSampleReceived() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
*
* \return Signed 24-bit audio sample from the audio interface
*/
static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_ALWAYS_INLINE;
static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
int32_t Sample;
(void)AudioInterfaceInfo;
Sample = (((uint32_t)Endpoint_Read_Byte() << 16) | Endpoint_Read_Word_LE());
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return Sample;
}
/** Writes the next 8-bit audio sample to the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsReadyForNextSample() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
* \param[in] Sample Signed 8-bit audio sample
*/
static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int8_t Sample) ATTR_ALWAYS_INLINE;
static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int8_t Sample)
{
Endpoint_Write_Byte(Sample);
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
Endpoint_ClearIN();
}
/** Writes the next 16-bit audio sample to the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsReadyForNextSample() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
* \param[in] Sample Signed 16-bit audio sample
*/
static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int16_t Sample) ATTR_ALWAYS_INLINE;
static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int16_t Sample)
{
Endpoint_Write_Word_LE(Sample);
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
Endpoint_ClearIN();
}
/** Writes the next 24-bit audio sample to the current audio interface.
*
* \note This should be preceded immediately by a call to the USB_Audio_IsReadyForNextSample() function to ensure that
* the correct endpoint is selected and ready for data.
*
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state
* \param[in] Sample Signed 24-bit audio sample
*/
static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int32_t Sample) ATTR_ALWAYS_INLINE;
static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
const int32_t Sample)
{
Endpoint_Write_Byte(Sample >> 16);
Endpoint_Write_Word_LE(Sample);
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
Endpoint_ClearIN();
}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,299 +1,299 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_CDC_CLASS_DEVICE_C
#define __INCLUDE_FROM_CDC_DRIVER
#include "CDC.h"
void CDC_Device_Event_Stub(void)
{
}
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_GetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
Endpoint_ClearOUT();
}
break;
case REQ_SetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
Endpoint_ClearIN();
}
break;
case REQ_SetControlLineState:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
Endpoint_ClearStatusStage();
}
break;
case REQ_SendBreak:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue);
Endpoint_ClearStatusStage();
}
break;
}
}
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.DataINEndpointSize,
CDCInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, CDCInterfaceInfo->Config.DataOUTEndpointSize,
CDCInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.NotificationEndpointSize,
CDCInterfaceInfo->Config.NotificationEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsOUTReceived() && !(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
CDC_Device_Flush(CDCInterfaceInfo);
}
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
return Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
}
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
if (!(Endpoint_IsReadWriteAllowed()))
{
Endpoint_ClearIN();
uint8_t ErrorCode;
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
return ErrorCode;
}
Endpoint_Write_Byte(Data);
return ENDPOINT_READYWAIT_NoError;
}
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
uint8_t ErrorCode;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
if (!(Endpoint_BytesInEndpoint()))
return ENDPOINT_READYWAIT_NoError;
bool BankFull = !(Endpoint_IsReadWriteAllowed());
Endpoint_ClearIN();
if (BankFull)
{
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
return ErrorCode;
Endpoint_ClearIN();
}
return ENDPOINT_READYWAIT_NoError;
}
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return 0;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsOUTReceived())
{
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
return 0;
}
else
{
return Endpoint_BytesInEndpoint();
}
}
else
{
return 0;
}
}
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return 0;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
uint8_t DataByte = Endpoint_Read_Byte();
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return DataByte;
}
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber);
USB_Request_Header_t Notification = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = NOTIF_SerialState,
.wValue = 0,
.wIndex = 0,
.wLength = sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
};
Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
NO_STREAM_CALLBACK);
Endpoint_ClearIN();
}
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Device_putchar(char c, FILE* Stream)
{
return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
}
static int CDC_Device_getchar(FILE* Stream)
{
if (!(CDC_Device_BytesReceived((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))))
return _FDEV_EOF;
return CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
}
static int CDC_Device_getchar_Blocking(FILE* Stream)
{
while (!(CDC_Device_BytesReceived((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return _FDEV_EOF;
CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
USB_USBTask();
}
return CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_CDC_CLASS_DEVICE_C
#define __INCLUDE_FROM_CDC_DRIVER
#include "CDC.h"
void CDC_Device_Event_Stub(void)
{
}
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_GetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
Endpoint_ClearOUT();
}
break;
case REQ_SetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
Endpoint_ClearIN();
}
break;
case REQ_SetControlLineState:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
Endpoint_ClearStatusStage();
}
break;
case REQ_SendBreak:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue);
Endpoint_ClearStatusStage();
}
break;
}
}
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.DataINEndpointSize,
CDCInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, CDCInterfaceInfo->Config.DataOUTEndpointSize,
CDCInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.NotificationEndpointSize,
CDCInterfaceInfo->Config.NotificationEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsOUTReceived() && !(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
CDC_Device_Flush(CDCInterfaceInfo);
}
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
return Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
}
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
if (!(Endpoint_IsReadWriteAllowed()))
{
Endpoint_ClearIN();
uint8_t ErrorCode;
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
return ErrorCode;
}
Endpoint_Write_Byte(Data);
return ENDPOINT_READYWAIT_NoError;
}
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
uint8_t ErrorCode;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
if (!(Endpoint_BytesInEndpoint()))
return ENDPOINT_READYWAIT_NoError;
bool BankFull = !(Endpoint_IsReadWriteAllowed());
Endpoint_ClearIN();
if (BankFull)
{
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
return ErrorCode;
Endpoint_ClearIN();
}
return ENDPOINT_READYWAIT_NoError;
}
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return 0;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsOUTReceived())
{
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
return 0;
}
else
{
return Endpoint_BytesInEndpoint();
}
}
else
{
return 0;
}
}
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return 0;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
uint8_t DataByte = Endpoint_Read_Byte();
if (!(Endpoint_BytesInEndpoint()))
Endpoint_ClearOUT();
return DataByte;
}
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber);
USB_Request_Header_t Notification = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = NOTIF_SerialState,
.wValue = 0,
.wIndex = 0,
.wLength = sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
};
Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
NO_STREAM_CALLBACK);
Endpoint_ClearIN();
}
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Device_putchar(char c, FILE* Stream)
{
return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
}
static int CDC_Device_getchar(FILE* Stream)
{
if (!(CDC_Device_BytesReceived((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))))
return _FDEV_EOF;
return CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
}
static int CDC_Device_getchar_Blocking(FILE* Stream)
{
while (!(CDC_Device_BytesReceived((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return _FDEV_EOF;
CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
USB_USBTask();
}
return CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
}
#endif

View file

@ -1,331 +1,331 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB CDC Class driver.
*
* Device mode driver for the library USB CDC Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/CDC.h.
*/
/** \ingroup Group_USBClassCDC
* @defgroup Group_USBClassCDCDevice CDC Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/CDC.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the CDC USB Class driver.
*
* \note There are several major drawbacks to the CDC-ACM standard USB class, however
* it is very standardized and thus usually available as a built-in driver on
* most platforms, and so is a better choice than a proprietary serial class.
*
* One major issue with CDC-ACM is that it requires two Interface descriptors,
* which will upset most hosts when part of a multi-function "Composite" USB
* device, as each interface will be loaded into a separate driver instance. To
* conbat this, you should use the "Interface Association Descriptor" addendum to
* the USB standard which is available on most OSes when creating Composite devices.
*
* Another major oversight is that there is no mechanism for the host to notify the
* device that there is a data sink on the host side ready to accept data. This
* means that the device may try to send data while the host isn't listening, causing
* lengthy blocking timeouts in the transmission routines. To combat this, it is
* recommended that the virtual serial line DTR (Data Terminal Ready) be used where
* possible to determine if a host application is ready for data.
*
* @{
*/
#ifndef _CDC_CLASS_DEVICE_H_
#define _CDC_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/CDC.h"
#include <stdio.h>
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/CDC.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief CDC Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each CDC interface
* within the user application, and passed to each of the CDC class driver functions as the
* CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
bool DataINEndpointDoubleBank; /** Indicates if the CDC interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
bool DataOUTEndpointDoubleBank; /** Indicates if the CDC interface's OUT data endpoint should use double banking */
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
bool NotificationEndpointDoubleBank; /** Indicates if the CDC interface's notification endpoint should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
struct
{
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
* masks. This value is updated each time \ref CDC_Device_USBTask() is called.
*/
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
* masks - to notify the host of changes to these values, call the
* \ref CDC_Device_SendControlLineStateChange() function.
*/
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
struct
{
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
* CDCDevice_CDC_LineCodingFormats_t enum
*/
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
* CDCDevice_LineCodingParity_t enum
*/
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
} LineEncoding; /** Line encoding used in the virtual serial port, for the device's information. This is generally
* only used if the virtual serial port data is to be reconstructed on a physical UART.
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_CDC_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
* the given CDC interface is selected.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given CDC class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
* line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
* user program by declaring a handler function with the same name and parameters listed here. The new line encoding
* settings are available in the LineEncoding structure inside the CDC interface structure passed as a parameter.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
* control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
* user program by declaring a handler function with the same name and parameters listed here. The new control line states
* are available in the ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as
* a mask of CDC_CONTROL_LINE_OUT_* masks.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** CDC class driver event for a send break request sent to the device from the host. This is generally used to seperate
* data or to indicate a special condition to the receiving device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in] Duration Duration of the break that has been sent by the host, in milliseconds
*/
void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given string to the attached USB host, if connected. If a host is not connected when the function is called, the
* string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
* \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in] Data Pointer to the string to send to the host
* \param[in] Length Size in bytes of the string to send to the host
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum
*/
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
* byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
* \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in] Data Byte of data to send to the host
*
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
/** Determines the number of bytes received by the CDC interface from the host, waiting to be read.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return Total number of buffered bytes received from the host
*/
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
* returns 0. The \ref CDC_Device_BytesReceived() function should be queried before data is received to ensure that no data
* underflow occurs.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return Next received byte from the host, or 0 if no data received
*/
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
* control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist
* until they are cleared via a second notification. This should be called each time the CDC class driver's
* ControlLineStates.DeviceToHost value is updated to push the new states to the USB host.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Creates a standard characer stream for the given CDC Device instance so that it can be used with all the regular
* functions in the avr-libc <stdio.h> library that accept a FILE stream as a destination (e.g. fprintf). The created
* stream is bidirectional and can be used for both input and output functions.
*
* Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
* fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
* be used when the read data is processed byte-per-bye (via getc()) or when the user application will implement its own
* line buffering.
*
* \note The created stream can be given as stdout if desired to direct the standard output from all <stdio.h> functions
* to the given CDC interface.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream);
/** Identical to CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
* the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_CDC_CLASS_DEVICE_C)
static int CDC_Device_putchar(char c, FILE* Stream);
static int CDC_Device_getchar(FILE* Stream);
static int CDC_Device_getchar_Blocking(FILE* Stream);
void CDC_Device_Event_Stub(void);
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t Duration)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB CDC Class driver.
*
* Device mode driver for the library USB CDC Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/CDC.h.
*/
/** \ingroup Group_USBClassCDC
* @defgroup Group_USBClassCDCDevice CDC Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/CDC.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the CDC USB Class driver.
*
* \note There are several major drawbacks to the CDC-ACM standard USB class, however
* it is very standardized and thus usually available as a built-in driver on
* most platforms, and so is a better choice than a proprietary serial class.
*
* One major issue with CDC-ACM is that it requires two Interface descriptors,
* which will upset most hosts when part of a multi-function "Composite" USB
* device, as each interface will be loaded into a separate driver instance. To
* conbat this, you should use the "Interface Association Descriptor" addendum to
* the USB standard which is available on most OSes when creating Composite devices.
*
* Another major oversight is that there is no mechanism for the host to notify the
* device that there is a data sink on the host side ready to accept data. This
* means that the device may try to send data while the host isn't listening, causing
* lengthy blocking timeouts in the transmission routines. To combat this, it is
* recommended that the virtual serial line DTR (Data Terminal Ready) be used where
* possible to determine if a host application is ready for data.
*
* @{
*/
#ifndef _CDC_CLASS_DEVICE_H_
#define _CDC_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/CDC.h"
#include <stdio.h>
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/CDC.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief CDC Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each CDC interface
* within the user application, and passed to each of the CDC class driver functions as the
* CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
bool DataINEndpointDoubleBank; /** Indicates if the CDC interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
bool DataOUTEndpointDoubleBank; /** Indicates if the CDC interface's OUT data endpoint should use double banking */
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
bool NotificationEndpointDoubleBank; /** Indicates if the CDC interface's notification endpoint should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
struct
{
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
* masks. This value is updated each time \ref CDC_Device_USBTask() is called.
*/
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
* masks - to notify the host of changes to these values, call the
* \ref CDC_Device_SendControlLineStateChange() function.
*/
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
struct
{
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
* CDCDevice_CDC_LineCodingFormats_t enum
*/
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
* CDCDevice_LineCodingParity_t enum
*/
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
} LineEncoding; /** Line encoding used in the virtual serial port, for the device's information. This is generally
* only used if the virtual serial port data is to be reconstructed on a physical UART.
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_CDC_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
* the given CDC interface is selected.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given CDC class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
* line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
* user program by declaring a handler function with the same name and parameters listed here. The new line encoding
* settings are available in the LineEncoding structure inside the CDC interface structure passed as a parameter.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
* control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
* user program by declaring a handler function with the same name and parameters listed here. The new control line states
* are available in the ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as
* a mask of CDC_CONTROL_LINE_OUT_* masks.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** CDC class driver event for a send break request sent to the device from the host. This is generally used to seperate
* data or to indicate a special condition to the receiving device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in] Duration Duration of the break that has been sent by the host, in milliseconds
*/
void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given string to the attached USB host, if connected. If a host is not connected when the function is called, the
* string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
* \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in] Data Pointer to the string to send to the host
* \param[in] Length Size in bytes of the string to send to the host
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum
*/
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
* byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
* \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in] Data Byte of data to send to the host
*
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
/** Determines the number of bytes received by the CDC interface from the host, waiting to be read.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return Total number of buffered bytes received from the host
*/
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
* returns 0. The \ref CDC_Device_BytesReceived() function should be queried before data is received to ensure that no data
* underflow occurs.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return Next received byte from the host, or 0 if no data received
*/
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
* control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist
* until they are cleared via a second notification. This should be called each time the CDC class driver's
* ControlLineStates.DeviceToHost value is updated to push the new states to the USB host.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
*/
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Creates a standard characer stream for the given CDC Device instance so that it can be used with all the regular
* functions in the avr-libc <stdio.h> library that accept a FILE stream as a destination (e.g. fprintf). The created
* stream is bidirectional and can be used for both input and output functions.
*
* Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
* fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
* be used when the read data is processed byte-per-bye (via getc()) or when the user application will implement its own
* line buffering.
*
* \note The created stream can be given as stdout if desired to direct the standard output from all <stdio.h> functions
* to the given CDC interface.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream);
/** Identical to CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
* the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, FILE* Stream);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_CDC_CLASS_DEVICE_C)
static int CDC_Device_putchar(char c, FILE* Stream);
static int CDC_Device_getchar(FILE* Stream);
static int CDC_Device_getchar_Blocking(FILE* Stream);
void CDC_Device_Event_Stub(void);
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t Duration)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,194 +1,194 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_HID_DRIVER
#include "HID.h"
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_GetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
uint16_t ReportINSize = 0;
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
memset(ReportINData, 0, sizeof(ReportINData));
CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType,
HIDInterfaceInfo->Config.PrevReportINBuffer, &ReportINSize);
if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
Endpoint_Write_Control_Stream_LE(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize);
Endpoint_ClearOUT();
}
break;
case REQ_SetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
uint16_t ReportOUTSize = USB_ControlRequest.wLength;
uint8_t ReportOUTData[ReportOUTSize];
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
Endpoint_Read_Control_Stream_LE(ReportOUTData, ReportOUTSize);
CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportOUTData, ReportOUTSize);
Endpoint_ClearIN();
}
break;
case REQ_GetProtocol:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
case REQ_SetProtocol:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
Endpoint_ClearStatusStage();
}
break;
case REQ_SetIdle:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
Endpoint_ClearStatusStage();
}
break;
case REQ_GetIdle:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
}
}
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
{
memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
HIDInterfaceInfo->State.UsingReportProtocol = true;
HIDInterfaceInfo->State.IdleCount = 500;
if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize,
HIDInterfaceInfo->Config.ReportINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
if (Endpoint_IsReadWriteAllowed())
{
uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
uint8_t ReportID = 0;
uint16_t ReportINSize = 0;
memset(ReportINData, 0, sizeof(ReportINData));
bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, REPORT_ITEM_TYPE_In,
ReportINData, &ReportINSize);
bool StatesChanged = false;
bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
{
StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
}
if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
{
HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
if (ReportID)
Endpoint_Write_Byte(ReportID);
Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NO_STREAM_CALLBACK);
Endpoint_ClearIN();
}
}
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_HID_DRIVER
#include "HID.h"
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_GetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
uint16_t ReportINSize = 0;
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
memset(ReportINData, 0, sizeof(ReportINData));
CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType,
HIDInterfaceInfo->Config.PrevReportINBuffer, &ReportINSize);
if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
Endpoint_Write_Control_Stream_LE(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize);
Endpoint_ClearOUT();
}
break;
case REQ_SetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
uint16_t ReportOUTSize = USB_ControlRequest.wLength;
uint8_t ReportOUTData[ReportOUTSize];
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
Endpoint_Read_Control_Stream_LE(ReportOUTData, ReportOUTSize);
CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportOUTData, ReportOUTSize);
Endpoint_ClearIN();
}
break;
case REQ_GetProtocol:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
case REQ_SetProtocol:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
Endpoint_ClearStatusStage();
}
break;
case REQ_SetIdle:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
Endpoint_ClearStatusStage();
}
break;
case REQ_GetIdle:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
}
}
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
{
memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
HIDInterfaceInfo->State.UsingReportProtocol = true;
HIDInterfaceInfo->State.IdleCount = 500;
if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize,
HIDInterfaceInfo->Config.ReportINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
if (Endpoint_IsReadWriteAllowed())
{
uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
uint8_t ReportID = 0;
uint16_t ReportINSize = 0;
memset(ReportINData, 0, sizeof(ReportINData));
bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, REPORT_ITEM_TYPE_In,
ReportINData, &ReportINSize);
bool StatesChanged = false;
bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
{
StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
}
if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
{
HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
if (ReportID)
Endpoint_Write_Byte(ReportID);
Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NO_STREAM_CALLBACK);
Endpoint_ClearIN();
}
}
}
#endif

View file

@ -1,206 +1,206 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB HID Class driver.
*
* Device mode driver for the library USB HID Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/HID.h.
*/
/** \ingroup Group_USBClassHID
* @defgroup Group_USBClassHIDDevice HID Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/HID.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the HID USB Class driver.
*
* @{
*/
#ifndef _HID_CLASS_DEVICE_H_
#define _HID_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/HID.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_HID_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/HID.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief HID Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each HID interface
* within the user application, and passed to each of the HID class driver functions as the
* HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information.
*
* \note Due to technical limitations, the HID device class driver does not utilize a separate OUT
* endpoint for host->device communications. Instead, the host->device data (if any) is sent to
* the device via the control endpoint.
*/
typedef struct
{
const struct
{
uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device */
uint8_t ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */
uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */
bool ReportINEndpointDoubleBank; /** Indicates if the HID interface's IN report endpoint should use double banking */
void* PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be
* stored by the driver, for comparison purposes to detect report changes that
* must be sent immediately to the host. This should point to a buffer big enough
* to hold the largest HID input report sent from the HID interface. If this is set
* to NULL, it is up to the user to force transfers when needed in the
* \ref CALLBACK_HID_Device_CreateHIDReport() callback function.
*
* \note Due to the single buffer, the internal driver can only correctly compare
* subsequent reports with identical report IDs. In multiple report devices,
* this buffer should be set to NULL and the decision to send reports made
* by the user application instead.
*/
uint8_t PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a
* second buffer of the same size within the driver so that subsequent reports
* can be compared. If the user app is to determine when reports are to be sent
* exclusively (i.e. \ref PrevReportINBuffer is NULL) this value must still be
* set to the size of the largest report the device can issue to the host.
*/
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */
uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host */
uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this
* should be decremented by the user application if non-zero each millisecond */
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_HID_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given HID interface is selected.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*/
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given HID class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*/
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either
* HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
* user is responsible for the creation of the next HID input report to be sent to the host.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
* \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero, this should
* be set to the report ID of the generated HID input report (if any). If multiple reports are not sent via the
* given HID interface, this parameter should be ignored.
* \param[in] ReportType Type of HID report to generate, either \ref REPORT_ITEM_TYPE_In or \ref REPORT_ITEM_TYPE_Feature
* \param[out] ReportData Pointer to a buffer where the generated HID report should be stored
* \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent
*
* \return Boolean true to force the sending of the report even if it is identical to the previous report and still within
* the idle period (useful for devices which report relative movement), false otherwise
*/
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5);
/** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to
* either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
* the user is responsible for the processing of the received HID output report from the host.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
* \param[in] ReportID Report ID of the received output report. If multiple reports are not received via the given HID
* interface, this parameter should be ignored.
* \param[in] ReportData Pointer to a buffer where the received HID report is stored.
* \param[in] ReportSize Size in bytes of the received report from the host.
*/
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/* Inline Functions: */
/** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
* decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
* that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via
* \ref USB_Device_EnableSOFEvents();.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*/
static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo)
{
if (HIDInterfaceInfo->State.IdleMSRemaining)
HIDInterfaceInfo->State.IdleMSRemaining--;
}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB HID Class driver.
*
* Device mode driver for the library USB HID Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/HID.h.
*/
/** \ingroup Group_USBClassHID
* @defgroup Group_USBClassHIDDevice HID Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/HID.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the HID USB Class driver.
*
* @{
*/
#ifndef _HID_CLASS_DEVICE_H_
#define _HID_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/HID.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_HID_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/HID.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief HID Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each HID interface
* within the user application, and passed to each of the HID class driver functions as the
* HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information.
*
* \note Due to technical limitations, the HID device class driver does not utilize a separate OUT
* endpoint for host->device communications. Instead, the host->device data (if any) is sent to
* the device via the control endpoint.
*/
typedef struct
{
const struct
{
uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device */
uint8_t ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */
uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */
bool ReportINEndpointDoubleBank; /** Indicates if the HID interface's IN report endpoint should use double banking */
void* PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be
* stored by the driver, for comparison purposes to detect report changes that
* must be sent immediately to the host. This should point to a buffer big enough
* to hold the largest HID input report sent from the HID interface. If this is set
* to NULL, it is up to the user to force transfers when needed in the
* \ref CALLBACK_HID_Device_CreateHIDReport() callback function.
*
* \note Due to the single buffer, the internal driver can only correctly compare
* subsequent reports with identical report IDs. In multiple report devices,
* this buffer should be set to NULL and the decision to send reports made
* by the user application instead.
*/
uint8_t PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a
* second buffer of the same size within the driver so that subsequent reports
* can be compared. If the user app is to determine when reports are to be sent
* exclusively (i.e. \ref PrevReportINBuffer is NULL) this value must still be
* set to the size of the largest report the device can issue to the host.
*/
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */
uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host */
uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this
* should be decremented by the user application if non-zero each millisecond */
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_HID_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given HID interface is selected.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*/
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given HID class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*/
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either
* HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
* user is responsible for the creation of the next HID input report to be sent to the host.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
* \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero, this should
* be set to the report ID of the generated HID input report (if any). If multiple reports are not sent via the
* given HID interface, this parameter should be ignored.
* \param[in] ReportType Type of HID report to generate, either \ref REPORT_ITEM_TYPE_In or \ref REPORT_ITEM_TYPE_Feature
* \param[out] ReportData Pointer to a buffer where the generated HID report should be stored
* \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent
*
* \return Boolean true to force the sending of the report even if it is identical to the previous report and still within
* the idle period (useful for devices which report relative movement), false otherwise
*/
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5);
/** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to
* either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
* the user is responsible for the processing of the received HID output report from the host.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
* \param[in] ReportID Report ID of the received output report. If multiple reports are not received via the given HID
* interface, this parameter should be ignored.
* \param[in] ReportData Pointer to a buffer where the received HID report is stored.
* \param[in] ReportSize Size in bytes of the received report from the host.
*/
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/* Inline Functions: */
/** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
* decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
* that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via
* \ref USB_Device_EnableSOFEvents();.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state
*/
static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo)
{
if (HIDInterfaceInfo->State.IdleMSRemaining)
HIDInterfaceInfo->State.IdleMSRemaining--;
}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,124 +1,124 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_MIDI_DRIVER
#include "MIDI.h"
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
if (MIDIInterfaceInfo->Config.DataINEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, MIDIInterfaceInfo->Config.DataINEndpointSize,
MIDIInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
if (MIDIInterfaceInfo->Config.DataOUTEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, MIDIInterfaceInfo->Config.DataOUTEndpointSize,
MIDIInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
return true;
}
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
if (Endpoint_IsReadWriteAllowed());
{
uint8_t ErrorCode;
if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != ENDPOINT_RWSTREAM_NoError)
return ErrorCode;
if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearIN();
}
return ENDPOINT_RWSTREAM_NoError;
}
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return ENDPOINT_RWSTREAM_DeviceDisconnected;
uint8_t ErrorCode;
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
if (Endpoint_BytesInEndpoint())
{
Endpoint_ClearIN();
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
return ErrorCode;
}
return ENDPOINT_READYWAIT_NoError;
}
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return false;
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber);
if (!(Endpoint_IsReadWriteAllowed()))
return false;
Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearOUT();
return true;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_MIDI_DRIVER
#include "MIDI.h"
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
if (MIDIInterfaceInfo->Config.DataINEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, MIDIInterfaceInfo->Config.DataINEndpointSize,
MIDIInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
if (MIDIInterfaceInfo->Config.DataOUTEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, MIDIInterfaceInfo->Config.DataOUTEndpointSize,
MIDIInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
return true;
}
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
if (Endpoint_IsReadWriteAllowed());
{
uint8_t ErrorCode;
if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != ENDPOINT_RWSTREAM_NoError)
return ErrorCode;
if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearIN();
}
return ENDPOINT_RWSTREAM_NoError;
}
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return ENDPOINT_RWSTREAM_DeviceDisconnected;
uint8_t ErrorCode;
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
if (Endpoint_BytesInEndpoint())
{
Endpoint_ClearIN();
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
return ErrorCode;
}
return ENDPOINT_READYWAIT_NoError;
}
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return false;
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber);
if (!(Endpoint_IsReadWriteAllowed()))
return false;
Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearOUT();
return true;
}
#endif

View file

@ -1,184 +1,184 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB MIDI Class driver.
*
* Device mode driver for the library USB MIDI Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MIDI.h.
*/
/** \ingroup Group_USBClassMIDI
* @defgroup Group_USBClassMIDIDevice MIDI Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MIDI.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the MIDI USB Class driver.
*
* @{
*/
#ifndef _MIDI_CLASS_DEVICE_H_
#define _MIDI_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/MIDI.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MIDI.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Define: */
/** \brief MIDI Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each MIDI interface
* within the user application, and passed to each of the MIDI class driver functions as the
* MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls */
uint8_t DataINEndpointNumber; /**< Endpoint number of the incoming MIDI data, if available (zero if unused) */
uint16_t DataINEndpointSize; /**< Size in bytes of the incoming MIDI data endpoint, if available (zero if unused) */
bool DataINEndpointDoubleBank; /** Indicates if the MIDI interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing MIDI data, if available (zero if unused) */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing MIDI data endpoint, if available (zero if unused) */
bool DataOUTEndpointDoubleBank; /** Indicates if the MIDI interface's IN data endpoint should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
// No state information for this class yet
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_MIDI_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given MIDI interface is selected.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the
* endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple
* MIDI events to be packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum
*/
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the
* \ref MIDI_Device_SendEventPacket() function's packing behaviour, to flush queued events.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
/** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains
* multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed
*
* \return Boolean true if a MIDI event packet was received, false otherwise
*/
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given MIDI class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*/
static inline void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
static inline void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
(void)MIDIInterfaceInfo;
}
/** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*/
static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
(void)MIDIInterfaceInfo;
}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB MIDI Class driver.
*
* Device mode driver for the library USB MIDI Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MIDI.h.
*/
/** \ingroup Group_USBClassMIDI
* @defgroup Group_USBClassMIDIDevice MIDI Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MIDI.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the MIDI USB Class driver.
*
* @{
*/
#ifndef _MIDI_CLASS_DEVICE_H_
#define _MIDI_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/MIDI.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MIDI.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Define: */
/** \brief MIDI Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each MIDI interface
* within the user application, and passed to each of the MIDI class driver functions as the
* MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls */
uint8_t DataINEndpointNumber; /**< Endpoint number of the incoming MIDI data, if available (zero if unused) */
uint16_t DataINEndpointSize; /**< Size in bytes of the incoming MIDI data endpoint, if available (zero if unused) */
bool DataINEndpointDoubleBank; /** Indicates if the MIDI interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing MIDI data, if available (zero if unused) */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing MIDI data endpoint, if available (zero if unused) */
bool DataOUTEndpointDoubleBank; /** Indicates if the MIDI interface's IN data endpoint should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
// No state information for this class yet
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_MIDI_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given MIDI interface is selected.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the
* endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple
* MIDI events to be packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum
*/
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the
* \ref MIDI_Device_SendEventPacket() function's packing behaviour, to flush queued events.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
/** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains
* multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed
*
* \return Boolean true if a MIDI event packet was received, false otherwise
*/
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given MIDI class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*/
static inline void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
static inline void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
(void)MIDIInterfaceInfo;
}
/** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*/
static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
(void)MIDIInterfaceInfo;
}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,230 +1,230 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_MS_CLASS_DEVICE_C
#define __INCLUDE_FROM_MS_DRIVER
#include "MassStorage.h"
static volatile bool* CallbackIsResetSource;
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_MassStorageReset:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
MSInterfaceInfo->State.IsMassStoreReset = true;
Endpoint_ClearStatusStage();
}
break;
case REQ_GetMaxLUN:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
}
}
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, MSInterfaceInfo->Config.DataINEndpointSize,
MSInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, MSInterfaceInfo->Config.DataOUTEndpointSize,
MSInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsReadWriteAllowed())
{
if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
{
if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
MSInterfaceInfo->State.CommandStatus.Status = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo) ?
SCSI_Command_Pass : SCSI_Command_Fail;
MSInterfaceInfo->State.CommandStatus.Signature = MS_CSW_SIGNATURE;
MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag;
MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;
if ((MSInterfaceInfo->State.CommandStatus.Status == SCSI_Command_Fail) &&
(MSInterfaceInfo->State.CommandStatus.DataTransferResidue))
{
Endpoint_StallTransaction();
}
MS_Device_ReturnCommandStatus(MSInterfaceInfo);
}
}
if (MSInterfaceInfo->State.IsMassStoreReset)
{
Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataOUTEndpointNumber);
Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataINEndpointNumber);
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
Endpoint_ClearStall();
Endpoint_ResetDataToggle();
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
Endpoint_ClearStall();
Endpoint_ResetDataToggle();
MSInterfaceInfo->State.IsMassStoreReset = false;
}
}
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
if (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock,
(sizeof(MS_CommandBlockWrapper_t) - 16),
StreamCallback_MS_Device_AbortOnMassStoreReset))
{
return false;
}
if ((MSInterfaceInfo->State.CommandBlock.Signature != MS_CBW_SIGNATURE) ||
(MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) ||
(MSInterfaceInfo->State.CommandBlock.Flags & 0x1F) ||
(MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0) ||
(MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16))
{
Endpoint_StallTransaction();
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
Endpoint_StallTransaction();
return false;
}
CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
if (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData,
MSInterfaceInfo->State.CommandBlock.SCSICommandLength,
StreamCallback_MS_Device_AbortOnMassStoreReset))
{
return false;
}
Endpoint_ClearOUT();
return true;
}
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
while (Endpoint_IsStalled())
{
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
USB_USBTask();
#endif
if (MSInterfaceInfo->State.IsMassStoreReset)
return;
}
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
while (Endpoint_IsStalled())
{
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
USB_USBTask();
#endif
if (MSInterfaceInfo->State.IsMassStoreReset)
return;
}
CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
if (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus, sizeof(MS_CommandStatusWrapper_t),
StreamCallback_MS_Device_AbortOnMassStoreReset))
{
return;
}
Endpoint_ClearIN();
}
static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void)
{
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
USB_USBTask();
#endif
if (*CallbackIsResetSource)
return STREAMCALLBACK_Abort;
else
return STREAMCALLBACK_Continue;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_MS_CLASS_DEVICE_C
#define __INCLUDE_FROM_MS_DRIVER
#include "MassStorage.h"
static volatile bool* CallbackIsResetSource;
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_MassStorageReset:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
MSInterfaceInfo->State.IsMassStoreReset = true;
Endpoint_ClearStatusStage();
}
break;
case REQ_GetMaxLUN:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
}
}
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, MSInterfaceInfo->Config.DataINEndpointSize,
MSInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, MSInterfaceInfo->Config.DataOUTEndpointSize,
MSInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsReadWriteAllowed())
{
if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
{
if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
MSInterfaceInfo->State.CommandStatus.Status = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo) ?
SCSI_Command_Pass : SCSI_Command_Fail;
MSInterfaceInfo->State.CommandStatus.Signature = MS_CSW_SIGNATURE;
MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag;
MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;
if ((MSInterfaceInfo->State.CommandStatus.Status == SCSI_Command_Fail) &&
(MSInterfaceInfo->State.CommandStatus.DataTransferResidue))
{
Endpoint_StallTransaction();
}
MS_Device_ReturnCommandStatus(MSInterfaceInfo);
}
}
if (MSInterfaceInfo->State.IsMassStoreReset)
{
Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataOUTEndpointNumber);
Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataINEndpointNumber);
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
Endpoint_ClearStall();
Endpoint_ResetDataToggle();
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
Endpoint_ClearStall();
Endpoint_ResetDataToggle();
MSInterfaceInfo->State.IsMassStoreReset = false;
}
}
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
if (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock,
(sizeof(MS_CommandBlockWrapper_t) - 16),
StreamCallback_MS_Device_AbortOnMassStoreReset))
{
return false;
}
if ((MSInterfaceInfo->State.CommandBlock.Signature != MS_CBW_SIGNATURE) ||
(MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) ||
(MSInterfaceInfo->State.CommandBlock.Flags & 0x1F) ||
(MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0) ||
(MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16))
{
Endpoint_StallTransaction();
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
Endpoint_StallTransaction();
return false;
}
CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
if (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData,
MSInterfaceInfo->State.CommandBlock.SCSICommandLength,
StreamCallback_MS_Device_AbortOnMassStoreReset))
{
return false;
}
Endpoint_ClearOUT();
return true;
}
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
while (Endpoint_IsStalled())
{
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
USB_USBTask();
#endif
if (MSInterfaceInfo->State.IsMassStoreReset)
return;
}
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
while (Endpoint_IsStalled())
{
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
USB_USBTask();
#endif
if (MSInterfaceInfo->State.IsMassStoreReset)
return;
}
CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
if (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus, sizeof(MS_CommandStatusWrapper_t),
StreamCallback_MS_Device_AbortOnMassStoreReset))
{
return;
}
Endpoint_ClearIN();
}
static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void)
{
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
USB_USBTask();
#endif
if (*CallbackIsResetSource)
return STREAMCALLBACK_Abort;
else
return STREAMCALLBACK_Continue;
}
#endif

View file

@ -1,168 +1,168 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB Mass Storage Class driver.
*
* Device mode driver for the library USB Mass Storage Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MassStorage.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassMSDevice Mass Storage Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MassStorage.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
*
* @{
*/
#ifndef _MS_CLASS_DEVICE_H_
#define _MS_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/MassStorage.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MassStorage.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief Mass Storage Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each Mass Storage interface
* within the user application, and passed to each of the Mass Storage class driver functions as the
* MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device */
uint8_t DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint */
uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint */
bool DataINEndpointDoubleBank; /** Indicates if the Mass Storage interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the Mass Storage interface's OUT data endpoint */
bool DataOUTEndpointDoubleBank; /** Indicates if the Mass Storage interface's OUT data endpoint should use double banking */
uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
MS_CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI
* command from the host which is to be processed
*/
MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate
* the issued command's success or failure to the host
*/
volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
* and that all current Mass Storage operations should immediately abort
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_MS_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given Mass Storage interface is selected.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
*/
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state
*/
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
* host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
* for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure
* inside the Mass Storage class state structure passed as a parameter to the callback function.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
*
* \return Boolean true if the SCSI command was successfully processed, false otherwise
*/
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_MS_CLASS_DEVICE_C)
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB Mass Storage Class driver.
*
* Device mode driver for the library USB Mass Storage Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MassStorage.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassMSDevice Mass Storage Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MassStorage.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
*
* @{
*/
#ifndef _MS_CLASS_DEVICE_H_
#define _MS_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/MassStorage.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MassStorage.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief Mass Storage Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each Mass Storage interface
* within the user application, and passed to each of the Mass Storage class driver functions as the
* MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device */
uint8_t DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint */
uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint */
bool DataINEndpointDoubleBank; /** Indicates if the Mass Storage interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the Mass Storage interface's OUT data endpoint */
bool DataOUTEndpointDoubleBank; /** Indicates if the Mass Storage interface's OUT data endpoint should use double banking */
uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
MS_CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI
* command from the host which is to be processed
*/
MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate
* the issued command's success or failure to the host
*/
volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
* and that all current Mass Storage operations should immediately abort
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_MS_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given Mass Storage interface is selected.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
*/
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state
*/
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
* host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
* for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure
* inside the Mass Storage class state structure passed as a parameter to the callback function.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
*
* \return Boolean true if the SCSI command was successfully processed, false otherwise
*/
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_MS_CLASS_DEVICE_C)
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,472 +1,472 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_RNDIS_CLASS_DEVICE_C
#define __INCLUDE_FROM_RNDIS_DRIVER
#include "RNDIS.h"
static const uint32_t PROGMEM AdapterSupportedOIDList[] =
{
OID_GEN_SUPPORTED_LIST,
OID_GEN_PHYSICAL_MEDIUM,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_XMIT_OK,
OID_GEN_RCV_OK,
OID_GEN_XMIT_ERROR,
OID_GEN_RCV_ERROR,
OID_GEN_RCV_NO_BUFFER,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS,
};
void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_SendEncapsulatedCommand:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
Endpoint_ClearIN();
}
break;
case REQ_GetEncapsulatedResponse:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
if (!(MessageHeader->MessageLength))
{
RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0;
MessageHeader->MessageLength = 1;
}
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, MessageHeader->MessageLength);
Endpoint_ClearOUT();
MessageHeader->MessageLength = 0;
}
break;
}
}
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.DataINEndpointSize,
RNDISInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, RNDISInterfaceInfo->Config.DataOUTEndpointSize,
RNDISInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.NotificationEndpointSize,
RNDISInterfaceInfo->Config.NotificationEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber);
if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
{
USB_Request_Header_t Notification = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = NOTIF_ResponseAvailable,
.wValue = 0,
.wIndex = 0,
.wLength = 0,
};
Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
Endpoint_ClearIN();
RNDISInterfaceInfo->State.ResponseReady = false;
}
if ((RNDISInterfaceInfo->State.CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
{
RNDIS_Packet_Message_t RNDISPacketHeader;
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->State.FrameIN.FrameInBuffer))
{
Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NO_STREAM_CALLBACK);
if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
{
Endpoint_StallTransaction();
return;
}
Endpoint_Read_Stream_LE(RNDISInterfaceInfo->State.FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
Endpoint_ClearOUT();
RNDISInterfaceInfo->State.FrameIN.FrameLength = RNDISPacketHeader.DataLength;
RNDISInterfaceInfo->State.FrameIN.FrameInBuffer = true;
}
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber);
if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer)
{
memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
RNDISPacketHeader.MessageLength = (sizeof(RNDIS_Packet_Message_t) + RNDISInterfaceInfo->State.FrameOUT.FrameLength);
RNDISPacketHeader.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
RNDISPacketHeader.DataLength = RNDISInterfaceInfo->State.FrameOUT.FrameLength;
Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(RNDISInterfaceInfo->State.FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
Endpoint_ClearIN();
RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer = false;
}
}
}
void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
switch (MessageHeader->MessageType)
{
case REMOTE_NDIS_INITIALIZE_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Initialize_Message_t* INITIALIZE_Message =
(RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Initialize_Complete_t* INITIALIZE_Response =
(RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
INITIALIZE_Response->MessageLength = sizeof(RNDIS_Initialize_Complete_t);
INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
INITIALIZE_Response->MaxPacketsPerTransfer = 1;
INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
INITIALIZE_Response->PacketAlignmentFactor = 0;
INITIALIZE_Response->AFListOffset = 0;
INITIALIZE_Response->AFListSize = 0;
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
break;
case REMOTE_NDIS_HALT_MSG:
RNDISInterfaceInfo->State.ResponseReady = false;
MessageHeader->MessageLength = 0;
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
break;
case REMOTE_NDIS_QUERY_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
uint32_t Query_Oid = QUERY_Message->Oid;
void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
QUERY_Message->InformationBufferOffset];
void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
uint16_t ResponseSize;
QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
QUERY_Response->MessageLength = sizeof(RNDIS_Query_Complete_t);
if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
ResponseData, &ResponseSize))
{
QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
QUERY_Response->MessageLength += ResponseSize;
QUERY_Response->InformationBufferLength = ResponseSize;
QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
}
else
{
QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
QUERY_Response->InformationBufferLength = 0;
QUERY_Response->InformationBufferOffset = 0;
}
break;
case REMOTE_NDIS_SET_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
uint32_t SET_Oid = SET_Message->Oid;
SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
SET_Response->MessageLength = sizeof(RNDIS_Set_Complete_t);
SET_Response->RequestId = SET_Message->RequestId;
void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
SET_Message->InformationBufferOffset];
SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
SET_Message->InformationBufferLength) ?
REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
break;
case REMOTE_NDIS_RESET_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
RESET_Response->MessageLength = sizeof(RNDIS_Reset_Complete_t);
RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
RESET_Response->AddressingReset = 0;
break;
case REMOTE_NDIS_KEEPALIVE_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
(RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
(RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KeepAlive_Complete_t);
KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
break;
}
}
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
const uint32_t OId, void* const QueryData, const uint16_t QuerySize,
void* ResponseData, uint16_t* const ResponseSize)
{
(void)QueryData;
(void)QuerySize;
switch (OId)
{
case OID_GEN_SUPPORTED_LIST:
*ResponseSize = sizeof(AdapterSupportedOIDList);
memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
return true;
case OID_GEN_PHYSICAL_MEDIUM:
*ResponseSize = sizeof(uint32_t);
/* Indicate that the device is a true ethernet link */
*((uint32_t*)ResponseData) = 0;
return true;
case OID_GEN_HARDWARE_STATUS:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = NDIS_HardwareStatus_Ready;
return true;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
return true;
case OID_GEN_VENDOR_ID:
*ResponseSize = sizeof(uint32_t);
/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
*((uint32_t*)ResponseData) = 0x00FFFFFF;
return true;
case OID_GEN_MAXIMUM_FRAME_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
return true;
case OID_GEN_VENDOR_DESCRIPTION:
*ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
return true;
case OID_GEN_MEDIA_CONNECT_STATUS:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
return true;
case OID_GEN_LINK_SPEED:
*ResponseSize = sizeof(uint32_t);
/* Indicate 10Mb/s link speed */
*((uint32_t*)ResponseData) = 100000;
return true;
case OID_802_3_PERMANENT_ADDRESS:
case OID_802_3_CURRENT_ADDRESS:
*ResponseSize = sizeof(MAC_Address_t);
memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
return true;
case OID_802_3_MAXIMUM_LIST_SIZE:
*ResponseSize = sizeof(uint32_t);
/* Indicate only one multicast address supported */
*((uint32_t*)ResponseData) = 1;
return true;
case OID_GEN_CURRENT_PACKET_FILTER:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = RNDISInterfaceInfo->State.CurrPacketFilter;
return true;
case OID_GEN_XMIT_OK:
case OID_GEN_RCV_OK:
case OID_GEN_XMIT_ERROR:
case OID_GEN_RCV_ERROR:
case OID_GEN_RCV_NO_BUFFER:
case OID_802_3_RCV_ERROR_ALIGNMENT:
case OID_802_3_XMIT_ONE_COLLISION:
case OID_802_3_XMIT_MORE_COLLISIONS:
*ResponseSize = sizeof(uint32_t);
/* Unused statistic OIDs - always return 0 for each */
*((uint32_t*)ResponseData) = 0;
return true;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
*ResponseSize = sizeof(uint32_t);
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
*((uint32_t*)ResponseData) = (RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
return true;
default:
return false;
}
}
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, const uint32_t OId,
void* SetData, const uint16_t SetSize)
{
(void)SetSize;
switch (OId)
{
case OID_GEN_CURRENT_PACKET_FILTER:
RNDISInterfaceInfo->State.CurrPacketFilter = *((uint32_t*)SetData);
RNDISInterfaceInfo->State.CurrRNDISState = ((RNDISInterfaceInfo->State.CurrPacketFilter) ?
RNDIS_Data_Initialized : RNDIS_Data_Initialized);
return true;
case OID_802_3_MULTICAST_LIST:
/* Do nothing - throw away the value from the host as it is unused */
return true;
default:
return false;
}
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_DEVICE)
#define __INCLUDE_FROM_RNDIS_CLASS_DEVICE_C
#define __INCLUDE_FROM_RNDIS_DRIVER
#include "RNDIS.h"
static const uint32_t PROGMEM AdapterSupportedOIDList[] =
{
OID_GEN_SUPPORTED_LIST,
OID_GEN_PHYSICAL_MEDIUM,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_XMIT_OK,
OID_GEN_RCV_OK,
OID_GEN_XMIT_ERROR,
OID_GEN_RCV_ERROR,
OID_GEN_RCV_NO_BUFFER,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS,
};
void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
if (!(Endpoint_IsSETUPReceived()))
return;
if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
return;
switch (USB_ControlRequest.bRequest)
{
case REQ_SendEncapsulatedCommand:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
Endpoint_ClearIN();
}
break;
case REQ_GetEncapsulatedResponse:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
if (!(MessageHeader->MessageLength))
{
RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0;
MessageHeader->MessageLength = 1;
}
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, MessageHeader->MessageLength);
Endpoint_ClearOUT();
MessageHeader->MessageLength = 0;
}
break;
}
}
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.DataINEndpointSize,
RNDISInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, RNDISInterfaceInfo->Config.DataOUTEndpointSize,
RNDISInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.NotificationEndpointSize,
RNDISInterfaceInfo->Config.NotificationEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
return true;
}
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber);
if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
{
USB_Request_Header_t Notification = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = NOTIF_ResponseAvailable,
.wValue = 0,
.wIndex = 0,
.wLength = 0,
};
Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
Endpoint_ClearIN();
RNDISInterfaceInfo->State.ResponseReady = false;
}
if ((RNDISInterfaceInfo->State.CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
{
RNDIS_Packet_Message_t RNDISPacketHeader;
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber);
if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->State.FrameIN.FrameInBuffer))
{
Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NO_STREAM_CALLBACK);
if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
{
Endpoint_StallTransaction();
return;
}
Endpoint_Read_Stream_LE(RNDISInterfaceInfo->State.FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
Endpoint_ClearOUT();
RNDISInterfaceInfo->State.FrameIN.FrameLength = RNDISPacketHeader.DataLength;
RNDISInterfaceInfo->State.FrameIN.FrameInBuffer = true;
}
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber);
if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer)
{
memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
RNDISPacketHeader.MessageLength = (sizeof(RNDIS_Packet_Message_t) + RNDISInterfaceInfo->State.FrameOUT.FrameLength);
RNDISPacketHeader.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
RNDISPacketHeader.DataLength = RNDISInterfaceInfo->State.FrameOUT.FrameLength;
Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(RNDISInterfaceInfo->State.FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
Endpoint_ClearIN();
RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer = false;
}
}
}
void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
{
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
switch (MessageHeader->MessageType)
{
case REMOTE_NDIS_INITIALIZE_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Initialize_Message_t* INITIALIZE_Message =
(RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Initialize_Complete_t* INITIALIZE_Response =
(RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
INITIALIZE_Response->MessageLength = sizeof(RNDIS_Initialize_Complete_t);
INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
INITIALIZE_Response->MaxPacketsPerTransfer = 1;
INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
INITIALIZE_Response->PacketAlignmentFactor = 0;
INITIALIZE_Response->AFListOffset = 0;
INITIALIZE_Response->AFListSize = 0;
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
break;
case REMOTE_NDIS_HALT_MSG:
RNDISInterfaceInfo->State.ResponseReady = false;
MessageHeader->MessageLength = 0;
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
break;
case REMOTE_NDIS_QUERY_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
uint32_t Query_Oid = QUERY_Message->Oid;
void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
QUERY_Message->InformationBufferOffset];
void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
uint16_t ResponseSize;
QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
QUERY_Response->MessageLength = sizeof(RNDIS_Query_Complete_t);
if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
ResponseData, &ResponseSize))
{
QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
QUERY_Response->MessageLength += ResponseSize;
QUERY_Response->InformationBufferLength = ResponseSize;
QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
}
else
{
QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
QUERY_Response->InformationBufferLength = 0;
QUERY_Response->InformationBufferOffset = 0;
}
break;
case REMOTE_NDIS_SET_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
uint32_t SET_Oid = SET_Message->Oid;
SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
SET_Response->MessageLength = sizeof(RNDIS_Set_Complete_t);
SET_Response->RequestId = SET_Message->RequestId;
void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
SET_Message->InformationBufferOffset];
SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
SET_Message->InformationBufferLength) ?
REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
break;
case REMOTE_NDIS_RESET_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
RESET_Response->MessageLength = sizeof(RNDIS_Reset_Complete_t);
RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
RESET_Response->AddressingReset = 0;
break;
case REMOTE_NDIS_KEEPALIVE_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
(RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
(RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KeepAlive_Complete_t);
KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
break;
}
}
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
const uint32_t OId, void* const QueryData, const uint16_t QuerySize,
void* ResponseData, uint16_t* const ResponseSize)
{
(void)QueryData;
(void)QuerySize;
switch (OId)
{
case OID_GEN_SUPPORTED_LIST:
*ResponseSize = sizeof(AdapterSupportedOIDList);
memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
return true;
case OID_GEN_PHYSICAL_MEDIUM:
*ResponseSize = sizeof(uint32_t);
/* Indicate that the device is a true ethernet link */
*((uint32_t*)ResponseData) = 0;
return true;
case OID_GEN_HARDWARE_STATUS:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = NDIS_HardwareStatus_Ready;
return true;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
return true;
case OID_GEN_VENDOR_ID:
*ResponseSize = sizeof(uint32_t);
/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
*((uint32_t*)ResponseData) = 0x00FFFFFF;
return true;
case OID_GEN_MAXIMUM_FRAME_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
return true;
case OID_GEN_VENDOR_DESCRIPTION:
*ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
return true;
case OID_GEN_MEDIA_CONNECT_STATUS:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
return true;
case OID_GEN_LINK_SPEED:
*ResponseSize = sizeof(uint32_t);
/* Indicate 10Mb/s link speed */
*((uint32_t*)ResponseData) = 100000;
return true;
case OID_802_3_PERMANENT_ADDRESS:
case OID_802_3_CURRENT_ADDRESS:
*ResponseSize = sizeof(MAC_Address_t);
memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
return true;
case OID_802_3_MAXIMUM_LIST_SIZE:
*ResponseSize = sizeof(uint32_t);
/* Indicate only one multicast address supported */
*((uint32_t*)ResponseData) = 1;
return true;
case OID_GEN_CURRENT_PACKET_FILTER:
*ResponseSize = sizeof(uint32_t);
*((uint32_t*)ResponseData) = RNDISInterfaceInfo->State.CurrPacketFilter;
return true;
case OID_GEN_XMIT_OK:
case OID_GEN_RCV_OK:
case OID_GEN_XMIT_ERROR:
case OID_GEN_RCV_ERROR:
case OID_GEN_RCV_NO_BUFFER:
case OID_802_3_RCV_ERROR_ALIGNMENT:
case OID_802_3_XMIT_ONE_COLLISION:
case OID_802_3_XMIT_MORE_COLLISIONS:
*ResponseSize = sizeof(uint32_t);
/* Unused statistic OIDs - always return 0 for each */
*((uint32_t*)ResponseData) = 0;
return true;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
*ResponseSize = sizeof(uint32_t);
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
*((uint32_t*)ResponseData) = (RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
return true;
default:
return false;
}
}
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, const uint32_t OId,
void* SetData, const uint16_t SetSize)
{
(void)SetSize;
switch (OId)
{
case OID_GEN_CURRENT_PACKET_FILTER:
RNDISInterfaceInfo->State.CurrPacketFilter = *((uint32_t*)SetData);
RNDISInterfaceInfo->State.CurrRNDISState = ((RNDISInterfaceInfo->State.CurrPacketFilter) ?
RNDIS_Data_Initialized : RNDIS_Data_Initialized);
return true;
case OID_802_3_MULTICAST_LIST:
/* Do nothing - throw away the value from the host as it is unused */
return true;
default:
return false;
}
}
#endif

View file

@ -1,171 +1,171 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB RNDIS Class driver.
*
* Device mode driver for the library USB RNDIS Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/RNDIS.h.
*/
/** \ingroup Group_USBClassRNDIS
* @defgroup Group_USBClassRNDISDevice RNDIS Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/RNDIS.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the RNDIS USB Class driver.
*
* @{
*/
#ifndef _RNDIS_CLASS_DEVICE_H_
#define _RNDIS_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/RNDIS.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/RNDIS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief RNDIS Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each RNDIS interface
* within the user application, and passed to each of the RNDIS class driver functions as the
* RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
bool DataINEndpointDoubleBank; /** Indicates if the RNDIS interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
bool DataOUTEndpointDoubleBank; /** Indicates if the RNDIS interface's OUT data endpoint should use double banking */
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
bool NotificationEndpointDoubleBank; /** Indicates if the RNDIS interface's notification endpoint should use double banking */
char* AdapterVendorDescription; /**< String description of the adapter vendor */
MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host,
* managed by the class driver
*/
bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host */
uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the RNDIS_States_t enum */
uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver */
Ethernet_Frame_Info_t FrameIN; /**< Structure holding the last received Ethernet frame from the host, for user
* processing
*/
Ethernet_Frame_Info_t FrameOUT; /**< Structure holding the next Ethernet frame to send to the host, populated by the
* user application
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_RNDIS_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given HID interface is selected.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state
*/
void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given HID class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state
*/
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_RNDIS_CLASS_DEVICE_C)
static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
ATTR_NON_NULL_PTR_ARG(1);
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
const uint32_t OId, void* const QueryData, const uint16_t QuerySize,
void* ResponseData, uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6);
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, const uint32_t OId,
void* SetData, const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Device mode driver for the library USB RNDIS Class driver.
*
* Device mode driver for the library USB RNDIS Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/RNDIS.h.
*/
/** \ingroup Group_USBClassRNDIS
* @defgroup Group_USBClassRNDISDevice RNDIS Class Device Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/RNDIS.c
*
* \section Module Description
* Device Mode USB Class driver framework interface, for the RNDIS USB Class driver.
*
* @{
*/
#ifndef _RNDIS_CLASS_DEVICE_H_
#define _RNDIS_CLASS_DEVICE_H_
/* Includes: */
#include "../../USB.h"
#include "../Common/RNDIS.h"
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/RNDIS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief RNDIS Class Device Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made for each RNDIS interface
* within the user application, and passed to each of the RNDIS class driver functions as the
* RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
bool DataINEndpointDoubleBank; /** Indicates if the RNDIS interface's IN data endpoint should use double banking */
uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
bool DataOUTEndpointDoubleBank; /** Indicates if the RNDIS interface's OUT data endpoint should use double banking */
uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
bool NotificationEndpointDoubleBank; /** Indicates if the RNDIS interface's notification endpoint should use double banking */
char* AdapterVendorDescription; /**< String description of the adapter vendor */
MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host,
* managed by the class driver
*/
bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host */
uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the RNDIS_States_t enum */
uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver */
Ethernet_Frame_Info_t FrameIN; /**< Structure holding the last received Ethernet frame from the host, for user
* processing
*/
Ethernet_Frame_Info_t FrameOUT; /**< Structure holding the next Ethernet frame to send to the host, populated by the
* user application
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* are reset to their defaults when the interface is enumerated.
*/
} USB_ClassInfo_RNDIS_Device_t;
/* Function Prototypes: */
/** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
* containing the given HID interface is selected.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state
*
* \return Boolean true if the endpoints were successfully configured, false otherwise
*/
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be
* linked to the library \ref EVENT_USB_Device_UnhandledControlRequest() event.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state
*/
void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** General management task for a given HID class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state
*/
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_RNDIS_CLASS_DEVICE_C)
static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
ATTR_NON_NULL_PTR_ARG(1);
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
const uint32_t OId, void* const QueryData, const uint16_t QuerySize,
void* ResponseData, uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6);
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, const uint32_t OId,
void* SetData, const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,84 +1,84 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB HID Class driver.
*
* Master include file for the library USB HID Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassHID HID Class Driver - LUFA/Drivers/Class/HID.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/HID.c
* - LUFA/Drivers/USB/Class/Host/HID.c
* - LUFA/Drivers/USB/Class/Host/HIDParser.c
*
* \section Module Description
* HID Class Driver module. This module contains an internal implementation of the USB HID Class, for both Device
* and Host USB modes. User applications can use this class driver instead of implementing the HID class manually
* via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB HID Class.
*
* @{
*/
#ifndef _HID_CLASS_H_
#define _HID_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_HID_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/HID.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/HID.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB HID Class driver.
*
* Master include file for the library USB HID Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassHID HID Class Driver - LUFA/Drivers/Class/HID.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/HID.c
* - LUFA/Drivers/USB/Class/Host/HID.c
* - LUFA/Drivers/USB/Class/Host/HIDParser.c
*
* \section Module Description
* HID Class Driver module. This module contains an internal implementation of the USB HID Class, for both Device
* and Host USB modes. User applications can use this class driver instead of implementing the HID class manually
* via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB HID Class.
*
* @{
*/
#ifndef _HID_CLASS_H_
#define _HID_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_HID_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/HID.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/HID.h"
#endif
#endif
/** @} */

View file

@ -1,446 +1,446 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_CDC_CLASS_HOST_C
#define __INCLUDE_FROM_CDC_DRIVER
#include "CDC.h"
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return CDC_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
CDCInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber;
while (FoundEndpoints != (CDC_FOUND_NOTIFICATION_IN | CDC_FOUND_DATAPIPE_IN | CDC_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
if (FoundEndpoints & CDC_FOUND_NOTIFICATION_IN)
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
}
else
{
FoundEndpoints = 0;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
Pipe_DisablePipe();
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
}
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_EndpointsNotFound;
}
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.NotificationPipeSize = EndpointData->EndpointSize;
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
FoundEndpoints |= CDC_FOUND_NOTIFICATION_IN;
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= CDC_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= CDC_FOUND_DATAPIPE_OUT;
}
}
}
CDCInterfaceInfo->State.ControlLineStates.HostToDevice = (CDC_CONTROL_LINE_OUT_RTS | CDC_CONTROL_LINE_OUT_DTR);
CDCInterfaceInfo->State.ControlLineStates.DeviceToHost = (CDC_CONTROL_LINE_IN_DCD | CDC_CONTROL_LINE_IN_DSR);
CDCInterfaceInfo->State.IsActive = true;
return CDC_ENUMERROR_NoError;
}
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == CDC_CONTROL_CLASS) &&
(CurrentInterface->SubClass == CDC_CONTROL_SUBCLASS) &&
(CurrentInterface->Protocol == CDC_CONTROL_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == CDC_DATA_CLASS) &&
(CurrentInterface->SubClass == CDC_DATA_SUBCLASS) &&
(CurrentInterface->Protocol == CDC_DATA_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
{
return DESCRIPTOR_SEARCH_Found;
}
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return;
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
if (Pipe_IsINReceived())
{
USB_Request_Header_t Notification;
Pipe_Read_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
if ((Notification.bRequest == NOTIF_SerialState) &&
(Notification.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)))
{
Pipe_Read_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
NO_STREAM_CALLBACK);
}
Pipe_ClearIN();
EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo);
}
Pipe_Freeze();
}
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetLineEncoding,
.wValue = 0,
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
.wLength = sizeof(CDCInterfaceInfo->State.LineEncoding),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(&CDCInterfaceInfo->State.LineEncoding);
}
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetControlLineState,
.wValue = CDCInterfaceInfo->State.ControlLineStates.HostToDevice,
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL);
}
uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Duration)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SendBreak,
.wValue = Duration,
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL);
}
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, char* Data, const uint16_t Length)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
Pipe_Freeze();
return ErrorCode;
}
uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Data)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (!(Pipe_IsReadWriteAllowed()))
{
Pipe_ClearOUT();
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
return ErrorCode;
}
Pipe_Write_Byte(Data);
Pipe_Freeze();
return PIPE_READYWAIT_NoError;
}
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return 0;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
if (Pipe_IsINReceived())
{
if (!(Pipe_BytesInPipe()))
{
Pipe_ClearIN();
Pipe_Freeze();
return 0;
}
else
{
Pipe_Freeze();
return Pipe_BytesInPipe();
}
}
else
{
Pipe_Freeze();
return 0;
}
}
uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
uint8_t ReceivedByte = 0;
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return 0;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
ReceivedByte = Pipe_Read_Byte();
if (!(Pipe_BytesInPipe()))
Pipe_ClearIN();
Pipe_Freeze();
return ReceivedByte;
}
uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (!(Pipe_BytesInPipe()))
return PIPE_READYWAIT_NoError;
bool BankFull = !(Pipe_IsReadWriteAllowed());
Pipe_ClearOUT();
if (BankFull)
{
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
return ErrorCode;
Pipe_ClearOUT();
}
Pipe_Freeze();
return PIPE_READYWAIT_NoError;
}
void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Host_putchar(char c, FILE* Stream)
{
return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
}
static int CDC_Host_getchar(FILE* Stream)
{
if (!(CDC_Host_BytesReceived((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))))
return _FDEV_EOF;
return CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
}
static int CDC_Host_getchar_Blocking(FILE* Stream)
{
while (!(CDC_Host_BytesReceived((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))))
{
if (USB_HostState == HOST_STATE_Unattached)
return _FDEV_EOF;
CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
USB_USBTask();
}
return CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
}
void CDC_Host_Event_Stub(void)
{
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_CDC_CLASS_HOST_C
#define __INCLUDE_FROM_CDC_DRIVER
#include "CDC.h"
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return CDC_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
CDCInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber;
while (FoundEndpoints != (CDC_FOUND_NOTIFICATION_IN | CDC_FOUND_DATAPIPE_IN | CDC_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
if (FoundEndpoints & CDC_FOUND_NOTIFICATION_IN)
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
}
else
{
FoundEndpoints = 0;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
Pipe_DisablePipe();
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
}
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_EndpointsNotFound;
}
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.NotificationPipeSize = EndpointData->EndpointSize;
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
FoundEndpoints |= CDC_FOUND_NOTIFICATION_IN;
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= CDC_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= CDC_FOUND_DATAPIPE_OUT;
}
}
}
CDCInterfaceInfo->State.ControlLineStates.HostToDevice = (CDC_CONTROL_LINE_OUT_RTS | CDC_CONTROL_LINE_OUT_DTR);
CDCInterfaceInfo->State.ControlLineStates.DeviceToHost = (CDC_CONTROL_LINE_IN_DCD | CDC_CONTROL_LINE_IN_DSR);
CDCInterfaceInfo->State.IsActive = true;
return CDC_ENUMERROR_NoError;
}
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == CDC_CONTROL_CLASS) &&
(CurrentInterface->SubClass == CDC_CONTROL_SUBCLASS) &&
(CurrentInterface->Protocol == CDC_CONTROL_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == CDC_DATA_CLASS) &&
(CurrentInterface->SubClass == CDC_DATA_SUBCLASS) &&
(CurrentInterface->Protocol == CDC_DATA_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
{
return DESCRIPTOR_SEARCH_Found;
}
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return;
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
if (Pipe_IsINReceived())
{
USB_Request_Header_t Notification;
Pipe_Read_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
if ((Notification.bRequest == NOTIF_SerialState) &&
(Notification.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)))
{
Pipe_Read_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
NO_STREAM_CALLBACK);
}
Pipe_ClearIN();
EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo);
}
Pipe_Freeze();
}
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetLineEncoding,
.wValue = 0,
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
.wLength = sizeof(CDCInterfaceInfo->State.LineEncoding),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(&CDCInterfaceInfo->State.LineEncoding);
}
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetControlLineState,
.wValue = CDCInterfaceInfo->State.ControlLineStates.HostToDevice,
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL);
}
uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Duration)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SendBreak,
.wValue = Duration,
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL);
}
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, char* Data, const uint16_t Length)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
Pipe_Freeze();
return ErrorCode;
}
uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Data)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (!(Pipe_IsReadWriteAllowed()))
{
Pipe_ClearOUT();
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
return ErrorCode;
}
Pipe_Write_Byte(Data);
Pipe_Freeze();
return PIPE_READYWAIT_NoError;
}
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return 0;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
if (Pipe_IsINReceived())
{
if (!(Pipe_BytesInPipe()))
{
Pipe_ClearIN();
Pipe_Freeze();
return 0;
}
else
{
Pipe_Freeze();
return Pipe_BytesInPipe();
}
}
else
{
Pipe_Freeze();
return 0;
}
}
uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
uint8_t ReceivedByte = 0;
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return 0;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
ReceivedByte = Pipe_Read_Byte();
if (!(Pipe_BytesInPipe()))
Pipe_ClearIN();
Pipe_Freeze();
return ReceivedByte;
}
uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (!(Pipe_BytesInPipe()))
return PIPE_READYWAIT_NoError;
bool BankFull = !(Pipe_IsReadWriteAllowed());
Pipe_ClearOUT();
if (BankFull)
{
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
return ErrorCode;
Pipe_ClearOUT();
}
Pipe_Freeze();
return PIPE_READYWAIT_NoError;
}
void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Host_putchar(char c, FILE* Stream)
{
return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
}
static int CDC_Host_getchar(FILE* Stream)
{
if (!(CDC_Host_BytesReceived((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))))
return _FDEV_EOF;
return CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
}
static int CDC_Host_getchar_Blocking(FILE* Stream)
{
while (!(CDC_Host_BytesReceived((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))))
{
if (USB_HostState == HOST_STATE_Unattached)
return _FDEV_EOF;
CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
USB_USBTask();
}
return CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
}
void CDC_Host_Event_Stub(void)
{
}
#endif

View file

@ -1,336 +1,336 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB CDC Class driver.
*
* Host mode driver for the library USB CDC Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/CDC.h.
*/
/** \ingroup Group_USBClassCDC
* @defgroup Group_USBClassCDCHost CDC Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/CDC.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the CDC USB Class driver.
*
* @{
*/
#ifndef __CDC_CLASS_HOST_H__
#define __CDC_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/CDC.h"
#include <stdio.h>
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/CDC.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief CDC Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the CDC class driver functions as the CDCInterfaceInfo parameter. This
* stores each CDC interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the CDC interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the CDC interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the CDC interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the CDC interface's OUT data pipe should use double banking */
uint8_t NotificationPipeNumber; /**< Pipe number of the CDC interface's IN notification endpoint, if used */
bool NotificationPipeDoubleBank; /** Indicates if the CDC interface's notification pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref CDC_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the CDC interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe */
uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification pipe, if used */
struct
{
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
* masks - to notify the device of changes to these values, call the
* \ref CDC_Host_SendControlLineStateChange() function.
*/
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
* masks. This value is updated each time \ref CDC_Host_USBTask() is called.
*/
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
struct
{
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
* CDCDevice_CDC_LineCodingFormats_t enum
*/
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
* CDCDevice_LineCodingParity_t enum
*/
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
} LineEncoding; /** Line encoding used in the virtual serial port, for the device's information. This is generally
* only used if the virtual serial port data is to be reconstructed on a physical UART. When set
* by the host application, the \ref CDC_Host_SetLineEncoding() function must be called to push
* the changes to the device.
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_CDC_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref CDC_Host_ConfigurePipes() function. */
enum CDCHost_EnumerationFailure_ErrorCodes_t
{
CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
CDC_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
CDC_ENUMERROR_NoCDCInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor */
CDC_ENUMERROR_EndpointsNotFound = 3, /**< Compatible CDC endpoints were not found in the device's CDC interface */
};
/* Function Prototypes: */
/** General management task for a given CDC host class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state
*/
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Host interface configuration routine, to configure a given CDC host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given CDC Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the device.
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
* the Addressed state.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref CDCHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sets the line encoding for the attached device's virtual serial port. This should be called when the LineEncoding
* values of the interface have been changed to push the new settings to the USB device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a Serial Control Line State Change notification to the device. This should be called when the virtual serial
* control lines (DTR, RTS, etc.) have changed states. Line states persist until they are cleared via a second
* notification. This should be called each time the CDC class driver's ControlLineStates.HostToDevice value is updated
* to push the new states to the USB device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a Send Break request to the device. This is generally used to seperate data data or to indicate a special condition
* to the receiving device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
* \param[in] Duration Duration of the break, in milliseconds
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given string to the attached USB device, if connected. If a device is not connected when the function is called, the
* string is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the
* \ref CDC_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single pipe packet, increasing data throughput.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
* \param[in] Data Pointer to the string to send to the device
* \param[in] Length Size in bytes of the string to send to the device
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, char* Data, const uint16_t Length)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the
* byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the
* \ref CDC_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single pipe packet, increasing data throughput.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
* \param[in] Data Byte of data to send to the device
*
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
/** Determines the number of bytes received by the CDC interface from the device, waiting to be read.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return Total number of buffered bytes received from the device
*/
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function
* returns 0. The \ref CDC_Host_BytesReceived() function should be queried before data is received to ensure that no data
* underflow occurs.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return Next received byte from the device, or 0 if no data received
*/
uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Creates a standard characer stream for the given CDC Device instance so that it can be used with all the regular
* functions in the avr-libc <stdio.h> library that accept a FILE stream as a destination (e.g. fprintf). The created
* stream is bidirectional and can be used for both input and output functions.
*
* \note The created stream can be given as stdout if desired to direct the standard output from all <stdio.h> functions
* to the given CDC interface.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream);
/** Identical to CDC_Host_CreateStream(), except that reads are blocking until the calling stream function terminates
* the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream);
/** CDC class driver event for a control line state change on a CDC host interface. This event fires each time the device notifies
* the host of a control line state change (containing the virtual serial control line states, such as DCD) and may be hooked in the
* user program by declaring a handler function with the same name and parameters listed here. The new control line states
* are available in the ControlLineStates.DeviceToHost value inside the CDC host interface structure passed as a parameter, set as
* a mask of CDC_CONTROL_LINE_IN_* masks.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*/
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define CDC_CONTROL_CLASS 0x02
#define CDC_CONTROL_SUBCLASS 0x02
#define CDC_CONTROL_PROTOCOL 0x01
#define CDC_DATA_CLASS 0x0A
#define CDC_DATA_SUBCLASS 0x00
#define CDC_DATA_PROTOCOL 0x00
#define CDC_FOUND_DATAPIPE_IN (1 << 0)
#define CDC_FOUND_DATAPIPE_OUT (1 << 1)
#define CDC_FOUND_NOTIFICATION_IN (1 << 2)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_CDC_CLASS_HOST_C)
static int CDC_Host_putchar(char c, FILE* Stream);
static int CDC_Host_getchar(FILE* Stream);
static int CDC_Host_getchar_Blocking(FILE* Stream);
void CDC_Host_Event_Stub(void);
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Host_Event_Stub);
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB CDC Class driver.
*
* Host mode driver for the library USB CDC Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/CDC.h.
*/
/** \ingroup Group_USBClassCDC
* @defgroup Group_USBClassCDCHost CDC Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/CDC.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the CDC USB Class driver.
*
* @{
*/
#ifndef __CDC_CLASS_HOST_H__
#define __CDC_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/CDC.h"
#include <stdio.h>
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/CDC.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief CDC Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the CDC class driver functions as the CDCInterfaceInfo parameter. This
* stores each CDC interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the CDC interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the CDC interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the CDC interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the CDC interface's OUT data pipe should use double banking */
uint8_t NotificationPipeNumber; /**< Pipe number of the CDC interface's IN notification endpoint, if used */
bool NotificationPipeDoubleBank; /** Indicates if the CDC interface's notification pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref CDC_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the CDC interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe */
uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification pipe, if used */
struct
{
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
* masks - to notify the device of changes to these values, call the
* \ref CDC_Host_SendControlLineStateChange() function.
*/
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
* masks. This value is updated each time \ref CDC_Host_USBTask() is called.
*/
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
struct
{
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
* CDCDevice_CDC_LineCodingFormats_t enum
*/
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
* CDCDevice_LineCodingParity_t enum
*/
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
} LineEncoding; /** Line encoding used in the virtual serial port, for the device's information. This is generally
* only used if the virtual serial port data is to be reconstructed on a physical UART. When set
* by the host application, the \ref CDC_Host_SetLineEncoding() function must be called to push
* the changes to the device.
*/
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_CDC_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref CDC_Host_ConfigurePipes() function. */
enum CDCHost_EnumerationFailure_ErrorCodes_t
{
CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
CDC_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
CDC_ENUMERROR_NoCDCInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor */
CDC_ENUMERROR_EndpointsNotFound = 3, /**< Compatible CDC endpoints were not found in the device's CDC interface */
};
/* Function Prototypes: */
/** General management task for a given CDC host class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state
*/
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Host interface configuration routine, to configure a given CDC host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given CDC Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the device.
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
* the Addressed state.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref CDCHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sets the line encoding for the attached device's virtual serial port. This should be called when the LineEncoding
* values of the interface have been changed to push the new settings to the USB device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a Serial Control Line State Change notification to the device. This should be called when the virtual serial
* control lines (DTR, RTS, etc.) have changed states. Line states persist until they are cleared via a second
* notification. This should be called each time the CDC class driver's ControlLineStates.HostToDevice value is updated
* to push the new states to the USB device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a Send Break request to the device. This is generally used to seperate data data or to indicate a special condition
* to the receiving device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
* \param[in] Duration Duration of the break, in milliseconds
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given string to the attached USB device, if connected. If a device is not connected when the function is called, the
* string is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the
* \ref CDC_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single pipe packet, increasing data throughput.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
* \param[in] Data Pointer to the string to send to the device
* \param[in] Length Size in bytes of the string to send to the device
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, char* Data, const uint16_t Length)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the
* byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the
* \ref CDC_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
* packed into a single pipe packet, increasing data throughput.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
* \param[in] Data Byte of data to send to the device
*
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
/** Determines the number of bytes received by the CDC interface from the device, waiting to be read.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return Total number of buffered bytes received from the device
*/
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function
* returns 0. The \ref CDC_Host_BytesReceived() function should be queried before data is received to ensure that no data
* underflow occurs.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return Next received byte from the device, or 0 if no data received
*/
uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Creates a standard characer stream for the given CDC Device instance so that it can be used with all the regular
* functions in the avr-libc <stdio.h> library that accept a FILE stream as a destination (e.g. fprintf). The created
* stream is bidirectional and can be used for both input and output functions.
*
* \note The created stream can be given as stdout if desired to direct the standard output from all <stdio.h> functions
* to the given CDC interface.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream);
/** Identical to CDC_Host_CreateStream(), except that reads are blocking until the calling stream function terminates
* the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed
*/
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream);
/** CDC class driver event for a control line state change on a CDC host interface. This event fires each time the device notifies
* the host of a control line state change (containing the virtual serial control line states, such as DCD) and may be hooked in the
* user program by declaring a handler function with the same name and parameters listed here. The new control line states
* are available in the ControlLineStates.DeviceToHost value inside the CDC host interface structure passed as a parameter, set as
* a mask of CDC_CONTROL_LINE_IN_* masks.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
*/
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define CDC_CONTROL_CLASS 0x02
#define CDC_CONTROL_SUBCLASS 0x02
#define CDC_CONTROL_PROTOCOL 0x01
#define CDC_DATA_CLASS 0x0A
#define CDC_DATA_SUBCLASS 0x00
#define CDC_DATA_PROTOCOL 0x00
#define CDC_FOUND_DATAPIPE_IN (1 << 0)
#define CDC_FOUND_DATAPIPE_OUT (1 << 1)
#define CDC_FOUND_NOTIFICATION_IN (1 << 2)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_CDC_CLASS_HOST_C)
static int CDC_Host_putchar(char c, FILE* Stream);
static int CDC_Host_getchar(FILE* Stream);
static int CDC_Host_getchar_Blocking(FILE* Stream);
void CDC_Host_Event_Stub(void);
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Host_Event_Stub);
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,362 +1,362 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_HID_CLASS_HOST_C
#define __INCLUDE_FROM_HID_DRIVER
#include "HID.h"
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return HID_ENUMERROR_InvalidConfigDescriptor;
USB_Descriptor_Interface_t* CurrentHIDInterface;
do
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return HID_ENUMERROR_NoHIDInterfaceFound;
}
CurrentHIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
} while (HIDInterfaceInfo->Config.HIDInterfaceProtocol &&
(CurrentHIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol));
HIDInterfaceInfo->State.InterfaceNumber = CurrentHIDInterface->InterfaceNumber;
HIDInterfaceInfo->State.SupportsBootProtocol = (CurrentHIDInterface->SubClass != HID_NON_BOOT_PROTOCOL);
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
{
return HID_ENUMERROR_NoHIDDescriptorFound;
}
HIDInterfaceInfo->State.HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_HID_Descriptor_t).HIDReportLength;
while (FoundEndpoints != (HID_FOUND_DATAPIPE_IN | HID_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
if (FoundEndpoints & HID_FOUND_DATAPIPE_IN)
break;
return HID_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
HIDInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
HIDInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= HID_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
HIDInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
HIDInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
HIDInterfaceInfo->State.DeviceUsesOUTPipe = true;
FoundEndpoints |= HID_FOUND_DATAPIPE_OUT;
}
}
HIDInterfaceInfo->State.LargestReportSize = 8;
HIDInterfaceInfo->State.IsActive = true;
return HID_ENUMERROR_NoError;
}
static uint8_t DComp_HID_Host_NextHIDInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if (CurrentInterface->Class == HID_INTERFACE_CLASS)
return DESCRIPTOR_SEARCH_Found;
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_NextHID(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_HID)
return DESCRIPTOR_SEARCH_Found;
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
return DESCRIPTOR_SEARCH_Fail;
else
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
if (!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, const uint8_t ReportID, void* Buffer)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetReport,
.wValue = ((REPORT_ITEM_TYPE_In + 1) << 8) | ReportID,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, REPORT_ITEM_TYPE_In),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
#endif
uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, void* Buffer)
{
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
uint16_t ReportSize;
uint8_t* BufferPos = Buffer;
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
if (!(HIDInterfaceInfo->State.UsingBootProtocol))
{
uint8_t ReportID = 0;
if (HIDInterfaceInfo->Config.HIDParserData->UsingReportIDs)
{
ReportID = Pipe_Read_Byte();
*(BufferPos++) = ReportID;
}
ReportSize = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, REPORT_ITEM_TYPE_In);
}
else
#endif
{
ReportSize = Pipe_BytesInPipe();
}
if ((ErrorCode = Pipe_Read_Stream_LE(BufferPos, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearIN();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
const uint8_t ReportID,
#endif
void* Buffer, const uint16_t ReportSize)
{
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
return false;
if (HIDInterfaceInfo->State.DeviceUsesOUTPipe)
{
uint8_t ErrorCode;
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (ReportID)
Pipe_Write_Stream_LE(&ReportID, sizeof(ReportID), NO_STREAM_CALLBACK);
if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearOUT();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
else
#endif
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetReport,
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
.wValue = ((REPORT_ITEM_TYPE_Out + 1) << 8) | ReportID,
#else
.wValue = ((REPORT_ITEM_TYPE_Out + 1) << 8),
#endif
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = ReportSize,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
}
bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
return false;
bool ReportReceived;
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
ReportReceived = Pipe_IsINReceived();
Pipe_Freeze();
return ReportReceived;
}
uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
uint8_t ErrorCode;
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol,
.wValue = 0,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if (!(HIDInterfaceInfo->State.SupportsBootProtocol))
return HID_ERROR_LOGICAL;
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
HIDInterfaceInfo->State.LargestReportSize = 8;
HIDInterfaceInfo->State.UsingBootProtocol = true;
return HOST_SENDCONTROL_Successful;
}
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
uint8_t ErrorCode;
uint8_t HIDReportData[HIDInterfaceInfo->State.HIDReportSize];
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE),
.bRequest = REQ_GetDescriptor,
.wValue = (DTYPE_Report << 8),
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = HIDInterfaceInfo->State.HIDReportSize,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
if (HIDInterfaceInfo->State.UsingBootProtocol)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol,
.wValue = 1,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
HIDInterfaceInfo->State.UsingBootProtocol = false;
}
if (HIDInterfaceInfo->Config.HIDParserData == NULL)
return HID_ERROR_LOGICAL;
if ((ErrorCode = USB_ProcessHIDReport(HIDReportData, HIDInterfaceInfo->State.HIDReportSize,
HIDInterfaceInfo->Config.HIDParserData)) != HID_PARSE_Successful)
{
return HID_ERROR_LOGICAL | ErrorCode;
}
uint8_t LargestReportSizeBits = HIDInterfaceInfo->Config.HIDParserData->LargestReportSizeBits;
HIDInterfaceInfo->State.LargestReportSize = (LargestReportSizeBits >> 3) + ((LargestReportSizeBits & 0x07) != 0);
return 0;
}
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_HID_CLASS_HOST_C
#define __INCLUDE_FROM_HID_DRIVER
#include "HID.h"
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return HID_ENUMERROR_InvalidConfigDescriptor;
USB_Descriptor_Interface_t* CurrentHIDInterface;
do
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return HID_ENUMERROR_NoHIDInterfaceFound;
}
CurrentHIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
} while (HIDInterfaceInfo->Config.HIDInterfaceProtocol &&
(CurrentHIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol));
HIDInterfaceInfo->State.InterfaceNumber = CurrentHIDInterface->InterfaceNumber;
HIDInterfaceInfo->State.SupportsBootProtocol = (CurrentHIDInterface->SubClass != HID_NON_BOOT_PROTOCOL);
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
{
return HID_ENUMERROR_NoHIDDescriptorFound;
}
HIDInterfaceInfo->State.HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_HID_Descriptor_t).HIDReportLength;
while (FoundEndpoints != (HID_FOUND_DATAPIPE_IN | HID_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
if (FoundEndpoints & HID_FOUND_DATAPIPE_IN)
break;
return HID_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
HIDInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
HIDInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= HID_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
HIDInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
HIDInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
HIDInterfaceInfo->State.DeviceUsesOUTPipe = true;
FoundEndpoints |= HID_FOUND_DATAPIPE_OUT;
}
}
HIDInterfaceInfo->State.LargestReportSize = 8;
HIDInterfaceInfo->State.IsActive = true;
return HID_ENUMERROR_NoError;
}
static uint8_t DComp_HID_Host_NextHIDInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if (CurrentInterface->Class == HID_INTERFACE_CLASS)
return DESCRIPTOR_SEARCH_Found;
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_NextHID(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_HID)
return DESCRIPTOR_SEARCH_Found;
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
return DESCRIPTOR_SEARCH_Fail;
else
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
if (!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, const uint8_t ReportID, void* Buffer)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetReport,
.wValue = ((REPORT_ITEM_TYPE_In + 1) << 8) | ReportID,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, REPORT_ITEM_TYPE_In),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
#endif
uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, void* Buffer)
{
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
uint16_t ReportSize;
uint8_t* BufferPos = Buffer;
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
if (!(HIDInterfaceInfo->State.UsingBootProtocol))
{
uint8_t ReportID = 0;
if (HIDInterfaceInfo->Config.HIDParserData->UsingReportIDs)
{
ReportID = Pipe_Read_Byte();
*(BufferPos++) = ReportID;
}
ReportSize = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, REPORT_ITEM_TYPE_In);
}
else
#endif
{
ReportSize = Pipe_BytesInPipe();
}
if ((ErrorCode = Pipe_Read_Stream_LE(BufferPos, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearIN();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
const uint8_t ReportID,
#endif
void* Buffer, const uint16_t ReportSize)
{
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
return false;
if (HIDInterfaceInfo->State.DeviceUsesOUTPipe)
{
uint8_t ErrorCode;
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (ReportID)
Pipe_Write_Stream_LE(&ReportID, sizeof(ReportID), NO_STREAM_CALLBACK);
if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearOUT();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
else
#endif
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetReport,
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
.wValue = ((REPORT_ITEM_TYPE_Out + 1) << 8) | ReportID,
#else
.wValue = ((REPORT_ITEM_TYPE_Out + 1) << 8),
#endif
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = ReportSize,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
}
bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
return false;
bool ReportReceived;
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
ReportReceived = Pipe_IsINReceived();
Pipe_Freeze();
return ReportReceived;
}
uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
uint8_t ErrorCode;
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol,
.wValue = 0,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if (!(HIDInterfaceInfo->State.SupportsBootProtocol))
return HID_ERROR_LOGICAL;
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
HIDInterfaceInfo->State.LargestReportSize = 8;
HIDInterfaceInfo->State.UsingBootProtocol = true;
return HOST_SENDCONTROL_Successful;
}
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
uint8_t ErrorCode;
uint8_t HIDReportData[HIDInterfaceInfo->State.HIDReportSize];
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE),
.bRequest = REQ_GetDescriptor,
.wValue = (DTYPE_Report << 8),
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = HIDInterfaceInfo->State.HIDReportSize,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
if (HIDInterfaceInfo->State.UsingBootProtocol)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol,
.wValue = 1,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
HIDInterfaceInfo->State.UsingBootProtocol = false;
}
if (HIDInterfaceInfo->Config.HIDParserData == NULL)
return HID_ERROR_LOGICAL;
if ((ErrorCode = USB_ProcessHIDReport(HIDReportData, HIDInterfaceInfo->State.HIDReportSize,
HIDInterfaceInfo->Config.HIDParserData)) != HID_PARSE_Successful)
{
return HID_ERROR_LOGICAL | ErrorCode;
}
uint8_t LargestReportSizeBits = HIDInterfaceInfo->Config.HIDParserData->LargestReportSizeBits;
HIDInterfaceInfo->State.LargestReportSize = (LargestReportSizeBits >> 3) + ((LargestReportSizeBits & 0x07) != 0);
return 0;
}
#endif
#endif

View file

@ -1,312 +1,312 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB HID Class driver.
*
* Host mode driver for the library USB HID Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/HID.h.
*/
/** \ingroup Group_USBClassHID
* @defgroup Group_USBClassHIDHost HID Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/HID.c
* - LUFA/Drivers/USB/Class/Host/HIDParser.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the HID USB Class driver.
*
* @{
*/
#ifndef __HID_CLASS_HOST_H__
#define __HID_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/HID.h"
#include "HIDParser.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_HID_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/HID.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some HID Host functions, indicating a logical (and not hardware) error */
#define HID_ERROR_LOGICAL 0x80
/* Type Defines: */
/** \brief HID Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the HID class driver functions as the HIDInterfaceInfo parameter. This
* stores each HID interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the HID interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the HID interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the HID interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the HID interface's OUT data pipe should use double banking */
uint8_t HIDInterfaceProtocol; /**< HID interface protocol value to match against if a specific
* boot subclass protocol is required, either \ref HID_BOOT_MOUSE_PROTOCOL,
* \ref HID_BOOT_KEYBOARD_PROTOCOL or \ref HID_NON_BOOT_PROTOCOL if any
* HID device should be enumerated by the interface
*/
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
HID_ReportInfo_t* HIDParserData; /**< HID parser data to store the parsed HID report data, when boot protocol
* is not used
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined,
* this method is unavailable.
*/
#endif
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t InterfaceNumber; /**< Interface index of the HID interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the HID interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the HID interface's OUT data pipe */
bool SupportsBootProtocol; /**< Indicates if the current interface instance supports the HID Boot
* Protocol when enabled via \ref HID_Host_SetBootProtocol()
*/
bool DeviceUsesOUTPipe; /**< Indicates if the current interface instance uses a separate OUT data pipe for
* OUT reports, or if OUT reports are sent via the control pipe instead.
*/
bool UsingBootProtocol; /**< Indicates that the interface is currently initialized in Boot Protocol mode */
uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device */
uint8_t LargestReportSize; /**< Largest report the device will send, in bytes */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_HID_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */
enum HIDHost_EnumerationFailure_ErrorCodes_t
{
HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
HID_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
HID_ENUMERROR_NoHIDInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor */
HID_ENUMERROR_NoHIDDescriptorFound = 3, /**< The HID descriptor was not found in the device's HID interface */
HID_ENUMERROR_EndpointsNotFound = 4, /**< Compatible HID endpoints were not found in the device's HID interface */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given HID host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given HID Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the
* device. This should be called once after the stack has enumerated the attached device, while the host state
* machine is in the Addressed state.
*
* \note Once the device pipes are configured, the HID device's reporting protocol <b>must</b> be set via a call
* to either the \ref HID_Host_SetBootProtocol() or \ref HID_Host_SetReportProtocol() function.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref HIDHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Receives a HID IN report from the attached HID device, when a report has been received on the HID IN Data pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
* \n\n
*
* \note The destination buffer should be large enough to accommodate the largest report that the attached device
* can generate.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] Buffer Buffer to store the received report into
*
* \return An error code from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, void* Buffer)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
/** Receives a HID IN report from the attached device, by the report ID.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
* \n\n
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] ReportID Report ID of the received report if ControlRequest is false, set by the to the Report ID to fetch
* \param[in] Buffer Buffer to store the received report into
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, const uint8_t ReportID,
void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
#endif
/** Sends an OUT report to the currently attached HID device, using the device's OUT pipe if available or the device's
* Control pipe if not.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
* \n\n
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, the ReportID parameter is removed
* from the parameter list of this function.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] ReportID Report ID of the report to send to the device, or 0 if the device does not use report IDs
* \param[in] Buffer Buffer containing the report to send to the attached device
* \param[in] ReportSize Report size in bytes to send to the attached device
*
* \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the DeviceUsesOUTPipe flag is set in
* the interface's state structure, a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise
*/
uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
const uint8_t ReportID,
#endif
void* Buffer, const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1)
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
ATTR_NON_NULL_PTR_ARG(3);
#else
ATTR_NON_NULL_PTR_ARG(2);
#endif
/** Determines if a HID IN report has been received from the attached device on the data IN pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*
* \return Boolean true if a report has been received, false otherwise
*/
bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices.
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method must still be called
* to explicitly place the attached device into boot protocol mode before use.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*
* \return \ref HID_ERROR_LOGICAL if the device does not support Boot Protocol mode, a value from the
* \ref USB_Host_SendControlErrorCodes_t enum otherwise
*/
uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
/** Switches the attached HID device's reporting protocol over to the standard Report protocol mode. This also retrieves
* and parses the device's HID report descriptor, so that the size of each report can be determined in advance.
*
* \note Whether this function is used or not, the \ref CALLBACK_HIDParser_FilterHIDReportItem() callback from the HID
* Report Parser this function references <b>must</b> be implemented in the user code.
* \n\n
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum if an error occurs while retrieving the HID
* Report descriptor or the setting of the Report protocol, \ref HID_ERROR_LOGICAL if the HID interface does
* not have a valid \ref HID_ReportInfo_t structure set in its configuration, a mask of \ref HID_ERROR_LOGICAL
* and a value from the \ref HID_Parse_ErrorCodes_t otherwise
*/
uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
#endif
/* Inline Functions: */
/** General management task for a given Human Interface Class host class interface, required for the correct operation of
* the interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*/
static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo);
static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
(void)HIDInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define HID_INTERFACE_CLASS 0x03
#define HID_FOUND_DATAPIPE_IN (1 << 0)
#define HID_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_HID_CLASS_HOST_C)
static uint8_t DComp_HID_Host_NextHIDInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_NextHID(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB HID Class driver.
*
* Host mode driver for the library USB HID Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/HID.h.
*/
/** \ingroup Group_USBClassHID
* @defgroup Group_USBClassHIDHost HID Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/HID.c
* - LUFA/Drivers/USB/Class/Host/HIDParser.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the HID USB Class driver.
*
* @{
*/
#ifndef __HID_CLASS_HOST_H__
#define __HID_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/HID.h"
#include "HIDParser.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_HID_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/HID.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some HID Host functions, indicating a logical (and not hardware) error */
#define HID_ERROR_LOGICAL 0x80
/* Type Defines: */
/** \brief HID Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the HID class driver functions as the HIDInterfaceInfo parameter. This
* stores each HID interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the HID interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the HID interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the HID interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the HID interface's OUT data pipe should use double banking */
uint8_t HIDInterfaceProtocol; /**< HID interface protocol value to match against if a specific
* boot subclass protocol is required, either \ref HID_BOOT_MOUSE_PROTOCOL,
* \ref HID_BOOT_KEYBOARD_PROTOCOL or \ref HID_NON_BOOT_PROTOCOL if any
* HID device should be enumerated by the interface
*/
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
HID_ReportInfo_t* HIDParserData; /**< HID parser data to store the parsed HID report data, when boot protocol
* is not used
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined,
* this method is unavailable.
*/
#endif
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t InterfaceNumber; /**< Interface index of the HID interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the HID interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the HID interface's OUT data pipe */
bool SupportsBootProtocol; /**< Indicates if the current interface instance supports the HID Boot
* Protocol when enabled via \ref HID_Host_SetBootProtocol()
*/
bool DeviceUsesOUTPipe; /**< Indicates if the current interface instance uses a separate OUT data pipe for
* OUT reports, or if OUT reports are sent via the control pipe instead.
*/
bool UsingBootProtocol; /**< Indicates that the interface is currently initialized in Boot Protocol mode */
uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device */
uint8_t LargestReportSize; /**< Largest report the device will send, in bytes */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_HID_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */
enum HIDHost_EnumerationFailure_ErrorCodes_t
{
HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
HID_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
HID_ENUMERROR_NoHIDInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor */
HID_ENUMERROR_NoHIDDescriptorFound = 3, /**< The HID descriptor was not found in the device's HID interface */
HID_ENUMERROR_EndpointsNotFound = 4, /**< Compatible HID endpoints were not found in the device's HID interface */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given HID host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given HID Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the
* device. This should be called once after the stack has enumerated the attached device, while the host state
* machine is in the Addressed state.
*
* \note Once the device pipes are configured, the HID device's reporting protocol <b>must</b> be set via a call
* to either the \ref HID_Host_SetBootProtocol() or \ref HID_Host_SetReportProtocol() function.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref HIDHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Receives a HID IN report from the attached HID device, when a report has been received on the HID IN Data pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
* \n\n
*
* \note The destination buffer should be large enough to accommodate the largest report that the attached device
* can generate.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] Buffer Buffer to store the received report into
*
* \return An error code from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, void* Buffer)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
/** Receives a HID IN report from the attached device, by the report ID.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
* \n\n
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] ReportID Report ID of the received report if ControlRequest is false, set by the to the Report ID to fetch
* \param[in] Buffer Buffer to store the received report into
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, const uint8_t ReportID,
void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
#endif
/** Sends an OUT report to the currently attached HID device, using the device's OUT pipe if available or the device's
* Control pipe if not.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
* \n\n
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, the ReportID parameter is removed
* from the parameter list of this function.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
* \param[in] ReportID Report ID of the report to send to the device, or 0 if the device does not use report IDs
* \param[in] Buffer Buffer containing the report to send to the attached device
* \param[in] ReportSize Report size in bytes to send to the attached device
*
* \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the DeviceUsesOUTPipe flag is set in
* the interface's state structure, a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise
*/
uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
const uint8_t ReportID,
#endif
void* Buffer, const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1)
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
ATTR_NON_NULL_PTR_ARG(3);
#else
ATTR_NON_NULL_PTR_ARG(2);
#endif
/** Determines if a HID IN report has been received from the attached device on the data IN pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*
* \return Boolean true if a report has been received, false otherwise
*/
bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices.
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method must still be called
* to explicitly place the attached device into boot protocol mode before use.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*
* \return \ref HID_ERROR_LOGICAL if the device does not support Boot Protocol mode, a value from the
* \ref USB_Host_SendControlErrorCodes_t enum otherwise
*/
uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
/** Switches the attached HID device's reporting protocol over to the standard Report protocol mode. This also retrieves
* and parses the device's HID report descriptor, so that the size of each report can be determined in advance.
*
* \note Whether this function is used or not, the \ref CALLBACK_HIDParser_FilterHIDReportItem() callback from the HID
* Report Parser this function references <b>must</b> be implemented in the user code.
* \n\n
*
* \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum if an error occurs while retrieving the HID
* Report descriptor or the setting of the Report protocol, \ref HID_ERROR_LOGICAL if the HID interface does
* not have a valid \ref HID_ReportInfo_t structure set in its configuration, a mask of \ref HID_ERROR_LOGICAL
* and a value from the \ref HID_Parse_ErrorCodes_t otherwise
*/
uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
#endif
/* Inline Functions: */
/** General management task for a given Human Interface Class host class interface, required for the correct operation of
* the interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
*/
static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo);
static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
{
(void)HIDInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define HID_INTERFACE_CLASS 0x03
#define HID_FOUND_DATAPIPE_IN (1 << 0)
#define HID_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_HID_CLASS_HOST_C)
static uint8_t DComp_HID_Host_NextHIDInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_NextHID(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,353 +1,353 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#include "HIDParser.h"
uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)
{
HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH];
HID_StateTable_t* CurrStateTable = &StateTable[0];
HID_CollectionPath_t* CurrCollectionPath = NULL;
HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0];
uint16_t UsageList[HID_USAGE_STACK_DEPTH];
uint8_t UsageListSize = 0;
HID_MinMax_t UsageMinMax = {0, 0};
memset(ParserData, 0x00, sizeof(HID_ReportInfo_t));
memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));
memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
ParserData->TotalDeviceReports = 1;
while (ReportSize)
{
uint8_t HIDReportItem = *ReportData;
uint32_t ReportItemData = 0;
ReportData++;
ReportSize--;
switch (HIDReportItem & DATA_SIZE_MASK)
{
case DATA_SIZE_4:
ReportItemData = *((uint32_t*)ReportData);
ReportSize -= 4;
ReportData += 4;
break;
case DATA_SIZE_2:
ReportItemData = *((uint16_t*)ReportData);
ReportSize -= 2;
ReportData += 2;
break;
case DATA_SIZE_1:
ReportItemData = *((uint8_t*)ReportData);
ReportSize -= 1;
ReportData += 1;
break;
}
switch (HIDReportItem & (TYPE_MASK | TAG_MASK))
{
case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH - 1])
return HID_PARSE_HIDStackOverflow;
memcpy((CurrStateTable + 1),
CurrStateTable,
sizeof(HID_ReportItem_t));
CurrStateTable++;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_POP):
if (CurrStateTable == &StateTable[0])
return HID_PARSE_HIDStackUnderflow;
CurrStateTable--;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE):
CurrStateTable->Attributes.Usage.Page = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMIN):
CurrStateTable->Attributes.Logical.Minimum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMAX):
CurrStateTable->Attributes.Logical.Maximum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMIN):
CurrStateTable->Attributes.Physical.Minimum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMAX):
CurrStateTable->Attributes.Physical.Maximum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_UNITEXP):
CurrStateTable->Attributes.Unit.Exponent = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_UNIT):
CurrStateTable->Attributes.Unit.Type = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE):
CurrStateTable->Attributes.BitSize = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT):
CurrStateTable->ReportCount = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):
CurrStateTable->ReportID = ReportItemData;
if (ParserData->UsingReportIDs)
{
CurrReportIDInfo = NULL;
for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++)
{
if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID)
{
CurrReportIDInfo = &ParserData->ReportIDSizes[i];
break;
}
}
if (CurrReportIDInfo == NULL)
{
if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS)
return HID_PARSE_InsufficientReportIDItems;
CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++];
memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
}
}
ParserData->UsingReportIDs = true;
CurrReportIDInfo->ReportID = CurrStateTable->ReportID;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
if (UsageListSize == HID_USAGE_STACK_DEPTH)
return HID_PARSE_UsageListOverflow;
UsageList[UsageListSize++] = ReportItemData;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
UsageMinMax.Minimum = ReportItemData;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):
UsageMinMax.Maximum = ReportItemData;
break;
case (TYPE_MAIN | TAG_MAIN_COLLECTION):
if (CurrCollectionPath == NULL)
{
CurrCollectionPath = &ParserData->CollectionPaths[0];
}
else
{
HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath;
CurrCollectionPath = &ParserData->CollectionPaths[1];
while (CurrCollectionPath->Parent != NULL)
{
if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1])
return HID_PARSE_InsufficientCollectionPaths;
CurrCollectionPath++;
}
CurrCollectionPath->Parent = ParentCollectionPath;
}
CurrCollectionPath->Type = ReportItemData;
CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page;
if (UsageListSize)
{
CurrCollectionPath->Usage.Usage = UsageList[0];
for (uint8_t i = 0; i < UsageListSize; i++)
UsageList[i] = UsageList[i + 1];
UsageListSize--;
}
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
{
CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++;
}
break;
case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
if (CurrCollectionPath == NULL)
return HID_PARSE_UnexpectedEndCollection;
CurrCollectionPath = CurrCollectionPath->Parent;
break;
case (TYPE_MAIN | TAG_MAIN_INPUT):
case (TYPE_MAIN | TAG_MAIN_OUTPUT):
case (TYPE_MAIN | TAG_MAIN_FEATURE):
for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++)
{
HID_ReportItem_t NewReportItem;
memcpy(&NewReportItem.Attributes,
&CurrStateTable->Attributes,
sizeof(HID_ReportItem_Attributes_t));
NewReportItem.ItemFlags = ReportItemData;
NewReportItem.CollectionPath = CurrCollectionPath;
NewReportItem.ReportID = CurrStateTable->ReportID;
if (UsageListSize)
{
NewReportItem.Attributes.Usage.Usage = UsageList[0];
for (uint8_t i = 0; i < UsageListSize; i++)
UsageList[i] = UsageList[i + 1];
UsageListSize--;
}
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
{
NewReportItem.Attributes.Usage.Usage = UsageMinMax.Minimum++;
}
uint8_t ItemTag = (HIDReportItem & TAG_MASK);
if (ItemTag == TAG_MAIN_INPUT)
NewReportItem.ItemType = REPORT_ITEM_TYPE_In;
else if (ItemTag == TAG_MAIN_OUTPUT)
NewReportItem.ItemType = REPORT_ITEM_TYPE_Out;
else
NewReportItem.ItemType = REPORT_ITEM_TYPE_Feature;
NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType];
CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize;
if (ParserData->LargestReportSizeBits < NewReportItem.BitOffset)
ParserData->LargestReportSizeBits = NewReportItem.BitOffset;
if (!(ReportItemData & IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem))
{
if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS)
return HID_PARSE_InsufficientReportItems;
memcpy(&ParserData->ReportItems[ParserData->TotalReportItems],
&NewReportItem, sizeof(HID_ReportItem_t));
ParserData->TotalReportItems++;
}
}
break;
}
if ((HIDReportItem & TYPE_MASK) == TYPE_MAIN)
{
UsageMinMax.Minimum = 0;
UsageMinMax.Maximum = 0;
UsageListSize = 0;
}
}
if (!(ParserData->TotalReportItems))
return HID_PARSE_NoUnfilteredReportItems;
return HID_PARSE_Successful;
}
bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
{
uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
uint16_t CurrentBit = ReportItem->BitOffset;
uint32_t BitMask = (1 << 0);
ReportItem->PreviousValue = ReportItem->Value;
ReportItem->Value = 0;
if (ReportItem->ReportID)
{
if (ReportItem->ReportID != ReportData[0])
return false;
ReportData++;
}
while (DataBitsRem--)
{
if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8)))
ReportItem->Value |= BitMask;
CurrentBit++;
BitMask <<= 1;
}
return true;
}
void USB_SetHIDReportItemInfo(uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
{
uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
uint16_t CurrentBit = ReportItem->BitOffset;
uint32_t BitMask = (1 << 0);
if (ReportItem->ReportID)
{
ReportData[0] = ReportItem->ReportID;
ReportData++;
}
ReportItem->PreviousValue = ReportItem->Value;
while (DataBitsRem--)
{
if (ReportItem->Value & (1 << (CurrentBit % 8)))
ReportData[CurrentBit / 8] |= BitMask;
CurrentBit++;
BitMask <<= 1;
}
}
uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, const uint8_t ReportID, const uint8_t ReportType)
{
for (uint8_t i = 0; i < HID_MAX_REPORT_IDS; i++)
{
uint16_t ReportSizeBits = ParserData->ReportIDSizes[i].ReportSizeBits[ReportType];
if (ParserData->ReportIDSizes[i].ReportID == ReportID)
return ((ReportSizeBits >> 3) + ((ReportSizeBits & 0x07) ? 1 : 0));
}
return 0;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#include "HIDParser.h"
uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)
{
HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH];
HID_StateTable_t* CurrStateTable = &StateTable[0];
HID_CollectionPath_t* CurrCollectionPath = NULL;
HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0];
uint16_t UsageList[HID_USAGE_STACK_DEPTH];
uint8_t UsageListSize = 0;
HID_MinMax_t UsageMinMax = {0, 0};
memset(ParserData, 0x00, sizeof(HID_ReportInfo_t));
memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));
memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
ParserData->TotalDeviceReports = 1;
while (ReportSize)
{
uint8_t HIDReportItem = *ReportData;
uint32_t ReportItemData = 0;
ReportData++;
ReportSize--;
switch (HIDReportItem & DATA_SIZE_MASK)
{
case DATA_SIZE_4:
ReportItemData = *((uint32_t*)ReportData);
ReportSize -= 4;
ReportData += 4;
break;
case DATA_SIZE_2:
ReportItemData = *((uint16_t*)ReportData);
ReportSize -= 2;
ReportData += 2;
break;
case DATA_SIZE_1:
ReportItemData = *((uint8_t*)ReportData);
ReportSize -= 1;
ReportData += 1;
break;
}
switch (HIDReportItem & (TYPE_MASK | TAG_MASK))
{
case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH - 1])
return HID_PARSE_HIDStackOverflow;
memcpy((CurrStateTable + 1),
CurrStateTable,
sizeof(HID_ReportItem_t));
CurrStateTable++;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_POP):
if (CurrStateTable == &StateTable[0])
return HID_PARSE_HIDStackUnderflow;
CurrStateTable--;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE):
CurrStateTable->Attributes.Usage.Page = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMIN):
CurrStateTable->Attributes.Logical.Minimum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMAX):
CurrStateTable->Attributes.Logical.Maximum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMIN):
CurrStateTable->Attributes.Physical.Minimum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMAX):
CurrStateTable->Attributes.Physical.Maximum = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_UNITEXP):
CurrStateTable->Attributes.Unit.Exponent = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_UNIT):
CurrStateTable->Attributes.Unit.Type = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE):
CurrStateTable->Attributes.BitSize = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT):
CurrStateTable->ReportCount = ReportItemData;
break;
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):
CurrStateTable->ReportID = ReportItemData;
if (ParserData->UsingReportIDs)
{
CurrReportIDInfo = NULL;
for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++)
{
if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID)
{
CurrReportIDInfo = &ParserData->ReportIDSizes[i];
break;
}
}
if (CurrReportIDInfo == NULL)
{
if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS)
return HID_PARSE_InsufficientReportIDItems;
CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++];
memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
}
}
ParserData->UsingReportIDs = true;
CurrReportIDInfo->ReportID = CurrStateTable->ReportID;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
if (UsageListSize == HID_USAGE_STACK_DEPTH)
return HID_PARSE_UsageListOverflow;
UsageList[UsageListSize++] = ReportItemData;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
UsageMinMax.Minimum = ReportItemData;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):
UsageMinMax.Maximum = ReportItemData;
break;
case (TYPE_MAIN | TAG_MAIN_COLLECTION):
if (CurrCollectionPath == NULL)
{
CurrCollectionPath = &ParserData->CollectionPaths[0];
}
else
{
HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath;
CurrCollectionPath = &ParserData->CollectionPaths[1];
while (CurrCollectionPath->Parent != NULL)
{
if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1])
return HID_PARSE_InsufficientCollectionPaths;
CurrCollectionPath++;
}
CurrCollectionPath->Parent = ParentCollectionPath;
}
CurrCollectionPath->Type = ReportItemData;
CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page;
if (UsageListSize)
{
CurrCollectionPath->Usage.Usage = UsageList[0];
for (uint8_t i = 0; i < UsageListSize; i++)
UsageList[i] = UsageList[i + 1];
UsageListSize--;
}
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
{
CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++;
}
break;
case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
if (CurrCollectionPath == NULL)
return HID_PARSE_UnexpectedEndCollection;
CurrCollectionPath = CurrCollectionPath->Parent;
break;
case (TYPE_MAIN | TAG_MAIN_INPUT):
case (TYPE_MAIN | TAG_MAIN_OUTPUT):
case (TYPE_MAIN | TAG_MAIN_FEATURE):
for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++)
{
HID_ReportItem_t NewReportItem;
memcpy(&NewReportItem.Attributes,
&CurrStateTable->Attributes,
sizeof(HID_ReportItem_Attributes_t));
NewReportItem.ItemFlags = ReportItemData;
NewReportItem.CollectionPath = CurrCollectionPath;
NewReportItem.ReportID = CurrStateTable->ReportID;
if (UsageListSize)
{
NewReportItem.Attributes.Usage.Usage = UsageList[0];
for (uint8_t i = 0; i < UsageListSize; i++)
UsageList[i] = UsageList[i + 1];
UsageListSize--;
}
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
{
NewReportItem.Attributes.Usage.Usage = UsageMinMax.Minimum++;
}
uint8_t ItemTag = (HIDReportItem & TAG_MASK);
if (ItemTag == TAG_MAIN_INPUT)
NewReportItem.ItemType = REPORT_ITEM_TYPE_In;
else if (ItemTag == TAG_MAIN_OUTPUT)
NewReportItem.ItemType = REPORT_ITEM_TYPE_Out;
else
NewReportItem.ItemType = REPORT_ITEM_TYPE_Feature;
NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType];
CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize;
if (ParserData->LargestReportSizeBits < NewReportItem.BitOffset)
ParserData->LargestReportSizeBits = NewReportItem.BitOffset;
if (!(ReportItemData & IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem))
{
if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS)
return HID_PARSE_InsufficientReportItems;
memcpy(&ParserData->ReportItems[ParserData->TotalReportItems],
&NewReportItem, sizeof(HID_ReportItem_t));
ParserData->TotalReportItems++;
}
}
break;
}
if ((HIDReportItem & TYPE_MASK) == TYPE_MAIN)
{
UsageMinMax.Minimum = 0;
UsageMinMax.Maximum = 0;
UsageListSize = 0;
}
}
if (!(ParserData->TotalReportItems))
return HID_PARSE_NoUnfilteredReportItems;
return HID_PARSE_Successful;
}
bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
{
uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
uint16_t CurrentBit = ReportItem->BitOffset;
uint32_t BitMask = (1 << 0);
ReportItem->PreviousValue = ReportItem->Value;
ReportItem->Value = 0;
if (ReportItem->ReportID)
{
if (ReportItem->ReportID != ReportData[0])
return false;
ReportData++;
}
while (DataBitsRem--)
{
if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8)))
ReportItem->Value |= BitMask;
CurrentBit++;
BitMask <<= 1;
}
return true;
}
void USB_SetHIDReportItemInfo(uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
{
uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
uint16_t CurrentBit = ReportItem->BitOffset;
uint32_t BitMask = (1 << 0);
if (ReportItem->ReportID)
{
ReportData[0] = ReportItem->ReportID;
ReportData++;
}
ReportItem->PreviousValue = ReportItem->Value;
while (DataBitsRem--)
{
if (ReportItem->Value & (1 << (CurrentBit % 8)))
ReportData[CurrentBit / 8] |= BitMask;
CurrentBit++;
BitMask <<= 1;
}
}
uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, const uint8_t ReportID, const uint8_t ReportType)
{
for (uint8_t i = 0; i < HID_MAX_REPORT_IDS; i++)
{
uint16_t ReportSizeBits = ParserData->ReportIDSizes[i].ReportSizeBits[ReportType];
if (ParserData->ReportIDSizes[i].ReportID == ReportID)
return ((ReportSizeBits >> 3) + ((ReportSizeBits & 0x07) ? 1 : 0));
}
return 0;
}
#endif

View file

@ -1,355 +1,355 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief USB Human Interface Device (HID) Class report descriptor parser.
*
* This file allows for the easy parsing of complex HID report descriptors, which describes the data that
* a HID device transmits to the host. It also provides an easy API for extracting and processing the data
* elements inside a HID report sent from an attached HID device.
*/
/** \ingroup Group_USB
* @defgroup Group_HIDParser HID Report Parser
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/HIDParser.c
*
* \section Module Description
* Functions, macros, variables, enums and types related to the parsing of HID class device report descriptors.
*
* The processed HID report is presented back to the user application as a flat structure containing each report
* item's IN, OUT and FEATURE items along with each item's attributes.
*
* This library portion also allows for easy setting and retrieval of data from a HID report, including devices
* with multiple reports on the one HID interface.
*
* @{
*/
#ifndef __HIDPARSER_H__
#define __HIDPARSER_H__
/* Macros: */
#define __INCLUDE_FROM_USB_DRIVER
#define __INCLUDE_FROM_HID_DRIVER
/* Includes: */
#include <string.h>
#include <stdbool.h>
#include "HIDReportData.h"
#include "../Common/HID.h"
#include "../../../../Common/Common.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Macros: */
#if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__)
/** Constant indicating the maximum stack depth of the state table. A larger state table
* allows for more PUSH/POP report items to be nested, but consumes more memory. By default
* this is set to 2 levels (allowing non-nested PUSH items) but this can be overridden by
* defining HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the
* define to the compiler using the -D compiler switch.
*/
#define HID_STATETABLE_STACK_DEPTH 2
#endif
#if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__)
/** Constant indicating the maximum stack depth of the usage table. A larger usage table
* allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than
* one, but requires more stack space. By default this is set to 8 levels (allowing for a report
* item with a count of 8) but this can be overridden by defining HID_USAGE_STACK_DEPTH to another
* value in the user project makefile, passing the define to the compiler using the -D compiler
* switch.
*/
#define HID_USAGE_STACK_DEPTH 8
#endif
#if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__)
/** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be
* processed in the report item descriptor. A large value allows for more COLLECTION items to be
* processed, but consumes more memory. By default this is set to 5 collections, but this can be
* overridden by defining HID_MAX_COLLECTIONS to another value in the user project makefile, passing
* the define to the compiler using the -D compiler switch.
*/
#define HID_MAX_COLLECTIONS 10
#endif
#if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__)
/** Constant indicating the maximum number of report items (IN, OUT or FEATURE) that can be processed
* in the report item descriptor and stored in the user HID Report Info structure. A large value allows
* for more report items to be stored, but consumes more memory. By default this is set to 20 items,
* but this can be overridden by defining HID_MAX_REPORTITEMS to another value in the user project
* makefile, and passing the define to the compiler using the -D compiler switch.
*/
#define HID_MAX_REPORTITEMS 20
#endif
#if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__)
/** Constant indicating the maximum number of unique report IDs that can be processed in the report item
* descriptor for the report size information array in the user HID Report Info structure. A large value
* allows for more report ID report sizes to be stored, but consumes more memory. By default this is set
* to 5 items, but this can be overridden by defining HID_MAX_REPORT_IDS to another value in the user project
* makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE
* items sharing the same report ID consume only one size item in the array.
*/
#define HID_MAX_REPORT_IDS 10
#endif
/** Returns the value a given HID report item (once its value has been fetched via \ref USB_GetHIDReportItemInfo())
* left-aligned to the given data type. This allows for signed data to be interpreted correctly, by shifting the data
* leftwards until the data's sign bit is in the correct position.
*
* \param[in] reportitem HID Report Item whose retrieved value is to be aligned
* \param[in] type Data type to align the HID report item's value to
*
* \return Left-aligned data of the given report item's pre-retrived value for the given datatype
*/
#define HID_ALIGN_DATA(reportitem, type) ((type)(reportitem->Value << ((8 * sizeof(type)) - reportitem->Attributes.BitSize)))
/* Public Interface - May be used in end-application: */
/* Enums: */
/** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function */
enum HID_Parse_ErrorCodes_t
{
HID_PARSE_Successful = 0, /**< Successful parse of the HID report descriptor, no error. */
HID_PARSE_HIDStackOverflow = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */
HID_PARSE_HIDStackUnderflow = 2, /**< A POP was found when the state table stack was empty. */
HID_PARSE_InsufficientReportItems = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */
HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */
HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */
HID_PARSE_UsageListOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */
HID_PARSE_NoUnfilteredReportItems = 8, /**< All report items from the device were filtered by the filtering callback routine. */
};
/* Type Defines: */
/** \brief HID Parser Report Item Min/Max Structure.
*
* Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max).
*/
typedef struct
{
uint32_t Minimum; /**< Minimum value for the attribute. */
uint32_t Maximum; /**< Maximum value for the attribute. */
} HID_MinMax_t;
/** \brief HID Parser Report Item Unit Structure.
*
* Type define for the Unit attributes of a report item.
*/
typedef struct
{
uint32_t Type; /**< Unit type (refer to HID specifications for details). */
uint8_t Exponent; /**< Unit exponent (refer to HID specifications for details). */
} HID_Unit_t;
/** \brief HID Parser Report Item Usage Structure.
*
* Type define for the Usage attributes of a report item.
*/
typedef struct
{
uint16_t Page; /**< Usage page of the report item. */
uint16_t Usage; /**< Usage of the report item. */
} HID_Usage_t;
/** \brief HID Parser Report Item Collection Path Structure.
*
* Type define for a COLLECTION object. Contains the collection attributes and a reference to the
* parent collection if any.
*/
typedef struct CollectionPath
{
uint8_t Type; /**< Collection type (e.g. "Generic Desktop"). */
HID_Usage_t Usage; /**< Collection usage. */
struct CollectionPath* Parent; /**< Reference to parent collection, or NULL if root collection. */
} HID_CollectionPath_t;
/** \brief HID Parser Report Item Attributes Structure.
*
* Type define for all the data attributes of a report item, except flags.
*/
typedef struct
{
uint8_t BitSize; /**< Size in bits of the report item's data. */
HID_Usage_t Usage; /**< Usage of the report item. */
HID_Unit_t Unit; /**< Unit type and exponent of the report item. */
HID_MinMax_t Logical; /**< Logical minimum and maximum of the report item. */
HID_MinMax_t Physical; /**< Physical minimum and maximum of the report item. */
} HID_ReportItem_Attributes_t;
/** \brief HID Parser Report Item Details Structure.
*
* Type define for a report item (IN, OUT or FEATURE) layout attributes and other details.
*/
typedef struct
{
uint16_t BitOffset; /**< Bit offset in the IN, OUT or FEATURE report of the item. */
uint8_t ItemType; /**< Report item type, a value in HID_ReportItemTypes_t. */
uint16_t ItemFlags; /**< Item data flags, such as constant/variable, etc. */
uint8_t ReportID; /**< Report ID this item belongs to, or 0x00 if device has only one report */
HID_CollectionPath_t* CollectionPath; /**< Collection path of the item. */
HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */
uint32_t Value; /**< Current value of the report item - use \ref HID_ALIGN_DATA() when processing
* a retrieved value so that it is aligned to a specific type.
*/
uint32_t PreviousValue; /**< Previous value of the report item. */
} HID_ReportItem_t;
/** \brief HID Parser Report Size Structure.
*
* Type define for a report item size information structure, to retain the size of a device's reports by ID.
*/
typedef struct
{
uint8_t ReportID; /** Report ID of the report within the HID interface */
uint16_t ReportSizeBits[3]; /** Total number of bits in each report type for the given Report ID,
* indexed by the \ref HID_ReportItemTypes_t enum
*/
} HID_ReportSizeInfo_t;
/** \brief HID Parser State Structure.
*
* Type define for a complete processed HID report, including all report item data and collections.
*/
typedef struct
{
uint8_t TotalReportItems; /**< Total number of report items stored in the
* ReportItems array.
*/
HID_ReportItem_t ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including
* all IN, OUT and FEATURE items.
*/
HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced
* by the report items.
*/
uint8_t TotalDeviceReports; /**< Number of reports within the HID interface */
HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /**< Report sizes for each report in the interface */
uint16_t LargestReportSizeBits; /**< Largest report that the attached device will generate, in bits */
bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID
* element in its HID report descriptor.
*/
} HID_ReportInfo_t;
/* Function Prototypes: */
/** Function to process a given HID report returned from an attached device, and store it into a given
* \ref HID_ReportInfo_t structure.
*
* \param[in] ReportData Buffer containing the device's HID report table
* \param[in] ReportSize Size in bytes of the HID report table
* \param[out] ParserData Pointer to a \ref HID_ReportInfo_t instance for the parser output
*
* \return A value in the \ref HID_Parse_ErrorCodes_t enum
*/
uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Extracts the given report item's value out of the given HID report and places it into the Value
* member of the report item's \ref HID_ReportItem_t structure.
*
* When called, this copies the report item's Value element to it's PreviousValue element for easy
* checking to see if an item's value has changed before processing a report.
*
* \param[in] ReportData Buffer containing an IN or FEATURE report from an attached device
* \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array
*
* \returns Boolean true if the item to retrieve was located in the given report, false otherwise
*/
bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the given report item's value out of the Value member of the report item's
* \ref HID_ReportItem_t structure and places it into the correct position in the HID report
* buffer. The report buffer is assumed to have the appropriate bits cleared before calling
* this function (i.e., the buffer should be explicitly cleared before report values are added).
*
* When called, this copies the report item's Value element to it's PreviousValue element for easy
* checking to see if an item's value has changed before sending a report.
*
* If the device has multiple HID reports, the first byte in the report is set to the report ID of the given item.
*
* \param[out] ReportData Buffer holding the current OUT or FEATURE report data
* \param[in] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array
*/
void USB_SetHIDReportItemInfo(uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the size of a given HID report in bytes from it's Report ID.
*
* \param[in] ParserData Pointer to a \ref HID_ReportInfo_t instance containing the parser output
* \param[in] ReportID Report ID of the report whose size is to be retrieved
* \param[in] ReportType Type of the report whose size is to be determined, a valued from the
* \ref HID_ReportItemTypes_t enum
*
* \return Size of the report in bytes, or 0 if the report does not exist
*/
uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, const uint8_t ReportID,
const uint8_t ReportType) ATTR_CONST ATTR_NON_NULL_PTR_ARG(1);
/** Callback routine for the HID Report Parser. This callback <b>must</b> be implemented by the user code when
* the parser is used, to determine what report IN, OUT and FEATURE item's information is stored into the user
* HID_ReportInfo_t structure. This can be used to filter only those items the application will be using, so that
* no RAM is wasted storing the attributes for report items which will never be referenced by the application.
*
* \param[in] CurrentItem Pointer to the current report item for user checking
*
* \return Boolean true if the item should be stored into the HID_ReportInfo_t structure, false if it should be ignored
*/
bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* CurrentItem);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Type Defines: */
typedef struct
{
HID_ReportItem_Attributes_t Attributes;
uint8_t ReportCount;
uint8_t ReportID;
} HID_StateTable_t;
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief USB Human Interface Device (HID) Class report descriptor parser.
*
* This file allows for the easy parsing of complex HID report descriptors, which describes the data that
* a HID device transmits to the host. It also provides an easy API for extracting and processing the data
* elements inside a HID report sent from an attached HID device.
*/
/** \ingroup Group_USB
* @defgroup Group_HIDParser HID Report Parser
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/HIDParser.c
*
* \section Module Description
* Functions, macros, variables, enums and types related to the parsing of HID class device report descriptors.
*
* The processed HID report is presented back to the user application as a flat structure containing each report
* item's IN, OUT and FEATURE items along with each item's attributes.
*
* This library portion also allows for easy setting and retrieval of data from a HID report, including devices
* with multiple reports on the one HID interface.
*
* @{
*/
#ifndef __HIDPARSER_H__
#define __HIDPARSER_H__
/* Macros: */
#define __INCLUDE_FROM_USB_DRIVER
#define __INCLUDE_FROM_HID_DRIVER
/* Includes: */
#include <string.h>
#include <stdbool.h>
#include "HIDReportData.h"
#include "../Common/HID.h"
#include "../../../../Common/Common.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Macros: */
#if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__)
/** Constant indicating the maximum stack depth of the state table. A larger state table
* allows for more PUSH/POP report items to be nested, but consumes more memory. By default
* this is set to 2 levels (allowing non-nested PUSH items) but this can be overridden by
* defining HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the
* define to the compiler using the -D compiler switch.
*/
#define HID_STATETABLE_STACK_DEPTH 2
#endif
#if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__)
/** Constant indicating the maximum stack depth of the usage table. A larger usage table
* allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than
* one, but requires more stack space. By default this is set to 8 levels (allowing for a report
* item with a count of 8) but this can be overridden by defining HID_USAGE_STACK_DEPTH to another
* value in the user project makefile, passing the define to the compiler using the -D compiler
* switch.
*/
#define HID_USAGE_STACK_DEPTH 8
#endif
#if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__)
/** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be
* processed in the report item descriptor. A large value allows for more COLLECTION items to be
* processed, but consumes more memory. By default this is set to 5 collections, but this can be
* overridden by defining HID_MAX_COLLECTIONS to another value in the user project makefile, passing
* the define to the compiler using the -D compiler switch.
*/
#define HID_MAX_COLLECTIONS 10
#endif
#if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__)
/** Constant indicating the maximum number of report items (IN, OUT or FEATURE) that can be processed
* in the report item descriptor and stored in the user HID Report Info structure. A large value allows
* for more report items to be stored, but consumes more memory. By default this is set to 20 items,
* but this can be overridden by defining HID_MAX_REPORTITEMS to another value in the user project
* makefile, and passing the define to the compiler using the -D compiler switch.
*/
#define HID_MAX_REPORTITEMS 20
#endif
#if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__)
/** Constant indicating the maximum number of unique report IDs that can be processed in the report item
* descriptor for the report size information array in the user HID Report Info structure. A large value
* allows for more report ID report sizes to be stored, but consumes more memory. By default this is set
* to 5 items, but this can be overridden by defining HID_MAX_REPORT_IDS to another value in the user project
* makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE
* items sharing the same report ID consume only one size item in the array.
*/
#define HID_MAX_REPORT_IDS 10
#endif
/** Returns the value a given HID report item (once its value has been fetched via \ref USB_GetHIDReportItemInfo())
* left-aligned to the given data type. This allows for signed data to be interpreted correctly, by shifting the data
* leftwards until the data's sign bit is in the correct position.
*
* \param[in] reportitem HID Report Item whose retrieved value is to be aligned
* \param[in] type Data type to align the HID report item's value to
*
* \return Left-aligned data of the given report item's pre-retrived value for the given datatype
*/
#define HID_ALIGN_DATA(reportitem, type) ((type)(reportitem->Value << ((8 * sizeof(type)) - reportitem->Attributes.BitSize)))
/* Public Interface - May be used in end-application: */
/* Enums: */
/** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function */
enum HID_Parse_ErrorCodes_t
{
HID_PARSE_Successful = 0, /**< Successful parse of the HID report descriptor, no error. */
HID_PARSE_HIDStackOverflow = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */
HID_PARSE_HIDStackUnderflow = 2, /**< A POP was found when the state table stack was empty. */
HID_PARSE_InsufficientReportItems = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */
HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */
HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */
HID_PARSE_UsageListOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */
HID_PARSE_NoUnfilteredReportItems = 8, /**< All report items from the device were filtered by the filtering callback routine. */
};
/* Type Defines: */
/** \brief HID Parser Report Item Min/Max Structure.
*
* Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max).
*/
typedef struct
{
uint32_t Minimum; /**< Minimum value for the attribute. */
uint32_t Maximum; /**< Maximum value for the attribute. */
} HID_MinMax_t;
/** \brief HID Parser Report Item Unit Structure.
*
* Type define for the Unit attributes of a report item.
*/
typedef struct
{
uint32_t Type; /**< Unit type (refer to HID specifications for details). */
uint8_t Exponent; /**< Unit exponent (refer to HID specifications for details). */
} HID_Unit_t;
/** \brief HID Parser Report Item Usage Structure.
*
* Type define for the Usage attributes of a report item.
*/
typedef struct
{
uint16_t Page; /**< Usage page of the report item. */
uint16_t Usage; /**< Usage of the report item. */
} HID_Usage_t;
/** \brief HID Parser Report Item Collection Path Structure.
*
* Type define for a COLLECTION object. Contains the collection attributes and a reference to the
* parent collection if any.
*/
typedef struct CollectionPath
{
uint8_t Type; /**< Collection type (e.g. "Generic Desktop"). */
HID_Usage_t Usage; /**< Collection usage. */
struct CollectionPath* Parent; /**< Reference to parent collection, or NULL if root collection. */
} HID_CollectionPath_t;
/** \brief HID Parser Report Item Attributes Structure.
*
* Type define for all the data attributes of a report item, except flags.
*/
typedef struct
{
uint8_t BitSize; /**< Size in bits of the report item's data. */
HID_Usage_t Usage; /**< Usage of the report item. */
HID_Unit_t Unit; /**< Unit type and exponent of the report item. */
HID_MinMax_t Logical; /**< Logical minimum and maximum of the report item. */
HID_MinMax_t Physical; /**< Physical minimum and maximum of the report item. */
} HID_ReportItem_Attributes_t;
/** \brief HID Parser Report Item Details Structure.
*
* Type define for a report item (IN, OUT or FEATURE) layout attributes and other details.
*/
typedef struct
{
uint16_t BitOffset; /**< Bit offset in the IN, OUT or FEATURE report of the item. */
uint8_t ItemType; /**< Report item type, a value in HID_ReportItemTypes_t. */
uint16_t ItemFlags; /**< Item data flags, such as constant/variable, etc. */
uint8_t ReportID; /**< Report ID this item belongs to, or 0x00 if device has only one report */
HID_CollectionPath_t* CollectionPath; /**< Collection path of the item. */
HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */
uint32_t Value; /**< Current value of the report item - use \ref HID_ALIGN_DATA() when processing
* a retrieved value so that it is aligned to a specific type.
*/
uint32_t PreviousValue; /**< Previous value of the report item. */
} HID_ReportItem_t;
/** \brief HID Parser Report Size Structure.
*
* Type define for a report item size information structure, to retain the size of a device's reports by ID.
*/
typedef struct
{
uint8_t ReportID; /** Report ID of the report within the HID interface */
uint16_t ReportSizeBits[3]; /** Total number of bits in each report type for the given Report ID,
* indexed by the \ref HID_ReportItemTypes_t enum
*/
} HID_ReportSizeInfo_t;
/** \brief HID Parser State Structure.
*
* Type define for a complete processed HID report, including all report item data and collections.
*/
typedef struct
{
uint8_t TotalReportItems; /**< Total number of report items stored in the
* ReportItems array.
*/
HID_ReportItem_t ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including
* all IN, OUT and FEATURE items.
*/
HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced
* by the report items.
*/
uint8_t TotalDeviceReports; /**< Number of reports within the HID interface */
HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /**< Report sizes for each report in the interface */
uint16_t LargestReportSizeBits; /**< Largest report that the attached device will generate, in bits */
bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID
* element in its HID report descriptor.
*/
} HID_ReportInfo_t;
/* Function Prototypes: */
/** Function to process a given HID report returned from an attached device, and store it into a given
* \ref HID_ReportInfo_t structure.
*
* \param[in] ReportData Buffer containing the device's HID report table
* \param[in] ReportSize Size in bytes of the HID report table
* \param[out] ParserData Pointer to a \ref HID_ReportInfo_t instance for the parser output
*
* \return A value in the \ref HID_Parse_ErrorCodes_t enum
*/
uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Extracts the given report item's value out of the given HID report and places it into the Value
* member of the report item's \ref HID_ReportItem_t structure.
*
* When called, this copies the report item's Value element to it's PreviousValue element for easy
* checking to see if an item's value has changed before processing a report.
*
* \param[in] ReportData Buffer containing an IN or FEATURE report from an attached device
* \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array
*
* \returns Boolean true if the item to retrieve was located in the given report, false otherwise
*/
bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the given report item's value out of the Value member of the report item's
* \ref HID_ReportItem_t structure and places it into the correct position in the HID report
* buffer. The report buffer is assumed to have the appropriate bits cleared before calling
* this function (i.e., the buffer should be explicitly cleared before report values are added).
*
* When called, this copies the report item's Value element to it's PreviousValue element for easy
* checking to see if an item's value has changed before sending a report.
*
* If the device has multiple HID reports, the first byte in the report is set to the report ID of the given item.
*
* \param[out] ReportData Buffer holding the current OUT or FEATURE report data
* \param[in] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array
*/
void USB_SetHIDReportItemInfo(uint8_t* ReportData, HID_ReportItem_t* const ReportItem)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the size of a given HID report in bytes from it's Report ID.
*
* \param[in] ParserData Pointer to a \ref HID_ReportInfo_t instance containing the parser output
* \param[in] ReportID Report ID of the report whose size is to be retrieved
* \param[in] ReportType Type of the report whose size is to be determined, a valued from the
* \ref HID_ReportItemTypes_t enum
*
* \return Size of the report in bytes, or 0 if the report does not exist
*/
uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, const uint8_t ReportID,
const uint8_t ReportType) ATTR_CONST ATTR_NON_NULL_PTR_ARG(1);
/** Callback routine for the HID Report Parser. This callback <b>must</b> be implemented by the user code when
* the parser is used, to determine what report IN, OUT and FEATURE item's information is stored into the user
* HID_ReportInfo_t structure. This can be used to filter only those items the application will be using, so that
* no RAM is wasted storing the attributes for report items which will never be referenced by the application.
*
* \param[in] CurrentItem Pointer to the current report item for user checking
*
* \return Boolean true if the item should be stored into the HID_ReportInfo_t structure, false if it should be ignored
*/
bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* CurrentItem);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Type Defines: */
typedef struct
{
HID_ReportItem_Attributes_t Attributes;
uint8_t ReportCount;
uint8_t ReportID;
} HID_StateTable_t;
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,141 +1,141 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Constants for HID report item attributes.
*
* HID report item constants for report item attributes. Refer to the HID specification for
* details on each flag's meaning when applied to an IN, OUT or FEATURE item.
*/
/** \ingroup Group_HIDParser
* @defgroup Group_HIDIOFConst Input/Output/Feature Masks
*
* Masks indicating the type of Input, Output of Feature HID report item.
*
* @{
*/
#ifndef __HIDREPORTDATA_H__
#define __HIDREPORTDATA_H__
/* Public Interface - May be used in end-application: */
/* Macros: */
/** HID_ReportItem_t.ItemFlags flag for constant data. */
#define IOF_CONSTANT (1 << 0)
/** HID_ReportItem_t.ItemFlags flag for data. */
#define IOF_DATA (0 << 0)
/** HID_ReportItem_t.ItemFlags flag for variable data. */
#define IOF_VARIABLE (1 << 1)
/** HID_ReportItem_t.ItemFlags flag for array data. */
#define IOF_ARRAY (0 << 1)
/** HID_ReportItem_t.ItemFlags flag for relative data. */
#define IOF_RELATIVE (1 << 2)
/** HID_ReportItem_t.ItemFlags flag for absolute data. */
#define IOF_ABSOLUTE (0 << 2)
/** HID_ReportItem_t.ItemFlags flag for wrapped value data. */
#define IOF_WRAP (1 << 3)
/** HID_ReportItem_t.ItemFlags flag for non-wrapped value data. */
#define IOF_NOWRAP (0 << 3)
/** HID_ReportItem_t.ItemFlags flag for non linear data. */
#define IOF_NONLINEAR (1 << 4)
/** HID_ReportItem_t.ItemFlags flag for linear data. */
#define IOF_LINEAR (0 << 4)
/** HID_ReportItem_t.ItemFlags flag for no preferred state. */
#define IOF_NOPREFERRED (1 << 5)
/** HID_ReportItem_t.ItemFlags flag for preferred state items. */
#define IOF_PREFERREDSTATE (0 << 5)
/** HID_ReportItem_t.ItemFlags flag for null state items. */
#define IOF_NULLSTATE (1 << 6)
/** HID_ReportItem_t.ItemFlags flag for no null position data. */
#define IOF_NONULLPOSITION (0 << 6)
/** HID_ReportItem_t.ItemFlags flag for buffered bytes. */
#define IOF_BUFFEREDBYTES (1 << 8)
/** HID_ReportItem_t.ItemFlags flag for bit field data. */
#define IOF_BITFIELD (0 << 8)
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define DATA_SIZE_MASK 0x03
#define TYPE_MASK 0x0C
#define TAG_MASK 0xF0
#define DATA_SIZE_0 0x00
#define DATA_SIZE_1 0x01
#define DATA_SIZE_2 0x02
#define DATA_SIZE_4 0x03
#define TYPE_MAIN 0x00
#define TYPE_GLOBAL 0x04
#define TYPE_LOCAL 0x08
#define TAG_MAIN_INPUT 0x80
#define TAG_MAIN_OUTPUT 0x90
#define TAG_MAIN_COLLECTION 0xA0
#define TAG_MAIN_FEATURE 0xB0
#define TAG_MAIN_ENDCOLLECTION 0xC0
#define TAG_GLOBAL_USAGEPAGE 0x00
#define TAG_GLOBAL_LOGICALMIN 0x10
#define TAG_GLOBAL_LOGICALMAX 0x20
#define TAG_GLOBAL_PHYSMIN 0x30
#define TAG_GLOBAL_PHYSMAX 0x40
#define TAG_GLOBAL_UNITEXP 0x50
#define TAG_GLOBAL_UNIT 0x60
#define TAG_GLOBAL_REPORTSIZE 0x70
#define TAG_GLOBAL_REPORTID 0x80
#define TAG_GLOBAL_REPORTCOUNT 0x90
#define TAG_GLOBAL_PUSH 0xA0
#define TAG_GLOBAL_POP 0xB0
#define TAG_LOCAL_USAGE 0x00
#define TAG_LOCAL_USAGEMIN 0x10
#define TAG_LOCAL_USAGEMAX 0x20
#endif
/** @} */
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Constants for HID report item attributes.
*
* HID report item constants for report item attributes. Refer to the HID specification for
* details on each flag's meaning when applied to an IN, OUT or FEATURE item.
*/
/** \ingroup Group_HIDParser
* @defgroup Group_HIDIOFConst Input/Output/Feature Masks
*
* Masks indicating the type of Input, Output of Feature HID report item.
*
* @{
*/
#ifndef __HIDREPORTDATA_H__
#define __HIDREPORTDATA_H__
/* Public Interface - May be used in end-application: */
/* Macros: */
/** HID_ReportItem_t.ItemFlags flag for constant data. */
#define IOF_CONSTANT (1 << 0)
/** HID_ReportItem_t.ItemFlags flag for data. */
#define IOF_DATA (0 << 0)
/** HID_ReportItem_t.ItemFlags flag for variable data. */
#define IOF_VARIABLE (1 << 1)
/** HID_ReportItem_t.ItemFlags flag for array data. */
#define IOF_ARRAY (0 << 1)
/** HID_ReportItem_t.ItemFlags flag for relative data. */
#define IOF_RELATIVE (1 << 2)
/** HID_ReportItem_t.ItemFlags flag for absolute data. */
#define IOF_ABSOLUTE (0 << 2)
/** HID_ReportItem_t.ItemFlags flag for wrapped value data. */
#define IOF_WRAP (1 << 3)
/** HID_ReportItem_t.ItemFlags flag for non-wrapped value data. */
#define IOF_NOWRAP (0 << 3)
/** HID_ReportItem_t.ItemFlags flag for non linear data. */
#define IOF_NONLINEAR (1 << 4)
/** HID_ReportItem_t.ItemFlags flag for linear data. */
#define IOF_LINEAR (0 << 4)
/** HID_ReportItem_t.ItemFlags flag for no preferred state. */
#define IOF_NOPREFERRED (1 << 5)
/** HID_ReportItem_t.ItemFlags flag for preferred state items. */
#define IOF_PREFERREDSTATE (0 << 5)
/** HID_ReportItem_t.ItemFlags flag for null state items. */
#define IOF_NULLSTATE (1 << 6)
/** HID_ReportItem_t.ItemFlags flag for no null position data. */
#define IOF_NONULLPOSITION (0 << 6)
/** HID_ReportItem_t.ItemFlags flag for buffered bytes. */
#define IOF_BUFFEREDBYTES (1 << 8)
/** HID_ReportItem_t.ItemFlags flag for bit field data. */
#define IOF_BITFIELD (0 << 8)
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define DATA_SIZE_MASK 0x03
#define TYPE_MASK 0x0C
#define TAG_MASK 0xF0
#define DATA_SIZE_0 0x00
#define DATA_SIZE_1 0x01
#define DATA_SIZE_2 0x02
#define DATA_SIZE_4 0x03
#define TYPE_MAIN 0x00
#define TYPE_GLOBAL 0x04
#define TYPE_LOCAL 0x08
#define TAG_MAIN_INPUT 0x80
#define TAG_MAIN_OUTPUT 0x90
#define TAG_MAIN_COLLECTION 0xA0
#define TAG_MAIN_FEATURE 0xB0
#define TAG_MAIN_ENDCOLLECTION 0xC0
#define TAG_GLOBAL_USAGEPAGE 0x00
#define TAG_GLOBAL_LOGICALMIN 0x10
#define TAG_GLOBAL_LOGICALMAX 0x20
#define TAG_GLOBAL_PHYSMIN 0x30
#define TAG_GLOBAL_PHYSMAX 0x40
#define TAG_GLOBAL_UNITEXP 0x50
#define TAG_GLOBAL_UNIT 0x60
#define TAG_GLOBAL_REPORTSIZE 0x70
#define TAG_GLOBAL_REPORTID 0x80
#define TAG_GLOBAL_REPORTCOUNT 0x90
#define TAG_GLOBAL_PUSH 0xA0
#define TAG_GLOBAL_POP 0xB0
#define TAG_LOCAL_USAGE 0x00
#define TAG_LOCAL_USAGEMIN 0x10
#define TAG_LOCAL_USAGEMAX 0x20
#endif
/** @} */
#endif

View file

@ -1,186 +1,186 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_MIDI_CLASS_HOST_C
#define __INCLUDE_FROM_MIDI_DRIVER
#include "MIDI.h"
uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return MIDI_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return MIDI_ENUMERROR_NoStreamingInterfaceFound;
}
while (FoundEndpoints != (MIDI_FOUND_DATAPIPE_IN | MIDI_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return MIDI_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(MIDIInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
MIDIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
MIDIInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= MIDI_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
MIDIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
MIDIInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= MIDI_FOUND_DATAPIPE_OUT;
}
}
MIDIInterfaceInfo->State.IsActive = true;
return MIDI_ENUMERROR_NoError;
}
static uint8_t DComp_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == MIDI_STREAMING_CLASS) &&
(CurrentInterface->SubClass == MIDI_STREAMING_SUBCLASS) &&
(CurrentInterface->Protocol == MIDI_STREAMING_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
{
if (USB_HostState != HOST_STATE_Configured)
return PIPE_RWSTREAM_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber);
if (Pipe_BytesInPipe())
{
Pipe_ClearOUT();
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
return ErrorCode;
}
return PIPE_READYWAIT_NoError;
}
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber);
if (Pipe_IsReadWriteAllowed())
{
uint8_t ErrorCode;
if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if (!(Pipe_IsReadWriteAllowed()))
Pipe_ClearOUT();
}
return PIPE_RWSTREAM_NoError;
}
bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipeNumber);
if (!(Pipe_IsReadWriteAllowed()))
return false;
Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
if (!(Pipe_IsReadWriteAllowed()))
Pipe_ClearIN();
return true;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_MIDI_CLASS_HOST_C
#define __INCLUDE_FROM_MIDI_DRIVER
#include "MIDI.h"
uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return MIDI_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return MIDI_ENUMERROR_NoStreamingInterfaceFound;
}
while (FoundEndpoints != (MIDI_FOUND_DATAPIPE_IN | MIDI_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return MIDI_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(MIDIInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
MIDIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
MIDIInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= MIDI_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
MIDIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
MIDIInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= MIDI_FOUND_DATAPIPE_OUT;
}
}
MIDIInterfaceInfo->State.IsActive = true;
return MIDI_ENUMERROR_NoError;
}
static uint8_t DComp_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == MIDI_STREAMING_CLASS) &&
(CurrentInterface->SubClass == MIDI_STREAMING_SUBCLASS) &&
(CurrentInterface->Protocol == MIDI_STREAMING_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
{
if (USB_HostState != HOST_STATE_Configured)
return PIPE_RWSTREAM_DeviceDisconnected;
uint8_t ErrorCode;
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber);
if (Pipe_BytesInPipe())
{
Pipe_ClearOUT();
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
return ErrorCode;
}
return PIPE_READYWAIT_NoError;
}
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber);
if (Pipe_IsReadWriteAllowed())
{
uint8_t ErrorCode;
if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if (!(Pipe_IsReadWriteAllowed()))
Pipe_ClearOUT();
}
return PIPE_RWSTREAM_NoError;
}
bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipeNumber);
if (!(Pipe_IsReadWriteAllowed()))
return false;
Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
if (!(Pipe_IsReadWriteAllowed()))
Pipe_ClearIN();
return true;
}
#endif

View file

@ -1,204 +1,204 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB MIDI Class driver.
*
* Host mode driver for the library USB MIDI Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MIDI.h.
*/
/** \ingroup Group_USBClassMIDI
* @defgroup Group_USBClassMIDIHost MIDI Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/MIDI.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the MIDI USB Class driver.
*
* @{
*/
#ifndef __MIDI_CLASS_HOST_H__
#define __MIDI_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/MIDI.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MIDI.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief MIDI Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the MIDI class driver functions as the MIDIInterfaceInfo parameter. This
* stores each MIDI interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the MIDI interface's streaming IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the MIDI interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the MIDI interface's streaming OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the MIDI interface's OUT data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint16_t DataINPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's OUT data pipe */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_MIDI_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref MIDI_Host_ConfigurePipes() function. */
enum MIDIHost_EnumerationFailure_ErrorCodes_t
{
MIDI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
MIDI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
MIDI_ENUMERROR_NoStreamingInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor */
MIDI_ENUMERROR_EndpointsNotFound = 3, /**< Compatible MIDI data endpoints were not found in the device's MIDI interface */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given MIDI host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given MIDI Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the device.
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
* the Addressed state.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref MIDIHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sends a MIDI event packet to the device. If no device is connected, the event packet is discarded.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Flushes the MIDI send buffer, sending any queued MIDI events to the device. This should be called to override the
* \ref MIDI_Host_SendEventPacket() function's packing behaviour, to flush queued events. Events are queued into the
* pipe bank until either the pipe bank is full, or \ref MIDI_Host_Flush() is called. This allows for multiple MIDI
* events to be packed into a single pipe packet, increasing data throughput.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo);
/** Receives a MIDI event packet from the device.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed
*
* \return Boolean true if a MIDI event packet was received, false otherwise
*/
bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given MIDI host class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state
*/
static inline void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo);
static inline void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
{
(void)MIDIInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define MIDI_STREAMING_CLASS 0x01
#define MIDI_STREAMING_SUBCLASS 0x03
#define MIDI_STREAMING_PROTOCOL 0x00
#define MIDI_FOUND_DATAPIPE_IN (1 << 0)
#define MIDI_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_MIDI_CLASS_HOST_C)
static uint8_t DComp_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB MIDI Class driver.
*
* Host mode driver for the library USB MIDI Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MIDI.h.
*/
/** \ingroup Group_USBClassMIDI
* @defgroup Group_USBClassMIDIHost MIDI Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/MIDI.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the MIDI USB Class driver.
*
* @{
*/
#ifndef __MIDI_CLASS_HOST_H__
#define __MIDI_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/MIDI.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MIDI.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief MIDI Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the MIDI class driver functions as the MIDIInterfaceInfo parameter. This
* stores each MIDI interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the MIDI interface's streaming IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the MIDI interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the MIDI interface's streaming OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the MIDI interface's OUT data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint16_t DataINPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's OUT data pipe */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_MIDI_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref MIDI_Host_ConfigurePipes() function. */
enum MIDIHost_EnumerationFailure_ErrorCodes_t
{
MIDI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
MIDI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
MIDI_ENUMERROR_NoStreamingInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor */
MIDI_ENUMERROR_EndpointsNotFound = 3, /**< Compatible MIDI data endpoints were not found in the device's MIDI interface */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given MIDI host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given MIDI Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the device.
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
* the Addressed state.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref MIDIHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sends a MIDI event packet to the device. If no device is connected, the event packet is discarded.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Flushes the MIDI send buffer, sending any queued MIDI events to the device. This should be called to override the
* \ref MIDI_Host_SendEventPacket() function's packing behaviour, to flush queued events. Events are queued into the
* pipe bank until either the pipe bank is full, or \ref MIDI_Host_Flush() is called. This allows for multiple MIDI
* events to be packed into a single pipe packet, increasing data throughput.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo);
/** Receives a MIDI event packet from the device.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
* \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed
*
* \return Boolean true if a MIDI event packet was received, false otherwise
*/
bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given MIDI host class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state
*/
static inline void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo);
static inline void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
{
(void)MIDIInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define MIDI_STREAMING_CLASS 0x01
#define MIDI_STREAMING_SUBCLASS 0x03
#define MIDI_STREAMING_PROTOCOL 0x00
#define MIDI_FOUND_DATAPIPE_IN (1 << 0)
#define MIDI_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_MIDI_CLASS_HOST_C)
static uint8_t DComp_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

File diff suppressed because it is too large Load diff

View file

@ -1,339 +1,339 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB Mass Storage Class driver.
*
* Host mode driver for the library USB Mass Storage Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MassStorage.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassMassStorageHost Mass Storage Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/MassStorage.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
*
* @{
*/
#ifndef __MS_CLASS_HOST_H__
#define __MS_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/MassStorage.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MassStorage.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error */
#define MS_ERROR_LOGICAL_CMD_FAILED 0x80
/* Type Defines: */
/** \brief Mass Storage Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the Mass Storage class driver functions as the MSInterfaceInfo parameter. This
* stores each Mass Storage interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the Mass Storage interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the Mass Storage interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the Mass Storage interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the Mass Storage interface's OUT data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the Mass Storage interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the Mass Storage interface's OUT data pipe */
uint32_t TransactionTag; /**< Current transaction tag for data synchronizing of packets */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_MS_Host_t;
/** \brief SCSI Device LUN Capacity Structure.
*
* SCSI capacity structure, to hold the total capacity of the device in both the number
* of blocks in the current LUN, and the size of each block. This structure is filled by
* the device when the MassStore_ReadCapacity() function is called.
*/
typedef struct
{
uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */
uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */
} SCSI_Capacity_t;
/* Enums: */
enum MSHost_EnumerationFailure_ErrorCodes_t
{
MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
MS_ENUMERROR_NoMSInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor */
MS_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Mass Storage endpoints were not found in the device's interfaces */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given Mass Storage host interface instance using the
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass
* Storage Host instance's state values and configures the pipes required to communicate with the interface if it
* is found within the device. This should be called once after the stack has enumerated the attached device, while
* the host state machine is in the Addressed state.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref MSHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface
* and readying it for the next Mass Storage command.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a GET MAX LUN control request to the attached device, retrieving the index of the highest LUN (Logical
* UNit, a logical drive) in the device. This value can then be used in the other functions of the Mass Storage
* Host mode Class driver to address a specific LUN within the device.
*
* \note Some devices do not support this request, and will STALL it when issued. To get around this,
* on unsupported devices the max LUN index will be reported as zero and no error will be returned
* if the device STALLs the request.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[out] MaxLUNIndex Pointer to a location where the highest LUN index value should be stored
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint8_t* const MaxLUNIndex)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the Mass Storage device's inquiry data for the specified LUN, indicating the device characteristics and
* properties.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] InquiryData Location where the read inquiry data should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED
*/
uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
SCSI_Inquiry_Response_t* const InquiryData) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/** Sends a TEST UNIT READY command to the device, to determine if it is ready to accept other SCSI commands.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex)
ATTR_NON_NULL_PTR_ARG(1);
/** Retrieves the total capacity of the attached USB Mass Storage device, in blocks, and block size.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] DeviceCapacity Pointer to the location where the capacity information should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
SCSI_Capacity_t* const DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/** Retrieves the device sense data, indicating the current device state and error codes for the previously
* issued command.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] SenseData Pointer to the location where the sense information should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
SCSI_Request_Sense_Response_t* const SenseData) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/** Issues a PREVENT MEDIUM REMOVAL command, to logically (or, depending on the type of device, physically) lock
* the device from removal so that blocks of data on the medium can be read or altered.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] PreventRemoval Boolean true if the device should be locked from removal, false otherwise
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
const bool PreventRemoval) ATTR_NON_NULL_PTR_ARG(1);
/** Reads blocks of data from the attached Mass Storage device's medium.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] BlockAddress Starting block address within the device to read from
* \param[in] Blocks Total number of blocks to read
* \param[in] BlockSize Size in bytes of each block within the device
* \param[out] BlockBuffer Pointer to where the read data from the device should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
const uint32_t BlockAddress, const uint8_t Blocks, const uint16_t BlockSize,
void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
/** Writes blocks of data to the attached Mass Storage device's medium.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] BlockAddress Starting block address within the device to write to
* \param[in] Blocks Total number of blocks to read
* \param[in] BlockSize Size in bytes of each block within the device
* \param[in] BlockBuffer Pointer to where the data to write should be sourced from
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
const uint32_t BlockAddress, const uint8_t Blocks, const uint16_t BlockSize,
const void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
/* Inline Functions: */
/** General management task for a given Mass Storage host class interface, required for the correct operation of
* the interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state
*/
static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo);
static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
{
(void)MSInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define MASS_STORE_CLASS 0x08
#define MASS_STORE_SUBCLASS 0x06
#define MASS_STORE_PROTOCOL 0x50
#define REQ_MassStorageReset 0xFF
#define REQ_GetMaxLUN 0xFE
#define CBW_SIGNATURE 0x43425355UL
#define CSW_SIGNATURE 0x53425355UL
#define COMMAND_DIRECTION_DATA_OUT (0 << 7)
#define COMMAND_DIRECTION_DATA_IN (1 << 7)
#define COMMAND_DATA_TIMEOUT_MS 10000
#define MS_FOUND_DATAPIPE_IN (1 << 0)
#define MS_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_MS_CLASS_HOST_C)
static uint8_t DComp_NextMSInterface(void* const CurrentDescriptor);
static uint8_t DComp_NextMSInterfaceEndpoint(void* const CurrentDescriptor);
static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
MS_CommandBlockWrapper_t* const SCSICommandBlock,
const void* const BufferPtr);
static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo);
static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
MS_CommandBlockWrapper_t* const SCSICommandBlock, void* BufferPtr);
static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
MS_CommandStatusWrapper_t* const SCSICommandStatus);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB Mass Storage Class driver.
*
* Host mode driver for the library USB Mass Storage Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/MassStorage.h.
*/
/** \ingroup Group_USBClassMS
* @defgroup Group_USBClassMassStorageHost Mass Storage Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/MassStorage.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
*
* @{
*/
#ifndef __MS_CLASS_HOST_H__
#define __MS_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/MassStorage.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_MS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/MassStorage.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error */
#define MS_ERROR_LOGICAL_CMD_FAILED 0x80
/* Type Defines: */
/** \brief Mass Storage Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the Mass Storage class driver functions as the MSInterfaceInfo parameter. This
* stores each Mass Storage interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the Mass Storage interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the Mass Storage interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the Mass Storage interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the Mass Storage interface's OUT data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the Mass Storage interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the Mass Storage interface's OUT data pipe */
uint32_t TransactionTag; /**< Current transaction tag for data synchronizing of packets */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_MS_Host_t;
/** \brief SCSI Device LUN Capacity Structure.
*
* SCSI capacity structure, to hold the total capacity of the device in both the number
* of blocks in the current LUN, and the size of each block. This structure is filled by
* the device when the MassStore_ReadCapacity() function is called.
*/
typedef struct
{
uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */
uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */
} SCSI_Capacity_t;
/* Enums: */
enum MSHost_EnumerationFailure_ErrorCodes_t
{
MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
MS_ENUMERROR_NoMSInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor */
MS_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Mass Storage endpoints were not found in the device's interfaces */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given Mass Storage host interface instance using the
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass
* Storage Host instance's state values and configures the pipes required to communicate with the interface if it
* is found within the device. This should be called once after the stack has enumerated the attached device, while
* the host state machine is in the Addressed state.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref MSHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface
* and readying it for the next Mass Storage command.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a GET MAX LUN control request to the attached device, retrieving the index of the highest LUN (Logical
* UNit, a logical drive) in the device. This value can then be used in the other functions of the Mass Storage
* Host mode Class driver to address a specific LUN within the device.
*
* \note Some devices do not support this request, and will STALL it when issued. To get around this,
* on unsupported devices the max LUN index will be reported as zero and no error will be returned
* if the device STALLs the request.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[out] MaxLUNIndex Pointer to a location where the highest LUN index value should be stored
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint8_t* const MaxLUNIndex)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the Mass Storage device's inquiry data for the specified LUN, indicating the device characteristics and
* properties.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] InquiryData Location where the read inquiry data should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED
*/
uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
SCSI_Inquiry_Response_t* const InquiryData) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/** Sends a TEST UNIT READY command to the device, to determine if it is ready to accept other SCSI commands.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex)
ATTR_NON_NULL_PTR_ARG(1);
/** Retrieves the total capacity of the attached USB Mass Storage device, in blocks, and block size.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] DeviceCapacity Pointer to the location where the capacity information should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
SCSI_Capacity_t* const DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/** Retrieves the device sense data, indicating the current device state and error codes for the previously
* issued command.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] SenseData Pointer to the location where the sense information should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
SCSI_Request_Sense_Response_t* const SenseData) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(3);
/** Issues a PREVENT MEDIUM REMOVAL command, to logically (or, depending on the type of device, physically) lock
* the device from removal so that blocks of data on the medium can be read or altered.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] PreventRemoval Boolean true if the device should be locked from removal, false otherwise
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
const bool PreventRemoval) ATTR_NON_NULL_PTR_ARG(1);
/** Reads blocks of data from the attached Mass Storage device's medium.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] BlockAddress Starting block address within the device to read from
* \param[in] Blocks Total number of blocks to read
* \param[in] BlockSize Size in bytes of each block within the device
* \param[out] BlockBuffer Pointer to where the read data from the device should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
const uint32_t BlockAddress, const uint8_t Blocks, const uint16_t BlockSize,
void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
/** Writes blocks of data to the attached Mass Storage device's medium.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] BlockAddress Starting block address within the device to write to
* \param[in] Blocks Total number of blocks to read
* \param[in] BlockSize Size in bytes of each block within the device
* \param[in] BlockBuffer Pointer to where the data to write should be sourced from
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, const uint8_t LUNIndex,
const uint32_t BlockAddress, const uint8_t Blocks, const uint16_t BlockSize,
const void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
/* Inline Functions: */
/** General management task for a given Mass Storage host class interface, required for the correct operation of
* the interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state
*/
static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo);
static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
{
(void)MSInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define MASS_STORE_CLASS 0x08
#define MASS_STORE_SUBCLASS 0x06
#define MASS_STORE_PROTOCOL 0x50
#define REQ_MassStorageReset 0xFF
#define REQ_GetMaxLUN 0xFE
#define CBW_SIGNATURE 0x43425355UL
#define CSW_SIGNATURE 0x53425355UL
#define COMMAND_DIRECTION_DATA_OUT (0 << 7)
#define COMMAND_DIRECTION_DATA_IN (1 << 7)
#define COMMAND_DATA_TIMEOUT_MS 10000
#define MS_FOUND_DATAPIPE_IN (1 << 0)
#define MS_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_MS_CLASS_HOST_C)
static uint8_t DComp_NextMSInterface(void* const CurrentDescriptor);
static uint8_t DComp_NextMSInterfaceEndpoint(void* const CurrentDescriptor);
static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
MS_CommandBlockWrapper_t* const SCSICommandBlock,
const void* const BufferPtr);
static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo);
static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
MS_CommandBlockWrapper_t* const SCSICommandBlock, void* BufferPtr);
static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
MS_CommandStatusWrapper_t* const SCSICommandStatus);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,250 +1,250 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_PRINTER_CLASS_HOST_C
#define __INCLUDE_FROM_PRINTER_DRIVER
#include "Printer.h"
uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor)
{
uint8_t FoundEndpoints = 0;
memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
return PRNT_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return PRNT_ENUMERROR_NoPrinterInterfaceFound;
}
USB_Descriptor_Interface_t* PrinterInterface = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Interface_t);
PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber;
PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting;
while (FoundEndpoints != (PRNT_FOUND_DATAPIPE_IN | PRNT_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return PRNT_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PRNTInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
PRNTInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= PRNT_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PRNTInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
PRNTInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= PRNT_FOUND_DATAPIPE_OUT;
}
}
PRNTInterfaceInfo->State.IsActive = true;
return PRNT_ENUMERROR_NoError;
}
static uint8_t DComp_NextPRNTInterface(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == PRINTER_CLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == PRINTER_SUBCLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == PRINTER_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_NextPRNTInterfaceEndpoint(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
uint8_t EndpointType = (DESCRIPTOR_CAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t).Attributes & EP_TYPE_MASK);
if (EndpointType == EP_TYPE_BULK)
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
{
if (PRNTInterfaceInfo->State.AlternateSetting)
{
uint8_t ErrorCode;
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
.bRequest = REQ_SetInterface,
.wValue = PRNTInterfaceInfo->State.AlternateSetting,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
}
return HOST_SENDCONTROL_Successful;
}
uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint8_t* const PortStatus)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_GetPortStatus,
.wValue = 0,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = sizeof(uint8_t),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(PortStatus);
}
uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SoftReset,
.wValue = 0,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL);
}
uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, void* PrinterCommands, uint16_t CommandSize)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(PrinterCommands, CommandSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearOUT();
while (!(Pipe_IsOUTReady()))
{
if (USB_HostState == HOST_STATE_Unattached)
return PIPE_RWSTREAM_DeviceDisconnected;
}
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, char* DeviceIDString, uint16_t BufferSize)
{
uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
uint16_t DeviceIDStringLength = 0;
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_GetDeviceID,
.wValue = 0,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = sizeof(DeviceIDStringLength),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
if (!(DeviceIDStringLength))
{
DeviceIDString[0] = 0x00;
return HOST_SENDCONTROL_Successful;
}
DeviceIDStringLength = SwapEndian_16(DeviceIDStringLength);
if (DeviceIDStringLength > BufferSize)
DeviceIDStringLength = BufferSize;
USB_ControlRequest.wLength = DeviceIDStringLength;
if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2);
DeviceIDString[DeviceIDStringLength - 2] = 0x00;
return HOST_SENDCONTROL_Successful;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_PRINTER_CLASS_HOST_C
#define __INCLUDE_FROM_PRINTER_DRIVER
#include "Printer.h"
uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor)
{
uint8_t FoundEndpoints = 0;
memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
return PRNT_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return PRNT_ENUMERROR_NoPrinterInterfaceFound;
}
USB_Descriptor_Interface_t* PrinterInterface = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Interface_t);
PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber;
PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting;
while (FoundEndpoints != (PRNT_FOUND_DATAPIPE_IN | PRNT_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return PRNT_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PRNTInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
PRNTInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= PRNT_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PRNTInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
PRNTInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= PRNT_FOUND_DATAPIPE_OUT;
}
}
PRNTInterfaceInfo->State.IsActive = true;
return PRNT_ENUMERROR_NoError;
}
static uint8_t DComp_NextPRNTInterface(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == PRINTER_CLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == PRINTER_SUBCLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == PRINTER_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_NextPRNTInterfaceEndpoint(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
uint8_t EndpointType = (DESCRIPTOR_CAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t).Attributes & EP_TYPE_MASK);
if (EndpointType == EP_TYPE_BULK)
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
{
if (PRNTInterfaceInfo->State.AlternateSetting)
{
uint8_t ErrorCode;
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
.bRequest = REQ_SetInterface,
.wValue = PRNTInterfaceInfo->State.AlternateSetting,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
}
return HOST_SENDCONTROL_Successful;
}
uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint8_t* const PortStatus)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_GetPortStatus,
.wValue = 0,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = sizeof(uint8_t),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(PortStatus);
}
uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SoftReset,
.wValue = 0,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL);
}
uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, void* PrinterCommands, uint16_t CommandSize)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(PrinterCommands, CommandSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearOUT();
while (!(Pipe_IsOUTReady()))
{
if (USB_HostState == HOST_STATE_Unattached)
return PIPE_RWSTREAM_DeviceDisconnected;
}
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, char* DeviceIDString, uint16_t BufferSize)
{
uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
uint16_t DeviceIDStringLength = 0;
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_GetDeviceID,
.wValue = 0,
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
.wLength = sizeof(DeviceIDStringLength),
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
if (!(DeviceIDStringLength))
{
DeviceIDString[0] = 0x00;
return HOST_SENDCONTROL_Successful;
}
DeviceIDStringLength = SwapEndian_16(DeviceIDStringLength);
if (DeviceIDStringLength > BufferSize)
DeviceIDStringLength = BufferSize;
USB_ControlRequest.wLength = DeviceIDStringLength;
if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2);
DeviceIDString[DeviceIDStringLength - 2] = 0x00;
return HOST_SENDCONTROL_Successful;
}
#endif

View file

@ -1,233 +1,233 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB Printer Class driver.
*
* Host mode driver for the library USB Printer Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Printer.h.
*/
/** \ingroup Group_USBClassPrinter
* @defgroup Group_USBClassPrinterHost Printer Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/Printer.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Printer USB Class driver.
*
* @{
*/
#ifndef __PRINTER_CLASS_HOST_H__
#define __PRINTER_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/Printer.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Printer.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief Printer Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the Printer class driver functions as the PRNTInterfaceInfo parameter. This
* stores each Printer interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the Printer interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the Printer interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the Printer interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the Printer interface's OUT data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref PRNT_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t InterfaceNumber; /**< Interface index of the Printer interface within the attached device */
uint8_t AlternateSetting; /**< Alternate setting within the Printer Interface in the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the Printer interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the Printer interface's OUT data pipe */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_PRNT_Host_t;
/* Enums: */
enum PRNTHost_EnumerationFailure_ErrorCodes_t
{
PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
PRNT_ENUMERROR_NoPrinterInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor */
PRNT_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Printer endpoints were not found in the device's interfaces */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given Printer host interface instance using the
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Printer
* instance's state values and configures the pipes required to communicate with the interface if it is found within
* the device. This should be called once after the stack has enumerated the attached device, while the host state
* machine is in the Addressed state.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref PRNTHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Configures the printer to enable Bidirectional mode, if it is not already in this mode. This should be called
* once the connected device's configuration has been set, to ensure the printer is ready to accept commands.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Retrieves the status of the virtual Printer port's inbound status lines. The result can then be masked against the
* PRNT_PORTSTATUS_* macros to determine the printer port's status.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[out] PortStatus Location where the retrieved port status should be stored
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint8_t* const PortStatus)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Soft-resets the attached printer, readying it for new commands.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends the given raw data stream to the attached printer's input endpoint. This should contain commands that the
* printer is able to understand - for example, PCL data. Not all printers accept all printer languages; see
* \ref PRNT_Host_GetDeviceID() for details on determining acceptable languages for an attached printer.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[in] PrinterCommands Pointer to a buffer containing the raw command stream to send to the printer
* \param[in] CommandSize Size in bytes of the command stream to be sent
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, void* PrinterCommands,
uint16_t CommandSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the attached printer device's ID string, formatted according to IEEE 1284. This string is sent as a
* Unicode string from the device and is automatically converted to an ASCII encoded C string by this function, thus
* the maximum reportable string length is two less than the size given (to accommodate the Unicode string length
* bytes which are removed).
*
* This string, when supported, contains the model, manufacturer and acceptable printer languages for the attached device.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[out] DeviceIDString Pointer to a buffer where the Device ID string should be stored, in ASCII format
* \param[in] BufferSize Size in bytes of the buffer allocated for the Device ID string
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, char* DeviceIDString,
uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(1);
/* Inline Functions: */
/** General management task for a given Printer host class interface, required for the correct operation of
* the interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
*/
static inline void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo);
static inline void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
{
(void)PRNTInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define PRINTER_CLASS 0x07
#define PRINTER_SUBCLASS 0x01
#define PRINTER_PROTOCOL 0x02
#define REQ_GetDeviceID 0
#define REQ_GetPortStatus 1
#define REQ_SoftReset 2
#define PRNT_FOUND_DATAPIPE_IN (1 << 0)
#define PRNT_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_PRINTER_CLASS_HOST_C)
static uint8_t DComp_NextPRNTInterface(void* const CurrentDescriptor);
static uint8_t DComp_NextPRNTInterfaceEndpoint(void* const CurrentDescriptor);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB Printer Class driver.
*
* Host mode driver for the library USB Printer Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/Printer.h.
*/
/** \ingroup Group_USBClassPrinter
* @defgroup Group_USBClassPrinterHost Printer Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/Printer.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Printer USB Class driver.
*
* @{
*/
#ifndef __PRINTER_CLASS_HOST_H__
#define __PRINTER_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/Printer.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/Printer.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief Printer Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the Printer class driver functions as the PRNTInterfaceInfo parameter. This
* stores each Printer interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the Printer interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the Printer interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the Printer interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the Printer interface's OUT data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref PRNT_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t InterfaceNumber; /**< Interface index of the Printer interface within the attached device */
uint8_t AlternateSetting; /**< Alternate setting within the Printer Interface in the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the Printer interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the Printer interface's OUT data pipe */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_PRNT_Host_t;
/* Enums: */
enum PRNTHost_EnumerationFailure_ErrorCodes_t
{
PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
PRNT_ENUMERROR_NoPrinterInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor */
PRNT_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Printer endpoints were not found in the device's interfaces */
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given Printer host interface instance using the
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Printer
* instance's state values and configures the pipes required to communicate with the interface if it is found within
* the device. This should be called once after the stack has enumerated the attached device, while the host state
* machine is in the Addressed state.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref PRNTHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Configures the printer to enable Bidirectional mode, if it is not already in this mode. This should be called
* once the connected device's configuration has been set, to ensure the printer is ready to accept commands.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Retrieves the status of the virtual Printer port's inbound status lines. The result can then be masked against the
* PRNT_PORTSTATUS_* macros to determine the printer port's status.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[out] PortStatus Location where the retrieved port status should be stored
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint8_t* const PortStatus)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Soft-resets the attached printer, readying it for new commands.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends the given raw data stream to the attached printer's input endpoint. This should contain commands that the
* printer is able to understand - for example, PCL data. Not all printers accept all printer languages; see
* \ref PRNT_Host_GetDeviceID() for details on determining acceptable languages for an attached printer.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[in] PrinterCommands Pointer to a buffer containing the raw command stream to send to the printer
* \param[in] CommandSize Size in bytes of the command stream to be sent
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, void* PrinterCommands,
uint16_t CommandSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Retrieves the attached printer device's ID string, formatted according to IEEE 1284. This string is sent as a
* Unicode string from the device and is automatically converted to an ASCII encoded C string by this function, thus
* the maximum reportable string length is two less than the size given (to accommodate the Unicode string length
* bytes which are removed).
*
* This string, when supported, contains the model, manufacturer and acceptable printer languages for the attached device.
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
* \param[out] DeviceIDString Pointer to a buffer where the Device ID string should be stored, in ASCII format
* \param[in] BufferSize Size in bytes of the buffer allocated for the Device ID string
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, char* DeviceIDString,
uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(1);
/* Inline Functions: */
/** General management task for a given Printer host class interface, required for the correct operation of
* the interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
*/
static inline void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo);
static inline void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
{
(void)PRNTInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define PRINTER_CLASS 0x07
#define PRINTER_SUBCLASS 0x01
#define PRINTER_PROTOCOL 0x02
#define REQ_GetDeviceID 0
#define REQ_GetPortStatus 1
#define REQ_SoftReset 2
#define PRNT_FOUND_DATAPIPE_IN (1 << 0)
#define PRNT_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_PRINTER_CLASS_HOST_C)
static uint8_t DComp_NextPRNTInterface(void* const CurrentDescriptor);
static uint8_t DComp_NextPRNTInterfaceEndpoint(void* const CurrentDescriptor);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,467 +1,467 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_RNDIS_CLASS_HOST_C
#define __INCLUDE_FROM_RNDIS_DRIVER
#include "RNDIS.h"
uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return RNDIS_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_NoRNDISInterfaceFound;
}
RNDISInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber;
while (FoundEndpoints != (RNDIS_FOUND_NOTIFICATION_IN | RNDIS_FOUND_DATAPIPE_IN | RNDIS_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
if (FoundEndpoints & RNDIS_FOUND_NOTIFICATION_IN)
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_NoRNDISInterfaceFound;
}
}
else
{
FoundEndpoints = 0;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(RNDISInterfaceInfo->Config.NotificationPipeNumber);
Pipe_DisablePipe();
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_NoRNDISInterfaceFound;
}
}
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_EndpointsNotFound;
}
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
RNDISInterfaceInfo->State.NotificationPipeSize = EndpointData->EndpointSize;
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
FoundEndpoints |= RNDIS_FOUND_NOTIFICATION_IN;
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
RNDISInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= RNDIS_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
RNDISInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= RNDIS_FOUND_DATAPIPE_OUT;
}
}
}
RNDISInterfaceInfo->State.IsActive = true;
return RNDIS_ENUMERROR_NoError;
}
static uint8_t DComp_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == RNDIS_CONTROL_CLASS) &&
(CurrentInterface->SubClass == RNDIS_CONTROL_SUBCLASS) &&
(CurrentInterface->Protocol == RNDIS_CONTROL_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == RNDIS_DATA_CLASS) &&
(CurrentInterface->SubClass == RNDIS_DATA_SUBCLASS) &&
(CurrentInterface->Protocol == RNDIS_DATA_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
{
return DESCRIPTOR_SEARCH_Found;
}
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SendEncapsulatedCommand,
.wValue = 0,
.wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
.wLength = Length,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_GetEncapsulatedResponse,
.wValue = 0,
.wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
.wLength = Length,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
uint8_t ErrorCode;
RNDIS_KeepAlive_Message_t KeepAliveMessage;
RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse;
KeepAliveMessage.MessageType = REMOTE_NDIS_KEEPALIVE_MSG;
KeepAliveMessage.MessageLength = sizeof(RNDIS_KeepAlive_Message_t);
KeepAliveMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &KeepAliveMessage,
sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &KeepAliveMessageResponse,
sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
return HOST_SENDCONTROL_Successful;
}
uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
uint8_t ErrorCode;
RNDIS_Initialize_Message_t InitMessage;
RNDIS_Initialize_Complete_t InitMessageResponse;
InitMessage.MessageType = REMOTE_NDIS_INITIALIZE_MSG;
InitMessage.MessageLength = sizeof(RNDIS_Initialize_Message_t);
InitMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
InitMessage.MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
InitMessage.MinorVersion = REMOTE_NDIS_VERSION_MINOR;
InitMessage.MaxTransferSize = RNDISInterfaceInfo->Config.HostMaxPacketSize;
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &InitMessage,
sizeof(RNDIS_Initialize_Message_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &InitMessageResponse,
sizeof(RNDIS_Initialize_Complete_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if (InitMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
return RNDIS_COMMAND_FAILED;
RNDISInterfaceInfo->State.DeviceMaxPacketSize = InitMessageResponse.MaxTransferSize;
return HOST_SENDCONTROL_Successful;
}
uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer, uint16_t Length)
{
uint8_t ErrorCode;
struct
{
RNDIS_Set_Message_t SetMessage;
uint8_t ContigiousBuffer[Length];
} SetMessageData;
RNDIS_Set_Complete_t SetMessageResponse;
SetMessageData.SetMessage.MessageType = REMOTE_NDIS_SET_MSG;
SetMessageData.SetMessage.MessageLength = sizeof(RNDIS_Set_Message_t) + Length;
SetMessageData.SetMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
SetMessageData.SetMessage.Oid = Oid;
SetMessageData.SetMessage.InformationBufferLength = Length;
SetMessageData.SetMessage.InformationBufferOffset = (sizeof(RNDIS_Set_Message_t) - sizeof(RNDIS_Message_Header_t));
SetMessageData.SetMessage.DeviceVcHandle = 0;
memcpy(&SetMessageData.ContigiousBuffer, Buffer, Length);
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &SetMessageData,
SetMessageData.SetMessage.MessageLength)) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &SetMessageResponse,
sizeof(RNDIS_Set_Complete_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if (SetMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
return RNDIS_COMMAND_FAILED;
return HOST_SENDCONTROL_Successful;
}
uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer, uint16_t MaxLength)
{
uint8_t ErrorCode;
RNDIS_Query_Message_t QueryMessage;
struct
{
RNDIS_Query_Complete_t QueryMessageResponse;
uint8_t ContigiousBuffer[MaxLength];
} QueryMessageResponseData;
QueryMessage.MessageType = REMOTE_NDIS_QUERY_MSG;
QueryMessage.MessageLength = sizeof(RNDIS_Query_Message_t);
QueryMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
QueryMessage.Oid = Oid;
QueryMessage.InformationBufferLength = 0;
QueryMessage.InformationBufferOffset = 0;
QueryMessage.DeviceVcHandle = 0;
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &QueryMessage,
sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &QueryMessageResponseData,
sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if (QueryMessageResponseData.QueryMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
return RNDIS_COMMAND_FAILED;
memcpy(Buffer, &QueryMessageResponseData.ContigiousBuffer, MaxLength);
return HOST_SENDCONTROL_Successful;
}
bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
bool PacketWaiting;
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
return false;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
PacketWaiting = Pipe_IsINReceived();
Pipe_Freeze();
return PacketWaiting;
}
uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t* PacketLength)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
if (!(Pipe_IsReadWriteAllowed()))
{
if (Pipe_IsINReceived())
Pipe_ClearIN();
*PacketLength = 0;
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
RNDIS_Packet_Message_t DeviceMessage;
if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
{
return ErrorCode;
}
*PacketLength = (uint16_t)DeviceMessage.DataLength;
Pipe_Discard_Stream(DeviceMessage.DataOffset - (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)),
NO_STREAM_CALLBACK);
Pipe_Read_Stream_LE(Buffer, *PacketLength, NO_STREAM_CALLBACK);
if (!(Pipe_BytesInPipe()))
Pipe_ClearIN();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t PacketLength)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
RNDIS_Packet_Message_t DeviceMessage;
memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t));
DeviceMessage.MessageType = REMOTE_NDIS_PACKET_MSG;
DeviceMessage.MessageLength = (sizeof(RNDIS_Packet_Message_t) + PacketLength);
DeviceMessage.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
DeviceMessage.DataLength = PacketLength;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
{
return ErrorCode;
}
Pipe_Write_Stream_LE(Buffer, PacketLength, NO_STREAM_CALLBACK);
Pipe_ClearOUT();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_RNDIS_CLASS_HOST_C
#define __INCLUDE_FROM_RNDIS_DRIVER
#include "RNDIS.h"
uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint16_t ConfigDescriptorSize,
void* ConfigDescriptorData)
{
uint8_t FoundEndpoints = 0;
memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return RNDIS_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_NoRNDISInterfaceFound;
}
RNDISInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber;
while (FoundEndpoints != (RNDIS_FOUND_NOTIFICATION_IN | RNDIS_FOUND_DATAPIPE_IN | RNDIS_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
if (FoundEndpoints & RNDIS_FOUND_NOTIFICATION_IN)
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_NoRNDISInterfaceFound;
}
}
else
{
FoundEndpoints = 0;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(RNDISInterfaceInfo->Config.NotificationPipeNumber);
Pipe_DisablePipe();
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_NoRNDISInterfaceFound;
}
}
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return RNDIS_ENUMERROR_EndpointsNotFound;
}
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
RNDISInterfaceInfo->State.NotificationPipeSize = EndpointData->EndpointSize;
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
FoundEndpoints |= RNDIS_FOUND_NOTIFICATION_IN;
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
RNDISInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= RNDIS_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
RNDISInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= RNDIS_FOUND_DATAPIPE_OUT;
}
}
}
RNDISInterfaceInfo->State.IsActive = true;
return RNDIS_ENUMERROR_NoError;
}
static uint8_t DComp_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == RNDIS_CONTROL_CLASS) &&
(CurrentInterface->SubClass == RNDIS_CONTROL_SUBCLASS) &&
(CurrentInterface->Protocol == RNDIS_CONTROL_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == RNDIS_DATA_CLASS) &&
(CurrentInterface->SubClass == RNDIS_DATA_SUBCLASS) &&
(CurrentInterface->Protocol == RNDIS_DATA_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
{
return DESCRIPTOR_SEARCH_Found;
}
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SendEncapsulatedCommand,
.wValue = 0,
.wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
.wLength = Length,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length)
{
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_GetEncapsulatedResponse,
.wValue = 0,
.wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
.wLength = Length,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(Buffer);
}
uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
uint8_t ErrorCode;
RNDIS_KeepAlive_Message_t KeepAliveMessage;
RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse;
KeepAliveMessage.MessageType = REMOTE_NDIS_KEEPALIVE_MSG;
KeepAliveMessage.MessageLength = sizeof(RNDIS_KeepAlive_Message_t);
KeepAliveMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &KeepAliveMessage,
sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &KeepAliveMessageResponse,
sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
return HOST_SENDCONTROL_Successful;
}
uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
uint8_t ErrorCode;
RNDIS_Initialize_Message_t InitMessage;
RNDIS_Initialize_Complete_t InitMessageResponse;
InitMessage.MessageType = REMOTE_NDIS_INITIALIZE_MSG;
InitMessage.MessageLength = sizeof(RNDIS_Initialize_Message_t);
InitMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
InitMessage.MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
InitMessage.MinorVersion = REMOTE_NDIS_VERSION_MINOR;
InitMessage.MaxTransferSize = RNDISInterfaceInfo->Config.HostMaxPacketSize;
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &InitMessage,
sizeof(RNDIS_Initialize_Message_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &InitMessageResponse,
sizeof(RNDIS_Initialize_Complete_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if (InitMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
return RNDIS_COMMAND_FAILED;
RNDISInterfaceInfo->State.DeviceMaxPacketSize = InitMessageResponse.MaxTransferSize;
return HOST_SENDCONTROL_Successful;
}
uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer, uint16_t Length)
{
uint8_t ErrorCode;
struct
{
RNDIS_Set_Message_t SetMessage;
uint8_t ContigiousBuffer[Length];
} SetMessageData;
RNDIS_Set_Complete_t SetMessageResponse;
SetMessageData.SetMessage.MessageType = REMOTE_NDIS_SET_MSG;
SetMessageData.SetMessage.MessageLength = sizeof(RNDIS_Set_Message_t) + Length;
SetMessageData.SetMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
SetMessageData.SetMessage.Oid = Oid;
SetMessageData.SetMessage.InformationBufferLength = Length;
SetMessageData.SetMessage.InformationBufferOffset = (sizeof(RNDIS_Set_Message_t) - sizeof(RNDIS_Message_Header_t));
SetMessageData.SetMessage.DeviceVcHandle = 0;
memcpy(&SetMessageData.ContigiousBuffer, Buffer, Length);
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &SetMessageData,
SetMessageData.SetMessage.MessageLength)) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &SetMessageResponse,
sizeof(RNDIS_Set_Complete_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if (SetMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
return RNDIS_COMMAND_FAILED;
return HOST_SENDCONTROL_Successful;
}
uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer, uint16_t MaxLength)
{
uint8_t ErrorCode;
RNDIS_Query_Message_t QueryMessage;
struct
{
RNDIS_Query_Complete_t QueryMessageResponse;
uint8_t ContigiousBuffer[MaxLength];
} QueryMessageResponseData;
QueryMessage.MessageType = REMOTE_NDIS_QUERY_MSG;
QueryMessage.MessageLength = sizeof(RNDIS_Query_Message_t);
QueryMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
QueryMessage.Oid = Oid;
QueryMessage.InformationBufferLength = 0;
QueryMessage.InformationBufferOffset = 0;
QueryMessage.DeviceVcHandle = 0;
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &QueryMessage,
sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &QueryMessageResponseData,
sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful)
{
return ErrorCode;
}
if (QueryMessageResponseData.QueryMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
return RNDIS_COMMAND_FAILED;
memcpy(Buffer, &QueryMessageResponseData.ContigiousBuffer, MaxLength);
return HOST_SENDCONTROL_Successful;
}
bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
bool PacketWaiting;
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
return false;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
PacketWaiting = Pipe_IsINReceived();
Pipe_Freeze();
return PacketWaiting;
}
uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t* PacketLength)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();
if (!(Pipe_IsReadWriteAllowed()))
{
if (Pipe_IsINReceived())
Pipe_ClearIN();
*PacketLength = 0;
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
RNDIS_Packet_Message_t DeviceMessage;
if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
{
return ErrorCode;
}
*PacketLength = (uint16_t)DeviceMessage.DataLength;
Pipe_Discard_Stream(DeviceMessage.DataOffset - (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)),
NO_STREAM_CALLBACK);
Pipe_Read_Stream_LE(Buffer, *PacketLength, NO_STREAM_CALLBACK);
if (!(Pipe_BytesInPipe()))
Pipe_ClearIN();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t PacketLength)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
RNDIS_Packet_Message_t DeviceMessage;
memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t));
DeviceMessage.MessageType = REMOTE_NDIS_PACKET_MSG;
DeviceMessage.MessageLength = (sizeof(RNDIS_Packet_Message_t) + PacketLength);
DeviceMessage.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
DeviceMessage.DataLength = PacketLength;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
{
return ErrorCode;
}
Pipe_Write_Stream_LE(Buffer, PacketLength, NO_STREAM_CALLBACK);
Pipe_ClearOUT();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
#endif

View file

@ -1,283 +1,283 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB RNDIS Class driver.
*
* Host mode driver for the library USB RNDIS Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/RNDIS.h.
*/
/** \ingroup Group_USBClassRNDIS
* @defgroup Group_USBClassRNDISHost RNDIS Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/RNDIS.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Microsoft RNDIS Ethernet
* USB Class driver.
*
* @{
*/
#ifndef __RNDIS_CLASS_HOST_H__
#define __RNDIS_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/RNDIS.h"
#include <stdio.h>
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/RNDIS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief RNDIS Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the RNDIS class driver functions as the RNDISInterfaceInfo parameter. This
* stores each RNDIS interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the RNDIS interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the RNDIS interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the RNDIS interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the RNDIS interface's OUT data pipe should use double banking */
uint8_t NotificationPipeNumber; /**< Pipe number of the RNDIS interface's IN notification endpoint, if used */
bool NotificationPipeDoubleBank; /** Indicates if the RNDIS interface's notification pipe should use double banking */
uint32_t HostMaxPacketSize; /**< Maximum size of a packet which can be buffered by the host */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref RNDIS_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t ControlInterfaceNumber; /**< Interface index of the RNDIS control interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the RNDIS interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the RNDIS interface's OUT data pipe */
uint16_t NotificationPipeSize; /**< Size in bytes of the RNDIS interface's IN notification pipe, if used */
uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device */
uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_RNDIS_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref RNDIS_Host_ConfigurePipes() function. */
enum RNDISHost_EnumerationFailure_ErrorCodes_t
{
RNDIS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
RNDIS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
RNDIS_ENUMERROR_NoRNDISInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor */
RNDIS_ENUMERROR_EndpointsNotFound = 3, /**< Compatible RNDIS endpoints were not found in the device's RNDIS interface */
};
/* Macros: */
/** Additional error code for RNDIS functions when a device returns a logical command failure */
#define RNDIS_COMMAND_FAILED 0xC0
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given RNDIS host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given RNDIS Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the device.
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
* the Addressed state.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref RNDISHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sends a RNDIS KEEPALIVE command to the device, to ensure that it does not enter standby mode after periods
* of long inactivity.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Initializes the attached RNDIS device's RNDIS interface. This should be called after the device's pipes have been
* configured via the call to \ref RNDIS_Host_ConfigurePipes().
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sets a given RNDIS property of an attached RNDIS device.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] Oid OID number of the parameter to set
* \param[in] Buffer Pointer to where the property data is to be sourced from
* \param[in] Length Length in bytes of the property data to sent to the device
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer,
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Gets a given RNDIS property of an attached RNDIS device.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] Oid OID number of the parameter to get
* \param[in] Buffer Pointer to where the property data is to be written to
* \param[in] MaxLength Length in bytes of the destination buffer size
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer,
uint16_t MaxLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Determines if a packet is currently waiting for the host to read in and process.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*
* \return Boolean true if a packet is waiting to be read in by the host, false otherwise
*/
bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo);
/** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave
* only the packet contents for processing by the host in the nominated buffer.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[out] Buffer Pointer to a buffer where the packer data is to be written to
* \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored
*
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t* PacketLength)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3);
/** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] Buffer Pointer to a buffer where the packer data is to be read from
* \param[in] PacketLength Length in bytes of the packet to send
*
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t PacketLength)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given RNDIS host class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*/
static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo);
static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
(void)RNDISInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define RNDIS_CONTROL_CLASS 0x02
#define RNDIS_CONTROL_SUBCLASS 0x02
#define RNDIS_CONTROL_PROTOCOL 0xFF
#define RNDIS_DATA_CLASS 0x0A
#define RNDIS_DATA_SUBCLASS 0x00
#define RNDIS_DATA_PROTOCOL 0x00
#define RNDIS_FOUND_DATAPIPE_IN (1 << 0)
#define RNDIS_FOUND_DATAPIPE_OUT (1 << 1)
#define RNDIS_FOUND_NOTIFICATION_IN (1 << 2)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_RNDIS_CLASS_HOST_C)
static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB RNDIS Class driver.
*
* Host mode driver for the library USB RNDIS Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/RNDIS.h.
*/
/** \ingroup Group_USBClassRNDIS
* @defgroup Group_USBClassRNDISHost RNDIS Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/RNDIS.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Microsoft RNDIS Ethernet
* USB Class driver.
*
* @{
*/
#ifndef __RNDIS_CLASS_HOST_H__
#define __RNDIS_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/RNDIS.h"
#include <stdio.h>
#include <string.h>
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/RNDIS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** \brief RNDIS Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the RNDIS class driver functions as the RNDISInterfaceInfo parameter. This
* stores each RNDIS interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the RNDIS interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the RNDIS interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the RNDIS interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the RNDIS interface's OUT data pipe should use double banking */
uint8_t NotificationPipeNumber; /**< Pipe number of the RNDIS interface's IN notification endpoint, if used */
bool NotificationPipeDoubleBank; /** Indicates if the RNDIS interface's notification pipe should use double banking */
uint32_t HostMaxPacketSize; /**< Maximum size of a packet which can be buffered by the host */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref RNDIS_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t ControlInterfaceNumber; /**< Interface index of the RNDIS control interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the RNDIS interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the RNDIS interface's OUT data pipe */
uint16_t NotificationPipeSize; /**< Size in bytes of the RNDIS interface's IN notification pipe, if used */
uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device */
uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_RNDIS_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref RNDIS_Host_ConfigurePipes() function. */
enum RNDISHost_EnumerationFailure_ErrorCodes_t
{
RNDIS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
RNDIS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
RNDIS_ENUMERROR_NoRNDISInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor */
RNDIS_ENUMERROR_EndpointsNotFound = 3, /**< Compatible RNDIS endpoints were not found in the device's RNDIS interface */
};
/* Macros: */
/** Additional error code for RNDIS functions when a device returns a logical command failure */
#define RNDIS_COMMAND_FAILED 0xC0
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given RNDIS host interface instance using the Configuration
* Descriptor read from an attached USB device. This function automatically updates the given RNDIS Host instance's
* state values and configures the pipes required to communicate with the interface if it is found within the device.
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
* the Addressed state.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref RNDISHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Sends a RNDIS KEEPALIVE command to the device, to ensure that it does not enter standby mode after periods
* of long inactivity.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Initializes the attached RNDIS device's RNDIS interface. This should be called after the device's pipes have been
* configured via the call to \ref RNDIS_Host_ConfigurePipes().
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sets a given RNDIS property of an attached RNDIS device.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] Oid OID number of the parameter to set
* \param[in] Buffer Pointer to where the property data is to be sourced from
* \param[in] Length Length in bytes of the property data to sent to the device
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer,
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Gets a given RNDIS property of an attached RNDIS device.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] Oid OID number of the parameter to get
* \param[in] Buffer Pointer to where the property data is to be written to
* \param[in] MaxLength Length in bytes of the destination buffer size
*
* \return A value from the USB_Host_SendControlErrorCodes_t enum or RNDIS_COMMAND_FAILED if the device returned a
* logical command failure
*/
uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, uint32_t Oid, void* Buffer,
uint16_t MaxLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Determines if a packet is currently waiting for the host to read in and process.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*
* \return Boolean true if a packet is waiting to be read in by the host, false otherwise
*/
bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo);
/** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave
* only the packet contents for processing by the host in the nominated buffer.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[out] Buffer Pointer to a buffer where the packer data is to be written to
* \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored
*
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t* PacketLength)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3);
/** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
* \param[in] Buffer Pointer to a buffer where the packer data is to be read from
* \param[in] PacketLength Length in bytes of the packet to send
*
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, void* Buffer, uint16_t PacketLength)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given RNDIS host class interface, required for the correct operation of the interface. This should
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
*
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state
*/
static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo);
static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
{
(void)RNDISInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define RNDIS_CONTROL_CLASS 0x02
#define RNDIS_CONTROL_SUBCLASS 0x02
#define RNDIS_CONTROL_PROTOCOL 0xFF
#define RNDIS_DATA_CLASS 0x0A
#define RNDIS_DATA_SUBCLASS 0x00
#define RNDIS_DATA_PROTOCOL 0x00
#define RNDIS_FOUND_DATAPIPE_IN (1 << 0)
#define RNDIS_FOUND_DATAPIPE_OUT (1 << 1)
#define RNDIS_FOUND_NOTIFICATION_IN (1 << 2)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_RNDIS_CLASS_HOST_C)
static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,413 +1,413 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_SI_CLASS_HOST_C
#define __INCLUDE_FROM_SI_DRIVER
#include "StillImage.h"
uint8_t SImage_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor)
{
uint8_t FoundEndpoints = 0;
memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State));
if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
return SI_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return SI_ENUMERROR_NoSIInterfaceFound;
}
while (FoundEndpoints != (SI_FOUND_EVENTS_IN | SI_FOUND_DATAPIPE_IN | SI_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_SI_Host_NextSIInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return SI_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t);
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(SIInterfaceInfo->Config.EventsPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
SIInterfaceInfo->Config.EventsPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
SIInterfaceInfo->State.EventsPipeSize = EndpointData->EndpointSize;
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
FoundEndpoints |= SI_FOUND_EVENTS_IN;
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(SIInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
SIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
SIInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= SI_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(SIInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
SIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
SIInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= SI_FOUND_DATAPIPE_OUT;
}
}
}
SIInterfaceInfo->State.IsActive = true;
return SI_ENUMERROR_NoError;
}
uint8_t DComp_SI_Host_NextSIInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == STILL_IMAGE_CLASS) &&
(CurrentInterface->SubClass == STILL_IMAGE_SUBCLASS) &&
(CurrentInterface->Protocol == STILL_IMAGE_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t DComp_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
(!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress))))
{
return DESCRIPTOR_SEARCH_Found;
}
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
if (SIInterfaceInfo->State.IsSessionOpen)
PIMAHeader->TransactionID = SIInterfaceInfo->State.TransactionID++;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
if (ParamBytes)
{
if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
}
Pipe_ClearOUT();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader)
{
uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
while (!(Pipe_IsReadWriteAllowed()))
{
if (USB_INT_HasOccurred(USB_INT_HSOFI))
{
USB_INT_Clear(USB_INT_HSOFI);
TimeoutMSRem--;
if (!(TimeoutMSRem))
{
return PIPE_RWSTREAM_Timeout;
}
}
Pipe_Freeze();
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (Pipe_IsStalled())
{
USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber);
return PIPE_RWSTREAM_PipeStalled;
}
Pipe_Freeze();
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
if (Pipe_IsStalled())
{
USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber);
return PIPE_RWSTREAM_PipeStalled;
}
if (USB_HostState == HOST_STATE_Unattached)
return PIPE_RWSTREAM_DeviceDisconnected;
}
Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK);
if (PIMAHeader->Type == CType_ResponseBlock)
{
uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
if (ParamBytes)
Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK);
Pipe_ClearIN();
}
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer, const uint16_t Bytes)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Write_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
Pipe_ClearOUT();
Pipe_Freeze();
return ErrorCode;
}
uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer, const uint16_t Bytes)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
Pipe_Freeze();
return ErrorCode;
}
bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo)
{
bool IsEventReceived = false;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return false;
Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
Pipe_Unfreeze();
if (Pipe_BytesInPipe())
IsEventReceived = true;
Pipe_Freeze();
return IsEventReceived;
}
uint8_t SImage_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Read_Stream_LE(PIMAHeader, sizeof(SI_PIMA_Container_t), NO_STREAM_CALLBACK);
Pipe_ClearIN();
Pipe_Freeze();
return ErrorCode;
}
uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
uint8_t ErrorCode;
SIInterfaceInfo->State.TransactionID = 0;
SIInterfaceInfo->State.IsSessionOpen = false;
SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t)
{
.DataLength = PIMA_COMMAND_SIZE(1),
.Type = CType_CommandBlock,
.Code = 0x1002,
.Params = {1},
};
if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED;
SIInterfaceInfo->State.IsSessionOpen = true;
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
uint8_t ErrorCode;
SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t)
{
.DataLength = PIMA_COMMAND_SIZE(1),
.Type = CType_CommandBlock,
.Code = 0x1003,
.Params = {1},
};
if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
SIInterfaceInfo->State.IsSessionOpen = false;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED;
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, const uint16_t Operation,
const uint8_t TotalParams, uint32_t* Params)
{
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
uint8_t ErrorCode;
SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t)
{
.DataLength = PIMA_COMMAND_SIZE(TotalParams),
.Type = CType_CommandBlock,
.Code = Operation,
};
memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams);
if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
uint8_t ErrorCode;
SI_PIMA_Container_t PIMABlock;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED;
return PIPE_RWSTREAM_NoError;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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.
*/
#define __INCLUDE_FROM_USB_DRIVER
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define __INCLUDE_FROM_SI_CLASS_HOST_C
#define __INCLUDE_FROM_SI_DRIVER
#include "StillImage.h"
uint8_t SImage_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor)
{
uint8_t FoundEndpoints = 0;
memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State));
if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
return SI_ENUMERROR_InvalidConfigDescriptor;
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return SI_ENUMERROR_NoSIInterfaceFound;
}
while (FoundEndpoints != (SI_FOUND_EVENTS_IN | SI_FOUND_DATAPIPE_IN | SI_FOUND_DATAPIPE_OUT))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
DComp_SI_Host_NextSIInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return SI_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t);
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(SIInterfaceInfo->Config.EventsPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
SIInterfaceInfo->Config.EventsPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
SIInterfaceInfo->State.EventsPipeSize = EndpointData->EndpointSize;
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
FoundEndpoints |= SI_FOUND_EVENTS_IN;
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(SIInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
SIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
SIInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= SI_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(SIInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
SIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
SIInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= SI_FOUND_DATAPIPE_OUT;
}
}
}
SIInterfaceInfo->State.IsActive = true;
return SI_ENUMERROR_NoError;
}
uint8_t DComp_SI_Host_NextSIInterface(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if ((CurrentInterface->Class == STILL_IMAGE_CLASS) &&
(CurrentInterface->SubClass == STILL_IMAGE_SUBCLASS) &&
(CurrentInterface->Protocol == STILL_IMAGE_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t DComp_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
(!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress))))
{
return DESCRIPTOR_SEARCH_Found;
}
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
uint8_t SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
if (SIInterfaceInfo->State.IsSessionOpen)
PIMAHeader->TransactionID = SIInterfaceInfo->State.TransactionID++;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
if (ParamBytes)
{
if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
}
Pipe_ClearOUT();
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader)
{
uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
while (!(Pipe_IsReadWriteAllowed()))
{
if (USB_INT_HasOccurred(USB_INT_HSOFI))
{
USB_INT_Clear(USB_INT_HSOFI);
TimeoutMSRem--;
if (!(TimeoutMSRem))
{
return PIPE_RWSTREAM_Timeout;
}
}
Pipe_Freeze();
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
if (Pipe_IsStalled())
{
USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber);
return PIPE_RWSTREAM_PipeStalled;
}
Pipe_Freeze();
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
if (Pipe_IsStalled())
{
USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber);
return PIPE_RWSTREAM_PipeStalled;
}
if (USB_HostState == HOST_STATE_Unattached)
return PIPE_RWSTREAM_DeviceDisconnected;
}
Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK);
if (PIMAHeader->Type == CType_ResponseBlock)
{
uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
if (ParamBytes)
Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK);
Pipe_ClearIN();
}
Pipe_Freeze();
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer, const uint16_t Bytes)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Write_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
Pipe_ClearOUT();
Pipe_Freeze();
return ErrorCode;
}
uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer, const uint16_t Bytes)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
Pipe_Freeze();
return ErrorCode;
}
bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo)
{
bool IsEventReceived = false;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return false;
Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
Pipe_Unfreeze();
if (Pipe_BytesInPipe())
IsEventReceived = true;
Pipe_Freeze();
return IsEventReceived;
}
uint8_t SImage_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader)
{
uint8_t ErrorCode;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return PIPE_RWSTREAM_DeviceDisconnected;
Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
Pipe_Unfreeze();
ErrorCode = Pipe_Read_Stream_LE(PIMAHeader, sizeof(SI_PIMA_Container_t), NO_STREAM_CALLBACK);
Pipe_ClearIN();
Pipe_Freeze();
return ErrorCode;
}
uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
uint8_t ErrorCode;
SIInterfaceInfo->State.TransactionID = 0;
SIInterfaceInfo->State.IsSessionOpen = false;
SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t)
{
.DataLength = PIMA_COMMAND_SIZE(1),
.Type = CType_CommandBlock,
.Code = 0x1002,
.Params = {1},
};
if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED;
SIInterfaceInfo->State.IsSessionOpen = true;
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
uint8_t ErrorCode;
SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t)
{
.DataLength = PIMA_COMMAND_SIZE(1),
.Type = CType_CommandBlock,
.Code = 0x1003,
.Params = {1},
};
if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
SIInterfaceInfo->State.IsSessionOpen = false;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED;
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, const uint16_t Operation,
const uint8_t TotalParams, uint32_t* Params)
{
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
uint8_t ErrorCode;
SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t)
{
.DataLength = PIMA_COMMAND_SIZE(TotalParams),
.Type = CType_CommandBlock,
.Code = Operation,
};
memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams);
if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
return PIPE_RWSTREAM_NoError;
}
uint8_t SImage_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
uint8_t ErrorCode;
SI_PIMA_Container_t PIMABlock;
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnected;
if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED;
return PIPE_RWSTREAM_NoError;
}
#endif

View file

@ -1,323 +1,323 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB Still Image Class driver.
*
* Host mode driver for the library USB Still Image Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/StillImage.h.
*/
/** \ingroup Group_USBClassSI
* @defgroup Group_USBClassStillImageHost Still Image Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/StillImage.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Still Image USB Class driver.
*
* @{
*/
#ifndef __SI_CLASS_HOST_H__
#define __SI_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/StillImage.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_SI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/StillImage.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some Still Image Host functions, indicating a logical (and not hardware) error */
#define SI_ERROR_LOGICAL_CMD_FAILED 0x80
/* Type Defines: */
/** \brief Still Image Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the Still Image class driver functions as the SIInterfaceInfo parameter. This
* stores each Still Image interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the Still Image interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the Still Image interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the Still Image interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the Still Image interface's OUT data pipe should use double banking */
uint8_t EventsPipeNumber; /**< Pipe number of the Still Image interface's IN events endpoint, if used */
bool EventsPipeDoubleBank; /** Indicates if the Still Image interface's events data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref SImage_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint16_t DataINPipeSize; /**< Size in bytes of the Still Image interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the Still Image interface's OUT data pipe */
uint16_t EventsPipeSize; /**< Size in bytes of the Still Image interface's IN events pipe */
bool IsSessionOpen; /**< Indicates if a PIMA session is currently open with the attached device */
uint32_t TransactionID; /**< Transaction ID for the next transaction to send to the device */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_SI_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref SImage_Host_ConfigurePipes() function. */
enum SIHost_EnumerationFailure_ErrorCodes_t
{
SI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
SI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
SI_ENUMERROR_NoSIInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's
* Configuration Descriptor
*/
SI_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Still Image data endpoints were not found in the
* device's Still Image interface
*/
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given Still Image host interface instance using the
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Still
* Image Host instance's state values and configures the pipes required to communicate with the interface if it is
* found within the device. This should be called once after the stack has enumerated the attached device, while
* the host state machine is in the Addressed state.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref SIHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t SImage_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands
* are issued to the device. Only one session can be open at the one time.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Closes an already opened PIMA session with the attached device. This should be used after all session-orientated
* PIMA commands have been issued to the device.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a raw PIMA block header to the device, filling out the transaction ID automatically. This can be used to send
* arbitrary PIMA blocks to the device with or without parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] PIMAHeader Pointer to a PIMA container structure that is to be sent
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader);
/** Receives a raw PIMA block header to the device. This can be used to receive arbitrary PIMA blocks from the device with
* or without parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[out] PIMAHeader Pointer to a PIMA container structure where the received block is to be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader);
/** Sends a given PIMA command to the attached device, filling out the PIMA command header's Transaction ID automatically.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] Operation PIMA operation code to issue to the device
* \param[in] TotalParams Total number of 32-bit parameters to send to the device in the issued command block
* \param[in] Params Pointer to an array of 32-bit values containing the parameters to send in the command block
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, const uint16_t Operation,
const uint8_t TotalParams, uint32_t* Params) ATTR_NON_NULL_PTR_ARG(1);
/** Receives and checks a response block from the attached PIMA device, once a command has been issued and all data
* associated with the command has been transferred.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Indicates if the device has issued a PIMA event block to the host via the asynchronous events pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return Boolean true if an event is waiting to be read, false otherwise
*/
bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Receives an asynchronous event block from the device via the asynchronous events pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[out] PIMAHeader Pointer to a PIMA container structure where the event should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
SI_PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(2);
/** Sends arbitrary data to the attached device, for use in the data phase of PIMA commands which require data
* transfer beyond the regular PIMA command block parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] Buffer Pointer to a buffer where the data to send has been stored
* \param[in] Bytes Length in bytes of the data in the buffer to send to the attached device
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer,
const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Receives arbitrary data from the attached device, for use in the data phase of PIMA commands which require data
* transfer beyond the regular PIMA command block parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[out] Buffer Pointer to a buffer where the received data is to be stored
* \param[in] Bytes Length in bytes of the data to read
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer,
const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given Still Image host class interface, required for the correct operation of the
* interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*/
static inline void SImage_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo);
static inline void SImage_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
(void)SIInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define STILL_IMAGE_CLASS 0x06
#define STILL_IMAGE_SUBCLASS 0x01
#define STILL_IMAGE_PROTOCOL 0x01
#define SI_FOUND_EVENTS_IN (1 << 0)
#define SI_FOUND_DATAPIPE_IN (1 << 1)
#define SI_FOUND_DATAPIPE_OUT (1 << 2)
#define COMMAND_DATA_TIMEOUT_MS 10000
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_SI_CLASS_HOST_C)
static uint8_t DComp_SI_Host_NextSIInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Host mode driver for the library USB Still Image Class driver.
*
* Host mode driver for the library USB Still Image Class driver.
*
* \note This file should not be included directly. It is automatically included as needed by the class driver
* dispatch header located in LUFA/Drivers/USB/Class/StillImage.h.
*/
/** \ingroup Group_USBClassSI
* @defgroup Group_USBClassStillImageHost Still Image Class Host Mode Driver
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/StillImage.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the Still Image USB Class driver.
*
* @{
*/
#ifndef __SI_CLASS_HOST_H__
#define __SI_CLASS_HOST_H__
/* Includes: */
#include "../../USB.h"
#include "../Common/StillImage.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_SI_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/Class/StillImage.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some Still Image Host functions, indicating a logical (and not hardware) error */
#define SI_ERROR_LOGICAL_CMD_FAILED 0x80
/* Type Defines: */
/** \brief Still Image Class Host Mode Configuration and State Structure.
*
* Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the Still Image class driver functions as the SIInterfaceInfo parameter. This
* stores each Still Image interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the Still Image interface's IN data pipe */
bool DataINPipeDoubleBank; /** Indicates if the Still Image interface's IN data pipe should use double banking */
uint8_t DataOUTPipeNumber; /**< Pipe number of the Still Image interface's OUT data pipe */
bool DataOUTPipeDoubleBank; /** Indicates if the Still Image interface's OUT data pipe should use double banking */
uint8_t EventsPipeNumber; /**< Pipe number of the Still Image interface's IN events endpoint, if used */
bool EventsPipeDoubleBank; /** Indicates if the Still Image interface's events data pipe should use double banking */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
* after \ref SImage_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint16_t DataINPipeSize; /**< Size in bytes of the Still Image interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the Still Image interface's OUT data pipe */
uint16_t EventsPipeSize; /**< Size in bytes of the Still Image interface's IN events pipe */
bool IsSessionOpen; /**< Indicates if a PIMA session is currently open with the attached device */
uint32_t TransactionID; /**< Transaction ID for the next transaction to send to the device */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_SI_Host_t;
/* Enums: */
/** Enum for the possible error codes returned by the \ref SImage_Host_ConfigurePipes() function. */
enum SIHost_EnumerationFailure_ErrorCodes_t
{
SI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
SI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
SI_ENUMERROR_NoSIInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's
* Configuration Descriptor
*/
SI_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Still Image data endpoints were not found in the
* device's Still Image interface
*/
};
/* Function Prototypes: */
/** Host interface configuration routine, to configure a given Still Image host interface instance using the
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Still
* Image Host instance's state values and configures the pipes required to communicate with the interface if it is
* found within the device. This should be called once after the stack has enumerated the attached device, while
* the host state machine is in the Addressed state.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
*
* \return A value from the \ref SIHost_EnumerationFailure_ErrorCodes_t enum
*/
uint8_t SImage_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, uint16_t ConfigDescriptorSize,
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
/** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands
* are issued to the device. Only one session can be open at the one time.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Closes an already opened PIMA session with the attached device. This should be used after all session-orientated
* PIMA commands have been issued to the device.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a raw PIMA block header to the device, filling out the transaction ID automatically. This can be used to send
* arbitrary PIMA blocks to the device with or without parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] PIMAHeader Pointer to a PIMA container structure that is to be sent
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader);
/** Receives a raw PIMA block header to the device. This can be used to receive arbitrary PIMA blocks from the device with
* or without parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[out] PIMAHeader Pointer to a PIMA container structure where the received block is to be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader);
/** Sends a given PIMA command to the attached device, filling out the PIMA command header's Transaction ID automatically.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] Operation PIMA operation code to issue to the device
* \param[in] TotalParams Total number of 32-bit parameters to send to the device in the issued command block
* \param[in] Params Pointer to an array of 32-bit values containing the parameters to send in the command block
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, const uint16_t Operation,
const uint8_t TotalParams, uint32_t* Params) ATTR_NON_NULL_PTR_ARG(1);
/** Receives and checks a response block from the attached PIMA device, once a command has been issued and all data
* associated with the command has been transferred.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Indicates if the device has issued a PIMA event block to the host via the asynchronous events pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*
* \return Boolean true if an event is waiting to be read, false otherwise
*/
bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Receives an asynchronous event block from the device via the asynchronous events pipe.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[out] PIMAHeader Pointer to a PIMA container structure where the event should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
* returned a logical command failure
*/
uint8_t SImage_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
SI_PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
ATTR_NON_NULL_PTR_ARG(2);
/** Sends arbitrary data to the attached device, for use in the data phase of PIMA commands which require data
* transfer beyond the regular PIMA command block parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[in] Buffer Pointer to a buffer where the data to send has been stored
* \param[in] Bytes Length in bytes of the data in the buffer to send to the attached device
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer,
const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Receives arbitrary data from the attached device, for use in the data phase of PIMA commands which require data
* transfer beyond the regular PIMA command block parameters.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
* \param[out] Buffer Pointer to a buffer where the received data is to be stored
* \param[in] Bytes Length in bytes of the data to read
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
*/
uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer,
const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/* Inline Functions: */
/** General management task for a given Still Image host class interface, required for the correct operation of the
* interface. This should be called frequently in the main program loop, before the master USB management task
* \ref USB_USBTask().
*
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state
*/
static inline void SImage_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo);
static inline void SImage_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
{
(void)SIInterfaceInfo;
}
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define STILL_IMAGE_CLASS 0x06
#define STILL_IMAGE_SUBCLASS 0x01
#define STILL_IMAGE_PROTOCOL 0x01
#define SI_FOUND_EVENTS_IN (1 << 0)
#define SI_FOUND_DATAPIPE_IN (1 << 1)
#define SI_FOUND_DATAPIPE_OUT (1 << 2)
#define COMMAND_DATA_TIMEOUT_MS 10000
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_SI_CLASS_HOST_C)
static uint8_t DComp_SI_Host_NextSIInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
static uint8_t DComp_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */

View file

@ -1,86 +1,86 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB MIDI Class driver.
*
* Master include file for the library USB MIDI Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassMIDI MIDI Class Driver - LUFA/Drivers/Class/MIDI.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MIDI.c
* - LUFA/Drivers/USB/Class/Host/MIDI.c
*
* \section Module Description
* MIDI Class Driver module. This module contains an internal implementation of the USB MIDI Class, for both Device
* and Host USB modes. User applications can use this class driver instead of implementing the MIDI class manually
* via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB MIDI Class.
*
* \note The USB MIDI class is actually a special case of the regular Audio class, thus this module depends on
* structure definitions from the \ref Group_USBClassAudioDevice class driver module.
*
* @{
*/
#ifndef _MIDI_CLASS_H_
#define _MIDI_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_MIDI_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/MIDI.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/MIDI.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB MIDI Class driver.
*
* Master include file for the library USB MIDI Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassMIDI MIDI Class Driver - LUFA/Drivers/Class/MIDI.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MIDI.c
* - LUFA/Drivers/USB/Class/Host/MIDI.c
*
* \section Module Description
* MIDI Class Driver module. This module contains an internal implementation of the USB MIDI Class, for both Device
* and Host USB modes. User applications can use this class driver instead of implementing the MIDI class manually
* via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB MIDI Class.
*
* \note The USB MIDI class is actually a special case of the regular Audio class, thus this module depends on
* structure definitions from the \ref Group_USBClassAudioDevice class driver module.
*
* @{
*/
#ifndef _MIDI_CLASS_H_
#define _MIDI_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_MIDI_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/MIDI.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/MIDI.h"
#endif
#endif
/** @} */

View file

@ -1,83 +1,83 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Mass Storage Class driver.
*
* Master include file for the library USB Mass Storage Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassMS Mass Storage Class Driver - LUFA/Drivers/Class/MassStorage.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MassStorage.c
* - LUFA/Drivers/USB/Class/Host/MassStorage.c
*
* \section Module Description
* Mass Storage Class Driver module. This module contains an internal implementation of the USB Mass Storage Class, for both
* Device and Host USB modes. User applications can use this class driver instead of implementing the Mass Storage class
* manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB Mass Storage Class.
*
* @{
*/
#ifndef _MS_CLASS_H_
#define _MS_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_MS_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/MassStorage.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/MassStorage.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Mass Storage Class driver.
*
* Master include file for the library USB Mass Storage Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassMS Mass Storage Class Driver - LUFA/Drivers/Class/MassStorage.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/MassStorage.c
* - LUFA/Drivers/USB/Class/Host/MassStorage.c
*
* \section Module Description
* Mass Storage Class Driver module. This module contains an internal implementation of the USB Mass Storage Class, for both
* Device and Host USB modes. User applications can use this class driver instead of implementing the Mass Storage class
* manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts or Devices using the USB Mass Storage Class.
*
* @{
*/
#ifndef _MS_CLASS_H_
#define _MS_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_MS_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/MassStorage.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/MassStorage.h"
#endif
#endif
/** @} */

View file

@ -1,80 +1,80 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Printer Class driver.
*
* Master include file for the library USB Printer Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassPrinter Printer Class Driver - LUFA/Drivers/Class/Printer.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/Printer.c
*
* \section Module Description
* Printer Class Driver module. This module contains an internal implementation of the USB Printer Class, for the base
* USB Printer transport layer for USB Host mode only. Note that printers are free to implement whatever printer language
* they choose on top of this (e.g. Postscript), and so this driver exposes low level data transport functions only rather
* than high level raster or text functions. User applications can use this class driver instead of implementing the Printer
* class manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Devices using the USB Printer Class.
*
* @{
*/
#ifndef _PRINTER_CLASS_H_
#define _PRINTER_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_PRINTER_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/Printer.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Printer Class driver.
*
* Master include file for the library USB Printer Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassPrinter Printer Class Driver - LUFA/Drivers/Class/Printer.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/Printer.c
*
* \section Module Description
* Printer Class Driver module. This module contains an internal implementation of the USB Printer Class, for the base
* USB Printer transport layer for USB Host mode only. Note that printers are free to implement whatever printer language
* they choose on top of this (e.g. Postscript), and so this driver exposes low level data transport functions only rather
* than high level raster or text functions. User applications can use this class driver instead of implementing the Printer
* class manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Devices using the USB Printer Class.
*
* @{
*/
#ifndef _PRINTER_CLASS_H_
#define _PRINTER_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_PRINTER_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/Printer.h"
#endif
#endif
/** @} */

View file

@ -1,83 +1,83 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB RNDIS Class driver.
*
* Master include file for the library USB RNDIS Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassRNDIS RNDIS (Networking) Class Driver - LUFA/Drivers/Class/RNDIS.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/RNDIS.c
* - LUFA/Drivers/USB/Class/Host/RNDIS.c
*
* \section Module Description
* RNDIS Class Driver module. This module contains an internal implementation of the Microsoft USB RNDIS Networking
* Class, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
* RNDIS class manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts using the USB RNDIS Class.
*
* @{
*/
#ifndef _RNDIS_CLASS_H_
#define _RNDIS_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_RNDIS_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/RNDIS.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/RNDIS.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB RNDIS Class driver.
*
* Master include file for the library USB RNDIS Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassRNDIS RNDIS (Networking) Class Driver - LUFA/Drivers/Class/RNDIS.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Device/RNDIS.c
* - LUFA/Drivers/USB/Class/Host/RNDIS.c
*
* \section Module Description
* RNDIS Class Driver module. This module contains an internal implementation of the Microsoft USB RNDIS Networking
* Class, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
* RNDIS class manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Hosts using the USB RNDIS Class.
*
* @{
*/
#ifndef _RNDIS_CLASS_H_
#define _RNDIS_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_RNDIS_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_DEVICE)
#include "Device/RNDIS.h"
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/RNDIS.h"
#endif
#endif
/** @} */

View file

@ -1,78 +1,78 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Still Image Class driver.
*
* Master include file for the library USB Still Image Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassSI Still Image Class Driver - LUFA/Drivers/Class/StillImage.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/StillImage.c
*
* \section Module Description
* Still Image Class Driver module. This module contains an internal implementation of the USB Still Image Class,
* for USB Host mode only. User applications can use this class driver instead of implementing the Still Image class
* manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Devices using the USB Still Image Class.
*
* @{
*/
#ifndef _SI_CLASS_H_
#define _SI_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_SI_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/StillImage.h"
#endif
#endif
/** @} */
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, 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
* \brief Master include file for the library USB Still Image Class driver.
*
* Master include file for the library USB Still Image Class driver, for both host and device modes, where available.
*
* This file should be included in all user projects making use of this optional class driver, instead of
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
*/
/** \ingroup Group_USBClassDrivers
* @defgroup Group_USBClassSI Still Image Class Driver - LUFA/Drivers/Class/StillImage.h
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/StillImage.c
*
* \section Module Description
* Still Image Class Driver module. This module contains an internal implementation of the USB Still Image Class,
* for USB Host mode only. User applications can use this class driver instead of implementing the Still Image class
* manually via the low-level LUFA APIs.
*
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
* Devices using the USB Still Image Class.
*
* @{
*/
#ifndef _SI_CLASS_H_
#define _SI_CLASS_H_
/* Macros: */
#define __INCLUDE_FROM_SI_DRIVER
#define __INCLUDE_FROM_USB_DRIVER
/* Includes: */
#include "../HighLevel/USBMode.h"
#if defined(NO_STREAM_CALLBACKS)
#error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
#endif
#if defined(USB_CAN_BE_HOST)
#include "Host/StillImage.h"
#endif
#endif
/** @} */