diff options
Diffstat (limited to 'lib/lufa/LUFA/Drivers/USB/Class')
53 files changed, 15272 insertions, 0 deletions
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h b/lib/lufa/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h new file mode 100644 index 000000000..f1c0109ea --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB Android Open Accessory Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB Android Open Accessory Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassAOA Android Open Accessory Class Driver | ||
| 42 | * \brief USB class driver for the Google Android Open Accessory class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassAOA_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * | ||
| 48 | * \section Sec_USBClassAOA_ModDescription Module Description | ||
| 49 | * Android Open Accessory Class Driver module. This module contains an internal implementation of the USB Android Open Accessory | ||
| 50 | * Class, for Host USB mode. User applications can use this class driver instead of implementing the Android Open Accessory Class | ||
| 51 | * manually via the low-level LUFA APIs. | ||
| 52 | * | ||
| 53 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 54 | * Host using the USB Android Open Accessory Class. | ||
| 55 | * | ||
| 56 | * @{ | ||
| 57 | */ | ||
| 58 | |||
| 59 | #ifndef _AOA_CLASS_H_ | ||
| 60 | #define _AOA_CLASS_H_ | ||
| 61 | |||
| 62 | /* Macros: */ | ||
| 63 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 64 | #define __INCLUDE_FROM_AOA_DRIVER | ||
| 65 | |||
| 66 | /* Includes: */ | ||
| 67 | #include "../Core/USBMode.h" | ||
| 68 | |||
| 69 | #if defined(USB_CAN_BE_HOST) | ||
| 70 | #include "Host/AndroidAccessoryClassHost.h" | ||
| 71 | #endif | ||
| 72 | |||
| 73 | #endif | ||
| 74 | |||
| 75 | /** @} */ | ||
| 76 | |||
| 77 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/AudioClass.h b/lib/lufa/LUFA/Drivers/USB/Class/AudioClass.h new file mode 100644 index 000000000..d6ced05dc --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/AudioClass.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB Audio 1.0 Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB Audio 1.0 Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassAudio Audio 1.0 Class Driver | ||
| 42 | * \brief USB class driver for the USB-IF Audio 1.0 class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassAudio_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * - LUFA/Drivers/USB/Class/Host/AudioClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 48 | * | ||
| 49 | * \section Sec_USBClassAudio_ModDescription Module Description | ||
| 50 | * Audio 1.0 Class Driver module. This module contains an internal implementation of the USB Audio 1.0 Class, for both | ||
| 51 | * Device and Host USB modes. User applications can use this class driver instead of implementing the Audio 1.0 class | ||
| 52 | * manually via the low-level LUFA APIs. | ||
| 53 | * | ||
| 54 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 55 | * Hosts or Devices using the USB Audio 1.0 Class. | ||
| 56 | * | ||
| 57 | * @{ | ||
| 58 | */ | ||
| 59 | |||
| 60 | #ifndef _AUDIO_CLASS_H_ | ||
| 61 | #define _AUDIO_CLASS_H_ | ||
| 62 | |||
| 63 | /* Macros: */ | ||
| 64 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 65 | #define __INCLUDE_FROM_AUDIO_DRIVER | ||
| 66 | |||
| 67 | /* Includes: */ | ||
| 68 | #include "../Core/USBMode.h" | ||
| 69 | |||
| 70 | #if defined(USB_CAN_BE_DEVICE) | ||
| 71 | #include "Device/AudioClassDevice.h" | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #if defined(USB_CAN_BE_HOST) | ||
| 75 | #include "Host/AudioClassHost.h" | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #endif | ||
| 79 | |||
| 80 | /** @} */ | ||
| 81 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/CDCClass.h b/lib/lufa/LUFA/Drivers/USB/Class/CDCClass.h new file mode 100644 index 000000000..30b3ee237 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/CDCClass.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB CDC-ACM Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB CDC Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassCDC CDC-ACM (Virtual Serial) Class Driver | ||
| 42 | * \brief USB class driver for the USB-IF CDC-ACM (Virtual Serial) class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassCDC_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * - LUFA/Drivers/USB/Class/Host/CDCClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 48 | * | ||
| 49 | * \section Sec_USBClassCDC_ModDescription Module Description | ||
| 50 | * CDC Class Driver module. This module contains an internal implementation of the USB CDC-ACM class Virtual Serial | ||
| 51 | * Ports, for both Device and Host USB modes. User applications can use this class driver instead of implementing the | ||
| 52 | * CDC class manually via the low-level LUFA APIs. | ||
| 53 | * | ||
| 54 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 55 | * Hosts or Devices using the USB CDC Class. | ||
| 56 | * | ||
| 57 | * @{ | ||
| 58 | */ | ||
| 59 | |||
| 60 | #ifndef _CDC_CLASS_H_ | ||
| 61 | #define _CDC_CLASS_H_ | ||
| 62 | |||
| 63 | /* Macros: */ | ||
| 64 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 65 | #define __INCLUDE_FROM_CDC_DRIVER | ||
| 66 | |||
| 67 | /* Includes: */ | ||
| 68 | #include "../Core/USBMode.h" | ||
| 69 | |||
| 70 | #if defined(USB_CAN_BE_DEVICE) | ||
| 71 | #include "Device/CDCClassDevice.h" | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #if defined(USB_CAN_BE_HOST) | ||
| 75 | #include "Host/CDCClassHost.h" | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #endif | ||
| 79 | |||
| 80 | /** @} */ | ||
| 81 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h new file mode 100644 index 000000000..fdf8671fc --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB Android Open Accessory Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB Android Open Accessory Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassAOA | ||
| 41 | * \defgroup Group_USBClassAOACommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassAOACommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * Android Open Accessory Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _AOA_CLASS_COMMON_H_ | ||
| 51 | #define _AOA_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Includes: */ | ||
| 54 | #include "../../Core/StdDescriptors.h" | ||
| 55 | |||
| 56 | /* Enable C linkage for C++ Compilers: */ | ||
| 57 | #if defined(__cplusplus) | ||
| 58 | extern "C" { | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Preprocessor Checks: */ | ||
| 62 | #if !defined(__INCLUDE_FROM_AOA_DRIVER) | ||
| 63 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* Macros: */ | ||
| 67 | /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory mode. */ | ||
| 68 | #define ANDROID_ACCESSORY_PRODUCT_ID 0x2D00 | ||
| 69 | |||
| 70 | /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory and Android Debug mode. */ | ||
| 71 | #define ANDROID_ACCESSORY_ADB_PRODUCT_ID 0x2D01 | ||
| 72 | |||
| 73 | /* Enums: */ | ||
| 74 | /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the | ||
| 75 | * Android Open Accessory class. | ||
| 76 | */ | ||
| 77 | enum AOA_Descriptor_ClassSubclassProtocol_t | ||
| 78 | { | ||
| 79 | AOA_CSCP_AOADataClass = 0xFF, /**< Descriptor Class value indicating that the device or interface | ||
| 80 | * belongs to the AOA data class. | ||
| 81 | */ | ||
| 82 | AOA_CSCP_AOADataSubclass = 0xFF, /**< Descriptor Subclass value indicating that the device or interface | ||
| 83 | * belongs to AOA data subclass. | ||
| 84 | */ | ||
| 85 | AOA_CSCP_AOADataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface | ||
| 86 | * belongs to the AOA data class protocol. | ||
| 87 | */ | ||
| 88 | }; | ||
| 89 | |||
| 90 | /** Enum for the Android Open Accessory class specific control requests that can be issued by the USB bus host. */ | ||
| 91 | enum AOA_ClassRequests_t | ||
| 92 | { | ||
| 93 | AOA_REQ_GetAccessoryProtocol = 0x33, /**< Android Open Accessory control request to retrieve the device's supported Accessory Protocol version. */ | ||
| 94 | AOA_REQ_SendString = 0x34, /**< Android Open Accessory control request to set an accessory property string in the device. */ | ||
| 95 | AOA_REQ_StartAccessoryMode = 0x35, /**< Android Open Accessory control request to switch the device into Accessory mode. */ | ||
| 96 | }; | ||
| 97 | |||
| 98 | /** Enum for the possible Android Open Accessory property string indexes. */ | ||
| 99 | enum AOA_Strings_t | ||
| 100 | { | ||
| 101 | AOA_STRING_Manufacturer = 0, /**< Index of the Manufacturer property string. */ | ||
| 102 | AOA_STRING_Model = 1, /**< Index of the Model Name property string. */ | ||
| 103 | AOA_STRING_Description = 2, /**< Index of the Description property string. */ | ||
| 104 | AOA_STRING_Version = 3, /**< Index of the Version Number property string. */ | ||
| 105 | AOA_STRING_URI = 4, /**< Index of the URI Information property string. */ | ||
| 106 | AOA_STRING_Serial = 5, /**< Index of the Serial Number property string. */ | ||
| 107 | |||
| 108 | #if !defined(__DOXYGEN__) | ||
| 109 | AOA_STRING_TOTAL_STRINGS | ||
| 110 | #endif | ||
| 111 | }; | ||
| 112 | |||
| 113 | /** Enum for the possible Android Open Accessory protocol versions. */ | ||
| 114 | enum AOA_Protocols_t | ||
| 115 | { | ||
| 116 | AOA_PROTOCOL_AccessoryV1 = 0x0001, /**< Android Open Accessory version 1. */ | ||
| 117 | AOA_PROTOCOL_AccessoryV2 = 0x0002, /**< Android Open Accessory version 2. */ | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* Disable C linkage for C++ Compilers: */ | ||
| 121 | #if defined(__cplusplus) | ||
| 122 | } | ||
| 123 | #endif | ||
| 124 | |||
| 125 | #endif | ||
| 126 | |||
| 127 | /** @} */ | ||
| 128 | |||
| 129 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h new file mode 100644 index 000000000..46ecd0858 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h | |||
| @@ -0,0 +1,780 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB Audio 1.0 Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB Audio 1.0 Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassAudio | ||
| 41 | * \defgroup Group_USBClassAudioCommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassAudioCommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * Audio 1.0 Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _AUDIO_CLASS_COMMON_H_ | ||
| 51 | #define _AUDIO_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Includes: */ | ||
| 54 | #include "../../Core/StdDescriptors.h" | ||
| 55 | |||
| 56 | /* Enable C linkage for C++ Compilers: */ | ||
| 57 | #if defined(__cplusplus) | ||
| 58 | extern "C" { | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Preprocessor Checks: */ | ||
| 62 | #if !defined(__INCLUDE_FROM_AUDIO_DRIVER) | ||
| 63 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* Macros: */ | ||
| 67 | /** \name Audio Channel Masks */ | ||
| 68 | //@{ | ||
| 69 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 70 | #define AUDIO_CHANNEL_LEFT_FRONT (1 << 0) | ||
| 71 | |||
| 72 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 73 | #define AUDIO_CHANNEL_RIGHT_FRONT (1 << 1) | ||
| 74 | |||
| 75 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 76 | #define AUDIO_CHANNEL_CENTER_FRONT (1 << 2) | ||
| 77 | |||
| 78 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 79 | #define AUDIO_CHANNEL_LOW_FREQ_ENHANCE (1 << 3) | ||
| 80 | |||
| 81 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 82 | #define AUDIO_CHANNEL_LEFT_SURROUND (1 << 4) | ||
| 83 | |||
| 84 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 85 | #define AUDIO_CHANNEL_RIGHT_SURROUND (1 << 5) | ||
| 86 | |||
| 87 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 88 | #define AUDIO_CHANNEL_LEFT_OF_CENTER (1 << 6) | ||
| 89 | |||
| 90 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 91 | #define AUDIO_CHANNEL_RIGHT_OF_CENTER (1 << 7) | ||
| 92 | |||
| 93 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 94 | #define AUDIO_CHANNEL_SURROUND (1 << 8) | ||
| 95 | |||
| 96 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 97 | #define AUDIO_CHANNEL_SIDE_LEFT (1 << 9) | ||
| 98 | |||
| 99 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 100 | #define AUDIO_CHANNEL_SIDE_RIGHT (1 << 10) | ||
| 101 | |||
| 102 | /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 103 | #define AUDIO_CHANNEL_TOP (1 << 11) | ||
| 104 | //@} | ||
| 105 | |||
| 106 | /** \name Audio Feature Masks */ | ||
| 107 | //@{ | ||
| 108 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 109 | #define AUDIO_FEATURE_MUTE (1 << 0) | ||
| 110 | |||
| 111 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 112 | #define AUDIO_FEATURE_VOLUME (1 << 1) | ||
| 113 | |||
| 114 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 115 | #define AUDIO_FEATURE_BASS (1 << 2) | ||
| 116 | |||
| 117 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 118 | #define AUDIO_FEATURE_MID (1 << 3) | ||
| 119 | |||
| 120 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 121 | #define AUDIO_FEATURE_TREBLE (1 << 4) | ||
| 122 | |||
| 123 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 124 | #define AUDIO_FEATURE_GRAPHIC_EQUALIZER (1 << 5) | ||
| 125 | |||
| 126 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 127 | #define AUDIO_FEATURE_AUTOMATIC_GAIN (1 << 6) | ||
| 128 | |||
| 129 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 130 | #define AUDIO_FEATURE_DELAY (1 << 7) | ||
| 131 | |||
| 132 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 133 | #define AUDIO_FEATURE_BASS_BOOST (1 << 8) | ||
| 134 | |||
| 135 | /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ | ||
| 136 | #define AUDIO_FEATURE_BASS_LOUDNESS (1 << 9) | ||
| 137 | //@} | ||
| 138 | |||
| 139 | /** \name Audio Terminal Types */ | ||
| 140 | //@{ | ||
| 141 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 142 | #define AUDIO_TERMINAL_UNDEFINED 0x0100 | ||
| 143 | |||
| 144 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 145 | #define AUDIO_TERMINAL_STREAMING 0x0101 | ||
| 146 | |||
| 147 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 148 | #define AUDIO_TERMINAL_VENDOR 0x01FF | ||
| 149 | |||
| 150 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 151 | #define AUDIO_TERMINAL_IN_UNDEFINED 0x0200 | ||
| 152 | |||
| 153 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 154 | #define AUDIO_TERMINAL_IN_MIC 0x0201 | ||
| 155 | |||
| 156 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 157 | #define AUDIO_TERMINAL_IN_DESKTOP_MIC 0x0202 | ||
| 158 | |||
| 159 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 160 | #define AUDIO_TERMINAL_IN_PERSONAL_MIC 0x0203 | ||
| 161 | |||
| 162 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 163 | #define AUDIO_TERMINAL_IN_OMNIDIR_MIC 0x0204 | ||
| 164 | |||
| 165 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 166 | #define AUDIO_TERMINAL_IN_MIC_ARRAY 0x0205 | ||
| 167 | |||
| 168 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 169 | #define AUDIO_TERMINAL_IN_PROCESSING_MIC 0x0206 | ||
| 170 | |||
| 171 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 172 | #define AUDIO_TERMINAL_IN_OUT_UNDEFINED 0x0300 | ||
| 173 | |||
| 174 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 175 | #define AUDIO_TERMINAL_OUT_SPEAKER 0x0301 | ||
| 176 | |||
| 177 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 178 | #define AUDIO_TERMINAL_OUT_HEADPHONES 0x0302 | ||
| 179 | |||
| 180 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 181 | #define AUDIO_TERMINAL_OUT_HEAD_MOUNTED 0x0303 | ||
| 182 | |||
| 183 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 184 | #define AUDIO_TERMINAL_OUT_DESKTOP 0x0304 | ||
| 185 | |||
| 186 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 187 | #define AUDIO_TERMINAL_OUT_ROOM 0x0305 | ||
| 188 | |||
| 189 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 190 | #define AUDIO_TERMINAL_OUT_COMMUNICATION 0x0306 | ||
| 191 | |||
| 192 | /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ | ||
| 193 | #define AUDIO_TERMINAL_OUT_LOWFREQ 0x0307 | ||
| 194 | //@} | ||
| 195 | |||
| 196 | /** Convenience macro to fill a 24-bit \ref USB_Audio_SampleFreq_t structure with the given sample rate as a 24-bit number. | ||
| 197 | * | ||
| 198 | * \param[in] freq Required audio sampling frequency in HZ | ||
| 199 | */ | ||
| 200 | #define AUDIO_SAMPLE_FREQ(freq) {.Byte1 = ((uint32_t)freq & 0xFF), .Byte2 = (((uint32_t)freq >> 8) & 0xFF), .Byte3 = (((uint32_t)freq >> 16) & 0xFF)} | ||
| 201 | |||
| 202 | /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint | ||
| 203 | * accepts only filled endpoint packets of audio samples. | ||
| 204 | */ | ||
| 205 | #define AUDIO_EP_FULL_PACKETS_ONLY (1 << 7) | ||
| 206 | |||
| 207 | /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint | ||
| 208 | * will accept partially filled endpoint packets of audio samples. | ||
| 209 | */ | ||
| 210 | #define AUDIO_EP_ACCEPTS_SMALL_PACKETS (0 << 7) | ||
| 211 | |||
| 212 | /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint | ||
| 213 | * allows for sampling frequency adjustments to be made via control requests directed at the endpoint. | ||
| 214 | */ | ||
| 215 | #define AUDIO_EP_SAMPLE_FREQ_CONTROL (1 << 0) | ||
| 216 | |||
| 217 | /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint | ||
| 218 | * allows for pitch adjustments to be made via control requests directed at the endpoint. | ||
| 219 | */ | ||
| 220 | #define AUDIO_EP_PITCH_CONTROL (1 << 1) | ||
| 221 | |||
| 222 | /* Enums: */ | ||
| 223 | /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Audio | ||
| 224 | * device class. | ||
| 225 | */ | ||
| 226 | enum Audio_Descriptor_ClassSubclassProtocol_t | ||
| 227 | { | ||
| 228 | AUDIO_CSCP_AudioClass = 0x01, /**< Descriptor Class value indicating that the device or | ||
| 229 | * interface belongs to the USB Audio 1.0 class. | ||
| 230 | */ | ||
| 231 | AUDIO_CSCP_ControlSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or | ||
| 232 | * interface belongs to the Audio Control subclass. | ||
| 233 | */ | ||
| 234 | AUDIO_CSCP_ControlProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or | ||
| 235 | * interface belongs to the Audio Control protocol. | ||
| 236 | */ | ||
| 237 | AUDIO_CSCP_AudioStreamingSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or | ||
| 238 | * interface belongs to the MIDI Streaming subclass. | ||
| 239 | */ | ||
| 240 | AUDIO_CSCP_MIDIStreamingSubclass = 0x03, /**< Descriptor Subclass value indicating that the device or | ||
| 241 | * interface belongs to the Audio streaming subclass. | ||
| 242 | */ | ||
| 243 | AUDIO_CSCP_StreamingProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or | ||
| 244 | * interface belongs to the Streaming Audio protocol. | ||
| 245 | */ | ||
| 246 | }; | ||
| 247 | |||
| 248 | /** Audio class specific interface description subtypes, for the Audio Control interface. */ | ||
| 249 | enum Audio_CSInterface_AC_SubTypes_t | ||
| 250 | { | ||
| 251 | AUDIO_DSUBTYPE_CSInterface_Header = 0x01, /**< Audio class specific control interface header. */ | ||
| 252 | AUDIO_DSUBTYPE_CSInterface_InputTerminal = 0x02, /**< Audio class specific control interface Input Terminal. */ | ||
| 253 | AUDIO_DSUBTYPE_CSInterface_OutputTerminal = 0x03, /**< Audio class specific control interface Output Terminal. */ | ||
| 254 | AUDIO_DSUBTYPE_CSInterface_Mixer = 0x04, /**< Audio class specific control interface Mixer Unit. */ | ||
| 255 | AUDIO_DSUBTYPE_CSInterface_Selector = 0x05, /**< Audio class specific control interface Selector Unit. */ | ||
| 256 | AUDIO_DSUBTYPE_CSInterface_Feature = 0x06, /**< Audio class specific control interface Feature Unit. */ | ||
| 257 | AUDIO_DSUBTYPE_CSInterface_Processing = 0x07, /**< Audio class specific control interface Processing Unit. */ | ||
| 258 | AUDIO_DSUBTYPE_CSInterface_Extension = 0x08, /**< Audio class specific control interface Extension Unit. */ | ||
| 259 | }; | ||
| 260 | |||
| 261 | /** Audio class specific interface description subtypes, for the Audio Streaming interface. */ | ||
| 262 | enum Audio_CSInterface_AS_SubTypes_t | ||
| 263 | { | ||
| 264 | AUDIO_DSUBTYPE_CSInterface_General = 0x01, /**< Audio class specific streaming interface general descriptor. */ | ||
| 265 | AUDIO_DSUBTYPE_CSInterface_FormatType = 0x02, /**< Audio class specific streaming interface format type descriptor. */ | ||
| 266 | AUDIO_DSUBTYPE_CSInterface_FormatSpecific = 0x03, /**< Audio class specific streaming interface format information descriptor. */ | ||
| 267 | }; | ||
| 268 | |||
| 269 | /** Audio class specific endpoint description subtypes, for the Audio Streaming interface. */ | ||
| 270 | enum Audio_CSEndpoint_SubTypes_t | ||
| 271 | { | ||
| 272 | AUDIO_DSUBTYPE_CSEndpoint_General = 0x01, /**< Audio class specific endpoint general descriptor. */ | ||
| 273 | }; | ||
| 274 | |||
| 275 | /** Enum for the Audio class specific control requests that can be issued by the USB bus host. */ | ||
| 276 | enum Audio_ClassRequests_t | ||
| 277 | { | ||
| 278 | AUDIO_REQ_SetCurrent = 0x01, /**< Audio class-specific request to set the current value of a parameter within the device. */ | ||
| 279 | AUDIO_REQ_SetMinimum = 0x02, /**< Audio class-specific request to set the minimum value of a parameter within the device. */ | ||
| 280 | AUDIO_REQ_SetMaximum = 0x03, /**< Audio class-specific request to set the maximum value of a parameter within the device. */ | ||
| 281 | AUDIO_REQ_SetResolution = 0x04, /**< Audio class-specific request to set the resolution value of a parameter within the device. */ | ||
| 282 | AUDIO_REQ_SetMemory = 0x05, /**< Audio class-specific request to set the memory value of a parameter within the device. */ | ||
| 283 | AUDIO_REQ_GetCurrent = 0x81, /**< Audio class-specific request to get the current value of a parameter within the device. */ | ||
| 284 | AUDIO_REQ_GetMinimum = 0x82, /**< Audio class-specific request to get the minimum value of a parameter within the device. */ | ||
| 285 | AUDIO_REQ_GetMaximum = 0x83, /**< Audio class-specific request to get the maximum value of a parameter within the device. */ | ||
| 286 | AUDIO_REQ_GetResolution = 0x84, /**< Audio class-specific request to get the resolution value of a parameter within the device. */ | ||
| 287 | AUDIO_REQ_GetMemory = 0x85, /**< Audio class-specific request to get the memory value of a parameter within the device. */ | ||
| 288 | AUDIO_REQ_GetStatus = 0xFF, /**< Audio class-specific request to get the device status. */ | ||
| 289 | }; | ||
| 290 | |||
| 291 | /** Enum for Audio class specific Endpoint control modifiers which can be set and retrieved by a USB host, if the corresponding | ||
| 292 | * endpoint control is indicated to be supported in the Endpoint's Audio-class specific endpoint descriptor. | ||
| 293 | */ | ||
| 294 | enum Audio_EndpointControls_t | ||
| 295 | { | ||
| 296 | AUDIO_EPCONTROL_SamplingFreq = 0x01, /**< Sampling frequency adjustment of the endpoint. */ | ||
| 297 | AUDIO_EPCONTROL_Pitch = 0x02, /**< Pitch adjustment of the endpoint. */ | ||
| 298 | }; | ||
| 299 | |||
| 300 | /* Type Defines: */ | ||
| 301 | /** \brief Audio class-specific Input Terminal Descriptor (LUFA naming conventions). | ||
| 302 | * | ||
| 303 | * Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device | ||
| 304 | * contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example, | ||
| 305 | * a USB endpoint). See the USB Audio specification for more details. | ||
| 306 | * | ||
| 307 | * \see \ref USB_Audio_StdDescriptor_InputTerminal_t for the version of this type with standard element names. | ||
| 308 | * | ||
| 309 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 310 | */ | ||
| 311 | typedef struct | ||
| 312 | { | ||
| 313 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 314 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 315 | * must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal. | ||
| 316 | */ | ||
| 317 | |||
| 318 | uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ | ||
| 319 | uint16_t TerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ | ||
| 320 | uint8_t AssociatedOutputTerminal; /**< ID of associated output terminal, for physically grouped terminals | ||
| 321 | * such as the speaker and microphone of a phone handset. | ||
| 322 | */ | ||
| 323 | uint8_t TotalChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */ | ||
| 324 | uint16_t ChannelConfig; /**< \c CHANNEL_* masks indicating what channel layout is supported by this terminal. */ | ||
| 325 | |||
| 326 | uint8_t ChannelStrIndex; /**< Index of a string descriptor describing this channel within the device. */ | ||
| 327 | uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 328 | } ATTR_PACKED USB_Audio_Descriptor_InputTerminal_t; | ||
| 329 | |||
| 330 | /** \brief Audio class-specific Input Terminal Descriptor (USB-IF naming conventions). | ||
| 331 | * | ||
| 332 | * Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device | ||
| 333 | * contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example, | ||
| 334 | * a USB endpoint). See the USB Audio specification for more details. | ||
| 335 | * | ||
| 336 | * \see \ref USB_Audio_Descriptor_InputTerminal_t for the version of this type with non-standard LUFA specific | ||
| 337 | * element names. | ||
| 338 | * | ||
| 339 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 340 | */ | ||
| 341 | typedef struct | ||
| 342 | { | ||
| 343 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 344 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 345 | * given by the specific class. | ||
| 346 | */ | ||
| 347 | |||
| 348 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 349 | * must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal. | ||
| 350 | */ | ||
| 351 | uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ | ||
| 352 | uint16_t wTerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ | ||
| 353 | uint8_t bAssocTerminal; /**< ID of associated output terminal, for physically grouped terminals | ||
| 354 | * such as the speaker and microphone of a phone handset. | ||
| 355 | */ | ||
| 356 | uint8_t bNrChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */ | ||
| 357 | uint16_t wChannelConfig; /**< \c CHANNEL_* masks indicating what channel layout is supported by this terminal. */ | ||
| 358 | |||
| 359 | uint8_t iChannelNames; /**< Index of a string descriptor describing this channel within the device. */ | ||
| 360 | uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 361 | } ATTR_PACKED USB_Audio_StdDescriptor_InputTerminal_t; | ||
| 362 | |||
| 363 | /** \brief Audio class-specific Output Terminal Descriptor (LUFA naming conventions). | ||
| 364 | * | ||
| 365 | * Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device | ||
| 366 | * contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example, | ||
| 367 | * a USB endpoint). See the USB Audio specification for more details. | ||
| 368 | * | ||
| 369 | * \see \ref USB_Audio_StdDescriptor_OutputTerminal_t for the version of this type with standard element names. | ||
| 370 | * | ||
| 371 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 372 | */ | ||
| 373 | typedef struct | ||
| 374 | { | ||
| 375 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 376 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 377 | * must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal. | ||
| 378 | */ | ||
| 379 | |||
| 380 | uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ | ||
| 381 | uint16_t TerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ | ||
| 382 | uint8_t AssociatedInputTerminal; /**< ID of associated input terminal, for physically grouped terminals | ||
| 383 | * such as the speaker and microphone of a phone handset. | ||
| 384 | */ | ||
| 385 | uint8_t SourceID; /**< ID value of the unit this terminal's audio is sourced from. */ | ||
| 386 | |||
| 387 | uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 388 | } ATTR_PACKED USB_Audio_Descriptor_OutputTerminal_t; | ||
| 389 | |||
| 390 | /** \brief Audio class-specific Output Terminal Descriptor (USB-IF naming conventions). | ||
| 391 | * | ||
| 392 | * Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device | ||
| 393 | * contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example, | ||
| 394 | * a USB endpoint). See the USB Audio specification for more details. | ||
| 395 | * | ||
| 396 | * \see \ref USB_Audio_Descriptor_OutputTerminal_t for the version of this type with non-standard LUFA specific | ||
| 397 | * element names. | ||
| 398 | * | ||
| 399 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 400 | */ | ||
| 401 | typedef struct | ||
| 402 | { | ||
| 403 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 404 | uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 405 | * must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal. | ||
| 406 | */ | ||
| 407 | |||
| 408 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 409 | * a value from the \ref Audio_CSInterface_AC_SubTypes_t enum. | ||
| 410 | */ | ||
| 411 | uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ | ||
| 412 | uint16_t wTerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ | ||
| 413 | uint8_t bAssocTerminal; /**< ID of associated input terminal, for physically grouped terminals | ||
| 414 | * such as the speaker and microphone of a phone handset. | ||
| 415 | */ | ||
| 416 | uint8_t bSourceID; /**< ID value of the unit this terminal's audio is sourced from. */ | ||
| 417 | |||
| 418 | uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 419 | } ATTR_PACKED USB_Audio_StdDescriptor_OutputTerminal_t; | ||
| 420 | |||
| 421 | /** \brief Audio class-specific Interface Descriptor (LUFA naming conventions). | ||
| 422 | * | ||
| 423 | * Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to | ||
| 424 | * supply extra information about the audio device's layout to the host. See the USB Audio specification for more | ||
| 425 | * details. | ||
| 426 | * | ||
| 427 | * \see \ref USB_Audio_StdDescriptor_Interface_AC_t for the version of this type with standard element names. | ||
| 428 | * | ||
| 429 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 430 | */ | ||
| 431 | typedef struct | ||
| 432 | { | ||
| 433 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 434 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 435 | * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. | ||
| 436 | */ | ||
| 437 | |||
| 438 | uint16_t ACSpecification; /**< Binary Coded Decimal value, indicating the supported Audio Class specification version. | ||
| 439 | * | ||
| 440 | * \see \ref VERSION_BCD() utility macro. | ||
| 441 | */ | ||
| 442 | uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ | ||
| 443 | |||
| 444 | uint8_t InCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */ | ||
| 445 | uint8_t InterfaceNumber; /**< Interface number of the associated Audio Streaming interface. */ | ||
| 446 | } ATTR_PACKED USB_Audio_Descriptor_Interface_AC_t; | ||
| 447 | |||
| 448 | /** \brief Audio class-specific Interface Descriptor (USB-IF naming conventions). | ||
| 449 | * | ||
| 450 | * Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to | ||
| 451 | * supply extra information about the audio device's layout to the host. See the USB Audio specification for more | ||
| 452 | * details. | ||
| 453 | * | ||
| 454 | * \see \ref USB_Audio_Descriptor_Interface_AC_t for the version of this type with non-standard LUFA specific | ||
| 455 | * element names. | ||
| 456 | * | ||
| 457 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 458 | */ | ||
| 459 | typedef struct | ||
| 460 | { | ||
| 461 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 462 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 463 | * given by the specific class. | ||
| 464 | */ | ||
| 465 | |||
| 466 | uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 467 | * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. | ||
| 468 | */ | ||
| 469 | |||
| 470 | uint16_t bcdADC; /**< Binary coded decimal value, indicating the supported Audio Class specification version. | ||
| 471 | * | ||
| 472 | * \see \ref VERSION_BCD() utility macro. | ||
| 473 | */ | ||
| 474 | uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ | ||
| 475 | |||
| 476 | uint8_t bInCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */ | ||
| 477 | uint8_t bInterfaceNumbers; /**< Interface number of the associated Audio Streaming interface. */ | ||
| 478 | } ATTR_PACKED USB_Audio_StdDescriptor_Interface_AC_t; | ||
| 479 | |||
| 480 | /** \brief Audio class-specific Feature Unit Descriptor (LUFA naming conventions). | ||
| 481 | * | ||
| 482 | * Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features | ||
| 483 | * are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio | ||
| 484 | * specification for more details. | ||
| 485 | * | ||
| 486 | * \see \ref USB_Audio_StdDescriptor_FeatureUnit_t for the version of this type with standard element names. | ||
| 487 | * | ||
| 488 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 489 | */ | ||
| 490 | typedef struct | ||
| 491 | { | ||
| 492 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 493 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 494 | * must be \ref AUDIO_DSUBTYPE_CSInterface_Feature. | ||
| 495 | */ | ||
| 496 | |||
| 497 | uint8_t UnitID; /**< ID value of this feature unit - must be a unique value within the device. */ | ||
| 498 | uint8_t SourceID; /**< Source ID value of the audio source input into this feature unit. */ | ||
| 499 | |||
| 500 | uint8_t ControlSize; /**< Size of each element in the \c ChannelControls array. */ | ||
| 501 | uint8_t ChannelControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */ | ||
| 502 | |||
| 503 | uint8_t FeatureUnitStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 504 | } ATTR_PACKED USB_Audio_Descriptor_FeatureUnit_t; | ||
| 505 | |||
| 506 | /** \brief Audio class-specific Feature Unit Descriptor (USB-IF naming conventions). | ||
| 507 | * | ||
| 508 | * Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features | ||
| 509 | * are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio | ||
| 510 | * specification for more details. | ||
| 511 | * | ||
| 512 | * \see \ref USB_Audio_Descriptor_FeatureUnit_t for the version of this type with non-standard LUFA specific | ||
| 513 | * element names. | ||
| 514 | * | ||
| 515 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 516 | */ | ||
| 517 | typedef struct | ||
| 518 | { | ||
| 519 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 520 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 521 | * given by the specific class. | ||
| 522 | */ | ||
| 523 | |||
| 524 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 525 | * must be \ref AUDIO_DSUBTYPE_CSInterface_Feature. | ||
| 526 | */ | ||
| 527 | |||
| 528 | uint8_t bUnitID; /**< ID value of this feature unit - must be a unique value within the device. */ | ||
| 529 | uint8_t bSourceID; /**< Source ID value of the audio source input into this feature unit. */ | ||
| 530 | |||
| 531 | uint8_t bControlSize; /**< Size of each element in the \c ChannelControls array. */ | ||
| 532 | uint8_t bmaControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */ | ||
| 533 | |||
| 534 | uint8_t iFeature; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 535 | } ATTR_PACKED USB_Audio_StdDescriptor_FeatureUnit_t; | ||
| 536 | |||
| 537 | /** \brief Audio class-specific Streaming Audio Interface Descriptor (LUFA naming conventions). | ||
| 538 | * | ||
| 539 | * Type define for an Audio class-specific streaming interface descriptor. This indicates to the host | ||
| 540 | * how audio streams within the device are formatted. See the USB Audio specification for more details. | ||
| 541 | * | ||
| 542 | * \see \ref USB_Audio_StdDescriptor_Interface_AS_t for the version of this type with standard element names. | ||
| 543 | * | ||
| 544 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 545 | */ | ||
| 546 | typedef struct | ||
| 547 | { | ||
| 548 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 549 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 550 | * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. | ||
| 551 | */ | ||
| 552 | |||
| 553 | uint8_t TerminalLink; /**< ID value of the output terminal this descriptor is describing. */ | ||
| 554 | |||
| 555 | uint8_t FrameDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */ | ||
| 556 | uint16_t AudioFormat; /**< Format of the audio stream, see Audio Device Formats specification. */ | ||
| 557 | } ATTR_PACKED USB_Audio_Descriptor_Interface_AS_t; | ||
| 558 | |||
| 559 | /** \brief Audio class-specific Streaming Audio Interface Descriptor (USB-IF naming conventions). | ||
| 560 | * | ||
| 561 | * Type define for an Audio class-specific streaming interface descriptor. This indicates to the host | ||
| 562 | * how audio streams within the device are formatted. See the USB Audio specification for more details. | ||
| 563 | * | ||
| 564 | * \see \ref USB_Audio_Descriptor_Interface_AS_t for the version of this type with non-standard LUFA specific | ||
| 565 | * element names. | ||
| 566 | * | ||
| 567 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 568 | */ | ||
| 569 | typedef struct | ||
| 570 | { | ||
| 571 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 572 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 573 | * given by the specific class. | ||
| 574 | */ | ||
| 575 | |||
| 576 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 577 | * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. | ||
| 578 | */ | ||
| 579 | |||
| 580 | uint8_t bTerminalLink; /**< ID value of the output terminal this descriptor is describing. */ | ||
| 581 | |||
| 582 | uint8_t bDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */ | ||
| 583 | uint16_t wFormatTag; /**< Format of the audio stream, see Audio Device Formats specification. */ | ||
| 584 | } ATTR_PACKED USB_Audio_StdDescriptor_Interface_AS_t; | ||
| 585 | |||
| 586 | /** \brief Audio class-specific Format Descriptor (LUFA naming conventions). | ||
| 587 | * | ||
| 588 | * Type define for an Audio class-specific audio format descriptor. This is used to give the host full details | ||
| 589 | * about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used | ||
| 590 | * in the device's audio streams. See the USB Audio specification for more details. | ||
| 591 | * | ||
| 592 | * \attention This descriptor <b>must</b> be followed by one or more \ref USB_Audio_SampleFreq_t elements containing | ||
| 593 | * the continuous or discrete sample frequencies. | ||
| 594 | * | ||
| 595 | * \see \ref USB_Audio_StdDescriptor_Format_t for the version of this type with standard element names. | ||
| 596 | * | ||
| 597 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 598 | */ | ||
| 599 | typedef struct | ||
| 600 | { | ||
| 601 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 602 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 603 | * must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType. | ||
| 604 | */ | ||
| 605 | |||
| 606 | uint8_t FormatType; /**< Format of the audio stream, see Audio Device Formats specification. */ | ||
| 607 | uint8_t Channels; /**< Total number of discrete channels in the stream. */ | ||
| 608 | |||
| 609 | uint8_t SubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */ | ||
| 610 | uint8_t BitResolution; /**< Bits of resolution of each channel's samples in the stream. */ | ||
| 611 | |||
| 612 | uint8_t TotalDiscreteSampleRates; /**< Total number of discrete sample frequencies supported by the device. When | ||
| 613 | * zero, this must be followed by the lower and upper continuous sampling | ||
| 614 | * frequencies supported by the device; otherwise, this must be followed | ||
| 615 | * by the given number of discrete sampling frequencies supported. | ||
| 616 | */ | ||
| 617 | } ATTR_PACKED USB_Audio_Descriptor_Format_t; | ||
| 618 | |||
| 619 | /** \brief 24-Bit Audio Frequency Structure. | ||
| 620 | * | ||
| 621 | * Type define for a 24-bit audio sample frequency structure. As GCC does not contain a built in 24-bit datatype, | ||
| 622 | * this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro. | ||
| 623 | * | ||
| 624 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 625 | */ | ||
| 626 | typedef struct | ||
| 627 | { | ||
| 628 | uint8_t Byte1; /**< Lowest 8 bits of the 24-bit value. */ | ||
| 629 | uint8_t Byte2; /**< Middle 8 bits of the 24-bit value. */ | ||
| 630 | uint8_t Byte3; /**< Upper 8 bits of the 24-bit value. */ | ||
| 631 | } ATTR_PACKED USB_Audio_SampleFreq_t; | ||
| 632 | |||
| 633 | /** \brief Audio class-specific Format Descriptor (USB-IF naming conventions). | ||
| 634 | * | ||
| 635 | * Type define for an Audio class-specific audio format descriptor. This is used to give the host full details | ||
| 636 | * about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used | ||
| 637 | * in the device's audio streams. See the USB Audio specification for more details. | ||
| 638 | * | ||
| 639 | * \attention This descriptor <b>must</b> be followed by one or more 24-bit integer elements containing the continuous | ||
| 640 | * or discrete sample frequencies. | ||
| 641 | * | ||
| 642 | * \see \ref USB_Audio_Descriptor_Format_t for the version of this type with non-standard LUFA specific | ||
| 643 | * element names. | ||
| 644 | * | ||
| 645 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 646 | */ | ||
| 647 | typedef struct | ||
| 648 | { | ||
| 649 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 650 | uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 651 | * must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType. | ||
| 652 | */ | ||
| 653 | |||
| 654 | uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 655 | * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. | ||
| 656 | */ | ||
| 657 | |||
| 658 | uint8_t bFormatType; /**< Format of the audio stream, see Audio Device Formats specification. */ | ||
| 659 | uint8_t bNrChannels; /**< Total number of discrete channels in the stream. */ | ||
| 660 | |||
| 661 | uint8_t bSubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */ | ||
| 662 | uint8_t bBitResolution; /**< Bits of resolution of each channel's samples in the stream. */ | ||
| 663 | |||
| 664 | uint8_t bSampleFrequencyType; /**< Total number of sample frequencies supported by the device. When | ||
| 665 | * zero, this must be followed by the lower and upper continuous sampling | ||
| 666 | * frequencies supported by the device; otherwise, this must be followed | ||
| 667 | * by the given number of discrete sampling frequencies supported. | ||
| 668 | */ | ||
| 669 | } ATTR_PACKED USB_Audio_StdDescriptor_Format_t; | ||
| 670 | |||
| 671 | /** \brief Audio class-specific Streaming Endpoint Descriptor (LUFA naming conventions). | ||
| 672 | * | ||
| 673 | * Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint | ||
| 674 | * descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details. | ||
| 675 | * | ||
| 676 | * \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Std_t for the version of this type with standard element names. | ||
| 677 | * | ||
| 678 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 679 | */ | ||
| 680 | typedef struct | ||
| 681 | { | ||
| 682 | USB_Descriptor_Endpoint_t Endpoint; /**< Standard endpoint descriptor describing the audio endpoint. */ | ||
| 683 | |||
| 684 | uint8_t Refresh; /**< Always set to zero for Audio class devices. */ | ||
| 685 | uint8_t SyncEndpointNumber; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */ | ||
| 686 | } ATTR_PACKED USB_Audio_Descriptor_StreamEndpoint_Std_t; | ||
| 687 | |||
| 688 | /** \brief Audio class-specific Streaming Endpoint Descriptor (USB-IF naming conventions). | ||
| 689 | * | ||
| 690 | * Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint | ||
| 691 | * descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details. | ||
| 692 | * | ||
| 693 | * \see \ref USB_Audio_Descriptor_StreamEndpoint_Std_t for the version of this type with non-standard LUFA specific | ||
| 694 | * element names. | ||
| 695 | * | ||
| 696 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 697 | */ | ||
| 698 | typedef struct | ||
| 699 | { | ||
| 700 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 701 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a | ||
| 702 | * value given by the specific class. | ||
| 703 | */ | ||
| 704 | uint8_t bEndpointAddress; /**< Logical address of the endpoint within the device for the current | ||
| 705 | * configuration, including direction mask. | ||
| 706 | */ | ||
| 707 | uint8_t bmAttributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (\c EP_TYPE_*) | ||
| 708 | * and attributes (\c ENDPOINT_ATTR_*) masks. | ||
| 709 | */ | ||
| 710 | uint16_t wMaxPacketSize; /**< Size of the endpoint bank, in bytes. This indicates the maximum packet size | ||
| 711 | * that the endpoint can receive at a time. | ||
| 712 | */ | ||
| 713 | uint8_t bInterval; /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT or | ||
| 714 | * ISOCHRONOUS type. | ||
| 715 | */ | ||
| 716 | |||
| 717 | uint8_t bRefresh; /**< Always set to zero for Audio class devices. */ | ||
| 718 | uint8_t bSynchAddress; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */ | ||
| 719 | } ATTR_PACKED USB_Audio_StdDescriptor_StreamEndpoint_Std_t; | ||
| 720 | |||
| 721 | /** \brief Audio class-specific Extended Endpoint Descriptor (LUFA naming conventions). | ||
| 722 | * | ||
| 723 | * Type define for an Audio class-specific extended endpoint descriptor. This contains extra information | ||
| 724 | * on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio | ||
| 725 | * class-specific extended endpoint descriptor. See the USB Audio specification for more details. | ||
| 726 | * | ||
| 727 | * \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Spc_t for the version of this type with standard element names. | ||
| 728 | * | ||
| 729 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 730 | */ | ||
| 731 | typedef struct | ||
| 732 | { | ||
| 733 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 734 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 735 | * a value from the \ref Audio_CSEndpoint_SubTypes_t enum. | ||
| 736 | */ | ||
| 737 | |||
| 738 | uint8_t Attributes; /**< Audio class-specific endpoint attributes, such as \ref AUDIO_EP_FULL_PACKETS_ONLY. */ | ||
| 739 | |||
| 740 | uint8_t LockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */ | ||
| 741 | uint16_t LockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */ | ||
| 742 | } ATTR_PACKED USB_Audio_Descriptor_StreamEndpoint_Spc_t; | ||
| 743 | |||
| 744 | /** \brief Audio class-specific Extended Endpoint Descriptor (USB-IF naming conventions). | ||
| 745 | * | ||
| 746 | * Type define for an Audio class-specific extended endpoint descriptor. This contains extra information | ||
| 747 | * on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio | ||
| 748 | * class-specific extended endpoint descriptor. See the USB Audio specification for more details. | ||
| 749 | * | ||
| 750 | * \see \ref USB_Audio_Descriptor_StreamEndpoint_Spc_t for the version of this type with non-standard LUFA specific | ||
| 751 | * element names. | ||
| 752 | * | ||
| 753 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 754 | */ | ||
| 755 | typedef struct | ||
| 756 | { | ||
| 757 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 758 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 759 | * given by the specific class. | ||
| 760 | */ | ||
| 761 | |||
| 762 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, | ||
| 763 | * a value from the \ref Audio_CSEndpoint_SubTypes_t enum. | ||
| 764 | */ | ||
| 765 | |||
| 766 | uint8_t bmAttributes; /**< Audio class-specific endpoint attributes, such as \ref AUDIO_EP_FULL_PACKETS_ONLY. */ | ||
| 767 | |||
| 768 | uint8_t bLockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */ | ||
| 769 | uint16_t wLockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */ | ||
| 770 | } ATTR_PACKED USB_Audio_StdDescriptor_StreamEndpoint_Spc_t; | ||
| 771 | |||
| 772 | /* Disable C linkage for C++ Compilers: */ | ||
| 773 | #if defined(__cplusplus) | ||
| 774 | } | ||
| 775 | #endif | ||
| 776 | |||
| 777 | #endif | ||
| 778 | |||
| 779 | /** @} */ | ||
| 780 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h new file mode 100644 index 000000000..1ad49eca1 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h | |||
| @@ -0,0 +1,391 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB CDC Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB CDC Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassCDC | ||
| 41 | * \defgroup Group_USBClassCDCCommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassCDCCommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * CDC Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _CDC_CLASS_COMMON_H_ | ||
| 51 | #define _CDC_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Includes: */ | ||
| 54 | #include "../../Core/StdDescriptors.h" | ||
| 55 | |||
| 56 | /* Enable C linkage for C++ Compilers: */ | ||
| 57 | #if defined(__cplusplus) | ||
| 58 | extern "C" { | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Preprocessor Checks: */ | ||
| 62 | #if !defined(__INCLUDE_FROM_CDC_DRIVER) | ||
| 63 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* Macros: */ | ||
| 67 | /** \name Virtual Control Line Masks */ | ||
| 68 | //@{ | ||
| 69 | /** Mask for the DTR handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request | ||
| 70 | * from the host, to indicate that the DTR line state should be high. | ||
| 71 | */ | ||
| 72 | #define CDC_CONTROL_LINE_OUT_DTR (1 << 0) | ||
| 73 | |||
| 74 | /** Mask for the RTS handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request | ||
| 75 | * from the host, to indicate that the RTS line state should be high. | ||
| 76 | */ | ||
| 77 | #define CDC_CONTROL_LINE_OUT_RTS (1 << 1) | ||
| 78 | |||
| 79 | /** Mask for the DCD handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification | ||
| 80 | * from the device to the host, to indicate that the DCD line state is currently high. | ||
| 81 | */ | ||
| 82 | #define CDC_CONTROL_LINE_IN_DCD (1 << 0) | ||
| 83 | |||
| 84 | /** Mask for the DSR handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification | ||
| 85 | * from the device to the host, to indicate that the DSR line state is currently high. | ||
| 86 | */ | ||
| 87 | #define CDC_CONTROL_LINE_IN_DSR (1 << 1) | ||
| 88 | |||
| 89 | /** Mask for the BREAK handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification | ||
| 90 | * from the device to the host, to indicate that the BREAK line state is currently high. | ||
| 91 | */ | ||
| 92 | #define CDC_CONTROL_LINE_IN_BREAK (1 << 2) | ||
| 93 | |||
| 94 | /** Mask for the RING handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification | ||
| 95 | * from the device to the host, to indicate that the RING line state is currently high. | ||
| 96 | */ | ||
| 97 | #define CDC_CONTROL_LINE_IN_RING (1 << 3) | ||
| 98 | |||
| 99 | /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host, | ||
| 100 | * to indicate that a framing error has occurred on the virtual serial port. | ||
| 101 | */ | ||
| 102 | #define CDC_CONTROL_LINE_IN_FRAMEERROR (1 << 4) | ||
| 103 | |||
| 104 | /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host, | ||
| 105 | * to indicate that a parity error has occurred on the virtual serial port. | ||
| 106 | */ | ||
| 107 | #define CDC_CONTROL_LINE_IN_PARITYERROR (1 << 5) | ||
| 108 | |||
| 109 | /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host, | ||
| 110 | * to indicate that a data overrun error has occurred on the virtual serial port. | ||
| 111 | */ | ||
| 112 | #define CDC_CONTROL_LINE_IN_OVERRUNERROR (1 << 6) | ||
| 113 | //@} | ||
| 114 | |||
| 115 | /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a | ||
| 116 | * uniform structure but variable sized data payloads, thus cannot be represented accurately by | ||
| 117 | * a single \c typedef \c struct. A macro is used instead so that functional descriptors can be created | ||
| 118 | * easily by specifying the size of the payload. This allows \c sizeof() to work correctly. | ||
| 119 | * | ||
| 120 | * \param[in] DataSize Size in bytes of the CDC functional descriptor's data payload. | ||
| 121 | */ | ||
| 122 | #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ | ||
| 123 | struct \ | ||
| 124 | { \ | ||
| 125 | USB_Descriptor_Header_t Header; \ | ||
| 126 | uint8_t SubType; \ | ||
| 127 | uint8_t Data[DataSize]; \ | ||
| 128 | } | ||
| 129 | |||
| 130 | /* Enums: */ | ||
| 131 | /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the CDC | ||
| 132 | * device class. | ||
| 133 | */ | ||
| 134 | enum CDC_Descriptor_ClassSubclassProtocol_t | ||
| 135 | { | ||
| 136 | CDC_CSCP_CDCClass = 0x02, /**< Descriptor Class value indicating that the device or interface | ||
| 137 | * belongs to the CDC class. | ||
| 138 | */ | ||
| 139 | CDC_CSCP_NoSpecificSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface | ||
| 140 | * belongs to no specific subclass of the CDC class. | ||
| 141 | */ | ||
| 142 | CDC_CSCP_ACMSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or interface | ||
| 143 | * belongs to the Abstract Control Model CDC subclass. | ||
| 144 | */ | ||
| 145 | CDC_CSCP_ATCommandProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface | ||
| 146 | * belongs to the AT Command protocol of the CDC class. | ||
| 147 | */ | ||
| 148 | CDC_CSCP_NoSpecificProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface | ||
| 149 | * belongs to no specific protocol of the CDC class. | ||
| 150 | */ | ||
| 151 | CDC_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Protocol value indicating that the device or interface | ||
| 152 | * belongs to a vendor-specific protocol of the CDC class. | ||
| 153 | */ | ||
| 154 | CDC_CSCP_CDCDataClass = 0x0A, /**< Descriptor Class value indicating that the device or interface | ||
| 155 | * belongs to the CDC Data class. | ||
| 156 | */ | ||
| 157 | CDC_CSCP_NoDataSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface | ||
| 158 | * belongs to no specific subclass of the CDC data class. | ||
| 159 | */ | ||
| 160 | CDC_CSCP_NoDataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface | ||
| 161 | * belongs to no specific protocol of the CDC data class. | ||
| 162 | */ | ||
| 163 | }; | ||
| 164 | |||
| 165 | /** Enum for the CDC class specific control requests that can be issued by the USB bus host. */ | ||
| 166 | enum CDC_ClassRequests_t | ||
| 167 | { | ||
| 168 | CDC_REQ_SendEncapsulatedCommand = 0x00, /**< CDC class-specific request to send an encapsulated command to the device. */ | ||
| 169 | CDC_REQ_GetEncapsulatedResponse = 0x01, /**< CDC class-specific request to retrieve an encapsulated command response from the device. */ | ||
| 170 | CDC_REQ_SetLineEncoding = 0x20, /**< CDC class-specific request to set the current virtual serial port configuration settings. */ | ||
| 171 | CDC_REQ_GetLineEncoding = 0x21, /**< CDC class-specific request to get the current virtual serial port configuration settings. */ | ||
| 172 | CDC_REQ_SetControlLineState = 0x22, /**< CDC class-specific request to set the current virtual serial port handshake line states. */ | ||
| 173 | CDC_REQ_SendBreak = 0x23, /**< CDC class-specific request to send a break to the receiver via the carrier channel. */ | ||
| 174 | }; | ||
| 175 | |||
| 176 | /** Enum for the CDC class specific notification requests that can be issued by a CDC device to a host. */ | ||
| 177 | enum CDC_ClassNotifications_t | ||
| 178 | { | ||
| 179 | CDC_NOTIF_SerialState = 0x20, /**< Notification type constant for a change in the virtual serial port | ||
| 180 | * handshake line states, for use with a \ref USB_Request_Header_t | ||
| 181 | * notification structure when sent to the host via the CDC notification | ||
| 182 | * endpoint. | ||
| 183 | */ | ||
| 184 | }; | ||
| 185 | |||
| 186 | /** Enum for the CDC class specific interface descriptor subtypes. */ | ||
| 187 | enum CDC_DescriptorSubtypes_t | ||
| 188 | { | ||
| 189 | CDC_DSUBTYPE_CSInterface_Header = 0x00, /**< CDC class-specific Header functional descriptor. */ | ||
| 190 | CDC_DSUBTYPE_CSInterface_CallManagement = 0x01, /**< CDC class-specific Call Management functional descriptor. */ | ||
| 191 | CDC_DSUBTYPE_CSInterface_ACM = 0x02, /**< CDC class-specific Abstract Control Model functional descriptor. */ | ||
| 192 | CDC_DSUBTYPE_CSInterface_DirectLine = 0x03, /**< CDC class-specific Direct Line functional descriptor. */ | ||
| 193 | CDC_DSUBTYPE_CSInterface_TelephoneRinger = 0x04, /**< CDC class-specific Telephone Ringer functional descriptor. */ | ||
| 194 | CDC_DSUBTYPE_CSInterface_TelephoneCall = 0x05, /**< CDC class-specific Telephone Call functional descriptor. */ | ||
| 195 | CDC_DSUBTYPE_CSInterface_Union = 0x06, /**< CDC class-specific Union functional descriptor. */ | ||
| 196 | CDC_DSUBTYPE_CSInterface_CountrySelection = 0x07, /**< CDC class-specific Country Selection functional descriptor. */ | ||
| 197 | CDC_DSUBTYPE_CSInterface_TelephoneOpModes = 0x08, /**< CDC class-specific Telephone Operation Modes functional descriptor. */ | ||
| 198 | CDC_DSUBTYPE_CSInterface_USBTerminal = 0x09, /**< CDC class-specific USB Terminal functional descriptor. */ | ||
| 199 | CDC_DSUBTYPE_CSInterface_NetworkChannel = 0x0A, /**< CDC class-specific Network Channel functional descriptor. */ | ||
| 200 | CDC_DSUBTYPE_CSInterface_ProtocolUnit = 0x0B, /**< CDC class-specific Protocol Unit functional descriptor. */ | ||
| 201 | CDC_DSUBTYPE_CSInterface_ExtensionUnit = 0x0C, /**< CDC class-specific Extension Unit functional descriptor. */ | ||
| 202 | CDC_DSUBTYPE_CSInterface_MultiChannel = 0x0D, /**< CDC class-specific Multi-Channel Management functional descriptor. */ | ||
| 203 | CDC_DSUBTYPE_CSInterface_CAPI = 0x0E, /**< CDC class-specific Common ISDN API functional descriptor. */ | ||
| 204 | CDC_DSUBTYPE_CSInterface_Ethernet = 0x0F, /**< CDC class-specific Ethernet functional descriptor. */ | ||
| 205 | CDC_DSUBTYPE_CSInterface_ATM = 0x10, /**< CDC class-specific Asynchronous Transfer Mode functional descriptor. */ | ||
| 206 | }; | ||
| 207 | |||
| 208 | /** Enum for the possible line encoding formats of a virtual serial port. */ | ||
| 209 | enum CDC_LineEncodingFormats_t | ||
| 210 | { | ||
| 211 | CDC_LINEENCODING_OneStopBit = 0, /**< Each frame contains one stop bit. */ | ||
| 212 | CDC_LINEENCODING_OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits. */ | ||
| 213 | CDC_LINEENCODING_TwoStopBits = 2, /**< Each frame contains two stop bits. */ | ||
| 214 | }; | ||
| 215 | |||
| 216 | /** Enum for the possible line encoding parity settings of a virtual serial port. */ | ||
| 217 | enum CDC_LineEncodingParity_t | ||
| 218 | { | ||
| 219 | CDC_PARITY_None = 0, /**< No parity bit mode on each frame. */ | ||
| 220 | CDC_PARITY_Odd = 1, /**< Odd parity bit mode on each frame. */ | ||
| 221 | CDC_PARITY_Even = 2, /**< Even parity bit mode on each frame. */ | ||
| 222 | CDC_PARITY_Mark = 3, /**< Mark parity bit mode on each frame. */ | ||
| 223 | CDC_PARITY_Space = 4, /**< Space parity bit mode on each frame. */ | ||
| 224 | }; | ||
| 225 | |||
| 226 | /* Type Defines: */ | ||
| 227 | /** \brief CDC class-specific Functional Header Descriptor (LUFA naming conventions). | ||
| 228 | * | ||
| 229 | * Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device | ||
| 230 | * contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration. | ||
| 231 | * See the CDC class specification for more details. | ||
| 232 | * | ||
| 233 | * \see \ref USB_CDC_StdDescriptor_FunctionalHeader_t for the version of this type with standard element names. | ||
| 234 | * | ||
| 235 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 236 | */ | ||
| 237 | typedef struct | ||
| 238 | { | ||
| 239 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 240 | uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors, | ||
| 241 | * must be \ref CDC_DSUBTYPE_CSInterface_Header. | ||
| 242 | */ | ||
| 243 | uint16_t CDCSpecification; /**< Version number of the CDC specification implemented by the device, | ||
| 244 | * encoded in BCD format. | ||
| 245 | * | ||
| 246 | * \see \ref VERSION_BCD() utility macro. | ||
| 247 | */ | ||
| 248 | } ATTR_PACKED USB_CDC_Descriptor_FunctionalHeader_t; | ||
| 249 | |||
| 250 | /** \brief CDC class-specific Functional Header Descriptor (USB-IF naming conventions). | ||
| 251 | * | ||
| 252 | * Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device | ||
| 253 | * contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration. | ||
| 254 | * See the CDC class specification for more details. | ||
| 255 | * | ||
| 256 | * \see \ref USB_CDC_Descriptor_FunctionalHeader_t for the version of this type with non-standard LUFA specific | ||
| 257 | * element names. | ||
| 258 | * | ||
| 259 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 260 | */ | ||
| 261 | typedef struct | ||
| 262 | { | ||
| 263 | uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */ | ||
| 264 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 265 | * given by the specific class. | ||
| 266 | */ | ||
| 267 | uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors, | ||
| 268 | * must be \ref CDC_DSUBTYPE_CSInterface_Header. | ||
| 269 | */ | ||
| 270 | uint16_t bcdCDC; /**< Version number of the CDC specification implemented by the device, encoded in BCD format. | ||
| 271 | * | ||
| 272 | * \see \ref VERSION_BCD() utility macro. | ||
| 273 | */ | ||
| 274 | } ATTR_PACKED USB_CDC_StdDescriptor_FunctionalHeader_t; | ||
| 275 | |||
| 276 | /** \brief CDC class-specific Functional ACM Descriptor (LUFA naming conventions). | ||
| 277 | * | ||
| 278 | * Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface | ||
| 279 | * supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details. | ||
| 280 | * | ||
| 281 | * \see \ref USB_CDC_StdDescriptor_FunctionalACM_t for the version of this type with standard element names. | ||
| 282 | * | ||
| 283 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 284 | */ | ||
| 285 | typedef struct | ||
| 286 | { | ||
| 287 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 288 | uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors, | ||
| 289 | * must be \ref CDC_DSUBTYPE_CSInterface_ACM. | ||
| 290 | */ | ||
| 291 | uint8_t Capabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices, | ||
| 292 | * this should be set to a fixed value of \c 0x06 - for other capabilities, refer | ||
| 293 | * to the CDC ACM specification. | ||
| 294 | */ | ||
| 295 | } ATTR_PACKED USB_CDC_Descriptor_FunctionalACM_t; | ||
| 296 | |||
| 297 | /** \brief CDC class-specific Functional ACM Descriptor (USB-IF naming conventions). | ||
| 298 | * | ||
| 299 | * Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface | ||
| 300 | * supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details. | ||
| 301 | * | ||
| 302 | * \see \ref USB_CDC_Descriptor_FunctionalACM_t for the version of this type with non-standard LUFA specific | ||
| 303 | * element names. | ||
| 304 | * | ||
| 305 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 306 | */ | ||
| 307 | typedef struct | ||
| 308 | { | ||
| 309 | uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */ | ||
| 310 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 311 | * given by the specific class. | ||
| 312 | */ | ||
| 313 | uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors, | ||
| 314 | * must be \ref CDC_DSUBTYPE_CSInterface_ACM. | ||
| 315 | */ | ||
| 316 | uint8_t bmCapabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices, | ||
| 317 | * this should be set to a fixed value of 0x06 - for other capabilities, refer | ||
| 318 | * to the CDC ACM specification. | ||
| 319 | */ | ||
| 320 | } ATTR_PACKED USB_CDC_StdDescriptor_FunctionalACM_t; | ||
| 321 | |||
| 322 | /** \brief CDC class-specific Functional Union Descriptor (LUFA naming conventions). | ||
| 323 | * | ||
| 324 | * Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific | ||
| 325 | * CDC control and data interfaces are related. See the CDC class specification for more details. | ||
| 326 | * | ||
| 327 | * \see \ref USB_CDC_StdDescriptor_FunctionalUnion_t for the version of this type with standard element names. | ||
| 328 | * | ||
| 329 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 330 | */ | ||
| 331 | typedef struct | ||
| 332 | { | ||
| 333 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 334 | uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors, | ||
| 335 | * must be \ref CDC_DSUBTYPE_CSInterface_Union. | ||
| 336 | */ | ||
| 337 | uint8_t MasterInterfaceNumber; /**< Interface number of the CDC Control interface. */ | ||
| 338 | uint8_t SlaveInterfaceNumber; /**< Interface number of the CDC Data interface. */ | ||
| 339 | } ATTR_PACKED USB_CDC_Descriptor_FunctionalUnion_t; | ||
| 340 | |||
| 341 | /** \brief CDC class-specific Functional Union Descriptor (USB-IF naming conventions). | ||
| 342 | * | ||
| 343 | * Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific | ||
| 344 | * CDC control and data interfaces are related. See the CDC class specification for more details. | ||
| 345 | * | ||
| 346 | * \see \ref USB_CDC_Descriptor_FunctionalUnion_t for the version of this type with non-standard LUFA specific | ||
| 347 | * element names. | ||
| 348 | * | ||
| 349 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 350 | */ | ||
| 351 | typedef struct | ||
| 352 | { | ||
| 353 | uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */ | ||
| 354 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 355 | * given by the specific class. | ||
| 356 | */ | ||
| 357 | uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors, | ||
| 358 | * must be \ref CDC_DSUBTYPE_CSInterface_Union. | ||
| 359 | */ | ||
| 360 | uint8_t bMasterInterface; /**< Interface number of the CDC Control interface. */ | ||
| 361 | uint8_t bSlaveInterface0; /**< Interface number of the CDC Data interface. */ | ||
| 362 | } ATTR_PACKED USB_CDC_StdDescriptor_FunctionalUnion_t; | ||
| 363 | |||
| 364 | /** \brief CDC Virtual Serial Port Line Encoding Settings Structure. | ||
| 365 | * | ||
| 366 | * Type define for a CDC Line Encoding structure, used to hold the various encoding parameters for a virtual | ||
| 367 | * serial port. | ||
| 368 | * | ||
| 369 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 370 | */ | ||
| 371 | typedef struct | ||
| 372 | { | ||
| 373 | uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second. */ | ||
| 374 | uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the | ||
| 375 | * \ref CDC_LineEncodingFormats_t enum. | ||
| 376 | */ | ||
| 377 | uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the | ||
| 378 | * \ref CDC_LineEncodingParity_t enum. | ||
| 379 | */ | ||
| 380 | uint8_t DataBits; /**< Bits of data per character of the virtual serial port. */ | ||
| 381 | } ATTR_PACKED CDC_LineEncoding_t; | ||
| 382 | |||
| 383 | /* Disable C linkage for C++ Compilers: */ | ||
| 384 | #if defined(__cplusplus) | ||
| 385 | } | ||
| 386 | #endif | ||
| 387 | |||
| 388 | #endif | ||
| 389 | |||
| 390 | /** @} */ | ||
| 391 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h new file mode 100644 index 000000000..6e700a9b1 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h | |||
| @@ -0,0 +1,681 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB HID Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB HID Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassHID | ||
| 41 | * \defgroup Group_USBClassHIDCommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassHIDCommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * HID Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _HID_CLASS_COMMON_H_ | ||
| 51 | #define _HID_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Includes: */ | ||
| 54 | #include "../../Core/StdDescriptors.h" | ||
| 55 | #include "HIDParser.h" | ||
| 56 | |||
| 57 | /* Enable C linkage for C++ Compilers: */ | ||
| 58 | #if defined(__cplusplus) | ||
| 59 | extern "C" { | ||
| 60 | #endif | ||
| 61 | |||
| 62 | /* Preprocessor Checks: */ | ||
| 63 | #if !defined(__INCLUDE_FROM_HID_DRIVER) | ||
| 64 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* Macros: */ | ||
| 68 | /** \name Keyboard Standard Report Modifier Masks */ | ||
| 69 | //@{ | ||
| 70 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's left control key is currently pressed. */ | ||
| 71 | #define HID_KEYBOARD_MODIFIER_LEFTCTRL (1 << 0) | ||
| 72 | |||
| 73 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's left shift key is currently pressed. */ | ||
| 74 | #define HID_KEYBOARD_MODIFIER_LEFTSHIFT (1 << 1) | ||
| 75 | |||
| 76 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's left alt key is currently pressed. */ | ||
| 77 | #define HID_KEYBOARD_MODIFIER_LEFTALT (1 << 2) | ||
| 78 | |||
| 79 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's left GUI key is currently pressed. */ | ||
| 80 | #define HID_KEYBOARD_MODIFIER_LEFTGUI (1 << 3) | ||
| 81 | |||
| 82 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's right control key is currently pressed. */ | ||
| 83 | #define HID_KEYBOARD_MODIFIER_RIGHTCTRL (1 << 4) | ||
| 84 | |||
| 85 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's right shift key is currently pressed. */ | ||
| 86 | #define HID_KEYBOARD_MODIFIER_RIGHTSHIFT (1 << 5) | ||
| 87 | |||
| 88 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's right alt key is currently pressed. */ | ||
| 89 | #define HID_KEYBOARD_MODIFIER_RIGHTALT (1 << 6) | ||
| 90 | |||
| 91 | /** Constant for a keyboard report modifier byte, indicating that the keyboard's right GUI key is currently pressed. */ | ||
| 92 | #define HID_KEYBOARD_MODIFIER_RIGHTGUI (1 << 7) | ||
| 93 | //@} | ||
| 94 | |||
| 95 | /** \name Keyboard Standard Report LED Masks */ | ||
| 96 | //@{ | ||
| 97 | /** Constant for a keyboard output report LED byte, indicating that the host's NUM LOCK mode is currently set. */ | ||
| 98 | #define HID_KEYBOARD_LED_NUMLOCK (1 << 0) | ||
| 99 | |||
| 100 | /** Constant for a keyboard output report LED byte, indicating that the host's CAPS LOCK mode is currently set. */ | ||
| 101 | #define HID_KEYBOARD_LED_CAPSLOCK (1 << 1) | ||
| 102 | |||
| 103 | /** Constant for a keyboard output report LED byte, indicating that the host's SCROLL LOCK mode is currently set. */ | ||
| 104 | #define HID_KEYBOARD_LED_SCROLLLOCK (1 << 2) | ||
| 105 | |||
| 106 | /** Constant for a keyboard output report LED byte, indicating that the host's COMPOSE mode is currently set. */ | ||
| 107 | #define HID_KEYBOARD_LED_COMPOSE (1 << 3) | ||
| 108 | |||
| 109 | /** Constant for a keyboard output report LED byte, indicating that the host's KANA mode is currently set. */ | ||
| 110 | #define HID_KEYBOARD_LED_KANA (1 << 4) | ||
| 111 | //@} | ||
| 112 | |||
| 113 | /** \name Keyboard Standard Report Key Scan-codes */ | ||
| 114 | //@{ | ||
| 115 | #define HID_KEYBOARD_SC_ERROR_ROLLOVER 0x01 | ||
| 116 | #define HID_KEYBOARD_SC_POST_FAIL 0x02 | ||
| 117 | #define HID_KEYBOARD_SC_ERROR_UNDEFINED 0x03 | ||
| 118 | #define HID_KEYBOARD_SC_A 0x04 | ||
| 119 | #define HID_KEYBOARD_SC_B 0x05 | ||
| 120 | #define HID_KEYBOARD_SC_C 0x06 | ||
| 121 | #define HID_KEYBOARD_SC_D 0x07 | ||
| 122 | #define HID_KEYBOARD_SC_E 0x08 | ||
| 123 | #define HID_KEYBOARD_SC_F 0x09 | ||
| 124 | #define HID_KEYBOARD_SC_G 0x0A | ||
| 125 | #define HID_KEYBOARD_SC_H 0x0B | ||
| 126 | #define HID_KEYBOARD_SC_I 0x0C | ||
| 127 | #define HID_KEYBOARD_SC_J 0x0D | ||
| 128 | #define HID_KEYBOARD_SC_K 0x0E | ||
| 129 | #define HID_KEYBOARD_SC_L 0x0F | ||
| 130 | #define HID_KEYBOARD_SC_M 0x10 | ||
| 131 | #define HID_KEYBOARD_SC_N 0x11 | ||
| 132 | #define HID_KEYBOARD_SC_O 0x12 | ||
| 133 | #define HID_KEYBOARD_SC_P 0x13 | ||
| 134 | #define HID_KEYBOARD_SC_Q 0x14 | ||
| 135 | #define HID_KEYBOARD_SC_R 0x15 | ||
| 136 | #define HID_KEYBOARD_SC_S 0x16 | ||
| 137 | #define HID_KEYBOARD_SC_T 0x17 | ||
| 138 | #define HID_KEYBOARD_SC_U 0x18 | ||
| 139 | #define HID_KEYBOARD_SC_V 0x19 | ||
| 140 | #define HID_KEYBOARD_SC_W 0x1A | ||
| 141 | #define HID_KEYBOARD_SC_X 0x1B | ||
| 142 | #define HID_KEYBOARD_SC_Y 0x1C | ||
| 143 | #define HID_KEYBOARD_SC_Z 0x1D | ||
| 144 | #define HID_KEYBOARD_SC_1_AND_EXCLAMATION 0x1E | ||
| 145 | #define HID_KEYBOARD_SC_2_AND_AT 0x1F | ||
| 146 | #define HID_KEYBOARD_SC_3_AND_HASHMARK 0x20 | ||
| 147 | #define HID_KEYBOARD_SC_4_AND_DOLLAR 0x21 | ||
| 148 | #define HID_KEYBOARD_SC_5_AND_PERCENTAGE 0x22 | ||
| 149 | #define HID_KEYBOARD_SC_6_AND_CARET 0x23 | ||
| 150 | #define HID_KEYBOARD_SC_7_AND_AMPERSAND 0x24 | ||
| 151 | #define HID_KEYBOARD_SC_8_AND_ASTERISK 0x25 | ||
| 152 | #define HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS 0x26 | ||
| 153 | #define HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS 0x27 | ||
| 154 | #define HID_KEYBOARD_SC_ENTER 0x28 | ||
| 155 | #define HID_KEYBOARD_SC_ESCAPE 0x29 | ||
| 156 | #define HID_KEYBOARD_SC_BACKSPACE 0x2A | ||
| 157 | #define HID_KEYBOARD_SC_TAB 0x2B | ||
| 158 | #define HID_KEYBOARD_SC_SPACE 0x2C | ||
| 159 | #define HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE 0x2D | ||
| 160 | #define HID_KEYBOARD_SC_EQUAL_AND_PLUS 0x2E | ||
| 161 | #define HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE 0x2F | ||
| 162 | #define HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE 0x30 | ||
| 163 | #define HID_KEYBOARD_SC_BACKSLASH_AND_PIPE 0x31 | ||
| 164 | #define HID_KEYBOARD_SC_NON_US_HASHMARK_AND_TILDE 0x32 | ||
| 165 | #define HID_KEYBOARD_SC_SEMICOLON_AND_COLON 0x33 | ||
| 166 | #define HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE 0x34 | ||
| 167 | #define HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE 0x35 | ||
| 168 | #define HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN 0x36 | ||
| 169 | #define HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN 0x37 | ||
| 170 | #define HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK 0x38 | ||
| 171 | #define HID_KEYBOARD_SC_CAPS_LOCK 0x39 | ||
| 172 | #define HID_KEYBOARD_SC_F1 0x3A | ||
| 173 | #define HID_KEYBOARD_SC_F2 0x3B | ||
| 174 | #define HID_KEYBOARD_SC_F3 0x3C | ||
| 175 | #define HID_KEYBOARD_SC_F4 0x3D | ||
| 176 | #define HID_KEYBOARD_SC_F5 0x3E | ||
| 177 | #define HID_KEYBOARD_SC_F6 0x3F | ||
| 178 | #define HID_KEYBOARD_SC_F7 0x40 | ||
| 179 | #define HID_KEYBOARD_SC_F8 0x41 | ||
| 180 | #define HID_KEYBOARD_SC_F9 0x42 | ||
| 181 | #define HID_KEYBOARD_SC_F10 0x43 | ||
| 182 | #define HID_KEYBOARD_SC_F11 0x44 | ||
| 183 | #define HID_KEYBOARD_SC_F12 0x45 | ||
| 184 | #define HID_KEYBOARD_SC_PRINT_SCREEN 0x46 | ||
| 185 | #define HID_KEYBOARD_SC_SCROLL_LOCK 0x47 | ||
| 186 | #define HID_KEYBOARD_SC_PAUSE 0x48 | ||
| 187 | #define HID_KEYBOARD_SC_INSERT 0x49 | ||
| 188 | #define HID_KEYBOARD_SC_HOME 0x4A | ||
| 189 | #define HID_KEYBOARD_SC_PAGE_UP 0x4B | ||
| 190 | #define HID_KEYBOARD_SC_DELETE 0x4C | ||
| 191 | #define HID_KEYBOARD_SC_END 0x4D | ||
| 192 | #define HID_KEYBOARD_SC_PAGE_DOWN 0x4E | ||
| 193 | #define HID_KEYBOARD_SC_RIGHT_ARROW 0x4F | ||
| 194 | #define HID_KEYBOARD_SC_LEFT_ARROW 0x50 | ||
| 195 | #define HID_KEYBOARD_SC_DOWN_ARROW 0x51 | ||
| 196 | #define HID_KEYBOARD_SC_UP_ARROW 0x52 | ||
| 197 | #define HID_KEYBOARD_SC_NUM_LOCK 0x53 | ||
| 198 | #define HID_KEYBOARD_SC_KEYPAD_SLASH 0x54 | ||
| 199 | #define HID_KEYBOARD_SC_KEYPAD_ASTERISK 0x55 | ||
| 200 | #define HID_KEYBOARD_SC_KEYPAD_MINUS 0x56 | ||
| 201 | #define HID_KEYBOARD_SC_KEYPAD_PLUS 0x57 | ||
| 202 | #define HID_KEYBOARD_SC_KEYPAD_ENTER 0x58 | ||
| 203 | #define HID_KEYBOARD_SC_KEYPAD_1_AND_END 0x59 | ||
| 204 | #define HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW 0x5A | ||
| 205 | #define HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN 0x5B | ||
| 206 | #define HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW 0x5C | ||
| 207 | #define HID_KEYBOARD_SC_KEYPAD_5 0x5D | ||
| 208 | #define HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW 0x5E | ||
| 209 | #define HID_KEYBOARD_SC_KEYPAD_7_AND_HOME 0x5F | ||
| 210 | #define HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW 0x60 | ||
| 211 | #define HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP 0x61 | ||
| 212 | #define HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT 0x62 | ||
| 213 | #define HID_KEYBOARD_SC_KEYPAD_DOT_AND_DELETE 0x63 | ||
| 214 | #define HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE 0x64 | ||
| 215 | #define HID_KEYBOARD_SC_APPLICATION 0x65 | ||
| 216 | #define HID_KEYBOARD_SC_POWER 0x66 | ||
| 217 | #define HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN 0x67 | ||
| 218 | #define HID_KEYBOARD_SC_F13 0x68 | ||
| 219 | #define HID_KEYBOARD_SC_F14 0x69 | ||
| 220 | #define HID_KEYBOARD_SC_F15 0x6A | ||
| 221 | #define HID_KEYBOARD_SC_F16 0x6B | ||
| 222 | #define HID_KEYBOARD_SC_F17 0x6C | ||
| 223 | #define HID_KEYBOARD_SC_F18 0x6D | ||
| 224 | #define HID_KEYBOARD_SC_F19 0x6E | ||
| 225 | #define HID_KEYBOARD_SC_F20 0x6F | ||
| 226 | #define HID_KEYBOARD_SC_F21 0x70 | ||
| 227 | #define HID_KEYBOARD_SC_F22 0x71 | ||
| 228 | #define HID_KEYBOARD_SC_F23 0x72 | ||
| 229 | #define HID_KEYBOARD_SC_F24 0x73 | ||
| 230 | #define HID_KEYBOARD_SC_EXECUTE 0x74 | ||
| 231 | #define HID_KEYBOARD_SC_HELP 0x75 | ||
| 232 | #define HID_KEYBOARD_SC_MENU 0x76 | ||
| 233 | #define HID_KEYBOARD_SC_SELECT 0x77 | ||
| 234 | #define HID_KEYBOARD_SC_STOP 0x78 | ||
| 235 | #define HID_KEYBOARD_SC_AGAIN 0x79 | ||
| 236 | #define HID_KEYBOARD_SC_UNDO 0x7A | ||
| 237 | #define HID_KEYBOARD_SC_CUT 0x7B | ||
| 238 | #define HID_KEYBOARD_SC_COPY 0x7C | ||
| 239 | #define HID_KEYBOARD_SC_PASTE 0x7D | ||
| 240 | #define HID_KEYBOARD_SC_FIND 0x7E | ||
| 241 | #define HID_KEYBOARD_SC_MUTE 0x7F | ||
| 242 | #define HID_KEYBOARD_SC_VOLUME_UP 0x80 | ||
| 243 | #define HID_KEYBOARD_SC_VOLUME_DOWN 0x81 | ||
| 244 | #define HID_KEYBOARD_SC_LOCKING_CAPS_LOCK 0x82 | ||
| 245 | #define HID_KEYBOARD_SC_LOCKING_NUM_LOCK 0x83 | ||
| 246 | #define HID_KEYBOARD_SC_LOCKING_SCROLL_LOCK 0x84 | ||
| 247 | #define HID_KEYBOARD_SC_KEYPAD_COMMA 0x85 | ||
| 248 | #define HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN_AS400 0x86 | ||
| 249 | #define HID_KEYBOARD_SC_INTERNATIONAL1 0x87 | ||
| 250 | #define HID_KEYBOARD_SC_INTERNATIONAL2 0x88 | ||
| 251 | #define HID_KEYBOARD_SC_INTERNATIONAL3 0x89 | ||
| 252 | #define HID_KEYBOARD_SC_INTERNATIONAL4 0x8A | ||
| 253 | #define HID_KEYBOARD_SC_INTERNATIONAL5 0x8B | ||
| 254 | #define HID_KEYBOARD_SC_INTERNATIONAL6 0x8C | ||
| 255 | #define HID_KEYBOARD_SC_INTERNATIONAL7 0x8D | ||
| 256 | #define HID_KEYBOARD_SC_INTERNATIONAL8 0x8E | ||
| 257 | #define HID_KEYBOARD_SC_INTERNATIONAL9 0x8F | ||
| 258 | #define HID_KEYBOARD_SC_LANG1 0x90 | ||
| 259 | #define HID_KEYBOARD_SC_LANG2 0x91 | ||
| 260 | #define HID_KEYBOARD_SC_LANG3 0x92 | ||
| 261 | #define HID_KEYBOARD_SC_LANG4 0x93 | ||
| 262 | #define HID_KEYBOARD_SC_LANG5 0x94 | ||
| 263 | #define HID_KEYBOARD_SC_LANG6 0x95 | ||
| 264 | #define HID_KEYBOARD_SC_LANG7 0x96 | ||
| 265 | #define HID_KEYBOARD_SC_LANG8 0x97 | ||
| 266 | #define HID_KEYBOARD_SC_LANG9 0x98 | ||
| 267 | #define HID_KEYBOARD_SC_ALTERNATE_ERASE 0x99 | ||
| 268 | #define HID_KEYBOARD_SC_SYSREQ 0x9A | ||
| 269 | #define HID_KEYBOARD_SC_CANCEL 0x9B | ||
| 270 | #define HID_KEYBOARD_SC_CLEAR 0x9C | ||
| 271 | #define HID_KEYBOARD_SC_PRIOR 0x9D | ||
| 272 | #define HID_KEYBOARD_SC_RETURN 0x9E | ||
| 273 | #define HID_KEYBOARD_SC_SEPARATOR 0x9F | ||
| 274 | #define HID_KEYBOARD_SC_OUT 0xA0 | ||
| 275 | #define HID_KEYBOARD_SC_OPER 0xA1 | ||
| 276 | #define HID_KEYBOARD_SC_CLEAR_AND_AGAIN 0xA2 | ||
| 277 | #define HID_KEYBOARD_SC_CRSEL_AND_PROPS 0xA3 | ||
| 278 | #define HID_KEYBOARD_SC_EXSEL 0xA4 | ||
| 279 | #define HID_KEYBOARD_SC_KEYPAD_00 0xB0 | ||
| 280 | #define HID_KEYBOARD_SC_KEYPAD_000 0xB1 | ||
| 281 | #define HID_KEYBOARD_SC_THOUSANDS_SEPARATOR 0xB2 | ||
| 282 | #define HID_KEYBOARD_SC_DECIMAL_SEPARATOR 0xB3 | ||
| 283 | #define HID_KEYBOARD_SC_CURRENCY_UNIT 0xB4 | ||
| 284 | #define HID_KEYBOARD_SC_CURRENCY_SUB_UNIT 0xB5 | ||
| 285 | #define HID_KEYBOARD_SC_KEYPAD_OPENING_PARENTHESIS 0xB6 | ||
| 286 | #define HID_KEYBOARD_SC_KEYPAD_CLOSING_PARENTHESIS 0xB7 | ||
| 287 | #define HID_KEYBOARD_SC_KEYPAD_OPENING_BRACE 0xB8 | ||
| 288 | #define HID_KEYBOARD_SC_KEYPAD_CLOSING_BRACE 0xB9 | ||
| 289 | #define HID_KEYBOARD_SC_KEYPAD_TAB 0xBA | ||
| 290 | #define HID_KEYBOARD_SC_KEYPAD_BACKSPACE 0xBB | ||
| 291 | #define HID_KEYBOARD_SC_KEYPAD_A 0xBC | ||
| 292 | #define HID_KEYBOARD_SC_KEYPAD_B 0xBD | ||
| 293 | #define HID_KEYBOARD_SC_KEYPAD_C 0xBE | ||
| 294 | #define HID_KEYBOARD_SC_KEYPAD_D 0xBF | ||
| 295 | #define HID_KEYBOARD_SC_KEYPAD_E 0xC0 | ||
| 296 | #define HID_KEYBOARD_SC_KEYPAD_F 0xC1 | ||
| 297 | #define HID_KEYBOARD_SC_KEYPAD_XOR 0xC2 | ||
| 298 | #define HID_KEYBOARD_SC_KEYPAD_CARET 0xC3 | ||
| 299 | #define HID_KEYBOARD_SC_KEYPAD_PERCENTAGE 0xC4 | ||
| 300 | #define HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN 0xC5 | ||
| 301 | #define HID_KEYBOARD_SC_KEYPAD_GREATER_THAN_SIGN 0xC6 | ||
| 302 | #define HID_KEYBOARD_SC_KEYPAD_AMP 0xC7 | ||
| 303 | #define HID_KEYBOARD_SC_KEYPAD_AMP_AMP 0xC8 | ||
| 304 | #define HID_KEYBOARD_SC_KEYPAD_PIPE 0xC9 | ||
| 305 | #define HID_KEYBOARD_SC_KEYPAD_PIPE_PIPE 0xCA | ||
| 306 | #define HID_KEYBOARD_SC_KEYPAD_COLON 0xCB | ||
| 307 | #define HID_KEYBOARD_SC_KEYPAD_HASHMARK 0xCC | ||
| 308 | #define HID_KEYBOARD_SC_KEYPAD_SPACE 0xCD | ||
| 309 | #define HID_KEYBOARD_SC_KEYPAD_AT 0xCE | ||
| 310 | #define HID_KEYBOARD_SC_KEYPAD_EXCLAMATION_SIGN 0xCF | ||
| 311 | #define HID_KEYBOARD_SC_KEYPAD_MEMORY_STORE 0xD0 | ||
| 312 | #define HID_KEYBOARD_SC_KEYPAD_MEMORY_RECALL 0xD1 | ||
| 313 | #define HID_KEYBOARD_SC_KEYPAD_MEMORY_CLEAR 0xD2 | ||
| 314 | #define HID_KEYBOARD_SC_KEYPAD_MEMORY_ADD 0xD3 | ||
| 315 | #define HID_KEYBOARD_SC_KEYPAD_MEMORY_SUBTRACT 0xD4 | ||
| 316 | #define HID_KEYBOARD_SC_KEYPAD_MEMORY_MULTIPLY 0xD5 | ||
| 317 | #define HID_KEYBOARD_SC_KEYPAD_MEMORY_DIVIDE 0xD6 | ||
| 318 | #define HID_KEYBOARD_SC_KEYPAD_PLUS_AND_MINUS 0xD7 | ||
| 319 | #define HID_KEYBOARD_SC_KEYPAD_CLEAR 0xD8 | ||
| 320 | #define HID_KEYBOARD_SC_KEYPAD_CLEAR_ENTRY 0xD9 | ||
| 321 | #define HID_KEYBOARD_SC_KEYPAD_BINARY 0xDA | ||
| 322 | #define HID_KEYBOARD_SC_KEYPAD_OCTAL 0xDB | ||
| 323 | #define HID_KEYBOARD_SC_KEYPAD_DECIMAL 0xDC | ||
| 324 | #define HID_KEYBOARD_SC_KEYPAD_HEXADECIMAL 0xDD | ||
| 325 | #define HID_KEYBOARD_SC_LEFT_CONTROL 0xE0 | ||
| 326 | #define HID_KEYBOARD_SC_LEFT_SHIFT 0xE1 | ||
| 327 | #define HID_KEYBOARD_SC_LEFT_ALT 0xE2 | ||
| 328 | #define HID_KEYBOARD_SC_LEFT_GUI 0xE3 | ||
| 329 | #define HID_KEYBOARD_SC_RIGHT_CONTROL 0xE4 | ||
| 330 | #define HID_KEYBOARD_SC_RIGHT_SHIFT 0xE5 | ||
| 331 | #define HID_KEYBOARD_SC_RIGHT_ALT 0xE6 | ||
| 332 | #define HID_KEYBOARD_SC_RIGHT_GUI 0xE7 | ||
| 333 | #define HID_KEYBOARD_SC_MEDIA_PLAY 0xE8 | ||
| 334 | #define HID_KEYBOARD_SC_MEDIA_STOP 0xE9 | ||
| 335 | #define HID_KEYBOARD_SC_MEDIA_PREVIOUS_TRACK 0xEA | ||
| 336 | #define HID_KEYBOARD_SC_MEDIA_NEXT_TRACK 0xEB | ||
| 337 | #define HID_KEYBOARD_SC_MEDIA_EJECT 0xEC | ||
| 338 | #define HID_KEYBOARD_SC_MEDIA_VOLUME_UP 0xED | ||
| 339 | #define HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN 0xEE | ||
| 340 | #define HID_KEYBOARD_SC_MEDIA_MUTE 0xEF | ||
| 341 | #define HID_KEYBOARD_SC_MEDIA_WWW 0xF0 | ||
| 342 | #define HID_KEYBOARD_SC_MEDIA_BACKWARD 0xF1 | ||
| 343 | #define HID_KEYBOARD_SC_MEDIA_FORWARD 0xF2 | ||
| 344 | #define HID_KEYBOARD_SC_MEDIA_CANCEL 0xF3 | ||
| 345 | #define HID_KEYBOARD_SC_MEDIA_SEARCH 0xF4 | ||
| 346 | #define HID_KEYBOARD_SC_MEDIA_SLEEP 0xF8 | ||
| 347 | #define HID_KEYBOARD_SC_MEDIA_LOCK 0xF9 | ||
| 348 | #define HID_KEYBOARD_SC_MEDIA_RELOAD 0xFA | ||
| 349 | #define HID_KEYBOARD_SC_MEDIA_CALCULATOR 0xFB | ||
| 350 | //@} | ||
| 351 | |||
| 352 | /** \name Common HID Device Report Descriptors */ | ||
| 353 | //@{ | ||
| 354 | /** \hideinitializer | ||
| 355 | * A list of HID report item array elements that describe a typical HID USB Joystick. The resulting report | ||
| 356 | * descriptor is structured according to the following layout: | ||
| 357 | * | ||
| 358 | * \code | ||
| 359 | * struct | ||
| 360 | * { | ||
| 361 | * intA_t X; // Signed X axis value | ||
| 362 | * intA_t Y; // Signed Y axis value | ||
| 363 | * intA_t Z; // Signed Z axis value | ||
| 364 | * uintB_t Buttons; // Pressed buttons bitmask | ||
| 365 | * } Joystick_Report; | ||
| 366 | * \endcode | ||
| 367 | * | ||
| 368 | * Where \c uintA_t is a type large enough to hold the ranges of the signed \c MinAxisVal and \c MaxAxisVal values, | ||
| 369 | * and \c intB_t is a type large enough to hold one bit per button. | ||
| 370 | * | ||
| 371 | * \param[in] MinAxisVal Minimum logical axis value (16-bit). | ||
| 372 | * \param[in] MaxAxisVal Maximum logical axis value (16-bit). | ||
| 373 | * \param[in] MinPhysicalVal Minimum physical axis value, for movement resolution calculations (16-bit). | ||
| 374 | * \param[in] MaxPhysicalVal Maximum physical axis value, for movement resolution calculations (16-bit). | ||
| 375 | * \param[in] Buttons Total number of buttons in the device (8-bit). | ||
| 376 | */ | ||
| 377 | #define HID_DESCRIPTOR_JOYSTICK(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons) \ | ||
| 378 | HID_RI_USAGE_PAGE(8, 0x01), \ | ||
| 379 | HID_RI_USAGE(8, 0x04), \ | ||
| 380 | HID_RI_COLLECTION(8, 0x01), \ | ||
| 381 | HID_RI_USAGE(8, 0x01), \ | ||
| 382 | HID_RI_COLLECTION(8, 0x00), \ | ||
| 383 | HID_RI_USAGE(8, 0x30), \ | ||
| 384 | HID_RI_USAGE(8, 0x31), \ | ||
| 385 | HID_RI_USAGE(8, 0x32), \ | ||
| 386 | HID_RI_LOGICAL_MINIMUM(16, MinAxisVal), \ | ||
| 387 | HID_RI_LOGICAL_MAXIMUM(16, MaxAxisVal), \ | ||
| 388 | HID_RI_PHYSICAL_MINIMUM(16, MinPhysicalVal), \ | ||
| 389 | HID_RI_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \ | ||
| 390 | HID_RI_REPORT_COUNT(8, 3), \ | ||
| 391 | HID_RI_REPORT_SIZE(8, (((MinAxisVal >= -128) && (MaxAxisVal <= 127)) ? 8 : 16)), \ | ||
| 392 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ | ||
| 393 | HID_RI_END_COLLECTION(0), \ | ||
| 394 | HID_RI_USAGE_PAGE(8, 0x09), \ | ||
| 395 | HID_RI_USAGE_MINIMUM(8, 0x01), \ | ||
| 396 | HID_RI_USAGE_MAXIMUM(8, Buttons), \ | ||
| 397 | HID_RI_LOGICAL_MINIMUM(8, 0x00), \ | ||
| 398 | HID_RI_LOGICAL_MAXIMUM(8, 0x01), \ | ||
| 399 | HID_RI_REPORT_SIZE(8, 0x01), \ | ||
| 400 | HID_RI_REPORT_COUNT(8, Buttons), \ | ||
| 401 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ | ||
| 402 | HID_RI_REPORT_SIZE(8, (Buttons % 8) ? (8 - (Buttons % 8)) : 0), \ | ||
| 403 | HID_RI_REPORT_COUNT(8, 0x01), \ | ||
| 404 | HID_RI_INPUT(8, HID_IOF_CONSTANT), \ | ||
| 405 | HID_RI_END_COLLECTION(0) | ||
| 406 | |||
| 407 | /** \hideinitializer | ||
| 408 | * A list of HID report item array elements that describe a typical HID USB keyboard. The resulting report descriptor | ||
| 409 | * is compatible with \ref USB_KeyboardReport_Data_t when \c MaxKeys is equal to 6. For other values, the report will | ||
| 410 | * be structured according to the following layout: | ||
| 411 | * | ||
| 412 | * \code | ||
| 413 | * struct | ||
| 414 | * { | ||
| 415 | * uint8_t Modifier; // Keyboard modifier byte indicating pressed modifier keys (\c HID_KEYBOARD_MODIFER_* masks) | ||
| 416 | * uint8_t Reserved; // Reserved for OEM use, always set to 0. | ||
| 417 | * uint8_t KeyCode[MaxKeys]; // Length determined by the number of keys that can be reported | ||
| 418 | * } Keyboard_Report; | ||
| 419 | * \endcode | ||
| 420 | * | ||
| 421 | * \param[in] MaxKeys Number of simultaneous keys that can be reported at the one time (8-bit). | ||
| 422 | */ | ||
| 423 | #define HID_DESCRIPTOR_KEYBOARD(MaxKeys) \ | ||
| 424 | HID_RI_USAGE_PAGE(8, 0x01), \ | ||
| 425 | HID_RI_USAGE(8, 0x06), \ | ||
| 426 | HID_RI_COLLECTION(8, 0x01), \ | ||
| 427 | HID_RI_USAGE_PAGE(8, 0x07), \ | ||
| 428 | HID_RI_USAGE_MINIMUM(8, 0xE0), \ | ||
| 429 | HID_RI_USAGE_MAXIMUM(8, 0xE7), \ | ||
| 430 | HID_RI_LOGICAL_MINIMUM(8, 0x00), \ | ||
| 431 | HID_RI_LOGICAL_MAXIMUM(8, 0x01), \ | ||
| 432 | HID_RI_REPORT_SIZE(8, 0x01), \ | ||
| 433 | HID_RI_REPORT_COUNT(8, 0x08), \ | ||
| 434 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ | ||
| 435 | HID_RI_REPORT_COUNT(8, 0x01), \ | ||
| 436 | HID_RI_REPORT_SIZE(8, 0x08), \ | ||
| 437 | HID_RI_INPUT(8, HID_IOF_CONSTANT), \ | ||
| 438 | HID_RI_USAGE_PAGE(8, 0x08), \ | ||
| 439 | HID_RI_USAGE_MINIMUM(8, 0x01), \ | ||
| 440 | HID_RI_USAGE_MAXIMUM(8, 0x05), \ | ||
| 441 | HID_RI_REPORT_COUNT(8, 0x05), \ | ||
| 442 | HID_RI_REPORT_SIZE(8, 0x01), \ | ||
| 443 | HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \ | ||
| 444 | HID_RI_REPORT_COUNT(8, 0x01), \ | ||
| 445 | HID_RI_REPORT_SIZE(8, 0x03), \ | ||
| 446 | HID_RI_OUTPUT(8, HID_IOF_CONSTANT), \ | ||
| 447 | HID_RI_LOGICAL_MINIMUM(8, 0x00), \ | ||
| 448 | HID_RI_LOGICAL_MAXIMUM(16, 0xFF), \ | ||
| 449 | HID_RI_USAGE_PAGE(8, 0x07), \ | ||
| 450 | HID_RI_USAGE_MINIMUM(8, 0x00), \ | ||
| 451 | HID_RI_USAGE_MAXIMUM(8, 0xFF), \ | ||
| 452 | HID_RI_REPORT_COUNT(8, MaxKeys), \ | ||
| 453 | HID_RI_REPORT_SIZE(8, 0x08), \ | ||
| 454 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), \ | ||
| 455 | HID_RI_END_COLLECTION(0) | ||
| 456 | |||
| 457 | /** \hideinitializer | ||
| 458 | * A list of HID report item array elements that describe a typical HID USB mouse. The resulting report descriptor | ||
| 459 | * is compatible with \ref USB_MouseReport_Data_t if the \c MinAxisVal and \c MaxAxisVal values fit within a \c int8_t range | ||
| 460 | * and the number of Buttons is less than 8. For other values, the report is structured according to the following layout: | ||
| 461 | * | ||
| 462 | * \code | ||
| 463 | * struct | ||
| 464 | * { | ||
| 465 | * uintA_t Buttons; // Pressed buttons bitmask | ||
| 466 | * intB_t X; // X axis value | ||
| 467 | * intB_t Y; // Y axis value | ||
| 468 | * } Mouse_Report; | ||
| 469 | * \endcode | ||
| 470 | * | ||
| 471 | * Where \c intA_t is a type large enough to hold one bit per button, and \c intB_t is a type large enough to hold the | ||
| 472 | * ranges of the signed \c MinAxisVal and \c MaxAxisVal values. | ||
| 473 | * | ||
| 474 | * \param[in] MinAxisVal Minimum X/Y logical axis value (16-bit). | ||
| 475 | * \param[in] MaxAxisVal Maximum X/Y logical axis value (16-bit). | ||
| 476 | * \param[in] MinPhysicalVal Minimum X/Y physical axis value, for movement resolution calculations (16-bit). | ||
| 477 | * \param[in] MaxPhysicalVal Maximum X/Y physical axis value, for movement resolution calculations (16-bit). | ||
| 478 | * \param[in] Buttons Total number of buttons in the device (8-bit). | ||
| 479 | * \param[in] AbsoluteCoords Boolean \c true to use absolute X/Y coordinates (e.g. touchscreen). | ||
| 480 | */ | ||
| 481 | #define HID_DESCRIPTOR_MOUSE(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons, AbsoluteCoords) \ | ||
| 482 | HID_RI_USAGE_PAGE(8, 0x01), \ | ||
| 483 | HID_RI_USAGE(8, 0x02), \ | ||
| 484 | HID_RI_COLLECTION(8, 0x01), \ | ||
| 485 | HID_RI_USAGE(8, 0x01), \ | ||
| 486 | HID_RI_COLLECTION(8, 0x00), \ | ||
| 487 | HID_RI_USAGE_PAGE(8, 0x09), \ | ||
| 488 | HID_RI_USAGE_MINIMUM(8, 0x01), \ | ||
| 489 | HID_RI_USAGE_MAXIMUM(8, Buttons), \ | ||
| 490 | HID_RI_LOGICAL_MINIMUM(8, 0x00), \ | ||
| 491 | HID_RI_LOGICAL_MAXIMUM(8, 0x01), \ | ||
| 492 | HID_RI_REPORT_COUNT(8, Buttons), \ | ||
| 493 | HID_RI_REPORT_SIZE(8, 0x01), \ | ||
| 494 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ | ||
| 495 | HID_RI_REPORT_COUNT(8, 0x01), \ | ||
| 496 | HID_RI_REPORT_SIZE(8, (Buttons % 8) ? (8 - (Buttons % 8)) : 0), \ | ||
| 497 | HID_RI_INPUT(8, HID_IOF_CONSTANT), \ | ||
| 498 | HID_RI_USAGE_PAGE(8, 0x01), \ | ||
| 499 | HID_RI_USAGE(8, 0x30), \ | ||
| 500 | HID_RI_USAGE(8, 0x31), \ | ||
| 501 | HID_RI_LOGICAL_MINIMUM(16, MinAxisVal), \ | ||
| 502 | HID_RI_LOGICAL_MAXIMUM(16, MaxAxisVal), \ | ||
| 503 | HID_RI_PHYSICAL_MINIMUM(16, MinPhysicalVal), \ | ||
| 504 | HID_RI_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \ | ||
| 505 | HID_RI_REPORT_COUNT(8, 0x02), \ | ||
| 506 | HID_RI_REPORT_SIZE(8, (((MinAxisVal >= -128) && (MaxAxisVal <= 127)) ? 8 : 16)), \ | ||
| 507 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | (AbsoluteCoords ? HID_IOF_ABSOLUTE : HID_IOF_RELATIVE)), \ | ||
| 508 | HID_RI_END_COLLECTION(0), \ | ||
| 509 | HID_RI_END_COLLECTION(0) | ||
| 510 | |||
| 511 | /** \hideinitializer | ||
| 512 | * A list of HID report item array elements that describe a typical Vendor Defined byte array HID report descriptor, | ||
| 513 | * used for transporting arbitrary data between the USB host and device via HID reports. The resulting report should be | ||
| 514 | * a \c uint8_t byte array of the specified length in both Device to Host (IN) and Host to Device (OUT) directions. | ||
| 515 | * | ||
| 516 | * \param[in] VendorPageNum Vendor Defined HID Usage Page index, ranging from 0x00 to 0xFF. | ||
| 517 | * \param[in] CollectionUsage Vendor Usage for the encompassing report IN and OUT collection, ranging from 0x00 to 0xFF. | ||
| 518 | * \param[in] DataINUsage Vendor Usage for the IN report data, ranging from 0x00 to 0xFF. | ||
| 519 | * \param[in] DataOUTUsage Vendor Usage for the OUT report data, ranging from 0x00 to 0xFF. | ||
| 520 | * \param[in] NumBytes Length of the data IN and OUT reports. | ||
| 521 | */ | ||
| 522 | #define HID_DESCRIPTOR_VENDOR(VendorPageNum, CollectionUsage, DataINUsage, DataOUTUsage, NumBytes) \ | ||
| 523 | HID_RI_USAGE_PAGE(16, (0xFF00 | VendorPageNum)), \ | ||
| 524 | HID_RI_USAGE(8, CollectionUsage), \ | ||
| 525 | HID_RI_COLLECTION(8, 0x01), \ | ||
| 526 | HID_RI_USAGE(8, DataINUsage), \ | ||
| 527 | HID_RI_LOGICAL_MINIMUM(8, 0x00), \ | ||
| 528 | HID_RI_LOGICAL_MAXIMUM(8, 0xFF), \ | ||
| 529 | HID_RI_REPORT_SIZE(8, 0x08), \ | ||
| 530 | HID_RI_REPORT_COUNT(8, NumBytes), \ | ||
| 531 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ | ||
| 532 | HID_RI_USAGE(8, DataOUTUsage), \ | ||
| 533 | HID_RI_LOGICAL_MINIMUM(8, 0x00), \ | ||
| 534 | HID_RI_LOGICAL_MAXIMUM(8, 0xFF), \ | ||
| 535 | HID_RI_REPORT_SIZE(8, 0x08), \ | ||
| 536 | HID_RI_REPORT_COUNT(8, NumBytes), \ | ||
| 537 | HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \ | ||
| 538 | HID_RI_END_COLLECTION(0) | ||
| 539 | //@} | ||
| 540 | |||
| 541 | /* Type Defines: */ | ||
| 542 | /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the HID | ||
| 543 | * device class. | ||
| 544 | */ | ||
| 545 | enum HID_Descriptor_ClassSubclassProtocol_t | ||
| 546 | { | ||
| 547 | HID_CSCP_HIDClass = 0x03, /**< Descriptor Class value indicating that the device or interface | ||
| 548 | * belongs to the HID class. | ||
| 549 | */ | ||
| 550 | HID_CSCP_NonBootSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface | ||
| 551 | * does not implement a HID boot protocol. | ||
| 552 | */ | ||
| 553 | HID_CSCP_BootSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface | ||
| 554 | * implements a HID boot protocol. | ||
| 555 | */ | ||
| 556 | HID_CSCP_NonBootProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface | ||
| 557 | * does not belong to a HID boot protocol. | ||
| 558 | */ | ||
| 559 | HID_CSCP_KeyboardBootProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface | ||
| 560 | * belongs to the Keyboard HID boot protocol. | ||
| 561 | */ | ||
| 562 | HID_CSCP_MouseBootProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface | ||
| 563 | * belongs to the Mouse HID boot protocol. | ||
| 564 | */ | ||
| 565 | }; | ||
| 566 | |||
| 567 | /** Enum for the HID class specific control requests that can be issued by the USB bus host. */ | ||
| 568 | enum HID_ClassRequests_t | ||
| 569 | { | ||
| 570 | HID_REQ_GetReport = 0x01, /**< HID class-specific Request to get the current HID report from the device. */ | ||
| 571 | HID_REQ_GetIdle = 0x02, /**< HID class-specific Request to get the current device idle count. */ | ||
| 572 | HID_REQ_GetProtocol = 0x03, /**< HID class-specific Request to get the current HID report protocol mode. */ | ||
| 573 | HID_REQ_SetReport = 0x09, /**< HID class-specific Request to set the current HID report to the device. */ | ||
| 574 | HID_REQ_SetIdle = 0x0A, /**< HID class-specific Request to set the device's idle count. */ | ||
| 575 | HID_REQ_SetProtocol = 0x0B, /**< HID class-specific Request to set the current HID report protocol mode. */ | ||
| 576 | }; | ||
| 577 | |||
| 578 | /** Enum for the HID class specific descriptor types. */ | ||
| 579 | enum HID_DescriptorTypes_t | ||
| 580 | { | ||
| 581 | HID_DTYPE_HID = 0x21, /**< Descriptor header type value, to indicate a HID class HID descriptor. */ | ||
| 582 | HID_DTYPE_Report = 0x22, /**< Descriptor header type value, to indicate a HID class HID report descriptor. */ | ||
| 583 | }; | ||
| 584 | |||
| 585 | /** Enum for the different types of HID reports. */ | ||
| 586 | enum HID_ReportItemTypes_t | ||
| 587 | { | ||
| 588 | HID_REPORT_ITEM_In = 0, /**< Indicates that the item is an IN report type. */ | ||
| 589 | HID_REPORT_ITEM_Out = 1, /**< Indicates that the item is an OUT report type. */ | ||
| 590 | HID_REPORT_ITEM_Feature = 2, /**< Indicates that the item is a FEATURE report type. */ | ||
| 591 | }; | ||
| 592 | |||
| 593 | /** \brief HID class-specific HID Descriptor (LUFA naming conventions). | ||
| 594 | * | ||
| 595 | * Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID | ||
| 596 | * specification for details on the structure elements. | ||
| 597 | * | ||
| 598 | * \see \ref USB_HID_StdDescriptor_HID_t for the version of this type with standard element names. | ||
| 599 | * | ||
| 600 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 601 | */ | ||
| 602 | typedef struct | ||
| 603 | { | ||
| 604 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 605 | |||
| 606 | uint16_t HIDSpec; /**< BCD encoded version that the HID descriptor and device complies to. | ||
| 607 | * | ||
| 608 | * \see \ref VERSION_BCD() utility macro. | ||
| 609 | */ | ||
| 610 | uint8_t CountryCode; /**< Country code of the localized device, or zero if universal. */ | ||
| 611 | |||
| 612 | uint8_t TotalReportDescriptors; /**< Total number of HID report descriptors for the interface. */ | ||
| 613 | |||
| 614 | uint8_t HIDReportType; /**< Type of HID report, set to \ref HID_DTYPE_Report. */ | ||
| 615 | uint16_t HIDReportLength; /**< Length of the associated HID report descriptor, in bytes. */ | ||
| 616 | } ATTR_PACKED USB_HID_Descriptor_HID_t; | ||
| 617 | |||
| 618 | /** \brief HID class-specific HID Descriptor (USB-IF naming conventions). | ||
| 619 | * | ||
| 620 | * Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID | ||
| 621 | * specification for details on the structure elements. | ||
| 622 | * | ||
| 623 | * \see \ref USB_HID_Descriptor_HID_t for the version of this type with non-standard LUFA specific | ||
| 624 | * element names. | ||
| 625 | * | ||
| 626 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 627 | */ | ||
| 628 | typedef struct | ||
| 629 | { | ||
| 630 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 631 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 632 | * given by the specific class. | ||
| 633 | */ | ||
| 634 | |||
| 635 | uint16_t bcdHID; /**< BCD encoded version that the HID descriptor and device complies to. | ||
| 636 | * | ||
| 637 | * \see \ref VERSION_BCD() utility macro. | ||
| 638 | */ | ||
| 639 | uint8_t bCountryCode; /**< Country code of the localized device, or zero if universal. */ | ||
| 640 | |||
| 641 | uint8_t bNumDescriptors; /**< Total number of HID report descriptors for the interface. */ | ||
| 642 | |||
| 643 | uint8_t bDescriptorType2; /**< Type of HID report, set to \ref HID_DTYPE_Report. */ | ||
| 644 | uint16_t wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */ | ||
| 645 | } ATTR_PACKED USB_HID_StdDescriptor_HID_t; | ||
| 646 | |||
| 647 | /** \brief Standard HID Boot Protocol Mouse Report. | ||
| 648 | * | ||
| 649 | * Type define for a standard Boot Protocol Mouse report | ||
| 650 | */ | ||
| 651 | typedef struct | ||
| 652 | { | ||
| 653 | uint8_t Button; /**< Button mask for currently pressed buttons in the mouse. */ | ||
| 654 | int8_t X; /**< Current delta X movement of the mouse. */ | ||
| 655 | int8_t Y; /**< Current delta Y movement on the mouse. */ | ||
| 656 | } ATTR_PACKED USB_MouseReport_Data_t; | ||
| 657 | |||
| 658 | /** \brief Standard HID Boot Protocol Keyboard Report. | ||
| 659 | * | ||
| 660 | * Type define for a standard Boot Protocol Keyboard report | ||
| 661 | */ | ||
| 662 | typedef struct | ||
| 663 | { | ||
| 664 | uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of | ||
| 665 | * \c HID_KEYBOARD_MODIFER_* masks). | ||
| 666 | */ | ||
| 667 | uint8_t Reserved; /**< Reserved for OEM use, always set to 0. */ | ||
| 668 | uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys. */ | ||
| 669 | } ATTR_PACKED USB_KeyboardReport_Data_t; | ||
| 670 | |||
| 671 | /** Type define for the data type used to store HID report descriptor elements. */ | ||
| 672 | typedef uint8_t USB_Descriptor_HIDReport_Datatype_t; | ||
| 673 | |||
| 674 | /* Disable C linkage for C++ Compilers: */ | ||
| 675 | #if defined(__cplusplus) | ||
| 676 | } | ||
| 677 | #endif | ||
| 678 | |||
| 679 | #endif | ||
| 680 | |||
| 681 | /** @} */ | ||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.c b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.c new file mode 100644 index 000000000..62f10c4e2 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.c | |||
| @@ -0,0 +1,389 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #define __INCLUDE_FROM_HID_DRIVER | ||
| 33 | #include "HIDParser.h" | ||
| 34 | |||
| 35 | uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, | ||
| 36 | uint16_t ReportSize, | ||
| 37 | HID_ReportInfo_t* const ParserData) | ||
| 38 | { | ||
| 39 | HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH]; | ||
| 40 | HID_StateTable_t* CurrStateTable = &StateTable[0]; | ||
| 41 | HID_CollectionPath_t* CurrCollectionPath = NULL; | ||
| 42 | HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0]; | ||
| 43 | uint16_t UsageList[HID_USAGE_STACK_DEPTH]; | ||
| 44 | uint8_t UsageListSize = 0; | ||
| 45 | HID_MinMax_t UsageMinMax = {0, 0}; | ||
| 46 | |||
| 47 | memset(ParserData, 0x00, sizeof(HID_ReportInfo_t)); | ||
| 48 | memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t)); | ||
| 49 | memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t)); | ||
| 50 | |||
| 51 | ParserData->TotalDeviceReports = 1; | ||
| 52 | |||
| 53 | while (ReportSize) | ||
| 54 | { | ||
| 55 | uint8_t HIDReportItem = *ReportData; | ||
| 56 | uint32_t ReportItemData; | ||
| 57 | |||
| 58 | ReportData++; | ||
| 59 | ReportSize--; | ||
| 60 | |||
| 61 | switch (HIDReportItem & HID_RI_DATA_SIZE_MASK) | ||
| 62 | { | ||
| 63 | case HID_RI_DATA_BITS_32: | ||
| 64 | ReportItemData = (((uint32_t)ReportData[3] << 24) | ((uint32_t)ReportData[2] << 16) | | ||
| 65 | ((uint16_t)ReportData[1] << 8) | ReportData[0]); | ||
| 66 | ReportSize -= 4; | ||
| 67 | ReportData += 4; | ||
| 68 | break; | ||
| 69 | |||
| 70 | case HID_RI_DATA_BITS_16: | ||
| 71 | ReportItemData = (((uint16_t)ReportData[1] << 8) | (ReportData[0])); | ||
| 72 | ReportSize -= 2; | ||
| 73 | ReportData += 2; | ||
| 74 | break; | ||
| 75 | |||
| 76 | case HID_RI_DATA_BITS_8: | ||
| 77 | ReportItemData = ReportData[0]; | ||
| 78 | ReportSize -= 1; | ||
| 79 | ReportData += 1; | ||
| 80 | break; | ||
| 81 | |||
| 82 | default: | ||
| 83 | ReportItemData = 0; | ||
| 84 | break; | ||
| 85 | } | ||
| 86 | |||
| 87 | switch (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK)) | ||
| 88 | { | ||
| 89 | case HID_RI_PUSH(0): | ||
| 90 | if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH - 1]) | ||
| 91 | return HID_PARSE_HIDStackOverflow; | ||
| 92 | |||
| 93 | memcpy((CurrStateTable + 1), | ||
| 94 | CurrStateTable, | ||
| 95 | sizeof(HID_ReportItem_t)); | ||
| 96 | |||
| 97 | CurrStateTable++; | ||
| 98 | break; | ||
| 99 | |||
| 100 | case HID_RI_POP(0): | ||
| 101 | if (CurrStateTable == &StateTable[0]) | ||
| 102 | return HID_PARSE_HIDStackUnderflow; | ||
| 103 | |||
| 104 | CurrStateTable--; | ||
| 105 | break; | ||
| 106 | |||
| 107 | case HID_RI_USAGE_PAGE(0): | ||
| 108 | if ((HIDReportItem & HID_RI_DATA_SIZE_MASK) == HID_RI_DATA_BITS_32) | ||
| 109 | CurrStateTable->Attributes.Usage.Page = (ReportItemData >> 16); | ||
| 110 | |||
| 111 | CurrStateTable->Attributes.Usage.Page = ReportItemData; | ||
| 112 | break; | ||
| 113 | |||
| 114 | case HID_RI_LOGICAL_MINIMUM(0): | ||
| 115 | CurrStateTable->Attributes.Logical.Minimum = ReportItemData; | ||
| 116 | break; | ||
| 117 | |||
| 118 | case HID_RI_LOGICAL_MAXIMUM(0): | ||
| 119 | CurrStateTable->Attributes.Logical.Maximum = ReportItemData; | ||
| 120 | break; | ||
| 121 | |||
| 122 | case HID_RI_PHYSICAL_MINIMUM(0): | ||
| 123 | CurrStateTable->Attributes.Physical.Minimum = ReportItemData; | ||
| 124 | break; | ||
| 125 | |||
| 126 | case HID_RI_PHYSICAL_MAXIMUM(0): | ||
| 127 | CurrStateTable->Attributes.Physical.Maximum = ReportItemData; | ||
| 128 | break; | ||
| 129 | |||
| 130 | case HID_RI_UNIT_EXPONENT(0): | ||
| 131 | CurrStateTable->Attributes.Unit.Exponent = ReportItemData; | ||
| 132 | break; | ||
| 133 | |||
| 134 | case HID_RI_UNIT(0): | ||
| 135 | CurrStateTable->Attributes.Unit.Type = ReportItemData; | ||
| 136 | break; | ||
| 137 | |||
| 138 | case HID_RI_REPORT_SIZE(0): | ||
| 139 | CurrStateTable->Attributes.BitSize = ReportItemData; | ||
| 140 | break; | ||
| 141 | |||
| 142 | case HID_RI_REPORT_COUNT(0): | ||
| 143 | CurrStateTable->ReportCount = ReportItemData; | ||
| 144 | break; | ||
| 145 | |||
| 146 | case HID_RI_REPORT_ID(0): | ||
| 147 | CurrStateTable->ReportID = ReportItemData; | ||
| 148 | |||
| 149 | if (ParserData->UsingReportIDs) | ||
| 150 | { | ||
| 151 | CurrReportIDInfo = NULL; | ||
| 152 | |||
| 153 | for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++) | ||
| 154 | { | ||
| 155 | if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID) | ||
| 156 | { | ||
| 157 | CurrReportIDInfo = &ParserData->ReportIDSizes[i]; | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | if (CurrReportIDInfo == NULL) | ||
| 163 | { | ||
| 164 | if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS) | ||
| 165 | return HID_PARSE_InsufficientReportIDItems; | ||
| 166 | |||
| 167 | CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++]; | ||
| 168 | memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t)); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | ParserData->UsingReportIDs = true; | ||
| 173 | |||
| 174 | CurrReportIDInfo->ReportID = CurrStateTable->ReportID; | ||
| 175 | break; | ||
| 176 | |||
| 177 | case HID_RI_USAGE(0): | ||
| 178 | if (UsageListSize == HID_USAGE_STACK_DEPTH) | ||
| 179 | return HID_PARSE_UsageListOverflow; | ||
| 180 | |||
| 181 | UsageList[UsageListSize++] = ReportItemData; | ||
| 182 | break; | ||
| 183 | |||
| 184 | case HID_RI_USAGE_MINIMUM(0): | ||
| 185 | UsageMinMax.Minimum = ReportItemData; | ||
| 186 | break; | ||
| 187 | |||
| 188 | case HID_RI_USAGE_MAXIMUM(0): | ||
| 189 | UsageMinMax.Maximum = ReportItemData; | ||
| 190 | break; | ||
| 191 | |||
| 192 | case HID_RI_COLLECTION(0): | ||
| 193 | if (CurrCollectionPath == NULL) | ||
| 194 | { | ||
| 195 | CurrCollectionPath = &ParserData->CollectionPaths[0]; | ||
| 196 | } | ||
| 197 | else | ||
| 198 | { | ||
| 199 | HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath; | ||
| 200 | |||
| 201 | CurrCollectionPath = &ParserData->CollectionPaths[1]; | ||
| 202 | |||
| 203 | while (CurrCollectionPath->Parent != NULL) | ||
| 204 | { | ||
| 205 | if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1]) | ||
| 206 | return HID_PARSE_InsufficientCollectionPaths; | ||
| 207 | |||
| 208 | CurrCollectionPath++; | ||
| 209 | } | ||
| 210 | |||
| 211 | CurrCollectionPath->Parent = ParentCollectionPath; | ||
| 212 | } | ||
| 213 | |||
| 214 | CurrCollectionPath->Type = ReportItemData; | ||
| 215 | CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page; | ||
| 216 | |||
| 217 | if (UsageListSize) | ||
| 218 | { | ||
| 219 | CurrCollectionPath->Usage.Usage = UsageList[0]; | ||
| 220 | |||
| 221 | for (uint8_t i = 1; i < UsageListSize; i++) | ||
| 222 | UsageList[i - 1] = UsageList[i]; | ||
| 223 | |||
| 224 | UsageListSize--; | ||
| 225 | } | ||
| 226 | else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) | ||
| 227 | { | ||
| 228 | CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++; | ||
| 229 | } | ||
| 230 | |||
| 231 | break; | ||
| 232 | |||
| 233 | case HID_RI_END_COLLECTION(0): | ||
| 234 | if (CurrCollectionPath == NULL) | ||
| 235 | return HID_PARSE_UnexpectedEndCollection; | ||
| 236 | |||
| 237 | CurrCollectionPath = CurrCollectionPath->Parent; | ||
| 238 | break; | ||
| 239 | |||
| 240 | case HID_RI_INPUT(0): | ||
| 241 | case HID_RI_OUTPUT(0): | ||
| 242 | case HID_RI_FEATURE(0): | ||
| 243 | for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++) | ||
| 244 | { | ||
| 245 | HID_ReportItem_t NewReportItem; | ||
| 246 | |||
| 247 | memcpy(&NewReportItem.Attributes, | ||
| 248 | &CurrStateTable->Attributes, | ||
| 249 | sizeof(HID_ReportItem_Attributes_t)); | ||
| 250 | |||
| 251 | NewReportItem.ItemFlags = ReportItemData; | ||
| 252 | NewReportItem.CollectionPath = CurrCollectionPath; | ||
| 253 | NewReportItem.ReportID = CurrStateTable->ReportID; | ||
| 254 | |||
| 255 | if (UsageListSize) | ||
| 256 | { | ||
| 257 | NewReportItem.Attributes.Usage.Usage = UsageList[0]; | ||
| 258 | |||
| 259 | for (uint8_t i = 1; i < UsageListSize; i++) | ||
| 260 | UsageList[i - 1] = UsageList[i]; | ||
| 261 | |||
| 262 | UsageListSize--; | ||
| 263 | } | ||
| 264 | else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) | ||
| 265 | { | ||
| 266 | NewReportItem.Attributes.Usage.Usage = UsageMinMax.Minimum++; | ||
| 267 | } | ||
| 268 | |||
| 269 | uint8_t ItemTypeTag = (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK)); | ||
| 270 | |||
| 271 | if (ItemTypeTag == HID_RI_INPUT(0)) | ||
| 272 | NewReportItem.ItemType = HID_REPORT_ITEM_In; | ||
| 273 | else if (ItemTypeTag == HID_RI_OUTPUT(0)) | ||
| 274 | NewReportItem.ItemType = HID_REPORT_ITEM_Out; | ||
| 275 | else | ||
| 276 | NewReportItem.ItemType = HID_REPORT_ITEM_Feature; | ||
| 277 | |||
| 278 | NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType]; | ||
| 279 | |||
| 280 | CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize; | ||
| 281 | |||
| 282 | ParserData->LargestReportSizeBits = MAX(ParserData->LargestReportSizeBits, CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType]); | ||
| 283 | |||
| 284 | if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS) | ||
| 285 | return HID_PARSE_InsufficientReportItems; | ||
| 286 | |||
| 287 | memcpy(&ParserData->ReportItems[ParserData->TotalReportItems], | ||
| 288 | &NewReportItem, sizeof(HID_ReportItem_t)); | ||
| 289 | |||
| 290 | if (!(ReportItemData & HID_IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem)) | ||
| 291 | ParserData->TotalReportItems++; | ||
| 292 | } | ||
| 293 | |||
| 294 | break; | ||
| 295 | |||
| 296 | default: | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | |||
| 300 | if ((HIDReportItem & HID_RI_TYPE_MASK) == HID_RI_TYPE_MAIN) | ||
| 301 | { | ||
| 302 | UsageMinMax.Minimum = 0; | ||
| 303 | UsageMinMax.Maximum = 0; | ||
| 304 | UsageListSize = 0; | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | if (!(ParserData->TotalReportItems)) | ||
| 309 | return HID_PARSE_NoUnfilteredReportItems; | ||
| 310 | |||
| 311 | return HID_PARSE_Successful; | ||
| 312 | } | ||
| 313 | |||
| 314 | bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, | ||
| 315 | HID_ReportItem_t* const ReportItem) | ||
| 316 | { | ||
| 317 | if (ReportItem == NULL) | ||
| 318 | return false; | ||
| 319 | |||
| 320 | uint16_t DataBitsRem = ReportItem->Attributes.BitSize; | ||
| 321 | uint16_t CurrentBit = ReportItem->BitOffset; | ||
| 322 | uint32_t BitMask = (1 << 0); | ||
| 323 | |||
| 324 | if (ReportItem->ReportID) | ||
| 325 | { | ||
| 326 | if (ReportItem->ReportID != ReportData[0]) | ||
| 327 | return false; | ||
| 328 | |||
| 329 | ReportData++; | ||
| 330 | } | ||
| 331 | |||
| 332 | ReportItem->PreviousValue = ReportItem->Value; | ||
| 333 | ReportItem->Value = 0; | ||
| 334 | |||
| 335 | while (DataBitsRem--) | ||
| 336 | { | ||
| 337 | if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8))) | ||
| 338 | ReportItem->Value |= BitMask; | ||
| 339 | |||
| 340 | CurrentBit++; | ||
| 341 | BitMask <<= 1; | ||
| 342 | } | ||
| 343 | |||
| 344 | return true; | ||
| 345 | } | ||
| 346 | |||
| 347 | void USB_SetHIDReportItemInfo(uint8_t* ReportData, | ||
| 348 | HID_ReportItem_t* const ReportItem) | ||
| 349 | { | ||
| 350 | if (ReportItem == NULL) | ||
| 351 | return; | ||
| 352 | |||
| 353 | uint16_t DataBitsRem = ReportItem->Attributes.BitSize; | ||
| 354 | uint16_t CurrentBit = ReportItem->BitOffset; | ||
| 355 | uint32_t BitMask = (1 << 0); | ||
| 356 | |||
| 357 | if (ReportItem->ReportID) | ||
| 358 | { | ||
| 359 | ReportData[0] = ReportItem->ReportID; | ||
| 360 | ReportData++; | ||
| 361 | } | ||
| 362 | |||
| 363 | ReportItem->PreviousValue = ReportItem->Value; | ||
| 364 | |||
| 365 | while (DataBitsRem--) | ||
| 366 | { | ||
| 367 | if (ReportItem->Value & BitMask) | ||
| 368 | ReportData[CurrentBit / 8] |= (1 << (CurrentBit % 8)); | ||
| 369 | |||
| 370 | CurrentBit++; | ||
| 371 | BitMask <<= 1; | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 375 | uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, | ||
| 376 | const uint8_t ReportID, | ||
| 377 | const uint8_t ReportType) | ||
| 378 | { | ||
| 379 | for (uint8_t i = 0; i < HID_MAX_REPORT_IDS; i++) | ||
| 380 | { | ||
| 381 | uint16_t ReportSizeBits = ParserData->ReportIDSizes[i].ReportSizeBits[ReportType]; | ||
| 382 | |||
| 383 | if (ParserData->ReportIDSizes[i].ReportID == ReportID) | ||
| 384 | return (ReportSizeBits / 8) + ((ReportSizeBits % 8) ? 1 : 0); | ||
| 385 | } | ||
| 386 | |||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.h new file mode 100644 index 000000000..023316d7e --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.h | |||
| @@ -0,0 +1,364 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief USB Human Interface Device (HID) Class report descriptor parser. | ||
| 33 | * | ||
| 34 | * This file allows for the easy parsing of complex HID report descriptors, which describes the data that | ||
| 35 | * a HID device transmits to the host. It also provides an easy API for extracting and processing the data | ||
| 36 | * elements inside a HID report sent from an attached HID device. | ||
| 37 | */ | ||
| 38 | |||
| 39 | /** \ingroup Group_USB | ||
| 40 | * \defgroup Group_HIDParser HID Report Parser | ||
| 41 | * \brief USB Human Interface Device (HID) Class report descriptor parser. | ||
| 42 | * | ||
| 43 | * \section Sec_HIDParser_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/HIDParser.c <i>(Makefile source module name: LUFA_SRC_USB)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_HIDParser_ModDescription Module Description | ||
| 48 | * Human Interface Device (HID) class report descriptor parser. This module implements a parser than is | ||
| 49 | * capable of processing a complete HID report descriptor, and outputting a flat structure containing the | ||
| 50 | * contents of the report in an a more friendly format. The parsed data may then be further processed and used | ||
| 51 | * within an application to process sent and received HID reports to and from an attached HID device. | ||
| 52 | * | ||
| 53 | * A HID report descriptor consists of a set of HID report items, which describe the function and layout | ||
| 54 | * of data exchanged between a HID device and a host, including both the physical encoding of each item | ||
| 55 | * (such as a button, key press or joystick axis) in the sent and received data packets - known as "reports" - | ||
| 56 | * as well as other information about each item such as the usages, data range, physical location and other | ||
| 57 | * characteristics. In this way a HID device can retain a high degree of flexibility in its capabilities, as it | ||
| 58 | * is not forced to comply with a given report layout or feature-set. | ||
| 59 | * | ||
| 60 | * This module also contains routines for the processing of data in an actual HID report, using the parsed report | ||
| 61 | * descriptor data as a guide for the encoding. | ||
| 62 | * | ||
| 63 | * @{ | ||
| 64 | */ | ||
| 65 | |||
| 66 | #ifndef __HIDPARSER_H__ | ||
| 67 | #define __HIDPARSER_H__ | ||
| 68 | |||
| 69 | /* Includes: */ | ||
| 70 | #include "../../../../Common/Common.h" | ||
| 71 | |||
| 72 | #include "HIDReportData.h" | ||
| 73 | #include "HIDClassCommon.h" | ||
| 74 | |||
| 75 | /* Enable C linkage for C++ Compilers: */ | ||
| 76 | #if defined(__cplusplus) | ||
| 77 | extern "C" { | ||
| 78 | #endif | ||
| 79 | |||
| 80 | /* Macros: */ | ||
| 81 | #if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__) | ||
| 82 | /** Constant indicating the maximum stack depth of the state table. A larger state table | ||
| 83 | * allows for more PUSH/POP report items to be nested, but consumes more memory. By default | ||
| 84 | * this is set to 2 levels (allowing non-nested PUSH items) but this can be overridden by | ||
| 85 | * defining \c HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the | ||
| 86 | * define to the compiler using the -D compiler switch. | ||
| 87 | */ | ||
| 88 | #define HID_STATETABLE_STACK_DEPTH 2 | ||
| 89 | #endif | ||
| 90 | |||
| 91 | #if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__) | ||
| 92 | /** Constant indicating the maximum stack depth of the usage table. A larger usage table | ||
| 93 | * allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than | ||
| 94 | * one, but requires more stack space. By default this is set to 8 levels (allowing for a report | ||
| 95 | * item with a count of 8) but this can be overridden by defining \c HID_USAGE_STACK_DEPTH to another | ||
| 96 | * value in the user project makefile, passing the define to the compiler using the -D compiler | ||
| 97 | * switch. | ||
| 98 | */ | ||
| 99 | #define HID_USAGE_STACK_DEPTH 8 | ||
| 100 | #endif | ||
| 101 | |||
| 102 | #if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__) | ||
| 103 | /** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be | ||
| 104 | * processed in the report item descriptor. A large value allows for more COLLECTION items to be | ||
| 105 | * processed, but consumes more memory. By default this is set to 10 collections, but this can be | ||
| 106 | * overridden by defining \c HID_MAX_COLLECTIONS to another value in the user project makefile, passing | ||
| 107 | * the define to the compiler using the -D compiler switch. | ||
| 108 | */ | ||
| 109 | #define HID_MAX_COLLECTIONS 10 | ||
| 110 | #endif | ||
| 111 | |||
| 112 | #if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__) | ||
| 113 | /** Constant indicating the maximum number of report items (IN, OUT or FEATURE) that can be processed | ||
| 114 | * in the report item descriptor and stored in the user HID Report Info structure. A large value allows | ||
| 115 | * for more report items to be stored, but consumes more memory. By default this is set to 20 items, | ||
| 116 | * but this can be overridden by defining \c HID_MAX_REPORTITEMS to another value in the user project | ||
| 117 | * makefile, and passing the define to the compiler using the -D compiler switch. | ||
| 118 | */ | ||
| 119 | #define HID_MAX_REPORTITEMS 20 | ||
| 120 | #endif | ||
| 121 | |||
| 122 | #if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__) | ||
| 123 | /** Constant indicating the maximum number of unique report IDs that can be processed in the report item | ||
| 124 | * descriptor for the report size information array in the user HID Report Info structure. A large value | ||
| 125 | * allows for more report ID report sizes to be stored, but consumes more memory. By default this is set | ||
| 126 | * to 10 items, but this can be overridden by defining \c HID_MAX_REPORT_IDS to another value in the user project | ||
| 127 | * makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE | ||
| 128 | * items sharing the same report ID consume only one size item in the array. | ||
| 129 | */ | ||
| 130 | #define HID_MAX_REPORT_IDS 10 | ||
| 131 | #endif | ||
| 132 | |||
| 133 | /** Returns the value a given HID report item (once its value has been fetched via \ref USB_GetHIDReportItemInfo()) | ||
| 134 | * left-aligned to the given data type. This allows for signed data to be interpreted correctly, by shifting the data | ||
| 135 | * leftwards until the data's sign bit is in the correct position. | ||
| 136 | * | ||
| 137 | * \param[in] ReportItem HID Report Item whose retrieved value is to be aligned. | ||
| 138 | * \param[in] Type Data type to align the HID report item's value to. | ||
| 139 | * | ||
| 140 | * \return Left-aligned data of the given report item's pre-retrieved value for the given datatype. | ||
| 141 | */ | ||
| 142 | #define HID_ALIGN_DATA(ReportItem, Type) ((Type)(ReportItem->Value << ((8 * sizeof(Type)) - ReportItem->Attributes.BitSize))) | ||
| 143 | |||
| 144 | /* Public Interface - May be used in end-application: */ | ||
| 145 | /* Enums: */ | ||
| 146 | /** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function. */ | ||
| 147 | enum HID_Parse_ErrorCodes_t | ||
| 148 | { | ||
| 149 | HID_PARSE_Successful = 0, /**< Successful parse of the HID report descriptor, no error. */ | ||
| 150 | HID_PARSE_HIDStackOverflow = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */ | ||
| 151 | HID_PARSE_HIDStackUnderflow = 2, /**< A POP was found when the state table stack was empty. */ | ||
| 152 | HID_PARSE_InsufficientReportItems = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */ | ||
| 153 | HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */ | ||
| 154 | HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */ | ||
| 155 | HID_PARSE_UsageListOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */ | ||
| 156 | HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */ | ||
| 157 | HID_PARSE_NoUnfilteredReportItems = 8, /**< All report items from the device were filtered by the filtering callback routine. */ | ||
| 158 | }; | ||
| 159 | |||
| 160 | /* Type Defines: */ | ||
| 161 | /** \brief HID Parser Report Item Min/Max Structure. | ||
| 162 | * | ||
| 163 | * Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max). | ||
| 164 | */ | ||
| 165 | typedef struct | ||
| 166 | { | ||
| 167 | uint32_t Minimum; /**< Minimum value for the attribute. */ | ||
| 168 | uint32_t Maximum; /**< Maximum value for the attribute. */ | ||
| 169 | } HID_MinMax_t; | ||
| 170 | |||
| 171 | /** \brief HID Parser Report Item Unit Structure. | ||
| 172 | * | ||
| 173 | * Type define for the Unit attributes of a report item. | ||
| 174 | */ | ||
| 175 | typedef struct | ||
| 176 | { | ||
| 177 | uint32_t Type; /**< Unit type (refer to HID specifications for details). */ | ||
| 178 | uint8_t Exponent; /**< Unit exponent (refer to HID specifications for details). */ | ||
| 179 | } HID_Unit_t; | ||
| 180 | |||
| 181 | /** \brief HID Parser Report Item Usage Structure. | ||
| 182 | * | ||
| 183 | * Type define for the Usage attributes of a report item. | ||
| 184 | */ | ||
| 185 | typedef struct | ||
| 186 | { | ||
| 187 | uint16_t Page; /**< Usage page of the report item. */ | ||
| 188 | uint16_t Usage; /**< Usage of the report item. */ | ||
| 189 | } HID_Usage_t; | ||
| 190 | |||
| 191 | /** \brief HID Parser Report Item Collection Path Structure. | ||
| 192 | * | ||
| 193 | * Type define for a COLLECTION object. Contains the collection attributes and a reference to the | ||
| 194 | * parent collection if any. | ||
| 195 | */ | ||
| 196 | typedef struct HID_CollectionPath | ||
| 197 | { | ||
| 198 | uint8_t Type; /**< Collection type (e.g. "Generic Desktop"). */ | ||
| 199 | HID_Usage_t Usage; /**< Collection usage. */ | ||
| 200 | struct HID_CollectionPath* Parent; /**< Reference to parent collection, or \c NULL if root collection. */ | ||
| 201 | } HID_CollectionPath_t; | ||
| 202 | |||
| 203 | /** \brief HID Parser Report Item Attributes Structure. | ||
| 204 | * | ||
| 205 | * Type define for all the data attributes of a report item, except flags. | ||
| 206 | */ | ||
| 207 | typedef struct | ||
| 208 | { | ||
| 209 | uint8_t BitSize; /**< Size in bits of the report item's data. */ | ||
| 210 | |||
| 211 | HID_Usage_t Usage; /**< Usage of the report item. */ | ||
| 212 | HID_Unit_t Unit; /**< Unit type and exponent of the report item. */ | ||
| 213 | HID_MinMax_t Logical; /**< Logical minimum and maximum of the report item. */ | ||
| 214 | HID_MinMax_t Physical; /**< Physical minimum and maximum of the report item. */ | ||
| 215 | } HID_ReportItem_Attributes_t; | ||
| 216 | |||
| 217 | /** \brief HID Parser Report Item Details Structure. | ||
| 218 | * | ||
| 219 | * Type define for a report item (IN, OUT or FEATURE) layout attributes and other details. | ||
| 220 | */ | ||
| 221 | typedef struct | ||
| 222 | { | ||
| 223 | uint16_t BitOffset; /**< Bit offset in the IN, OUT or FEATURE report of the item. */ | ||
| 224 | uint8_t ItemType; /**< Report item type, a value in \ref HID_ReportItemTypes_t. */ | ||
| 225 | uint16_t ItemFlags; /**< Item data flags, a mask of \c HID_IOF_* constants. */ | ||
| 226 | uint8_t ReportID; /**< Report ID this item belongs to, or 0x00 if device has only one report */ | ||
| 227 | HID_CollectionPath_t* CollectionPath; /**< Collection path of the item. */ | ||
| 228 | |||
| 229 | HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */ | ||
| 230 | |||
| 231 | uint32_t Value; /**< Current value of the report item - use \ref HID_ALIGN_DATA() when processing | ||
| 232 | * a retrieved value so that it is aligned to a specific type. | ||
| 233 | */ | ||
| 234 | uint32_t PreviousValue; /**< Previous value of the report item. */ | ||
| 235 | } HID_ReportItem_t; | ||
| 236 | |||
| 237 | /** \brief HID Parser Report Size Structure. | ||
| 238 | * | ||
| 239 | * Type define for a report item size information structure, to retain the size of a device's reports by ID. | ||
| 240 | */ | ||
| 241 | typedef struct | ||
| 242 | { | ||
| 243 | uint8_t ReportID; /**< Report ID of the report within the HID interface. */ | ||
| 244 | uint16_t ReportSizeBits[3]; /**< Total number of bits in each report type for the given Report ID, | ||
| 245 | * indexed by the \ref HID_ReportItemTypes_t enum. | ||
| 246 | */ | ||
| 247 | } HID_ReportSizeInfo_t; | ||
| 248 | |||
| 249 | /** \brief HID Parser State Structure. | ||
| 250 | * | ||
| 251 | * Type define for a complete processed HID report, including all report item data and collections. | ||
| 252 | */ | ||
| 253 | typedef struct | ||
| 254 | { | ||
| 255 | uint8_t TotalReportItems; /**< Total number of report items stored in the \c ReportItems array. */ | ||
| 256 | HID_ReportItem_t ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including all IN, OUT | ||
| 257 | * and FEATURE items. | ||
| 258 | */ | ||
| 259 | HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced | ||
| 260 | * by the report items. | ||
| 261 | */ | ||
| 262 | uint8_t TotalDeviceReports; /**< Number of reports within the HID interface */ | ||
| 263 | HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /**< Report sizes for each report in the interface */ | ||
| 264 | uint16_t LargestReportSizeBits; /**< Largest report that the attached device will generate, in bits */ | ||
| 265 | bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID | ||
| 266 | * element in its HID report descriptor. | ||
| 267 | */ | ||
| 268 | } HID_ReportInfo_t; | ||
| 269 | |||
| 270 | /* Function Prototypes: */ | ||
| 271 | /** Function to process a given HID report returned from an attached device, and store it into a given | ||
| 272 | * \ref HID_ReportInfo_t structure. | ||
| 273 | * | ||
| 274 | * \param[in] ReportData Buffer containing the device's HID report table. | ||
| 275 | * \param[in] ReportSize Size in bytes of the HID report table. | ||
| 276 | * \param[out] ParserData Pointer to a \ref HID_ReportInfo_t instance for the parser output. | ||
| 277 | * | ||
| 278 | * \return A value in the \ref HID_Parse_ErrorCodes_t enum. | ||
| 279 | */ | ||
| 280 | uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, | ||
| 281 | uint16_t ReportSize, | ||
| 282 | HID_ReportInfo_t* const ParserData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 283 | |||
| 284 | /** Extracts the given report item's value out of the given HID report and places it into the Value | ||
| 285 | * member of the report item's \ref HID_ReportItem_t structure. | ||
| 286 | * | ||
| 287 | * When called on a report with an item that exists in that report, this copies the report item's \c Value | ||
| 288 | * to its \c PreviousValue element for easy checking to see if an item's value has changed before processing | ||
| 289 | * a report. If the given item does not exist in the report, the function does not modify the report item's | ||
| 290 | * data. | ||
| 291 | * | ||
| 292 | * \param[in] ReportData Buffer containing an IN or FEATURE report from an attached device. | ||
| 293 | * \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array. | ||
| 294 | * | ||
| 295 | * \returns Boolean \c true if the item to retrieve was located in the given report, \c false otherwise. | ||
| 296 | */ | ||
| 297 | bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, | ||
| 298 | HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1); | ||
| 299 | |||
| 300 | /** Retrieves the given report item's value out of the \c Value member of the report item's | ||
| 301 | * \ref HID_ReportItem_t structure and places it into the correct position in the HID report | ||
| 302 | * buffer. The report buffer is assumed to have the appropriate bits cleared before calling | ||
| 303 | * this function (i.e., the buffer should be explicitly cleared before report values are added). | ||
| 304 | * | ||
| 305 | * When called, this copies the report item's \c Value element to its \c PreviousValue element for easy | ||
| 306 | * checking to see if an item's value has changed before sending a report. | ||
| 307 | * | ||
| 308 | * If the device has multiple HID reports, the first byte in the report is set to the report ID of the given item. | ||
| 309 | * | ||
| 310 | * \param[out] ReportData Buffer holding the current OUT or FEATURE report data. | ||
| 311 | * \param[in] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array. | ||
| 312 | */ | ||
| 313 | void USB_SetHIDReportItemInfo(uint8_t* ReportData, | ||
| 314 | HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1); | ||
| 315 | |||
| 316 | /** Retrieves the size of a given HID report in bytes from its Report ID. | ||
| 317 | * | ||
| 318 | * \param[in] ParserData Pointer to a \ref HID_ReportInfo_t instance containing the parser output. | ||
| 319 | * \param[in] ReportID Report ID of the report whose size is to be determined. | ||
| 320 | * \param[in] ReportType Type of the report whose size is to be determined, a value from the | ||
| 321 | * \ref HID_ReportItemTypes_t enum. | ||
| 322 | * | ||
| 323 | * \return Size of the report in bytes, or \c 0 if the report does not exist. | ||
| 324 | */ | ||
| 325 | uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, | ||
| 326 | const uint8_t ReportID, | ||
| 327 | const uint8_t ReportType) ATTR_CONST ATTR_NON_NULL_PTR_ARG(1); | ||
| 328 | |||
| 329 | /** Callback routine for the HID Report Parser. This callback <b>must</b> be implemented by the user code when | ||
| 330 | * the parser is used, to determine what report IN, OUT and FEATURE item's information is stored into the user | ||
| 331 | * \ref HID_ReportInfo_t structure. This can be used to filter only those items the application will be using, so that | ||
| 332 | * no RAM is wasted storing the attributes for report items which will never be referenced by the application. | ||
| 333 | * | ||
| 334 | * Report item pointers passed to this callback function may be cached by the user application for later use | ||
| 335 | * when processing report items. This provides faster report processing in the user application than would | ||
| 336 | * a search of the entire parsed report item table for each received or sent report. | ||
| 337 | * | ||
| 338 | * \param[in] CurrentItem Pointer to the current report item for user checking. | ||
| 339 | * | ||
| 340 | * \return Boolean \c true if the item should be stored into the \ref HID_ReportInfo_t structure, \c false if | ||
| 341 | * it should be ignored. | ||
| 342 | */ | ||
| 343 | bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem); | ||
| 344 | |||
| 345 | /* Private Interface - For use in library only: */ | ||
| 346 | #if !defined(__DOXYGEN__) | ||
| 347 | /* Type Defines: */ | ||
| 348 | typedef struct | ||
| 349 | { | ||
| 350 | HID_ReportItem_Attributes_t Attributes; | ||
| 351 | uint8_t ReportCount; | ||
| 352 | uint8_t ReportID; | ||
| 353 | } HID_StateTable_t; | ||
| 354 | #endif | ||
| 355 | |||
| 356 | /* Disable C linkage for C++ Compilers: */ | ||
| 357 | #if defined(__cplusplus) | ||
| 358 | } | ||
| 359 | #endif | ||
| 360 | |||
| 361 | #endif | ||
| 362 | |||
| 363 | /** @} */ | ||
| 364 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDReportData.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDReportData.h new file mode 100644 index 000000000..fe1c4df94 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/HIDReportData.h | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Constants for HID report item attributes. | ||
| 33 | * | ||
| 34 | * HID report item constants for report item attributes. Refer to the HID specification for | ||
| 35 | * details on each flag's meaning when applied to an IN, OUT or FEATURE item. | ||
| 36 | */ | ||
| 37 | |||
| 38 | /** \ingroup Group_HIDParser | ||
| 39 | * \defgroup Group_HIDReportItemConst HID Report Descriptor Item Constants | ||
| 40 | * | ||
| 41 | * General HID constant definitions for HID Report Descriptor elements. | ||
| 42 | * | ||
| 43 | * @{ | ||
| 44 | */ | ||
| 45 | |||
| 46 | #ifndef __HIDREPORTDATA_H__ | ||
| 47 | #define __HIDREPORTDATA_H__ | ||
| 48 | |||
| 49 | /* Private Interface - For use in library only: */ | ||
| 50 | #if !defined(__DOXYGEN__) | ||
| 51 | /* Macros: */ | ||
| 52 | #define HID_RI_DATA_SIZE_MASK 0x03 | ||
| 53 | #define HID_RI_TYPE_MASK 0x0C | ||
| 54 | #define HID_RI_TAG_MASK 0xF0 | ||
| 55 | |||
| 56 | #define HID_RI_TYPE_MAIN 0x00 | ||
| 57 | #define HID_RI_TYPE_GLOBAL 0x04 | ||
| 58 | #define HID_RI_TYPE_LOCAL 0x08 | ||
| 59 | |||
| 60 | #define HID_RI_DATA_BITS_0 0x00 | ||
| 61 | #define HID_RI_DATA_BITS_8 0x01 | ||
| 62 | #define HID_RI_DATA_BITS_16 0x02 | ||
| 63 | #define HID_RI_DATA_BITS_32 0x03 | ||
| 64 | #define HID_RI_DATA_BITS(DataBits) CONCAT_EXPANDED(HID_RI_DATA_BITS_, DataBits) | ||
| 65 | |||
| 66 | #define _HID_RI_ENCODE_0(Data) | ||
| 67 | #define _HID_RI_ENCODE_8(Data) , (Data & 0xFF) | ||
| 68 | #define _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_8(Data) _HID_RI_ENCODE_8(Data >> 8) | ||
| 69 | #define _HID_RI_ENCODE_32(Data) _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_16(Data >> 16) | ||
| 70 | #define _HID_RI_ENCODE(DataBits, ...) CONCAT_EXPANDED(_HID_RI_ENCODE_, DataBits(__VA_ARGS__)) | ||
| 71 | |||
| 72 | #define _HID_RI_ENTRY(Type, Tag, DataBits, ...) (Type | Tag | HID_RI_DATA_BITS(DataBits)) _HID_RI_ENCODE(DataBits, (__VA_ARGS__)) | ||
| 73 | #endif | ||
| 74 | |||
| 75 | /* Public Interface - May be used in end-application: */ | ||
| 76 | /* Macros: */ | ||
| 77 | /** \name HID Input, Output and Feature Report Descriptor Item Flags */ | ||
| 78 | //@{ | ||
| 79 | #define HID_IOF_CONSTANT (1 << 0) | ||
| 80 | #define HID_IOF_DATA (0 << 0) | ||
| 81 | #define HID_IOF_VARIABLE (1 << 1) | ||
| 82 | #define HID_IOF_ARRAY (0 << 1) | ||
| 83 | #define HID_IOF_RELATIVE (1 << 2) | ||
| 84 | #define HID_IOF_ABSOLUTE (0 << 2) | ||
| 85 | #define HID_IOF_WRAP (1 << 3) | ||
| 86 | #define HID_IOF_NO_WRAP (0 << 3) | ||
| 87 | #define HID_IOF_NON_LINEAR (1 << 4) | ||
| 88 | #define HID_IOF_LINEAR (0 << 4) | ||
| 89 | #define HID_IOF_NO_PREFERRED_STATE (1 << 5) | ||
| 90 | #define HID_IOF_PREFERRED_STATE (0 << 5) | ||
| 91 | #define HID_IOF_NULLSTATE (1 << 6) | ||
| 92 | #define HID_IOF_NO_NULL_POSITION (0 << 6) | ||
| 93 | #define HID_IOF_VOLATILE (1 << 7) | ||
| 94 | #define HID_IOF_NON_VOLATILE (0 << 7) | ||
| 95 | #define HID_IOF_BUFFERED_BYTES (1 << 8) | ||
| 96 | #define HID_IOF_BITFIELD (0 << 8) | ||
| 97 | //@} | ||
| 98 | |||
| 99 | /** \name HID Report Descriptor Item Macros */ | ||
| 100 | //@{ | ||
| 101 | #define HID_RI_INPUT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0x80, DataBits, __VA_ARGS__) | ||
| 102 | #define HID_RI_OUTPUT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0x90, DataBits, __VA_ARGS__) | ||
| 103 | #define HID_RI_COLLECTION(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xA0, DataBits, __VA_ARGS__) | ||
| 104 | #define HID_RI_FEATURE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xB0, DataBits, __VA_ARGS__) | ||
| 105 | #define HID_RI_END_COLLECTION(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xC0, DataBits, __VA_ARGS__) | ||
| 106 | #define HID_RI_USAGE_PAGE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x00, DataBits, __VA_ARGS__) | ||
| 107 | #define HID_RI_LOGICAL_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x10, DataBits, __VA_ARGS__) | ||
| 108 | #define HID_RI_LOGICAL_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x20, DataBits, __VA_ARGS__) | ||
| 109 | #define HID_RI_PHYSICAL_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x30, DataBits, __VA_ARGS__) | ||
| 110 | #define HID_RI_PHYSICAL_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x40, DataBits, __VA_ARGS__) | ||
| 111 | #define HID_RI_UNIT_EXPONENT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x50, DataBits, __VA_ARGS__) | ||
| 112 | #define HID_RI_UNIT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x60, DataBits, __VA_ARGS__) | ||
| 113 | #define HID_RI_REPORT_SIZE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x70, DataBits, __VA_ARGS__) | ||
| 114 | #define HID_RI_REPORT_ID(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x80, DataBits, __VA_ARGS__) | ||
| 115 | #define HID_RI_REPORT_COUNT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x90, DataBits, __VA_ARGS__) | ||
| 116 | #define HID_RI_PUSH(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xA0, DataBits, __VA_ARGS__) | ||
| 117 | #define HID_RI_POP(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xB0, DataBits, __VA_ARGS__) | ||
| 118 | #define HID_RI_USAGE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x00, DataBits, __VA_ARGS__) | ||
| 119 | #define HID_RI_USAGE_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x10, DataBits, __VA_ARGS__) | ||
| 120 | #define HID_RI_USAGE_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x20, DataBits, __VA_ARGS__) | ||
| 121 | //@} | ||
| 122 | |||
| 123 | /** @} */ | ||
| 124 | |||
| 125 | #endif | ||
| 126 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h new file mode 100644 index 000000000..b6414bc06 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h | |||
| @@ -0,0 +1,363 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB MIDI Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB MIDI Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassMIDI | ||
| 41 | * \defgroup Group_USBClassMIDICommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassMIDICommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * MIDI Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _MIDI_CLASS_COMMON_H_ | ||
| 51 | #define _MIDI_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Macros: */ | ||
| 54 | #define __INCLUDE_FROM_AUDIO_DRIVER | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../Core/StdDescriptors.h" | ||
| 58 | #include "AudioClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_MIDI_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Macros: */ | ||
| 71 | /** \name MIDI Command Values | ||
| 72 | * See http://www.midi.org/techspecs/midimessages.php for more information. | ||
| 73 | */ | ||
| 74 | //@{ | ||
| 75 | /** MIDI command for System Exclusive (SysEx) single event that has one byte of data total. */ | ||
| 76 | #define MIDI_COMMAND_SYSEX_1BYTE MIDI_COMMAND_SYSEX_END_1BYTE | ||
| 77 | |||
| 78 | /** MIDI command for System Exclusive (SysEx) single event that has two bytes of data total. */ | ||
| 79 | #define MIDI_COMMAND_SYSEX_2BYTE 0x20 | ||
| 80 | |||
| 81 | /** MIDI command for System Exclusive (SysEx) single event that has three bytes of data total. */ | ||
| 82 | #define MIDI_COMMAND_SYSEX_3BYTE 0x30 | ||
| 83 | |||
| 84 | /** MIDI command for System Exclusive (SysEx) stream event that has at least four bytes of data total. */ | ||
| 85 | #define MIDI_COMMAND_SYSEX_START_3BYTE 0x40 | ||
| 86 | |||
| 87 | /** MIDI command for System Exclusive (SysEx) stream event terminator with one remaining data byte. */ | ||
| 88 | #define MIDI_COMMAND_SYSEX_END_1BYTE 0x50 | ||
| 89 | |||
| 90 | /** MIDI command for System Exclusive (SysEx) stream event terminator with two remaining data bytes. */ | ||
| 91 | #define MIDI_COMMAND_SYSEX_END_2BYTE 0x60 | ||
| 92 | |||
| 93 | /** MIDI command for System Exclusive (SysEx) stream event terminator with three remaining data bytes. */ | ||
| 94 | #define MIDI_COMMAND_SYSEX_END_3BYTE 0x70 | ||
| 95 | |||
| 96 | /** MIDI command for a note off (deactivation) event. */ | ||
| 97 | #define MIDI_COMMAND_NOTE_OFF 0x80 | ||
| 98 | |||
| 99 | /** MIDI command for a note on (activation) event. */ | ||
| 100 | #define MIDI_COMMAND_NOTE_ON 0x90 | ||
| 101 | |||
| 102 | /** MIDI command for a note pressure change event. */ | ||
| 103 | #define MIDI_COMMAND_NOTE_PRESSURE 0xA0 | ||
| 104 | |||
| 105 | /** MIDI command for a control change event. */ | ||
| 106 | #define MIDI_COMMAND_CONTROL_CHANGE 0xB0 | ||
| 107 | |||
| 108 | /** MIDI command for a control change event. */ | ||
| 109 | #define MIDI_COMMAND_PROGRAM_CHANGE 0xC0 | ||
| 110 | |||
| 111 | /** MIDI command for a channel pressure change event. */ | ||
| 112 | #define MIDI_COMMAND_CHANNEL_PRESSURE 0xD0 | ||
| 113 | |||
| 114 | /** MIDI command for a pitch change event. */ | ||
| 115 | #define MIDI_COMMAND_PITCH_WHEEL_CHANGE 0xE0 | ||
| 116 | //@} | ||
| 117 | |||
| 118 | /** Standard key press velocity value used for all note events. */ | ||
| 119 | #define MIDI_STANDARD_VELOCITY 64 | ||
| 120 | |||
| 121 | /** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel | ||
| 122 | * addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address. | ||
| 123 | * | ||
| 124 | * \param[in] channel MIDI channel number to address. | ||
| 125 | * | ||
| 126 | * \return Constructed MIDI channel ID. | ||
| 127 | */ | ||
| 128 | #define MIDI_CHANNEL(channel) ((channel) - 1) | ||
| 129 | |||
| 130 | /** Constructs a MIDI event ID from a given MIDI command and a virtual MIDI cable index. This can then be | ||
| 131 | * used to create and decode \ref MIDI_EventPacket_t MIDI event packets. | ||
| 132 | * | ||
| 133 | * \param[in] virtualcable Index of the virtual MIDI cable the event relates to | ||
| 134 | * \param[in] command MIDI command to send through the virtual MIDI cable | ||
| 135 | * | ||
| 136 | * \return Constructed MIDI event ID. | ||
| 137 | */ | ||
| 138 | #define MIDI_EVENT(virtualcable, command) (((virtualcable) << 4) | ((command) >> 4)) | ||
| 139 | |||
| 140 | /* Enums: */ | ||
| 141 | /** Enum for the possible MIDI jack types in a MIDI device jack descriptor. */ | ||
| 142 | enum MIDI_JackTypes_t | ||
| 143 | { | ||
| 144 | MIDI_JACKTYPE_Embedded = 0x01, /**< MIDI class descriptor jack type value for an embedded (logical) MIDI input or output jack. */ | ||
| 145 | MIDI_JACKTYPE_External = 0x02, /**< MIDI class descriptor jack type value for an external (physical) MIDI input or output jack. */ | ||
| 146 | }; | ||
| 147 | |||
| 148 | /* Type Defines: */ | ||
| 149 | /** \brief MIDI class-specific Streaming Interface Descriptor (LUFA naming conventions). | ||
| 150 | * | ||
| 151 | * Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host | ||
| 152 | * how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors. | ||
| 153 | * See the USB Audio specification for more details. | ||
| 154 | * | ||
| 155 | * \see \ref USB_MIDI_StdDescriptor_AudioInterface_AS_t for the version of this type with standard element names. | ||
| 156 | * | ||
| 157 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 158 | */ | ||
| 159 | typedef struct | ||
| 160 | { | ||
| 161 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 162 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 163 | |||
| 164 | uint16_t AudioSpecification; /**< Binary coded decimal value, indicating the supported Audio Class | ||
| 165 | * specification version. | ||
| 166 | * | ||
| 167 | * \see \ref VERSION_BCD() utility macro. | ||
| 168 | */ | ||
| 169 | uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ | ||
| 170 | } ATTR_PACKED USB_MIDI_Descriptor_AudioInterface_AS_t; | ||
| 171 | |||
| 172 | /** \brief MIDI class-specific Streaming Interface Descriptor (USB-IF naming conventions). | ||
| 173 | * | ||
| 174 | * Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host | ||
| 175 | * how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors. | ||
| 176 | * See the USB Audio specification for more details. | ||
| 177 | * | ||
| 178 | * \see \ref USB_MIDI_Descriptor_AudioInterface_AS_t for the version of this type with non-standard LUFA specific | ||
| 179 | * element names. | ||
| 180 | * | ||
| 181 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 182 | */ | ||
| 183 | typedef struct | ||
| 184 | { | ||
| 185 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 186 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 187 | * given by the specific class. | ||
| 188 | */ | ||
| 189 | |||
| 190 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 191 | |||
| 192 | uint16_t bcdMSC; /**< Binary coded decimal value, indicating the supported MIDI Class specification version. | ||
| 193 | * | ||
| 194 | * \see \ref VERSION_BCD() utility macro. | ||
| 195 | */ | ||
| 196 | uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ | ||
| 197 | } ATTR_PACKED USB_MIDI_StdDescriptor_AudioInterface_AS_t; | ||
| 198 | |||
| 199 | /** \brief MIDI class-specific Input Jack Descriptor (LUFA naming conventions). | ||
| 200 | * | ||
| 201 | * Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either | ||
| 202 | * a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint). | ||
| 203 | * | ||
| 204 | * \see \ref USB_MIDI_StdDescriptor_InputJack_t for the version of this type with standard element names. | ||
| 205 | * | ||
| 206 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 207 | */ | ||
| 208 | typedef struct | ||
| 209 | { | ||
| 210 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 211 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 212 | |||
| 213 | uint8_t JackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ | ||
| 214 | uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */ | ||
| 215 | |||
| 216 | uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 217 | } ATTR_PACKED USB_MIDI_Descriptor_InputJack_t; | ||
| 218 | |||
| 219 | /** \brief MIDI class-specific Input Jack Descriptor (USB-IF naming conventions). | ||
| 220 | * | ||
| 221 | * Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either | ||
| 222 | * a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint). | ||
| 223 | * | ||
| 224 | * \see \ref USB_MIDI_Descriptor_InputJack_t for the version of this type with non-standard LUFA specific | ||
| 225 | * element names. | ||
| 226 | * | ||
| 227 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 228 | */ | ||
| 229 | typedef struct | ||
| 230 | { | ||
| 231 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 232 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 233 | * given by the specific class. | ||
| 234 | */ | ||
| 235 | |||
| 236 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 237 | |||
| 238 | uint8_t bJackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ | ||
| 239 | uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */ | ||
| 240 | |||
| 241 | uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 242 | } ATTR_PACKED USB_MIDI_StdDescriptor_InputJack_t; | ||
| 243 | |||
| 244 | /** \brief MIDI class-specific Output Jack Descriptor (LUFA naming conventions). | ||
| 245 | * | ||
| 246 | * Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either | ||
| 247 | * a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint). | ||
| 248 | * | ||
| 249 | * \see \ref USB_MIDI_StdDescriptor_OutputJack_t for the version of this type with standard element names. | ||
| 250 | * | ||
| 251 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 252 | */ | ||
| 253 | typedef struct | ||
| 254 | { | ||
| 255 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 256 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 257 | |||
| 258 | uint8_t JackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ | ||
| 259 | uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */ | ||
| 260 | |||
| 261 | uint8_t NumberOfPins; /**< Number of output channels within the jack, either physical or logical. */ | ||
| 262 | uint8_t SourceJackID[1]; /**< ID of each output pin's source data jack. */ | ||
| 263 | uint8_t SourcePinID[1]; /**< Pin number in the input jack of each output pin's source data. */ | ||
| 264 | |||
| 265 | uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 266 | } ATTR_PACKED USB_MIDI_Descriptor_OutputJack_t; | ||
| 267 | |||
| 268 | /** \brief MIDI class-specific Output Jack Descriptor (USB-IF naming conventions). | ||
| 269 | * | ||
| 270 | * Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either | ||
| 271 | * a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint). | ||
| 272 | * | ||
| 273 | * \see \ref USB_MIDI_Descriptor_OutputJack_t for the version of this type with non-standard LUFA specific | ||
| 274 | * element names. | ||
| 275 | * | ||
| 276 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 277 | */ | ||
| 278 | typedef struct | ||
| 279 | { | ||
| 280 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 281 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 282 | * given by the specific class. | ||
| 283 | */ | ||
| 284 | |||
| 285 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 286 | |||
| 287 | uint8_t bJackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ | ||
| 288 | uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */ | ||
| 289 | |||
| 290 | uint8_t bNrInputPins; /**< Number of output channels within the jack, either physical or logical. */ | ||
| 291 | uint8_t baSourceID[1]; /**< ID of each output pin's source data jack. */ | ||
| 292 | uint8_t baSourcePin[1]; /**< Pin number in the input jack of each output pin's source data. */ | ||
| 293 | |||
| 294 | uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */ | ||
| 295 | } ATTR_PACKED USB_MIDI_StdDescriptor_OutputJack_t; | ||
| 296 | |||
| 297 | /** \brief Audio class-specific Jack Endpoint Descriptor (LUFA naming conventions). | ||
| 298 | * | ||
| 299 | * Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information | ||
| 300 | * on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio | ||
| 301 | * class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details. | ||
| 302 | * | ||
| 303 | * \see \ref USB_MIDI_StdDescriptor_Jack_Endpoint_t for the version of this type with standard element names. | ||
| 304 | * | ||
| 305 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 306 | */ | ||
| 307 | typedef struct | ||
| 308 | { | ||
| 309 | USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ | ||
| 310 | uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 311 | |||
| 312 | uint8_t TotalEmbeddedJacks; /**< Total number of jacks inside this endpoint. */ | ||
| 313 | uint8_t AssociatedJackID[1]; /**< IDs of each jack inside the endpoint. */ | ||
| 314 | } ATTR_PACKED USB_MIDI_Descriptor_Jack_Endpoint_t; | ||
| 315 | |||
| 316 | /** \brief Audio class-specific Jack Endpoint Descriptor (USB-IF naming conventions). | ||
| 317 | * | ||
| 318 | * Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information | ||
| 319 | * on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio | ||
| 320 | * class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details. | ||
| 321 | * | ||
| 322 | * \see \ref USB_MIDI_Descriptor_Jack_Endpoint_t for the version of this type with non-standard LUFA specific | ||
| 323 | * element names. | ||
| 324 | * | ||
| 325 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 326 | */ | ||
| 327 | typedef struct | ||
| 328 | { | ||
| 329 | uint8_t bLength; /**< Size of the descriptor, in bytes. */ | ||
| 330 | uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value | ||
| 331 | * given by the specific class. | ||
| 332 | */ | ||
| 333 | |||
| 334 | uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ | ||
| 335 | |||
| 336 | uint8_t bNumEmbMIDIJack; /**< Total number of jacks inside this endpoint. */ | ||
| 337 | uint8_t bAssocJackID[1]; /**< IDs of each jack inside the endpoint. */ | ||
| 338 | } ATTR_PACKED USB_MIDI_StdDescriptor_Jack_Endpoint_t; | ||
| 339 | |||
| 340 | /** \brief MIDI Class Driver Event Packet. | ||
| 341 | * | ||
| 342 | * Type define for a USB MIDI event packet, used to encapsulate sent and received MIDI messages from a USB MIDI interface. | ||
| 343 | * | ||
| 344 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 345 | */ | ||
| 346 | typedef struct | ||
| 347 | { | ||
| 348 | uint8_t Event; /**< MIDI event type, constructed with the \ref MIDI_EVENT() macro. */ | ||
| 349 | |||
| 350 | uint8_t Data1; /**< First byte of data in the MIDI event. */ | ||
| 351 | uint8_t Data2; /**< Second byte of data in the MIDI event. */ | ||
| 352 | uint8_t Data3; /**< Third byte of data in the MIDI event. */ | ||
| 353 | } ATTR_PACKED MIDI_EventPacket_t; | ||
| 354 | |||
| 355 | /* Disable C linkage for C++ Compilers: */ | ||
| 356 | #if defined(__cplusplus) | ||
| 357 | } | ||
| 358 | #endif | ||
| 359 | |||
| 360 | #endif | ||
| 361 | |||
| 362 | /** @} */ | ||
| 363 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h new file mode 100644 index 000000000..d2ea37a82 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h | |||
| @@ -0,0 +1,368 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB Mass Storage Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB Mass Storage Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassMS | ||
| 41 | * \defgroup Group_USBClassMSCommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassMSCommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * Mass Storage Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _MS_CLASS_COMMON_H_ | ||
| 51 | #define _MS_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Includes: */ | ||
| 54 | #include "../../Core/StdDescriptors.h" | ||
| 55 | |||
| 56 | /* Enable C linkage for C++ Compilers: */ | ||
| 57 | #if defined(__cplusplus) | ||
| 58 | extern "C" { | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Preprocessor Checks: */ | ||
| 62 | #if !defined(__INCLUDE_FROM_MS_DRIVER) | ||
| 63 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* Macros: */ | ||
| 67 | /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */ | ||
| 68 | #define MS_CBW_SIGNATURE 0x43425355UL | ||
| 69 | |||
| 70 | /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */ | ||
| 71 | #define MS_CSW_SIGNATURE 0x53425355UL | ||
| 72 | |||
| 73 | /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */ | ||
| 74 | #define MS_COMMAND_DIR_DATA_OUT (0 << 7) | ||
| 75 | |||
| 76 | /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */ | ||
| 77 | #define MS_COMMAND_DIR_DATA_IN (1 << 7) | ||
| 78 | |||
| 79 | /** \name SCSI Commands*/ | ||
| 80 | //@{ | ||
| 81 | /** SCSI Command Code for an INQUIRY command. */ | ||
| 82 | #define SCSI_CMD_INQUIRY 0x12 | ||
| 83 | |||
| 84 | /** SCSI Command Code for a REQUEST SENSE command. */ | ||
| 85 | #define SCSI_CMD_REQUEST_SENSE 0x03 | ||
| 86 | |||
| 87 | /** SCSI Command Code for a TEST UNIT READY command. */ | ||
| 88 | #define SCSI_CMD_TEST_UNIT_READY 0x00 | ||
| 89 | |||
| 90 | /** SCSI Command Code for a READ CAPACITY (10) command. */ | ||
| 91 | #define SCSI_CMD_READ_CAPACITY_10 0x25 | ||
| 92 | |||
| 93 | /** SCSI Command Code for a START STOP UNIT command. */ | ||
| 94 | #define SCSI_CMD_START_STOP_UNIT 0x1B | ||
| 95 | |||
| 96 | /** SCSI Command Code for a SEND DIAGNOSTIC command. */ | ||
| 97 | #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D | ||
| 98 | |||
| 99 | /** SCSI Command Code for a PREVENT ALLOW MEDIUM REMOVAL command. */ | ||
| 100 | #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E | ||
| 101 | |||
| 102 | /** SCSI Command Code for a WRITE (10) command. */ | ||
| 103 | #define SCSI_CMD_WRITE_10 0x2A | ||
| 104 | |||
| 105 | /** SCSI Command Code for a READ (10) command. */ | ||
| 106 | #define SCSI_CMD_READ_10 0x28 | ||
| 107 | |||
| 108 | /** SCSI Command Code for a WRITE (6) command. */ | ||
| 109 | #define SCSI_CMD_WRITE_6 0x0A | ||
| 110 | |||
| 111 | /** SCSI Command Code for a READ (6) command. */ | ||
| 112 | #define SCSI_CMD_READ_6 0x08 | ||
| 113 | |||
| 114 | /** SCSI Command Code for a VERIFY (10) command. */ | ||
| 115 | #define SCSI_CMD_VERIFY_10 0x2F | ||
| 116 | |||
| 117 | /** SCSI Command Code for a MODE SENSE (6) command. */ | ||
| 118 | #define SCSI_CMD_MODE_SENSE_6 0x1A | ||
| 119 | |||
| 120 | /** SCSI Command Code for a MODE SENSE (10) command. */ | ||
| 121 | #define SCSI_CMD_MODE_SENSE_10 0x5A | ||
| 122 | //@} | ||
| 123 | |||
| 124 | /** \name SCSI Sense Key Values */ | ||
| 125 | //@{ | ||
| 126 | /** SCSI Sense Code to indicate no error has occurred. */ | ||
| 127 | #define SCSI_SENSE_KEY_GOOD 0x00 | ||
| 128 | |||
| 129 | /** SCSI Sense Code to indicate that the device has recovered from an error. */ | ||
| 130 | #define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01 | ||
| 131 | |||
| 132 | /** SCSI Sense Code to indicate that the device is not ready for a new command. */ | ||
| 133 | #define SCSI_SENSE_KEY_NOT_READY 0x02 | ||
| 134 | |||
| 135 | /** SCSI Sense Code to indicate an error whilst accessing the medium. */ | ||
| 136 | #define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03 | ||
| 137 | |||
| 138 | /** SCSI Sense Code to indicate a hardware error has occurred. */ | ||
| 139 | #define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04 | ||
| 140 | |||
| 141 | /** SCSI Sense Code to indicate that an illegal request has been issued. */ | ||
| 142 | #define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05 | ||
| 143 | |||
| 144 | /** SCSI Sense Code to indicate that the unit requires attention from the host to indicate | ||
| 145 | * a reset event, medium removal or other condition. | ||
| 146 | */ | ||
| 147 | #define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06 | ||
| 148 | |||
| 149 | /** SCSI Sense Code to indicate that a write attempt on a protected block has been made. */ | ||
| 150 | #define SCSI_SENSE_KEY_DATA_PROTECT 0x07 | ||
| 151 | |||
| 152 | /** SCSI Sense Code to indicate an error while trying to write to a write-once medium. */ | ||
| 153 | #define SCSI_SENSE_KEY_BLANK_CHECK 0x08 | ||
| 154 | |||
| 155 | /** SCSI Sense Code to indicate a vendor specific error has occurred. */ | ||
| 156 | #define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09 | ||
| 157 | |||
| 158 | /** SCSI Sense Code to indicate that an EXTENDED COPY command has aborted due to an error. */ | ||
| 159 | #define SCSI_SENSE_KEY_COPY_ABORTED 0x0A | ||
| 160 | |||
| 161 | /** SCSI Sense Code to indicate that the device has aborted the issued command. */ | ||
| 162 | #define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B | ||
| 163 | |||
| 164 | /** SCSI Sense Code to indicate an attempt to write past the end of a partition has been made. */ | ||
| 165 | #define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D | ||
| 166 | |||
| 167 | /** SCSI Sense Code to indicate that the source data did not match the data read from the medium. */ | ||
| 168 | #define SCSI_SENSE_KEY_MISCOMPARE 0x0E | ||
| 169 | //@} | ||
| 170 | |||
| 171 | /** \name SCSI Additional Sense Codes */ | ||
| 172 | //@{ | ||
| 173 | /** SCSI Additional Sense Code to indicate no additional sense information is available. */ | ||
| 174 | #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00 | ||
| 175 | |||
| 176 | /** SCSI Additional Sense Code to indicate that the logical unit (LUN) addressed is not ready. */ | ||
| 177 | #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04 | ||
| 178 | |||
| 179 | /** SCSI Additional Sense Code to indicate an invalid field was encountered while processing the issued command. */ | ||
| 180 | #define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24 | ||
| 181 | |||
| 182 | /** SCSI Additional Sense Code to indicate that a medium that was previously indicated as not ready has now | ||
| 183 | * become ready for use. | ||
| 184 | */ | ||
| 185 | #define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28 | ||
| 186 | |||
| 187 | /** SCSI Additional Sense Code to indicate that an attempt to write to a protected area was made. */ | ||
| 188 | #define SCSI_ASENSE_WRITE_PROTECTED 0x27 | ||
| 189 | |||
| 190 | /** SCSI Additional Sense Code to indicate an error whilst formatting the device medium. */ | ||
| 191 | #define SCSI_ASENSE_FORMAT_ERROR 0x31 | ||
| 192 | |||
| 193 | /** SCSI Additional Sense Code to indicate an invalid command was issued. */ | ||
| 194 | #define SCSI_ASENSE_INVALID_COMMAND 0x20 | ||
| 195 | |||
| 196 | /** SCSI Additional Sense Code to indicate a write to a block out outside of the medium's range was issued. */ | ||
| 197 | #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 | ||
| 198 | |||
| 199 | /** SCSI Additional Sense Code to indicate that no removable medium is inserted into the device. */ | ||
| 200 | #define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A | ||
| 201 | //@} | ||
| 202 | |||
| 203 | /** \name SCSI Additional Sense Key Code Qualifiers */ | ||
| 204 | //@{ | ||
| 205 | /** SCSI Additional Sense Qualifier Code to indicate no additional sense qualifier information is available. */ | ||
| 206 | #define SCSI_ASENSEQ_NO_QUALIFIER 0x00 | ||
| 207 | |||
| 208 | /** SCSI Additional Sense Qualifier Code to indicate that a medium format command failed to complete. */ | ||
| 209 | #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01 | ||
| 210 | |||
| 211 | /** SCSI Additional Sense Qualifier Code to indicate that an initializing command must be issued before the issued | ||
| 212 | * command can be executed. | ||
| 213 | */ | ||
| 214 | #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02 | ||
| 215 | |||
| 216 | /** SCSI Additional Sense Qualifier Code to indicate that an operation is currently in progress. */ | ||
| 217 | #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07 | ||
| 218 | //@} | ||
| 219 | |||
| 220 | /* Enums: */ | ||
| 221 | /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Mass | ||
| 222 | * Storage device class. | ||
| 223 | */ | ||
| 224 | enum MS_Descriptor_ClassSubclassProtocol_t | ||
| 225 | { | ||
| 226 | MS_CSCP_MassStorageClass = 0x08, /**< Descriptor Class value indicating that the device or interface | ||
| 227 | * belongs to the Mass Storage class. | ||
| 228 | */ | ||
| 229 | MS_CSCP_SCSITransparentSubclass = 0x06, /**< Descriptor Subclass value indicating that the device or interface | ||
| 230 | * belongs to the SCSI Transparent Command Set subclass of the Mass | ||
| 231 | * storage class. | ||
| 232 | */ | ||
| 233 | MS_CSCP_BulkOnlyTransportProtocol = 0x50, /**< Descriptor Protocol value indicating that the device or interface | ||
| 234 | * belongs to the Bulk Only Transport protocol of the Mass Storage class. | ||
| 235 | */ | ||
| 236 | }; | ||
| 237 | |||
| 238 | /** Enum for the Mass Storage class specific control requests that can be issued by the USB bus host. */ | ||
| 239 | enum MS_ClassRequests_t | ||
| 240 | { | ||
| 241 | MS_REQ_GetMaxLUN = 0xFE, /**< Mass Storage class-specific request to retrieve the total number of Logical | ||
| 242 | * Units (drives) in the SCSI device. | ||
| 243 | */ | ||
| 244 | MS_REQ_MassStorageReset = 0xFF, /**< Mass Storage class-specific request to reset the Mass Storage interface, | ||
| 245 | * ready for the next command. | ||
| 246 | */ | ||
| 247 | }; | ||
| 248 | |||
| 249 | /** Enum for the possible command status wrapper return status codes. */ | ||
| 250 | enum MS_CommandStatusCodes_t | ||
| 251 | { | ||
| 252 | MS_SCSI_COMMAND_Pass = 0, /**< Command completed with no error */ | ||
| 253 | MS_SCSI_COMMAND_Fail = 1, /**< Command failed to complete - host may check the exact error via a | ||
| 254 | * SCSI REQUEST SENSE command. | ||
| 255 | */ | ||
| 256 | MS_SCSI_COMMAND_PhaseError = 2, /**< Command failed due to being invalid in the current phase. */ | ||
| 257 | }; | ||
| 258 | |||
| 259 | /* Type Defines: */ | ||
| 260 | /** \brief Mass Storage Class Command Block Wrapper. | ||
| 261 | * | ||
| 262 | * Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. | ||
| 263 | * | ||
| 264 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 265 | */ | ||
| 266 | typedef struct | ||
| 267 | { | ||
| 268 | uint32_t Signature; /**< Command block signature, must be \ref MS_CBW_SIGNATURE to indicate a valid Command Block. */ | ||
| 269 | uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */ | ||
| 270 | uint32_t DataTransferLength; /**< Length of the optional data portion of the issued command, in bytes. */ | ||
| 271 | uint8_t Flags; /**< Command block flags, indicating command data direction. */ | ||
| 272 | uint8_t LUN; /**< Logical Unit number this command is issued to. */ | ||
| 273 | uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array. */ | ||
| 274 | uint8_t SCSICommandData[16]; /**< Issued SCSI command in the Command Block. */ | ||
| 275 | } ATTR_PACKED MS_CommandBlockWrapper_t; | ||
| 276 | |||
| 277 | /** \brief Mass Storage Class Command Status Wrapper. | ||
| 278 | * | ||
| 279 | * Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. | ||
| 280 | * | ||
| 281 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 282 | */ | ||
| 283 | typedef struct | ||
| 284 | { | ||
| 285 | uint32_t Signature; /**< Status block signature, must be \ref MS_CSW_SIGNATURE to indicate a valid Command Status. */ | ||
| 286 | uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */ | ||
| 287 | uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command. */ | ||
| 288 | uint8_t Status; /**< Status code of the issued command - a value from the \ref MS_CommandStatusCodes_t enum. */ | ||
| 289 | } ATTR_PACKED MS_CommandStatusWrapper_t; | ||
| 290 | |||
| 291 | /** \brief Mass Storage Class SCSI Sense Structure | ||
| 292 | * | ||
| 293 | * Type define for a SCSI Sense structure. Structures of this type are filled out by the | ||
| 294 | * device via the \ref MS_Host_RequestSense() function, indicating the current sense data of the | ||
| 295 | * device (giving explicit error codes for the last issued command). For details of the | ||
| 296 | * structure contents, refer to the SCSI specifications. | ||
| 297 | */ | ||
| 298 | typedef struct | ||
| 299 | { | ||
| 300 | uint8_t ResponseCode; | ||
| 301 | |||
| 302 | uint8_t SegmentNumber; | ||
| 303 | |||
| 304 | unsigned SenseKey : 4; | ||
| 305 | unsigned Reserved : 1; | ||
| 306 | unsigned ILI : 1; | ||
| 307 | unsigned EOM : 1; | ||
| 308 | unsigned FileMark : 1; | ||
| 309 | |||
| 310 | uint8_t Information[4]; | ||
| 311 | uint8_t AdditionalLength; | ||
| 312 | uint8_t CmdSpecificInformation[4]; | ||
| 313 | uint8_t AdditionalSenseCode; | ||
| 314 | uint8_t AdditionalSenseQualifier; | ||
| 315 | uint8_t FieldReplaceableUnitCode; | ||
| 316 | uint8_t SenseKeySpecific[3]; | ||
| 317 | } ATTR_PACKED SCSI_Request_Sense_Response_t; | ||
| 318 | |||
| 319 | /** \brief Mass Storage Class SCSI Inquiry Structure. | ||
| 320 | * | ||
| 321 | * Type define for a SCSI Inquiry structure. Structures of this type are filled out by the | ||
| 322 | * device via the \ref MS_Host_GetInquiryData() function, retrieving the attached device's | ||
| 323 | * information. | ||
| 324 | * | ||
| 325 | * For details of the structure contents, refer to the SCSI specifications. | ||
| 326 | */ | ||
| 327 | typedef struct | ||
| 328 | { | ||
| 329 | unsigned DeviceType : 5; | ||
| 330 | unsigned PeripheralQualifier : 3; | ||
| 331 | |||
| 332 | unsigned Reserved : 7; | ||
| 333 | unsigned Removable : 1; | ||
| 334 | |||
| 335 | uint8_t Version; | ||
| 336 | |||
| 337 | unsigned ResponseDataFormat : 4; | ||
| 338 | unsigned Reserved2 : 1; | ||
| 339 | unsigned NormACA : 1; | ||
| 340 | unsigned TrmTsk : 1; | ||
| 341 | unsigned AERC : 1; | ||
| 342 | |||
| 343 | uint8_t AdditionalLength; | ||
| 344 | uint8_t Reserved3[2]; | ||
| 345 | |||
| 346 | unsigned SoftReset : 1; | ||
| 347 | unsigned CmdQue : 1; | ||
| 348 | unsigned Reserved4 : 1; | ||
| 349 | unsigned Linked : 1; | ||
| 350 | unsigned Sync : 1; | ||
| 351 | unsigned WideBus16Bit : 1; | ||
| 352 | unsigned WideBus32Bit : 1; | ||
| 353 | unsigned RelAddr : 1; | ||
| 354 | |||
| 355 | uint8_t VendorID[8]; | ||
| 356 | uint8_t ProductID[16]; | ||
| 357 | uint8_t RevisionID[4]; | ||
| 358 | } ATTR_PACKED SCSI_Inquiry_Response_t; | ||
| 359 | |||
| 360 | /* Disable C linkage for C++ Compilers: */ | ||
| 361 | #if defined(__cplusplus) | ||
| 362 | } | ||
| 363 | #endif | ||
| 364 | |||
| 365 | #endif | ||
| 366 | |||
| 367 | /** @} */ | ||
| 368 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h new file mode 100644 index 000000000..2db830e04 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB Printer Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB Printer Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassPrinter | ||
| 41 | * \defgroup Group_USBClassPrinterCommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassPrinterCommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * Printer Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _PRINTER_CLASS_COMMON_H_ | ||
| 51 | #define _PRINTER_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Includes: */ | ||
| 54 | #include "../../Core/StdDescriptors.h" | ||
| 55 | |||
| 56 | /* Enable C linkage for C++ Compilers: */ | ||
| 57 | #if defined(__cplusplus) | ||
| 58 | extern "C" { | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Preprocessor Checks: */ | ||
| 62 | #if !defined(__INCLUDE_FROM_PRINTER_DRIVER) | ||
| 63 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* Macros: */ | ||
| 67 | /** \name Virtual Printer Status Line Masks */ | ||
| 68 | //@{ | ||
| 69 | /** Port status mask for a printer device, indicating that an error has *not* occurred. */ | ||
| 70 | #define PRNT_PORTSTATUS_NOTERROR (1 << 3) | ||
| 71 | |||
| 72 | /** Port status mask for a printer device, indicating that the device is currently selected. */ | ||
| 73 | #define PRNT_PORTSTATUS_SELECT (1 << 4) | ||
| 74 | |||
| 75 | /** Port status mask for a printer device, indicating that the device is currently out of paper. */ | ||
| 76 | #define PRNT_PORTSTATUS_PAPEREMPTY (1 << 5) | ||
| 77 | //@} | ||
| 78 | |||
| 79 | /* Enums: */ | ||
| 80 | /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Printer | ||
| 81 | * device class. | ||
| 82 | */ | ||
| 83 | enum PRNT_Descriptor_ClassSubclassProtocol_t | ||
| 84 | { | ||
| 85 | PRNT_CSCP_PrinterClass = 0x07, /**< Descriptor Class value indicating that the device or interface | ||
| 86 | * belongs to the Printer class. | ||
| 87 | */ | ||
| 88 | PRNT_CSCP_PrinterSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface | ||
| 89 | * belongs to the Printer subclass. | ||
| 90 | */ | ||
| 91 | PRNT_CSCP_BidirectionalProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface | ||
| 92 | * belongs to the Bidirectional protocol of the Printer class. | ||
| 93 | */ | ||
| 94 | }; | ||
| 95 | |||
| 96 | /** Enum for the Printer class specific control requests that can be issued by the USB bus host. */ | ||
| 97 | enum PRNT_ClassRequests_t | ||
| 98 | { | ||
| 99 | PRNT_REQ_GetDeviceID = 0x00, /**< Printer class-specific request to retrieve the Unicode ID | ||
| 100 | * string of the device, containing the device's name, manufacturer | ||
| 101 | * and supported printer languages. | ||
| 102 | */ | ||
| 103 | PRNT_REQ_GetPortStatus = 0x01, /**< Printer class-specific request to get the current status of the | ||
| 104 | * virtual printer port, for device selection and ready states. | ||
| 105 | */ | ||
| 106 | PRNT_REQ_SoftReset = 0x02, /**< Printer class-specific request to reset the device, ready for new | ||
| 107 | * printer commands. | ||
| 108 | */ | ||
| 109 | }; | ||
| 110 | |||
| 111 | /* Disable C linkage for C++ Compilers: */ | ||
| 112 | #if defined(__cplusplus) | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 116 | #endif | ||
| 117 | |||
| 118 | /** @} */ | ||
| 119 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h new file mode 100644 index 000000000..ade1af067 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h | |||
| @@ -0,0 +1,411 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB RNDIS Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB RNDIS Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassRNDIS | ||
| 41 | * \defgroup Group_USBClassRNDISCommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassRNDISCommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * RNDIS Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _RNDIS_CLASS_COMMON_H_ | ||
| 51 | #define _RNDIS_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Macros: */ | ||
| 54 | #define __INCLUDE_FROM_CDC_DRIVER | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../Core/StdDescriptors.h" | ||
| 58 | #include "CDCClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_RNDIS_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Macros: */ | ||
| 71 | /** Additional error code for RNDIS functions when a device returns a logical command failure. */ | ||
| 72 | #define RNDIS_ERROR_LOGICAL_CMD_FAILED 0x80 | ||
| 73 | |||
| 74 | /** Implemented RNDIS Version Major. */ | ||
| 75 | #define REMOTE_NDIS_VERSION_MAJOR 0x01 | ||
| 76 | |||
| 77 | /** Implemented RNDIS Version Minor. */ | ||
| 78 | #define REMOTE_NDIS_VERSION_MINOR 0x00 | ||
| 79 | |||
| 80 | /** \name RNDIS Message Values */ | ||
| 81 | //@{ | ||
| 82 | #define REMOTE_NDIS_PACKET_MSG 0x00000001UL | ||
| 83 | #define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL | ||
| 84 | #define REMOTE_NDIS_HALT_MSG 0x00000003UL | ||
| 85 | #define REMOTE_NDIS_QUERY_MSG 0x00000004UL | ||
| 86 | #define REMOTE_NDIS_SET_MSG 0x00000005UL | ||
| 87 | #define REMOTE_NDIS_RESET_MSG 0x00000006UL | ||
| 88 | #define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL | ||
| 89 | #define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL | ||
| 90 | //@} | ||
| 91 | |||
| 92 | /** \name RNDIS Response Values */ | ||
| 93 | //@{ | ||
| 94 | #define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL | ||
| 95 | #define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL | ||
| 96 | #define REMOTE_NDIS_SET_CMPLT 0x80000005UL | ||
| 97 | #define REMOTE_NDIS_RESET_CMPLT 0x80000006UL | ||
| 98 | #define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL | ||
| 99 | //@} | ||
| 100 | |||
| 101 | /** \name RNDIS Status Values */ | ||
| 102 | //@{ | ||
| 103 | #define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL | ||
| 104 | #define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL | ||
| 105 | #define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL | ||
| 106 | #define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL | ||
| 107 | #define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL | ||
| 108 | #define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL | ||
| 109 | //@} | ||
| 110 | |||
| 111 | /** \name RNDIS Media States */ | ||
| 112 | //@{ | ||
| 113 | #define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL | ||
| 114 | #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL | ||
| 115 | //@} | ||
| 116 | |||
| 117 | /** \name RNDIS Media Types */ | ||
| 118 | //@{ | ||
| 119 | #define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL | ||
| 120 | //@} | ||
| 121 | |||
| 122 | /** \name RNDIS Connection Types */ | ||
| 123 | //@{ | ||
| 124 | #define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL | ||
| 125 | #define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL | ||
| 126 | //@} | ||
| 127 | |||
| 128 | /** \name RNDIS Packet Types */ | ||
| 129 | //@{ | ||
| 130 | #define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL | ||
| 131 | #define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL | ||
| 132 | #define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL | ||
| 133 | #define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL | ||
| 134 | #define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL | ||
| 135 | #define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL | ||
| 136 | #define REMOTE_NDIS_PACKET_SMT 0x00000040UL | ||
| 137 | #define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL | ||
| 138 | #define REMOTE_NDIS_PACKET_GROUP 0x00001000UL | ||
| 139 | #define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL | ||
| 140 | #define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL | ||
| 141 | #define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL | ||
| 142 | //@} | ||
| 143 | |||
| 144 | /** \name RNDIS OID Values */ | ||
| 145 | //@{ | ||
| 146 | #define OID_GEN_SUPPORTED_LIST 0x00010101UL | ||
| 147 | #define OID_GEN_HARDWARE_STATUS 0x00010102UL | ||
| 148 | #define OID_GEN_MEDIA_SUPPORTED 0x00010103UL | ||
| 149 | #define OID_GEN_MEDIA_IN_USE 0x00010104UL | ||
| 150 | #define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL | ||
| 151 | #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL | ||
| 152 | #define OID_GEN_LINK_SPEED 0x00010107UL | ||
| 153 | #define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL | ||
| 154 | #define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL | ||
| 155 | #define OID_GEN_VENDOR_ID 0x0001010CUL | ||
| 156 | #define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL | ||
| 157 | #define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL | ||
| 158 | #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL | ||
| 159 | #define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL | ||
| 160 | #define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL | ||
| 161 | #define OID_GEN_XMIT_OK 0x00020101UL | ||
| 162 | #define OID_GEN_RCV_OK 0x00020102UL | ||
| 163 | #define OID_GEN_XMIT_ERROR 0x00020103UL | ||
| 164 | #define OID_GEN_RCV_ERROR 0x00020104UL | ||
| 165 | #define OID_GEN_RCV_NO_BUFFER 0x00020105UL | ||
| 166 | #define OID_802_3_PERMANENT_ADDRESS 0x01010101UL | ||
| 167 | #define OID_802_3_CURRENT_ADDRESS 0x01010102UL | ||
| 168 | #define OID_802_3_MULTICAST_LIST 0x01010103UL | ||
| 169 | #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL | ||
| 170 | #define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL | ||
| 171 | #define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL | ||
| 172 | #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL | ||
| 173 | //@} | ||
| 174 | |||
| 175 | /** Maximum size in bytes of an Ethernet frame according to the Ethernet standard. */ | ||
| 176 | #define ETHERNET_FRAME_SIZE_MAX 1500 | ||
| 177 | |||
| 178 | /* Enums: */ | ||
| 179 | /** Enum for the RNDIS class specific control requests that can be issued by the USB bus host. */ | ||
| 180 | enum RNDIS_ClassRequests_t | ||
| 181 | { | ||
| 182 | RNDIS_REQ_SendEncapsulatedCommand = 0x00, /**< RNDIS request to issue a host-to-device NDIS command. */ | ||
| 183 | RNDIS_REQ_GetEncapsulatedResponse = 0x01, /**< RNDIS request to issue a device-to-host NDIS response. */ | ||
| 184 | }; | ||
| 185 | |||
| 186 | /** Enum for the possible NDIS adapter states. */ | ||
| 187 | enum RNDIS_States_t | ||
| 188 | { | ||
| 189 | RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized. */ | ||
| 190 | RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers. */ | ||
| 191 | RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers. */ | ||
| 192 | }; | ||
| 193 | |||
| 194 | /** Enum for the RNDIS class specific notification requests that can be issued by a RNDIS device to a host. */ | ||
| 195 | enum RNDIS_ClassNotifications_t | ||
| 196 | { | ||
| 197 | RNDIS_NOTIF_ResponseAvailable = 0x01, /**< Notification request value for a RNDIS Response Available notification. */ | ||
| 198 | }; | ||
| 199 | |||
| 200 | /** Enum for the NDIS hardware states. */ | ||
| 201 | enum NDIS_Hardware_Status_t | ||
| 202 | { | ||
| 203 | NDIS_HardwareStatus_Ready, /**< Hardware Ready to accept commands from the host. */ | ||
| 204 | NDIS_HardwareStatus_Initializing, /**< Hardware busy initializing. */ | ||
| 205 | NDIS_HardwareStatus_Reset, /**< Hardware reset. */ | ||
| 206 | NDIS_HardwareStatus_Closing, /**< Hardware currently closing. */ | ||
| 207 | NDIS_HardwareStatus_NotReady /**< Hardware not ready to accept commands from the host. */ | ||
| 208 | }; | ||
| 209 | |||
| 210 | /* Type Defines: */ | ||
| 211 | /** \brief MAC Address Structure. | ||
| 212 | * | ||
| 213 | * Type define for a physical MAC address of a device on a network. | ||
| 214 | */ | ||
| 215 | typedef struct | ||
| 216 | { | ||
| 217 | uint8_t Octets[6]; /**< Individual bytes of a MAC address */ | ||
| 218 | } ATTR_PACKED MAC_Address_t; | ||
| 219 | |||
| 220 | /** \brief RNDIS Common Message Header Structure. | ||
| 221 | * | ||
| 222 | * Type define for a RNDIS message header, sent before RNDIS messages. | ||
| 223 | * | ||
| 224 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 225 | */ | ||
| 226 | typedef struct | ||
| 227 | { | ||
| 228 | uint32_t MessageType; /**< RNDIS message type, a \c REMOTE_NDIS_*_MSG constant */ | ||
| 229 | uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */ | ||
| 230 | } ATTR_PACKED RNDIS_Message_Header_t; | ||
| 231 | |||
| 232 | /** \brief RNDIS Message Structure. | ||
| 233 | * | ||
| 234 | * Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter. | ||
| 235 | * | ||
| 236 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 237 | */ | ||
| 238 | typedef struct | ||
| 239 | { | ||
| 240 | uint32_t MessageType; | ||
| 241 | uint32_t MessageLength; | ||
| 242 | uint32_t DataOffset; | ||
| 243 | uint32_t DataLength; | ||
| 244 | uint32_t OOBDataOffset; | ||
| 245 | uint32_t OOBDataLength; | ||
| 246 | uint32_t NumOOBDataElements; | ||
| 247 | uint32_t PerPacketInfoOffset; | ||
| 248 | uint32_t PerPacketInfoLength; | ||
| 249 | uint32_t VcHandle; | ||
| 250 | uint32_t Reserved; | ||
| 251 | } ATTR_PACKED RNDIS_Packet_Message_t; | ||
| 252 | |||
| 253 | /** \brief RNDIS Initialization Message Structure. | ||
| 254 | * | ||
| 255 | * Type define for a RNDIS Initialize command message. | ||
| 256 | * | ||
| 257 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 258 | */ | ||
| 259 | typedef struct | ||
| 260 | { | ||
| 261 | uint32_t MessageType; | ||
| 262 | uint32_t MessageLength; | ||
| 263 | uint32_t RequestId; | ||
| 264 | |||
| 265 | uint32_t MajorVersion; | ||
| 266 | uint32_t MinorVersion; | ||
| 267 | uint32_t MaxTransferSize; | ||
| 268 | } ATTR_PACKED RNDIS_Initialize_Message_t; | ||
| 269 | |||
| 270 | /** \brief RNDIS Initialize Complete Message Structure. | ||
| 271 | * | ||
| 272 | * Type define for a RNDIS Initialize Complete response message. | ||
| 273 | * | ||
| 274 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 275 | */ | ||
| 276 | typedef struct | ||
| 277 | { | ||
| 278 | uint32_t MessageType; | ||
| 279 | uint32_t MessageLength; | ||
| 280 | uint32_t RequestId; | ||
| 281 | uint32_t Status; | ||
| 282 | |||
| 283 | uint32_t MajorVersion; | ||
| 284 | uint32_t MinorVersion; | ||
| 285 | uint32_t DeviceFlags; | ||
| 286 | uint32_t Medium; | ||
| 287 | uint32_t MaxPacketsPerTransfer; | ||
| 288 | uint32_t MaxTransferSize; | ||
| 289 | uint32_t PacketAlignmentFactor; | ||
| 290 | uint32_t AFListOffset; | ||
| 291 | uint32_t AFListSize; | ||
| 292 | } ATTR_PACKED RNDIS_Initialize_Complete_t; | ||
| 293 | |||
| 294 | /** \brief RNDIS Keep Alive Message Structure. | ||
| 295 | * | ||
| 296 | * Type define for a RNDIS Keep Alive command message. | ||
| 297 | * | ||
| 298 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 299 | */ | ||
| 300 | typedef struct | ||
| 301 | { | ||
| 302 | uint32_t MessageType; | ||
| 303 | uint32_t MessageLength; | ||
| 304 | uint32_t RequestId; | ||
| 305 | } ATTR_PACKED RNDIS_KeepAlive_Message_t; | ||
| 306 | |||
| 307 | /** \brief RNDIS Keep Alive Complete Message Structure. | ||
| 308 | * | ||
| 309 | * Type define for a RNDIS Keep Alive Complete response message. | ||
| 310 | * | ||
| 311 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 312 | */ | ||
| 313 | typedef struct | ||
| 314 | { | ||
| 315 | uint32_t MessageType; | ||
| 316 | uint32_t MessageLength; | ||
| 317 | uint32_t RequestId; | ||
| 318 | uint32_t Status; | ||
| 319 | } ATTR_PACKED RNDIS_KeepAlive_Complete_t; | ||
| 320 | |||
| 321 | /** \brief RNDIS Reset Complete Message Structure. | ||
| 322 | * | ||
| 323 | * Type define for a RNDIS Reset Complete response message. | ||
| 324 | * | ||
| 325 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 326 | */ | ||
| 327 | typedef struct | ||
| 328 | { | ||
| 329 | uint32_t MessageType; | ||
| 330 | uint32_t MessageLength; | ||
| 331 | uint32_t Status; | ||
| 332 | |||
| 333 | uint32_t AddressingReset; | ||
| 334 | } ATTR_PACKED RNDIS_Reset_Complete_t; | ||
| 335 | |||
| 336 | /** \brief RNDIS OID Property Set Message Structure. | ||
| 337 | * | ||
| 338 | * Type define for a RNDIS OID Property Set command message. | ||
| 339 | * | ||
| 340 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 341 | */ | ||
| 342 | typedef struct | ||
| 343 | { | ||
| 344 | uint32_t MessageType; | ||
| 345 | uint32_t MessageLength; | ||
| 346 | uint32_t RequestId; | ||
| 347 | |||
| 348 | uint32_t Oid; | ||
| 349 | uint32_t InformationBufferLength; | ||
| 350 | uint32_t InformationBufferOffset; | ||
| 351 | uint32_t DeviceVcHandle; | ||
| 352 | } ATTR_PACKED RNDIS_Set_Message_t; | ||
| 353 | |||
| 354 | /** \brief RNDIS OID Property Set Complete Message Structure. | ||
| 355 | * | ||
| 356 | * Type define for a RNDIS OID Property Set Complete response message. | ||
| 357 | * | ||
| 358 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 359 | */ | ||
| 360 | typedef struct | ||
| 361 | { | ||
| 362 | uint32_t MessageType; | ||
| 363 | uint32_t MessageLength; | ||
| 364 | uint32_t RequestId; | ||
| 365 | uint32_t Status; | ||
| 366 | } ATTR_PACKED RNDIS_Set_Complete_t; | ||
| 367 | |||
| 368 | /** \brief RNDIS OID Property Query Message Structure. | ||
| 369 | * | ||
| 370 | * Type define for a RNDIS OID Property Query command message. | ||
| 371 | * | ||
| 372 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 373 | */ | ||
| 374 | typedef struct | ||
| 375 | { | ||
| 376 | uint32_t MessageType; | ||
| 377 | uint32_t MessageLength; | ||
| 378 | uint32_t RequestId; | ||
| 379 | |||
| 380 | uint32_t Oid; | ||
| 381 | uint32_t InformationBufferLength; | ||
| 382 | uint32_t InformationBufferOffset; | ||
| 383 | uint32_t DeviceVcHandle; | ||
| 384 | } ATTR_PACKED RNDIS_Query_Message_t; | ||
| 385 | |||
| 386 | /** \brief RNDIS OID Property Query Complete Message Structure. | ||
| 387 | * | ||
| 388 | * Type define for a RNDIS OID Property Query Complete response message. | ||
| 389 | * | ||
| 390 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 391 | */ | ||
| 392 | typedef struct | ||
| 393 | { | ||
| 394 | uint32_t MessageType; | ||
| 395 | uint32_t MessageLength; | ||
| 396 | uint32_t RequestId; | ||
| 397 | uint32_t Status; | ||
| 398 | |||
| 399 | uint32_t InformationBufferLength; | ||
| 400 | uint32_t InformationBufferOffset; | ||
| 401 | } ATTR_PACKED RNDIS_Query_Complete_t; | ||
| 402 | |||
| 403 | /* Disable C linkage for C++ Compilers: */ | ||
| 404 | #if defined(__cplusplus) | ||
| 405 | } | ||
| 406 | #endif | ||
| 407 | |||
| 408 | #endif | ||
| 409 | |||
| 410 | /** @} */ | ||
| 411 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h b/lib/lufa/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h new file mode 100644 index 000000000..7608b18cc --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Common definitions and declarations for the library USB Still Image Class driver. | ||
| 33 | * | ||
| 34 | * Common definitions and declarations for the library USB Still Image Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassSI | ||
| 41 | * \defgroup Group_USBClassSICommon Common Class Definitions | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassSICommon_ModDescription Module Description | ||
| 44 | * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB | ||
| 45 | * Still Image Class. | ||
| 46 | * | ||
| 47 | * @{ | ||
| 48 | */ | ||
| 49 | |||
| 50 | #ifndef _SI_CLASS_COMMON_H_ | ||
| 51 | #define _SI_CLASS_COMMON_H_ | ||
| 52 | |||
| 53 | /* Includes: */ | ||
| 54 | #include "../../Core/StdDescriptors.h" | ||
| 55 | |||
| 56 | /* Enable C linkage for C++ Compilers: */ | ||
| 57 | #if defined(__cplusplus) | ||
| 58 | extern "C" { | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Preprocessor Checks: */ | ||
| 62 | #if !defined(__INCLUDE_FROM_SI_DRIVER) | ||
| 63 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* Macros: */ | ||
| 67 | /** Length in bytes of a given Unicode string's character length. | ||
| 68 | * | ||
| 69 | * \param[in] Chars Total number of Unicode characters in the string. | ||
| 70 | * | ||
| 71 | * \return Number of bytes of the given unicode string. | ||
| 72 | */ | ||
| 73 | #define UNICODE_STRING_LENGTH(Chars) ((Chars) << 1) | ||
| 74 | |||
| 75 | /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for | ||
| 76 | * a command container. | ||
| 77 | * | ||
| 78 | * \param[in] Params Number of parameters which are to be sent in the \c Param field of the container. | ||
| 79 | */ | ||
| 80 | #define PIMA_COMMAND_SIZE(Params) ((sizeof(PIMA_Container_t) - 12) + ((Params) * sizeof(uint32_t))) | ||
| 81 | |||
| 82 | /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for | ||
| 83 | * a data container. | ||
| 84 | * | ||
| 85 | * \param[in] DataLen Length in bytes of the data in the container. | ||
| 86 | */ | ||
| 87 | #define PIMA_DATA_SIZE(DataLen) ((sizeof(PIMA_Container_t) - 12) + (DataLen)) | ||
| 88 | |||
| 89 | /* Enums: */ | ||
| 90 | /** Enum for the possible PIMA contains types. */ | ||
| 91 | enum PIMA_Container_Types_t | ||
| 92 | { | ||
| 93 | PIMA_CONTAINER_Undefined = 0, /**< Undefined container type. */ | ||
| 94 | PIMA_CONTAINER_CommandBlock = 1, /**< Command Block container type. */ | ||
| 95 | PIMA_CONTAINER_DataBlock = 2, /**< Data Block container type. */ | ||
| 96 | PIMA_CONTAINER_ResponseBlock = 3, /**< Response container type. */ | ||
| 97 | PIMA_CONTAINER_EventBlock = 4, /**< Event Block container type. */ | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* Enums: */ | ||
| 101 | /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the | ||
| 102 | * Still Image device class. | ||
| 103 | */ | ||
| 104 | enum SI_Descriptor_ClassSubclassProtocol_t | ||
| 105 | { | ||
| 106 | SI_CSCP_StillImageClass = 0x06, /**< Descriptor Class value indicating that the device or interface | ||
| 107 | * belongs to the Still Image class. | ||
| 108 | */ | ||
| 109 | SI_CSCP_StillImageSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface | ||
| 110 | * belongs to the Still Image subclass. | ||
| 111 | */ | ||
| 112 | SI_CSCP_BulkOnlyProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface | ||
| 113 | * belongs to the Bulk Only Transport protocol of the Still Image class. | ||
| 114 | */ | ||
| 115 | }; | ||
| 116 | |||
| 117 | /** Enums for the possible status codes of a returned Response Block from an attached PIMA compliant Still Image device. */ | ||
| 118 | enum PIMA_ResponseCodes_t | ||
| 119 | { | ||
| 120 | PIMA_RESPONSE_OK = 1, /**< Response code indicating no error in the issued command. */ | ||
| 121 | PIMA_RESPONSE_GeneralError = 2, /**< Response code indicating a general error while processing the | ||
| 122 | * issued command. | ||
| 123 | */ | ||
| 124 | PIMA_RESPONSE_SessionNotOpen = 3, /**< Response code indicating that the sent command requires an open | ||
| 125 | * session before being issued. | ||
| 126 | */ | ||
| 127 | PIMA_RESPONSE_InvalidTransaction = 4, /**< Response code indicating an invalid transaction occurred. */ | ||
| 128 | PIMA_RESPONSE_OperationNotSupported = 5, /**< Response code indicating that the issued command is not supported | ||
| 129 | * by the attached device. | ||
| 130 | */ | ||
| 131 | PIMA_RESPONSE_ParameterNotSupported = 6, /**< Response code indicating that one or more of the issued command's | ||
| 132 | * parameters are not supported by the device. | ||
| 133 | */ | ||
| 134 | }; | ||
| 135 | |||
| 136 | /* Type Defines: */ | ||
| 137 | /** \brief PIMA Still Image Device Command/Response Container. | ||
| 138 | * | ||
| 139 | * Type define for a PIMA container, use to send commands and receive responses to and from an | ||
| 140 | * attached Still Image device. | ||
| 141 | * | ||
| 142 | * \note Regardless of CPU architecture, these values should be stored as little endian. | ||
| 143 | */ | ||
| 144 | typedef struct | ||
| 145 | { | ||
| 146 | uint32_t DataLength; /**< Length of the container and data, in bytes. */ | ||
| 147 | uint16_t Type; /**< Container type, a value from the \ref PIMA_Container_Types_t enum. */ | ||
| 148 | uint16_t Code; /**< Command, event or response code of the container. */ | ||
| 149 | uint32_t TransactionID; /**< Unique container ID to link blocks together. */ | ||
| 150 | uint32_t Params[3]; /**< Block parameters to be issued along with the block code (command blocks only). */ | ||
| 151 | } ATTR_PACKED PIMA_Container_t; | ||
| 152 | |||
| 153 | /* Disable C linkage for C++ Compilers: */ | ||
| 154 | #if defined(__cplusplus) | ||
| 155 | } | ||
| 156 | #endif | ||
| 157 | |||
| 158 | #endif | ||
| 159 | |||
| 160 | /** @} */ | ||
| 161 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c new file mode 100644 index 000000000..08cbeb706 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c | |||
| @@ -0,0 +1,197 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_DEVICE) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_AUDIO_DRIVER | ||
| 37 | #define __INCLUDE_FROM_AUDIO_DEVICE_C | ||
| 38 | #include "AudioClassDevice.h" | ||
| 39 | |||
| 40 | void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 41 | { | ||
| 42 | if (!(Endpoint_IsSETUPReceived())) | ||
| 43 | return; | ||
| 44 | |||
| 45 | if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE) | ||
| 46 | { | ||
| 47 | uint8_t InterfaceIndex = (USB_ControlRequest.wIndex & 0xFF); | ||
| 48 | |||
| 49 | if ((InterfaceIndex != AudioInterfaceInfo->Config.ControlInterfaceNumber) && | ||
| 50 | (InterfaceIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)) | ||
| 51 | { | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | } | ||
| 55 | else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT) | ||
| 56 | { | ||
| 57 | uint8_t EndpointAddress = (USB_ControlRequest.wIndex & 0xFF); | ||
| 58 | |||
| 59 | if ((EndpointAddress != AudioInterfaceInfo->Config.DataINEndpoint.Address) && | ||
| 60 | (EndpointAddress != AudioInterfaceInfo->Config.DataOUTEndpoint.Address)) | ||
| 61 | { | ||
| 62 | return; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | switch (USB_ControlRequest.bRequest) | ||
| 67 | { | ||
| 68 | case REQ_SetInterface: | ||
| 69 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE)) | ||
| 70 | { | ||
| 71 | Endpoint_ClearSETUP(); | ||
| 72 | Endpoint_ClearStatusStage(); | ||
| 73 | |||
| 74 | AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0); | ||
| 75 | EVENT_Audio_Device_StreamStartStop(AudioInterfaceInfo); | ||
| 76 | } | ||
| 77 | |||
| 78 | break; | ||
| 79 | case AUDIO_REQ_GetStatus: | ||
| 80 | if ((USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) || | ||
| 81 | (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT))) | ||
| 82 | { | ||
| 83 | Endpoint_ClearSETUP(); | ||
| 84 | Endpoint_ClearStatusStage(); | ||
| 85 | } | ||
| 86 | |||
| 87 | break; | ||
| 88 | case AUDIO_REQ_SetCurrent: | ||
| 89 | case AUDIO_REQ_SetMinimum: | ||
| 90 | case AUDIO_REQ_SetMaximum: | ||
| 91 | case AUDIO_REQ_SetResolution: | ||
| 92 | if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT) | ||
| 93 | { | ||
| 94 | uint8_t EndpointProperty = USB_ControlRequest.bRequest; | ||
| 95 | uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex; | ||
| 96 | uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8); | ||
| 97 | |||
| 98 | if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress, | ||
| 99 | EndpointControl, NULL, NULL)) | ||
| 100 | { | ||
| 101 | uint16_t ValueLength = USB_ControlRequest.wLength; | ||
| 102 | uint8_t Value[ValueLength]; | ||
| 103 | |||
| 104 | Endpoint_ClearSETUP(); | ||
| 105 | Endpoint_Read_Control_Stream_LE(Value, ValueLength); | ||
| 106 | Endpoint_ClearIN(); | ||
| 107 | |||
| 108 | CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress, | ||
| 109 | EndpointControl, &ValueLength, Value); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE) | ||
| 113 | { | ||
| 114 | uint8_t Property = USB_ControlRequest.bRequest; | ||
| 115 | uint8_t Entity = (USB_ControlRequest.wIndex >> 8); | ||
| 116 | uint16_t Parameter = USB_ControlRequest.wValue; | ||
| 117 | |||
| 118 | if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity, | ||
| 119 | Parameter, NULL, NULL)) | ||
| 120 | { | ||
| 121 | uint16_t ValueLength = USB_ControlRequest.wLength; | ||
| 122 | uint8_t Value[ValueLength]; | ||
| 123 | |||
| 124 | Endpoint_ClearSETUP(); | ||
| 125 | Endpoint_Read_Control_Stream_LE(Value, ValueLength); | ||
| 126 | Endpoint_ClearIN(); | ||
| 127 | |||
| 128 | CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity, | ||
| 129 | Parameter, &ValueLength, Value); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | break; | ||
| 134 | case AUDIO_REQ_GetCurrent: | ||
| 135 | case AUDIO_REQ_GetMinimum: | ||
| 136 | case AUDIO_REQ_GetMaximum: | ||
| 137 | case AUDIO_REQ_GetResolution: | ||
| 138 | if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT) | ||
| 139 | { | ||
| 140 | uint8_t EndpointProperty = USB_ControlRequest.bRequest; | ||
| 141 | uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex; | ||
| 142 | uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8); | ||
| 143 | uint16_t ValueLength = USB_ControlRequest.wLength; | ||
| 144 | uint8_t Value[ValueLength]; | ||
| 145 | |||
| 146 | if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress, | ||
| 147 | EndpointControl, &ValueLength, Value)) | ||
| 148 | { | ||
| 149 | Endpoint_ClearSETUP(); | ||
| 150 | Endpoint_Write_Control_Stream_LE(Value, ValueLength); | ||
| 151 | Endpoint_ClearOUT(); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE) | ||
| 155 | { | ||
| 156 | uint8_t Property = USB_ControlRequest.bRequest; | ||
| 157 | uint8_t Entity = (USB_ControlRequest.wIndex >> 8); | ||
| 158 | uint16_t Parameter = USB_ControlRequest.wValue; | ||
| 159 | uint16_t ValueLength = USB_ControlRequest.wLength; | ||
| 160 | uint8_t Value[ValueLength]; | ||
| 161 | |||
| 162 | if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity, | ||
| 163 | Parameter, &ValueLength, Value)) | ||
| 164 | { | ||
| 165 | Endpoint_ClearSETUP(); | ||
| 166 | Endpoint_Write_Control_Stream_LE(Value, ValueLength); | ||
| 167 | Endpoint_ClearOUT(); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | break; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 176 | { | ||
| 177 | memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State)); | ||
| 178 | |||
| 179 | AudioInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_ISOCHRONOUS; | ||
| 180 | AudioInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_ISOCHRONOUS; | ||
| 181 | |||
| 182 | if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataINEndpoint, 1))) | ||
| 183 | return false; | ||
| 184 | |||
| 185 | if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataOUTEndpoint, 1))) | ||
| 186 | return false; | ||
| 187 | |||
| 188 | return true; | ||
| 189 | } | ||
| 190 | |||
| 191 | void Audio_Device_Event_Stub(void) | ||
| 192 | { | ||
| 193 | |||
| 194 | } | ||
| 195 | |||
| 196 | #endif | ||
| 197 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h new file mode 100644 index 000000000..ca63511b2 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h | |||
| @@ -0,0 +1,396 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Device mode driver for the library USB Audio 1.0 Class driver. | ||
| 33 | * | ||
| 34 | * Device mode driver for the library USB Audio 1.0 Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassAudio | ||
| 41 | * \defgroup Group_USBClassAudioDevice Audio 1.0 Class Device Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassAudioDevice_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassAudioDevice_ModDescription Module Description | ||
| 48 | * Device Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef _AUDIO_CLASS_DEVICE_H_ | ||
| 54 | #define _AUDIO_CLASS_DEVICE_H_ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/AudioClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_AUDIO_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Defines: */ | ||
| 72 | /** \brief Audio Class Device Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made for each Audio interface | ||
| 75 | * within the user application, and passed to each of the Audio class driver functions as the | ||
| 76 | * \c AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information. | ||
| 77 | */ | ||
| 78 | typedef struct | ||
| 79 | { | ||
| 80 | struct | ||
| 81 | { | ||
| 82 | uint8_t ControlInterfaceNumber; /**< Index of the Audio Control interface within the device this | ||
| 83 | * structure controls. | ||
| 84 | */ | ||
| 85 | uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this | ||
| 86 | * structure controls. | ||
| 87 | */ | ||
| 88 | |||
| 89 | USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ | ||
| 90 | USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ | ||
| 91 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 92 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 93 | */ | ||
| 94 | struct | ||
| 95 | { | ||
| 96 | bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints | ||
| 97 | * of the Audio Streaming interface. | ||
| 98 | */ | ||
| 99 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 100 | * are reset to their defaults when the interface is enumerated. | ||
| 101 | */ | ||
| 102 | } USB_ClassInfo_Audio_Device_t; | ||
| 103 | |||
| 104 | /* Function Prototypes: */ | ||
| 105 | /** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library | ||
| 106 | * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the | ||
| 107 | * given Audio interface is selected. | ||
| 108 | * | ||
| 109 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 110 | * | ||
| 111 | * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. | ||
| 112 | */ | ||
| 113 | bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 114 | |||
| 115 | /** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be | ||
| 116 | * linked to the library \ref EVENT_USB_Device_ControlRequest() event. | ||
| 117 | * | ||
| 118 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 119 | */ | ||
| 120 | void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 121 | |||
| 122 | /** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented | ||
| 123 | * in the user application to handle property manipulations on streaming audio endpoints. | ||
| 124 | * | ||
| 125 | * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for | ||
| 126 | * the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations | ||
| 127 | * to indicate the size of the retrieved data. | ||
| 128 | * | ||
| 129 | * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value | ||
| 130 | * of the \c DataLength parameter. | ||
| 131 | * | ||
| 132 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 133 | * \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t. | ||
| 134 | * \param[in] EndpointAddress Address of the streaming endpoint whose property is being referenced. | ||
| 135 | * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t. | ||
| 136 | * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum | ||
| 137 | * length of the retrieved data. When NULL, the function should return whether the given property | ||
| 138 | * and parameter is valid for the requested endpoint without reading or modifying the Data buffer. | ||
| 139 | * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where | ||
| 140 | * the retrieved data is to be stored for GET operations. | ||
| 141 | * | ||
| 142 | * \return Boolean \c true if the property GET/SET was successful, \c false otherwise | ||
| 143 | */ | ||
| 144 | bool CALLBACK_Audio_Device_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 145 | const uint8_t EndpointProperty, | ||
| 146 | const uint8_t EndpointAddress, | ||
| 147 | const uint8_t EndpointControl, | ||
| 148 | uint16_t* const DataLength, | ||
| 149 | uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1); | ||
| 150 | |||
| 151 | /** Audio class driver callback for the setting and retrieval of streaming interface properties. This callback must be implemented | ||
| 152 | * in the user application to handle property manipulations on streaming audio interfaces. | ||
| 153 | * | ||
| 154 | * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for | ||
| 155 | * the given entity and should return as fast as possible. When non-NULL, this value may be altered for GET operations | ||
| 156 | * to indicate the size of the retrieved data. | ||
| 157 | * | ||
| 158 | * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value | ||
| 159 | * of the \c DataLength parameter. | ||
| 160 | * | ||
| 161 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 162 | * \param[in] Property Property of the interface to get or set, a value from \ref Audio_ClassRequests_t. | ||
| 163 | * \param[in] EntityAddress Address of the audio entity whose property is being referenced. | ||
| 164 | * \param[in] Parameter Parameter of the entity to get or set, specific to each type of entity (see USB Audio specification). | ||
| 165 | * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum | ||
| 166 | * length of the retrieved data. When NULL, the function should return whether the given property | ||
| 167 | * and parameter is valid for the requested endpoint without reading or modifying the Data buffer. | ||
| 168 | * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where | ||
| 169 | * the retrieved data is to be stored for GET operations. | ||
| 170 | * | ||
| 171 | * \return Boolean \c true if the property GET/SET was successful, \c false otherwise | ||
| 172 | */ | ||
| 173 | bool CALLBACK_Audio_Device_GetSetInterfaceProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 174 | const uint8_t Property, | ||
| 175 | const uint8_t EntityAddress, | ||
| 176 | const uint16_t Parameter, | ||
| 177 | uint16_t* const DataLength, | ||
| 178 | uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1); | ||
| 179 | |||
| 180 | /** Audio class driver event for an Audio Stream start/stop change. This event fires each time the device receives a stream enable or | ||
| 181 | * disable control request from the host, to start and stop the audio stream. The current state of the stream can be determined by the | ||
| 182 | * State.InterfaceEnabled value inside the Audio interface structure passed as a parameter. | ||
| 183 | * | ||
| 184 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 185 | */ | ||
| 186 | void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo); | ||
| 187 | |||
| 188 | /* Inline Functions: */ | ||
| 189 | /** General management task for a given Audio class interface, required for the correct operation of the interface. This should | ||
| 190 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 191 | * | ||
| 192 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 193 | */ | ||
| 194 | static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 195 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 196 | static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 197 | { | ||
| 198 | (void)AudioInterfaceInfo; | ||
| 199 | } | ||
| 200 | |||
| 201 | /** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming | ||
| 202 | * OUT endpoint ready for reading. | ||
| 203 | * | ||
| 204 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 205 | * the call will fail. | ||
| 206 | * | ||
| 207 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 208 | * | ||
| 209 | * \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise. | ||
| 210 | */ | ||
| 211 | static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 212 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 213 | static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 214 | { | ||
| 215 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled)) | ||
| 216 | return false; | ||
| 217 | |||
| 218 | Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 219 | return Endpoint_IsOUTReceived(); | ||
| 220 | } | ||
| 221 | |||
| 222 | /** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects | ||
| 223 | * the streaming IN endpoint ready for writing. | ||
| 224 | * | ||
| 225 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 226 | * the call will fail. | ||
| 227 | * | ||
| 228 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 229 | * | ||
| 230 | * \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise. | ||
| 231 | */ | ||
| 232 | static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 233 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 234 | static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 235 | { | ||
| 236 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled)) | ||
| 237 | return false; | ||
| 238 | |||
| 239 | Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 240 | return Endpoint_IsINReady(); | ||
| 241 | } | ||
| 242 | |||
| 243 | /** Reads the next 8-bit audio sample from the current audio interface. | ||
| 244 | * | ||
| 245 | * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure | ||
| 246 | * that the correct endpoint is selected and ready for data. | ||
| 247 | * | ||
| 248 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 249 | * | ||
| 250 | * \return Signed 8-bit audio sample from the audio interface. | ||
| 251 | */ | ||
| 252 | static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 253 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 254 | static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 255 | { | ||
| 256 | int8_t Sample; | ||
| 257 | |||
| 258 | (void)AudioInterfaceInfo; | ||
| 259 | |||
| 260 | Sample = Endpoint_Read_8(); | ||
| 261 | |||
| 262 | if (!(Endpoint_BytesInEndpoint())) | ||
| 263 | Endpoint_ClearOUT(); | ||
| 264 | |||
| 265 | return Sample; | ||
| 266 | } | ||
| 267 | |||
| 268 | /** Reads the next 16-bit audio sample from the current audio interface. | ||
| 269 | * | ||
| 270 | * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure | ||
| 271 | * that the correct endpoint is selected and ready for data. | ||
| 272 | * | ||
| 273 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 274 | * | ||
| 275 | * \return Signed 16-bit audio sample from the audio interface. | ||
| 276 | */ | ||
| 277 | static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 278 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 279 | static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 280 | { | ||
| 281 | int16_t Sample; | ||
| 282 | |||
| 283 | (void)AudioInterfaceInfo; | ||
| 284 | |||
| 285 | Sample = (int16_t)Endpoint_Read_16_LE(); | ||
| 286 | |||
| 287 | if (!(Endpoint_BytesInEndpoint())) | ||
| 288 | Endpoint_ClearOUT(); | ||
| 289 | |||
| 290 | return Sample; | ||
| 291 | } | ||
| 292 | |||
| 293 | /** Reads the next 24-bit audio sample from the current audio interface. | ||
| 294 | * | ||
| 295 | * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure | ||
| 296 | * that the correct endpoint is selected and ready for data. | ||
| 297 | * | ||
| 298 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 299 | * | ||
| 300 | * \return Signed 24-bit audio sample from the audio interface. | ||
| 301 | */ | ||
| 302 | static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 303 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 304 | static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 305 | { | ||
| 306 | int32_t Sample; | ||
| 307 | |||
| 308 | (void)AudioInterfaceInfo; | ||
| 309 | |||
| 310 | Sample = (((uint32_t)Endpoint_Read_8() << 16) | Endpoint_Read_16_LE()); | ||
| 311 | |||
| 312 | if (!(Endpoint_BytesInEndpoint())) | ||
| 313 | Endpoint_ClearOUT(); | ||
| 314 | |||
| 315 | return Sample; | ||
| 316 | } | ||
| 317 | |||
| 318 | /** Writes the next 8-bit audio sample to the current audio interface. | ||
| 319 | * | ||
| 320 | * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to | ||
| 321 | * ensure that the correct endpoint is selected and ready for data. | ||
| 322 | * | ||
| 323 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 324 | * \param[in] Sample Signed 8-bit audio sample. | ||
| 325 | */ | ||
| 326 | static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 327 | const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 328 | static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 329 | const int8_t Sample) | ||
| 330 | { | ||
| 331 | Endpoint_Write_8(Sample); | ||
| 332 | |||
| 333 | if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size) | ||
| 334 | Endpoint_ClearIN(); | ||
| 335 | } | ||
| 336 | |||
| 337 | /** Writes the next 16-bit audio sample to the current audio interface. | ||
| 338 | * | ||
| 339 | * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to | ||
| 340 | * ensure that the correct endpoint is selected and ready for data. | ||
| 341 | * | ||
| 342 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 343 | * \param[in] Sample Signed 16-bit audio sample. | ||
| 344 | */ | ||
| 345 | static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 346 | const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 347 | static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 348 | const int16_t Sample) | ||
| 349 | { | ||
| 350 | Endpoint_Write_16_LE(Sample); | ||
| 351 | |||
| 352 | if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size) | ||
| 353 | Endpoint_ClearIN(); | ||
| 354 | } | ||
| 355 | |||
| 356 | /** Writes the next 24-bit audio sample to the current audio interface. | ||
| 357 | * | ||
| 358 | * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to | ||
| 359 | * ensure that the correct endpoint is selected and ready for data. | ||
| 360 | * | ||
| 361 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 362 | * \param[in] Sample Signed 24-bit audio sample. | ||
| 363 | */ | ||
| 364 | static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 365 | const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 366 | static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, | ||
| 367 | const int32_t Sample) | ||
| 368 | { | ||
| 369 | Endpoint_Write_16_LE(Sample); | ||
| 370 | Endpoint_Write_8(Sample >> 16); | ||
| 371 | |||
| 372 | if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size) | ||
| 373 | Endpoint_ClearIN(); | ||
| 374 | } | ||
| 375 | |||
| 376 | /* Private Interface - For use in library only: */ | ||
| 377 | #if !defined(__DOXYGEN__) | ||
| 378 | /* Function Prototypes: */ | ||
| 379 | #if defined(__INCLUDE_FROM_AUDIO_DEVICE_C) | ||
| 380 | void Audio_Device_Event_Stub(void) ATTR_CONST; | ||
| 381 | |||
| 382 | void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) | ||
| 383 | ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(Audio_Device_Event_Stub); | ||
| 384 | #endif | ||
| 385 | |||
| 386 | #endif | ||
| 387 | |||
| 388 | /* Disable C linkage for C++ Compilers: */ | ||
| 389 | #if defined(__cplusplus) | ||
| 390 | } | ||
| 391 | #endif | ||
| 392 | |||
| 393 | #endif | ||
| 394 | |||
| 395 | /** @} */ | ||
| 396 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c new file mode 100644 index 000000000..867548c00 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c | |||
| @@ -0,0 +1,362 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_DEVICE) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_CDC_DRIVER | ||
| 37 | #define __INCLUDE_FROM_CDC_DEVICE_C | ||
| 38 | #include "CDCClassDevice.h" | ||
| 39 | |||
| 40 | void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 41 | { | ||
| 42 | if (!(Endpoint_IsSETUPReceived())) | ||
| 43 | return; | ||
| 44 | |||
| 45 | if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) | ||
| 46 | return; | ||
| 47 | |||
| 48 | switch (USB_ControlRequest.bRequest) | ||
| 49 | { | ||
| 50 | case CDC_REQ_GetLineEncoding: | ||
| 51 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 52 | { | ||
| 53 | Endpoint_ClearSETUP(); | ||
| 54 | |||
| 55 | while (!(Endpoint_IsINReady())); | ||
| 56 | |||
| 57 | Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); | ||
| 58 | Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat); | ||
| 59 | Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType); | ||
| 60 | Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits); | ||
| 61 | |||
| 62 | Endpoint_ClearIN(); | ||
| 63 | Endpoint_ClearStatusStage(); | ||
| 64 | } | ||
| 65 | |||
| 66 | break; | ||
| 67 | case CDC_REQ_SetLineEncoding: | ||
| 68 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 69 | { | ||
| 70 | Endpoint_ClearSETUP(); | ||
| 71 | |||
| 72 | while (!(Endpoint_IsOUTReceived())) | ||
| 73 | { | ||
| 74 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
| 75 | return; | ||
| 76 | } | ||
| 77 | |||
| 78 | CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE(); | ||
| 79 | CDCInterfaceInfo->State.LineEncoding.CharFormat = Endpoint_Read_8(); | ||
| 80 | CDCInterfaceInfo->State.LineEncoding.ParityType = Endpoint_Read_8(); | ||
| 81 | CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8(); | ||
| 82 | |||
| 83 | Endpoint_ClearOUT(); | ||
| 84 | Endpoint_ClearStatusStage(); | ||
| 85 | |||
| 86 | EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); | ||
| 87 | } | ||
| 88 | |||
| 89 | break; | ||
| 90 | case CDC_REQ_SetControlLineState: | ||
| 91 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 92 | { | ||
| 93 | Endpoint_ClearSETUP(); | ||
| 94 | Endpoint_ClearStatusStage(); | ||
| 95 | |||
| 96 | CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; | ||
| 97 | |||
| 98 | EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); | ||
| 99 | } | ||
| 100 | |||
| 101 | break; | ||
| 102 | case CDC_REQ_SendBreak: | ||
| 103 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 104 | { | ||
| 105 | Endpoint_ClearSETUP(); | ||
| 106 | Endpoint_ClearStatusStage(); | ||
| 107 | |||
| 108 | EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); | ||
| 109 | } | ||
| 110 | |||
| 111 | break; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 116 | { | ||
| 117 | memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State)); | ||
| 118 | |||
| 119 | CDCInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; | ||
| 120 | CDCInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; | ||
| 121 | CDCInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT; | ||
| 122 | |||
| 123 | if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataINEndpoint, 1))) | ||
| 124 | return false; | ||
| 125 | |||
| 126 | if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataOUTEndpoint, 1))) | ||
| 127 | return false; | ||
| 128 | |||
| 129 | if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.NotificationEndpoint, 1))) | ||
| 130 | return false; | ||
| 131 | |||
| 132 | return true; | ||
| 133 | } | ||
| 134 | |||
| 135 | void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 136 | { | ||
| 137 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 138 | return; | ||
| 139 | |||
| 140 | #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) | ||
| 141 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 142 | |||
| 143 | if (Endpoint_IsINReady()) | ||
| 144 | CDC_Device_Flush(CDCInterfaceInfo); | ||
| 145 | #endif | ||
| 146 | } | ||
| 147 | |||
| 148 | uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 149 | const char* const String) | ||
| 150 | { | ||
| 151 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 152 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 153 | |||
| 154 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 155 | return Endpoint_Write_Stream_LE(String, strlen(String), NULL); | ||
| 156 | } | ||
| 157 | |||
| 158 | uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 159 | const char* const String) | ||
| 160 | { | ||
| 161 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 162 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 163 | |||
| 164 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 165 | return Endpoint_Write_PStream_LE(String, strlen_P(String), NULL); | ||
| 166 | } | ||
| 167 | |||
| 168 | uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 169 | const void* const Buffer, | ||
| 170 | const uint16_t Length) | ||
| 171 | { | ||
| 172 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 173 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 174 | |||
| 175 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 176 | return Endpoint_Write_Stream_LE(Buffer, Length, NULL); | ||
| 177 | } | ||
| 178 | |||
| 179 | uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 180 | const void* const Buffer, | ||
| 181 | const uint16_t Length) | ||
| 182 | { | ||
| 183 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 184 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 185 | |||
| 186 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 187 | return Endpoint_Write_PStream_LE(Buffer, Length, NULL); | ||
| 188 | } | ||
| 189 | |||
| 190 | uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 191 | const uint8_t Data) | ||
| 192 | { | ||
| 193 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 194 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 195 | |||
| 196 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 197 | |||
| 198 | if (!(Endpoint_IsReadWriteAllowed())) | ||
| 199 | { | ||
| 200 | Endpoint_ClearIN(); | ||
| 201 | |||
| 202 | uint8_t ErrorCode; | ||
| 203 | |||
| 204 | if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) | ||
| 205 | return ErrorCode; | ||
| 206 | } | ||
| 207 | |||
| 208 | Endpoint_Write_8(Data); | ||
| 209 | return ENDPOINT_READYWAIT_NoError; | ||
| 210 | } | ||
| 211 | |||
| 212 | uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 213 | { | ||
| 214 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 215 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 216 | |||
| 217 | uint8_t ErrorCode; | ||
| 218 | |||
| 219 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 220 | |||
| 221 | if (!(Endpoint_BytesInEndpoint())) | ||
| 222 | return ENDPOINT_READYWAIT_NoError; | ||
| 223 | |||
| 224 | bool BankFull = !(Endpoint_IsReadWriteAllowed()); | ||
| 225 | |||
| 226 | Endpoint_ClearIN(); | ||
| 227 | |||
| 228 | if (BankFull) | ||
| 229 | { | ||
| 230 | if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) | ||
| 231 | return ErrorCode; | ||
| 232 | |||
| 233 | Endpoint_ClearIN(); | ||
| 234 | } | ||
| 235 | |||
| 236 | return ENDPOINT_READYWAIT_NoError; | ||
| 237 | } | ||
| 238 | |||
| 239 | uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 240 | { | ||
| 241 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 242 | return 0; | ||
| 243 | |||
| 244 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 245 | |||
| 246 | if (Endpoint_IsOUTReceived()) | ||
| 247 | { | ||
| 248 | if (!(Endpoint_BytesInEndpoint())) | ||
| 249 | { | ||
| 250 | Endpoint_ClearOUT(); | ||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | else | ||
| 254 | { | ||
| 255 | return Endpoint_BytesInEndpoint(); | ||
| 256 | } | ||
| 257 | } | ||
| 258 | else | ||
| 259 | { | ||
| 260 | return 0; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 265 | { | ||
| 266 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 267 | return -1; | ||
| 268 | |||
| 269 | int16_t ReceivedByte = -1; | ||
| 270 | |||
| 271 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 272 | |||
| 273 | if (Endpoint_IsOUTReceived()) | ||
| 274 | { | ||
| 275 | if (Endpoint_BytesInEndpoint()) | ||
| 276 | ReceivedByte = Endpoint_Read_8(); | ||
| 277 | |||
| 278 | if (!(Endpoint_BytesInEndpoint())) | ||
| 279 | Endpoint_ClearOUT(); | ||
| 280 | } | ||
| 281 | |||
| 282 | return ReceivedByte; | ||
| 283 | } | ||
| 284 | |||
| 285 | void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 286 | { | ||
| 287 | if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) | ||
| 288 | return; | ||
| 289 | |||
| 290 | Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpoint.Address); | ||
| 291 | |||
| 292 | USB_Request_Header_t Notification = (USB_Request_Header_t) | ||
| 293 | { | ||
| 294 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 295 | .bRequest = CDC_NOTIF_SerialState, | ||
| 296 | .wValue = CPU_TO_LE16(0), | ||
| 297 | .wIndex = CPU_TO_LE16(0), | ||
| 298 | .wLength = CPU_TO_LE16(sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost)), | ||
| 299 | }; | ||
| 300 | |||
| 301 | Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL); | ||
| 302 | Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost, | ||
| 303 | sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost), | ||
| 304 | NULL); | ||
| 305 | Endpoint_ClearIN(); | ||
| 306 | } | ||
| 307 | |||
| 308 | #if defined(FDEV_SETUP_STREAM) | ||
| 309 | void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 310 | FILE* const Stream) | ||
| 311 | { | ||
| 312 | *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW); | ||
| 313 | fdev_set_udata(Stream, CDCInterfaceInfo); | ||
| 314 | } | ||
| 315 | |||
| 316 | void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 317 | FILE* const Stream) | ||
| 318 | { | ||
| 319 | *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW); | ||
| 320 | fdev_set_udata(Stream, CDCInterfaceInfo); | ||
| 321 | } | ||
| 322 | |||
| 323 | static int CDC_Device_putchar(char c, | ||
| 324 | FILE* Stream) | ||
| 325 | { | ||
| 326 | return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int CDC_Device_getchar(FILE* Stream) | ||
| 330 | { | ||
| 331 | int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream)); | ||
| 332 | |||
| 333 | if (ReceivedByte < 0) | ||
| 334 | return _FDEV_EOF; | ||
| 335 | |||
| 336 | return ReceivedByte; | ||
| 337 | } | ||
| 338 | |||
| 339 | static int CDC_Device_getchar_Blocking(FILE* Stream) | ||
| 340 | { | ||
| 341 | int16_t ReceivedByte; | ||
| 342 | |||
| 343 | while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0) | ||
| 344 | { | ||
| 345 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
| 346 | return _FDEV_EOF; | ||
| 347 | |||
| 348 | CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream)); | ||
| 349 | USB_USBTask(); | ||
| 350 | } | ||
| 351 | |||
| 352 | return ReceivedByte; | ||
| 353 | } | ||
| 354 | #endif | ||
| 355 | |||
| 356 | void CDC_Device_Event_Stub(void) | ||
| 357 | { | ||
| 358 | |||
| 359 | } | ||
| 360 | |||
| 361 | #endif | ||
| 362 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h new file mode 100644 index 000000000..9d5c4e5a0 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h | |||
| @@ -0,0 +1,386 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Device mode driver for the library USB CDC Class driver. | ||
| 33 | * | ||
| 34 | * Device mode driver for the library USB CDC Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassCDC | ||
| 41 | * \defgroup Group_USBClassCDCDevice CDC Class Device Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassCDCDevice_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassCDCDevice_ModDescription Module Description | ||
| 48 | * Device Mode USB Class driver framework interface, for the CDC USB Class driver. | ||
| 49 | * | ||
| 50 | * \note There are several major drawbacks to the CDC-ACM standard USB class, however | ||
| 51 | * it is very standardized and thus usually available as a built-in driver on | ||
| 52 | * most platforms, and so is a better choice than a proprietary serial class. | ||
| 53 | * | ||
| 54 | * One major issue with CDC-ACM is that it requires two Interface descriptors, | ||
| 55 | * which will upset most hosts when part of a multi-function "Composite" USB | ||
| 56 | * device. This is because each interface will be loaded into a separate driver | ||
| 57 | * instance, causing the two interfaces be become unlinked. To prevent this, you | ||
| 58 | * should use the "Interface Association Descriptor" addendum to the USB 2.0 standard | ||
| 59 | * which is available on most OSes when creating Composite devices. | ||
| 60 | * | ||
| 61 | * Another major oversight is that there is no mechanism for the host to notify the | ||
| 62 | * device that there is a data sink on the host side ready to accept data. This | ||
| 63 | * means that the device may try to send data while the host isn't listening, causing | ||
| 64 | * lengthy blocking timeouts in the transmission routines. It is thus highly recommended | ||
| 65 | * that the virtual serial line DTR (Data Terminal Ready) signal be used where possible | ||
| 66 | * to determine if a host application is ready for data. | ||
| 67 | * | ||
| 68 | * @{ | ||
| 69 | */ | ||
| 70 | |||
| 71 | #ifndef _CDC_CLASS_DEVICE_H_ | ||
| 72 | #define _CDC_CLASS_DEVICE_H_ | ||
| 73 | |||
| 74 | /* Includes: */ | ||
| 75 | #include "../../USB.h" | ||
| 76 | #include "../Common/CDCClassCommon.h" | ||
| 77 | |||
| 78 | #include <stdio.h> | ||
| 79 | |||
| 80 | /* Enable C linkage for C++ Compilers: */ | ||
| 81 | #if defined(__cplusplus) | ||
| 82 | extern "C" { | ||
| 83 | #endif | ||
| 84 | |||
| 85 | /* Preprocessor Checks: */ | ||
| 86 | #if !defined(__INCLUDE_FROM_CDC_DRIVER) | ||
| 87 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 88 | #endif | ||
| 89 | |||
| 90 | /* Public Interface - May be used in end-application: */ | ||
| 91 | /* Type Defines: */ | ||
| 92 | /** \brief CDC Class Device Mode Configuration and State Structure. | ||
| 93 | * | ||
| 94 | * Class state structure. An instance of this structure should be made for each CDC interface | ||
| 95 | * within the user application, and passed to each of the CDC class driver functions as the | ||
| 96 | * CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information. | ||
| 97 | */ | ||
| 98 | typedef struct | ||
| 99 | { | ||
| 100 | struct | ||
| 101 | { | ||
| 102 | uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */ | ||
| 103 | |||
| 104 | USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ | ||
| 105 | USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ | ||
| 106 | USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */ | ||
| 107 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 108 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 109 | */ | ||
| 110 | struct | ||
| 111 | { | ||
| 112 | struct | ||
| 113 | { | ||
| 114 | uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_* | ||
| 115 | * masks. This value is updated each time \ref CDC_Device_USBTask() is called. | ||
| 116 | */ | ||
| 117 | uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_* | ||
| 118 | * masks - to notify the host of changes to these values, call the | ||
| 119 | * \ref CDC_Device_SendControlLineStateChange() function. | ||
| 120 | */ | ||
| 121 | } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */ | ||
| 122 | |||
| 123 | CDC_LineEncoding_t LineEncoding; /**< Line encoding used in the virtual serial port, for the device's information. | ||
| 124 | * This is generally only used if the virtual serial port data is to be | ||
| 125 | * reconstructed on a physical UART. | ||
| 126 | */ | ||
| 127 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 128 | * are reset to their defaults when the interface is enumerated. | ||
| 129 | */ | ||
| 130 | } USB_ClassInfo_CDC_Device_t; | ||
| 131 | |||
| 132 | /* Function Prototypes: */ | ||
| 133 | /** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library | ||
| 134 | * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing | ||
| 135 | * the given CDC interface is selected. | ||
| 136 | * | ||
| 137 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 138 | * | ||
| 139 | * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. | ||
| 140 | */ | ||
| 141 | bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 142 | |||
| 143 | /** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be | ||
| 144 | * linked to the library \ref EVENT_USB_Device_ControlRequest() event. | ||
| 145 | * | ||
| 146 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 147 | */ | ||
| 148 | void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 149 | |||
| 150 | /** General management task for a given CDC class interface, required for the correct operation of the interface. This should | ||
| 151 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 152 | * | ||
| 153 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 154 | */ | ||
| 155 | void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 156 | |||
| 157 | /** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a | ||
| 158 | * line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the | ||
| 159 | * user program by declaring a handler function with the same name and parameters listed here. The new line encoding | ||
| 160 | * settings are available in the \c LineEncoding structure inside the CDC interface structure passed as a parameter. | ||
| 161 | * | ||
| 162 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 163 | */ | ||
| 164 | void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 165 | |||
| 166 | /** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a | ||
| 167 | * control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the | ||
| 168 | * user program by declaring a handler function with the same name and parameters listed here. The new control line states | ||
| 169 | * are available in the \c ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as | ||
| 170 | * a mask of \c CDC_CONTROL_LINE_OUT_* masks. | ||
| 171 | * | ||
| 172 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 173 | */ | ||
| 174 | void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 175 | |||
| 176 | /** CDC class driver event for a send break request sent to the device from the host. This is generally used to separate | ||
| 177 | * data or to indicate a special condition to the receiving device. | ||
| 178 | * | ||
| 179 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 180 | * \param[in] Duration Duration of the break that has been sent by the host, in milliseconds. | ||
| 181 | */ | ||
| 182 | void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 183 | const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1); | ||
| 184 | |||
| 185 | /** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is | ||
| 186 | * called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank | ||
| 187 | * becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows | ||
| 188 | * for multiple bytes to be packed into a single endpoint packet, increasing data throughput. | ||
| 189 | * | ||
| 190 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 191 | * the call will fail. | ||
| 192 | * | ||
| 193 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 194 | * \param[in] Buffer Pointer to a buffer containing the data to send to the device. | ||
| 195 | * \param[in] Length Length of the data to send to the host. | ||
| 196 | * | ||
| 197 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 198 | */ | ||
| 199 | uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 200 | const void* const Buffer, | ||
| 201 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 202 | |||
| 203 | /** Sends a given data buffer from PROGMEM space to the attached USB host, if connected. If a host is not connected when the | ||
| 204 | * function is called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint | ||
| 205 | * bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows | ||
| 206 | * for multiple bytes to be packed into a single endpoint packet, increasing data throughput. | ||
| 207 | * | ||
| 208 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 209 | * the call will fail. | ||
| 210 | * | ||
| 211 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 212 | * \param[in] Buffer Pointer to a buffer containing the data to send to the device. | ||
| 213 | * \param[in] Length Length of the data to send to the host. | ||
| 214 | * | ||
| 215 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 216 | */ | ||
| 217 | uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 218 | const void* const Buffer, | ||
| 219 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 220 | |||
| 221 | /** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when | ||
| 222 | * the function is called, the string is discarded. Bytes will be queued for transmission to the host until either | ||
| 223 | * the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to | ||
| 224 | * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput. | ||
| 225 | * | ||
| 226 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 227 | * the call will fail. | ||
| 228 | * | ||
| 229 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 230 | * \param[in] String Pointer to the null terminated string to send to the host. | ||
| 231 | * | ||
| 232 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 233 | */ | ||
| 234 | uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 235 | const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 236 | |||
| 237 | /** Sends a given null terminated string from PROGMEM space to the attached USB host, if connected. If a host is not connected | ||
| 238 | * when the function is called, the string is discarded. Bytes will be queued for transmission to the host until either | ||
| 239 | * the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to | ||
| 240 | * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput. | ||
| 241 | * | ||
| 242 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 243 | * the call will fail. | ||
| 244 | * | ||
| 245 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 246 | * \param[in] String Pointer to the null terminated string to send to the host. | ||
| 247 | * | ||
| 248 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 249 | */ | ||
| 250 | uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 251 | const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 252 | |||
| 253 | /** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the | ||
| 254 | * byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the | ||
| 255 | * \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be | ||
| 256 | * packed into a single endpoint packet, increasing data throughput. | ||
| 257 | * | ||
| 258 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 259 | * the call will fail. | ||
| 260 | * | ||
| 261 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 262 | * \param[in] Data Byte of data to send to the host. | ||
| 263 | * | ||
| 264 | * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. | ||
| 265 | */ | ||
| 266 | uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 267 | const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); | ||
| 268 | |||
| 269 | /** Determines the number of bytes received by the CDC interface from the host, waiting to be read. This indicates the number | ||
| 270 | * of bytes in the OUT endpoint bank only, and thus the number of calls to \ref CDC_Device_ReceiveByte() which are guaranteed to | ||
| 271 | * succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint | ||
| 272 | * bank will not be released back to the USB controller until all bytes are read. | ||
| 273 | * | ||
| 274 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 275 | * the call will fail. | ||
| 276 | * | ||
| 277 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 278 | * | ||
| 279 | * \return Total number of buffered bytes received from the host. | ||
| 280 | */ | ||
| 281 | uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 282 | |||
| 283 | /** 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 | ||
| 284 | * returns a negative value. The \ref CDC_Device_BytesReceived() function may be queried in advance to determine how many | ||
| 285 | * bytes are currently buffered in the CDC interface's data receive endpoint bank, and thus how many repeated calls to this | ||
| 286 | * function which are guaranteed to succeed. | ||
| 287 | * | ||
| 288 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 289 | * the call will fail. | ||
| 290 | * | ||
| 291 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 292 | * | ||
| 293 | * \return Next received byte from the host, or a negative value if no data received. | ||
| 294 | */ | ||
| 295 | int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 296 | |||
| 297 | /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. | ||
| 298 | * | ||
| 299 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 300 | * the call will fail. | ||
| 301 | * | ||
| 302 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 303 | * | ||
| 304 | * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. | ||
| 305 | */ | ||
| 306 | uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 307 | |||
| 308 | /** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial | ||
| 309 | * control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist | ||
| 310 | * until they are cleared via a second notification. This should be called each time the CDC class driver's | ||
| 311 | * \c ControlLineStates.DeviceToHost value is updated to push the new states to the USB host. | ||
| 312 | * | ||
| 313 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 314 | * the call will fail. | ||
| 315 | * | ||
| 316 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 317 | */ | ||
| 318 | void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 319 | |||
| 320 | #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__) | ||
| 321 | /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular | ||
| 322 | * functions in the standard <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created | ||
| 323 | * stream is bidirectional and can be used for both input and output functions. | ||
| 324 | * | ||
| 325 | * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single | ||
| 326 | * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may | ||
| 327 | * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own | ||
| 328 | * line buffering. | ||
| 329 | * | ||
| 330 | * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions | ||
| 331 | * to the given CDC interface. | ||
| 332 | * \n\n | ||
| 333 | * | ||
| 334 | * \note This function is not available on all microcontroller architectures. | ||
| 335 | * | ||
| 336 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 337 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 338 | */ | ||
| 339 | void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 340 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 341 | |||
| 342 | /** Identical to \ref CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates | ||
| 343 | * the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications. | ||
| 344 | * | ||
| 345 | * \note This function is not available on all microcontroller architectures. | ||
| 346 | * | ||
| 347 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 348 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 349 | */ | ||
| 350 | void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 351 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 352 | #endif | ||
| 353 | |||
| 354 | /* Private Interface - For use in library only: */ | ||
| 355 | #if !defined(__DOXYGEN__) | ||
| 356 | /* Function Prototypes: */ | ||
| 357 | #if defined(__INCLUDE_FROM_CDC_DEVICE_C) | ||
| 358 | #if defined(FDEV_SETUP_STREAM) | ||
| 359 | static int CDC_Device_putchar(char c, | ||
| 360 | FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); | ||
| 361 | static int CDC_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 362 | static int CDC_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 363 | #endif | ||
| 364 | |||
| 365 | void CDC_Device_Event_Stub(void) ATTR_CONST; | ||
| 366 | |||
| 367 | void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 368 | ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub); | ||
| 369 | void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) | ||
| 370 | ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub); | ||
| 371 | void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, | ||
| 372 | const uint8_t Duration) ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) | ||
| 373 | ATTR_ALIAS(CDC_Device_Event_Stub); | ||
| 374 | #endif | ||
| 375 | |||
| 376 | #endif | ||
| 377 | |||
| 378 | /* Disable C linkage for C++ Compilers: */ | ||
| 379 | #if defined(__cplusplus) | ||
| 380 | } | ||
| 381 | #endif | ||
| 382 | |||
| 383 | #endif | ||
| 384 | |||
| 385 | /** @} */ | ||
| 386 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c new file mode 100644 index 000000000..a8a6e8b50 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c | |||
| @@ -0,0 +1,211 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_DEVICE) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_HID_DRIVER | ||
| 37 | #define __INCLUDE_FROM_HID_DEVICE_C | ||
| 38 | #include "HIDClassDevice.h" | ||
| 39 | |||
| 40 | void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) | ||
| 41 | { | ||
| 42 | if (!(Endpoint_IsSETUPReceived())) | ||
| 43 | return; | ||
| 44 | |||
| 45 | if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber) | ||
| 46 | return; | ||
| 47 | |||
| 48 | switch (USB_ControlRequest.bRequest) | ||
| 49 | { | ||
| 50 | case HID_REQ_GetReport: | ||
| 51 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 52 | { | ||
| 53 | uint16_t ReportSize = 0; | ||
| 54 | uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF); | ||
| 55 | uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1; | ||
| 56 | uint8_t ReportData[HIDInterfaceInfo->Config.PrevReportINBufferSize]; | ||
| 57 | |||
| 58 | memset(ReportData, 0, sizeof(ReportData)); | ||
| 59 | |||
| 60 | CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType, ReportData, &ReportSize); | ||
| 61 | |||
| 62 | if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL) | ||
| 63 | { | ||
| 64 | memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData, | ||
| 65 | HIDInterfaceInfo->Config.PrevReportINBufferSize); | ||
| 66 | } | ||
| 67 | |||
| 68 | Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); | ||
| 69 | |||
| 70 | Endpoint_ClearSETUP(); | ||
| 71 | |||
| 72 | if (ReportID) | ||
| 73 | Endpoint_Write_8(ReportID); | ||
| 74 | |||
| 75 | Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); | ||
| 76 | Endpoint_ClearOUT(); | ||
| 77 | } | ||
| 78 | |||
| 79 | break; | ||
| 80 | case HID_REQ_SetReport: | ||
| 81 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 82 | { | ||
| 83 | uint16_t ReportSize = USB_ControlRequest.wLength; | ||
| 84 | uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF); | ||
| 85 | uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1; | ||
| 86 | uint8_t ReportData[ReportSize]; | ||
| 87 | |||
| 88 | Endpoint_ClearSETUP(); | ||
| 89 | Endpoint_Read_Control_Stream_LE(ReportData, ReportSize); | ||
| 90 | Endpoint_ClearIN(); | ||
| 91 | |||
| 92 | CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType, | ||
| 93 | &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0)); | ||
| 94 | } | ||
| 95 | |||
| 96 | break; | ||
| 97 | case HID_REQ_GetProtocol: | ||
| 98 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 99 | { | ||
| 100 | Endpoint_ClearSETUP(); | ||
| 101 | while (!(Endpoint_IsINReady())); | ||
| 102 | Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol); | ||
| 103 | Endpoint_ClearIN(); | ||
| 104 | Endpoint_ClearStatusStage(); | ||
| 105 | } | ||
| 106 | |||
| 107 | break; | ||
| 108 | case HID_REQ_SetProtocol: | ||
| 109 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 110 | { | ||
| 111 | Endpoint_ClearSETUP(); | ||
| 112 | Endpoint_ClearStatusStage(); | ||
| 113 | |||
| 114 | HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00); | ||
| 115 | } | ||
| 116 | |||
| 117 | break; | ||
| 118 | case HID_REQ_SetIdle: | ||
| 119 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 120 | { | ||
| 121 | Endpoint_ClearSETUP(); | ||
| 122 | Endpoint_ClearStatusStage(); | ||
| 123 | |||
| 124 | HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6); | ||
| 125 | } | ||
| 126 | |||
| 127 | break; | ||
| 128 | case HID_REQ_GetIdle: | ||
| 129 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 130 | { | ||
| 131 | Endpoint_ClearSETUP(); | ||
| 132 | while (!(Endpoint_IsINReady())); | ||
| 133 | Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2); | ||
| 134 | Endpoint_ClearIN(); | ||
| 135 | Endpoint_ClearStatusStage(); | ||
| 136 | } | ||
| 137 | |||
| 138 | break; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) | ||
| 143 | { | ||
| 144 | memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State)); | ||
| 145 | HIDInterfaceInfo->State.UsingReportProtocol = true; | ||
| 146 | HIDInterfaceInfo->State.IdleCount = 500; | ||
| 147 | |||
| 148 | HIDInterfaceInfo->Config.ReportINEndpoint.Type = EP_TYPE_INTERRUPT; | ||
| 149 | |||
| 150 | if (!(Endpoint_ConfigureEndpointTable(&HIDInterfaceInfo->Config.ReportINEndpoint, 1))) | ||
| 151 | return false; | ||
| 152 | |||
| 153 | return true; | ||
| 154 | } | ||
| 155 | |||
| 156 | void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) | ||
| 157 | { | ||
| 158 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 159 | return; | ||
| 160 | |||
| 161 | if (HIDInterfaceInfo->State.PrevFrameNum == USB_Device_GetFrameNumber()) | ||
| 162 | { | ||
| 163 | #if defined(USB_DEVICE_OPT_LOWSPEED) | ||
| 164 | if (!(USB_Options & USB_DEVICE_OPT_LOWSPEED)) | ||
| 165 | return; | ||
| 166 | #else | ||
| 167 | return; | ||
| 168 | #endif | ||
| 169 | } | ||
| 170 | |||
| 171 | Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address); | ||
| 172 | |||
| 173 | if (Endpoint_IsReadWriteAllowed()) | ||
| 174 | { | ||
| 175 | uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize]; | ||
| 176 | uint8_t ReportID = 0; | ||
| 177 | uint16_t ReportINSize = 0; | ||
| 178 | |||
| 179 | memset(ReportINData, 0, sizeof(ReportINData)); | ||
| 180 | |||
| 181 | bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In, | ||
| 182 | ReportINData, &ReportINSize); | ||
| 183 | bool StatesChanged = false; | ||
| 184 | bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining)); | ||
| 185 | |||
| 186 | if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL) | ||
| 187 | { | ||
| 188 | StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0); | ||
| 189 | memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize); | ||
| 190 | } | ||
| 191 | |||
| 192 | if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed)) | ||
| 193 | { | ||
| 194 | HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount; | ||
| 195 | |||
| 196 | Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address); | ||
| 197 | |||
| 198 | if (ReportID) | ||
| 199 | Endpoint_Write_8(ReportID); | ||
| 200 | |||
| 201 | Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NULL); | ||
| 202 | |||
| 203 | Endpoint_ClearIN(); | ||
| 204 | } | ||
| 205 | |||
| 206 | HIDInterfaceInfo->State.PrevFrameNum = USB_Device_GetFrameNumber(); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | #endif | ||
| 211 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h new file mode 100644 index 000000000..ae628c87d --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h | |||
| @@ -0,0 +1,210 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Device mode driver for the library USB HID Class driver. | ||
| 33 | * | ||
| 34 | * Device mode driver for the library USB HID Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassHID | ||
| 41 | * \defgroup Group_USBClassHIDDevice HID Class Device Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassHIDDevice_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassHIDDevice_ModDescription Module Description | ||
| 48 | * Device Mode USB Class driver framework interface, for the HID USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef _HID_CLASS_DEVICE_H_ | ||
| 54 | #define _HID_CLASS_DEVICE_H_ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/HIDClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_HID_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Defines: */ | ||
| 72 | /** \brief HID Class Device Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made for each HID interface | ||
| 75 | * within the user application, and passed to each of the HID class driver functions as the | ||
| 76 | * \c HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information. | ||
| 77 | * | ||
| 78 | * \note Due to technical limitations, the HID device class driver does not utilize a separate OUT | ||
| 79 | * endpoint for host->device communications. Instead, the host->device data (if any) is sent to | ||
| 80 | * the device via the control endpoint. | ||
| 81 | */ | ||
| 82 | typedef struct | ||
| 83 | { | ||
| 84 | struct | ||
| 85 | { | ||
| 86 | uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device. */ | ||
| 87 | |||
| 88 | USB_Endpoint_Table_t ReportINEndpoint; /**< Data IN HID report endpoint configuration table. */ | ||
| 89 | |||
| 90 | void* PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be | ||
| 91 | * stored by the driver, for comparison purposes to detect report changes that | ||
| 92 | * must be sent immediately to the host. This should point to a buffer big enough | ||
| 93 | * to hold the largest HID input report sent from the HID interface. If this is set | ||
| 94 | * to \c NULL, it is up to the user to force transfers when needed in the | ||
| 95 | * \ref CALLBACK_HID_Device_CreateHIDReport() callback function. | ||
| 96 | * | ||
| 97 | * \note Due to the single buffer, the internal driver can only correctly compare | ||
| 98 | * subsequent reports with identical report IDs. In multiple report devices, | ||
| 99 | * this buffer should be set to \c NULL and the decision to send reports made | ||
| 100 | * by the user application instead. | ||
| 101 | */ | ||
| 102 | uint8_t PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a | ||
| 103 | * second buffer of the same size within the driver so that subsequent reports | ||
| 104 | * can be compared. If the user app is to determine when reports are to be sent | ||
| 105 | * exclusively (i.e. \c PrevReportINBuffer is \c NULL) this value must still be | ||
| 106 | * set to the size of the largest report the device can issue to the host. | ||
| 107 | */ | ||
| 108 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 109 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 110 | */ | ||
| 111 | struct | ||
| 112 | { | ||
| 113 | bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode. */ | ||
| 114 | uint16_t PrevFrameNum; /**< Frame number of the previous HID report packet opportunity. */ | ||
| 115 | uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host. */ | ||
| 116 | uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this | ||
| 117 | * should be decremented by the user application if non-zero each millisecond. */ | ||
| 118 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 119 | * are reset to their defaults when the interface is enumerated. | ||
| 120 | */ | ||
| 121 | } USB_ClassInfo_HID_Device_t; | ||
| 122 | |||
| 123 | /* Function Prototypes: */ | ||
| 124 | /** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library | ||
| 125 | * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration | ||
| 126 | * containing the given HID interface is selected. | ||
| 127 | * | ||
| 128 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. | ||
| 129 | * | ||
| 130 | * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. | ||
| 131 | */ | ||
| 132 | bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 133 | |||
| 134 | /** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be | ||
| 135 | * linked to the library \ref EVENT_USB_Device_ControlRequest() event. | ||
| 136 | * | ||
| 137 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. | ||
| 138 | */ | ||
| 139 | void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 140 | |||
| 141 | /** General management task for a given HID class interface, required for the correct operation of the interface. This should | ||
| 142 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 143 | * | ||
| 144 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. | ||
| 145 | */ | ||
| 146 | void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 147 | |||
| 148 | /** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either | ||
| 149 | * HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the | ||
| 150 | * user is responsible for the creation of the next HID input report to be sent to the host. | ||
| 151 | * | ||
| 152 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. | ||
| 153 | * \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero, | ||
| 154 | * this should be set to the report ID of the generated HID input report (if any). If multiple | ||
| 155 | * reports are not sent via the given HID interface, this parameter should be ignored. | ||
| 156 | * \param[in] ReportType Type of HID report to generate, either \ref HID_REPORT_ITEM_In or \ref HID_REPORT_ITEM_Feature. | ||
| 157 | * \param[out] ReportData Pointer to a buffer where the generated HID report should be stored. | ||
| 158 | * \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent. | ||
| 159 | * | ||
| 160 | * \return Boolean \c true to force the sending of the report even if it is identical to the previous report and still within | ||
| 161 | * the idle period (useful for devices which report relative movement), \c false otherwise. | ||
| 162 | */ | ||
| 163 | bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, | ||
| 164 | uint8_t* const ReportID, | ||
| 165 | const uint8_t ReportType, | ||
| 166 | void* ReportData, | ||
| 167 | uint16_t* const ReportSize) ATTR_NON_NULL_PTR_ARG(1) | ||
| 168 | ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5); | ||
| 169 | |||
| 170 | /** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to | ||
| 171 | * either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback | ||
| 172 | * the user is responsible for the processing of the received HID output report from the host. | ||
| 173 | * | ||
| 174 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. | ||
| 175 | * \param[in] ReportID Report ID of the received output report. If multiple reports are not received via the given HID | ||
| 176 | * interface, this parameter should be ignored. | ||
| 177 | * \param[in] ReportType Type of received HID report, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature. | ||
| 178 | * \param[in] ReportData Pointer to a buffer where the received HID report is stored. | ||
| 179 | * \param[in] ReportSize Size in bytes of the received report from the host. | ||
| 180 | */ | ||
| 181 | void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, | ||
| 182 | const uint8_t ReportID, | ||
| 183 | const uint8_t ReportType, | ||
| 184 | const void* ReportData, | ||
| 185 | const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(4); | ||
| 186 | |||
| 187 | /* Inline Functions: */ | ||
| 188 | /** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be | ||
| 189 | * decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended | ||
| 190 | * that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via | ||
| 191 | * \ref USB_Device_EnableSOFEvents(). | ||
| 192 | * | ||
| 193 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. | ||
| 194 | */ | ||
| 195 | static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_ALWAYS_INLINE ATTR_NON_NULL_PTR_ARG(1); | ||
| 196 | static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) | ||
| 197 | { | ||
| 198 | if (HIDInterfaceInfo->State.IdleMSRemaining) | ||
| 199 | HIDInterfaceInfo->State.IdleMSRemaining--; | ||
| 200 | } | ||
| 201 | |||
| 202 | /* Disable C linkage for C++ Compilers: */ | ||
| 203 | #if defined(__cplusplus) | ||
| 204 | } | ||
| 205 | #endif | ||
| 206 | |||
| 207 | #endif | ||
| 208 | |||
| 209 | /** @} */ | ||
| 210 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c new file mode 100644 index 000000000..a35c4082b --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_DEVICE) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_MIDI_DRIVER | ||
| 37 | #define __INCLUDE_FROM_MIDI_DEVICE_C | ||
| 38 | #include "MIDIClassDevice.h" | ||
| 39 | |||
| 40 | bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) | ||
| 41 | { | ||
| 42 | memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State)); | ||
| 43 | |||
| 44 | MIDIInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; | ||
| 45 | MIDIInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; | ||
| 46 | |||
| 47 | if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataINEndpoint, 1))) | ||
| 48 | return false; | ||
| 49 | |||
| 50 | if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataOUTEndpoint, 1))) | ||
| 51 | return false; | ||
| 52 | |||
| 53 | return true; | ||
| 54 | } | ||
| 55 | |||
| 56 | void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) | ||
| 57 | { | ||
| 58 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 59 | return; | ||
| 60 | |||
| 61 | #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) | ||
| 62 | Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 63 | |||
| 64 | if (Endpoint_IsINReady()) | ||
| 65 | MIDI_Device_Flush(MIDIInterfaceInfo); | ||
| 66 | #endif | ||
| 67 | } | ||
| 68 | |||
| 69 | uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, | ||
| 70 | const MIDI_EventPacket_t* const Event) | ||
| 71 | { | ||
| 72 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 73 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 74 | |||
| 75 | uint8_t ErrorCode; | ||
| 76 | |||
| 77 | Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 78 | |||
| 79 | if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != ENDPOINT_RWSTREAM_NoError) | ||
| 80 | return ErrorCode; | ||
| 81 | |||
| 82 | if (!(Endpoint_IsReadWriteAllowed())) | ||
| 83 | Endpoint_ClearIN(); | ||
| 84 | |||
| 85 | return ENDPOINT_RWSTREAM_NoError; | ||
| 86 | } | ||
| 87 | |||
| 88 | uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) | ||
| 89 | { | ||
| 90 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 91 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 92 | |||
| 93 | uint8_t ErrorCode; | ||
| 94 | |||
| 95 | Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 96 | |||
| 97 | if (Endpoint_BytesInEndpoint()) | ||
| 98 | { | ||
| 99 | Endpoint_ClearIN(); | ||
| 100 | |||
| 101 | if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) | ||
| 102 | return ErrorCode; | ||
| 103 | } | ||
| 104 | |||
| 105 | return ENDPOINT_READYWAIT_NoError; | ||
| 106 | } | ||
| 107 | |||
| 108 | bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, | ||
| 109 | MIDI_EventPacket_t* const Event) | ||
| 110 | { | ||
| 111 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 112 | return false; | ||
| 113 | |||
| 114 | Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 115 | |||
| 116 | if (!(Endpoint_IsOUTReceived())) | ||
| 117 | return false; | ||
| 118 | |||
| 119 | if (!(Endpoint_IsReadWriteAllowed())) | ||
| 120 | return false; | ||
| 121 | |||
| 122 | Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL); | ||
| 123 | |||
| 124 | if (!(Endpoint_IsReadWriteAllowed())) | ||
| 125 | Endpoint_ClearOUT(); | ||
| 126 | |||
| 127 | return true; | ||
| 128 | } | ||
| 129 | |||
| 130 | #endif | ||
| 131 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h new file mode 100644 index 000000000..ee2efd7c1 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Device mode driver for the library USB MIDI Class driver. | ||
| 33 | * | ||
| 34 | * Device mode driver for the library USB MIDI Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassMIDI | ||
| 41 | * \defgroup Group_USBClassMIDIDevice MIDI Class Device Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassMIDIDevice_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassMIDIDevice_ModDescription Module Description | ||
| 48 | * Device Mode USB Class driver framework interface, for the MIDI USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef _MIDI_CLASS_DEVICE_H_ | ||
| 54 | #define _MIDI_CLASS_DEVICE_H_ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/MIDIClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_MIDI_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Define: */ | ||
| 72 | /** \brief MIDI Class Device Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made for each MIDI interface | ||
| 75 | * within the user application, and passed to each of the MIDI class driver functions as the | ||
| 76 | * \c MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information. | ||
| 77 | */ | ||
| 78 | typedef struct | ||
| 79 | { | ||
| 80 | struct | ||
| 81 | { | ||
| 82 | uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls. */ | ||
| 83 | |||
| 84 | USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ | ||
| 85 | USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ | ||
| 86 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 87 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 88 | */ | ||
| 89 | |||
| 90 | struct | ||
| 91 | { | ||
| 92 | uint8_t RESERVED; // No state information for this class | ||
| 93 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 94 | * are reset to their defaults when the interface is enumerated. | ||
| 95 | */ | ||
| 96 | } USB_ClassInfo_MIDI_Device_t; | ||
| 97 | |||
| 98 | /* Function Prototypes: */ | ||
| 99 | /** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library | ||
| 100 | * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration | ||
| 101 | * containing the given MIDI interface is selected. | ||
| 102 | * | ||
| 103 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 104 | * | ||
| 105 | * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. | ||
| 106 | */ | ||
| 107 | bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 108 | |||
| 109 | /** General management task for a given MIDI class interface, required for the correct operation of the interface. This should | ||
| 110 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 111 | * | ||
| 112 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 113 | */ | ||
| 114 | void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 115 | |||
| 116 | /** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the | ||
| 117 | * endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple | ||
| 118 | * MIDI events to be packed into a single endpoint packet, increasing data throughput. | ||
| 119 | * | ||
| 120 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 121 | * call will fail. | ||
| 122 | * | ||
| 123 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 124 | * \param[in] Event Pointer to a populated \ref MIDI_EventPacket_t structure containing the MIDI event to send. | ||
| 125 | * | ||
| 126 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 127 | */ | ||
| 128 | uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, | ||
| 129 | const MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 130 | |||
| 131 | |||
| 132 | /** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the | ||
| 133 | * \ref MIDI_Device_SendEventPacket() function's packing behavior, to flush queued events. | ||
| 134 | * | ||
| 135 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 136 | * | ||
| 137 | * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. | ||
| 138 | */ | ||
| 139 | uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 140 | |||
| 141 | /** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains | ||
| 142 | * multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event. | ||
| 143 | * | ||
| 144 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 145 | * call will fail. | ||
| 146 | * | ||
| 147 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 148 | * \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed. | ||
| 149 | * | ||
| 150 | * \return Boolean \c true if a MIDI event packet was received, \c false otherwise. | ||
| 151 | */ | ||
| 152 | bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, | ||
| 153 | MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 154 | |||
| 155 | /* Inline Functions: */ | ||
| 156 | /** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be | ||
| 157 | * linked to the library \ref EVENT_USB_Device_ControlRequest() event. | ||
| 158 | * | ||
| 159 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 160 | */ | ||
| 161 | static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 162 | static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) | ||
| 163 | { | ||
| 164 | (void)MIDIInterfaceInfo; | ||
| 165 | } | ||
| 166 | |||
| 167 | /* Disable C linkage for C++ Compilers: */ | ||
| 168 | #if defined(__cplusplus) | ||
| 169 | } | ||
| 170 | #endif | ||
| 171 | |||
| 172 | #endif | ||
| 173 | |||
| 174 | /** @} */ | ||
| 175 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c new file mode 100644 index 000000000..1ea30f7cb --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c | |||
| @@ -0,0 +1,215 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_DEVICE) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_MS_DRIVER | ||
| 37 | #define __INCLUDE_FROM_MASSSTORAGE_DEVICE_C | ||
| 38 | #include "MassStorageClassDevice.h" | ||
| 39 | |||
| 40 | void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||
| 41 | { | ||
| 42 | if (!(Endpoint_IsSETUPReceived())) | ||
| 43 | return; | ||
| 44 | |||
| 45 | if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber) | ||
| 46 | return; | ||
| 47 | |||
| 48 | switch (USB_ControlRequest.bRequest) | ||
| 49 | { | ||
| 50 | case MS_REQ_MassStorageReset: | ||
| 51 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 52 | { | ||
| 53 | Endpoint_ClearSETUP(); | ||
| 54 | Endpoint_ClearStatusStage(); | ||
| 55 | |||
| 56 | MSInterfaceInfo->State.IsMassStoreReset = true; | ||
| 57 | } | ||
| 58 | |||
| 59 | break; | ||
| 60 | case MS_REQ_GetMaxLUN: | ||
| 61 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 62 | { | ||
| 63 | Endpoint_ClearSETUP(); | ||
| 64 | while (!(Endpoint_IsINReady())); | ||
| 65 | Endpoint_Write_8(MSInterfaceInfo->Config.TotalLUNs - 1); | ||
| 66 | Endpoint_ClearIN(); | ||
| 67 | Endpoint_ClearStatusStage(); | ||
| 68 | } | ||
| 69 | |||
| 70 | break; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||
| 75 | { | ||
| 76 | memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State)); | ||
| 77 | |||
| 78 | MSInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; | ||
| 79 | MSInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; | ||
| 80 | |||
| 81 | if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataINEndpoint, 1))) | ||
| 82 | return false; | ||
| 83 | |||
| 84 | if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataOUTEndpoint, 1))) | ||
| 85 | return false; | ||
| 86 | |||
| 87 | return true; | ||
| 88 | } | ||
| 89 | |||
| 90 | void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||
| 91 | { | ||
| 92 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 93 | return; | ||
| 94 | |||
| 95 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 96 | |||
| 97 | if (Endpoint_IsOUTReceived()) | ||
| 98 | { | ||
| 99 | if (MS_Device_ReadInCommandBlock(MSInterfaceInfo)) | ||
| 100 | { | ||
| 101 | if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN) | ||
| 102 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 103 | |||
| 104 | bool SCSICommandResult = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo); | ||
| 105 | |||
| 106 | MSInterfaceInfo->State.CommandStatus.Status = (SCSICommandResult) ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail; | ||
| 107 | MSInterfaceInfo->State.CommandStatus.Signature = CPU_TO_LE32(MS_CSW_SIGNATURE); | ||
| 108 | MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag; | ||
| 109 | MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength; | ||
| 110 | |||
| 111 | if (!(SCSICommandResult) && (le32_to_cpu(MSInterfaceInfo->State.CommandStatus.DataTransferResidue))) | ||
| 112 | Endpoint_StallTransaction(); | ||
| 113 | |||
| 114 | MS_Device_ReturnCommandStatus(MSInterfaceInfo); | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | if (MSInterfaceInfo->State.IsMassStoreReset) | ||
| 119 | { | ||
| 120 | Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 121 | Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 122 | |||
| 123 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 124 | Endpoint_ClearStall(); | ||
| 125 | Endpoint_ResetDataToggle(); | ||
| 126 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 127 | Endpoint_ClearStall(); | ||
| 128 | Endpoint_ResetDataToggle(); | ||
| 129 | |||
| 130 | MSInterfaceInfo->State.IsMassStoreReset = false; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||
| 135 | { | ||
| 136 | uint16_t BytesProcessed; | ||
| 137 | |||
| 138 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 139 | |||
| 140 | BytesProcessed = 0; | ||
| 141 | while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock, | ||
| 142 | (sizeof(MS_CommandBlockWrapper_t) - 16), &BytesProcessed) == | ||
| 143 | ENDPOINT_RWSTREAM_IncompleteTransfer) | ||
| 144 | { | ||
| 145 | if (MSInterfaceInfo->State.IsMassStoreReset) | ||
| 146 | return false; | ||
| 147 | } | ||
| 148 | |||
| 149 | if ((MSInterfaceInfo->State.CommandBlock.Signature != CPU_TO_LE32(MS_CBW_SIGNATURE)) || | ||
| 150 | (MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) || | ||
| 151 | (MSInterfaceInfo->State.CommandBlock.Flags & 0x1F) || | ||
| 152 | (MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0) || | ||
| 153 | (MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16)) | ||
| 154 | { | ||
| 155 | Endpoint_StallTransaction(); | ||
| 156 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 157 | Endpoint_StallTransaction(); | ||
| 158 | |||
| 159 | return false; | ||
| 160 | } | ||
| 161 | |||
| 162 | BytesProcessed = 0; | ||
| 163 | while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData, | ||
| 164 | MSInterfaceInfo->State.CommandBlock.SCSICommandLength, &BytesProcessed) == | ||
| 165 | ENDPOINT_RWSTREAM_IncompleteTransfer) | ||
| 166 | { | ||
| 167 | if (MSInterfaceInfo->State.IsMassStoreReset) | ||
| 168 | return false; | ||
| 169 | } | ||
| 170 | |||
| 171 | Endpoint_ClearOUT(); | ||
| 172 | |||
| 173 | return true; | ||
| 174 | } | ||
| 175 | |||
| 176 | static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||
| 177 | { | ||
| 178 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 179 | |||
| 180 | while (Endpoint_IsStalled()) | ||
| 181 | { | ||
| 182 | #if !defined(INTERRUPT_CONTROL_ENDPOINT) | ||
| 183 | USB_USBTask(); | ||
| 184 | #endif | ||
| 185 | |||
| 186 | if (MSInterfaceInfo->State.IsMassStoreReset) | ||
| 187 | return; | ||
| 188 | } | ||
| 189 | |||
| 190 | Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 191 | |||
| 192 | while (Endpoint_IsStalled()) | ||
| 193 | { | ||
| 194 | #if !defined(INTERRUPT_CONTROL_ENDPOINT) | ||
| 195 | USB_USBTask(); | ||
| 196 | #endif | ||
| 197 | |||
| 198 | if (MSInterfaceInfo->State.IsMassStoreReset) | ||
| 199 | return; | ||
| 200 | } | ||
| 201 | |||
| 202 | uint16_t BytesProcessed = 0; | ||
| 203 | while (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus, | ||
| 204 | sizeof(MS_CommandStatusWrapper_t), &BytesProcessed) == | ||
| 205 | ENDPOINT_RWSTREAM_IncompleteTransfer) | ||
| 206 | { | ||
| 207 | if (MSInterfaceInfo->State.IsMassStoreReset) | ||
| 208 | return; | ||
| 209 | } | ||
| 210 | |||
| 211 | Endpoint_ClearIN(); | ||
| 212 | } | ||
| 213 | |||
| 214 | #endif | ||
| 215 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h new file mode 100644 index 000000000..12b54f8df --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Device mode driver for the library USB Mass Storage Class driver. | ||
| 33 | * | ||
| 34 | * Device mode driver for the library USB Mass Storage Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassMS | ||
| 41 | * \defgroup Group_USBClassMSDevice Mass Storage Class Device Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassMSDevice_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassMSDevice_ModDescription Module Description | ||
| 48 | * Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef _MS_CLASS_DEVICE_H_ | ||
| 54 | #define _MS_CLASS_DEVICE_H_ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/MassStorageClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_MS_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Defines: */ | ||
| 72 | /** \brief Mass Storage Class Device Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made for each Mass Storage interface | ||
| 75 | * within the user application, and passed to each of the Mass Storage class driver functions as the | ||
| 76 | * \c MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information. | ||
| 77 | */ | ||
| 78 | typedef struct | ||
| 79 | { | ||
| 80 | struct | ||
| 81 | { | ||
| 82 | uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device. */ | ||
| 83 | |||
| 84 | USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ | ||
| 85 | USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ | ||
| 86 | |||
| 87 | uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface. */ | ||
| 88 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 89 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 90 | */ | ||
| 91 | struct | ||
| 92 | { | ||
| 93 | MS_CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI | ||
| 94 | * command from the host which is to be processed. | ||
| 95 | */ | ||
| 96 | MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate | ||
| 97 | * the issued command's success or failure to the host. | ||
| 98 | */ | ||
| 99 | volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset | ||
| 100 | * and that all current Mass Storage operations should immediately abort. | ||
| 101 | */ | ||
| 102 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 103 | * are reset to their defaults when the interface is enumerated. | ||
| 104 | */ | ||
| 105 | } USB_ClassInfo_MS_Device_t; | ||
| 106 | |||
| 107 | /* Function Prototypes: */ | ||
| 108 | /** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library | ||
| 109 | * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration | ||
| 110 | * containing the given Mass Storage interface is selected. | ||
| 111 | * | ||
| 112 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state. | ||
| 113 | * | ||
| 114 | * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. | ||
| 115 | */ | ||
| 116 | bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 117 | |||
| 118 | /** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be | ||
| 119 | * linked to the library \ref EVENT_USB_Device_ControlRequest() event. | ||
| 120 | * | ||
| 121 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state. | ||
| 122 | */ | ||
| 123 | void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 124 | |||
| 125 | /** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should | ||
| 126 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 127 | * | ||
| 128 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state. | ||
| 129 | */ | ||
| 130 | void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 131 | |||
| 132 | /** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the | ||
| 133 | * host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible | ||
| 134 | * for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure | ||
| 135 | * inside the Mass Storage class state structure passed as a parameter to the callback function. | ||
| 136 | * | ||
| 137 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state. | ||
| 138 | * | ||
| 139 | * \return Boolean \c true if the SCSI command was successfully processed, \c false otherwise. | ||
| 140 | */ | ||
| 141 | bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 142 | |||
| 143 | /* Private Interface - For use in library only: */ | ||
| 144 | #if !defined(__DOXYGEN__) | ||
| 145 | /* Function Prototypes: */ | ||
| 146 | #if defined(__INCLUDE_FROM_MASSSTORAGE_DEVICE_C) | ||
| 147 | static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 148 | static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 149 | #endif | ||
| 150 | |||
| 151 | #endif | ||
| 152 | |||
| 153 | /* Disable C linkage for C++ Compilers: */ | ||
| 154 | #if defined(__cplusplus) | ||
| 155 | } | ||
| 156 | #endif | ||
| 157 | |||
| 158 | #endif | ||
| 159 | |||
| 160 | /** @} */ | ||
| 161 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c new file mode 100644 index 000000000..7209c452d --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c | |||
| @@ -0,0 +1,314 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_DEVICE) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_PRINTER_DRIVER | ||
| 37 | #define __INCLUDE_FROM_PRINTER_DEVICE_C | ||
| 38 | #include "PrinterClassDevice.h" | ||
| 39 | |||
| 40 | void PRNT_Device_ProcessControlRequest(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) | ||
| 41 | { | ||
| 42 | if (!(Endpoint_IsSETUPReceived())) | ||
| 43 | return; | ||
| 44 | |||
| 45 | if (USB_ControlRequest.wIndex != PRNTInterfaceInfo->Config.InterfaceNumber) | ||
| 46 | return; | ||
| 47 | |||
| 48 | switch (USB_ControlRequest.bRequest) | ||
| 49 | { | ||
| 50 | case PRNT_REQ_GetDeviceID: | ||
| 51 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 52 | { | ||
| 53 | Endpoint_ClearSETUP(); | ||
| 54 | |||
| 55 | while (!(Endpoint_IsINReady())) | ||
| 56 | { | ||
| 57 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | uint16_t IEEEStringLen = strlen(PRNTInterfaceInfo->Config.IEEE1284String); | ||
| 62 | Endpoint_Write_16_BE(IEEEStringLen); | ||
| 63 | Endpoint_Write_Control_Stream_LE(PRNTInterfaceInfo->Config.IEEE1284String, IEEEStringLen); | ||
| 64 | Endpoint_ClearStatusStage(); | ||
| 65 | } | ||
| 66 | |||
| 67 | break; | ||
| 68 | case PRNT_REQ_GetPortStatus: | ||
| 69 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 70 | { | ||
| 71 | Endpoint_ClearSETUP(); | ||
| 72 | |||
| 73 | while (!(Endpoint_IsINReady())) | ||
| 74 | { | ||
| 75 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
| 76 | return; | ||
| 77 | } | ||
| 78 | |||
| 79 | Endpoint_Write_8(PRNTInterfaceInfo->State.PortStatus); | ||
| 80 | Endpoint_ClearStatusStage(); | ||
| 81 | } | ||
| 82 | |||
| 83 | break; | ||
| 84 | case PRNT_REQ_SoftReset: | ||
| 85 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 86 | { | ||
| 87 | Endpoint_ClearSETUP(); | ||
| 88 | Endpoint_ClearStatusStage(); | ||
| 89 | |||
| 90 | PRNTInterfaceInfo->State.IsPrinterReset = true; | ||
| 91 | |||
| 92 | EVENT_PRNT_Device_SoftReset(PRNTInterfaceInfo); | ||
| 93 | } | ||
| 94 | |||
| 95 | break; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | bool PRNT_Device_ConfigureEndpoints(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) | ||
| 100 | { | ||
| 101 | memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State)); | ||
| 102 | PRNTInterfaceInfo->State.PortStatus = PRNT_PORTSTATUS_NOTERROR | PRNT_PORTSTATUS_SELECT; | ||
| 103 | |||
| 104 | PRNTInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; | ||
| 105 | PRNTInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; | ||
| 106 | |||
| 107 | if (!(Endpoint_ConfigureEndpointTable(&PRNTInterfaceInfo->Config.DataINEndpoint, 1))) | ||
| 108 | return false; | ||
| 109 | |||
| 110 | if (!(Endpoint_ConfigureEndpointTable(&PRNTInterfaceInfo->Config.DataOUTEndpoint, 1))) | ||
| 111 | return false; | ||
| 112 | |||
| 113 | return true; | ||
| 114 | } | ||
| 115 | |||
| 116 | void PRNT_Device_USBTask(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) | ||
| 117 | { | ||
| 118 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 119 | return; | ||
| 120 | |||
| 121 | #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) | ||
| 122 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 123 | |||
| 124 | if (Endpoint_IsINReady()) | ||
| 125 | PRNT_Device_Flush(PRNTInterfaceInfo); | ||
| 126 | #endif | ||
| 127 | |||
| 128 | if (PRNTInterfaceInfo->State.IsPrinterReset) | ||
| 129 | { | ||
| 130 | Endpoint_ResetEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 131 | Endpoint_ResetEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 132 | |||
| 133 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 134 | Endpoint_ClearStall(); | ||
| 135 | Endpoint_ResetDataToggle(); | ||
| 136 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 137 | Endpoint_ClearStall(); | ||
| 138 | Endpoint_ResetDataToggle(); | ||
| 139 | |||
| 140 | PRNTInterfaceInfo->State.IsPrinterReset = false; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | uint8_t PRNT_Device_SendString(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 145 | const char* const String) | ||
| 146 | { | ||
| 147 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 148 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 149 | |||
| 150 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 151 | return Endpoint_Write_Stream_LE(String, strlen(String), NULL); | ||
| 152 | } | ||
| 153 | |||
| 154 | uint8_t PRNT_Device_SendData(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 155 | const void* const Buffer, | ||
| 156 | const uint16_t Length) | ||
| 157 | { | ||
| 158 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 159 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 160 | |||
| 161 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 162 | return Endpoint_Write_Stream_LE(Buffer, Length, NULL); | ||
| 163 | } | ||
| 164 | |||
| 165 | uint8_t PRNT_Device_SendByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 166 | const uint8_t Data) | ||
| 167 | { | ||
| 168 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 169 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 170 | |||
| 171 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 172 | |||
| 173 | if (!(Endpoint_IsReadWriteAllowed())) | ||
| 174 | { | ||
| 175 | Endpoint_ClearIN(); | ||
| 176 | |||
| 177 | uint8_t ErrorCode; | ||
| 178 | |||
| 179 | if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) | ||
| 180 | return ErrorCode; | ||
| 181 | } | ||
| 182 | |||
| 183 | Endpoint_Write_8(Data); | ||
| 184 | return ENDPOINT_READYWAIT_NoError; | ||
| 185 | } | ||
| 186 | |||
| 187 | uint8_t PRNT_Device_Flush(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) | ||
| 188 | { | ||
| 189 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 190 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 191 | |||
| 192 | uint8_t ErrorCode; | ||
| 193 | |||
| 194 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 195 | |||
| 196 | if (!(Endpoint_BytesInEndpoint())) | ||
| 197 | return ENDPOINT_READYWAIT_NoError; | ||
| 198 | |||
| 199 | bool BankFull = !(Endpoint_IsReadWriteAllowed()); | ||
| 200 | |||
| 201 | Endpoint_ClearIN(); | ||
| 202 | |||
| 203 | if (BankFull) | ||
| 204 | { | ||
| 205 | if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) | ||
| 206 | return ErrorCode; | ||
| 207 | |||
| 208 | Endpoint_ClearIN(); | ||
| 209 | } | ||
| 210 | |||
| 211 | return ENDPOINT_READYWAIT_NoError; | ||
| 212 | } | ||
| 213 | |||
| 214 | uint16_t PRNT_Device_BytesReceived(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) | ||
| 215 | { | ||
| 216 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 217 | return 0; | ||
| 218 | |||
| 219 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 220 | |||
| 221 | if (Endpoint_IsOUTReceived()) | ||
| 222 | { | ||
| 223 | if (!(Endpoint_BytesInEndpoint())) | ||
| 224 | { | ||
| 225 | Endpoint_ClearOUT(); | ||
| 226 | return 0; | ||
| 227 | } | ||
| 228 | else | ||
| 229 | { | ||
| 230 | return Endpoint_BytesInEndpoint(); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | else | ||
| 234 | { | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | int16_t PRNT_Device_ReceiveByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) | ||
| 240 | { | ||
| 241 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 242 | return -1; | ||
| 243 | |||
| 244 | int16_t ReceivedByte = -1; | ||
| 245 | |||
| 246 | Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 247 | |||
| 248 | if (Endpoint_IsOUTReceived()) | ||
| 249 | { | ||
| 250 | if (Endpoint_BytesInEndpoint()) | ||
| 251 | ReceivedByte = Endpoint_Read_8(); | ||
| 252 | |||
| 253 | if (!(Endpoint_BytesInEndpoint())) | ||
| 254 | Endpoint_ClearOUT(); | ||
| 255 | } | ||
| 256 | |||
| 257 | return ReceivedByte; | ||
| 258 | } | ||
| 259 | |||
| 260 | #if defined(FDEV_SETUP_STREAM) | ||
| 261 | void PRNT_Device_CreateStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 262 | FILE* const Stream) | ||
| 263 | { | ||
| 264 | *Stream = (FILE)FDEV_SETUP_STREAM(PRNT_Device_putchar, PRNT_Device_getchar, _FDEV_SETUP_RW); | ||
| 265 | fdev_set_udata(Stream, PRNTInterfaceInfo); | ||
| 266 | } | ||
| 267 | |||
| 268 | void PRNT_Device_CreateBlockingStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 269 | FILE* const Stream) | ||
| 270 | { | ||
| 271 | *Stream = (FILE)FDEV_SETUP_STREAM(PRNT_Device_putchar, PRNT_Device_getchar_Blocking, _FDEV_SETUP_RW); | ||
| 272 | fdev_set_udata(Stream, PRNTInterfaceInfo); | ||
| 273 | } | ||
| 274 | |||
| 275 | static int PRNT_Device_putchar(char c, | ||
| 276 | FILE* Stream) | ||
| 277 | { | ||
| 278 | return PRNT_Device_SendByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; | ||
| 279 | } | ||
| 280 | |||
| 281 | static int PRNT_Device_getchar(FILE* Stream) | ||
| 282 | { | ||
| 283 | int16_t ReceivedByte = PRNT_Device_ReceiveByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream)); | ||
| 284 | |||
| 285 | if (ReceivedByte < 0) | ||
| 286 | return _FDEV_EOF; | ||
| 287 | |||
| 288 | return ReceivedByte; | ||
| 289 | } | ||
| 290 | |||
| 291 | static int PRNT_Device_getchar_Blocking(FILE* Stream) | ||
| 292 | { | ||
| 293 | int16_t ReceivedByte; | ||
| 294 | |||
| 295 | while ((ReceivedByte = PRNT_Device_ReceiveByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream))) < 0) | ||
| 296 | { | ||
| 297 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
| 298 | return _FDEV_EOF; | ||
| 299 | |||
| 300 | PRNT_Device_USBTask((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream)); | ||
| 301 | USB_USBTask(); | ||
| 302 | } | ||
| 303 | |||
| 304 | return ReceivedByte; | ||
| 305 | } | ||
| 306 | #endif | ||
| 307 | |||
| 308 | void PRNT_Device_Event_Stub(void) | ||
| 309 | { | ||
| 310 | |||
| 311 | } | ||
| 312 | |||
| 313 | #endif | ||
| 314 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h new file mode 100644 index 000000000..802c5912d --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h | |||
| @@ -0,0 +1,293 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Device mode driver for the library USB Printer Class driver. | ||
| 33 | * | ||
| 34 | * Device mode driver for the library USB Printer Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassPrinter | ||
| 41 | * \defgroup Group_USBClassPrinterDevice Printer Class Device Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassPrinterDevice_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassPrinterDevice_ModDescription Module Description | ||
| 48 | * Device Mode USB Class driver framework interface, for the Printer USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef _PRINTER_CLASS_DEVICE_H_ | ||
| 54 | #define _PRINTER_CLASS_DEVICE_H_ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/PrinterClassCommon.h" | ||
| 59 | |||
| 60 | #include <stdio.h> | ||
| 61 | |||
| 62 | /* Enable C linkage for C++ Compilers: */ | ||
| 63 | #if defined(__cplusplus) | ||
| 64 | extern "C" { | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* Preprocessor Checks: */ | ||
| 68 | #if !defined(__INCLUDE_FROM_PRINTER_DRIVER) | ||
| 69 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 70 | #endif | ||
| 71 | |||
| 72 | /* Public Interface - May be used in end-application: */ | ||
| 73 | /* Type Defines: */ | ||
| 74 | /** \brief Printer Class Device Mode Configuration and State Structure. | ||
| 75 | * | ||
| 76 | * Class state structure. An instance of this structure should be made for each Printer interface | ||
| 77 | * within the user application, and passed to each of the Printer class driver functions as the | ||
| 78 | * PRNTInterfaceInfo parameter. This stores each Printer interface's configuration and state information. | ||
| 79 | */ | ||
| 80 | typedef struct | ||
| 81 | { | ||
| 82 | struct | ||
| 83 | { | ||
| 84 | uint8_t InterfaceNumber; /**< Interface number of the Printer interface within the device. */ | ||
| 85 | |||
| 86 | USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ | ||
| 87 | USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ | ||
| 88 | |||
| 89 | char* IEEE1284String; /**< IEEE 1284 identification string, sent to the host during enumeration | ||
| 90 | * to identify the printer model, manufacturer and other characteristics. | ||
| 91 | */ | ||
| 92 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 93 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 94 | */ | ||
| 95 | struct | ||
| 96 | { | ||
| 97 | uint8_t PortStatus; /**< Current status of the Printer virtual port, a collection of \c PRNT_PORTSTATUS_* | ||
| 98 | * bitmask values. | ||
| 99 | */ | ||
| 100 | |||
| 101 | volatile bool IsPrinterReset; /**< Flag indicating that the host has requested that the Printer interface be reset | ||
| 102 | * and that all current Mass Storage operations should immediately abort. | ||
| 103 | */ | ||
| 104 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 105 | * are reset to their defaults when the interface is enumerated. | ||
| 106 | */ | ||
| 107 | } USB_ClassInfo_PRNT_Device_t; | ||
| 108 | |||
| 109 | /* Function Prototypes: */ | ||
| 110 | /** Configures the endpoints of a given Printer interface, ready for use. This should be linked to the library | ||
| 111 | * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing | ||
| 112 | * the given Printer interface is selected. | ||
| 113 | * | ||
| 114 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 115 | * | ||
| 116 | * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. | ||
| 117 | */ | ||
| 118 | bool PRNT_Device_ConfigureEndpoints(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 119 | |||
| 120 | /** Processes incoming control requests from the host, that are directed to the given Printer class interface. This should be | ||
| 121 | * linked to the library \ref EVENT_USB_Device_ControlRequest() event. | ||
| 122 | * | ||
| 123 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 124 | */ | ||
| 125 | void PRNT_Device_ProcessControlRequest(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 126 | |||
| 127 | /** General management task for a given Printer class interface, required for the correct operation of the interface. This should | ||
| 128 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 129 | * | ||
| 130 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 131 | */ | ||
| 132 | void PRNT_Device_USBTask(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 133 | |||
| 134 | /** Printer class driver event for a soft reset request on a Printer interface. This event fires each time the host | ||
| 135 | * requests a reset of the printer interface's internal state, and may be hooked in the user program by declaring a | ||
| 136 | * handler function with the same name and parameters listed here. | ||
| 137 | * | ||
| 138 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 139 | */ | ||
| 140 | void EVENT_PRNT_Device_SoftReset(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 141 | |||
| 142 | /** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is | ||
| 143 | * called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank | ||
| 144 | * becomes full, or the \ref PRNT_Device_Flush() function is called to flush the pending data to the host. This allows | ||
| 145 | * for multiple bytes to be packed into a single endpoint packet, increasing data throughput. | ||
| 146 | * | ||
| 147 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 148 | * the call will fail. | ||
| 149 | * | ||
| 150 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 151 | * \param[in] Buffer Pointer to a buffer containing the data to send to the device. | ||
| 152 | * \param[in] Length Length of the data to send to the host. | ||
| 153 | * | ||
| 154 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 155 | */ | ||
| 156 | uint8_t PRNT_Device_SendData(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 157 | const void* const Buffer, | ||
| 158 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 159 | |||
| 160 | /** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when | ||
| 161 | * the function is called, the string is discarded. Bytes will be queued for transmission to the host until either | ||
| 162 | * the endpoint bank becomes full, or the \ref PRNT_Device_Flush() function is called to flush the pending data to | ||
| 163 | * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput. | ||
| 164 | * | ||
| 165 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 166 | * the call will fail. | ||
| 167 | * | ||
| 168 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 169 | * \param[in] String Pointer to the null terminated string to send to the host. | ||
| 170 | * | ||
| 171 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 172 | */ | ||
| 173 | uint8_t PRNT_Device_SendString(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 174 | const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 175 | |||
| 176 | /** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the | ||
| 177 | * byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the | ||
| 178 | * \ref PRNT_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be | ||
| 179 | * packed into a single endpoint packet, increasing data throughput. | ||
| 180 | * | ||
| 181 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 182 | * the call will fail. | ||
| 183 | * | ||
| 184 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 185 | * \param[in] Data Byte of data to send to the host. | ||
| 186 | * | ||
| 187 | * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. | ||
| 188 | */ | ||
| 189 | uint8_t PRNT_Device_SendByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 190 | const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); | ||
| 191 | |||
| 192 | /** Determines the number of bytes received by the Printer interface from the host, waiting to be read. This indicates the number | ||
| 193 | * of bytes in the OUT endpoint bank only, and thus the number of calls to \ref PRNT_Device_ReceiveByte() which are guaranteed to | ||
| 194 | * succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint | ||
| 195 | * bank will not be released back to the USB controller until all bytes are read. | ||
| 196 | * | ||
| 197 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 198 | * the call will fail. | ||
| 199 | * | ||
| 200 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 201 | * | ||
| 202 | * \return Total number of buffered bytes received from the host. | ||
| 203 | */ | ||
| 204 | uint16_t PRNT_Device_BytesReceived(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 205 | |||
| 206 | /** 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 | ||
| 207 | * returns a negative value. The \ref PRNT_Device_BytesReceived() function may be queried in advance to determine how many | ||
| 208 | * bytes are currently buffered in the Printer interface's data receive endpoint bank, and thus how many repeated calls to this | ||
| 209 | * function which are guaranteed to succeed. | ||
| 210 | * | ||
| 211 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 212 | * the call will fail. | ||
| 213 | * | ||
| 214 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 215 | * | ||
| 216 | * \return Next received byte from the host, or a negative value if no data received. | ||
| 217 | */ | ||
| 218 | int16_t PRNT_Device_ReceiveByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 219 | |||
| 220 | /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. | ||
| 221 | * | ||
| 222 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or | ||
| 223 | * the call will fail. | ||
| 224 | * | ||
| 225 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 226 | * | ||
| 227 | * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. | ||
| 228 | */ | ||
| 229 | uint8_t PRNT_Device_Flush(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 230 | |||
| 231 | #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__) | ||
| 232 | /** Creates a standard character stream for the given Printer Device instance so that it can be used with all the regular | ||
| 233 | * functions in the standard <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created | ||
| 234 | * stream is bidirectional and can be used for both input and output functions. | ||
| 235 | * | ||
| 236 | * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single | ||
| 237 | * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may | ||
| 238 | * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own | ||
| 239 | * line buffering. | ||
| 240 | * | ||
| 241 | * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions | ||
| 242 | * to the given Printer interface. | ||
| 243 | * \n\n | ||
| 244 | * | ||
| 245 | * \note This function is not available on all microcontroller architectures. | ||
| 246 | * | ||
| 247 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 248 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 249 | */ | ||
| 250 | void PRNT_Device_CreateStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 251 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 252 | |||
| 253 | /** Identical to \ref PRNT_Device_CreateStream(), except that reads are blocking until the calling stream function terminates | ||
| 254 | * the transfer. While blocking, the USB and Printer service tasks are called repeatedly to maintain USB communications. | ||
| 255 | * | ||
| 256 | * \note This function is not available on all microcontroller architectures. | ||
| 257 | * | ||
| 258 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state. | ||
| 259 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 260 | */ | ||
| 261 | void PRNT_Device_CreateBlockingStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo, | ||
| 262 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 263 | #endif | ||
| 264 | |||
| 265 | /* Private Interface - For use in library only: */ | ||
| 266 | #if !defined(__DOXYGEN__) | ||
| 267 | /* Function Prototypes: */ | ||
| 268 | #if defined(__INCLUDE_FROM_PRINTER_DEVICE_C) | ||
| 269 | #if defined(FDEV_SETUP_STREAM) | ||
| 270 | static int PRNT_Device_putchar(char c, | ||
| 271 | FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); | ||
| 272 | static int PRNT_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 273 | static int PRNT_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 274 | #endif | ||
| 275 | |||
| 276 | void PRNT_Device_Event_Stub(void) ATTR_CONST; | ||
| 277 | |||
| 278 | void EVENT_PRNT_Device_SoftReset(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) | ||
| 279 | ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(PRNT_Device_Event_Stub); | ||
| 280 | |||
| 281 | #endif | ||
| 282 | |||
| 283 | #endif | ||
| 284 | |||
| 285 | /* Disable C linkage for C++ Compilers: */ | ||
| 286 | #if defined(__cplusplus) | ||
| 287 | } | ||
| 288 | #endif | ||
| 289 | |||
| 290 | #endif | ||
| 291 | |||
| 292 | /** @} */ | ||
| 293 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c new file mode 100644 index 000000000..45293b12f --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c | |||
| @@ -0,0 +1,508 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_DEVICE) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_RNDIS_DRIVER | ||
| 37 | #define __INCLUDE_FROM_RNDIS_DEVICE_C | ||
| 38 | #include "RNDISClassDevice.h" | ||
| 39 | |||
| 40 | static const uint32_t PROGMEM AdapterSupportedOIDList[] = | ||
| 41 | { | ||
| 42 | CPU_TO_LE32(OID_GEN_SUPPORTED_LIST), | ||
| 43 | CPU_TO_LE32(OID_GEN_PHYSICAL_MEDIUM), | ||
| 44 | CPU_TO_LE32(OID_GEN_HARDWARE_STATUS), | ||
| 45 | CPU_TO_LE32(OID_GEN_MEDIA_SUPPORTED), | ||
| 46 | CPU_TO_LE32(OID_GEN_MEDIA_IN_USE), | ||
| 47 | CPU_TO_LE32(OID_GEN_MAXIMUM_FRAME_SIZE), | ||
| 48 | CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE), | ||
| 49 | CPU_TO_LE32(OID_GEN_LINK_SPEED), | ||
| 50 | CPU_TO_LE32(OID_GEN_TRANSMIT_BLOCK_SIZE), | ||
| 51 | CPU_TO_LE32(OID_GEN_RECEIVE_BLOCK_SIZE), | ||
| 52 | CPU_TO_LE32(OID_GEN_VENDOR_ID), | ||
| 53 | CPU_TO_LE32(OID_GEN_VENDOR_DESCRIPTION), | ||
| 54 | CPU_TO_LE32(OID_GEN_CURRENT_PACKET_FILTER), | ||
| 55 | CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE), | ||
| 56 | CPU_TO_LE32(OID_GEN_MEDIA_CONNECT_STATUS), | ||
| 57 | CPU_TO_LE32(OID_GEN_XMIT_OK), | ||
| 58 | CPU_TO_LE32(OID_GEN_RCV_OK), | ||
| 59 | CPU_TO_LE32(OID_GEN_XMIT_ERROR), | ||
| 60 | CPU_TO_LE32(OID_GEN_RCV_ERROR), | ||
| 61 | CPU_TO_LE32(OID_GEN_RCV_NO_BUFFER), | ||
| 62 | CPU_TO_LE32(OID_802_3_PERMANENT_ADDRESS), | ||
| 63 | CPU_TO_LE32(OID_802_3_CURRENT_ADDRESS), | ||
| 64 | CPU_TO_LE32(OID_802_3_MULTICAST_LIST), | ||
| 65 | CPU_TO_LE32(OID_802_3_MAXIMUM_LIST_SIZE), | ||
| 66 | CPU_TO_LE32(OID_802_3_RCV_ERROR_ALIGNMENT), | ||
| 67 | CPU_TO_LE32(OID_802_3_XMIT_ONE_COLLISION), | ||
| 68 | CPU_TO_LE32(OID_802_3_XMIT_MORE_COLLISIONS), | ||
| 69 | }; | ||
| 70 | |||
| 71 | void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) | ||
| 72 | { | ||
| 73 | if (!(Endpoint_IsSETUPReceived())) | ||
| 74 | return; | ||
| 75 | |||
| 76 | if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber) | ||
| 77 | return; | ||
| 78 | |||
| 79 | switch (USB_ControlRequest.bRequest) | ||
| 80 | { | ||
| 81 | case RNDIS_REQ_SendEncapsulatedCommand: | ||
| 82 | if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 83 | { | ||
| 84 | Endpoint_ClearSETUP(); | ||
| 85 | Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, USB_ControlRequest.wLength); | ||
| 86 | Endpoint_ClearIN(); | ||
| 87 | |||
| 88 | RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo); | ||
| 89 | } | ||
| 90 | |||
| 91 | break; | ||
| 92 | case RNDIS_REQ_GetEncapsulatedResponse: | ||
| 93 | if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) | ||
| 94 | { | ||
| 95 | RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 96 | |||
| 97 | if (!(MessageHeader->MessageLength)) | ||
| 98 | { | ||
| 99 | RNDISInterfaceInfo->Config.MessageBuffer[0] = 0; | ||
| 100 | MessageHeader->MessageLength = CPU_TO_LE32(1); | ||
| 101 | } | ||
| 102 | |||
| 103 | Endpoint_ClearSETUP(); | ||
| 104 | Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, le32_to_cpu(MessageHeader->MessageLength)); | ||
| 105 | Endpoint_ClearOUT(); | ||
| 106 | |||
| 107 | MessageHeader->MessageLength = CPU_TO_LE32(0); | ||
| 108 | } | ||
| 109 | |||
| 110 | break; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) | ||
| 115 | { | ||
| 116 | memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State)); | ||
| 117 | |||
| 118 | RNDISInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; | ||
| 119 | RNDISInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; | ||
| 120 | RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT; | ||
| 121 | |||
| 122 | if (RNDISInterfaceInfo->Config.MessageBuffer == NULL) | ||
| 123 | return false; | ||
| 124 | |||
| 125 | if (RNDISInterfaceInfo->Config.MessageBufferLength < RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH) | ||
| 126 | return false; | ||
| 127 | |||
| 128 | if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1))) | ||
| 129 | return false; | ||
| 130 | |||
| 131 | if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataOUTEndpoint, 1))) | ||
| 132 | return false; | ||
| 133 | |||
| 134 | if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.NotificationEndpoint, 1))) | ||
| 135 | return false; | ||
| 136 | |||
| 137 | return true; | ||
| 138 | } | ||
| 139 | |||
| 140 | void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) | ||
| 141 | { | ||
| 142 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
| 143 | return; | ||
| 144 | |||
| 145 | Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpoint.Address); | ||
| 146 | |||
| 147 | if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady) | ||
| 148 | { | ||
| 149 | USB_Request_Header_t Notification = (USB_Request_Header_t) | ||
| 150 | { | ||
| 151 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 152 | .bRequest = RNDIS_NOTIF_ResponseAvailable, | ||
| 153 | .wValue = CPU_TO_LE16(0), | ||
| 154 | .wIndex = CPU_TO_LE16(0), | ||
| 155 | .wLength = CPU_TO_LE16(0), | ||
| 156 | }; | ||
| 157 | |||
| 158 | Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL); | ||
| 159 | |||
| 160 | Endpoint_ClearIN(); | ||
| 161 | |||
| 162 | RNDISInterfaceInfo->State.ResponseReady = false; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) | ||
| 167 | { | ||
| 168 | /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of | ||
| 169 | this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */ | ||
| 170 | |||
| 171 | RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 172 | |||
| 173 | switch (le32_to_cpu(MessageHeader->MessageType)) | ||
| 174 | { | ||
| 175 | case REMOTE_NDIS_INITIALIZE_MSG: | ||
| 176 | RNDISInterfaceInfo->State.ResponseReady = true; | ||
| 177 | |||
| 178 | RNDIS_Initialize_Message_t* INITIALIZE_Message = | ||
| 179 | (RNDIS_Initialize_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 180 | RNDIS_Initialize_Complete_t* INITIALIZE_Response = | ||
| 181 | (RNDIS_Initialize_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 182 | |||
| 183 | INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT); | ||
| 184 | INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t)); | ||
| 185 | INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId; | ||
| 186 | INITIALIZE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); | ||
| 187 | |||
| 188 | INITIALIZE_Response->MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR); | ||
| 189 | INITIALIZE_Response->MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR); | ||
| 190 | INITIALIZE_Response->DeviceFlags = CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS); | ||
| 191 | INITIALIZE_Response->Medium = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3); | ||
| 192 | INITIALIZE_Response->MaxPacketsPerTransfer = CPU_TO_LE32(1); | ||
| 193 | INITIALIZE_Response->MaxTransferSize = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX); | ||
| 194 | INITIALIZE_Response->PacketAlignmentFactor = CPU_TO_LE32(0); | ||
| 195 | INITIALIZE_Response->AFListOffset = CPU_TO_LE32(0); | ||
| 196 | INITIALIZE_Response->AFListSize = CPU_TO_LE32(0); | ||
| 197 | |||
| 198 | RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized; | ||
| 199 | break; | ||
| 200 | case REMOTE_NDIS_HALT_MSG: | ||
| 201 | RNDISInterfaceInfo->State.ResponseReady = false; | ||
| 202 | |||
| 203 | MessageHeader->MessageLength = CPU_TO_LE32(0); | ||
| 204 | |||
| 205 | RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized; | ||
| 206 | break; | ||
| 207 | case REMOTE_NDIS_QUERY_MSG: | ||
| 208 | RNDISInterfaceInfo->State.ResponseReady = true; | ||
| 209 | |||
| 210 | RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 211 | RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 212 | uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid); | ||
| 213 | |||
| 214 | void* QueryData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) + | ||
| 215 | le32_to_cpu(QUERY_Message->InformationBufferOffset)]; | ||
| 216 | void* ResponseData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Query_Complete_t)]; | ||
| 217 | uint16_t ResponseSize; | ||
| 218 | |||
| 219 | QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT); | ||
| 220 | |||
| 221 | if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, le32_to_cpu(QUERY_Message->InformationBufferLength), | ||
| 222 | ResponseData, &ResponseSize)) | ||
| 223 | { | ||
| 224 | QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); | ||
| 225 | QUERY_Response->MessageLength = cpu_to_le32(sizeof(RNDIS_Query_Complete_t) + ResponseSize); | ||
| 226 | |||
| 227 | QUERY_Response->InformationBufferLength = CPU_TO_LE32(ResponseSize); | ||
| 228 | QUERY_Response->InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t)); | ||
| 229 | } | ||
| 230 | else | ||
| 231 | { | ||
| 232 | QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED); | ||
| 233 | QUERY_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t)); | ||
| 234 | |||
| 235 | QUERY_Response->InformationBufferLength = CPU_TO_LE32(0); | ||
| 236 | QUERY_Response->InformationBufferOffset = CPU_TO_LE32(0); | ||
| 237 | } | ||
| 238 | |||
| 239 | break; | ||
| 240 | case REMOTE_NDIS_SET_MSG: | ||
| 241 | RNDISInterfaceInfo->State.ResponseReady = true; | ||
| 242 | |||
| 243 | RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 244 | RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 245 | uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid); | ||
| 246 | |||
| 247 | SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT); | ||
| 248 | SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t)); | ||
| 249 | SET_Response->RequestId = SET_Message->RequestId; | ||
| 250 | |||
| 251 | void* SetData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) + | ||
| 252 | le32_to_cpu(SET_Message->InformationBufferOffset)]; | ||
| 253 | |||
| 254 | SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, | ||
| 255 | le32_to_cpu(SET_Message->InformationBufferLength)) ? | ||
| 256 | REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED; | ||
| 257 | break; | ||
| 258 | case REMOTE_NDIS_RESET_MSG: | ||
| 259 | RNDISInterfaceInfo->State.ResponseReady = true; | ||
| 260 | |||
| 261 | RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 262 | |||
| 263 | RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT); | ||
| 264 | RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t)); | ||
| 265 | RESET_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); | ||
| 266 | RESET_Response->AddressingReset = CPU_TO_LE32(0); | ||
| 267 | |||
| 268 | break; | ||
| 269 | case REMOTE_NDIS_KEEPALIVE_MSG: | ||
| 270 | RNDISInterfaceInfo->State.ResponseReady = true; | ||
| 271 | |||
| 272 | RNDIS_KeepAlive_Message_t* KEEPALIVE_Message = | ||
| 273 | (RNDIS_KeepAlive_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 274 | RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response = | ||
| 275 | (RNDIS_KeepAlive_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; | ||
| 276 | |||
| 277 | KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT); | ||
| 278 | KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t)); | ||
| 279 | KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId; | ||
| 280 | KEEPALIVE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); | ||
| 281 | |||
| 282 | break; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 287 | const uint32_t OId, | ||
| 288 | void* const QueryData, | ||
| 289 | const uint16_t QuerySize, | ||
| 290 | void* ResponseData, | ||
| 291 | uint16_t* const ResponseSize) | ||
| 292 | { | ||
| 293 | (void)QueryData; | ||
| 294 | (void)QuerySize; | ||
| 295 | |||
| 296 | switch (OId) | ||
| 297 | { | ||
| 298 | case OID_GEN_SUPPORTED_LIST: | ||
| 299 | *ResponseSize = sizeof(AdapterSupportedOIDList); | ||
| 300 | |||
| 301 | memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList)); | ||
| 302 | |||
| 303 | return true; | ||
| 304 | case OID_GEN_PHYSICAL_MEDIUM: | ||
| 305 | *ResponseSize = sizeof(uint32_t); | ||
| 306 | |||
| 307 | /* Indicate that the device is a true ethernet link */ | ||
| 308 | *((uint32_t*)ResponseData) = CPU_TO_LE32(0); | ||
| 309 | |||
| 310 | return true; | ||
| 311 | case OID_GEN_HARDWARE_STATUS: | ||
| 312 | *ResponseSize = sizeof(uint32_t); | ||
| 313 | |||
| 314 | *((uint32_t*)ResponseData) = CPU_TO_LE32(NDIS_HardwareStatus_Ready); | ||
| 315 | |||
| 316 | return true; | ||
| 317 | case OID_GEN_MEDIA_SUPPORTED: | ||
| 318 | case OID_GEN_MEDIA_IN_USE: | ||
| 319 | *ResponseSize = sizeof(uint32_t); | ||
| 320 | |||
| 321 | *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3); | ||
| 322 | |||
| 323 | return true; | ||
| 324 | case OID_GEN_VENDOR_ID: | ||
| 325 | *ResponseSize = sizeof(uint32_t); | ||
| 326 | |||
| 327 | /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */ | ||
| 328 | *((uint32_t*)ResponseData) = CPU_TO_LE32(0x00FFFFFF); | ||
| 329 | |||
| 330 | return true; | ||
| 331 | case OID_GEN_MAXIMUM_FRAME_SIZE: | ||
| 332 | case OID_GEN_TRANSMIT_BLOCK_SIZE: | ||
| 333 | case OID_GEN_RECEIVE_BLOCK_SIZE: | ||
| 334 | *ResponseSize = sizeof(uint32_t); | ||
| 335 | |||
| 336 | *((uint32_t*)ResponseData) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX); | ||
| 337 | |||
| 338 | return true; | ||
| 339 | case OID_GEN_VENDOR_DESCRIPTION: | ||
| 340 | *ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1); | ||
| 341 | |||
| 342 | memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize); | ||
| 343 | |||
| 344 | return true; | ||
| 345 | case OID_GEN_MEDIA_CONNECT_STATUS: | ||
| 346 | *ResponseSize = sizeof(uint32_t); | ||
| 347 | |||
| 348 | *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED); | ||
| 349 | |||
| 350 | return true; | ||
| 351 | case OID_GEN_LINK_SPEED: | ||
| 352 | *ResponseSize = sizeof(uint32_t); | ||
| 353 | |||
| 354 | /* Indicate 10Mb/s link speed */ | ||
| 355 | *((uint32_t*)ResponseData) = CPU_TO_LE32(100000); | ||
| 356 | |||
| 357 | return true; | ||
| 358 | case OID_802_3_PERMANENT_ADDRESS: | ||
| 359 | case OID_802_3_CURRENT_ADDRESS: | ||
| 360 | *ResponseSize = sizeof(MAC_Address_t); | ||
| 361 | |||
| 362 | memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t)); | ||
| 363 | |||
| 364 | return true; | ||
| 365 | case OID_802_3_MAXIMUM_LIST_SIZE: | ||
| 366 | *ResponseSize = sizeof(uint32_t); | ||
| 367 | |||
| 368 | /* Indicate only one multicast address supported */ | ||
| 369 | *((uint32_t*)ResponseData) = CPU_TO_LE32(1); | ||
| 370 | |||
| 371 | return true; | ||
| 372 | case OID_GEN_CURRENT_PACKET_FILTER: | ||
| 373 | *ResponseSize = sizeof(uint32_t); | ||
| 374 | |||
| 375 | *((uint32_t*)ResponseData) = cpu_to_le32(RNDISInterfaceInfo->State.CurrPacketFilter); | ||
| 376 | |||
| 377 | return true; | ||
| 378 | case OID_GEN_XMIT_OK: | ||
| 379 | case OID_GEN_RCV_OK: | ||
| 380 | case OID_GEN_XMIT_ERROR: | ||
| 381 | case OID_GEN_RCV_ERROR: | ||
| 382 | case OID_GEN_RCV_NO_BUFFER: | ||
| 383 | case OID_802_3_RCV_ERROR_ALIGNMENT: | ||
| 384 | case OID_802_3_XMIT_ONE_COLLISION: | ||
| 385 | case OID_802_3_XMIT_MORE_COLLISIONS: | ||
| 386 | *ResponseSize = sizeof(uint32_t); | ||
| 387 | |||
| 388 | /* Unused statistic OIDs - always return 0 for each */ | ||
| 389 | *((uint32_t*)ResponseData) = CPU_TO_LE32(0); | ||
| 390 | |||
| 391 | return true; | ||
| 392 | case OID_GEN_MAXIMUM_TOTAL_SIZE: | ||
| 393 | *ResponseSize = sizeof(uint32_t); | ||
| 394 | |||
| 395 | /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */ | ||
| 396 | *((uint32_t*)ResponseData) = CPU_TO_LE32(RNDISInterfaceInfo->Config.MessageBufferLength + ETHERNET_FRAME_SIZE_MAX); | ||
| 397 | |||
| 398 | return true; | ||
| 399 | default: | ||
| 400 | return false; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 405 | const uint32_t OId, | ||
| 406 | const void* SetData, | ||
| 407 | const uint16_t SetSize) | ||
| 408 | { | ||
| 409 | (void)SetSize; | ||
| 410 | |||
| 411 | switch (OId) | ||
| 412 | { | ||
| 413 | case OID_GEN_CURRENT_PACKET_FILTER: | ||
| 414 | RNDISInterfaceInfo->State.CurrPacketFilter = le32_to_cpu(*((uint32_t*)SetData)); | ||
| 415 | RNDISInterfaceInfo->State.CurrRNDISState = (RNDISInterfaceInfo->State.CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Initialized; | ||
| 416 | |||
| 417 | return true; | ||
| 418 | case OID_802_3_MULTICAST_LIST: | ||
| 419 | /* Do nothing - throw away the value from the host as it is unused */ | ||
| 420 | |||
| 421 | return true; | ||
| 422 | default: | ||
| 423 | return false; | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 427 | bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) | ||
| 428 | { | ||
| 429 | if ((USB_DeviceState != DEVICE_STATE_Configured) || | ||
| 430 | (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) | ||
| 431 | { | ||
| 432 | return false; | ||
| 433 | } | ||
| 434 | |||
| 435 | Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 436 | return Endpoint_IsOUTReceived(); | ||
| 437 | } | ||
| 438 | |||
| 439 | uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 440 | void* Buffer, | ||
| 441 | uint16_t* const PacketLength) | ||
| 442 | { | ||
| 443 | if ((USB_DeviceState != DEVICE_STATE_Configured) || | ||
| 444 | (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) | ||
| 445 | { | ||
| 446 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 447 | } | ||
| 448 | |||
| 449 | Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address); | ||
| 450 | |||
| 451 | *PacketLength = 0; | ||
| 452 | |||
| 453 | if (!(Endpoint_IsOUTReceived())) | ||
| 454 | return ENDPOINT_RWSTREAM_NoError; | ||
| 455 | |||
| 456 | RNDIS_Packet_Message_t RNDISPacketHeader; | ||
| 457 | Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); | ||
| 458 | |||
| 459 | if (le32_to_cpu(RNDISPacketHeader.DataLength) > ETHERNET_FRAME_SIZE_MAX) | ||
| 460 | { | ||
| 461 | Endpoint_StallTransaction(); | ||
| 462 | |||
| 463 | return RNDIS_ERROR_LOGICAL_CMD_FAILED; | ||
| 464 | } | ||
| 465 | |||
| 466 | *PacketLength = (uint16_t)le32_to_cpu(RNDISPacketHeader.DataLength); | ||
| 467 | |||
| 468 | Endpoint_Read_Stream_LE(Buffer, *PacketLength, NULL); | ||
| 469 | Endpoint_ClearOUT(); | ||
| 470 | |||
| 471 | return ENDPOINT_RWSTREAM_NoError; | ||
| 472 | } | ||
| 473 | |||
| 474 | uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 475 | void* Buffer, | ||
| 476 | const uint16_t PacketLength) | ||
| 477 | { | ||
| 478 | uint8_t ErrorCode; | ||
| 479 | |||
| 480 | if ((USB_DeviceState != DEVICE_STATE_Configured) || | ||
| 481 | (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) | ||
| 482 | { | ||
| 483 | return ENDPOINT_RWSTREAM_DeviceDisconnected; | ||
| 484 | } | ||
| 485 | |||
| 486 | Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpoint.Address); | ||
| 487 | |||
| 488 | if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) | ||
| 489 | return ErrorCode; | ||
| 490 | |||
| 491 | RNDIS_Packet_Message_t RNDISPacketHeader; | ||
| 492 | |||
| 493 | memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t)); | ||
| 494 | |||
| 495 | RNDISPacketHeader.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG); | ||
| 496 | RNDISPacketHeader.MessageLength = cpu_to_le32(sizeof(RNDIS_Packet_Message_t) + PacketLength); | ||
| 497 | RNDISPacketHeader.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)); | ||
| 498 | RNDISPacketHeader.DataLength = cpu_to_le32(PacketLength); | ||
| 499 | |||
| 500 | Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); | ||
| 501 | Endpoint_Write_Stream_LE(Buffer, PacketLength, NULL); | ||
| 502 | Endpoint_ClearIN(); | ||
| 503 | |||
| 504 | return ENDPOINT_RWSTREAM_NoError; | ||
| 505 | } | ||
| 506 | |||
| 507 | #endif | ||
| 508 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h new file mode 100644 index 000000000..761bc2790 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h | |||
| @@ -0,0 +1,207 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Device mode driver for the library USB RNDIS Class driver. | ||
| 33 | * | ||
| 34 | * Device mode driver for the library USB RNDIS Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassRNDIS | ||
| 41 | * \defgroup Group_USBClassRNDISDevice RNDIS Class Device Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassRNDISDevice_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassRNDISDevice_ModDescription Module Description | ||
| 48 | * Device Mode USB Class driver framework interface, for the RNDIS USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef _RNDIS_CLASS_DEVICE_H_ | ||
| 54 | #define _RNDIS_CLASS_DEVICE_H_ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/RNDISClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_RNDIS_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Defines: */ | ||
| 72 | /** \brief RNDIS Class Device Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made for each RNDIS interface | ||
| 75 | * within the user application, and passed to each of the RNDIS class driver functions as the | ||
| 76 | * \c RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information. | ||
| 77 | */ | ||
| 78 | typedef struct | ||
| 79 | { | ||
| 80 | struct | ||
| 81 | { | ||
| 82 | uint8_t ControlInterfaceNumber; /**< Interface number of the RNDIS control interface within the device. */ | ||
| 83 | |||
| 84 | USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ | ||
| 85 | USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ | ||
| 86 | USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */ | ||
| 87 | |||
| 88 | char* AdapterVendorDescription; /**< String description of the adapter vendor. */ | ||
| 89 | MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */ | ||
| 90 | |||
| 91 | uint8_t* MessageBuffer; /**< Buffer where RNDIS messages can be stored by the internal driver. This | ||
| 92 | * should be at least 132 bytes in length for minimal functionality. */ | ||
| 93 | uint16_t MessageBufferLength; /**< Length in bytes of the \ref MessageBuffer RNDIS buffer. */ | ||
| 94 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 95 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 96 | */ | ||
| 97 | struct | ||
| 98 | { | ||
| 99 | bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */ | ||
| 100 | uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */ | ||
| 101 | uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */ | ||
| 102 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 103 | * are reset to their defaults when the interface is enumerated. | ||
| 104 | */ | ||
| 105 | } USB_ClassInfo_RNDIS_Device_t; | ||
| 106 | |||
| 107 | /* Function Prototypes: */ | ||
| 108 | /** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library | ||
| 109 | * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration | ||
| 110 | * containing the given RNDIS interface is selected. | ||
| 111 | * | ||
| 112 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state. | ||
| 113 | * | ||
| 114 | * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. | ||
| 115 | */ | ||
| 116 | bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 117 | |||
| 118 | /** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be | ||
| 119 | * linked to the library \ref EVENT_USB_Device_ControlRequest() event. | ||
| 120 | * | ||
| 121 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state. | ||
| 122 | */ | ||
| 123 | void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 124 | |||
| 125 | /** General management task for a given RNDIS class interface, required for the correct operation of the interface. This should | ||
| 126 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 127 | * | ||
| 128 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state. | ||
| 129 | */ | ||
| 130 | void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 131 | |||
| 132 | /** Determines if a packet is currently waiting for the device to read in and process. | ||
| 133 | * | ||
| 134 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the | ||
| 135 | * call will fail. | ||
| 136 | * | ||
| 137 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. | ||
| 138 | * | ||
| 139 | * \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise. | ||
| 140 | */ | ||
| 141 | bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 142 | |||
| 143 | /** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave | ||
| 144 | * only the packet contents for processing by the device in the nominated buffer. | ||
| 145 | * | ||
| 146 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the | ||
| 147 | * call will fail. | ||
| 148 | * | ||
| 149 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. | ||
| 150 | * \param[out] Buffer Pointer to a buffer where the packer data is to be written to. | ||
| 151 | * \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored. | ||
| 152 | * | ||
| 153 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 154 | */ | ||
| 155 | uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 156 | void* Buffer, | ||
| 157 | uint16_t* const PacketLength) ATTR_NON_NULL_PTR_ARG(1); | ||
| 158 | |||
| 159 | /** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header. | ||
| 160 | * | ||
| 161 | * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the | ||
| 162 | * call will fail. | ||
| 163 | * | ||
| 164 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. | ||
| 165 | * \param[in] Buffer Pointer to a buffer where the packer data is to be read from. | ||
| 166 | * \param[in] PacketLength Length in bytes of the packet to send. | ||
| 167 | * | ||
| 168 | * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. | ||
| 169 | */ | ||
| 170 | uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 171 | void* Buffer, | ||
| 172 | const uint16_t PacketLength) ATTR_NON_NULL_PTR_ARG(1); | ||
| 173 | |||
| 174 | /* Private Interface - For use in library only: */ | ||
| 175 | #if !defined(__DOXYGEN__) | ||
| 176 | /* Macros: */ | ||
| 177 | #define RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_Query_Complete_t) | ||
| 178 | |||
| 179 | /* Function Prototypes: */ | ||
| 180 | #if defined(__INCLUDE_FROM_RNDIS_DEVICE_C) | ||
| 181 | static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) | ||
| 182 | ATTR_NON_NULL_PTR_ARG(1); | ||
| 183 | static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 184 | const uint32_t OId, | ||
| 185 | void* const QueryData, | ||
| 186 | const uint16_t QuerySize, | ||
| 187 | void* ResponseData, | ||
| 188 | uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1) | ||
| 189 | ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6); | ||
| 190 | static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, | ||
| 191 | const uint32_t OId, | ||
| 192 | const void* SetData, | ||
| 193 | const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1) | ||
| 194 | ATTR_NON_NULL_PTR_ARG(3); | ||
| 195 | #endif | ||
| 196 | |||
| 197 | #endif | ||
| 198 | |||
| 199 | /* Disable C linkage for C++ Compilers: */ | ||
| 200 | #if defined(__cplusplus) | ||
| 201 | } | ||
| 202 | #endif | ||
| 203 | |||
| 204 | #endif | ||
| 205 | |||
| 206 | /** @} */ | ||
| 207 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/HIDClass.h b/lib/lufa/LUFA/Drivers/USB/Class/HIDClass.h new file mode 100644 index 000000000..158eb256b --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/HIDClass.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB HID Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB HID Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassHID HID Class Driver | ||
| 42 | * \brief USB class driver for the USB-IF Human Interface Device (HID) class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassHID_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * - LUFA/Drivers/USB/Class/Host/HIDClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 48 | * - LUFA/Drivers/USB/Class/Host/HIDParser.c <i>(Makefile source module name: LUFA_SRC_USB)</i> | ||
| 49 | * | ||
| 50 | * \section Sec_USBClassHID_ModDescription Module Description | ||
| 51 | * HID Class Driver module. This module contains an internal implementation of the USB HID Class, for both Device | ||
| 52 | * and Host USB modes. User applications can use this class driver instead of implementing the HID class manually | ||
| 53 | * via the low-level LUFA APIs. | ||
| 54 | * | ||
| 55 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 56 | * Hosts or Devices using the USB HID Class. | ||
| 57 | * | ||
| 58 | * @{ | ||
| 59 | */ | ||
| 60 | |||
| 61 | #ifndef _HID_CLASS_H_ | ||
| 62 | #define _HID_CLASS_H_ | ||
| 63 | |||
| 64 | /* Macros: */ | ||
| 65 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 66 | #define __INCLUDE_FROM_HID_DRIVER | ||
| 67 | |||
| 68 | /* Includes: */ | ||
| 69 | #include "../Core/USBMode.h" | ||
| 70 | |||
| 71 | #if defined(USB_CAN_BE_DEVICE) | ||
| 72 | #include "Device/HIDClassDevice.h" | ||
| 73 | #endif | ||
| 74 | |||
| 75 | #if defined(USB_CAN_BE_HOST) | ||
| 76 | #include "Host/HIDClassHost.h" | ||
| 77 | #endif | ||
| 78 | |||
| 79 | #endif | ||
| 80 | |||
| 81 | /** @} */ | ||
| 82 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c new file mode 100644 index 000000000..ea8903366 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c | |||
| @@ -0,0 +1,422 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_AOA_DRIVER | ||
| 37 | #define __INCLUDE_FROM_ANDROIDACCESSORY_HOST_C | ||
| 38 | #include "AndroidAccessoryClassHost.h" | ||
| 39 | |||
| 40 | bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 41 | const USB_Descriptor_Device_t* const DeviceDescriptor, | ||
| 42 | bool* const NeedModeSwitch) | ||
| 43 | { | ||
| 44 | (void)AOAInterfaceInfo; | ||
| 45 | |||
| 46 | if (DeviceDescriptor->Header.Type != DTYPE_Device) | ||
| 47 | return false; | ||
| 48 | |||
| 49 | *NeedModeSwitch = ((DeviceDescriptor->ProductID != ANDROID_ACCESSORY_PRODUCT_ID) && | ||
| 50 | (DeviceDescriptor->ProductID != ANDROID_ACCESSORY_ADB_PRODUCT_ID)); | ||
| 51 | |||
| 52 | return true; | ||
| 53 | } | ||
| 54 | |||
| 55 | uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 56 | uint16_t ConfigDescriptorSize, | ||
| 57 | void* ConfigDescriptorData) | ||
| 58 | { | ||
| 59 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 60 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 61 | USB_Descriptor_Interface_t* AOAInterface = NULL; | ||
| 62 | |||
| 63 | memset(&AOAInterfaceInfo->State, 0x00, sizeof(AOAInterfaceInfo->State)); | ||
| 64 | |||
| 65 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 66 | return AOA_ENUMERROR_InvalidConfigDescriptor; | ||
| 67 | |||
| 68 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 69 | DCOMP_AOA_Host_NextAndroidAccessoryInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 70 | { | ||
| 71 | return AOA_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 72 | } | ||
| 73 | |||
| 74 | AOAInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 75 | |||
| 76 | while (!(DataINEndpoint) || !(DataOUTEndpoint)) | ||
| 77 | { | ||
| 78 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 79 | DCOMP_AOA_Host_NextInterfaceBulkEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 80 | { | ||
| 81 | return AOA_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 82 | } | ||
| 83 | |||
| 84 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 85 | |||
| 86 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 87 | DataINEndpoint = EndpointData; | ||
| 88 | else | ||
| 89 | DataOUTEndpoint = EndpointData; | ||
| 90 | } | ||
| 91 | |||
| 92 | AOAInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 93 | AOAInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 94 | AOAInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; | ||
| 95 | |||
| 96 | AOAInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 97 | AOAInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 98 | AOAInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; | ||
| 99 | |||
| 100 | if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataINPipe, 1))) | ||
| 101 | return AOA_ENUMERROR_PipeConfigurationFailed; | ||
| 102 | |||
| 103 | if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 104 | return AOA_ENUMERROR_PipeConfigurationFailed; | ||
| 105 | |||
| 106 | AOAInterfaceInfo->State.IsActive = true; | ||
| 107 | AOAInterfaceInfo->State.InterfaceNumber = AOAInterface->InterfaceNumber; | ||
| 108 | |||
| 109 | return AOA_ENUMERROR_NoError; | ||
| 110 | } | ||
| 111 | |||
| 112 | static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) | ||
| 113 | { | ||
| 114 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 115 | |||
| 116 | if (Header->Type == DTYPE_Interface) | ||
| 117 | { | ||
| 118 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 119 | |||
| 120 | if ((Interface->Class == AOA_CSCP_AOADataClass) && | ||
| 121 | (Interface->SubClass == AOA_CSCP_AOADataSubclass) && | ||
| 122 | (Interface->Protocol == AOA_CSCP_AOADataProtocol)) | ||
| 123 | { | ||
| 124 | return DESCRIPTOR_SEARCH_Found; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 129 | } | ||
| 130 | |||
| 131 | static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) | ||
| 132 | { | ||
| 133 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 134 | |||
| 135 | if (Header->Type == DTYPE_Endpoint) | ||
| 136 | { | ||
| 137 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 138 | |||
| 139 | uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); | ||
| 140 | |||
| 141 | if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) | ||
| 142 | return DESCRIPTOR_SEARCH_Found; | ||
| 143 | } | ||
| 144 | else if (Header->Type == DTYPE_Interface) | ||
| 145 | { | ||
| 146 | return DESCRIPTOR_SEARCH_Fail; | ||
| 147 | } | ||
| 148 | |||
| 149 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 150 | } | ||
| 151 | |||
| 152 | void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) | ||
| 153 | { | ||
| 154 | if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) | ||
| 155 | return; | ||
| 156 | |||
| 157 | #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) | ||
| 158 | AOA_Host_Flush(AOAInterfaceInfo); | ||
| 159 | #endif | ||
| 160 | } | ||
| 161 | |||
| 162 | uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) | ||
| 163 | { | ||
| 164 | uint8_t ErrorCode; | ||
| 165 | |||
| 166 | uint16_t AccessoryProtocol; | ||
| 167 | if ((ErrorCode = AOA_Host_GetAccessoryProtocol(&AccessoryProtocol)) != HOST_WAITERROR_Successful) | ||
| 168 | return ErrorCode; | ||
| 169 | |||
| 170 | if ((AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV1)) && (AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV2))) | ||
| 171 | return AOA_ERROR_LOGICAL_CMD_FAILED; | ||
| 172 | |||
| 173 | for (uint8_t PropertyIndex = 0; PropertyIndex < AOA_STRING_TOTAL_STRINGS; PropertyIndex++) | ||
| 174 | { | ||
| 175 | if ((ErrorCode = AOA_Host_SendPropertyString(AOAInterfaceInfo, PropertyIndex)) != HOST_WAITERROR_Successful) | ||
| 176 | return ErrorCode; | ||
| 177 | } | ||
| 178 | |||
| 179 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 180 | { | ||
| 181 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), | ||
| 182 | .bRequest = AOA_REQ_StartAccessoryMode, | ||
| 183 | .wValue = 0, | ||
| 184 | .wIndex = 0, | ||
| 185 | .wLength = 0, | ||
| 186 | }; | ||
| 187 | |||
| 188 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 189 | return USB_Host_SendControlRequest(NULL); | ||
| 190 | } | ||
| 191 | |||
| 192 | static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) | ||
| 193 | { | ||
| 194 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 195 | { | ||
| 196 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE), | ||
| 197 | .bRequest = AOA_REQ_GetAccessoryProtocol, | ||
| 198 | .wValue = 0, | ||
| 199 | .wIndex = 0, | ||
| 200 | .wLength = sizeof(uint16_t), | ||
| 201 | }; | ||
| 202 | |||
| 203 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 204 | return USB_Host_SendControlRequest(Protocol); | ||
| 205 | } | ||
| 206 | |||
| 207 | static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 208 | const uint8_t StringIndex) | ||
| 209 | { | ||
| 210 | const char* String = AOAInterfaceInfo->Config.PropertyStrings[StringIndex]; | ||
| 211 | |||
| 212 | if (String == NULL) | ||
| 213 | String = ""; | ||
| 214 | |||
| 215 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 216 | { | ||
| 217 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), | ||
| 218 | .bRequest = AOA_REQ_SendString, | ||
| 219 | .wValue = 0, | ||
| 220 | .wIndex = StringIndex, | ||
| 221 | .wLength = (strlen(String) + 1), | ||
| 222 | }; | ||
| 223 | |||
| 224 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 225 | return USB_Host_SendControlRequest((char*)String); | ||
| 226 | } | ||
| 227 | |||
| 228 | uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 229 | const void* const Buffer, | ||
| 230 | const uint16_t Length) | ||
| 231 | { | ||
| 232 | if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) | ||
| 233 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 234 | |||
| 235 | uint8_t ErrorCode; | ||
| 236 | |||
| 237 | Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 238 | |||
| 239 | Pipe_Unfreeze(); | ||
| 240 | ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); | ||
| 241 | Pipe_Freeze(); | ||
| 242 | |||
| 243 | return ErrorCode; | ||
| 244 | } | ||
| 245 | |||
| 246 | uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 247 | const char* const String) | ||
| 248 | { | ||
| 249 | if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) | ||
| 250 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 251 | |||
| 252 | uint8_t ErrorCode; | ||
| 253 | |||
| 254 | Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 255 | |||
| 256 | Pipe_Unfreeze(); | ||
| 257 | ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); | ||
| 258 | Pipe_Freeze(); | ||
| 259 | |||
| 260 | return ErrorCode; | ||
| 261 | } | ||
| 262 | |||
| 263 | uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 264 | const uint8_t Data) | ||
| 265 | { | ||
| 266 | if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) | ||
| 267 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 268 | |||
| 269 | uint8_t ErrorCode; | ||
| 270 | |||
| 271 | Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 272 | Pipe_Unfreeze(); | ||
| 273 | |||
| 274 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 275 | { | ||
| 276 | Pipe_ClearOUT(); | ||
| 277 | |||
| 278 | if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) | ||
| 279 | return ErrorCode; | ||
| 280 | } | ||
| 281 | |||
| 282 | Pipe_Write_8(Data); | ||
| 283 | Pipe_Freeze(); | ||
| 284 | |||
| 285 | return PIPE_READYWAIT_NoError; | ||
| 286 | } | ||
| 287 | |||
| 288 | uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) | ||
| 289 | { | ||
| 290 | if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) | ||
| 291 | return 0; | ||
| 292 | |||
| 293 | Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); | ||
| 294 | Pipe_Unfreeze(); | ||
| 295 | |||
| 296 | if (Pipe_IsINReceived()) | ||
| 297 | { | ||
| 298 | if (!(Pipe_BytesInPipe())) | ||
| 299 | { | ||
| 300 | Pipe_ClearIN(); | ||
| 301 | Pipe_Freeze(); | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | else | ||
| 305 | { | ||
| 306 | Pipe_Freeze(); | ||
| 307 | return Pipe_BytesInPipe(); | ||
| 308 | } | ||
| 309 | } | ||
| 310 | else | ||
| 311 | { | ||
| 312 | Pipe_Freeze(); | ||
| 313 | |||
| 314 | return 0; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) | ||
| 319 | { | ||
| 320 | if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) | ||
| 321 | return -1; | ||
| 322 | |||
| 323 | int16_t ReceivedByte = -1; | ||
| 324 | |||
| 325 | Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); | ||
| 326 | Pipe_Unfreeze(); | ||
| 327 | |||
| 328 | if (Pipe_IsINReceived()) | ||
| 329 | { | ||
| 330 | if (Pipe_BytesInPipe()) | ||
| 331 | ReceivedByte = Pipe_Read_8(); | ||
| 332 | |||
| 333 | if (!(Pipe_BytesInPipe())) | ||
| 334 | Pipe_ClearIN(); | ||
| 335 | } | ||
| 336 | |||
| 337 | Pipe_Freeze(); | ||
| 338 | |||
| 339 | return ReceivedByte; | ||
| 340 | } | ||
| 341 | |||
| 342 | uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) | ||
| 343 | { | ||
| 344 | if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) | ||
| 345 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 346 | |||
| 347 | uint8_t ErrorCode; | ||
| 348 | |||
| 349 | Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 350 | Pipe_Unfreeze(); | ||
| 351 | |||
| 352 | if (!(Pipe_BytesInPipe())) | ||
| 353 | return PIPE_READYWAIT_NoError; | ||
| 354 | |||
| 355 | bool BankFull = !(Pipe_IsReadWriteAllowed()); | ||
| 356 | |||
| 357 | Pipe_ClearOUT(); | ||
| 358 | |||
| 359 | if (BankFull) | ||
| 360 | { | ||
| 361 | if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) | ||
| 362 | return ErrorCode; | ||
| 363 | |||
| 364 | Pipe_ClearOUT(); | ||
| 365 | } | ||
| 366 | |||
| 367 | Pipe_Freeze(); | ||
| 368 | |||
| 369 | return PIPE_READYWAIT_NoError; | ||
| 370 | } | ||
| 371 | |||
| 372 | #if defined(FDEV_SETUP_STREAM) | ||
| 373 | void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 374 | FILE* const Stream) | ||
| 375 | { | ||
| 376 | *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar, _FDEV_SETUP_RW); | ||
| 377 | fdev_set_udata(Stream, AOAInterfaceInfo); | ||
| 378 | } | ||
| 379 | |||
| 380 | void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 381 | FILE* const Stream) | ||
| 382 | { | ||
| 383 | *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar_Blocking, _FDEV_SETUP_RW); | ||
| 384 | fdev_set_udata(Stream, AOAInterfaceInfo); | ||
| 385 | } | ||
| 386 | |||
| 387 | static int AOA_Host_putchar(char c, | ||
| 388 | FILE* Stream) | ||
| 389 | { | ||
| 390 | return AOA_Host_SendByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; | ||
| 391 | } | ||
| 392 | |||
| 393 | static int AOA_Host_getchar(FILE* Stream) | ||
| 394 | { | ||
| 395 | int16_t ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); | ||
| 396 | |||
| 397 | if (ReceivedByte < 0) | ||
| 398 | return _FDEV_EOF; | ||
| 399 | |||
| 400 | return ReceivedByte; | ||
| 401 | } | ||
| 402 | |||
| 403 | static int AOA_Host_getchar_Blocking(FILE* Stream) | ||
| 404 | { | ||
| 405 | int16_t ReceivedByte; | ||
| 406 | |||
| 407 | while ((ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream))) < 0) | ||
| 408 | { | ||
| 409 | if (USB_HostState == HOST_STATE_Unattached) | ||
| 410 | return _FDEV_EOF; | ||
| 411 | |||
| 412 | AOA_Host_USBTask((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); | ||
| 413 | USB_USBTask(); | ||
| 414 | } | ||
| 415 | |||
| 416 | return ReceivedByte; | ||
| 417 | } | ||
| 418 | #endif | ||
| 419 | |||
| 420 | #endif | ||
| 421 | |||
| 422 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h new file mode 100644 index 000000000..f4f04e445 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h | |||
| @@ -0,0 +1,314 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB Android Open Accessory Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB Android Open Accessory Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassAOA | ||
| 41 | * \defgroup Group_USBClassAndroidAccessoryHost Android Open Accessory Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassAndroidAccessoryHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassAndroidAccessoryHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the Android Open Accessory USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __AOA_CLASS_HOST_H__ | ||
| 54 | #define __AOA_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/AndroidAccessoryClassCommon.h" | ||
| 59 | |||
| 60 | #include <stdio.h> | ||
| 61 | |||
| 62 | /* Enable C linkage for C++ Compilers: */ | ||
| 63 | #if defined(__cplusplus) | ||
| 64 | extern "C" { | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* Preprocessor Checks: */ | ||
| 68 | #if !defined(__INCLUDE_FROM_AOA_DRIVER) | ||
| 69 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 70 | #endif | ||
| 71 | |||
| 72 | /* Public Interface - May be used in end-application: */ | ||
| 73 | /* Macros: */ | ||
| 74 | /** Error code for some Android Open Accessory Host functions, indicating a logical (and not hardware) error. */ | ||
| 75 | #define AOA_ERROR_LOGICAL_CMD_FAILED 0x80 | ||
| 76 | |||
| 77 | /* Type Defines: */ | ||
| 78 | /** \brief Android Open Accessory Class Host Mode Configuration and State Structure. | ||
| 79 | * | ||
| 80 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 81 | * and passed to each of the Android Open Accessory class driver functions as the \c AOAInterfaceInfo | ||
| 82 | * parameter. This stores each Android Open Accessory interface's configuration and state information. | ||
| 83 | */ | ||
| 84 | typedef struct | ||
| 85 | { | ||
| 86 | struct | ||
| 87 | { | ||
| 88 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 89 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 90 | |||
| 91 | char* PropertyStrings[AOA_STRING_TOTAL_STRINGS]; /**< Android Accessory property strings, sent to identify the accessory when the | ||
| 92 | * Android device is switched into Open Accessory mode. */ | ||
| 93 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 94 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 95 | */ | ||
| 96 | struct | ||
| 97 | { | ||
| 98 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 99 | * after \ref AOA_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 100 | * Configured state. | ||
| 101 | */ | ||
| 102 | uint8_t InterfaceNumber; /**< Interface index of the AOA interface within the attached device. */ | ||
| 103 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 104 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 105 | * the interface is enumerated. | ||
| 106 | */ | ||
| 107 | } USB_ClassInfo_AOA_Host_t; | ||
| 108 | |||
| 109 | /* Enums: */ | ||
| 110 | /** Enum for the possible error codes returned by the \ref AOA_Host_ConfigurePipes() function. */ | ||
| 111 | enum AOA_Host_EnumerationFailure_ErrorCodes_t | ||
| 112 | { | ||
| 113 | AOA_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 114 | AOA_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 115 | AOA_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Android Open Accessory interface was not found in the device's Configuration Descriptor. */ | ||
| 116 | AOA_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 117 | }; | ||
| 118 | |||
| 119 | /* Function Prototypes: */ | ||
| 120 | /** General management task for a given Android Open Accessory host class interface, required for the correct operation of the interface. | ||
| 121 | * This should be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 122 | * | ||
| 123 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an Android Open Accessory Class host configuration and state. | ||
| 124 | */ | ||
| 125 | void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 126 | |||
| 127 | /** Validates a device descriptor, to check if the device is a valid Android device, and if it is currently in Android Open Accessory mode. | ||
| 128 | * | ||
| 129 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. | ||
| 130 | * \param[in] DeviceDescriptor Pointer a buffer containing the attached device's Device Descriptor. | ||
| 131 | * \param[out] NeedModeSwitch Pointer to a boolean where the mode switch requirement of the attached device is to be stored. | ||
| 132 | * | ||
| 133 | * \return Boolean \c true if the attached device is a valid Android device, \c false otherwise. | ||
| 134 | */ | ||
| 135 | bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 136 | const USB_Descriptor_Device_t* const DeviceDescriptor, | ||
| 137 | bool* const NeedModeSwitch) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); | ||
| 138 | |||
| 139 | /** Host interface configuration routine, to configure a given Android Open Accessory host interface instance using the Configuration | ||
| 140 | * Descriptor read from an attached USB device. This function automatically updates the given Android Open Accessory Host instance's | ||
| 141 | * state values and configures the pipes required to communicate with the interface if it is found within the device. This should be | ||
| 142 | * called once after the stack has enumerated the attached device, while the host state machine is in the Addressed state. | ||
| 143 | * | ||
| 144 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. | ||
| 145 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 146 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 147 | * | ||
| 148 | * \return A value from the \ref AOA_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 149 | */ | ||
| 150 | uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 151 | uint16_t ConfigDescriptorSize, | ||
| 152 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 153 | |||
| 154 | /** Starts Accessory Mode in the attached Android device. This function will validate the device's Android Open Accessory protocol | ||
| 155 | * version, send the configured property strings, and request a switch to Android Open Accessory mode. | ||
| 156 | * | ||
| 157 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. | ||
| 158 | * | ||
| 159 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum, or \ref AOA_ERROR_LOGICAL_CMD_FAILED if a logical error occurred.. | ||
| 160 | */ | ||
| 161 | uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 162 | |||
| 163 | /** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is | ||
| 164 | * called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank | ||
| 165 | * becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows for | ||
| 166 | * multiple bytes to be packed into a single pipe packet, increasing data throughput. | ||
| 167 | * | ||
| 168 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 169 | * call will fail. | ||
| 170 | * | ||
| 171 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. | ||
| 172 | * \param[in] Buffer Pointer to a buffer containing the data to send to the device. | ||
| 173 | * \param[in] Length Length of the data to send to the device. | ||
| 174 | * | ||
| 175 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 176 | */ | ||
| 177 | uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 178 | const void* const Buffer, | ||
| 179 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); | ||
| 180 | |||
| 181 | /** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the | ||
| 182 | * function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe | ||
| 183 | * bank becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows | ||
| 184 | * for multiple bytes to be packed into a single pipe packet, increasing data throughput. | ||
| 185 | * | ||
| 186 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 187 | * call will fail. | ||
| 188 | * | ||
| 189 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. | ||
| 190 | * \param[in] String Pointer to the null terminated string to send to the device. | ||
| 191 | * | ||
| 192 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 193 | */ | ||
| 194 | uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 195 | const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 196 | |||
| 197 | /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the | ||
| 198 | * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the | ||
| 199 | * \ref AOA_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be | ||
| 200 | * packed into a single pipe packet, increasing data throughput. | ||
| 201 | * | ||
| 202 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 203 | * call will fail. | ||
| 204 | * | ||
| 205 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. | ||
| 206 | * \param[in] Data Byte of data to send to the device. | ||
| 207 | * | ||
| 208 | * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. | ||
| 209 | */ | ||
| 210 | uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 211 | const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); | ||
| 212 | |||
| 213 | /** Determines the number of bytes received by the AOA interface from the device, waiting to be read. This indicates the number | ||
| 214 | * of bytes in the IN pipe bank only, and thus the number of calls to \ref AOA_Host_ReceiveByte() which are guaranteed to succeed | ||
| 215 | * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be | ||
| 216 | * released back to the USB controller until all bytes are read. | ||
| 217 | * | ||
| 218 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 219 | * call will fail. | ||
| 220 | * | ||
| 221 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. | ||
| 222 | * | ||
| 223 | * \return Total number of buffered bytes received from the device. | ||
| 224 | */ | ||
| 225 | uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 226 | |||
| 227 | /** 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 | ||
| 228 | * returns a negative value. The \ref AOA_Host_BytesReceived() function may be queried in advance to determine how many bytes | ||
| 229 | * are currently buffered in the AOA interface's data receive pipe. | ||
| 230 | * | ||
| 231 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 232 | * call will fail. | ||
| 233 | * | ||
| 234 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. | ||
| 235 | * | ||
| 236 | * \return Next received byte from the device, or a negative value if no data received. | ||
| 237 | */ | ||
| 238 | int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 239 | |||
| 240 | /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. | ||
| 241 | * | ||
| 242 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 243 | * call will fail. | ||
| 244 | * | ||
| 245 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. | ||
| 246 | * | ||
| 247 | * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. | ||
| 248 | */ | ||
| 249 | uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 250 | |||
| 251 | /** Creates a standard character stream for the given AOA Device instance so that it can be used with all the regular | ||
| 252 | * functions in the standard \c <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created | ||
| 253 | * stream is bidirectional and can be used for both input and output functions. | ||
| 254 | * | ||
| 255 | * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single | ||
| 256 | * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may | ||
| 257 | * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own | ||
| 258 | * line buffering. | ||
| 259 | * | ||
| 260 | * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions | ||
| 261 | * to the given AOA interface. | ||
| 262 | * \n\n | ||
| 263 | * | ||
| 264 | * \note This function is not available on all microcontroller architectures. | ||
| 265 | * | ||
| 266 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. | ||
| 267 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 268 | */ | ||
| 269 | void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 270 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 271 | |||
| 272 | /** Identical to \ref AOA_Host_CreateStream(), except that reads are blocking until the calling stream function terminates | ||
| 273 | * the transfer. While blocking, the USB and AOA service tasks are called repeatedly to maintain USB communications. | ||
| 274 | * | ||
| 275 | * \note This function is not available on all microcontroller architectures. | ||
| 276 | * | ||
| 277 | * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. | ||
| 278 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 279 | */ | ||
| 280 | void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 281 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 282 | |||
| 283 | /* Private Interface - For use in library only: */ | ||
| 284 | #if !defined(__DOXYGEN__) | ||
| 285 | /* Function Prototypes: */ | ||
| 286 | #if defined(__INCLUDE_FROM_ANDROIDACCESSORY_HOST_C) | ||
| 287 | #if defined(FDEV_SETUP_STREAM) | ||
| 288 | static int AOA_Host_putchar(char c, | ||
| 289 | FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); | ||
| 290 | static int AOA_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 291 | static int AOA_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 292 | #endif | ||
| 293 | |||
| 294 | static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) ATTR_NON_NULL_PTR_ARG(1); | ||
| 295 | static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, | ||
| 296 | const uint8_t StringIndex) ATTR_NON_NULL_PTR_ARG(1); | ||
| 297 | |||
| 298 | static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) | ||
| 299 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 300 | static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) | ||
| 301 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 302 | #endif | ||
| 303 | #endif | ||
| 304 | |||
| 305 | /* Disable C linkage for C++ Compilers: */ | ||
| 306 | #if defined(__cplusplus) | ||
| 307 | } | ||
| 308 | #endif | ||
| 309 | |||
| 310 | #endif | ||
| 311 | |||
| 312 | /** @} */ | ||
| 313 | |||
| 314 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/AudioClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/AudioClassHost.c new file mode 100644 index 000000000..9f1a6dc2c --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/AudioClassHost.c | |||
| @@ -0,0 +1,223 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_AUDIO_DRIVER | ||
| 37 | #define __INCLUDE_FROM_AUDIO_HOST_C | ||
| 38 | #include "AudioClassHost.h" | ||
| 39 | |||
| 40 | uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Interface_t* AudioControlInterface = NULL; | ||
| 47 | USB_Descriptor_Interface_t* AudioStreamingInterface = NULL; | ||
| 48 | |||
| 49 | memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State)); | ||
| 50 | |||
| 51 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 52 | return AUDIO_ENUMERROR_InvalidConfigDescriptor; | ||
| 53 | |||
| 54 | while ((AudioInterfaceInfo->Config.DataINPipe.Address && !(DataINEndpoint)) || | ||
| 55 | (AudioInterfaceInfo->Config.DataOUTPipe.Address && !(DataOUTEndpoint))) | ||
| 56 | { | ||
| 57 | if (!(AudioControlInterface) || | ||
| 58 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 59 | DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 60 | { | ||
| 61 | if (!(AudioControlInterface) || | ||
| 62 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 63 | DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 64 | { | ||
| 65 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 66 | DCOMP_Audio_Host_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 67 | { | ||
| 68 | return AUDIO_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 69 | } | ||
| 70 | |||
| 71 | AudioControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 72 | |||
| 73 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 74 | DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 75 | { | ||
| 76 | return AUDIO_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | AudioStreamingInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 81 | |||
| 82 | DataINEndpoint = NULL; | ||
| 83 | DataOUTEndpoint = NULL; | ||
| 84 | |||
| 85 | continue; | ||
| 86 | } | ||
| 87 | |||
| 88 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 89 | |||
| 90 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 91 | DataINEndpoint = EndpointData; | ||
| 92 | else | ||
| 93 | DataOUTEndpoint = EndpointData; | ||
| 94 | } | ||
| 95 | |||
| 96 | AudioInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 97 | AudioInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 98 | AudioInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_ISOCHRONOUS; | ||
| 99 | AudioInterfaceInfo->Config.DataINPipe.Banks = 2; | ||
| 100 | |||
| 101 | AudioInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 102 | AudioInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 103 | AudioInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_ISOCHRONOUS; | ||
| 104 | AudioInterfaceInfo->Config.DataOUTPipe.Banks = 2; | ||
| 105 | |||
| 106 | if (!(Pipe_ConfigurePipeTable(&AudioInterfaceInfo->Config.DataINPipe, 1))) | ||
| 107 | return AUDIO_ENUMERROR_PipeConfigurationFailed; | ||
| 108 | |||
| 109 | if (!(Pipe_ConfigurePipeTable(&AudioInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 110 | return AUDIO_ENUMERROR_PipeConfigurationFailed; | ||
| 111 | |||
| 112 | AudioInterfaceInfo->State.ControlInterfaceNumber = AudioControlInterface->InterfaceNumber; | ||
| 113 | AudioInterfaceInfo->State.StreamingInterfaceNumber = AudioStreamingInterface->InterfaceNumber; | ||
| 114 | AudioInterfaceInfo->State.EnabledStreamingAltIndex = AudioStreamingInterface->AlternateSetting; | ||
| 115 | AudioInterfaceInfo->State.IsActive = true; | ||
| 116 | |||
| 117 | return AUDIO_ENUMERROR_NoError; | ||
| 118 | } | ||
| 119 | |||
| 120 | static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor) | ||
| 121 | { | ||
| 122 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 123 | |||
| 124 | if (Header->Type == DTYPE_Interface) | ||
| 125 | { | ||
| 126 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 127 | |||
| 128 | if ((Interface->Class == AUDIO_CSCP_AudioClass) && | ||
| 129 | (Interface->SubClass == AUDIO_CSCP_ControlSubclass) && | ||
| 130 | (Interface->Protocol == AUDIO_CSCP_ControlProtocol)) | ||
| 131 | { | ||
| 132 | return DESCRIPTOR_SEARCH_Found; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 137 | } | ||
| 138 | |||
| 139 | static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor) | ||
| 140 | { | ||
| 141 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 142 | |||
| 143 | if (Header->Type == DTYPE_Interface) | ||
| 144 | { | ||
| 145 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 146 | |||
| 147 | if ((Interface->Class == AUDIO_CSCP_AudioClass) && | ||
| 148 | (Interface->SubClass == AUDIO_CSCP_AudioStreamingSubclass) && | ||
| 149 | (Interface->Protocol == AUDIO_CSCP_StreamingProtocol)) | ||
| 150 | { | ||
| 151 | return DESCRIPTOR_SEARCH_Found; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 156 | } | ||
| 157 | |||
| 158 | static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor) | ||
| 159 | { | ||
| 160 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 161 | |||
| 162 | if (Header->Type == DTYPE_Endpoint) | ||
| 163 | { | ||
| 164 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 165 | |||
| 166 | if ((Endpoint->Attributes & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) | ||
| 167 | return DESCRIPTOR_SEARCH_Found; | ||
| 168 | } | ||
| 169 | else if (Header->Type == DTYPE_Interface) | ||
| 170 | { | ||
| 171 | return DESCRIPTOR_SEARCH_Fail; | ||
| 172 | } | ||
| 173 | |||
| 174 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 175 | } | ||
| 176 | |||
| 177 | uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 178 | const bool EnableStreaming) | ||
| 179 | { | ||
| 180 | if (!(AudioInterfaceInfo->State.IsActive)) | ||
| 181 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 182 | |||
| 183 | return USB_Host_SetInterfaceAltSetting(AudioInterfaceInfo->State.StreamingInterfaceNumber, | ||
| 184 | EnableStreaming ? AudioInterfaceInfo->State.EnabledStreamingAltIndex : 0); | ||
| 185 | } | ||
| 186 | |||
| 187 | uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 188 | const uint8_t DataPipeIndex, | ||
| 189 | const uint8_t EndpointProperty, | ||
| 190 | const uint8_t EndpointControl, | ||
| 191 | const uint16_t DataLength, | ||
| 192 | void* const Data) | ||
| 193 | { | ||
| 194 | if (!(AudioInterfaceInfo->State.IsActive)) | ||
| 195 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 196 | |||
| 197 | uint8_t RequestType; | ||
| 198 | uint8_t EndpointAddress; | ||
| 199 | |||
| 200 | if (EndpointProperty & 0x80) | ||
| 201 | RequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT); | ||
| 202 | else | ||
| 203 | RequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT); | ||
| 204 | |||
| 205 | Pipe_SelectPipe(DataPipeIndex); | ||
| 206 | EndpointAddress = Pipe_GetBoundEndpointAddress(); | ||
| 207 | |||
| 208 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 209 | { | ||
| 210 | .bmRequestType = RequestType, | ||
| 211 | .bRequest = EndpointProperty, | ||
| 212 | .wValue = ((uint16_t)EndpointControl << 8), | ||
| 213 | .wIndex = EndpointAddress, | ||
| 214 | .wLength = DataLength, | ||
| 215 | }; | ||
| 216 | |||
| 217 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 218 | |||
| 219 | return USB_Host_SendControlRequest(Data); | ||
| 220 | } | ||
| 221 | |||
| 222 | #endif | ||
| 223 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/AudioClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/AudioClassHost.h new file mode 100644 index 000000000..f1f4207f1 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/AudioClassHost.h | |||
| @@ -0,0 +1,411 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB Audio 1.0 Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB Audio 1.0 Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassAudio | ||
| 41 | * \defgroup Group_USBClassAudioHost Audio 1.0 Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassAudioHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/AudioClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassAudioHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __AUDIO_CLASS_HOST_H__ | ||
| 54 | #define __AUDIO_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/AudioClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_AUDIO_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Defines: */ | ||
| 72 | /** \brief Audio Class Host Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 75 | * and passed to each of the Audio class driver functions as the \c AudioInterfaceInfo parameter. This | ||
| 76 | * stores each Audio interface's configuration and state information. | ||
| 77 | */ | ||
| 78 | typedef struct | ||
| 79 | { | ||
| 80 | struct | ||
| 81 | { | ||
| 82 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 83 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 84 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 85 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 86 | */ | ||
| 87 | struct | ||
| 88 | { | ||
| 89 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 90 | * after \ref Audio_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 91 | * Configured state. | ||
| 92 | */ | ||
| 93 | uint8_t ControlInterfaceNumber; /**< Interface index of the Audio Control interface within the attached device. */ | ||
| 94 | uint8_t StreamingInterfaceNumber; /**< Interface index of the Audio Streaming interface within the attached device. */ | ||
| 95 | |||
| 96 | uint8_t EnabledStreamingAltIndex; /**< Alternative setting index of the Audio Streaming interface when the stream is enabled. */ | ||
| 97 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 98 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 99 | * the interface is enumerated. | ||
| 100 | */ | ||
| 101 | } USB_ClassInfo_Audio_Host_t; | ||
| 102 | |||
| 103 | /* Enums: */ | ||
| 104 | /** Enum for the possible error codes returned by the \ref Audio_Host_ConfigurePipes() function. */ | ||
| 105 | enum AUDIO_Host_EnumerationFailure_ErrorCodes_t | ||
| 106 | { | ||
| 107 | AUDIO_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 108 | AUDIO_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 109 | AUDIO_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible AUDIO interface was not found in the device's Configuration Descriptor. */ | ||
| 110 | AUDIO_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 111 | }; | ||
| 112 | |||
| 113 | /* Function Prototypes: */ | ||
| 114 | /** Host interface configuration routine, to configure a given Audio host interface instance using the Configuration | ||
| 115 | * Descriptor read from an attached USB device. This function automatically updates the given Audio Host instance's | ||
| 116 | * state values and configures the pipes required to communicate with the interface if it is found within the | ||
| 117 | * device. This should be called once after the stack has enumerated the attached device, while the host state | ||
| 118 | * machine is in the Addressed state. | ||
| 119 | * | ||
| 120 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. | ||
| 121 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 122 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 123 | * | ||
| 124 | * \return A value from the \ref AUDIO_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 125 | */ | ||
| 126 | uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 127 | uint16_t ConfigDescriptorSize, | ||
| 128 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 129 | |||
| 130 | /** Starts or stops the audio streaming for the given configured Audio Host interface, allowing for audio samples to be | ||
| 131 | * send and/or received. | ||
| 132 | * | ||
| 133 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. | ||
| 134 | * \param[in] EnableStreaming Boolean true to enable streaming of the specified interface, \c false to disable | ||
| 135 | * | ||
| 136 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 137 | */ | ||
| 138 | uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 139 | const bool EnableStreaming) ATTR_NON_NULL_PTR_ARG(1); | ||
| 140 | |||
| 141 | /** Gets or sets the specified property of a streaming audio class endpoint that is bound to a pipe in the given | ||
| 142 | * class instance. | ||
| 143 | * | ||
| 144 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. | ||
| 145 | * \param[in] DataPipeIndex Index of the data pipe whose bound endpoint is to be altered. | ||
| 146 | * \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t. | ||
| 147 | * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t. | ||
| 148 | * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum | ||
| 149 | * length of the retrieved data. | ||
| 150 | * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where | ||
| 151 | * the retrieved data is to be stored for GET operations. | ||
| 152 | * | ||
| 153 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 154 | */ | ||
| 155 | uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 156 | const uint8_t DataPipeIndex, | ||
| 157 | const uint8_t EndpointProperty, | ||
| 158 | const uint8_t EndpointControl, | ||
| 159 | const uint16_t DataLength, | ||
| 160 | void* const Data) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6); | ||
| 161 | |||
| 162 | /* Inline Functions: */ | ||
| 163 | /** General management task for a given Audio host class interface, required for the correct operation of | ||
| 164 | * the interface. This should be called frequently in the main program loop, before the master USB management task | ||
| 165 | * \ref USB_USBTask(). | ||
| 166 | * | ||
| 167 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. | ||
| 168 | */ | ||
| 169 | static inline void Audio_Host_USBTask(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 170 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 171 | static inline void Audio_Host_USBTask(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 172 | { | ||
| 173 | (void)AudioInterfaceInfo; | ||
| 174 | } | ||
| 175 | |||
| 176 | /** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming | ||
| 177 | * IN pipe ready for reading. | ||
| 178 | * | ||
| 179 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or | ||
| 180 | * the call will fail. | ||
| 181 | * | ||
| 182 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 183 | * | ||
| 184 | * \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise. | ||
| 185 | */ | ||
| 186 | static inline bool Audio_Host_IsSampleReceived(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 187 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 188 | static inline bool Audio_Host_IsSampleReceived(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 189 | { | ||
| 190 | if ((USB_HostState != HOST_STATE_Configured) || !(AudioInterfaceInfo->State.IsActive)) | ||
| 191 | return false; | ||
| 192 | |||
| 193 | bool SampleReceived = false; | ||
| 194 | |||
| 195 | Pipe_SelectPipe(AudioInterfaceInfo->Config.DataINPipe.Address); | ||
| 196 | Pipe_Unfreeze(); | ||
| 197 | SampleReceived = Pipe_IsINReceived(); | ||
| 198 | Pipe_Freeze(); | ||
| 199 | |||
| 200 | return SampleReceived; | ||
| 201 | } | ||
| 202 | |||
| 203 | /** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects | ||
| 204 | * the streaming OUT pipe ready for writing. | ||
| 205 | * | ||
| 206 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or | ||
| 207 | * the call will fail. | ||
| 208 | * | ||
| 209 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 210 | * | ||
| 211 | * \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise. | ||
| 212 | */ | ||
| 213 | static inline bool Audio_Host_IsReadyForNextSample(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 214 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 215 | static inline bool Audio_Host_IsReadyForNextSample(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 216 | { | ||
| 217 | if ((USB_HostState != HOST_STATE_Configured) || !(AudioInterfaceInfo->State.IsActive)) | ||
| 218 | return false; | ||
| 219 | |||
| 220 | Pipe_SelectPipe(AudioInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 221 | return Pipe_IsOUTReady(); | ||
| 222 | } | ||
| 223 | |||
| 224 | /** Reads the next 8-bit audio sample from the current audio interface. | ||
| 225 | * | ||
| 226 | * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure | ||
| 227 | * that the correct pipe is selected and ready for data. | ||
| 228 | * | ||
| 229 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 230 | * | ||
| 231 | * \return Signed 8-bit audio sample from the audio interface. | ||
| 232 | */ | ||
| 233 | static inline int8_t Audio_Host_ReadSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 234 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 235 | static inline int8_t Audio_Host_ReadSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 236 | { | ||
| 237 | int8_t Sample; | ||
| 238 | |||
| 239 | (void)AudioInterfaceInfo; | ||
| 240 | |||
| 241 | Sample = Pipe_Read_8(); | ||
| 242 | |||
| 243 | if (!(Pipe_BytesInPipe())) | ||
| 244 | { | ||
| 245 | Pipe_Unfreeze(); | ||
| 246 | Pipe_ClearIN(); | ||
| 247 | Pipe_Freeze(); | ||
| 248 | } | ||
| 249 | |||
| 250 | return Sample; | ||
| 251 | } | ||
| 252 | |||
| 253 | /** Reads the next 16-bit audio sample from the current audio interface. | ||
| 254 | * | ||
| 255 | * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure | ||
| 256 | * that the correct pipe is selected and ready for data. | ||
| 257 | * | ||
| 258 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 259 | * | ||
| 260 | * \return Signed 16-bit audio sample from the audio interface. | ||
| 261 | */ | ||
| 262 | static inline int16_t Audio_Host_ReadSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 263 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 264 | static inline int16_t Audio_Host_ReadSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 265 | { | ||
| 266 | int16_t Sample; | ||
| 267 | |||
| 268 | (void)AudioInterfaceInfo; | ||
| 269 | |||
| 270 | Sample = (int16_t)Pipe_Read_16_LE(); | ||
| 271 | |||
| 272 | if (!(Pipe_BytesInPipe())) | ||
| 273 | { | ||
| 274 | Pipe_Unfreeze(); | ||
| 275 | Pipe_ClearIN(); | ||
| 276 | Pipe_Freeze(); | ||
| 277 | } | ||
| 278 | |||
| 279 | return Sample; | ||
| 280 | } | ||
| 281 | |||
| 282 | /** Reads the next 24-bit audio sample from the current audio interface. | ||
| 283 | * | ||
| 284 | * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure | ||
| 285 | * that the correct pipe is selected and ready for data. | ||
| 286 | * | ||
| 287 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 288 | * | ||
| 289 | * \return Signed 24-bit audio sample from the audio interface. | ||
| 290 | */ | ||
| 291 | static inline int32_t Audio_Host_ReadSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 292 | ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 293 | static inline int32_t Audio_Host_ReadSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) | ||
| 294 | { | ||
| 295 | int32_t Sample; | ||
| 296 | |||
| 297 | (void)AudioInterfaceInfo; | ||
| 298 | |||
| 299 | Sample = (((uint32_t)Pipe_Read_8() << 16) | Pipe_Read_16_LE()); | ||
| 300 | |||
| 301 | if (!(Pipe_BytesInPipe())) | ||
| 302 | { | ||
| 303 | Pipe_Unfreeze(); | ||
| 304 | Pipe_ClearIN(); | ||
| 305 | Pipe_Freeze(); | ||
| 306 | } | ||
| 307 | |||
| 308 | return Sample; | ||
| 309 | } | ||
| 310 | |||
| 311 | /** Writes the next 8-bit audio sample to the current audio interface. | ||
| 312 | * | ||
| 313 | * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to | ||
| 314 | * ensure that the correct pipe is selected and ready for data. | ||
| 315 | * | ||
| 316 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 317 | * \param[in] Sample Signed 8-bit audio sample. | ||
| 318 | */ | ||
| 319 | static inline void Audio_Host_WriteSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 320 | const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 321 | static inline void Audio_Host_WriteSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 322 | const int8_t Sample) | ||
| 323 | { | ||
| 324 | (void)AudioInterfaceInfo; | ||
| 325 | |||
| 326 | Pipe_Write_8(Sample); | ||
| 327 | |||
| 328 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 329 | { | ||
| 330 | Pipe_Unfreeze(); | ||
| 331 | Pipe_ClearOUT(); | ||
| 332 | Pipe_WaitUntilReady(); | ||
| 333 | Pipe_Freeze(); | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | /** Writes the next 16-bit audio sample to the current audio interface. | ||
| 338 | * | ||
| 339 | * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to | ||
| 340 | * ensure that the correct pipe is selected and ready for data. | ||
| 341 | * | ||
| 342 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 343 | * \param[in] Sample Signed 16-bit audio sample. | ||
| 344 | */ | ||
| 345 | static inline void Audio_Host_WriteSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 346 | const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 347 | static inline void Audio_Host_WriteSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 348 | const int16_t Sample) | ||
| 349 | { | ||
| 350 | (void)AudioInterfaceInfo; | ||
| 351 | |||
| 352 | Pipe_Write_16_LE(Sample); | ||
| 353 | |||
| 354 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 355 | { | ||
| 356 | Pipe_Unfreeze(); | ||
| 357 | Pipe_ClearOUT(); | ||
| 358 | Pipe_WaitUntilReady(); | ||
| 359 | Pipe_Freeze(); | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | /** Writes the next 24-bit audio sample to the current audio interface. | ||
| 364 | * | ||
| 365 | * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to | ||
| 366 | * ensure that the correct pipe is selected and ready for data. | ||
| 367 | * | ||
| 368 | * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. | ||
| 369 | * \param[in] Sample Signed 24-bit audio sample. | ||
| 370 | */ | ||
| 371 | static inline void Audio_Host_WriteSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 372 | const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 373 | static inline void Audio_Host_WriteSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, | ||
| 374 | const int32_t Sample) | ||
| 375 | { | ||
| 376 | (void)AudioInterfaceInfo; | ||
| 377 | |||
| 378 | Pipe_Write_16_LE(Sample); | ||
| 379 | Pipe_Write_8(Sample >> 16); | ||
| 380 | |||
| 381 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 382 | { | ||
| 383 | Pipe_Unfreeze(); | ||
| 384 | Pipe_ClearOUT(); | ||
| 385 | Pipe_WaitUntilReady(); | ||
| 386 | Pipe_Freeze(); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | /* Private Interface - For use in library only: */ | ||
| 391 | #if !defined(__DOXYGEN__) | ||
| 392 | /* Function Prototypes: */ | ||
| 393 | #if defined(__INCLUDE_FROM_AUDIO_HOST_C) | ||
| 394 | static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor) | ||
| 395 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 396 | static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor) | ||
| 397 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 398 | static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor) | ||
| 399 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 400 | #endif | ||
| 401 | #endif | ||
| 402 | |||
| 403 | /* Disable C linkage for C++ Compilers: */ | ||
| 404 | #if defined(__cplusplus) | ||
| 405 | } | ||
| 406 | #endif | ||
| 407 | |||
| 408 | #endif | ||
| 409 | |||
| 410 | /** @} */ | ||
| 411 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/CDCClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/CDCClassHost.c new file mode 100644 index 000000000..af9ed96e2 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/CDCClassHost.c | |||
| @@ -0,0 +1,512 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_CDC_DRIVER | ||
| 37 | #define __INCLUDE_FROM_CDC_HOST_C | ||
| 38 | #include "CDCClassHost.h" | ||
| 39 | |||
| 40 | uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL; | ||
| 47 | USB_Descriptor_Interface_t* CDCControlInterface = NULL; | ||
| 48 | |||
| 49 | memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State)); | ||
| 50 | |||
| 51 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 52 | return CDC_ENUMERROR_InvalidConfigDescriptor; | ||
| 53 | |||
| 54 | while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint)) | ||
| 55 | { | ||
| 56 | if (!(CDCControlInterface) || | ||
| 57 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 58 | DCOMP_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 59 | { | ||
| 60 | if (NotificationEndpoint) | ||
| 61 | { | ||
| 62 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 63 | DCOMP_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 64 | { | ||
| 65 | return CDC_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 66 | } | ||
| 67 | |||
| 68 | DataINEndpoint = NULL; | ||
| 69 | DataOUTEndpoint = NULL; | ||
| 70 | } | ||
| 71 | else | ||
| 72 | { | ||
| 73 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 74 | DCOMP_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 75 | { | ||
| 76 | return CDC_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 77 | } | ||
| 78 | |||
| 79 | CDCControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 80 | |||
| 81 | NotificationEndpoint = NULL; | ||
| 82 | } | ||
| 83 | |||
| 84 | continue; | ||
| 85 | } | ||
| 86 | |||
| 87 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 88 | |||
| 89 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 90 | { | ||
| 91 | if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) | ||
| 92 | NotificationEndpoint = EndpointData; | ||
| 93 | else | ||
| 94 | DataINEndpoint = EndpointData; | ||
| 95 | } | ||
| 96 | else | ||
| 97 | { | ||
| 98 | DataOUTEndpoint = EndpointData; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | CDCInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 103 | CDCInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 104 | CDCInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; | ||
| 105 | |||
| 106 | CDCInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 107 | CDCInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 108 | CDCInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; | ||
| 109 | |||
| 110 | CDCInterfaceInfo->Config.NotificationPipe.Size = le16_to_cpu(NotificationEndpoint->EndpointSize); | ||
| 111 | CDCInterfaceInfo->Config.NotificationPipe.EndpointAddress = NotificationEndpoint->EndpointAddress; | ||
| 112 | CDCInterfaceInfo->Config.NotificationPipe.Type = EP_TYPE_INTERRUPT; | ||
| 113 | |||
| 114 | if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.DataINPipe, 1))) | ||
| 115 | return CDC_ENUMERROR_PipeConfigurationFailed; | ||
| 116 | |||
| 117 | if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 118 | return CDC_ENUMERROR_PipeConfigurationFailed; | ||
| 119 | |||
| 120 | if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.NotificationPipe, 1))) | ||
| 121 | return CDC_ENUMERROR_PipeConfigurationFailed; | ||
| 122 | |||
| 123 | CDCInterfaceInfo->State.ControlInterfaceNumber = CDCControlInterface->InterfaceNumber; | ||
| 124 | CDCInterfaceInfo->State.ControlLineStates.HostToDevice = (CDC_CONTROL_LINE_OUT_RTS | CDC_CONTROL_LINE_OUT_DTR); | ||
| 125 | CDCInterfaceInfo->State.ControlLineStates.DeviceToHost = (CDC_CONTROL_LINE_IN_DCD | CDC_CONTROL_LINE_IN_DSR); | ||
| 126 | CDCInterfaceInfo->State.IsActive = true; | ||
| 127 | |||
| 128 | return CDC_ENUMERROR_NoError; | ||
| 129 | } | ||
| 130 | |||
| 131 | static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor) | ||
| 132 | { | ||
| 133 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 134 | |||
| 135 | if (Header->Type == DTYPE_Interface) | ||
| 136 | { | ||
| 137 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 138 | |||
| 139 | if ((Interface->Class == CDC_CSCP_CDCClass) && | ||
| 140 | (Interface->SubClass == CDC_CSCP_ACMSubclass) && | ||
| 141 | (Interface->Protocol == CDC_CSCP_ATCommandProtocol)) | ||
| 142 | { | ||
| 143 | return DESCRIPTOR_SEARCH_Found; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 148 | } | ||
| 149 | |||
| 150 | static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor) | ||
| 151 | { | ||
| 152 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 153 | |||
| 154 | if (Header->Type == DTYPE_Interface) | ||
| 155 | { | ||
| 156 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 157 | |||
| 158 | if ((Interface->Class == CDC_CSCP_CDCDataClass) && | ||
| 159 | (Interface->SubClass == CDC_CSCP_NoDataSubclass) && | ||
| 160 | (Interface->Protocol == CDC_CSCP_NoDataProtocol)) | ||
| 161 | { | ||
| 162 | return DESCRIPTOR_SEARCH_Found; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 167 | } | ||
| 168 | |||
| 169 | static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 170 | { | ||
| 171 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 172 | |||
| 173 | if (Header->Type == DTYPE_Endpoint) | ||
| 174 | { | ||
| 175 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 176 | |||
| 177 | uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); | ||
| 178 | |||
| 179 | if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) && | ||
| 180 | !(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) | ||
| 181 | { | ||
| 182 | return DESCRIPTOR_SEARCH_Found; | ||
| 183 | } | ||
| 184 | } | ||
| 185 | else if (Header->Type == DTYPE_Interface) | ||
| 186 | { | ||
| 187 | return DESCRIPTOR_SEARCH_Fail; | ||
| 188 | } | ||
| 189 | |||
| 190 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 191 | } | ||
| 192 | |||
| 193 | void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) | ||
| 194 | { | ||
| 195 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 196 | return; | ||
| 197 | |||
| 198 | Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipe.Address); | ||
| 199 | Pipe_Unfreeze(); | ||
| 200 | |||
| 201 | if (Pipe_IsINReceived()) | ||
| 202 | { | ||
| 203 | USB_Request_Header_t Notification; | ||
| 204 | Pipe_Read_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL); | ||
| 205 | |||
| 206 | if ((Notification.bRequest == CDC_NOTIF_SerialState) && | ||
| 207 | (Notification.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))) | ||
| 208 | { | ||
| 209 | Pipe_Read_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost, | ||
| 210 | sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost), | ||
| 211 | NULL); | ||
| 212 | |||
| 213 | Pipe_ClearIN(); | ||
| 214 | |||
| 215 | EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo); | ||
| 216 | } | ||
| 217 | else | ||
| 218 | { | ||
| 219 | Pipe_ClearIN(); | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | Pipe_Freeze(); | ||
| 224 | |||
| 225 | #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) | ||
| 226 | CDC_Host_Flush(CDCInterfaceInfo); | ||
| 227 | #endif | ||
| 228 | } | ||
| 229 | |||
| 230 | uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) | ||
| 231 | { | ||
| 232 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 233 | { | ||
| 234 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 235 | .bRequest = CDC_REQ_SetLineEncoding, | ||
| 236 | .wValue = 0, | ||
| 237 | .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber, | ||
| 238 | .wLength = sizeof(CDCInterfaceInfo->State.LineEncoding), | ||
| 239 | }; | ||
| 240 | |||
| 241 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 242 | |||
| 243 | return USB_Host_SendControlRequest(&CDCInterfaceInfo->State.LineEncoding); | ||
| 244 | } | ||
| 245 | |||
| 246 | uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) | ||
| 247 | { | ||
| 248 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 249 | { | ||
| 250 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 251 | .bRequest = CDC_REQ_SetControlLineState, | ||
| 252 | .wValue = CDCInterfaceInfo->State.ControlLineStates.HostToDevice, | ||
| 253 | .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber, | ||
| 254 | .wLength = 0, | ||
| 255 | }; | ||
| 256 | |||
| 257 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 258 | |||
| 259 | return USB_Host_SendControlRequest(NULL); | ||
| 260 | } | ||
| 261 | |||
| 262 | uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 263 | const uint8_t Duration) | ||
| 264 | { | ||
| 265 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 266 | { | ||
| 267 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 268 | .bRequest = CDC_REQ_SendBreak, | ||
| 269 | .wValue = Duration, | ||
| 270 | .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber, | ||
| 271 | .wLength = 0, | ||
| 272 | }; | ||
| 273 | |||
| 274 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 275 | |||
| 276 | return USB_Host_SendControlRequest(NULL); | ||
| 277 | } | ||
| 278 | |||
| 279 | uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 280 | const void* const Buffer, | ||
| 281 | const uint16_t Length) | ||
| 282 | { | ||
| 283 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 284 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 285 | |||
| 286 | uint8_t ErrorCode; | ||
| 287 | |||
| 288 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 289 | |||
| 290 | Pipe_Unfreeze(); | ||
| 291 | ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); | ||
| 292 | Pipe_Freeze(); | ||
| 293 | |||
| 294 | return ErrorCode; | ||
| 295 | } | ||
| 296 | |||
| 297 | uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 298 | const void* const Buffer, | ||
| 299 | const uint16_t Length) | ||
| 300 | { | ||
| 301 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 302 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 303 | |||
| 304 | uint8_t ErrorCode; | ||
| 305 | |||
| 306 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 307 | |||
| 308 | Pipe_Unfreeze(); | ||
| 309 | ErrorCode = Pipe_Write_PStream_LE(Buffer, Length, NULL); | ||
| 310 | Pipe_Freeze(); | ||
| 311 | |||
| 312 | return ErrorCode; | ||
| 313 | } | ||
| 314 | |||
| 315 | uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 316 | const char* const String) | ||
| 317 | { | ||
| 318 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 319 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 320 | |||
| 321 | uint8_t ErrorCode; | ||
| 322 | |||
| 323 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 324 | |||
| 325 | Pipe_Unfreeze(); | ||
| 326 | ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); | ||
| 327 | Pipe_Freeze(); | ||
| 328 | |||
| 329 | return ErrorCode; | ||
| 330 | } | ||
| 331 | |||
| 332 | uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 333 | const char* const String) | ||
| 334 | { | ||
| 335 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 336 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 337 | |||
| 338 | uint8_t ErrorCode; | ||
| 339 | |||
| 340 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 341 | |||
| 342 | Pipe_Unfreeze(); | ||
| 343 | ErrorCode = Pipe_Write_PStream_LE(String, strlen_P(String), NULL); | ||
| 344 | Pipe_Freeze(); | ||
| 345 | |||
| 346 | return ErrorCode; | ||
| 347 | } | ||
| 348 | |||
| 349 | uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 350 | const uint8_t Data) | ||
| 351 | { | ||
| 352 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 353 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 354 | |||
| 355 | uint8_t ErrorCode; | ||
| 356 | |||
| 357 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 358 | Pipe_Unfreeze(); | ||
| 359 | |||
| 360 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 361 | { | ||
| 362 | Pipe_ClearOUT(); | ||
| 363 | |||
| 364 | if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) | ||
| 365 | return ErrorCode; | ||
| 366 | } | ||
| 367 | |||
| 368 | Pipe_Write_8(Data); | ||
| 369 | Pipe_Freeze(); | ||
| 370 | |||
| 371 | return PIPE_READYWAIT_NoError; | ||
| 372 | } | ||
| 373 | |||
| 374 | uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) | ||
| 375 | { | ||
| 376 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 377 | return 0; | ||
| 378 | |||
| 379 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipe.Address); | ||
| 380 | Pipe_Unfreeze(); | ||
| 381 | |||
| 382 | if (Pipe_IsINReceived()) | ||
| 383 | { | ||
| 384 | if (!(Pipe_BytesInPipe())) | ||
| 385 | { | ||
| 386 | Pipe_ClearIN(); | ||
| 387 | Pipe_Freeze(); | ||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | else | ||
| 391 | { | ||
| 392 | Pipe_Freeze(); | ||
| 393 | return Pipe_BytesInPipe(); | ||
| 394 | } | ||
| 395 | } | ||
| 396 | else | ||
| 397 | { | ||
| 398 | Pipe_Freeze(); | ||
| 399 | |||
| 400 | return 0; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | int16_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) | ||
| 405 | { | ||
| 406 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 407 | return -1; | ||
| 408 | |||
| 409 | int16_t ReceivedByte = -1; | ||
| 410 | |||
| 411 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipe.Address); | ||
| 412 | Pipe_Unfreeze(); | ||
| 413 | |||
| 414 | if (Pipe_IsINReceived()) | ||
| 415 | { | ||
| 416 | if (Pipe_BytesInPipe()) | ||
| 417 | ReceivedByte = Pipe_Read_8(); | ||
| 418 | |||
| 419 | if (!(Pipe_BytesInPipe())) | ||
| 420 | Pipe_ClearIN(); | ||
| 421 | } | ||
| 422 | |||
| 423 | Pipe_Freeze(); | ||
| 424 | |||
| 425 | return ReceivedByte; | ||
| 426 | } | ||
| 427 | |||
| 428 | uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) | ||
| 429 | { | ||
| 430 | if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) | ||
| 431 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 432 | |||
| 433 | uint8_t ErrorCode; | ||
| 434 | |||
| 435 | Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 436 | Pipe_Unfreeze(); | ||
| 437 | |||
| 438 | if (!(Pipe_BytesInPipe())) | ||
| 439 | return PIPE_READYWAIT_NoError; | ||
| 440 | |||
| 441 | bool BankFull = !(Pipe_IsReadWriteAllowed()); | ||
| 442 | |||
| 443 | Pipe_ClearOUT(); | ||
| 444 | |||
| 445 | if (BankFull) | ||
| 446 | { | ||
| 447 | if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) | ||
| 448 | return ErrorCode; | ||
| 449 | |||
| 450 | Pipe_ClearOUT(); | ||
| 451 | } | ||
| 452 | |||
| 453 | Pipe_Freeze(); | ||
| 454 | |||
| 455 | return PIPE_READYWAIT_NoError; | ||
| 456 | } | ||
| 457 | |||
| 458 | #if defined(FDEV_SETUP_STREAM) | ||
| 459 | void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 460 | FILE* const Stream) | ||
| 461 | { | ||
| 462 | *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW); | ||
| 463 | fdev_set_udata(Stream, CDCInterfaceInfo); | ||
| 464 | } | ||
| 465 | |||
| 466 | void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 467 | FILE* const Stream) | ||
| 468 | { | ||
| 469 | *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW); | ||
| 470 | fdev_set_udata(Stream, CDCInterfaceInfo); | ||
| 471 | } | ||
| 472 | |||
| 473 | static int CDC_Host_putchar(char c, | ||
| 474 | FILE* Stream) | ||
| 475 | { | ||
| 476 | return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; | ||
| 477 | } | ||
| 478 | |||
| 479 | static int CDC_Host_getchar(FILE* Stream) | ||
| 480 | { | ||
| 481 | int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream)); | ||
| 482 | |||
| 483 | if (ReceivedByte < 0) | ||
| 484 | return _FDEV_EOF; | ||
| 485 | |||
| 486 | return ReceivedByte; | ||
| 487 | } | ||
| 488 | |||
| 489 | static int CDC_Host_getchar_Blocking(FILE* Stream) | ||
| 490 | { | ||
| 491 | int16_t ReceivedByte; | ||
| 492 | |||
| 493 | while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0) | ||
| 494 | { | ||
| 495 | if (USB_HostState == HOST_STATE_Unattached) | ||
| 496 | return _FDEV_EOF; | ||
| 497 | |||
| 498 | CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream)); | ||
| 499 | USB_USBTask(); | ||
| 500 | } | ||
| 501 | |||
| 502 | return ReceivedByte; | ||
| 503 | } | ||
| 504 | #endif | ||
| 505 | |||
| 506 | void CDC_Host_Event_Stub(void) | ||
| 507 | { | ||
| 508 | |||
| 509 | } | ||
| 510 | |||
| 511 | #endif | ||
| 512 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/CDCClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/CDCClassHost.h new file mode 100644 index 000000000..86ce6def3 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/CDCClassHost.h | |||
| @@ -0,0 +1,385 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB CDC Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB CDC Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassCDC | ||
| 41 | * \defgroup Group_USBClassCDCHost CDC Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassCDCHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/CDCClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassCDCHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the CDC USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __CDC_CLASS_HOST_H__ | ||
| 54 | #define __CDC_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/CDCClassCommon.h" | ||
| 59 | |||
| 60 | #include <stdio.h> | ||
| 61 | |||
| 62 | /* Enable C linkage for C++ Compilers: */ | ||
| 63 | #if defined(__cplusplus) | ||
| 64 | extern "C" { | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* Preprocessor Checks: */ | ||
| 68 | #if !defined(__INCLUDE_FROM_CDC_DRIVER) | ||
| 69 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 70 | #endif | ||
| 71 | |||
| 72 | /* Public Interface - May be used in end-application: */ | ||
| 73 | /* Type Defines: */ | ||
| 74 | /** \brief CDC Class Host Mode Configuration and State Structure. | ||
| 75 | * | ||
| 76 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 77 | * and passed to each of the CDC class driver functions as the \c CDCInterfaceInfo parameter. This | ||
| 78 | * stores each CDC interface's configuration and state information. | ||
| 79 | */ | ||
| 80 | typedef struct | ||
| 81 | { | ||
| 82 | struct | ||
| 83 | { | ||
| 84 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 85 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 86 | USB_Pipe_Table_t NotificationPipe; /**< Notification IN Pipe configuration table. */ | ||
| 87 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 88 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 89 | */ | ||
| 90 | struct | ||
| 91 | { | ||
| 92 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 93 | * after \ref CDC_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 94 | * Configured state. | ||
| 95 | */ | ||
| 96 | uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device. */ | ||
| 97 | |||
| 98 | struct | ||
| 99 | { | ||
| 100 | uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_* | ||
| 101 | * masks - to notify the device of changes to these values, call the | ||
| 102 | * \ref CDC_Host_SendControlLineStateChange() function. | ||
| 103 | */ | ||
| 104 | uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_* | ||
| 105 | * masks. This value is updated each time \ref CDC_Host_USBTask() is called. | ||
| 106 | */ | ||
| 107 | } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */ | ||
| 108 | |||
| 109 | CDC_LineEncoding_t LineEncoding; /**< Line encoding used in the virtual serial port, for the device's information. | ||
| 110 | * This is generally only used if the virtual serial port data is to be | ||
| 111 | * reconstructed on a physical UART. When set by the host application, the | ||
| 112 | * \ref CDC_Host_SetLineEncoding() function must be called to push the changes | ||
| 113 | * to the device. | ||
| 114 | */ | ||
| 115 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 116 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 117 | * the interface is enumerated. | ||
| 118 | */ | ||
| 119 | } USB_ClassInfo_CDC_Host_t; | ||
| 120 | |||
| 121 | /* Enums: */ | ||
| 122 | /** Enum for the possible error codes returned by the \ref CDC_Host_ConfigurePipes() function. */ | ||
| 123 | enum CDC_Host_EnumerationFailure_ErrorCodes_t | ||
| 124 | { | ||
| 125 | CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 126 | CDC_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 127 | CDC_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor. */ | ||
| 128 | CDC_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 129 | }; | ||
| 130 | |||
| 131 | /* Function Prototypes: */ | ||
| 132 | /** General management task for a given CDC host class interface, required for the correct operation of the interface. This should | ||
| 133 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 134 | * | ||
| 135 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state. | ||
| 136 | */ | ||
| 137 | void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 138 | |||
| 139 | /** Host interface configuration routine, to configure a given CDC host interface instance using the Configuration | ||
| 140 | * Descriptor read from an attached USB device. This function automatically updates the given CDC Host instance's | ||
| 141 | * state values and configures the pipes required to communicate with the interface if it is found within the device. | ||
| 142 | * This should be called once after the stack has enumerated the attached device, while the host state machine is in | ||
| 143 | * the Addressed state. | ||
| 144 | * | ||
| 145 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state. | ||
| 146 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 147 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 148 | * | ||
| 149 | * \return A value from the \ref CDC_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 150 | */ | ||
| 151 | uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 152 | uint16_t ConfigDescriptorSize, | ||
| 153 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 154 | |||
| 155 | /** Sets the line encoding for the attached device's virtual serial port. This should be called when the \c LineEncoding | ||
| 156 | * values of the interface have been changed to push the new settings to the USB device. | ||
| 157 | * | ||
| 158 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 159 | * | ||
| 160 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 161 | */ | ||
| 162 | uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 163 | |||
| 164 | /** Sends a Serial Control Line State Change notification to the device. This should be called when the virtual serial | ||
| 165 | * control lines (DTR, RTS, etc.) have changed states. Line states persist until they are cleared via a second | ||
| 166 | * notification. This should be called each time the CDC class driver's \c ControlLineStates.HostToDevice value is updated | ||
| 167 | * to push the new states to the USB device. | ||
| 168 | * | ||
| 169 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 170 | * | ||
| 171 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 172 | */ | ||
| 173 | uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 174 | |||
| 175 | /** Sends a Send Break request to the device. This is generally used to separate data or to indicate a special condition | ||
| 176 | * to the receiving device. | ||
| 177 | * | ||
| 178 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 179 | * \param[in] Duration Duration of the break, in milliseconds. | ||
| 180 | * | ||
| 181 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 182 | */ | ||
| 183 | uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 184 | const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1); | ||
| 185 | |||
| 186 | /** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is | ||
| 187 | * called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank | ||
| 188 | * becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows for | ||
| 189 | * multiple bytes to be packed into a single pipe packet, increasing data throughput. | ||
| 190 | * | ||
| 191 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 192 | * call will fail. | ||
| 193 | * | ||
| 194 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 195 | * \param[in] Buffer Pointer to a buffer containing the data to send to the device. | ||
| 196 | * \param[in] Length Length of the data to send to the device. | ||
| 197 | * | ||
| 198 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 199 | */ | ||
| 200 | uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 201 | const void* const Buffer, | ||
| 202 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); | ||
| 203 | |||
| 204 | /** Sends a given data buffer from PROGMEM space to the attached USB device, if connected. If a device is not connected when the | ||
| 205 | * function is called, the string is discarded. Bytes will be queued for transmission to the host until either the pipe | ||
| 206 | * bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows | ||
| 207 | * for multiple bytes to be packed into a single pipe packet, increasing data throughput. | ||
| 208 | * | ||
| 209 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or | ||
| 210 | * the call will fail. | ||
| 211 | * | ||
| 212 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 213 | * \param[in] Buffer Pointer to a buffer containing the data to send to the device. | ||
| 214 | * \param[in] Length Length of the data to send to the host. | ||
| 215 | * | ||
| 216 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 217 | */ | ||
| 218 | uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 219 | const void* const Buffer, | ||
| 220 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); | ||
| 221 | |||
| 222 | /** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the | ||
| 223 | * function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe | ||
| 224 | * bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows | ||
| 225 | * for multiple bytes to be packed into a single pipe packet, increasing data throughput. | ||
| 226 | * | ||
| 227 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 228 | * call will fail. | ||
| 229 | * | ||
| 230 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 231 | * \param[in] String Pointer to the null terminated string to send to the device. | ||
| 232 | * | ||
| 233 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 234 | */ | ||
| 235 | uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 236 | const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 237 | |||
| 238 | /** Sends a given null terminated string from PROGMEM space to the attached USB device, if connected. If a device is not connected | ||
| 239 | * when the function is called, the string is discarded. Bytes will be queued for transmission to the device until either | ||
| 240 | * the pipe bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to | ||
| 241 | * the device. This allows for multiple bytes to be packed into a single pipe packet, increasing data throughput. | ||
| 242 | * | ||
| 243 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or | ||
| 244 | * the call will fail. | ||
| 245 | * | ||
| 246 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 247 | * \param[in] String Pointer to the null terminated string to send to the host. | ||
| 248 | * | ||
| 249 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 250 | */ | ||
| 251 | uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 252 | const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 253 | |||
| 254 | /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the | ||
| 255 | * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the | ||
| 256 | * \ref CDC_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be | ||
| 257 | * packed into a single pipe packet, increasing data throughput. | ||
| 258 | * | ||
| 259 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 260 | * call will fail. | ||
| 261 | * | ||
| 262 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 263 | * \param[in] Data Byte of data to send to the device. | ||
| 264 | * | ||
| 265 | * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. | ||
| 266 | */ | ||
| 267 | uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 268 | const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); | ||
| 269 | |||
| 270 | /** Determines the number of bytes received by the CDC interface from the device, waiting to be read. This indicates the number | ||
| 271 | * of bytes in the IN pipe bank only, and thus the number of calls to \ref CDC_Host_ReceiveByte() which are guaranteed to succeed | ||
| 272 | * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be | ||
| 273 | * released back to the USB controller until all bytes are read. | ||
| 274 | * | ||
| 275 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 276 | * call will fail. | ||
| 277 | * | ||
| 278 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 279 | * | ||
| 280 | * \return Total number of buffered bytes received from the device. | ||
| 281 | */ | ||
| 282 | uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 283 | |||
| 284 | /** 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 | ||
| 285 | * returns a negative value. The \ref CDC_Host_BytesReceived() function may be queried in advance to determine how many bytes | ||
| 286 | * are currently buffered in the CDC interface's data receive pipe. | ||
| 287 | * | ||
| 288 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 289 | * call will fail. | ||
| 290 | * | ||
| 291 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 292 | * | ||
| 293 | * \return Next received byte from the device, or a negative value if no data received. | ||
| 294 | */ | ||
| 295 | int16_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 296 | |||
| 297 | /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. | ||
| 298 | * | ||
| 299 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 300 | * call will fail. | ||
| 301 | * | ||
| 302 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 303 | * | ||
| 304 | * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. | ||
| 305 | */ | ||
| 306 | uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 307 | |||
| 308 | #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__) | ||
| 309 | /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular | ||
| 310 | * functions in the standard \c <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created | ||
| 311 | * stream is bidirectional and can be used for both input and output functions. | ||
| 312 | * | ||
| 313 | * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single | ||
| 314 | * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may | ||
| 315 | * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own | ||
| 316 | * line buffering. | ||
| 317 | * | ||
| 318 | * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions | ||
| 319 | * to the given CDC interface. | ||
| 320 | * \n\n | ||
| 321 | * | ||
| 322 | * \note This function is not available on all microcontroller architectures. | ||
| 323 | * | ||
| 324 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 325 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 326 | */ | ||
| 327 | void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 328 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 329 | |||
| 330 | /** Identical to \ref CDC_Host_CreateStream(), except that reads are blocking until the calling stream function terminates | ||
| 331 | * the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications. | ||
| 332 | * | ||
| 333 | * \note This function is not available on all microcontroller architectures. | ||
| 334 | * | ||
| 335 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. | ||
| 336 | * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. | ||
| 337 | */ | ||
| 338 | void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, | ||
| 339 | FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 340 | #endif | ||
| 341 | |||
| 342 | /** CDC class driver event for a control line state change on a CDC host interface. This event fires each time the device notifies | ||
| 343 | * the host of a control line state change (containing the virtual serial control line states, such as DCD) and may be hooked in the | ||
| 344 | * user program by declaring a handler function with the same name and parameters listed here. The new control line states | ||
| 345 | * are available in the \c ControlLineStates.DeviceToHost value inside the CDC host interface structure passed as a parameter, set as | ||
| 346 | * a mask of \c CDC_CONTROL_LINE_IN_* masks. | ||
| 347 | * | ||
| 348 | * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. | ||
| 349 | */ | ||
| 350 | void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 351 | |||
| 352 | /* Private Interface - For use in library only: */ | ||
| 353 | #if !defined(__DOXYGEN__) | ||
| 354 | /* Function Prototypes: */ | ||
| 355 | #if defined(__INCLUDE_FROM_CDC_HOST_C) | ||
| 356 | #if defined(FDEV_SETUP_STREAM) | ||
| 357 | static int CDC_Host_putchar(char c, | ||
| 358 | FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); | ||
| 359 | static int CDC_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 360 | static int CDC_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); | ||
| 361 | #endif | ||
| 362 | |||
| 363 | void CDC_Host_Event_Stub(void) ATTR_CONST; | ||
| 364 | |||
| 365 | void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) | ||
| 366 | ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Host_Event_Stub); | ||
| 367 | |||
| 368 | static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor) | ||
| 369 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 370 | static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor) | ||
| 371 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 372 | static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 373 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 374 | #endif | ||
| 375 | #endif | ||
| 376 | |||
| 377 | /* Disable C linkage for C++ Compilers: */ | ||
| 378 | #if defined(__cplusplus) | ||
| 379 | } | ||
| 380 | #endif | ||
| 381 | |||
| 382 | #endif | ||
| 383 | |||
| 384 | /** @} */ | ||
| 385 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/HIDClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/HIDClassHost.c new file mode 100644 index 000000000..32591ffd7 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/HIDClassHost.c | |||
| @@ -0,0 +1,399 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_HID_DRIVER | ||
| 37 | #define __INCLUDE_FROM_HID_HOST_C | ||
| 38 | #include "HIDClassHost.h" | ||
| 39 | |||
| 40 | uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Interface_t* HIDInterface = NULL; | ||
| 47 | USB_HID_Descriptor_HID_t* HIDDescriptor = NULL; | ||
| 48 | |||
| 49 | memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State)); | ||
| 50 | |||
| 51 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 52 | return HID_ENUMERROR_InvalidConfigDescriptor; | ||
| 53 | |||
| 54 | while (!(DataINEndpoint) || !(DataOUTEndpoint)) | ||
| 55 | { | ||
| 56 | if (!(HIDInterface) || | ||
| 57 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 58 | DCOMP_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 59 | { | ||
| 60 | if (DataINEndpoint) | ||
| 61 | break; | ||
| 62 | |||
| 63 | do | ||
| 64 | { | ||
| 65 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 66 | DCOMP_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 67 | { | ||
| 68 | return HID_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 69 | } | ||
| 70 | |||
| 71 | HIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 72 | } while (HIDInterfaceInfo->Config.HIDInterfaceProtocol && | ||
| 73 | (HIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol)); | ||
| 74 | |||
| 75 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 76 | DCOMP_HID_Host_NextHIDDescriptor) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 77 | { | ||
| 78 | return HID_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 79 | } | ||
| 80 | |||
| 81 | HIDDescriptor = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_HID_Descriptor_HID_t); | ||
| 82 | |||
| 83 | DataINEndpoint = NULL; | ||
| 84 | DataOUTEndpoint = NULL; | ||
| 85 | |||
| 86 | continue; | ||
| 87 | } | ||
| 88 | |||
| 89 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 90 | |||
| 91 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 92 | DataINEndpoint = EndpointData; | ||
| 93 | else | ||
| 94 | DataOUTEndpoint = EndpointData; | ||
| 95 | } | ||
| 96 | |||
| 97 | HIDInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 98 | HIDInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 99 | HIDInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_INTERRUPT; | ||
| 100 | |||
| 101 | if (!(Pipe_ConfigurePipeTable(&HIDInterfaceInfo->Config.DataINPipe, 1))) | ||
| 102 | return HID_ENUMERROR_PipeConfigurationFailed; | ||
| 103 | |||
| 104 | if (DataOUTEndpoint) | ||
| 105 | { | ||
| 106 | HIDInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 107 | HIDInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 108 | HIDInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_INTERRUPT; | ||
| 109 | |||
| 110 | if (!(Pipe_ConfigurePipeTable(&HIDInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 111 | return HID_ENUMERROR_PipeConfigurationFailed; | ||
| 112 | } | ||
| 113 | |||
| 114 | HIDInterfaceInfo->State.InterfaceNumber = HIDInterface->InterfaceNumber; | ||
| 115 | HIDInterfaceInfo->State.HIDReportSize = LE16_TO_CPU(HIDDescriptor->HIDReportLength); | ||
| 116 | HIDInterfaceInfo->State.SupportsBootProtocol = (HIDInterface->SubClass != HID_CSCP_NonBootProtocol); | ||
| 117 | HIDInterfaceInfo->State.LargestReportSize = 8; | ||
| 118 | HIDInterfaceInfo->State.IsActive = true; | ||
| 119 | |||
| 120 | return HID_ENUMERROR_NoError; | ||
| 121 | } | ||
| 122 | |||
| 123 | static uint8_t DCOMP_HID_Host_NextHIDInterface(void* const CurrentDescriptor) | ||
| 124 | { | ||
| 125 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 126 | |||
| 127 | if (Header->Type == DTYPE_Interface) | ||
| 128 | { | ||
| 129 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 130 | |||
| 131 | if (Interface->Class == HID_CSCP_HIDClass) | ||
| 132 | return DESCRIPTOR_SEARCH_Found; | ||
| 133 | } | ||
| 134 | |||
| 135 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 136 | } | ||
| 137 | |||
| 138 | static uint8_t DCOMP_HID_Host_NextHIDDescriptor(void* const CurrentDescriptor) | ||
| 139 | { | ||
| 140 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 141 | |||
| 142 | if (Header->Type == HID_DTYPE_HID) | ||
| 143 | return DESCRIPTOR_SEARCH_Found; | ||
| 144 | else if (Header->Type == DTYPE_Interface) | ||
| 145 | return DESCRIPTOR_SEARCH_Fail; | ||
| 146 | else | ||
| 147 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 148 | } | ||
| 149 | |||
| 150 | static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 151 | { | ||
| 152 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 153 | |||
| 154 | if (Header->Type == DTYPE_Endpoint) | ||
| 155 | { | ||
| 156 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 157 | |||
| 158 | if (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) | ||
| 159 | return DESCRIPTOR_SEARCH_Found; | ||
| 160 | } | ||
| 161 | else if (Header->Type == DTYPE_Interface) | ||
| 162 | { | ||
| 163 | return DESCRIPTOR_SEARCH_Fail; | ||
| 164 | } | ||
| 165 | |||
| 166 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 167 | } | ||
| 168 | |||
| 169 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 170 | uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 171 | const uint8_t ReportID, | ||
| 172 | void* Buffer) | ||
| 173 | { | ||
| 174 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 175 | { | ||
| 176 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 177 | .bRequest = HID_REQ_SetReport, | ||
| 178 | .wValue = ((HID_REPORT_ITEM_In + 1) << 8) | ReportID, | ||
| 179 | .wIndex = HIDInterfaceInfo->State.InterfaceNumber, | ||
| 180 | .wLength = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In), | ||
| 181 | }; | ||
| 182 | |||
| 183 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 184 | |||
| 185 | return USB_Host_SendControlRequest(Buffer); | ||
| 186 | } | ||
| 187 | #endif | ||
| 188 | |||
| 189 | uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 190 | void* Buffer) | ||
| 191 | { | ||
| 192 | if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive)) | ||
| 193 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 194 | |||
| 195 | uint8_t ErrorCode; | ||
| 196 | |||
| 197 | Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipe.Address); | ||
| 198 | Pipe_Unfreeze(); | ||
| 199 | |||
| 200 | uint16_t ReportSize; | ||
| 201 | uint8_t* BufferPos = Buffer; | ||
| 202 | |||
| 203 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 204 | if (!(HIDInterfaceInfo->State.UsingBootProtocol)) | ||
| 205 | { | ||
| 206 | uint8_t ReportID = 0; | ||
| 207 | |||
| 208 | if (HIDInterfaceInfo->Config.HIDParserData->UsingReportIDs) | ||
| 209 | { | ||
| 210 | ReportID = Pipe_Read_8(); | ||
| 211 | *(BufferPos++) = ReportID; | ||
| 212 | } | ||
| 213 | |||
| 214 | ReportSize = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In); | ||
| 215 | } | ||
| 216 | else | ||
| 217 | #endif | ||
| 218 | { | ||
| 219 | ReportSize = Pipe_BytesInPipe(); | ||
| 220 | } | ||
| 221 | |||
| 222 | if ((ErrorCode = Pipe_Read_Stream_LE(BufferPos, ReportSize, NULL)) != PIPE_RWSTREAM_NoError) | ||
| 223 | return ErrorCode; | ||
| 224 | |||
| 225 | Pipe_ClearIN(); | ||
| 226 | Pipe_Freeze(); | ||
| 227 | |||
| 228 | return PIPE_RWSTREAM_NoError; | ||
| 229 | } | ||
| 230 | |||
| 231 | uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 232 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 233 | const uint8_t ReportID, | ||
| 234 | #endif | ||
| 235 | const uint8_t ReportType, | ||
| 236 | void* Buffer, | ||
| 237 | const uint16_t ReportSize) | ||
| 238 | { | ||
| 239 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 240 | if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive)) | ||
| 241 | return PIPE_RWSTREAM_NoError; | ||
| 242 | |||
| 243 | if (HIDInterfaceInfo->State.DeviceUsesOUTPipe && (ReportType == HID_REPORT_ITEM_Out)) | ||
| 244 | { | ||
| 245 | uint8_t ErrorCode; | ||
| 246 | |||
| 247 | Pipe_SelectPipe(HIDInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 248 | Pipe_Unfreeze(); | ||
| 249 | |||
| 250 | if (ReportID) | ||
| 251 | Pipe_Write_Stream_LE(&ReportID, sizeof(ReportID), NULL); | ||
| 252 | |||
| 253 | if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, ReportSize, NULL)) != PIPE_RWSTREAM_NoError) | ||
| 254 | return ErrorCode; | ||
| 255 | |||
| 256 | Pipe_ClearOUT(); | ||
| 257 | Pipe_Freeze(); | ||
| 258 | |||
| 259 | return PIPE_RWSTREAM_NoError; | ||
| 260 | } | ||
| 261 | else | ||
| 262 | #endif | ||
| 263 | { | ||
| 264 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 265 | { | ||
| 266 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 267 | .bRequest = HID_REQ_SetReport, | ||
| 268 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 269 | .wValue = ((ReportType + 1) << 8) | ReportID, | ||
| 270 | #else | ||
| 271 | .wValue = ((ReportType + 1) << 8), | ||
| 272 | #endif | ||
| 273 | .wIndex = HIDInterfaceInfo->State.InterfaceNumber, | ||
| 274 | .wLength = ReportSize, | ||
| 275 | }; | ||
| 276 | |||
| 277 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 278 | |||
| 279 | return USB_Host_SendControlRequest(Buffer); | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) | ||
| 284 | { | ||
| 285 | if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive)) | ||
| 286 | return false; | ||
| 287 | |||
| 288 | bool ReportReceived; | ||
| 289 | |||
| 290 | Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipe.Address); | ||
| 291 | Pipe_Unfreeze(); | ||
| 292 | |||
| 293 | ReportReceived = Pipe_IsINReceived(); | ||
| 294 | |||
| 295 | Pipe_Freeze(); | ||
| 296 | |||
| 297 | return ReportReceived; | ||
| 298 | } | ||
| 299 | |||
| 300 | uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) | ||
| 301 | { | ||
| 302 | uint8_t ErrorCode; | ||
| 303 | |||
| 304 | if (!(HIDInterfaceInfo->State.SupportsBootProtocol)) | ||
| 305 | return HID_ERROR_LOGICAL; | ||
| 306 | |||
| 307 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 308 | { | ||
| 309 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 310 | .bRequest = HID_REQ_SetProtocol, | ||
| 311 | .wValue = 0, | ||
| 312 | .wIndex = HIDInterfaceInfo->State.InterfaceNumber, | ||
| 313 | .wLength = 0, | ||
| 314 | }; | ||
| 315 | |||
| 316 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 317 | |||
| 318 | if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) | ||
| 319 | return ErrorCode; | ||
| 320 | |||
| 321 | HIDInterfaceInfo->State.LargestReportSize = 8; | ||
| 322 | HIDInterfaceInfo->State.UsingBootProtocol = true; | ||
| 323 | |||
| 324 | return HOST_SENDCONTROL_Successful; | ||
| 325 | } | ||
| 326 | |||
| 327 | uint8_t HID_Host_SetIdlePeriod(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 328 | const uint16_t MS) | ||
| 329 | { | ||
| 330 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 331 | { | ||
| 332 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 333 | .bRequest = HID_REQ_SetIdle, | ||
| 334 | .wValue = ((MS << 6) & 0xFF00), | ||
| 335 | .wIndex = HIDInterfaceInfo->State.InterfaceNumber, | ||
| 336 | .wLength = 0, | ||
| 337 | }; | ||
| 338 | |||
| 339 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 340 | |||
| 341 | return USB_Host_SendControlRequest(NULL); | ||
| 342 | } | ||
| 343 | |||
| 344 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 345 | uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) | ||
| 346 | { | ||
| 347 | uint8_t ErrorCode; | ||
| 348 | |||
| 349 | uint8_t HIDReportData[HIDInterfaceInfo->State.HIDReportSize]; | ||
| 350 | |||
| 351 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 352 | { | ||
| 353 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE), | ||
| 354 | .bRequest = REQ_GetDescriptor, | ||
| 355 | .wValue = (HID_DTYPE_Report << 8), | ||
| 356 | .wIndex = HIDInterfaceInfo->State.InterfaceNumber, | ||
| 357 | .wLength = HIDInterfaceInfo->State.HIDReportSize, | ||
| 358 | }; | ||
| 359 | |||
| 360 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 361 | |||
| 362 | if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful) | ||
| 363 | return ErrorCode; | ||
| 364 | |||
| 365 | if (HIDInterfaceInfo->State.UsingBootProtocol) | ||
| 366 | { | ||
| 367 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 368 | { | ||
| 369 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 370 | .bRequest = HID_REQ_SetProtocol, | ||
| 371 | .wValue = 1, | ||
| 372 | .wIndex = HIDInterfaceInfo->State.InterfaceNumber, | ||
| 373 | .wLength = 0, | ||
| 374 | }; | ||
| 375 | |||
| 376 | if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) | ||
| 377 | return ErrorCode; | ||
| 378 | |||
| 379 | HIDInterfaceInfo->State.UsingBootProtocol = false; | ||
| 380 | } | ||
| 381 | |||
| 382 | if (HIDInterfaceInfo->Config.HIDParserData == NULL) | ||
| 383 | return HID_ERROR_LOGICAL; | ||
| 384 | |||
| 385 | if ((ErrorCode = USB_ProcessHIDReport(HIDReportData, HIDInterfaceInfo->State.HIDReportSize, | ||
| 386 | HIDInterfaceInfo->Config.HIDParserData)) != HID_PARSE_Successful) | ||
| 387 | { | ||
| 388 | return HID_ERROR_LOGICAL | ErrorCode; | ||
| 389 | } | ||
| 390 | |||
| 391 | uint16_t LargestReportSizeBits = HIDInterfaceInfo->Config.HIDParserData->LargestReportSizeBits; | ||
| 392 | HIDInterfaceInfo->State.LargestReportSize = (LargestReportSizeBits >> 3) + ((LargestReportSizeBits & 0x07) != 0); | ||
| 393 | |||
| 394 | return 0; | ||
| 395 | } | ||
| 396 | #endif | ||
| 397 | |||
| 398 | #endif | ||
| 399 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/HIDClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/HIDClassHost.h new file mode 100644 index 000000000..73b5abb1b --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/HIDClassHost.h | |||
| @@ -0,0 +1,313 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB HID Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB HID Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassHID | ||
| 41 | * \defgroup Group_USBClassHIDHost HID Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassHIDHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/HIDClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassHIDHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the HID USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __HID_CLASS_HOST_H__ | ||
| 54 | #define __HID_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/HIDClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_HID_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Macros: */ | ||
| 72 | /** Error code for some HID Host functions, indicating a logical (and not hardware) error. */ | ||
| 73 | #define HID_ERROR_LOGICAL 0x80 | ||
| 74 | |||
| 75 | /* Type Defines: */ | ||
| 76 | /** \brief HID Class Host Mode Configuration and State Structure. | ||
| 77 | * | ||
| 78 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 79 | * and passed to each of the HID class driver functions as the \c HIDInterfaceInfo parameter. This | ||
| 80 | * stores each HID interface's configuration and state information. | ||
| 81 | */ | ||
| 82 | typedef struct | ||
| 83 | { | ||
| 84 | struct | ||
| 85 | { | ||
| 86 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 87 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 88 | |||
| 89 | uint8_t HIDInterfaceProtocol; /**< HID interface protocol value to match against if a specific | ||
| 90 | * boot subclass protocol is required, a protocol value from the | ||
| 91 | * \ref HID_Descriptor_ClassSubclassProtocol_t enum. | ||
| 92 | */ | ||
| 93 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 94 | HID_ReportInfo_t* HIDParserData; /**< HID parser data to store the parsed HID report data, when boot protocol | ||
| 95 | * is not used. | ||
| 96 | * | ||
| 97 | * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, | ||
| 98 | * this field is unavailable. | ||
| 99 | */ | ||
| 100 | #endif | ||
| 101 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 102 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 103 | */ | ||
| 104 | struct | ||
| 105 | { | ||
| 106 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 107 | * after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 108 | * Configured state. | ||
| 109 | */ | ||
| 110 | uint8_t InterfaceNumber; /**< Interface index of the HID interface within the attached device. */ | ||
| 111 | |||
| 112 | bool SupportsBootProtocol; /**< Indicates if the current interface instance supports the HID Boot | ||
| 113 | * Protocol when enabled via \ref HID_Host_SetBootProtocol(). | ||
| 114 | */ | ||
| 115 | bool DeviceUsesOUTPipe; /**< Indicates if the current interface instance uses a separate OUT data pipe for | ||
| 116 | * OUT reports, or if OUT reports are sent via the control pipe instead. | ||
| 117 | */ | ||
| 118 | bool UsingBootProtocol; /**< Indicates that the interface is currently initialized in Boot Protocol mode */ | ||
| 119 | uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device. */ | ||
| 120 | |||
| 121 | uint8_t LargestReportSize; /**< Largest report the device will send, in bytes. */ | ||
| 122 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 123 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 124 | * the interface is enumerated. | ||
| 125 | */ | ||
| 126 | } USB_ClassInfo_HID_Host_t; | ||
| 127 | |||
| 128 | /* Enums: */ | ||
| 129 | /** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */ | ||
| 130 | enum HID_Host_EnumerationFailure_ErrorCodes_t | ||
| 131 | { | ||
| 132 | HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 133 | HID_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 134 | HID_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor. */ | ||
| 135 | HID_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 136 | }; | ||
| 137 | |||
| 138 | /* Function Prototypes: */ | ||
| 139 | /** Host interface configuration routine, to configure a given HID host interface instance using the Configuration | ||
| 140 | * Descriptor read from an attached USB device. This function automatically updates the given HID Host instance's | ||
| 141 | * state values and configures the pipes required to communicate with the interface if it is found within the | ||
| 142 | * device. This should be called once after the stack has enumerated the attached device, while the host state | ||
| 143 | * machine is in the Addressed state. | ||
| 144 | * | ||
| 145 | * \attention Once the device pipes are configured, the HID device's reporting protocol <b>must</b> be set via a call | ||
| 146 | * to either the \ref HID_Host_SetBootProtocol() or \ref HID_Host_SetReportProtocol() function. | ||
| 147 | * | ||
| 148 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 149 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 150 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 151 | * | ||
| 152 | * \return A value from the \ref HID_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 153 | */ | ||
| 154 | uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 155 | uint16_t ConfigDescriptorSize, | ||
| 156 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 157 | |||
| 158 | |||
| 159 | /** Receives a HID IN report from the attached HID device, when a report has been received on the HID IN Data pipe. | ||
| 160 | * | ||
| 161 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 162 | * call will fail. | ||
| 163 | * | ||
| 164 | * \attention The destination buffer should be large enough to accommodate the largest report that the attached device | ||
| 165 | * can generate. | ||
| 166 | * | ||
| 167 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 168 | * \param[in] Buffer Buffer to store the received report into. | ||
| 169 | * | ||
| 170 | * \return An error code from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 171 | */ | ||
| 172 | uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 173 | void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 174 | |||
| 175 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 176 | /** Receives a HID IN report from the attached device, by the report ID. | ||
| 177 | * | ||
| 178 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 179 | * call will fail. | ||
| 180 | * | ||
| 181 | * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable. | ||
| 182 | * | ||
| 183 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 184 | * \param[in] ReportID Report ID of the received report if ControlRequest is false, set by the to the Report ID to fetch. | ||
| 185 | * \param[in] Buffer Buffer to store the received report into. | ||
| 186 | * | ||
| 187 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 188 | */ | ||
| 189 | uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 190 | const uint8_t ReportID, | ||
| 191 | void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 192 | #endif | ||
| 193 | |||
| 194 | /** Sends an OUT or FEATURE report to the currently attached HID device, using the device's OUT pipe if available, | ||
| 195 | * or the device's Control pipe if not. | ||
| 196 | * | ||
| 197 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 198 | * call will fail. | ||
| 199 | * | ||
| 200 | * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, the ReportID parameter is removed | ||
| 201 | * from the parameter list of this function. | ||
| 202 | * | ||
| 203 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 204 | * \param[in] ReportID Report ID of the report to send to the device, or 0 if the device does not use report IDs. | ||
| 205 | * \param[in] ReportType Type of report to issue to the device, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature. | ||
| 206 | * \param[in] Buffer Buffer containing the report to send to the attached device. | ||
| 207 | * \param[in] ReportSize Report size in bytes to send to the attached device. | ||
| 208 | * | ||
| 209 | * \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the DeviceUsesOUTPipe flag is set in | ||
| 210 | * the interface's state structure, a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise. | ||
| 211 | */ | ||
| 212 | uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 213 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 214 | const uint8_t ReportID, | ||
| 215 | #endif | ||
| 216 | const uint8_t ReportType, | ||
| 217 | void* Buffer, | ||
| 218 | const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) | ||
| 219 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 220 | ATTR_NON_NULL_PTR_ARG(4); | ||
| 221 | #else | ||
| 222 | ATTR_NON_NULL_PTR_ARG(3); | ||
| 223 | #endif | ||
| 224 | |||
| 225 | /** Determines if a HID IN report has been received from the attached device on the data IN pipe. | ||
| 226 | * | ||
| 227 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 228 | * call will fail. | ||
| 229 | * | ||
| 230 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 231 | * | ||
| 232 | * \return Boolean \c true if a report has been received, \c false otherwise. | ||
| 233 | */ | ||
| 234 | bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 235 | |||
| 236 | /** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices. | ||
| 237 | * | ||
| 238 | * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method must still be called | ||
| 239 | * to explicitly place the attached device into boot protocol mode before use. | ||
| 240 | * | ||
| 241 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 242 | * | ||
| 243 | * \return \ref HID_ERROR_LOGICAL if the device does not support Boot Protocol mode, a value from the | ||
| 244 | * \ref USB_Host_SendControlErrorCodes_t enum otherwise. | ||
| 245 | */ | ||
| 246 | uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 247 | |||
| 248 | /** Sets the idle period for the attached HID device to the specified interval. The HID idle period determines the rate | ||
| 249 | * at which the device should send a report, when no state changes have occurred; i.e. on HID keyboards, this sets the | ||
| 250 | * hardware key repeat interval. | ||
| 251 | * | ||
| 252 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 253 | * \param[in] MS Idle period as a multiple of four milliseconds, zero to disable hardware repeats | ||
| 254 | * | ||
| 255 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 256 | */ | ||
| 257 | uint8_t HID_Host_SetIdlePeriod(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, | ||
| 258 | const uint16_t MS) ATTR_NON_NULL_PTR_ARG(1); | ||
| 259 | |||
| 260 | #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) | ||
| 261 | /** Switches the attached HID device's reporting protocol over to the standard Report protocol mode. This also retrieves | ||
| 262 | * and parses the device's HID report descriptor, so that the size of each report can be determined in advance. | ||
| 263 | * | ||
| 264 | * \attention Whether this function is used or not, the \ref CALLBACK_HIDParser_FilterHIDReportItem() callback from the HID | ||
| 265 | * Report Parser this function references <b>must</b> be implemented in the user code. | ||
| 266 | * | ||
| 267 | * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable. | ||
| 268 | * | ||
| 269 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 270 | * | ||
| 271 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum if an error occurs while retrieving the HID | ||
| 272 | * Report descriptor or the setting of the Report protocol, \ref HID_ERROR_LOGICAL if the HID interface does | ||
| 273 | * not have a valid \ref HID_ReportInfo_t structure set in its configuration, a mask of \ref HID_ERROR_LOGICAL | ||
| 274 | * and a value from the \ref HID_Parse_ErrorCodes_t otherwise. | ||
| 275 | */ | ||
| 276 | uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 277 | #endif | ||
| 278 | |||
| 279 | /* Inline Functions: */ | ||
| 280 | /** General management task for a given Human Interface Class host class interface, required for the correct operation of | ||
| 281 | * the interface. This should be called frequently in the main program loop, before the master USB management task | ||
| 282 | * \ref USB_USBTask(). | ||
| 283 | * | ||
| 284 | * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. | ||
| 285 | */ | ||
| 286 | static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 287 | static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) | ||
| 288 | { | ||
| 289 | (void)HIDInterfaceInfo; | ||
| 290 | } | ||
| 291 | |||
| 292 | /* Private Interface - For use in library only: */ | ||
| 293 | #if !defined(__DOXYGEN__) | ||
| 294 | /* Function Prototypes: */ | ||
| 295 | #if defined(__INCLUDE_FROM_HID_HOST_C) | ||
| 296 | static uint8_t DCOMP_HID_Host_NextHIDInterface(void* const CurrentDescriptor) | ||
| 297 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 298 | static uint8_t DCOMP_HID_Host_NextHIDDescriptor(void* const CurrentDescriptor) | ||
| 299 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 300 | static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 301 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 302 | #endif | ||
| 303 | #endif | ||
| 304 | |||
| 305 | /* Disable C linkage for C++ Compilers: */ | ||
| 306 | #if defined(__cplusplus) | ||
| 307 | } | ||
| 308 | #endif | ||
| 309 | |||
| 310 | #endif | ||
| 311 | |||
| 312 | /** @} */ | ||
| 313 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c new file mode 100644 index 000000000..635148f5e --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c | |||
| @@ -0,0 +1,231 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_MIDI_DRIVER | ||
| 37 | #define __INCLUDE_FROM_MIDI_HOST_C | ||
| 38 | #include "MIDIClassHost.h" | ||
| 39 | |||
| 40 | uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Interface_t* MIDIInterface = NULL; | ||
| 47 | |||
| 48 | memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State)); | ||
| 49 | |||
| 50 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 51 | return MIDI_ENUMERROR_InvalidConfigDescriptor; | ||
| 52 | |||
| 53 | while (!(DataINEndpoint) || !(DataOUTEndpoint)) | ||
| 54 | { | ||
| 55 | if (!(MIDIInterface) || | ||
| 56 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 57 | DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 58 | { | ||
| 59 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 60 | DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 61 | { | ||
| 62 | return MIDI_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 63 | } | ||
| 64 | |||
| 65 | MIDIInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 66 | |||
| 67 | DataINEndpoint = NULL; | ||
| 68 | DataOUTEndpoint = NULL; | ||
| 69 | |||
| 70 | continue; | ||
| 71 | } | ||
| 72 | |||
| 73 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 74 | |||
| 75 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 76 | DataINEndpoint = EndpointData; | ||
| 77 | else | ||
| 78 | DataOUTEndpoint = EndpointData; | ||
| 79 | } | ||
| 80 | |||
| 81 | MIDIInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 82 | MIDIInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 83 | MIDIInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; | ||
| 84 | |||
| 85 | MIDIInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 86 | MIDIInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 87 | MIDIInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; | ||
| 88 | |||
| 89 | if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataINPipe, 1))) | ||
| 90 | return MIDI_ENUMERROR_PipeConfigurationFailed; | ||
| 91 | |||
| 92 | if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 93 | return MIDI_ENUMERROR_PipeConfigurationFailed; | ||
| 94 | |||
| 95 | MIDIInterfaceInfo->State.InterfaceNumber = MIDIInterface->InterfaceNumber; | ||
| 96 | MIDIInterfaceInfo->State.IsActive = true; | ||
| 97 | |||
| 98 | return MIDI_ENUMERROR_NoError; | ||
| 99 | } | ||
| 100 | |||
| 101 | static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor) | ||
| 102 | { | ||
| 103 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 104 | |||
| 105 | if (Header->Type == DTYPE_Interface) | ||
| 106 | { | ||
| 107 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 108 | |||
| 109 | if ((Interface->Class == AUDIO_CSCP_AudioClass) && | ||
| 110 | (Interface->SubClass == AUDIO_CSCP_MIDIStreamingSubclass) && | ||
| 111 | (Interface->Protocol == AUDIO_CSCP_StreamingProtocol)) | ||
| 112 | { | ||
| 113 | return DESCRIPTOR_SEARCH_Found; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 118 | } | ||
| 119 | |||
| 120 | static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor) | ||
| 121 | { | ||
| 122 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 123 | |||
| 124 | if (Header->Type == DTYPE_Endpoint) | ||
| 125 | { | ||
| 126 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 127 | |||
| 128 | uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); | ||
| 129 | |||
| 130 | if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) | ||
| 131 | return DESCRIPTOR_SEARCH_Found; | ||
| 132 | } | ||
| 133 | else if (Header->Type == DTYPE_Interface) | ||
| 134 | { | ||
| 135 | return DESCRIPTOR_SEARCH_Fail; | ||
| 136 | } | ||
| 137 | |||
| 138 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 139 | } | ||
| 140 | |||
| 141 | void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) | ||
| 142 | { | ||
| 143 | if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) | ||
| 144 | return; | ||
| 145 | |||
| 146 | #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) | ||
| 147 | MIDI_Host_Flush(MIDIInterfaceInfo); | ||
| 148 | #endif | ||
| 149 | } | ||
| 150 | |||
| 151 | uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) | ||
| 152 | { | ||
| 153 | if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) | ||
| 154 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 155 | |||
| 156 | uint8_t ErrorCode; | ||
| 157 | |||
| 158 | Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 159 | Pipe_Unfreeze(); | ||
| 160 | |||
| 161 | if (Pipe_BytesInPipe()) | ||
| 162 | { | ||
| 163 | Pipe_ClearOUT(); | ||
| 164 | |||
| 165 | if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) | ||
| 166 | { | ||
| 167 | Pipe_Freeze(); | ||
| 168 | return ErrorCode; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | Pipe_Freeze(); | ||
| 173 | |||
| 174 | return PIPE_READYWAIT_NoError; | ||
| 175 | } | ||
| 176 | |||
| 177 | uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, | ||
| 178 | MIDI_EventPacket_t* const Event) | ||
| 179 | { | ||
| 180 | if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) | ||
| 181 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 182 | |||
| 183 | uint8_t ErrorCode; | ||
| 184 | |||
| 185 | Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 186 | Pipe_Unfreeze(); | ||
| 187 | |||
| 188 | if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != PIPE_RWSTREAM_NoError) | ||
| 189 | { | ||
| 190 | Pipe_Freeze(); | ||
| 191 | return ErrorCode; | ||
| 192 | } | ||
| 193 | |||
| 194 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 195 | Pipe_ClearOUT(); | ||
| 196 | |||
| 197 | Pipe_Freeze(); | ||
| 198 | |||
| 199 | return PIPE_RWSTREAM_NoError; | ||
| 200 | } | ||
| 201 | |||
| 202 | bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, | ||
| 203 | MIDI_EventPacket_t* const Event) | ||
| 204 | { | ||
| 205 | if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) | ||
| 206 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 207 | |||
| 208 | bool DataReady = false; | ||
| 209 | |||
| 210 | Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipe.Address); | ||
| 211 | Pipe_Unfreeze(); | ||
| 212 | |||
| 213 | if (Pipe_IsINReceived()) | ||
| 214 | { | ||
| 215 | if (Pipe_BytesInPipe()) | ||
| 216 | { | ||
| 217 | Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL); | ||
| 218 | DataReady = true; | ||
| 219 | } | ||
| 220 | |||
| 221 | if (!(Pipe_BytesInPipe())) | ||
| 222 | Pipe_ClearIN(); | ||
| 223 | } | ||
| 224 | |||
| 225 | Pipe_Freeze(); | ||
| 226 | |||
| 227 | return DataReady; | ||
| 228 | } | ||
| 229 | |||
| 230 | #endif | ||
| 231 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h new file mode 100644 index 000000000..9cae21a1b --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h | |||
| @@ -0,0 +1,190 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB MIDI Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB MIDI Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassMIDI | ||
| 41 | * \defgroup Group_USBClassMIDIHost MIDI Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassMIDIHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/MIDIClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassMIDIHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the MIDI USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __MIDI_CLASS_HOST_H__ | ||
| 54 | #define __MIDI_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/MIDIClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_MIDI_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Defines: */ | ||
| 72 | /** \brief MIDI Class Host Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 75 | * and passed to each of the MIDI class driver functions as the \c MIDIInterfaceInfo parameter. This | ||
| 76 | * stores each MIDI interface's configuration and state information. | ||
| 77 | */ | ||
| 78 | typedef struct | ||
| 79 | { | ||
| 80 | struct | ||
| 81 | { | ||
| 82 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 83 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 84 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 85 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 86 | */ | ||
| 87 | struct | ||
| 88 | { | ||
| 89 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 90 | * after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 91 | * Configured state. | ||
| 92 | */ | ||
| 93 | uint8_t InterfaceNumber; /**< Interface index of the MIDI interface within the attached device. */ | ||
| 94 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 95 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 96 | * the interface is enumerated. | ||
| 97 | */ | ||
| 98 | } USB_ClassInfo_MIDI_Host_t; | ||
| 99 | |||
| 100 | /* Enums: */ | ||
| 101 | /** Enum for the possible error codes returned by the \ref MIDI_Host_ConfigurePipes() function. */ | ||
| 102 | enum MIDI_Host_EnumerationFailure_ErrorCodes_t | ||
| 103 | { | ||
| 104 | MIDI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 105 | MIDI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 106 | MIDI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor. */ | ||
| 107 | MIDI_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 108 | }; | ||
| 109 | |||
| 110 | /* Function Prototypes: */ | ||
| 111 | /** Host interface configuration routine, to configure a given MIDI host interface instance using the Configuration | ||
| 112 | * Descriptor read from an attached USB device. This function automatically updates the given MIDI Host instance's | ||
| 113 | * state values and configures the pipes required to communicate with the interface if it is found within the device. | ||
| 114 | * This should be called once after the stack has enumerated the attached device, while the host state machine is in | ||
| 115 | * the Addressed state. | ||
| 116 | * | ||
| 117 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state. | ||
| 118 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 119 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 120 | * | ||
| 121 | * \return A value from the \ref MIDI_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 122 | */ | ||
| 123 | uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, | ||
| 124 | uint16_t ConfigDescriptorSize, | ||
| 125 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 126 | |||
| 127 | /** General management task for a given MIDI host class interface, required for the correct operation of the interface. This should | ||
| 128 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 129 | * | ||
| 130 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state. | ||
| 131 | */ | ||
| 132 | void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 133 | |||
| 134 | /** Sends a MIDI event packet to the device. If no device is connected, the event packet is discarded. | ||
| 135 | * | ||
| 136 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 137 | * call will fail. | ||
| 138 | * | ||
| 139 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 140 | * \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send. | ||
| 141 | * | ||
| 142 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 143 | */ | ||
| 144 | uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, | ||
| 145 | MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 146 | |||
| 147 | /** Flushes the MIDI send buffer, sending any queued MIDI events to the device. This should be called to override the | ||
| 148 | * \ref MIDI_Host_SendEventPacket() function's packing behavior, to flush queued events. Events are queued into the | ||
| 149 | * pipe bank until either the pipe bank is full, or \ref MIDI_Host_Flush() is called. This allows for multiple MIDI | ||
| 150 | * events to be packed into a single pipe packet, increasing data throughput. | ||
| 151 | * | ||
| 152 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 153 | * | ||
| 154 | * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. | ||
| 155 | */ | ||
| 156 | uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 157 | |||
| 158 | /** Receives a MIDI event packet from the device. | ||
| 159 | * | ||
| 160 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 161 | * call will fail. | ||
| 162 | * | ||
| 163 | * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. | ||
| 164 | * \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed. | ||
| 165 | * | ||
| 166 | * \return Boolean \c true if a MIDI event packet was received, \c false otherwise. | ||
| 167 | */ | ||
| 168 | bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, | ||
| 169 | MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 170 | |||
| 171 | /* Private Interface - For use in library only: */ | ||
| 172 | #if !defined(__DOXYGEN__) | ||
| 173 | /* Function Prototypes: */ | ||
| 174 | #if defined(__INCLUDE_FROM_MIDI_HOST_C) | ||
| 175 | static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor) | ||
| 176 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 177 | static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor) | ||
| 178 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 179 | #endif | ||
| 180 | #endif | ||
| 181 | |||
| 182 | /* Disable C linkage for C++ Compilers: */ | ||
| 183 | #if defined(__cplusplus) | ||
| 184 | } | ||
| 185 | #endif | ||
| 186 | |||
| 187 | #endif | ||
| 188 | |||
| 189 | /** @} */ | ||
| 190 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c new file mode 100644 index 000000000..f7c5a6a73 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c | |||
| @@ -0,0 +1,579 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_MS_DRIVER | ||
| 37 | #define __INCLUDE_FROM_MASSSTORAGE_HOST_C | ||
| 38 | #include "MassStorageClassHost.h" | ||
| 39 | |||
| 40 | uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Interface_t* MassStorageInterface = NULL; | ||
| 47 | |||
| 48 | memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State)); | ||
| 49 | |||
| 50 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 51 | return MS_ENUMERROR_InvalidConfigDescriptor; | ||
| 52 | |||
| 53 | while (!(DataINEndpoint) || !(DataOUTEndpoint)) | ||
| 54 | { | ||
| 55 | if (!(MassStorageInterface) || | ||
| 56 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 57 | DCOMP_MS_Host_NextMSInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 58 | { | ||
| 59 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 60 | DCOMP_MS_Host_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 61 | { | ||
| 62 | return MS_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 63 | } | ||
| 64 | |||
| 65 | MassStorageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 66 | |||
| 67 | DataINEndpoint = NULL; | ||
| 68 | DataOUTEndpoint = NULL; | ||
| 69 | |||
| 70 | continue; | ||
| 71 | } | ||
| 72 | |||
| 73 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 74 | |||
| 75 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 76 | DataINEndpoint = EndpointData; | ||
| 77 | else | ||
| 78 | DataOUTEndpoint = EndpointData; | ||
| 79 | } | ||
| 80 | |||
| 81 | MSInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 82 | MSInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 83 | MSInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; | ||
| 84 | |||
| 85 | MSInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 86 | MSInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 87 | MSInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; | ||
| 88 | |||
| 89 | if (!(Pipe_ConfigurePipeTable(&MSInterfaceInfo->Config.DataINPipe, 1))) | ||
| 90 | return MS_ENUMERROR_PipeConfigurationFailed; | ||
| 91 | |||
| 92 | if (!(Pipe_ConfigurePipeTable(&MSInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 93 | return MS_ENUMERROR_PipeConfigurationFailed; | ||
| 94 | |||
| 95 | MSInterfaceInfo->State.InterfaceNumber = MassStorageInterface->InterfaceNumber; | ||
| 96 | MSInterfaceInfo->State.IsActive = true; | ||
| 97 | |||
| 98 | return MS_ENUMERROR_NoError; | ||
| 99 | } | ||
| 100 | |||
| 101 | static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor) | ||
| 102 | { | ||
| 103 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 104 | |||
| 105 | if (Header->Type == DTYPE_Interface) | ||
| 106 | { | ||
| 107 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 108 | |||
| 109 | if ((Interface->Class == MS_CSCP_MassStorageClass) && | ||
| 110 | (Interface->SubClass == MS_CSCP_SCSITransparentSubclass) && | ||
| 111 | (Interface->Protocol == MS_CSCP_BulkOnlyTransportProtocol)) | ||
| 112 | { | ||
| 113 | return DESCRIPTOR_SEARCH_Found; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 118 | } | ||
| 119 | |||
| 120 | static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 121 | { | ||
| 122 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 123 | |||
| 124 | if (Header->Type == DTYPE_Endpoint) | ||
| 125 | { | ||
| 126 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 127 | |||
| 128 | uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); | ||
| 129 | |||
| 130 | if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) | ||
| 131 | { | ||
| 132 | return DESCRIPTOR_SEARCH_Found; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | else if (Header->Type == DTYPE_Interface) | ||
| 136 | { | ||
| 137 | return DESCRIPTOR_SEARCH_Fail; | ||
| 138 | } | ||
| 139 | |||
| 140 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 141 | } | ||
| 142 | |||
| 143 | static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 144 | MS_CommandBlockWrapper_t* const SCSICommandBlock, | ||
| 145 | const void* const BufferPtr) | ||
| 146 | { | ||
| 147 | uint8_t ErrorCode = PIPE_RWSTREAM_NoError; | ||
| 148 | |||
| 149 | if (++MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF) | ||
| 150 | MSInterfaceInfo->State.TransactionTag = 1; | ||
| 151 | |||
| 152 | SCSICommandBlock->Signature = CPU_TO_LE32(MS_CBW_SIGNATURE); | ||
| 153 | SCSICommandBlock->Tag = cpu_to_le32(MSInterfaceInfo->State.TransactionTag); | ||
| 154 | |||
| 155 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 156 | Pipe_Unfreeze(); | ||
| 157 | |||
| 158 | if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t), | ||
| 159 | NULL)) != PIPE_RWSTREAM_NoError) | ||
| 160 | { | ||
| 161 | return ErrorCode; | ||
| 162 | } | ||
| 163 | |||
| 164 | Pipe_ClearOUT(); | ||
| 165 | Pipe_WaitUntilReady(); | ||
| 166 | |||
| 167 | Pipe_Freeze(); | ||
| 168 | |||
| 169 | if (BufferPtr != NULL) | ||
| 170 | { | ||
| 171 | ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr); | ||
| 172 | |||
| 173 | if ((ErrorCode != PIPE_RWSTREAM_NoError) && (ErrorCode != PIPE_RWSTREAM_PipeStalled)) | ||
| 174 | { | ||
| 175 | Pipe_Freeze(); | ||
| 176 | return ErrorCode; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | MS_CommandStatusWrapper_t SCSIStatusBlock; | ||
| 181 | return MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSIStatusBlock); | ||
| 182 | } | ||
| 183 | |||
| 184 | static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) | ||
| 185 | { | ||
| 186 | uint16_t TimeoutMSRem = MS_COMMAND_DATA_TIMEOUT_MS; | ||
| 187 | uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); | ||
| 188 | |||
| 189 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); | ||
| 190 | Pipe_Unfreeze(); | ||
| 191 | |||
| 192 | while (!(Pipe_IsINReceived())) | ||
| 193 | { | ||
| 194 | uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); | ||
| 195 | |||
| 196 | if (CurrentFrameNumber != PreviousFrameNumber) | ||
| 197 | { | ||
| 198 | PreviousFrameNumber = CurrentFrameNumber; | ||
| 199 | |||
| 200 | if (!(TimeoutMSRem--)) | ||
| 201 | return PIPE_RWSTREAM_Timeout; | ||
| 202 | } | ||
| 203 | |||
| 204 | Pipe_Freeze(); | ||
| 205 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 206 | Pipe_Unfreeze(); | ||
| 207 | |||
| 208 | if (Pipe_IsStalled()) | ||
| 209 | { | ||
| 210 | USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); | ||
| 211 | return PIPE_RWSTREAM_PipeStalled; | ||
| 212 | } | ||
| 213 | |||
| 214 | Pipe_Freeze(); | ||
| 215 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); | ||
| 216 | Pipe_Unfreeze(); | ||
| 217 | |||
| 218 | if (Pipe_IsStalled()) | ||
| 219 | { | ||
| 220 | USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); | ||
| 221 | return PIPE_RWSTREAM_PipeStalled; | ||
| 222 | } | ||
| 223 | |||
| 224 | if (USB_HostState == HOST_STATE_Unattached) | ||
| 225 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 226 | }; | ||
| 227 | |||
| 228 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); | ||
| 229 | Pipe_Freeze(); | ||
| 230 | |||
| 231 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 232 | Pipe_Freeze(); | ||
| 233 | |||
| 234 | return PIPE_RWSTREAM_NoError; | ||
| 235 | } | ||
| 236 | |||
| 237 | static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 238 | MS_CommandBlockWrapper_t* const SCSICommandBlock, | ||
| 239 | void* BufferPtr) | ||
| 240 | { | ||
| 241 | uint8_t ErrorCode = PIPE_RWSTREAM_NoError; | ||
| 242 | uint16_t BytesRem = le32_to_cpu(SCSICommandBlock->DataTransferLength); | ||
| 243 | |||
| 244 | if (SCSICommandBlock->Flags & MS_COMMAND_DIR_DATA_IN) | ||
| 245 | { | ||
| 246 | if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError) | ||
| 247 | { | ||
| 248 | Pipe_Freeze(); | ||
| 249 | return ErrorCode; | ||
| 250 | } | ||
| 251 | |||
| 252 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); | ||
| 253 | Pipe_Unfreeze(); | ||
| 254 | |||
| 255 | if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError) | ||
| 256 | return ErrorCode; | ||
| 257 | |||
| 258 | Pipe_ClearIN(); | ||
| 259 | } | ||
| 260 | else | ||
| 261 | { | ||
| 262 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 263 | Pipe_Unfreeze(); | ||
| 264 | |||
| 265 | if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError) | ||
| 266 | return ErrorCode; | ||
| 267 | |||
| 268 | Pipe_ClearOUT(); | ||
| 269 | |||
| 270 | while (!(Pipe_IsOUTReady())) | ||
| 271 | { | ||
| 272 | if (USB_HostState == HOST_STATE_Unattached) | ||
| 273 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | Pipe_Freeze(); | ||
| 278 | |||
| 279 | return ErrorCode; | ||
| 280 | } | ||
| 281 | |||
| 282 | static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 283 | MS_CommandStatusWrapper_t* const SCSICommandStatus) | ||
| 284 | { | ||
| 285 | uint8_t ErrorCode = PIPE_RWSTREAM_NoError; | ||
| 286 | |||
| 287 | if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError) | ||
| 288 | return ErrorCode; | ||
| 289 | |||
| 290 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); | ||
| 291 | Pipe_Unfreeze(); | ||
| 292 | |||
| 293 | if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t), | ||
| 294 | NULL)) != PIPE_RWSTREAM_NoError) | ||
| 295 | { | ||
| 296 | return ErrorCode; | ||
| 297 | } | ||
| 298 | |||
| 299 | Pipe_ClearIN(); | ||
| 300 | Pipe_Freeze(); | ||
| 301 | |||
| 302 | if (SCSICommandStatus->Status != MS_SCSI_COMMAND_Pass) | ||
| 303 | ErrorCode = MS_ERROR_LOGICAL_CMD_FAILED; | ||
| 304 | |||
| 305 | return ErrorCode; | ||
| 306 | } | ||
| 307 | |||
| 308 | uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) | ||
| 309 | { | ||
| 310 | uint8_t ErrorCode; | ||
| 311 | |||
| 312 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 313 | { | ||
| 314 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 315 | .bRequest = MS_REQ_MassStorageReset, | ||
| 316 | .wValue = 0, | ||
| 317 | .wIndex = MSInterfaceInfo->State.InterfaceNumber, | ||
| 318 | .wLength = 0, | ||
| 319 | }; | ||
| 320 | |||
| 321 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 322 | |||
| 323 | if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) | ||
| 324 | return ErrorCode; | ||
| 325 | |||
| 326 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); | ||
| 327 | |||
| 328 | if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) | ||
| 329 | return ErrorCode; | ||
| 330 | |||
| 331 | Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 332 | |||
| 333 | if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) | ||
| 334 | return ErrorCode; | ||
| 335 | |||
| 336 | return HOST_SENDCONTROL_Successful; | ||
| 337 | } | ||
| 338 | |||
| 339 | uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 340 | uint8_t* const MaxLUNIndex) | ||
| 341 | { | ||
| 342 | uint8_t ErrorCode; | ||
| 343 | |||
| 344 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 345 | { | ||
| 346 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 347 | .bRequest = MS_REQ_GetMaxLUN, | ||
| 348 | .wValue = 0, | ||
| 349 | .wIndex = MSInterfaceInfo->State.InterfaceNumber, | ||
| 350 | .wLength = 1, | ||
| 351 | }; | ||
| 352 | |||
| 353 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 354 | |||
| 355 | if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled) | ||
| 356 | { | ||
| 357 | *MaxLUNIndex = 0; | ||
| 358 | ErrorCode = HOST_SENDCONTROL_Successful; | ||
| 359 | } | ||
| 360 | |||
| 361 | return ErrorCode; | ||
| 362 | } | ||
| 363 | |||
| 364 | uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 365 | const uint8_t LUNIndex, | ||
| 366 | SCSI_Inquiry_Response_t* const InquiryData) | ||
| 367 | { | ||
| 368 | if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) | ||
| 369 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 370 | |||
| 371 | MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) | ||
| 372 | { | ||
| 373 | .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Inquiry_Response_t)), | ||
| 374 | .Flags = MS_COMMAND_DIR_DATA_IN, | ||
| 375 | .LUN = LUNIndex, | ||
| 376 | .SCSICommandLength = 6, | ||
| 377 | .SCSICommandData = | ||
| 378 | { | ||
| 379 | SCSI_CMD_INQUIRY, | ||
| 380 | 0x00, // Reserved | ||
| 381 | 0x00, // Reserved | ||
| 382 | 0x00, // Reserved | ||
| 383 | sizeof(SCSI_Inquiry_Response_t), // Allocation Length | ||
| 384 | 0x00 // Unused (control) | ||
| 385 | } | ||
| 386 | }; | ||
| 387 | |||
| 388 | return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, InquiryData); | ||
| 389 | } | ||
| 390 | |||
| 391 | uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 392 | const uint8_t LUNIndex) | ||
| 393 | { | ||
| 394 | if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) | ||
| 395 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 396 | |||
| 397 | MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) | ||
| 398 | { | ||
| 399 | .DataTransferLength = CPU_TO_LE32(0), | ||
| 400 | .Flags = MS_COMMAND_DIR_DATA_IN, | ||
| 401 | .LUN = LUNIndex, | ||
| 402 | .SCSICommandLength = 6, | ||
| 403 | .SCSICommandData = | ||
| 404 | { | ||
| 405 | SCSI_CMD_TEST_UNIT_READY, | ||
| 406 | 0x00, // Reserved | ||
| 407 | 0x00, // Reserved | ||
| 408 | 0x00, // Reserved | ||
| 409 | 0x00, // Reserved | ||
| 410 | 0x00 // Unused (control) | ||
| 411 | } | ||
| 412 | }; | ||
| 413 | |||
| 414 | return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL); | ||
| 415 | } | ||
| 416 | |||
| 417 | uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 418 | const uint8_t LUNIndex, | ||
| 419 | SCSI_Capacity_t* const DeviceCapacity) | ||
| 420 | { | ||
| 421 | if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) | ||
| 422 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 423 | |||
| 424 | uint8_t ErrorCode; | ||
| 425 | |||
| 426 | MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) | ||
| 427 | { | ||
| 428 | .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Capacity_t)), | ||
| 429 | .Flags = MS_COMMAND_DIR_DATA_IN, | ||
| 430 | .LUN = LUNIndex, | ||
| 431 | .SCSICommandLength = 10, | ||
| 432 | .SCSICommandData = | ||
| 433 | { | ||
| 434 | SCSI_CMD_READ_CAPACITY_10, | ||
| 435 | 0x00, // Reserved | ||
| 436 | 0x00, // MSB of Logical block address | ||
| 437 | 0x00, | ||
| 438 | 0x00, | ||
| 439 | 0x00, // LSB of Logical block address | ||
| 440 | 0x00, // Reserved | ||
| 441 | 0x00, // Reserved | ||
| 442 | 0x00, // Partial Medium Indicator | ||
| 443 | 0x00 // Unused (control) | ||
| 444 | } | ||
| 445 | }; | ||
| 446 | |||
| 447 | if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, DeviceCapacity)) != PIPE_RWSTREAM_NoError) | ||
| 448 | return ErrorCode; | ||
| 449 | |||
| 450 | DeviceCapacity->Blocks = BE32_TO_CPU(DeviceCapacity->Blocks); | ||
| 451 | DeviceCapacity->BlockSize = BE32_TO_CPU(DeviceCapacity->BlockSize); | ||
| 452 | |||
| 453 | return PIPE_RWSTREAM_NoError; | ||
| 454 | } | ||
| 455 | |||
| 456 | uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 457 | const uint8_t LUNIndex, | ||
| 458 | SCSI_Request_Sense_Response_t* const SenseData) | ||
| 459 | { | ||
| 460 | if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) | ||
| 461 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 462 | |||
| 463 | MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) | ||
| 464 | { | ||
| 465 | .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Request_Sense_Response_t)), | ||
| 466 | .Flags = MS_COMMAND_DIR_DATA_IN, | ||
| 467 | .LUN = LUNIndex, | ||
| 468 | .SCSICommandLength = 6, | ||
| 469 | .SCSICommandData = | ||
| 470 | { | ||
| 471 | SCSI_CMD_REQUEST_SENSE, | ||
| 472 | 0x00, // Reserved | ||
| 473 | 0x00, // Reserved | ||
| 474 | 0x00, // Reserved | ||
| 475 | sizeof(SCSI_Request_Sense_Response_t), // Allocation Length | ||
| 476 | 0x00 // Unused (control) | ||
| 477 | } | ||
| 478 | }; | ||
| 479 | |||
| 480 | return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, SenseData); | ||
| 481 | } | ||
| 482 | |||
| 483 | uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 484 | const uint8_t LUNIndex, | ||
| 485 | const bool PreventRemoval) | ||
| 486 | { | ||
| 487 | if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) | ||
| 488 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 489 | |||
| 490 | MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) | ||
| 491 | { | ||
| 492 | .DataTransferLength = CPU_TO_LE32(0), | ||
| 493 | .Flags = MS_COMMAND_DIR_DATA_OUT, | ||
| 494 | .LUN = LUNIndex, | ||
| 495 | .SCSICommandLength = 6, | ||
| 496 | .SCSICommandData = | ||
| 497 | { | ||
| 498 | SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL, | ||
| 499 | 0x00, // Reserved | ||
| 500 | 0x00, // Reserved | ||
| 501 | PreventRemoval, // Prevent flag | ||
| 502 | 0x00, // Reserved | ||
| 503 | 0x00 // Unused (control) | ||
| 504 | } | ||
| 505 | }; | ||
| 506 | |||
| 507 | return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL); | ||
| 508 | } | ||
| 509 | |||
| 510 | uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 511 | const uint8_t LUNIndex, | ||
| 512 | const uint32_t BlockAddress, | ||
| 513 | const uint8_t Blocks, | ||
| 514 | const uint16_t BlockSize, | ||
| 515 | void* BlockBuffer) | ||
| 516 | { | ||
| 517 | if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) | ||
| 518 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 519 | |||
| 520 | MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) | ||
| 521 | { | ||
| 522 | .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize), | ||
| 523 | .Flags = MS_COMMAND_DIR_DATA_IN, | ||
| 524 | .LUN = LUNIndex, | ||
| 525 | .SCSICommandLength = 10, | ||
| 526 | .SCSICommandData = | ||
| 527 | { | ||
| 528 | SCSI_CMD_READ_10, | ||
| 529 | 0x00, // Unused (control bits, all off) | ||
| 530 | (BlockAddress >> 24), // MSB of Block Address | ||
| 531 | (BlockAddress >> 16), | ||
| 532 | (BlockAddress >> 8), | ||
| 533 | (BlockAddress & 0xFF), // LSB of Block Address | ||
| 534 | 0x00, // Reserved | ||
| 535 | 0x00, // MSB of Total Blocks to Read | ||
| 536 | Blocks, // LSB of Total Blocks to Read | ||
| 537 | 0x00 // Unused (control) | ||
| 538 | } | ||
| 539 | }; | ||
| 540 | |||
| 541 | return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer); | ||
| 542 | } | ||
| 543 | |||
| 544 | uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 545 | const uint8_t LUNIndex, | ||
| 546 | const uint32_t BlockAddress, | ||
| 547 | const uint8_t Blocks, | ||
| 548 | const uint16_t BlockSize, | ||
| 549 | const void* BlockBuffer) | ||
| 550 | { | ||
| 551 | if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) | ||
| 552 | return HOST_SENDCONTROL_DeviceDisconnected; | ||
| 553 | |||
| 554 | MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) | ||
| 555 | { | ||
| 556 | .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize), | ||
| 557 | .Flags = MS_COMMAND_DIR_DATA_OUT, | ||
| 558 | .LUN = LUNIndex, | ||
| 559 | .SCSICommandLength = 10, | ||
| 560 | .SCSICommandData = | ||
| 561 | { | ||
| 562 | SCSI_CMD_WRITE_10, | ||
| 563 | 0x00, // Unused (control bits, all off) | ||
| 564 | (BlockAddress >> 24), // MSB of Block Address | ||
| 565 | (BlockAddress >> 16), | ||
| 566 | (BlockAddress >> 8), | ||
| 567 | (BlockAddress & 0xFF), // LSB of Block Address | ||
| 568 | 0x00, // Reserved | ||
| 569 | 0x00, // MSB of Total Blocks to Write | ||
| 570 | Blocks, // LSB of Total Blocks to Write | ||
| 571 | 0x00 // Unused (control) | ||
| 572 | } | ||
| 573 | }; | ||
| 574 | |||
| 575 | return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer); | ||
| 576 | } | ||
| 577 | |||
| 578 | #endif | ||
| 579 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h new file mode 100644 index 000000000..348050f8f --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h | |||
| @@ -0,0 +1,335 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB Mass Storage Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB Mass Storage Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassMS | ||
| 41 | * \defgroup Group_USBClassMassStorageHost Mass Storage Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassMassStorageHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassMassStorageHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the Mass Storage USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __MS_CLASS_HOST_H__ | ||
| 54 | #define __MS_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/MassStorageClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_MS_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Macros: */ | ||
| 72 | /** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error. */ | ||
| 73 | #define MS_ERROR_LOGICAL_CMD_FAILED 0x80 | ||
| 74 | |||
| 75 | /* Type Defines: */ | ||
| 76 | /** \brief Mass Storage Class Host Mode Configuration and State Structure. | ||
| 77 | * | ||
| 78 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 79 | * and passed to each of the Mass Storage class driver functions as the \c MSInterfaceInfo parameter. This | ||
| 80 | * stores each Mass Storage interface's configuration and state information. | ||
| 81 | */ | ||
| 82 | typedef struct | ||
| 83 | { | ||
| 84 | struct | ||
| 85 | { | ||
| 86 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 87 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 88 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 89 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 90 | */ | ||
| 91 | struct | ||
| 92 | { | ||
| 93 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 94 | * after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 95 | * Configured state. | ||
| 96 | */ | ||
| 97 | uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */ | ||
| 98 | |||
| 99 | uint32_t TransactionTag; /**< Current transaction tag for data synchronizing of packets. */ | ||
| 100 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 101 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 102 | * the interface is enumerated. | ||
| 103 | */ | ||
| 104 | } USB_ClassInfo_MS_Host_t; | ||
| 105 | |||
| 106 | /** \brief SCSI Device LUN Capacity Structure. | ||
| 107 | * | ||
| 108 | * SCSI capacity structure, to hold the total capacity of the device in both the number | ||
| 109 | * of blocks in the current LUN, and the size of each block. This structure is filled by | ||
| 110 | * the device when the \ref MS_Host_ReadDeviceCapacity() function is called. | ||
| 111 | */ | ||
| 112 | typedef struct | ||
| 113 | { | ||
| 114 | uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device. */ | ||
| 115 | uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN. */ | ||
| 116 | } SCSI_Capacity_t; | ||
| 117 | |||
| 118 | /* Enums: */ | ||
| 119 | /** Enum for the possible error codes returned by the \ref MS_Host_ConfigurePipes() function. */ | ||
| 120 | enum MS_Host_EnumerationFailure_ErrorCodes_t | ||
| 121 | { | ||
| 122 | MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 123 | MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 124 | MS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor. */ | ||
| 125 | MS_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 126 | }; | ||
| 127 | |||
| 128 | /* Function Prototypes: */ | ||
| 129 | /** Host interface configuration routine, to configure a given Mass Storage host interface instance using the | ||
| 130 | * Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass | ||
| 131 | * Storage Host instance's state values and configures the pipes required to communicate with the interface if it | ||
| 132 | * is found within the device. This should be called once after the stack has enumerated the attached device, while | ||
| 133 | * the host state machine is in the Addressed state. | ||
| 134 | * | ||
| 135 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state. | ||
| 136 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 137 | * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 138 | * | ||
| 139 | * \return A value from the \ref MS_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 140 | */ | ||
| 141 | uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 142 | uint16_t ConfigDescriptorSize, | ||
| 143 | void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 144 | |||
| 145 | /** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface | ||
| 146 | * and readying it for the next Mass Storage command. This should be called after a failed SCSI request to | ||
| 147 | * ensure the attached Mass Storage device is ready to receive the next command. | ||
| 148 | * | ||
| 149 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 150 | * | ||
| 151 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 152 | */ | ||
| 153 | uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 154 | |||
| 155 | /** Sends a GET MAX LUN control request to the attached device, retrieving the index of the highest LUN (Logical | ||
| 156 | * UNit, a logical drive) in the device. This value can then be used in the other functions of the Mass Storage | ||
| 157 | * Host mode Class driver to address a specific LUN within the device. | ||
| 158 | * | ||
| 159 | * \note Some devices do not support this request, and will STALL it when issued. To get around this, | ||
| 160 | * on unsupported devices the max LUN index will be reported as zero and no error will be returned | ||
| 161 | * if the device STALLs the request. | ||
| 162 | * | ||
| 163 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 164 | * \param[out] MaxLUNIndex Pointer to a location where the highest LUN index value should be stored. | ||
| 165 | * | ||
| 166 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 167 | */ | ||
| 168 | uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 169 | uint8_t* const MaxLUNIndex) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 170 | |||
| 171 | /** Retrieves the Mass Storage device's inquiry data for the specified LUN, indicating the device characteristics and | ||
| 172 | * properties. | ||
| 173 | * | ||
| 174 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 175 | * call will fail. | ||
| 176 | * | ||
| 177 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 178 | * \param[in] LUNIndex LUN index within the device the command is being issued to. | ||
| 179 | * \param[out] InquiryData Location where the read inquiry data should be stored. | ||
| 180 | * | ||
| 181 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED. | ||
| 182 | */ | ||
| 183 | uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 184 | const uint8_t LUNIndex, | ||
| 185 | SCSI_Inquiry_Response_t* const InquiryData) ATTR_NON_NULL_PTR_ARG(1) | ||
| 186 | ATTR_NON_NULL_PTR_ARG(3); | ||
| 187 | |||
| 188 | /** Sends a TEST UNIT READY command to the device, to determine if it is ready to accept other SCSI commands. | ||
| 189 | * | ||
| 190 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 191 | * \param[in] LUNIndex LUN index within the device the command is being issued to. | ||
| 192 | * | ||
| 193 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. | ||
| 194 | */ | ||
| 195 | uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 196 | const uint8_t LUNIndex) ATTR_NON_NULL_PTR_ARG(1); | ||
| 197 | |||
| 198 | /** Retrieves the total capacity of the attached USB Mass Storage device, in blocks, and block size. | ||
| 199 | * | ||
| 200 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 201 | * call will fail. | ||
| 202 | * | ||
| 203 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 204 | * \param[in] LUNIndex LUN index within the device the command is being issued to. | ||
| 205 | * \param[out] DeviceCapacity Pointer to the location where the capacity information should be stored. | ||
| 206 | * | ||
| 207 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. | ||
| 208 | */ | ||
| 209 | uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 210 | const uint8_t LUNIndex, | ||
| 211 | SCSI_Capacity_t* const DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1) | ||
| 212 | ATTR_NON_NULL_PTR_ARG(3); | ||
| 213 | |||
| 214 | /** Retrieves the device sense data, indicating the current device state and error codes for the previously | ||
| 215 | * issued command. | ||
| 216 | * | ||
| 217 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 218 | * call will fail. | ||
| 219 | * | ||
| 220 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 221 | * \param[in] LUNIndex LUN index within the device the command is being issued to. | ||
| 222 | * \param[out] SenseData Pointer to the location where the sense information should be stored. | ||
| 223 | * | ||
| 224 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. | ||
| 225 | */ | ||
| 226 | uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 227 | const uint8_t LUNIndex, | ||
| 228 | SCSI_Request_Sense_Response_t* const SenseData) ATTR_NON_NULL_PTR_ARG(1) | ||
| 229 | ATTR_NON_NULL_PTR_ARG(3); | ||
| 230 | |||
| 231 | /** Issues a PREVENT MEDIUM REMOVAL command, to logically (or, depending on the type of device, physically) lock | ||
| 232 | * the device from removal so that blocks of data on the medium can be read or altered. | ||
| 233 | * | ||
| 234 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 235 | * call will fail. | ||
| 236 | * | ||
| 237 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 238 | * \param[in] LUNIndex LUN index within the device the command is being issued to. | ||
| 239 | * \param[in] PreventRemoval Boolean \c true if the device should be locked from removal, \c false otherwise. | ||
| 240 | * | ||
| 241 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. | ||
| 242 | */ | ||
| 243 | uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 244 | const uint8_t LUNIndex, | ||
| 245 | const bool PreventRemoval) ATTR_NON_NULL_PTR_ARG(1); | ||
| 246 | |||
| 247 | /** Reads blocks of data from the attached Mass Storage device's medium. | ||
| 248 | * | ||
| 249 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 250 | * call will fail. | ||
| 251 | * | ||
| 252 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 253 | * \param[in] LUNIndex LUN index within the device the command is being issued to. | ||
| 254 | * \param[in] BlockAddress Starting block address within the device to read from. | ||
| 255 | * \param[in] Blocks Total number of blocks to read. | ||
| 256 | * \param[in] BlockSize Size in bytes of each block within the device. | ||
| 257 | * \param[out] BlockBuffer Pointer to where the read data from the device should be stored. | ||
| 258 | * | ||
| 259 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. | ||
| 260 | */ | ||
| 261 | uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 262 | const uint8_t LUNIndex, | ||
| 263 | const uint32_t BlockAddress, | ||
| 264 | const uint8_t Blocks, | ||
| 265 | const uint16_t BlockSize, | ||
| 266 | void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6); | ||
| 267 | |||
| 268 | /** Writes blocks of data to the attached Mass Storage device's medium. | ||
| 269 | * | ||
| 270 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 271 | * call will fail. | ||
| 272 | * | ||
| 273 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. | ||
| 274 | * \param[in] LUNIndex LUN index within the device the command is being issued to. | ||
| 275 | * \param[in] BlockAddress Starting block address within the device to write to. | ||
| 276 | * \param[in] Blocks Total number of blocks to read. | ||
| 277 | * \param[in] BlockSize Size in bytes of each block within the device. | ||
| 278 | * \param[in] BlockBuffer Pointer to where the data to write should be sourced from. | ||
| 279 | * | ||
| 280 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. | ||
| 281 | */ | ||
| 282 | uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 283 | const uint8_t LUNIndex, | ||
| 284 | const uint32_t BlockAddress, | ||
| 285 | const uint8_t Blocks, | ||
| 286 | const uint16_t BlockSize, | ||
| 287 | const void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6); | ||
| 288 | |||
| 289 | /* Inline Functions: */ | ||
| 290 | /** General management task for a given Mass Storage host class interface, required for the correct operation of | ||
| 291 | * the interface. This should be called frequently in the main program loop, before the master USB management task | ||
| 292 | * \ref USB_USBTask(). | ||
| 293 | * | ||
| 294 | * \param[in,out] MSInterfaceInfo Pointer to a structure containing an Mass Storage Class host configuration and state. | ||
| 295 | */ | ||
| 296 | static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 297 | static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) | ||
| 298 | { | ||
| 299 | (void)MSInterfaceInfo; | ||
| 300 | } | ||
| 301 | |||
| 302 | /* Private Interface - For use in library only: */ | ||
| 303 | #if !defined(__DOXYGEN__) | ||
| 304 | /* Macros: */ | ||
| 305 | #define MS_COMMAND_DATA_TIMEOUT_MS 10000 | ||
| 306 | |||
| 307 | /* Function Prototypes: */ | ||
| 308 | #if defined(__INCLUDE_FROM_MASSSTORAGE_HOST_C) | ||
| 309 | static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 310 | MS_CommandBlockWrapper_t* const SCSICommandBlock, | ||
| 311 | const void* const BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 312 | static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 313 | static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 314 | MS_CommandBlockWrapper_t* const SCSICommandBlock, | ||
| 315 | void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 316 | static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, | ||
| 317 | MS_CommandStatusWrapper_t* const SCSICommandStatus) | ||
| 318 | ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 319 | |||
| 320 | static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor) | ||
| 321 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 322 | static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 323 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 324 | #endif | ||
| 325 | #endif | ||
| 326 | |||
| 327 | /* Disable C linkage for C++ Compilers: */ | ||
| 328 | #if defined(__cplusplus) | ||
| 329 | } | ||
| 330 | #endif | ||
| 331 | |||
| 332 | #endif | ||
| 333 | |||
| 334 | /** @} */ | ||
| 335 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c new file mode 100644 index 000000000..8a04d0ab8 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c | |||
| @@ -0,0 +1,400 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_PRINTER_DRIVER | ||
| 37 | #define __INCLUDE_FROM_PRINTER_HOST_C | ||
| 38 | #include "PrinterClassHost.h" | ||
| 39 | |||
| 40 | uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Interface_t* PrinterInterface = NULL; | ||
| 47 | |||
| 48 | memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State)); | ||
| 49 | |||
| 50 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 51 | return PRNT_ENUMERROR_InvalidConfigDescriptor; | ||
| 52 | |||
| 53 | while (!(DataINEndpoint) || !(DataOUTEndpoint)) | ||
| 54 | { | ||
| 55 | if (!(PrinterInterface) || | ||
| 56 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 57 | DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 58 | { | ||
| 59 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 60 | DCOMP_PRNT_Host_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 61 | { | ||
| 62 | return PRNT_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 63 | } | ||
| 64 | |||
| 65 | PrinterInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 66 | |||
| 67 | DataINEndpoint = NULL; | ||
| 68 | DataOUTEndpoint = NULL; | ||
| 69 | |||
| 70 | continue; | ||
| 71 | } | ||
| 72 | |||
| 73 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 74 | |||
| 75 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 76 | DataINEndpoint = EndpointData; | ||
| 77 | else | ||
| 78 | DataOUTEndpoint = EndpointData; | ||
| 79 | } | ||
| 80 | |||
| 81 | PRNTInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 82 | PRNTInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 83 | PRNTInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; | ||
| 84 | |||
| 85 | PRNTInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 86 | PRNTInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 87 | PRNTInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; | ||
| 88 | |||
| 89 | if (!(Pipe_ConfigurePipeTable(&PRNTInterfaceInfo->Config.DataINPipe, 1))) | ||
| 90 | return PRNT_ENUMERROR_PipeConfigurationFailed; | ||
| 91 | |||
| 92 | if (!(Pipe_ConfigurePipeTable(&PRNTInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 93 | return PRNT_ENUMERROR_PipeConfigurationFailed; | ||
| 94 | |||
| 95 | PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber; | ||
| 96 | PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting; | ||
| 97 | PRNTInterfaceInfo->State.IsActive = true; | ||
| 98 | |||
| 99 | return PRNT_ENUMERROR_NoError; | ||
| 100 | } | ||
| 101 | |||
| 102 | static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* CurrentDescriptor) | ||
| 103 | { | ||
| 104 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 105 | |||
| 106 | if (Header->Type == DTYPE_Interface) | ||
| 107 | { | ||
| 108 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 109 | |||
| 110 | if ((Interface->Class == PRNT_CSCP_PrinterClass) && | ||
| 111 | (Interface->SubClass == PRNT_CSCP_PrinterSubclass) && | ||
| 112 | (Interface->Protocol == PRNT_CSCP_BidirectionalProtocol)) | ||
| 113 | { | ||
| 114 | return DESCRIPTOR_SEARCH_Found; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 119 | } | ||
| 120 | |||
| 121 | static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* CurrentDescriptor) | ||
| 122 | { | ||
| 123 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 124 | |||
| 125 | if (Header->Type == DTYPE_Endpoint) | ||
| 126 | { | ||
| 127 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 128 | |||
| 129 | uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); | ||
| 130 | |||
| 131 | if (EndpointType == EP_TYPE_BULK) | ||
| 132 | return DESCRIPTOR_SEARCH_Found; | ||
| 133 | } | ||
| 134 | else if (Header->Type == DTYPE_Interface) | ||
| 135 | { | ||
| 136 | return DESCRIPTOR_SEARCH_Fail; | ||
| 137 | } | ||
| 138 | |||
| 139 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 140 | } | ||
| 141 | |||
| 142 | void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) | ||
| 143 | { | ||
| 144 | if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) | ||
| 145 | return; | ||
| 146 | |||
| 147 | #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) | ||
| 148 | PRNT_Host_Flush(PRNTInterfaceInfo); | ||
| 149 | #endif | ||
| 150 | } | ||
| 151 | |||
| 152 | uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) | ||
| 153 | { | ||
| 154 | if (PRNTInterfaceInfo->State.AlternateSetting) | ||
| 155 | { | ||
| 156 | uint8_t ErrorCode; | ||
| 157 | |||
| 158 | if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PRNTInterfaceInfo->State.InterfaceNumber, | ||
| 159 | PRNTInterfaceInfo->State.AlternateSetting)) != HOST_SENDCONTROL_Successful) | ||
| 160 | { | ||
| 161 | return ErrorCode; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | return HOST_SENDCONTROL_Successful; | ||
| 166 | } | ||
| 167 | |||
| 168 | uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 169 | uint8_t* const PortStatus) | ||
| 170 | { | ||
| 171 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 172 | { | ||
| 173 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 174 | .bRequest = PRNT_REQ_GetPortStatus, | ||
| 175 | .wValue = 0, | ||
| 176 | .wIndex = PRNTInterfaceInfo->State.InterfaceNumber, | ||
| 177 | .wLength = sizeof(uint8_t), | ||
| 178 | }; | ||
| 179 | |||
| 180 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 181 | return USB_Host_SendControlRequest(PortStatus); | ||
| 182 | } | ||
| 183 | |||
| 184 | uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) | ||
| 185 | { | ||
| 186 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 187 | { | ||
| 188 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 189 | .bRequest = PRNT_REQ_SoftReset, | ||
| 190 | .wValue = 0, | ||
| 191 | .wIndex = PRNTInterfaceInfo->State.InterfaceNumber, | ||
| 192 | .wLength = 0, | ||
| 193 | }; | ||
| 194 | |||
| 195 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 196 | return USB_Host_SendControlRequest(NULL); | ||
| 197 | } | ||
| 198 | |||
| 199 | uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) | ||
| 200 | { | ||
| 201 | if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) | ||
| 202 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 203 | |||
| 204 | uint8_t ErrorCode; | ||
| 205 | |||
| 206 | Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 207 | Pipe_Unfreeze(); | ||
| 208 | |||
| 209 | if (!(Pipe_BytesInPipe())) | ||
| 210 | return PIPE_READYWAIT_NoError; | ||
| 211 | |||
| 212 | bool BankFull = !(Pipe_IsReadWriteAllowed()); | ||
| 213 | |||
| 214 | Pipe_ClearOUT(); | ||
| 215 | |||
| 216 | if (BankFull) | ||
| 217 | { | ||
| 218 | if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) | ||
| 219 | return ErrorCode; | ||
| 220 | |||
| 221 | Pipe_ClearOUT(); | ||
| 222 | } | ||
| 223 | |||
| 224 | Pipe_Freeze(); | ||
| 225 | |||
| 226 | return PIPE_READYWAIT_NoError; | ||
| 227 | } | ||
| 228 | |||
| 229 | uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 230 | const uint8_t Data) | ||
| 231 | { | ||
| 232 | if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) | ||
| 233 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 234 | |||
| 235 | uint8_t ErrorCode; | ||
| 236 | |||
| 237 | Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 238 | Pipe_Unfreeze(); | ||
| 239 | |||
| 240 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 241 | { | ||
| 242 | Pipe_ClearOUT(); | ||
| 243 | |||
| 244 | if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) | ||
| 245 | return ErrorCode; | ||
| 246 | } | ||
| 247 | |||
| 248 | Pipe_Write_8(Data); | ||
| 249 | Pipe_Freeze(); | ||
| 250 | |||
| 251 | return PIPE_READYWAIT_NoError; | ||
| 252 | } | ||
| 253 | |||
| 254 | uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 255 | const char* const String) | ||
| 256 | { | ||
| 257 | uint8_t ErrorCode; | ||
| 258 | |||
| 259 | if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) | ||
| 260 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 261 | |||
| 262 | Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 263 | Pipe_Unfreeze(); | ||
| 264 | |||
| 265 | if ((ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL)) != PIPE_RWSTREAM_NoError) | ||
| 266 | return ErrorCode; | ||
| 267 | |||
| 268 | Pipe_ClearOUT(); | ||
| 269 | |||
| 270 | ErrorCode = Pipe_WaitUntilReady(); | ||
| 271 | |||
| 272 | Pipe_Freeze(); | ||
| 273 | |||
| 274 | return ErrorCode; | ||
| 275 | } | ||
| 276 | |||
| 277 | uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 278 | const void* Buffer, | ||
| 279 | const uint16_t Length) | ||
| 280 | { | ||
| 281 | uint8_t ErrorCode; | ||
| 282 | |||
| 283 | if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) | ||
| 284 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 285 | |||
| 286 | Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 287 | Pipe_Unfreeze(); | ||
| 288 | |||
| 289 | if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL)) != PIPE_RWSTREAM_NoError) | ||
| 290 | return ErrorCode; | ||
| 291 | |||
| 292 | Pipe_ClearOUT(); | ||
| 293 | |||
| 294 | ErrorCode = Pipe_WaitUntilReady(); | ||
| 295 | |||
| 296 | Pipe_Freeze(); | ||
| 297 | |||
| 298 | return ErrorCode; | ||
| 299 | } | ||
| 300 | |||
| 301 | uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) | ||
| 302 | { | ||
| 303 | if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) | ||
| 304 | return 0; | ||
| 305 | |||
| 306 | Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipe.Address); | ||
| 307 | Pipe_Unfreeze(); | ||
| 308 | |||
| 309 | if (Pipe_IsINReceived()) | ||
| 310 | { | ||
| 311 | if (!(Pipe_BytesInPipe())) | ||
| 312 | { | ||
| 313 | Pipe_ClearIN(); | ||
| 314 | Pipe_Freeze(); | ||
| 315 | return 0; | ||
| 316 | } | ||
| 317 | else | ||
| 318 | { | ||
| 319 | Pipe_Freeze(); | ||
| 320 | return Pipe_BytesInPipe(); | ||
| 321 | } | ||
| 322 | } | ||
| 323 | else | ||
| 324 | { | ||
| 325 | Pipe_Freeze(); | ||
| 326 | |||
| 327 | return 0; | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 331 | int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) | ||
| 332 | { | ||
| 333 | if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) | ||
| 334 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 335 | |||
| 336 | int16_t ReceivedByte = -1; | ||
| 337 | |||
| 338 | Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipe.Address); | ||
| 339 | Pipe_Unfreeze(); | ||
| 340 | |||
| 341 | if (Pipe_IsINReceived()) | ||
| 342 | { | ||
| 343 | if (Pipe_BytesInPipe()) | ||
| 344 | ReceivedByte = Pipe_Read_8(); | ||
| 345 | |||
| 346 | if (!(Pipe_BytesInPipe())) | ||
| 347 | Pipe_ClearIN(); | ||
| 348 | } | ||
| 349 | |||
| 350 | Pipe_Freeze(); | ||
| 351 | |||
| 352 | return ReceivedByte; | ||
| 353 | } | ||
| 354 | |||
| 355 | uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 356 | char* const DeviceIDString, | ||
| 357 | const uint16_t BufferSize) | ||
| 358 | { | ||
| 359 | uint8_t ErrorCode; | ||
| 360 | uint16_t DeviceIDStringLength = 0; | ||
| 361 | |||
| 362 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 363 | { | ||
| 364 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 365 | .bRequest = PRNT_REQ_GetDeviceID, | ||
| 366 | .wValue = 0, | ||
| 367 | .wIndex = PRNTInterfaceInfo->State.InterfaceNumber, | ||
| 368 | .wLength = sizeof(DeviceIDStringLength), | ||
| 369 | }; | ||
| 370 | |||
| 371 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 372 | |||
| 373 | if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful) | ||
| 374 | return ErrorCode; | ||
| 375 | |||
| 376 | if (!(DeviceIDStringLength)) | ||
| 377 | { | ||
| 378 | DeviceIDString[0] = 0x00; | ||
| 379 | return HOST_SENDCONTROL_Successful; | ||
| 380 | } | ||
| 381 | |||
| 382 | DeviceIDStringLength = be16_to_cpu(DeviceIDStringLength); | ||
| 383 | |||
| 384 | if (DeviceIDStringLength > BufferSize) | ||
| 385 | DeviceIDStringLength = BufferSize; | ||
| 386 | |||
| 387 | USB_ControlRequest.wLength = DeviceIDStringLength; | ||
| 388 | |||
| 389 | if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful) | ||
| 390 | return ErrorCode; | ||
| 391 | |||
| 392 | memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2); | ||
| 393 | |||
| 394 | DeviceIDString[DeviceIDStringLength - 2] = 0x00; | ||
| 395 | |||
| 396 | return HOST_SENDCONTROL_Successful; | ||
| 397 | } | ||
| 398 | |||
| 399 | #endif | ||
| 400 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h new file mode 100644 index 000000000..511dab4b4 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h | |||
| @@ -0,0 +1,285 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB Printer Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB Printer Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassPrinter | ||
| 41 | * \defgroup Group_USBClassPrinterHost Printer Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassPrinterHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/PrinterClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassPrinterHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the Printer USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __PRINTER_CLASS_HOST_H__ | ||
| 54 | #define __PRINTER_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/PrinterClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_PRINTER_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Type Defines: */ | ||
| 72 | /** \brief Printer Class Host Mode Configuration and State Structure. | ||
| 73 | * | ||
| 74 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 75 | * and passed to each of the Printer class driver functions as the \c PRNTInterfaceInfo parameter. This | ||
| 76 | * stores each Printer interface's configuration and state information. | ||
| 77 | */ | ||
| 78 | typedef struct | ||
| 79 | { | ||
| 80 | struct | ||
| 81 | { | ||
| 82 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 83 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 84 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 85 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 86 | */ | ||
| 87 | struct | ||
| 88 | { | ||
| 89 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 90 | * after \ref PRNT_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 91 | * Configured state. | ||
| 92 | */ | ||
| 93 | uint8_t InterfaceNumber; /**< Interface index of the Printer interface within the attached device. */ | ||
| 94 | uint8_t AlternateSetting; /**< Alternate setting within the Printer Interface in the attached device. */ | ||
| 95 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 96 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 97 | * the interface is enumerated. | ||
| 98 | */ | ||
| 99 | } USB_ClassInfo_PRNT_Host_t; | ||
| 100 | |||
| 101 | /* Enums: */ | ||
| 102 | /** Enum for the possible error codes returned by the \ref PRNT_Host_ConfigurePipes() function. */ | ||
| 103 | enum PRNT_Host_EnumerationFailure_ErrorCodes_t | ||
| 104 | { | ||
| 105 | PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 106 | PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 107 | PRNT_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor. */ | ||
| 108 | PRNT_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 109 | }; | ||
| 110 | |||
| 111 | /* Function Prototypes: */ | ||
| 112 | /** Host interface configuration routine, to configure a given Printer host interface instance using the | ||
| 113 | * Configuration Descriptor read from an attached USB device. This function automatically updates the given Printer | ||
| 114 | * instance's state values and configures the pipes required to communicate with the interface if it is found within | ||
| 115 | * the device. This should be called once after the stack has enumerated the attached device, while the host state | ||
| 116 | * machine is in the Addressed state. | ||
| 117 | * | ||
| 118 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 119 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 120 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 121 | * | ||
| 122 | * \return A value from the \ref PRNT_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 123 | */ | ||
| 124 | uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 125 | uint16_t ConfigDescriptorSize, | ||
| 126 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 127 | |||
| 128 | /** General management task for a given Printer host class interface, required for the correct operation of | ||
| 129 | * the interface. This should be called frequently in the main program loop, before the master USB management task | ||
| 130 | * \ref USB_USBTask(). | ||
| 131 | * | ||
| 132 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 133 | */ | ||
| 134 | void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 135 | |||
| 136 | /** Configures the printer to enable Bidirectional mode, if it is not already in this mode. This should be called | ||
| 137 | * once the connected device's configuration has been set, to ensure the printer is ready to accept commands. | ||
| 138 | * | ||
| 139 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 140 | * | ||
| 141 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 142 | */ | ||
| 143 | uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 144 | |||
| 145 | /** Retrieves the status of the virtual Printer port's inbound status lines. The result can then be masked against the | ||
| 146 | * \c PRNT_PORTSTATUS_* macros to determine the printer port's status. | ||
| 147 | * | ||
| 148 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 149 | * \param[out] PortStatus Location where the retrieved port status should be stored. | ||
| 150 | * | ||
| 151 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 152 | */ | ||
| 153 | uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 154 | uint8_t* const PortStatus) | ||
| 155 | ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 156 | |||
| 157 | /** Soft-resets the attached printer, readying it for new commands. | ||
| 158 | * | ||
| 159 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 160 | * | ||
| 161 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. | ||
| 162 | */ | ||
| 163 | uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 164 | |||
| 165 | /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. | ||
| 166 | * | ||
| 167 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 168 | * call will fail. | ||
| 169 | * | ||
| 170 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 171 | * | ||
| 172 | * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. | ||
| 173 | */ | ||
| 174 | uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 175 | |||
| 176 | /** Sends the given null terminated string to the attached printer's input endpoint. | ||
| 177 | * | ||
| 178 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 179 | * call will fail. | ||
| 180 | * | ||
| 181 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 182 | * \param[in] String Pointer to a null terminated string to send. | ||
| 183 | * | ||
| 184 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 185 | */ | ||
| 186 | uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 187 | const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 188 | |||
| 189 | /** Sends the given raw data stream to the attached printer's input endpoint. This should contain commands that the | ||
| 190 | * printer is able to understand - for example, PCL data. Not all printers accept all printer languages; see | ||
| 191 | * \ref PRNT_Host_GetDeviceID() for details on determining acceptable languages for an attached printer. | ||
| 192 | * | ||
| 193 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 194 | * call will fail. | ||
| 195 | * | ||
| 196 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 197 | * \param[in] Buffer Pointer to a buffer containing the raw command stream to send to the printer. | ||
| 198 | * \param[in] Length Size in bytes of the command stream to be sent. | ||
| 199 | * | ||
| 200 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 201 | */ | ||
| 202 | uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 203 | const void* Buffer, | ||
| 204 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 205 | |||
| 206 | /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the | ||
| 207 | * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the | ||
| 208 | * \ref PRNT_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be | ||
| 209 | * packed into a single pipe packet, increasing data throughput. | ||
| 210 | * | ||
| 211 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 212 | * call will fail. | ||
| 213 | * | ||
| 214 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 215 | * \param[in] Data Byte of data to send to the device. | ||
| 216 | * | ||
| 217 | * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. | ||
| 218 | */ | ||
| 219 | uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 220 | const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); | ||
| 221 | |||
| 222 | /** Determines the number of bytes received by the printer interface from the device, waiting to be read. This indicates the number | ||
| 223 | * of bytes in the IN pipe bank only, and thus the number of calls to \ref PRNT_Host_ReceiveByte() which are guaranteed to succeed | ||
| 224 | * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be | ||
| 225 | * released back to the USB controller until all bytes are read. | ||
| 226 | * | ||
| 227 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 228 | * call will fail. | ||
| 229 | * | ||
| 230 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 231 | * | ||
| 232 | * \return Total number of buffered bytes received from the device. | ||
| 233 | */ | ||
| 234 | uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 235 | |||
| 236 | /** 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 | ||
| 237 | * returns a negative value. The \ref PRNT_Host_BytesReceived() function may be queried in advance to determine how many bytes | ||
| 238 | * are currently buffered in the Printer interface's data receive pipe. | ||
| 239 | * | ||
| 240 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 241 | * call will fail. | ||
| 242 | * | ||
| 243 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 244 | * | ||
| 245 | * \return Next received byte from the device, or a negative value if no data received. | ||
| 246 | */ | ||
| 247 | int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 248 | |||
| 249 | /** Retrieves the attached printer device's ID string, formatted according to IEEE 1284. This string is sent as a | ||
| 250 | * Unicode string from the device and is automatically converted to an ASCII encoded C string by this function, thus | ||
| 251 | * the maximum reportable string length is two less than the size given (to accommodate the Unicode string length | ||
| 252 | * bytes which are removed). | ||
| 253 | * | ||
| 254 | * This string, when supported, contains the model, manufacturer and acceptable printer languages for the attached device. | ||
| 255 | * | ||
| 256 | * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. | ||
| 257 | * \param[out] DeviceIDString Pointer to a buffer where the Device ID string should be stored, in ASCII format. | ||
| 258 | * \param[in] BufferSize Size in bytes of the buffer allocated for the Device ID string. | ||
| 259 | * | ||
| 260 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 261 | */ | ||
| 262 | uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, | ||
| 263 | char* const DeviceIDString, | ||
| 264 | const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 265 | |||
| 266 | /* Private Interface - For use in library only: */ | ||
| 267 | #if !defined(__DOXYGEN__) | ||
| 268 | /* Function Prototypes: */ | ||
| 269 | #if defined(__INCLUDE_FROM_PRINTER_HOST_C) | ||
| 270 | static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* const CurrentDescriptor) | ||
| 271 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 272 | static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 273 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 274 | #endif | ||
| 275 | #endif | ||
| 276 | |||
| 277 | /* Disable C linkage for C++ Compilers: */ | ||
| 278 | #if defined(__cplusplus) | ||
| 279 | } | ||
| 280 | #endif | ||
| 281 | |||
| 282 | #endif | ||
| 283 | |||
| 284 | /** @} */ | ||
| 285 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c new file mode 100644 index 000000000..6fb09fdab --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c | |||
| @@ -0,0 +1,476 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_RNDIS_DRIVER | ||
| 37 | #define __INCLUDE_FROM_RNDIS_HOST_C | ||
| 38 | #include "RNDISClassHost.h" | ||
| 39 | |||
| 40 | uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL; | ||
| 47 | USB_Descriptor_Interface_t* RNDISControlInterface = NULL; | ||
| 48 | |||
| 49 | memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State)); | ||
| 50 | |||
| 51 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 52 | return RNDIS_ENUMERROR_InvalidConfigDescriptor; | ||
| 53 | |||
| 54 | RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 55 | |||
| 56 | while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint)) | ||
| 57 | { | ||
| 58 | if (!(RNDISControlInterface) || | ||
| 59 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 60 | DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 61 | { | ||
| 62 | if (NotificationEndpoint) | ||
| 63 | { | ||
| 64 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 65 | DCOMP_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 66 | { | ||
| 67 | return RNDIS_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 68 | } | ||
| 69 | |||
| 70 | DataINEndpoint = NULL; | ||
| 71 | DataOUTEndpoint = NULL; | ||
| 72 | } | ||
| 73 | else | ||
| 74 | { | ||
| 75 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 76 | DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 77 | { | ||
| 78 | return RNDIS_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 79 | } | ||
| 80 | |||
| 81 | RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 82 | |||
| 83 | NotificationEndpoint = NULL; | ||
| 84 | } | ||
| 85 | |||
| 86 | continue; | ||
| 87 | } | ||
| 88 | |||
| 89 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 90 | |||
| 91 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 92 | { | ||
| 93 | if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) | ||
| 94 | NotificationEndpoint = EndpointData; | ||
| 95 | else | ||
| 96 | DataINEndpoint = EndpointData; | ||
| 97 | } | ||
| 98 | else | ||
| 99 | { | ||
| 100 | DataOUTEndpoint = EndpointData; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | RNDISInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 105 | RNDISInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 106 | RNDISInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; | ||
| 107 | |||
| 108 | RNDISInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 109 | RNDISInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 110 | RNDISInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; | ||
| 111 | |||
| 112 | RNDISInterfaceInfo->Config.NotificationPipe.Size = le16_to_cpu(NotificationEndpoint->EndpointSize); | ||
| 113 | RNDISInterfaceInfo->Config.NotificationPipe.EndpointAddress = NotificationEndpoint->EndpointAddress; | ||
| 114 | RNDISInterfaceInfo->Config.NotificationPipe.Type = EP_TYPE_INTERRUPT; | ||
| 115 | |||
| 116 | if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataINPipe, 1))) | ||
| 117 | return RNDIS_ENUMERROR_PipeConfigurationFailed; | ||
| 118 | |||
| 119 | if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 120 | return RNDIS_ENUMERROR_PipeConfigurationFailed; | ||
| 121 | |||
| 122 | if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.NotificationPipe, 1))) | ||
| 123 | return RNDIS_ENUMERROR_PipeConfigurationFailed; | ||
| 124 | |||
| 125 | RNDISInterfaceInfo->State.ControlInterfaceNumber = RNDISControlInterface->InterfaceNumber; | ||
| 126 | RNDISInterfaceInfo->State.IsActive = true; | ||
| 127 | |||
| 128 | return RNDIS_ENUMERROR_NoError; | ||
| 129 | } | ||
| 130 | |||
| 131 | static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor) | ||
| 132 | { | ||
| 133 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 134 | |||
| 135 | if (Header->Type == DTYPE_Interface) | ||
| 136 | { | ||
| 137 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 138 | |||
| 139 | if ((Interface->Class == CDC_CSCP_CDCClass) && | ||
| 140 | (Interface->SubClass == CDC_CSCP_ACMSubclass) && | ||
| 141 | (Interface->Protocol == CDC_CSCP_VendorSpecificProtocol)) | ||
| 142 | { | ||
| 143 | return DESCRIPTOR_SEARCH_Found; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 148 | } | ||
| 149 | |||
| 150 | static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor) | ||
| 151 | { | ||
| 152 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 153 | |||
| 154 | if (Header->Type == DTYPE_Interface) | ||
| 155 | { | ||
| 156 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, | ||
| 157 | USB_Descriptor_Interface_t); | ||
| 158 | |||
| 159 | if ((Interface->Class == CDC_CSCP_CDCDataClass) && | ||
| 160 | (Interface->SubClass == CDC_CSCP_NoDataSubclass) && | ||
| 161 | (Interface->Protocol == CDC_CSCP_NoDataProtocol)) | ||
| 162 | { | ||
| 163 | return DESCRIPTOR_SEARCH_Found; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 168 | } | ||
| 169 | |||
| 170 | static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 171 | { | ||
| 172 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 173 | |||
| 174 | if (Header->Type == DTYPE_Endpoint) | ||
| 175 | { | ||
| 176 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 177 | |||
| 178 | uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); | ||
| 179 | |||
| 180 | if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) && | ||
| 181 | !(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) | ||
| 182 | { | ||
| 183 | return DESCRIPTOR_SEARCH_Found; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | else if (Header->Type == DTYPE_Interface) | ||
| 187 | { | ||
| 188 | return DESCRIPTOR_SEARCH_Fail; | ||
| 189 | } | ||
| 190 | |||
| 191 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 192 | } | ||
| 193 | |||
| 194 | static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 195 | void* Buffer, | ||
| 196 | const uint16_t Length) | ||
| 197 | { | ||
| 198 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 199 | { | ||
| 200 | .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 201 | .bRequest = RNDIS_REQ_SendEncapsulatedCommand, | ||
| 202 | .wValue = 0, | ||
| 203 | .wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber, | ||
| 204 | .wLength = Length, | ||
| 205 | }; | ||
| 206 | |||
| 207 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 208 | |||
| 209 | return USB_Host_SendControlRequest(Buffer); | ||
| 210 | } | ||
| 211 | |||
| 212 | static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 213 | void* Buffer, | ||
| 214 | const uint16_t Length) | ||
| 215 | { | ||
| 216 | USB_ControlRequest = (USB_Request_Header_t) | ||
| 217 | { | ||
| 218 | .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), | ||
| 219 | .bRequest = RNDIS_REQ_GetEncapsulatedResponse, | ||
| 220 | .wValue = 0, | ||
| 221 | .wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber, | ||
| 222 | .wLength = Length, | ||
| 223 | }; | ||
| 224 | |||
| 225 | Pipe_SelectPipe(PIPE_CONTROLPIPE); | ||
| 226 | |||
| 227 | return USB_Host_SendControlRequest(Buffer); | ||
| 228 | } | ||
| 229 | |||
| 230 | uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) | ||
| 231 | { | ||
| 232 | uint8_t ErrorCode; | ||
| 233 | |||
| 234 | RNDIS_KeepAlive_Message_t KeepAliveMessage; | ||
| 235 | RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse; | ||
| 236 | |||
| 237 | KeepAliveMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_MSG); | ||
| 238 | KeepAliveMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Message_t)); | ||
| 239 | KeepAliveMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); | ||
| 240 | |||
| 241 | if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &KeepAliveMessage, | ||
| 242 | sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful) | ||
| 243 | { | ||
| 244 | return ErrorCode; | ||
| 245 | } | ||
| 246 | |||
| 247 | if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &KeepAliveMessageResponse, | ||
| 248 | sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful) | ||
| 249 | { | ||
| 250 | return ErrorCode; | ||
| 251 | } | ||
| 252 | |||
| 253 | return HOST_SENDCONTROL_Successful; | ||
| 254 | } | ||
| 255 | |||
| 256 | uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) | ||
| 257 | { | ||
| 258 | uint8_t ErrorCode; | ||
| 259 | |||
| 260 | RNDIS_Initialize_Message_t InitMessage; | ||
| 261 | RNDIS_Initialize_Complete_t InitMessageResponse; | ||
| 262 | |||
| 263 | InitMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_MSG); | ||
| 264 | InitMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Message_t)); | ||
| 265 | InitMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); | ||
| 266 | |||
| 267 | InitMessage.MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR); | ||
| 268 | InitMessage.MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR); | ||
| 269 | InitMessage.MaxTransferSize = cpu_to_le32(RNDISInterfaceInfo->Config.HostMaxPacketSize); | ||
| 270 | |||
| 271 | if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &InitMessage, | ||
| 272 | sizeof(RNDIS_Initialize_Message_t))) != HOST_SENDCONTROL_Successful) | ||
| 273 | { | ||
| 274 | return ErrorCode; | ||
| 275 | } | ||
| 276 | |||
| 277 | if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &InitMessageResponse, | ||
| 278 | sizeof(RNDIS_Initialize_Complete_t))) != HOST_SENDCONTROL_Successful) | ||
| 279 | { | ||
| 280 | return ErrorCode; | ||
| 281 | } | ||
| 282 | |||
| 283 | if (InitMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS)) | ||
| 284 | return RNDIS_ERROR_LOGICAL_CMD_FAILED; | ||
| 285 | |||
| 286 | RNDISInterfaceInfo->State.DeviceMaxPacketSize = le32_to_cpu(InitMessageResponse.MaxTransferSize); | ||
| 287 | |||
| 288 | return HOST_SENDCONTROL_Successful; | ||
| 289 | } | ||
| 290 | |||
| 291 | uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 292 | const uint32_t Oid, | ||
| 293 | void* Buffer, | ||
| 294 | const uint16_t Length) | ||
| 295 | { | ||
| 296 | uint8_t ErrorCode; | ||
| 297 | |||
| 298 | struct | ||
| 299 | { | ||
| 300 | RNDIS_Set_Message_t SetMessage; | ||
| 301 | uint8_t ContiguousBuffer[Length]; | ||
| 302 | } SetMessageData; | ||
| 303 | |||
| 304 | RNDIS_Set_Complete_t SetMessageResponse; | ||
| 305 | |||
| 306 | SetMessageData.SetMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_MSG); | ||
| 307 | SetMessageData.SetMessage.MessageLength = cpu_to_le32(sizeof(RNDIS_Set_Message_t) + Length); | ||
| 308 | SetMessageData.SetMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); | ||
| 309 | |||
| 310 | SetMessageData.SetMessage.Oid = cpu_to_le32(Oid); | ||
| 311 | SetMessageData.SetMessage.InformationBufferLength = cpu_to_le32(Length); | ||
| 312 | SetMessageData.SetMessage.InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Set_Message_t) - sizeof(RNDIS_Message_Header_t)); | ||
| 313 | SetMessageData.SetMessage.DeviceVcHandle = CPU_TO_LE32(0); | ||
| 314 | |||
| 315 | memcpy(&SetMessageData.ContiguousBuffer, Buffer, Length); | ||
| 316 | |||
| 317 | if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &SetMessageData, | ||
| 318 | (sizeof(RNDIS_Set_Message_t) + Length))) != HOST_SENDCONTROL_Successful) | ||
| 319 | { | ||
| 320 | return ErrorCode; | ||
| 321 | } | ||
| 322 | |||
| 323 | if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &SetMessageResponse, | ||
| 324 | sizeof(RNDIS_Set_Complete_t))) != HOST_SENDCONTROL_Successful) | ||
| 325 | { | ||
| 326 | return ErrorCode; | ||
| 327 | } | ||
| 328 | |||
| 329 | if (SetMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS)) | ||
| 330 | return RNDIS_ERROR_LOGICAL_CMD_FAILED; | ||
| 331 | |||
| 332 | return HOST_SENDCONTROL_Successful; | ||
| 333 | } | ||
| 334 | |||
| 335 | uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 336 | const uint32_t Oid, | ||
| 337 | void* Buffer, | ||
| 338 | const uint16_t MaxLength) | ||
| 339 | { | ||
| 340 | uint8_t ErrorCode; | ||
| 341 | |||
| 342 | RNDIS_Query_Message_t QueryMessage; | ||
| 343 | |||
| 344 | struct | ||
| 345 | { | ||
| 346 | RNDIS_Query_Complete_t QueryMessageResponse; | ||
| 347 | uint8_t ContiguousBuffer[MaxLength]; | ||
| 348 | } QueryMessageResponseData; | ||
| 349 | |||
| 350 | QueryMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_MSG); | ||
| 351 | QueryMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Message_t)); | ||
| 352 | QueryMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); | ||
| 353 | |||
| 354 | QueryMessage.Oid = cpu_to_le32(Oid); | ||
| 355 | QueryMessage.InformationBufferLength = CPU_TO_LE32(0); | ||
| 356 | QueryMessage.InformationBufferOffset = CPU_TO_LE32(0); | ||
| 357 | QueryMessage.DeviceVcHandle = CPU_TO_LE32(0); | ||
| 358 | |||
| 359 | if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &QueryMessage, | ||
| 360 | sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful) | ||
| 361 | { | ||
| 362 | return ErrorCode; | ||
| 363 | } | ||
| 364 | |||
| 365 | if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &QueryMessageResponseData, | ||
| 366 | sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful) | ||
| 367 | { | ||
| 368 | return ErrorCode; | ||
| 369 | } | ||
| 370 | |||
| 371 | if (QueryMessageResponseData.QueryMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS)) | ||
| 372 | return RNDIS_ERROR_LOGICAL_CMD_FAILED; | ||
| 373 | |||
| 374 | memcpy(Buffer, &QueryMessageResponseData.ContiguousBuffer, MaxLength); | ||
| 375 | |||
| 376 | return HOST_SENDCONTROL_Successful; | ||
| 377 | } | ||
| 378 | |||
| 379 | bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) | ||
| 380 | { | ||
| 381 | bool PacketWaiting; | ||
| 382 | |||
| 383 | if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive)) | ||
| 384 | return false; | ||
| 385 | |||
| 386 | Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address); | ||
| 387 | |||
| 388 | Pipe_Unfreeze(); | ||
| 389 | PacketWaiting = Pipe_IsINReceived(); | ||
| 390 | Pipe_Freeze(); | ||
| 391 | |||
| 392 | return PacketWaiting; | ||
| 393 | } | ||
| 394 | |||
| 395 | uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 396 | void* Buffer, | ||
| 397 | uint16_t* const PacketLength) | ||
| 398 | { | ||
| 399 | uint8_t ErrorCode; | ||
| 400 | |||
| 401 | if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive)) | ||
| 402 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 403 | |||
| 404 | Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address); | ||
| 405 | Pipe_Unfreeze(); | ||
| 406 | |||
| 407 | if (!(Pipe_IsReadWriteAllowed())) | ||
| 408 | { | ||
| 409 | if (Pipe_IsINReceived()) | ||
| 410 | Pipe_ClearIN(); | ||
| 411 | |||
| 412 | *PacketLength = 0; | ||
| 413 | Pipe_Freeze(); | ||
| 414 | return PIPE_RWSTREAM_NoError; | ||
| 415 | } | ||
| 416 | |||
| 417 | RNDIS_Packet_Message_t DeviceMessage; | ||
| 418 | |||
| 419 | if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t), | ||
| 420 | NULL)) != PIPE_RWSTREAM_NoError) | ||
| 421 | { | ||
| 422 | return ErrorCode; | ||
| 423 | } | ||
| 424 | |||
| 425 | *PacketLength = (uint16_t)le32_to_cpu(DeviceMessage.DataLength); | ||
| 426 | |||
| 427 | Pipe_Discard_Stream(le32_to_cpu(DeviceMessage.DataOffset) - | ||
| 428 | (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)), | ||
| 429 | NULL); | ||
| 430 | |||
| 431 | Pipe_Read_Stream_LE(Buffer, *PacketLength, NULL); | ||
| 432 | |||
| 433 | if (!(Pipe_BytesInPipe())) | ||
| 434 | Pipe_ClearIN(); | ||
| 435 | |||
| 436 | Pipe_Freeze(); | ||
| 437 | |||
| 438 | return PIPE_RWSTREAM_NoError; | ||
| 439 | } | ||
| 440 | |||
| 441 | uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 442 | void* Buffer, | ||
| 443 | const uint16_t PacketLength) | ||
| 444 | { | ||
| 445 | uint8_t ErrorCode; | ||
| 446 | |||
| 447 | if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive)) | ||
| 448 | return PIPE_READYWAIT_DeviceDisconnected; | ||
| 449 | |||
| 450 | RNDIS_Packet_Message_t DeviceMessage; | ||
| 451 | |||
| 452 | memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t)); | ||
| 453 | DeviceMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG); | ||
| 454 | DeviceMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + PacketLength); | ||
| 455 | DeviceMessage.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)); | ||
| 456 | DeviceMessage.DataLength = cpu_to_le32(PacketLength); | ||
| 457 | |||
| 458 | Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 459 | Pipe_Unfreeze(); | ||
| 460 | |||
| 461 | if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t), | ||
| 462 | NULL)) != PIPE_RWSTREAM_NoError) | ||
| 463 | { | ||
| 464 | return ErrorCode; | ||
| 465 | } | ||
| 466 | |||
| 467 | Pipe_Write_Stream_LE(Buffer, PacketLength, NULL); | ||
| 468 | Pipe_ClearOUT(); | ||
| 469 | |||
| 470 | Pipe_Freeze(); | ||
| 471 | |||
| 472 | return PIPE_RWSTREAM_NoError; | ||
| 473 | } | ||
| 474 | |||
| 475 | #endif | ||
| 476 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h new file mode 100644 index 000000000..bddbc247a --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h | |||
| @@ -0,0 +1,270 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB RNDIS Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB RNDIS Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassRNDIS | ||
| 41 | * \defgroup Group_USBClassRNDISHost RNDIS Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassRNDISHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/RNDISClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassRNDISHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the Microsoft RNDIS Ethernet | ||
| 49 | * USB Class driver. | ||
| 50 | * | ||
| 51 | * @{ | ||
| 52 | */ | ||
| 53 | |||
| 54 | #ifndef __RNDIS_CLASS_HOST_H__ | ||
| 55 | #define __RNDIS_CLASS_HOST_H__ | ||
| 56 | |||
| 57 | /* Includes: */ | ||
| 58 | #include "../../USB.h" | ||
| 59 | #include "../Common/RNDISClassCommon.h" | ||
| 60 | |||
| 61 | /* Enable C linkage for C++ Compilers: */ | ||
| 62 | #if defined(__cplusplus) | ||
| 63 | extern "C" { | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* Preprocessor Checks: */ | ||
| 67 | #if !defined(__INCLUDE_FROM_RNDIS_DRIVER) | ||
| 68 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 69 | #endif | ||
| 70 | |||
| 71 | /* Public Interface - May be used in end-application: */ | ||
| 72 | /* Type Defines: */ | ||
| 73 | /** \brief RNDIS Class Host Mode Configuration and State Structure. | ||
| 74 | * | ||
| 75 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 76 | * and passed to each of the RNDIS class driver functions as the \c RNDISInterfaceInfo parameter. This | ||
| 77 | * stores each RNDIS interface's configuration and state information. | ||
| 78 | */ | ||
| 79 | typedef struct | ||
| 80 | { | ||
| 81 | struct | ||
| 82 | { | ||
| 83 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 84 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 85 | USB_Pipe_Table_t NotificationPipe; /**< Notification IN Pipe configuration table. */ | ||
| 86 | |||
| 87 | uint32_t HostMaxPacketSize; /**< Maximum size of a packet which can be buffered by the host. */ | ||
| 88 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 89 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 90 | */ | ||
| 91 | struct | ||
| 92 | { | ||
| 93 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 94 | * after \ref RNDIS_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 95 | * Configured state. | ||
| 96 | */ | ||
| 97 | uint8_t ControlInterfaceNumber; /**< Interface index of the RNDIS control interface within the attached device. */ | ||
| 98 | |||
| 99 | uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device. */ | ||
| 100 | |||
| 101 | uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair. */ | ||
| 102 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 103 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 104 | * the interface is enumerated. | ||
| 105 | */ | ||
| 106 | } USB_ClassInfo_RNDIS_Host_t; | ||
| 107 | |||
| 108 | /* Enums: */ | ||
| 109 | /** Enum for the possible error codes returned by the \ref RNDIS_Host_ConfigurePipes() function. */ | ||
| 110 | enum RNDIS_Host_EnumerationFailure_ErrorCodes_t | ||
| 111 | { | ||
| 112 | RNDIS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 113 | RNDIS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 114 | RNDIS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor. */ | ||
| 115 | RNDIS_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 116 | }; | ||
| 117 | |||
| 118 | /* Function Prototypes: */ | ||
| 119 | /** Host interface configuration routine, to configure a given RNDIS host interface instance using the Configuration | ||
| 120 | * Descriptor read from an attached USB device. This function automatically updates the given RNDIS Host instance's | ||
| 121 | * state values and configures the pipes required to communicate with the interface if it is found within the device. | ||
| 122 | * This should be called once after the stack has enumerated the attached device, while the host state machine is in | ||
| 123 | * the Addressed state. | ||
| 124 | * | ||
| 125 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 126 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 127 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 128 | * | ||
| 129 | * \return A value from the \ref RNDIS_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 130 | */ | ||
| 131 | uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 132 | uint16_t ConfigDescriptorSize, | ||
| 133 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 134 | |||
| 135 | /** Sends a RNDIS KEEPALIVE command to the device, to ensure that it does not enter standby mode after periods | ||
| 136 | * of long inactivity. | ||
| 137 | * | ||
| 138 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 139 | * | ||
| 140 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the device returned a | ||
| 141 | * logical command failure. | ||
| 142 | */ | ||
| 143 | uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 144 | |||
| 145 | /** Initializes the attached RNDIS device's RNDIS interface. This should be called after the device's pipes have been | ||
| 146 | * configured via the call to \ref RNDIS_Host_ConfigurePipes(). | ||
| 147 | * | ||
| 148 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 149 | * | ||
| 150 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the | ||
| 151 | * device returned a logical command failure. | ||
| 152 | */ | ||
| 153 | uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 154 | |||
| 155 | /** Sets a given RNDIS property of an attached RNDIS device. | ||
| 156 | * | ||
| 157 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 158 | * \param[in] Oid OID number of the parameter to set. | ||
| 159 | * \param[in] Buffer Pointer to where the property data is to be sourced from. | ||
| 160 | * \param[in] Length Length in bytes of the property data to sent to the device. | ||
| 161 | * | ||
| 162 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the | ||
| 163 | * device returned a logical command failure. | ||
| 164 | */ | ||
| 165 | uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 166 | const uint32_t Oid, | ||
| 167 | void* Buffer, | ||
| 168 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 169 | |||
| 170 | /** Gets a given RNDIS property of an attached RNDIS device. | ||
| 171 | * | ||
| 172 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 173 | * \param[in] Oid OID number of the parameter to get. | ||
| 174 | * \param[in] Buffer Pointer to where the property data is to be written to. | ||
| 175 | * \param[in] MaxLength Length in bytes of the destination buffer size. | ||
| 176 | * | ||
| 177 | * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the | ||
| 178 | * device returned a logical command failure. | ||
| 179 | */ | ||
| 180 | uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 181 | const uint32_t Oid, | ||
| 182 | void* Buffer, | ||
| 183 | const uint16_t MaxLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 184 | |||
| 185 | /** Determines if a packet is currently waiting for the host to read in and process. | ||
| 186 | * | ||
| 187 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 188 | * call will fail. | ||
| 189 | * | ||
| 190 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 191 | * | ||
| 192 | * \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise. | ||
| 193 | */ | ||
| 194 | bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 195 | |||
| 196 | /** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave | ||
| 197 | * only the packet contents for processing by the host in the nominated buffer. | ||
| 198 | * | ||
| 199 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 200 | * call will fail. | ||
| 201 | * | ||
| 202 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 203 | * \param[out] Buffer Pointer to a buffer where the packer data is to be written to. | ||
| 204 | * \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored. | ||
| 205 | * | ||
| 206 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 207 | */ | ||
| 208 | uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 209 | void* Buffer, | ||
| 210 | uint16_t* const PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) | ||
| 211 | ATTR_NON_NULL_PTR_ARG(3); | ||
| 212 | |||
| 213 | /** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header. | ||
| 214 | * | ||
| 215 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 216 | * call will fail. | ||
| 217 | * | ||
| 218 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 219 | * \param[in] Buffer Pointer to a buffer where the packer data is to be read from. | ||
| 220 | * \param[in] PacketLength Length in bytes of the packet to send. | ||
| 221 | * | ||
| 222 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 223 | */ | ||
| 224 | uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 225 | void* Buffer, | ||
| 226 | const uint16_t PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 227 | |||
| 228 | /* Inline Functions: */ | ||
| 229 | /** General management task for a given RNDIS host class interface, required for the correct operation of the interface. This should | ||
| 230 | * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). | ||
| 231 | * | ||
| 232 | * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. | ||
| 233 | */ | ||
| 234 | static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 235 | static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) | ||
| 236 | { | ||
| 237 | (void)RNDISInterfaceInfo; | ||
| 238 | } | ||
| 239 | |||
| 240 | /* Private Interface - For use in library only: */ | ||
| 241 | #if !defined(__DOXYGEN__) | ||
| 242 | /* Function Prototypes: */ | ||
| 243 | #if defined(__INCLUDE_FROM_RNDIS_HOST_C) | ||
| 244 | static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 245 | void* Buffer, | ||
| 246 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) | ||
| 247 | ATTR_NON_NULL_PTR_ARG(2); | ||
| 248 | static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, | ||
| 249 | void* Buffer, | ||
| 250 | const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) | ||
| 251 | ATTR_NON_NULL_PTR_ARG(2); | ||
| 252 | |||
| 253 | static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor) | ||
| 254 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 255 | static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor) | ||
| 256 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 257 | static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 258 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 259 | #endif | ||
| 260 | #endif | ||
| 261 | |||
| 262 | /* Disable C linkage for C++ Compilers: */ | ||
| 263 | #if defined(__cplusplus) | ||
| 264 | } | ||
| 265 | #endif | ||
| 266 | |||
| 267 | #endif | ||
| 268 | |||
| 269 | /** @} */ | ||
| 270 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c b/lib/lufa/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c new file mode 100644 index 000000000..ef33d9be4 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c | |||
| @@ -0,0 +1,436 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 32 | #include "../../Core/USBMode.h" | ||
| 33 | |||
| 34 | #if defined(USB_CAN_BE_HOST) | ||
| 35 | |||
| 36 | #define __INCLUDE_FROM_SI_DRIVER | ||
| 37 | #define __INCLUDE_FROM_STILLIMAGE_HOST_C | ||
| 38 | #include "StillImageClassHost.h" | ||
| 39 | |||
| 40 | uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 41 | uint16_t ConfigDescriptorSize, | ||
| 42 | void* ConfigDescriptorData) | ||
| 43 | { | ||
| 44 | USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; | ||
| 45 | USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; | ||
| 46 | USB_Descriptor_Endpoint_t* EventsEndpoint = NULL; | ||
| 47 | USB_Descriptor_Interface_t* StillImageInterface = NULL; | ||
| 48 | |||
| 49 | memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State)); | ||
| 50 | |||
| 51 | if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) | ||
| 52 | return SI_ENUMERROR_InvalidConfigDescriptor; | ||
| 53 | |||
| 54 | while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(EventsEndpoint)) | ||
| 55 | { | ||
| 56 | if (!(StillImageInterface) || | ||
| 57 | USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 58 | DCOMP_SI_Host_NextSIInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 59 | { | ||
| 60 | if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, | ||
| 61 | DCOMP_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found) | ||
| 62 | { | ||
| 63 | return SI_ENUMERROR_NoCompatibleInterfaceFound; | ||
| 64 | } | ||
| 65 | |||
| 66 | StillImageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); | ||
| 67 | |||
| 68 | DataINEndpoint = NULL; | ||
| 69 | DataOUTEndpoint = NULL; | ||
| 70 | EventsEndpoint = NULL; | ||
| 71 | |||
| 72 | continue; | ||
| 73 | } | ||
| 74 | |||
| 75 | USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); | ||
| 76 | |||
| 77 | if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) | ||
| 78 | { | ||
| 79 | if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) | ||
| 80 | EventsEndpoint = EndpointData; | ||
| 81 | else | ||
| 82 | DataINEndpoint = EndpointData; | ||
| 83 | } | ||
| 84 | else | ||
| 85 | { | ||
| 86 | DataOUTEndpoint = EndpointData; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | SIInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); | ||
| 91 | SIInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; | ||
| 92 | SIInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; | ||
| 93 | |||
| 94 | SIInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); | ||
| 95 | SIInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; | ||
| 96 | SIInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; | ||
| 97 | |||
| 98 | SIInterfaceInfo->Config.EventsPipe.Size = le16_to_cpu(EventsEndpoint->EndpointSize); | ||
| 99 | SIInterfaceInfo->Config.EventsPipe.EndpointAddress = EventsEndpoint->EndpointAddress; | ||
| 100 | SIInterfaceInfo->Config.EventsPipe.Type = EP_TYPE_INTERRUPT; | ||
| 101 | |||
| 102 | if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.DataINPipe, 1))) | ||
| 103 | return SI_ENUMERROR_PipeConfigurationFailed; | ||
| 104 | |||
| 105 | if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.DataOUTPipe, 1))) | ||
| 106 | return SI_ENUMERROR_PipeConfigurationFailed; | ||
| 107 | |||
| 108 | if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.EventsPipe, 1))) | ||
| 109 | return SI_ENUMERROR_PipeConfigurationFailed; | ||
| 110 | |||
| 111 | SIInterfaceInfo->State.InterfaceNumber = StillImageInterface->InterfaceNumber; | ||
| 112 | SIInterfaceInfo->State.IsActive = true; | ||
| 113 | |||
| 114 | return SI_ENUMERROR_NoError; | ||
| 115 | } | ||
| 116 | |||
| 117 | uint8_t DCOMP_SI_Host_NextSIInterface(void* const CurrentDescriptor) | ||
| 118 | { | ||
| 119 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 120 | |||
| 121 | if (Header->Type == DTYPE_Interface) | ||
| 122 | { | ||
| 123 | USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); | ||
| 124 | |||
| 125 | if ((Interface->Class == SI_CSCP_StillImageClass) && | ||
| 126 | (Interface->SubClass == SI_CSCP_StillImageSubclass) && | ||
| 127 | (Interface->Protocol == SI_CSCP_BulkOnlyProtocol)) | ||
| 128 | { | ||
| 129 | return DESCRIPTOR_SEARCH_Found; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 134 | } | ||
| 135 | |||
| 136 | uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 137 | { | ||
| 138 | USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); | ||
| 139 | |||
| 140 | if (Header->Type == DTYPE_Endpoint) | ||
| 141 | { | ||
| 142 | USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); | ||
| 143 | |||
| 144 | uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); | ||
| 145 | |||
| 146 | if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) && | ||
| 147 | (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) | ||
| 148 | { | ||
| 149 | return DESCRIPTOR_SEARCH_Found; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | else if (Header->Type == DTYPE_Interface) | ||
| 153 | { | ||
| 154 | return DESCRIPTOR_SEARCH_Fail; | ||
| 155 | } | ||
| 156 | |||
| 157 | return DESCRIPTOR_SEARCH_NotFound; | ||
| 158 | } | ||
| 159 | |||
| 160 | uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 161 | PIMA_Container_t* const PIMAHeader) | ||
| 162 | { | ||
| 163 | uint8_t ErrorCode; | ||
| 164 | |||
| 165 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 166 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 167 | |||
| 168 | if (SIInterfaceInfo->State.IsSessionOpen) | ||
| 169 | PIMAHeader->TransactionID = cpu_to_le32(SIInterfaceInfo->State.TransactionID++); | ||
| 170 | |||
| 171 | Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 172 | Pipe_Unfreeze(); | ||
| 173 | |||
| 174 | if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NULL)) != PIPE_RWSTREAM_NoError) | ||
| 175 | return ErrorCode; | ||
| 176 | |||
| 177 | uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); | ||
| 178 | |||
| 179 | if (ParamBytes) | ||
| 180 | { | ||
| 181 | if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NULL)) != PIPE_RWSTREAM_NoError) | ||
| 182 | return ErrorCode; | ||
| 183 | } | ||
| 184 | |||
| 185 | Pipe_ClearOUT(); | ||
| 186 | Pipe_Freeze(); | ||
| 187 | |||
| 188 | return PIPE_RWSTREAM_NoError; | ||
| 189 | } | ||
| 190 | |||
| 191 | uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 192 | PIMA_Container_t* const PIMAHeader) | ||
| 193 | { | ||
| 194 | uint16_t TimeoutMSRem = SI_COMMAND_DATA_TIMEOUT_MS; | ||
| 195 | uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); | ||
| 196 | |||
| 197 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 198 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 199 | |||
| 200 | Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address); | ||
| 201 | Pipe_Unfreeze(); | ||
| 202 | |||
| 203 | while (!(Pipe_IsINReceived())) | ||
| 204 | { | ||
| 205 | uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); | ||
| 206 | |||
| 207 | if (CurrentFrameNumber != PreviousFrameNumber) | ||
| 208 | { | ||
| 209 | PreviousFrameNumber = CurrentFrameNumber; | ||
| 210 | |||
| 211 | if (!(TimeoutMSRem--)) | ||
| 212 | return PIPE_RWSTREAM_Timeout; | ||
| 213 | } | ||
| 214 | |||
| 215 | Pipe_Freeze(); | ||
| 216 | Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 217 | Pipe_Unfreeze(); | ||
| 218 | |||
| 219 | if (Pipe_IsStalled()) | ||
| 220 | { | ||
| 221 | USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); | ||
| 222 | return PIPE_RWSTREAM_PipeStalled; | ||
| 223 | } | ||
| 224 | |||
| 225 | Pipe_Freeze(); | ||
| 226 | Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address); | ||
| 227 | Pipe_Unfreeze(); | ||
| 228 | |||
| 229 | if (Pipe_IsStalled()) | ||
| 230 | { | ||
| 231 | USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); | ||
| 232 | return PIPE_RWSTREAM_PipeStalled; | ||
| 233 | } | ||
| 234 | |||
| 235 | if (USB_HostState == HOST_STATE_Unattached) | ||
| 236 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 237 | } | ||
| 238 | |||
| 239 | Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NULL); | ||
| 240 | |||
| 241 | if (PIMAHeader->Type == CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) | ||
| 242 | { | ||
| 243 | uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); | ||
| 244 | |||
| 245 | if (ParamBytes) | ||
| 246 | Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NULL); | ||
| 247 | |||
| 248 | Pipe_ClearIN(); | ||
| 249 | } | ||
| 250 | |||
| 251 | Pipe_Freeze(); | ||
| 252 | |||
| 253 | return PIPE_RWSTREAM_NoError; | ||
| 254 | } | ||
| 255 | |||
| 256 | uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 257 | const void* Buffer, | ||
| 258 | const uint16_t Bytes) | ||
| 259 | { | ||
| 260 | uint8_t ErrorCode; | ||
| 261 | |||
| 262 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 263 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 264 | |||
| 265 | Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address); | ||
| 266 | Pipe_Unfreeze(); | ||
| 267 | |||
| 268 | ErrorCode = Pipe_Write_Stream_LE(Buffer, Bytes, NULL); | ||
| 269 | |||
| 270 | Pipe_ClearOUT(); | ||
| 271 | Pipe_Freeze(); | ||
| 272 | |||
| 273 | return ErrorCode; | ||
| 274 | } | ||
| 275 | |||
| 276 | uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 277 | void* Buffer, | ||
| 278 | const uint16_t Bytes) | ||
| 279 | { | ||
| 280 | uint8_t ErrorCode; | ||
| 281 | |||
| 282 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 283 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 284 | |||
| 285 | Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address); | ||
| 286 | Pipe_Unfreeze(); | ||
| 287 | |||
| 288 | ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NULL); | ||
| 289 | |||
| 290 | Pipe_Freeze(); | ||
| 291 | |||
| 292 | return ErrorCode; | ||
| 293 | } | ||
| 294 | |||
| 295 | bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) | ||
| 296 | { | ||
| 297 | bool IsEventReceived = false; | ||
| 298 | |||
| 299 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 300 | return false; | ||
| 301 | |||
| 302 | Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipe.Address); | ||
| 303 | Pipe_Unfreeze(); | ||
| 304 | |||
| 305 | if (Pipe_IsINReceived()) | ||
| 306 | IsEventReceived = true; | ||
| 307 | |||
| 308 | Pipe_Freeze(); | ||
| 309 | |||
| 310 | return IsEventReceived; | ||
| 311 | } | ||
| 312 | |||
| 313 | uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 314 | PIMA_Container_t* const PIMAHeader) | ||
| 315 | { | ||
| 316 | uint8_t ErrorCode; | ||
| 317 | |||
| 318 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 319 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 320 | |||
| 321 | Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipe.Address); | ||
| 322 | Pipe_Unfreeze(); | ||
| 323 | |||
| 324 | ErrorCode = Pipe_Read_Stream_LE(PIMAHeader, sizeof(PIMA_Container_t), NULL); | ||
| 325 | |||
| 326 | Pipe_ClearIN(); | ||
| 327 | Pipe_Freeze(); | ||
| 328 | |||
| 329 | return ErrorCode; | ||
| 330 | } | ||
| 331 | |||
| 332 | uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) | ||
| 333 | { | ||
| 334 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 335 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 336 | |||
| 337 | uint8_t ErrorCode; | ||
| 338 | |||
| 339 | SIInterfaceInfo->State.TransactionID = 0; | ||
| 340 | SIInterfaceInfo->State.IsSessionOpen = false; | ||
| 341 | |||
| 342 | PIMA_Container_t PIMABlock = (PIMA_Container_t) | ||
| 343 | { | ||
| 344 | .DataLength = CPU_TO_LE32(PIMA_COMMAND_SIZE(1)), | ||
| 345 | .Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock), | ||
| 346 | .Code = CPU_TO_LE16(0x1002), | ||
| 347 | .Params = {CPU_TO_LE32(1)}, | ||
| 348 | }; | ||
| 349 | |||
| 350 | if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) | ||
| 351 | return ErrorCode; | ||
| 352 | |||
| 353 | if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) | ||
| 354 | return ErrorCode; | ||
| 355 | |||
| 356 | if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001))) | ||
| 357 | return SI_ERROR_LOGICAL_CMD_FAILED; | ||
| 358 | |||
| 359 | SIInterfaceInfo->State.IsSessionOpen = true; | ||
| 360 | |||
| 361 | return PIPE_RWSTREAM_NoError; | ||
| 362 | } | ||
| 363 | |||
| 364 | uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) | ||
| 365 | { | ||
| 366 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 367 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 368 | |||
| 369 | uint8_t ErrorCode; | ||
| 370 | |||
| 371 | PIMA_Container_t PIMABlock = (PIMA_Container_t) | ||
| 372 | { | ||
| 373 | .DataLength = CPU_TO_LE32(PIMA_COMMAND_SIZE(1)), | ||
| 374 | .Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock), | ||
| 375 | .Code = CPU_TO_LE16(0x1003), | ||
| 376 | .Params = {CPU_TO_LE32(1)}, | ||
| 377 | }; | ||
| 378 | |||
| 379 | if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) | ||
| 380 | return ErrorCode; | ||
| 381 | |||
| 382 | if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) | ||
| 383 | return ErrorCode; | ||
| 384 | |||
| 385 | SIInterfaceInfo->State.IsSessionOpen = false; | ||
| 386 | |||
| 387 | if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001))) | ||
| 388 | return SI_ERROR_LOGICAL_CMD_FAILED; | ||
| 389 | |||
| 390 | return PIPE_RWSTREAM_NoError; | ||
| 391 | } | ||
| 392 | |||
| 393 | uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 394 | const uint16_t Operation, | ||
| 395 | const uint8_t TotalParams, | ||
| 396 | uint32_t* const Params) | ||
| 397 | { | ||
| 398 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 399 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 400 | |||
| 401 | uint8_t ErrorCode; | ||
| 402 | |||
| 403 | PIMA_Container_t PIMABlock = (PIMA_Container_t) | ||
| 404 | { | ||
| 405 | .DataLength = cpu_to_le32(PIMA_COMMAND_SIZE(TotalParams)), | ||
| 406 | .Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock), | ||
| 407 | .Code = cpu_to_le16(Operation), | ||
| 408 | }; | ||
| 409 | |||
| 410 | memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams); | ||
| 411 | |||
| 412 | if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) | ||
| 413 | return ErrorCode; | ||
| 414 | |||
| 415 | return PIPE_RWSTREAM_NoError; | ||
| 416 | } | ||
| 417 | |||
| 418 | uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) | ||
| 419 | { | ||
| 420 | uint8_t ErrorCode; | ||
| 421 | PIMA_Container_t PIMABlock; | ||
| 422 | |||
| 423 | if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) | ||
| 424 | return PIPE_RWSTREAM_DeviceDisconnected; | ||
| 425 | |||
| 426 | if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) | ||
| 427 | return ErrorCode; | ||
| 428 | |||
| 429 | if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001))) | ||
| 430 | return SI_ERROR_LOGICAL_CMD_FAILED; | ||
| 431 | |||
| 432 | return PIPE_RWSTREAM_NoError; | ||
| 433 | } | ||
| 434 | |||
| 435 | #endif | ||
| 436 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h b/lib/lufa/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h new file mode 100644 index 000000000..ababdb09a --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h | |||
| @@ -0,0 +1,317 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Host mode driver for the library USB Still Image Class driver. | ||
| 33 | * | ||
| 34 | * Host mode driver for the library USB Still Image Class driver. | ||
| 35 | * | ||
| 36 | * \note This file should not be included directly. It is automatically included as needed by the USB module driver | ||
| 37 | * dispatch header located in LUFA/Drivers/USB.h. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassSI | ||
| 41 | * \defgroup Group_USBClassStillImageHost Still Image Class Host Mode Driver | ||
| 42 | * | ||
| 43 | * \section Sec_USBClassStillImageHost_Dependencies Module Source Dependencies | ||
| 44 | * The following files must be built with any user project that uses this module: | ||
| 45 | * - LUFA/Drivers/USB/Class/Host/StillImageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 46 | * | ||
| 47 | * \section Sec_USBClassStillImageHost_ModDescription Module Description | ||
| 48 | * Host Mode USB Class driver framework interface, for the Still Image USB Class driver. | ||
| 49 | * | ||
| 50 | * @{ | ||
| 51 | */ | ||
| 52 | |||
| 53 | #ifndef __SI_CLASS_HOST_H__ | ||
| 54 | #define __SI_CLASS_HOST_H__ | ||
| 55 | |||
| 56 | /* Includes: */ | ||
| 57 | #include "../../USB.h" | ||
| 58 | #include "../Common/StillImageClassCommon.h" | ||
| 59 | |||
| 60 | /* Enable C linkage for C++ Compilers: */ | ||
| 61 | #if defined(__cplusplus) | ||
| 62 | extern "C" { | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* Preprocessor Checks: */ | ||
| 66 | #if !defined(__INCLUDE_FROM_SI_DRIVER) | ||
| 67 | #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* Public Interface - May be used in end-application: */ | ||
| 71 | /* Macros: */ | ||
| 72 | /** Error code for some Still Image Host functions, indicating a logical (and not hardware) error. */ | ||
| 73 | #define SI_ERROR_LOGICAL_CMD_FAILED 0x80 | ||
| 74 | |||
| 75 | /* Type Defines: */ | ||
| 76 | /** \brief Still Image Class Host Mode Configuration and State Structure. | ||
| 77 | * | ||
| 78 | * Class state structure. An instance of this structure should be made within the user application, | ||
| 79 | * and passed to each of the Still Image class driver functions as the \c SIInterfaceInfo parameter. This | ||
| 80 | * stores each Still Image interface's configuration and state information. | ||
| 81 | */ | ||
| 82 | typedef struct | ||
| 83 | { | ||
| 84 | struct | ||
| 85 | { | ||
| 86 | USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ | ||
| 87 | USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ | ||
| 88 | USB_Pipe_Table_t EventsPipe; /**< Event notification IN Pipe configuration table. */ | ||
| 89 | } Config; /**< Config data for the USB class interface within the device. All elements in this section | ||
| 90 | * <b>must</b> be set or the interface will fail to enumerate and operate correctly. | ||
| 91 | */ | ||
| 92 | struct | ||
| 93 | { | ||
| 94 | bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid | ||
| 95 | * after \ref SI_Host_ConfigurePipes() is called and the Host state machine is in the | ||
| 96 | * Configured state. | ||
| 97 | */ | ||
| 98 | uint8_t InterfaceNumber; /**< Interface index of the Still Image interface within the attached device. */ | ||
| 99 | |||
| 100 | bool IsSessionOpen; /**< Indicates if a PIMA session is currently open with the attached device. */ | ||
| 101 | uint32_t TransactionID; /**< Transaction ID for the next transaction to send to the device. */ | ||
| 102 | } State; /**< State data for the USB class interface within the device. All elements in this section | ||
| 103 | * <b>may</b> be set to initial values, but may also be ignored to default to sane values when | ||
| 104 | * the interface is enumerated. | ||
| 105 | */ | ||
| 106 | } USB_ClassInfo_SI_Host_t; | ||
| 107 | |||
| 108 | /* Enums: */ | ||
| 109 | /** Enum for the possible error codes returned by the \ref SI_Host_ConfigurePipes() function. */ | ||
| 110 | enum SI_Host_EnumerationFailure_ErrorCodes_t | ||
| 111 | { | ||
| 112 | SI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ | ||
| 113 | SI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ | ||
| 114 | SI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's | ||
| 115 | * Configuration Descriptor. | ||
| 116 | */ | ||
| 117 | SI_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* Function Prototypes: */ | ||
| 121 | /** Host interface configuration routine, to configure a given Still Image host interface instance using the | ||
| 122 | * Configuration Descriptor read from an attached USB device. This function automatically updates the given Still | ||
| 123 | * Image Host instance's state values and configures the pipes required to communicate with the interface if it is | ||
| 124 | * found within the device. This should be called once after the stack has enumerated the attached device, while | ||
| 125 | * the host state machine is in the Addressed state. | ||
| 126 | * | ||
| 127 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 128 | * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. | ||
| 129 | * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. | ||
| 130 | * | ||
| 131 | * \return A value from the \ref SI_Host_EnumerationFailure_ErrorCodes_t enum. | ||
| 132 | */ | ||
| 133 | uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 134 | uint16_t ConfigDescriptorSize, | ||
| 135 | void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); | ||
| 136 | |||
| 137 | /** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands | ||
| 138 | * are issued to the device. Only one session can be open at the one time. | ||
| 139 | * | ||
| 140 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 141 | * call will fail. | ||
| 142 | * | ||
| 143 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 144 | * | ||
| 145 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device | ||
| 146 | * returned a logical command failure. | ||
| 147 | */ | ||
| 148 | uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 149 | |||
| 150 | /** Closes an already opened PIMA session with the attached device. This should be used after all session-orientated | ||
| 151 | * PIMA commands have been issued to the device. | ||
| 152 | * | ||
| 153 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 154 | * call will fail. | ||
| 155 | * | ||
| 156 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 157 | * | ||
| 158 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device | ||
| 159 | * returned a logical command failure. | ||
| 160 | */ | ||
| 161 | uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 162 | |||
| 163 | /** Sends a raw PIMA block header to the device, filling out the transaction ID automatically. This can be used to send | ||
| 164 | * arbitrary PIMA blocks to the device with or without parameters. | ||
| 165 | * | ||
| 166 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 167 | * call will fail. | ||
| 168 | * | ||
| 169 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 170 | * \param[in] PIMAHeader Pointer to a PIMA container structure that is to be sent. | ||
| 171 | * | ||
| 172 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 173 | */ | ||
| 174 | uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 175 | PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1) | ||
| 176 | ATTR_NON_NULL_PTR_ARG(2); | ||
| 177 | |||
| 178 | /** Receives a raw PIMA block header from the device. This can be used to receive arbitrary PIMA blocks from the device with | ||
| 179 | * or without parameters. | ||
| 180 | * | ||
| 181 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 182 | * call will fail. | ||
| 183 | * | ||
| 184 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 185 | * \param[out] PIMAHeader Pointer to a PIMA container structure where the received block is to be stored. | ||
| 186 | * | ||
| 187 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 188 | */ | ||
| 189 | uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 190 | PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1) | ||
| 191 | ATTR_NON_NULL_PTR_ARG(2); | ||
| 192 | |||
| 193 | /** Sends a given PIMA command to the attached device, filling out the PIMA command header's Transaction ID automatically. | ||
| 194 | * | ||
| 195 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 196 | * call will fail. | ||
| 197 | * | ||
| 198 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 199 | * \param[in] Operation PIMA operation code to issue to the device. | ||
| 200 | * \param[in] TotalParams Total number of 32-bit parameters to send to the device in the issued command block. | ||
| 201 | * \param[in] Params Pointer to an array of 32-bit values containing the parameters to send in the command block. | ||
| 202 | * | ||
| 203 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device | ||
| 204 | * returned a logical command failure. | ||
| 205 | */ | ||
| 206 | uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 207 | const uint16_t Operation, | ||
| 208 | const uint8_t TotalParams, | ||
| 209 | uint32_t* const Params) ATTR_NON_NULL_PTR_ARG(1); | ||
| 210 | |||
| 211 | /** Receives and checks a response block from the attached Still Image device, once a command has been issued and all data | ||
| 212 | * associated with the command has been transferred. | ||
| 213 | * | ||
| 214 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 215 | * call will fail. | ||
| 216 | * | ||
| 217 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 218 | * | ||
| 219 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device | ||
| 220 | * returned a logical command failure. | ||
| 221 | */ | ||
| 222 | uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 223 | |||
| 224 | /** Indicates if the device has issued a PIMA event block to the host via the asynchronous events pipe. | ||
| 225 | * | ||
| 226 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 227 | * call will fail. | ||
| 228 | * | ||
| 229 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 230 | * | ||
| 231 | * \return Boolean \c true if an event is waiting to be read, \c false otherwise. | ||
| 232 | */ | ||
| 233 | bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); | ||
| 234 | |||
| 235 | /** Receives an asynchronous event block from the device via the asynchronous events pipe. | ||
| 236 | * | ||
| 237 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 238 | * call will fail. | ||
| 239 | * | ||
| 240 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 241 | * \param[out] PIMAHeader Pointer to a PIMA container structure where the event should be stored. | ||
| 242 | * | ||
| 243 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device | ||
| 244 | * returned a logical command failure. | ||
| 245 | */ | ||
| 246 | uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 247 | PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1) | ||
| 248 | ATTR_NON_NULL_PTR_ARG(2); | ||
| 249 | |||
| 250 | /** Sends arbitrary data to the attached device, for use in the data phase of PIMA commands which require data | ||
| 251 | * transfer beyond the regular PIMA command block parameters. | ||
| 252 | * | ||
| 253 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 254 | * call will fail. | ||
| 255 | * | ||
| 256 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 257 | * \param[in] Buffer Pointer to a buffer where the data to send has been stored. | ||
| 258 | * \param[in] Bytes Length in bytes of the data in the buffer to send to the attached device. | ||
| 259 | * | ||
| 260 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 261 | */ | ||
| 262 | uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 263 | const void* Buffer, | ||
| 264 | const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 265 | |||
| 266 | /** Receives arbitrary data from the attached device, for use in the data phase of PIMA commands which require data | ||
| 267 | * transfer beyond the regular PIMA command block parameters. | ||
| 268 | * | ||
| 269 | * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the | ||
| 270 | * call will fail. | ||
| 271 | * | ||
| 272 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 273 | * \param[out] Buffer Pointer to a buffer where the received data is to be stored. | ||
| 274 | * \param[in] Bytes Length in bytes of the data to read. | ||
| 275 | * | ||
| 276 | * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. | ||
| 277 | */ | ||
| 278 | uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, | ||
| 279 | void* Buffer, | ||
| 280 | const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); | ||
| 281 | |||
| 282 | /* Inline Functions: */ | ||
| 283 | /** General management task for a given Still Image host class interface, required for the correct operation of the | ||
| 284 | * interface. This should be called frequently in the main program loop, before the master USB management task | ||
| 285 | * \ref USB_USBTask(). | ||
| 286 | * | ||
| 287 | * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. | ||
| 288 | */ | ||
| 289 | static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; | ||
| 290 | static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) | ||
| 291 | { | ||
| 292 | (void)SIInterfaceInfo; | ||
| 293 | } | ||
| 294 | |||
| 295 | /* Private Interface - For use in library only: */ | ||
| 296 | #if !defined(__DOXYGEN__) | ||
| 297 | /* Macros: */ | ||
| 298 | #define SI_COMMAND_DATA_TIMEOUT_MS 10000 | ||
| 299 | |||
| 300 | /* Function Prototypes: */ | ||
| 301 | #if defined(__INCLUDE_FROM_STILLIMAGE_HOST_C) | ||
| 302 | static uint8_t DCOMP_SI_Host_NextSIInterface(void* const CurrentDescriptor) | ||
| 303 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 304 | static uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor) | ||
| 305 | ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); | ||
| 306 | #endif | ||
| 307 | #endif | ||
| 308 | |||
| 309 | /* Disable C linkage for C++ Compilers: */ | ||
| 310 | #if defined(__cplusplus) | ||
| 311 | } | ||
| 312 | #endif | ||
| 313 | |||
| 314 | #endif | ||
| 315 | |||
| 316 | /** @} */ | ||
| 317 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/MIDIClass.h b/lib/lufa/LUFA/Drivers/USB/Class/MIDIClass.h new file mode 100644 index 000000000..a35ae13aa --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/MIDIClass.h | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB MIDI Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB MIDI Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassMIDI MIDI Class Driver | ||
| 42 | * \brief USB class driver for the USB-IF MIDI class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassMIDI_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * - LUFA/Drivers/USB/Class/Host/MIDIClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 48 | * | ||
| 49 | * \section Sec_USBClassMIDI_ModDescription Module Description | ||
| 50 | * MIDI Class Driver module. This module contains an internal implementation of the USB MIDI Class, for both Device | ||
| 51 | * and Host USB modes. User applications can use this class driver instead of implementing the MIDI class manually | ||
| 52 | * via the low-level LUFA APIs. | ||
| 53 | * | ||
| 54 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 55 | * Hosts or Devices using the USB MIDI Class. | ||
| 56 | * | ||
| 57 | * \note The USB MIDI class is actually a special case of the regular Audio class, thus this module depends on | ||
| 58 | * structure definitions from the \ref Group_USBClassAudioDevice class driver module. | ||
| 59 | * | ||
| 60 | * @{ | ||
| 61 | */ | ||
| 62 | |||
| 63 | #ifndef _MIDI_CLASS_H_ | ||
| 64 | #define _MIDI_CLASS_H_ | ||
| 65 | |||
| 66 | /* Macros: */ | ||
| 67 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 68 | #define __INCLUDE_FROM_MIDI_DRIVER | ||
| 69 | |||
| 70 | /* Includes: */ | ||
| 71 | #include "../Core/USBMode.h" | ||
| 72 | |||
| 73 | #if defined(USB_CAN_BE_DEVICE) | ||
| 74 | #include "Device/MIDIClassDevice.h" | ||
| 75 | #endif | ||
| 76 | |||
| 77 | #if defined(USB_CAN_BE_HOST) | ||
| 78 | #include "Host/MIDIClassHost.h" | ||
| 79 | #endif | ||
| 80 | |||
| 81 | #endif | ||
| 82 | |||
| 83 | /** @} */ | ||
| 84 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/MassStorageClass.h b/lib/lufa/LUFA/Drivers/USB/Class/MassStorageClass.h new file mode 100644 index 000000000..fa41fbf81 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/MassStorageClass.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB Mass Storage Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB Mass Storage Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassMS Mass Storage Class Driver | ||
| 42 | * \brief USB class driver for the USB-IF Bulk-Only Transport Mass Storage class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassMS_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * - LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 48 | * | ||
| 49 | * \section Sec_USBClassMS_ModDescription Module Description | ||
| 50 | * Mass Storage Class Driver module. This module contains an internal implementation of the USB Mass Storage Class, for both | ||
| 51 | * Device and Host USB modes. User applications can use this class driver instead of implementing the Mass Storage class | ||
| 52 | * manually via the low-level LUFA APIs. | ||
| 53 | * | ||
| 54 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 55 | * Hosts or Devices using the USB Mass Storage Class. | ||
| 56 | * | ||
| 57 | * @{ | ||
| 58 | */ | ||
| 59 | |||
| 60 | #ifndef _MS_CLASS_H_ | ||
| 61 | #define _MS_CLASS_H_ | ||
| 62 | |||
| 63 | /* Macros: */ | ||
| 64 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 65 | #define __INCLUDE_FROM_MS_DRIVER | ||
| 66 | |||
| 67 | /* Includes: */ | ||
| 68 | #include "../Core/USBMode.h" | ||
| 69 | |||
| 70 | #if defined(USB_CAN_BE_DEVICE) | ||
| 71 | #include "Device/MassStorageClassDevice.h" | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #if defined(USB_CAN_BE_HOST) | ||
| 75 | #include "Host/MassStorageClassHost.h" | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #endif | ||
| 79 | |||
| 80 | /** @} */ | ||
| 81 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/PrinterClass.h b/lib/lufa/LUFA/Drivers/USB/Class/PrinterClass.h new file mode 100644 index 000000000..78ad52068 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/PrinterClass.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB Printer Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB Printer Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassPrinter Printer Class Driver | ||
| 42 | * \brief USB class driver for the USB-IF Printer class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassPrinter_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Host/PrinterClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * - LUFA/Drivers/USB/Class/Host/PrinterClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 48 | * | ||
| 49 | * \section Sec_USBClassPrinter_ModDescription Module Description | ||
| 50 | * Printer Class Driver module. This module contains an internal implementation of the USB Printer Class, for the base | ||
| 51 | * USB Printer transport layer for USB Host mode only. Note that printers are free to implement whatever printer language | ||
| 52 | * they choose on top of this (e.g. Postscript), and so this driver exposes low level data transport functions only rather | ||
| 53 | * than high level raster or text functions. User applications can use this class driver instead of implementing the Printer | ||
| 54 | * class manually via the low-level LUFA APIs. | ||
| 55 | * | ||
| 56 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 57 | * Devices using the USB Printer Class. | ||
| 58 | * | ||
| 59 | * @{ | ||
| 60 | */ | ||
| 61 | |||
| 62 | #ifndef _PRINTER_CLASS_H_ | ||
| 63 | #define _PRINTER_CLASS_H_ | ||
| 64 | |||
| 65 | /* Macros: */ | ||
| 66 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 67 | #define __INCLUDE_FROM_PRINTER_DRIVER | ||
| 68 | |||
| 69 | /* Includes: */ | ||
| 70 | #include "../Core/USBMode.h" | ||
| 71 | |||
| 72 | #if defined(USB_CAN_BE_DEVICE) | ||
| 73 | #include "Device/PrinterClassDevice.h" | ||
| 74 | #endif | ||
| 75 | |||
| 76 | #if defined(USB_CAN_BE_HOST) | ||
| 77 | #include "Host/PrinterClassHost.h" | ||
| 78 | #endif | ||
| 79 | |||
| 80 | #endif | ||
| 81 | |||
| 82 | /** @} */ | ||
| 83 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/RNDISClass.h b/lib/lufa/LUFA/Drivers/USB/Class/RNDISClass.h new file mode 100644 index 000000000..07b4f5627 --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/RNDISClass.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB RNDIS Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB RNDIS Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassRNDIS RNDIS (Networking) Class Driver | ||
| 42 | * \brief USB class driver for the Microsoft Remote Network Driver Interface Specification (RNDIS) class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassRNDIS_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * - LUFA/Drivers/USB/Class/Host/RNDISClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 48 | * | ||
| 49 | * \section Sec_USBClassRNDIS_ModDescription Module Description | ||
| 50 | * RNDIS Class Driver module. This module contains an internal implementation of the Microsoft USB RNDIS Networking | ||
| 51 | * Class, for both Device and Host USB modes. User applications can use this class driver instead of implementing the | ||
| 52 | * RNDIS class manually via the low-level LUFA APIs. | ||
| 53 | * | ||
| 54 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 55 | * Hosts using the USB RNDIS Class. | ||
| 56 | * | ||
| 57 | * @{ | ||
| 58 | */ | ||
| 59 | |||
| 60 | #ifndef _RNDIS_CLASS_H_ | ||
| 61 | #define _RNDIS_CLASS_H_ | ||
| 62 | |||
| 63 | /* Macros: */ | ||
| 64 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 65 | #define __INCLUDE_FROM_RNDIS_DRIVER | ||
| 66 | |||
| 67 | /* Includes: */ | ||
| 68 | #include "../Core/USBMode.h" | ||
| 69 | |||
| 70 | #if defined(USB_CAN_BE_DEVICE) | ||
| 71 | #include "Device/RNDISClassDevice.h" | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #if defined(USB_CAN_BE_HOST) | ||
| 75 | #include "Host/RNDISClassHost.h" | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #endif | ||
| 79 | |||
| 80 | /** @} */ | ||
| 81 | |||
diff --git a/lib/lufa/LUFA/Drivers/USB/Class/StillImageClass.h b/lib/lufa/LUFA/Drivers/USB/Class/StillImageClass.h new file mode 100644 index 000000000..7cb8b4fcf --- /dev/null +++ b/lib/lufa/LUFA/Drivers/USB/Class/StillImageClass.h | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * \brief Master include file for the library USB Still Image Class driver. | ||
| 33 | * | ||
| 34 | * Master include file for the library USB Still Image Class driver, for both host and device modes, where available. | ||
| 35 | * | ||
| 36 | * This file should be included in all user projects making use of this optional class driver, instead of | ||
| 37 | * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. | ||
| 38 | */ | ||
| 39 | |||
| 40 | /** \ingroup Group_USBClassDrivers | ||
| 41 | * \defgroup Group_USBClassSI Still Image Class Driver | ||
| 42 | * \brief USB class driver for the USB-IF Still Image (PIMA-compliant) class standard. | ||
| 43 | * | ||
| 44 | * \section Sec_USBClassSI_Dependencies Module Source Dependencies | ||
| 45 | * The following files must be built with any user project that uses this module: | ||
| 46 | * - LUFA/Drivers/USB/Class/Host/StillImageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i> | ||
| 47 | * | ||
| 48 | * \section Sec_USBClassSI_ModDescription Module Description | ||
| 49 | * Still Image Class Driver module. This module contains an internal implementation of the USB Still Image Class, | ||
| 50 | * for USB Host mode only. User applications can use this class driver instead of implementing the Still Image class | ||
| 51 | * manually via the low-level LUFA APIs. | ||
| 52 | * | ||
| 53 | * This module is designed to simplify the user code by exposing only the required interface needed to interface with | ||
| 54 | * Devices using the USB Still Image Class. | ||
| 55 | * | ||
| 56 | * @{ | ||
| 57 | */ | ||
| 58 | |||
| 59 | #ifndef _SI_CLASS_H_ | ||
| 60 | #define _SI_CLASS_H_ | ||
| 61 | |||
| 62 | /* Macros: */ | ||
| 63 | #define __INCLUDE_FROM_USB_DRIVER | ||
| 64 | #define __INCLUDE_FROM_SI_DRIVER | ||
| 65 | |||
| 66 | /* Includes: */ | ||
| 67 | #include "../Core/USBMode.h" | ||
| 68 | |||
| 69 | #if defined(USB_CAN_BE_HOST) | ||
| 70 | #include "Host/StillImageClassHost.h" | ||
| 71 | #endif | ||
| 72 | |||
| 73 | #endif | ||
| 74 | |||
| 75 | /** @} */ | ||
| 76 | |||
