First commit off H2003-V1_USB_PWM
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/H2003-V1_USB_PWM/Debug
|
||||
/.vs
|
||||
22
H2003-V1_USB_PWM.atsln
Normal file
22
H2003-V1_USB_PWM.atsln
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Atmel Studio Solution File, Format Version 11.00
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "H2003-V1_USB_PWM", "H2003-V1_USB_PWM\H2003-V1_USB_PWM.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|AVR = Debug|AVR
|
||||
Release|AVR = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.ActiveCfg = Debug|AVR
|
||||
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.Build.0 = Debug|AVR
|
||||
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.ActiveCfg = Release|AVR
|
||||
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.Build.0 = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
220
H2003-V1_USB_PWM/Descriptors.c
Normal file
220
H2003-V1_USB_PWM/Descriptors.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** HID class report descriptor. This is a special descriptor constructed with values from the
|
||||
* USBIF HID class specification to describe the reports and capabilities of the HID device. This
|
||||
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
|
||||
* the device will send, and what it may be sent back from the host. Refer to the HID specification for
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
|
||||
{
|
||||
/* Use the HID class driver's standard Vendor HID report.
|
||||
* Vendor Usage Page: 0
|
||||
* Vendor Collection Usage: 1
|
||||
* Vendor Report IN Usage: 2
|
||||
* Vendor Report OUT Usage: 3
|
||||
* Vendor Report Size: GENERIC_REPORT_SIZE
|
||||
*/
|
||||
HID_DESCRIPTOR_VENDOR(0x00, 0x01, 0x02, 0x03, GENERIC_REPORT_SIZE)
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* device characteristics, including the supported USB version, control endpoint size and the
|
||||
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
||||
* process begins.
|
||||
*/
|
||||
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(1,1,0),
|
||||
.Class = USB_CSCP_NoDeviceClass,
|
||||
.SubClass = USB_CSCP_NoDeviceSubclass,
|
||||
.Protocol = USB_CSCP_NoDeviceProtocol,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204F,
|
||||
.ReleaseNumber = VERSION_BCD(0,0,1),
|
||||
|
||||
.ManufacturerStrIndex = STRING_ID_Manufacturer,
|
||||
.ProductStrIndex = STRING_ID_Product,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
|
||||
* of the device in one of its supported configurations, including information about any device interfaces
|
||||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
|
||||
* a configuration so that the host may correctly communicate with the USB device.
|
||||
*/
|
||||
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = INTERFACE_ID_GenericHID,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = HID_CSCP_HIDClass,
|
||||
.SubClass = HID_CSCP_NonBootSubclass,
|
||||
.Protocol = HID_CSCP_NonBootProtocol,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_GenericHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(1,1,1),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = HID_DTYPE_Report,
|
||||
.HIDReportLength = sizeof(GenericReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = GENERIC_IN_EPADDR,
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = GENERIC_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
},
|
||||
};
|
||||
|
||||
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
|
||||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
|
||||
|
||||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
|
||||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera");
|
||||
|
||||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
|
||||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA Generic HID Demo");
|
||||
|
||||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
|
||||
* documentation) by the application code so that the address and size of a requested descriptor can be given
|
||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint16_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
const uint8_t DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
const void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case STRING_ID_Language:
|
||||
Address = &LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case STRING_ID_Manufacturer:
|
||||
Address = &ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case STRING_ID_Product:
|
||||
Address = &ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_DTYPE_HID:
|
||||
Address = &ConfigurationDescriptor.HID_GenericHID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
break;
|
||||
case HID_DTYPE_Report:
|
||||
Address = &GenericReport;
|
||||
Size = sizeof(GenericReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
||||
95
H2003-V1_USB_PWM/Descriptors.h
Normal file
95
H2003-V1_USB_PWM/Descriptors.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
|
||||
// Generic HID Interface
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_HID_t HID_GenericHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
|
||||
* should have a unique ID index associated with it, which can be used to refer to the
|
||||
* interface from other descriptors.
|
||||
*/
|
||||
enum InterfaceDescriptors_t
|
||||
{
|
||||
INTERFACE_ID_GenericHID = 0, /**< GenericHID interface descriptor ID */
|
||||
};
|
||||
|
||||
/** Enum for the device string descriptor IDs within the device. Each string descriptor should
|
||||
* have a unique ID index associated with it, which can be used to refer to the string from
|
||||
* other descriptors.
|
||||
*/
|
||||
enum StringDescriptors_t
|
||||
{
|
||||
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
|
||||
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
|
||||
STRING_ID_Product = 2, /**< Product string ID */
|
||||
};
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint address of the Generic HID reporting IN endpoint. */
|
||||
#define GENERIC_IN_EPADDR (ENDPOINT_DIR_IN | 1)
|
||||
|
||||
/** Size in bytes of the Generic HID reporting endpoint. */
|
||||
#define GENERIC_EPSIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint16_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
#endif
|
||||
|
||||
79
H2003-V1_USB_PWM/GenericHID.txt
Normal file
79
H2003-V1_USB_PWM/GenericHID.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Generic HID Device
|
||||
*
|
||||
* \section Sec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* \li Series 7 USB AVRs (AT90USBxxx7)
|
||||
* \li Series 6 USB AVRs (AT90USBxxx6)
|
||||
* \li Series 4 USB AVRs (ATMEGAxxU4)
|
||||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2)
|
||||
* \li Series AU XMEGA AVRs (ATXMEGAxxxAxU)
|
||||
* \li Series B XMEGA AVRs (ATXMEGAxxxBx)
|
||||
* \li Series C XMEGA AVRs (ATXMEGAxxxCx)
|
||||
*
|
||||
* \section Sec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Supported USB Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section Sec_Description Project Description:
|
||||
*
|
||||
* Generic HID device demonstration application. This gives a simple reference application
|
||||
* for implementing a generic HID device, using the basic USB HID drivers in all modern
|
||||
* OSes (i.e. no special drivers required). By default it accepts and sends up to 8 byte reports
|
||||
* to and from a USB Host, and transmits the last sent report back to the host.
|
||||
*
|
||||
* On start-up the system will automatically enumerate and function as a vendor HID device.
|
||||
* When controlled by a custom HID class application, reports can be sent and received by
|
||||
* both the standard data endpoint and control request methods defined in the HID specification.
|
||||
*
|
||||
* \section Sec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th><b>Define Name:</b></th>
|
||||
* <th><b>Location:</b></th>
|
||||
* <th><b>Description:</b></th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>GENERIC_REPORT_SIZE</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>This token defines the size of the device reports, both sent and received (including report ID byte). The value
|
||||
* must be an integer ranging from 1 to 255.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
||||
86
H2003-V1_USB_PWM/H2003-V1_USB_PWM.componentinfo.xml
Normal file
86
H2003-V1_USB_PWM/H2003-V1_USB_PWM.componentinfo.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Store xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="AtmelPackComponentManagement">
|
||||
<ProjectComponents>
|
||||
<ProjectComponent z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
|
||||
<CApiVersion></CApiVersion>
|
||||
<CBundle></CBundle>
|
||||
<CClass>Device</CClass>
|
||||
<CGroup>Startup</CGroup>
|
||||
<CSub></CSub>
|
||||
<CVariant></CVariant>
|
||||
<CVendor>Atmel</CVendor>
|
||||
<CVersion>1.5.0</CVersion>
|
||||
<DefaultRepoPath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs</DefaultRepoPath>
|
||||
<DependentComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
|
||||
<Description></Description>
|
||||
<Files xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.5.362\include\</AbsolutePath>
|
||||
<Attribute></Attribute>
|
||||
<Category>include</Category>
|
||||
<Condition>C</Condition>
|
||||
<FileContentHash i:nil="true" />
|
||||
<FileVersion></FileVersion>
|
||||
<Name>include/</Name>
|
||||
<SelectString></SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.5.362\include\avr\iom16u2.h</AbsolutePath>
|
||||
<Attribute></Attribute>
|
||||
<Category>header</Category>
|
||||
<Condition>C</Condition>
|
||||
<FileContentHash>GvCQ1wBIcgPNSfB8xl1d/A==</FileContentHash>
|
||||
<FileVersion></FileVersion>
|
||||
<Name>include/avr/iom16u2.h</Name>
|
||||
<SelectString></SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.5.362\templates\main.c</AbsolutePath>
|
||||
<Attribute>template</Attribute>
|
||||
<Category>source</Category>
|
||||
<Condition>C Exe</Condition>
|
||||
<FileContentHash>KjvOcFWd++tbnsEMfVPd/w==</FileContentHash>
|
||||
<FileVersion></FileVersion>
|
||||
<Name>templates/main.c</Name>
|
||||
<SelectString>Main file (.c)</SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.5.362\templates\main.cpp</AbsolutePath>
|
||||
<Attribute>template</Attribute>
|
||||
<Category>source</Category>
|
||||
<Condition>C Exe</Condition>
|
||||
<FileContentHash>mkKaE95TOoATsuBGv6jmxg==</FileContentHash>
|
||||
<FileVersion></FileVersion>
|
||||
<Name>templates/main.cpp</Name>
|
||||
<SelectString>Main file (.cpp)</SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.5.362\gcc\dev\atmega16u2</AbsolutePath>
|
||||
<Attribute></Attribute>
|
||||
<Category>libraryPrefix</Category>
|
||||
<Condition>GCC</Condition>
|
||||
<FileContentHash i:nil="true" />
|
||||
<FileVersion></FileVersion>
|
||||
<Name>gcc/dev/atmega16u2</Name>
|
||||
<SelectString></SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
</Files>
|
||||
<PackName>ATmega_DFP</PackName>
|
||||
<PackPath>C:/Program Files (x86)/Atmel/Studio/7.0/Packs/Atmel/ATmega_DFP/1.5.362/Atmel.ATmega_DFP.pdsc</PackPath>
|
||||
<PackVersion>1.5.362</PackVersion>
|
||||
<PresentInProject>true</PresentInProject>
|
||||
<ReferenceConditionId>ATmega16U2</ReferenceConditionId>
|
||||
<RteComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
|
||||
<d4p1:string></d4p1:string>
|
||||
</RteComponents>
|
||||
<Status>Resolved</Status>
|
||||
<VersionMode>Fixed</VersionMode>
|
||||
<IsComponentInAtProject>true</IsComponentInAtProject>
|
||||
</ProjectComponent>
|
||||
</ProjectComponents>
|
||||
</Store>
|
||||
735
H2003-V1_USB_PWM/H2003-V1_USB_PWM.cproj
Normal file
735
H2003-V1_USB_PWM/H2003-V1_USB_PWM.cproj
Normal file
@@ -0,0 +1,735 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectVersion>7.0</ProjectVersion>
|
||||
<ToolchainName>com.Atmel.AVRGCC8.C</ToolchainName>
|
||||
<ProjectGuid>dce6c7e3-ee26-4d79-826b-08594b9ad897</ProjectGuid>
|
||||
<avrdevice>ATmega16U2</avrdevice>
|
||||
<avrdeviceseries>mega</avrdeviceseries>
|
||||
<OutputType>Executable</OutputType>
|
||||
<Language>C</Language>
|
||||
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
|
||||
<OutputFileExtension>.elf</OutputFileExtension>
|
||||
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
|
||||
<AssemblyName>H2003-V1_USB_PWM</AssemblyName>
|
||||
<Name>H2003-V1_USB_PWM</Name>
|
||||
<RootNamespace>H2003-V1_USB_PWM</RootNamespace>
|
||||
<ToolchainFlavour>Native</ToolchainFlavour>
|
||||
<KeepTimersRunning>true</KeepTimersRunning>
|
||||
<OverrideVtor>false</OverrideVtor>
|
||||
<CacheFlash>true</CacheFlash>
|
||||
<ProgFlashFromRam>true</ProgFlashFromRam>
|
||||
<RamSnippetAddress>0x20000000</RamSnippetAddress>
|
||||
<UncachedRange />
|
||||
<preserveEEPROM>true</preserveEEPROM>
|
||||
<OverrideVtorValue>exception_table</OverrideVtorValue>
|
||||
<BootSegment>2</BootSegment>
|
||||
<ResetRule>0</ResetRule>
|
||||
<eraseonlaunchrule>0</eraseonlaunchrule>
|
||||
<EraseKey />
|
||||
<AsfFrameworkConfig>
|
||||
<framework-data>
|
||||
<options>
|
||||
<option id="lufa.common" value="Add" config="" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<option id="lufa.demos.device.class.generic_hid" value="Add" config="" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<option id="lufa.drivers.board" value="Add" config="none" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<option id="lufa.drivers.board.leds" value="Add" config="" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<option id="lufa.drivers.usb" value="Add" config="" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<option id="lufa.platform" value="Add" config="" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
</options>
|
||||
<configurations>
|
||||
<configuration key="lufa.drivers.board.name" value="none" default="none" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
</configurations>
|
||||
<files>
|
||||
<file path="src/config/AppConfig.h" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/Config/AppConfig.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/config/LUFAConfig.h" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/Config/LUFAConfig.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="Descriptors.c" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/Descriptors.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="Descriptors.h" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/Descriptors.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="GenericHID.c" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/GenericHID.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="GenericHID.h" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/GenericHID.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="GenericHID.txt" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/GenericHID.txt" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="HostTestApp/test_generic_hid_libusb.js" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/HostTestApp/test_generic_hid_libusb.js" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="HostTestApp/test_generic_hid_libusb.py" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/HostTestApp/test_generic_hid_libusb.py" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="HostTestApp/test_generic_hid_winusb.py" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/HostTestApp/test_generic_hid_winusb.py" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="doxyfile" framework="" version="" source="Demos/Device/ClassDriver/GenericHID/doxyfile" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Common/ArchitectureSpecific.h" framework="" version="" source="LUFA/Common/ArchitectureSpecific.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Common/Architectures.h" framework="" version="" source="LUFA/Common/Architectures.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Common/Attributes.h" framework="" version="" source="LUFA/Common/Attributes.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Common/BoardTypes.h" framework="" version="" source="LUFA/Common/BoardTypes.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Common/Common.h" framework="" version="" source="LUFA/Common/Common.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Common/CompilerSpecific.h" framework="" version="" source="LUFA/Common/CompilerSpecific.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Common/Endianness.h" framework="" version="" source="LUFA/Common/Endianness.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/Board/Board.h" framework="" version="" source="LUFA/Drivers/Board/Board.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/Board/LEDs.h" framework="" version="" source="LUFA/Drivers/Board/LEDs.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/AndroidAccessoryClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/AudioClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/AudioClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/CDCClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/CDCClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/AudioClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/CDCClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/HIDClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/HIDParser.c" framework="" version="" source="LUFA/Drivers/USB/Class/Common/HIDParser.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/HIDParser.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/HIDParser.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/HIDReportData.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/HIDReportData.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h" framework="" version="" source="LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c" framework="" version="" source="LUFA/Drivers/USB/Class/Device/AudioClassDevice.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h" framework="" version="" source="LUFA/Drivers/USB/Class/Device/AudioClassDevice.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c" framework="" version="" source="LUFA/Drivers/USB/Class/Device/CDCClassDevice.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h" framework="" version="" source="LUFA/Drivers/USB/Class/Device/CDCClassDevice.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c" framework="" version="" source="LUFA/Drivers/USB/Class/Device/HIDClassDevice.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h" framework="" version="" source="LUFA/Drivers/USB/Class/Device/HIDClassDevice.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c" framework="" version="" source="LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h" framework="" version="" source="LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c" framework="" version="" source="LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h" framework="" version="" source="LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c" framework="" version="" source="LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h" framework="" version="" source="LUFA/Drivers/USB/Class/Device/PrinterClassDevice.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c" framework="" version="" source="LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h" framework="" version="" source="LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/HIDClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/HIDClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/AudioClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/AudioClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/AudioClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/AudioClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/CDCClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/CDCClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/CDCClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/CDCClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/HIDClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/HIDClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/HIDClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/HIDClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/MIDIClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/MIDIClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/PrinterClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/PrinterClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/RNDISClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/RNDISClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c" framework="" version="" source="LUFA/Drivers/USB/Class/Host/StillImageClassHost.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h" framework="" version="" source="LUFA/Drivers/USB/Class/Host/StillImageClassHost.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/MIDIClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/MIDIClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/MassStorageClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/MassStorageClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/PrinterClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/PrinterClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/RNDISClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/RNDISClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Class/StillImageClass.h" framework="" version="" source="LUFA/Drivers/USB/Class/StillImageClass.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_R.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_R.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_RW.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_RW.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/Template/Template_Pipe_RW.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/Template/Template_Pipe_RW.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h" framework="" version="" source="LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/ConfigDescriptors.c" framework="" version="" source="LUFA/Drivers/USB/Core/ConfigDescriptors.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/ConfigDescriptors.h" framework="" version="" source="LUFA/Drivers/USB/Core/ConfigDescriptors.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/Device.h" framework="" version="" source="LUFA/Drivers/USB/Core/Device.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/DeviceStandardReq.c" framework="" version="" source="LUFA/Drivers/USB/Core/DeviceStandardReq.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/DeviceStandardReq.h" framework="" version="" source="LUFA/Drivers/USB/Core/DeviceStandardReq.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/Endpoint.h" framework="" version="" source="LUFA/Drivers/USB/Core/Endpoint.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/EndpointStream.h" framework="" version="" source="LUFA/Drivers/USB/Core/EndpointStream.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/Events.c" framework="" version="" source="LUFA/Drivers/USB/Core/Events.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/Events.h" framework="" version="" source="LUFA/Drivers/USB/Core/Events.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/Host.h" framework="" version="" source="LUFA/Drivers/USB/Core/Host.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/HostStandardReq.c" framework="" version="" source="LUFA/Drivers/USB/Core/HostStandardReq.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/HostStandardReq.h" framework="" version="" source="LUFA/Drivers/USB/Core/HostStandardReq.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/OTG.h" framework="" version="" source="LUFA/Drivers/USB/Core/OTG.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/Pipe.h" framework="" version="" source="LUFA/Drivers/USB/Core/Pipe.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/PipeStream.h" framework="" version="" source="LUFA/Drivers/USB/Core/PipeStream.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/StdDescriptors.h" framework="" version="" source="LUFA/Drivers/USB/Core/StdDescriptors.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/StdRequestType.h" framework="" version="" source="LUFA/Drivers/USB/Core/StdRequestType.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/USBController.h" framework="" version="" source="LUFA/Drivers/USB/Core/USBController.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/USBInterrupt.h" framework="" version="" source="LUFA/Drivers/USB/Core/USBInterrupt.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/USBMode.h" framework="" version="" source="LUFA/Drivers/USB/Core/USBMode.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/USBTask.c" framework="" version="" source="LUFA/Drivers/USB/Core/USBTask.c" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/Core/USBTask.h" framework="" version="" source="LUFA/Drivers/USB/Core/USBTask.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Drivers/USB/USB.h" framework="" version="" source="LUFA/Drivers/USB/USB.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/License.txt" framework="" version="" source="LUFA/License.txt" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Platform/Platform.h" framework="" version="" source="LUFA/Platform/Platform.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<file path="src/LUFA/LUFA/Version.h" framework="" version="" source="LUFA/Version.h" changed="False" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
</files>
|
||||
<documentation help="" />
|
||||
<offline-documentation help="" />
|
||||
<dependencies>
|
||||
<content-extension eid="fourwalledcubicle.lufa" uuidref="0e160d5c-e331-48d9-850b-e0387912171b" version="17.04.18" />
|
||||
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.49.1" />
|
||||
</dependencies>
|
||||
<project id="lufa.demos.device.class.generic_hid.example.avr8" value="Add" config="" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
<board id="lufa.boards.dummy.avr8" value="Add" config="" content-id="0e160d5c-e331-48d9-850b-e0387912171b" />
|
||||
</framework-data>
|
||||
</AsfFrameworkConfig>
|
||||
<avrtool>com.atmel.avrdbg.tool.megadfu</avrtool>
|
||||
<avrtoolserialnumber />
|
||||
<avrdeviceexpectedsignature>0x1E9489</avrdeviceexpectedsignature>
|
||||
<com_atmel_avrdbg_tool_megadfu>
|
||||
<ToolOptions xmlns="">
|
||||
<InterfaceProperties>
|
||||
</InterfaceProperties>
|
||||
</ToolOptions>
|
||||
<ToolType xmlns="">com.atmel.avrdbg.tool.megadfu</ToolType>
|
||||
<ToolNumber xmlns="">
|
||||
</ToolNumber>
|
||||
<ToolName xmlns="">Atmel Mega DFU</ToolName>
|
||||
</com_atmel_avrdbg_tool_megadfu>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGcc>
|
||||
<avrgcc.common.Device>-mmcu=atmega16u2 -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.5.362\gcc\dev\atmega16u2"</avrgcc.common.Device>
|
||||
<avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>NDEBUG</Value>
|
||||
<Value>ARCH=ARCH_AVR8</Value>
|
||||
<Value>BOARD=BOARD_NONE</Value>
|
||||
<Value>F_CPU=16000000UL</Value>
|
||||
<Value>USE_LUFA_CONFIG_HEADER</Value>
|
||||
<Value>F_USB=16000000UL</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.symbols.DefSymbols>
|
||||
<avrgcc.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>../src/LUFA</Value>
|
||||
<Value>../src</Value>
|
||||
<Value>../src/config</Value>
|
||||
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.5.362\include\</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.directories.IncludePaths>
|
||||
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
|
||||
<avrgcc.compiler.optimization.OtherFlags>-fdata-sections</avrgcc.compiler.optimization.OtherFlags>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcc.compiler.miscellaneous.OtherFlags>-mrelax -std=gnu99 -fno-strict-aliasing -fno-jump-tables</avrgcc.compiler.miscellaneous.OtherFlags>
|
||||
<avrgcc.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcc.linker.libraries.Libraries>
|
||||
<avrgcc.linker.miscellaneous.LinkerFlags>-Wl,--relax</avrgcc.linker.miscellaneous.LinkerFlags>
|
||||
<avrgcc.assembler.general.AssemblerFlags>-DARCH=ARCH_AVR8 -DBOARD=BOARD_NONE -DF_CPU=16000000UL -DF_USB=16000000UL -DUSE_LUFA_CONFIG_HEADER</avrgcc.assembler.general.AssemblerFlags>
|
||||
<avrgcc.assembler.general.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>../src/LUFA</Value>
|
||||
<Value>../src</Value>
|
||||
<Value>../src/config</Value>
|
||||
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.5.362\include\</Value>
|
||||
</ListValues>
|
||||
</avrgcc.assembler.general.IncludePaths>
|
||||
</AvrGcc>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGcc>
|
||||
<avrgcc.common.Device>-mmcu=atmega16u2 -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.5.362\gcc\dev\atmega16u2"</avrgcc.common.Device>
|
||||
<avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>DEBUG</Value>
|
||||
<Value>ARCH=ARCH_AVR8</Value>
|
||||
<Value>BOARD=BOARD_NONE</Value>
|
||||
<Value>F_CPU=16000000UL</Value>
|
||||
<Value>USE_LUFA_CONFIG_HEADER</Value>
|
||||
<Value>F_USB=16000000UL</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.symbols.DefSymbols>
|
||||
<avrgcc.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>../src/LUFA</Value>
|
||||
<Value>../src</Value>
|
||||
<Value>../src/config</Value>
|
||||
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.5.362\include\</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.directories.IncludePaths>
|
||||
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
|
||||
<avrgcc.compiler.optimization.OtherFlags>-fdata-sections</avrgcc.compiler.optimization.OtherFlags>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcc.compiler.miscellaneous.OtherFlags>-mrelax -std=gnu99 -fno-strict-aliasing -fno-jump-tables</avrgcc.compiler.miscellaneous.OtherFlags>
|
||||
<avrgcc.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcc.linker.libraries.Libraries>
|
||||
<avrgcc.linker.miscellaneous.LinkerFlags>-Wl,--relax</avrgcc.linker.miscellaneous.LinkerFlags>
|
||||
<avrgcc.assembler.general.AssemblerFlags>-DARCH=ARCH_AVR8 -DBOARD=BOARD_NONE -DF_CPU=16000000UL -DF_USB=16000000UL -DUSE_LUFA_CONFIG_HEADER</avrgcc.assembler.general.AssemblerFlags>
|
||||
<avrgcc.assembler.general.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>../src/LUFA</Value>
|
||||
<Value>../src</Value>
|
||||
<Value>../src/config</Value>
|
||||
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.5.362\include\</Value>
|
||||
</ListValues>
|
||||
</avrgcc.assembler.general.IncludePaths>
|
||||
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
|
||||
</AvrGcc>
|
||||
</ToolchainSettings>
|
||||
<PostBuildEvent>copy "$(SolutionDir)megaUSB_DFU_Bootloaders\at90usb162-bl-usb-1_0_5.hex" "$(OutputDirectory)\Bootloader.hex"
|
||||
srec_cat "$(OutputDirectory)\$(OutputFilename).hex" -Intel "$(OutputDirectory)\Bootloader.hex" -Intel -o "$(OutputFilename)_DFU.hex" -Intel</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="HostTestApp\" />
|
||||
<Folder Include="src\" />
|
||||
<Folder Include="src\config\" />
|
||||
<Folder Include="src\LUFA\" />
|
||||
<Folder Include="src\LUFA\LUFA\" />
|
||||
<Folder Include="src\LUFA\LUFA\Common\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\Board\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\Misc\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\Peripheral\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\Class\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\Class\Common\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\Class\Device\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\Class\Host\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\Core\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\" />
|
||||
<Folder Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Template\" />
|
||||
<Folder Include="src\LUFA\LUFA\Platform\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Descriptors.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<None Include="src\asf.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="doxyfile">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="GenericHID.txt">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="HostTestApp\test_generic_hid_libusb.js">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="HostTestApp\test_generic_hid_libusb.py">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="HostTestApp\test_generic_hid_winusb.py">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\EndpointStream.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Device_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\PrinterClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Endpoint_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\config\AppConfig.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\Board\Board.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\USBTask.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\PrinterClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\HIDClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\RNDISClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\USBMode.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\Board\LEDs.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\Device.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Common\BoardTypes.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Device\CDCClassDevice.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Common\Attributes.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="H2003.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\HIDClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\CDCClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\StdDescriptors.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\MassStorageClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\OTG.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\EndpointStream_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\HostStandardReq.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\RNDISClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\Pipe.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Common\CompilerSpecific.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\AndroidAccessoryClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\USB.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\StillImageClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\MIDIClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\PipeStream.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Device\MIDIClassDevice.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Platform\Platform.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\StillImageClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\AudioClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\config\LUFAConfig.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\HIDParser.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\MassStorageClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\MIDIClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Common\Common.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\MIDIClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Common\ArchitectureSpecific.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\AndroidAccessoryClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="Descriptors.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<Compile Include="H2003.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\StdRequestType.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Device\AudioClassDevice.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\ConfigDescriptors.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Device\HIDClassDevice.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\USBInterrupt_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\HIDClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\AudioClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\AndroidAccessoryClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\RNDISClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\OTG_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\Host.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\USBInterrupt.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\MassStorageClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\AudioClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\HIDReportData.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Device\RNDISClassDevice.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\DeviceStandardReq.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\Events.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Host_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Device\MassStorageClassDevice.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Device\PrinterClassDevice.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Common\Endianness.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Common\Architectures.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\PrinterClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Common\CDCClassCommon.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\PipeStream_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\USBController.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Version.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Pipe_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\USBController_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Core\Endpoint.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\Host\StillImageClassHost.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<None Include="src\LUFA\LUFA\Drivers\USB\Class\CDCClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</None>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Misc\AT45DB321C.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Misc\AT45DB642D.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Misc\RingBuffer.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Misc\TerminalCodes.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\ADC.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\ADC_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\SerialSPI_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\Serial_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\Serial_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\SPI_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\TWI_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\AVR8\TWI_AVR8.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\Serial.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\SerialSPI.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\SPI.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\Peripheral\TWI.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Common\HIDParser.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Device\AudioClassDevice.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Device\CDCClassDevice.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Device\HIDClassDevice.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Device\MassStorageClassDevice.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Device\MIDIClassDevice.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Device\PrinterClassDevice.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Device\RNDISClassDevice.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\AndroidAccessoryClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\AudioClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\CDCClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\HIDClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\MassStorageClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\MIDIClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\PrinterClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\RNDISClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Class\Host\StillImageClassHost.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Device_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\EndpointStream_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Endpoint_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Host_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\PipeStream_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Pipe_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Template\Template_Endpoint_Control_R.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Template\Template_Endpoint_Control_W.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Template\Template_Endpoint_RW.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\Template\Template_Pipe_RW.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\USBController_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\AVR8\USBInterrupt_AVR8.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\ConfigDescriptors.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\DeviceStandardReq.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\Events.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\HostStandardReq.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="src\LUFA\LUFA\Drivers\USB\Core\USBTask.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
||||
</Project>
|
||||
222
H2003-V1_USB_PWM/H2003.c
Normal file
222
H2003-V1_USB_PWM/H2003.c
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the GenericHID demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "H2003.h"
|
||||
|
||||
/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
|
||||
static uint8_t PrevHIDReportBuffer[GENERIC_REPORT_SIZE];
|
||||
|
||||
|
||||
volatile bool PowerState;
|
||||
volatile uint8_t BrightnessLevel;
|
||||
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Generic_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = INTERFACE_ID_GenericHID,
|
||||
.ReportINEndpoint =
|
||||
{
|
||||
.Address = GENERIC_IN_EPADDR,
|
||||
.Size = GENERIC_EPSIZE,
|
||||
.Banks = 1,
|
||||
},
|
||||
.PrevReportINBuffer = PrevHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
void LEDSet(bool state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
PORTB |= (1<<DDB5); //Bit high
|
||||
}
|
||||
else
|
||||
{
|
||||
PORTB &= ~(1<<DDB5); //clear bit
|
||||
}
|
||||
}
|
||||
|
||||
void LEDToggle()
|
||||
{
|
||||
PORTB ^= 1 << DDB5;
|
||||
}
|
||||
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
GlobalInterruptEnable();
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Generic_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Hardware Initialization */
|
||||
Serial_Init(9600, false);
|
||||
/* Create a stdio stream for the serial port for stdin and stdout */
|
||||
Serial_CreateStream(NULL);
|
||||
|
||||
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Led */
|
||||
DDRB |= (1<<DDB5); //As output
|
||||
|
||||
/* PWM Timer 0 8bit */
|
||||
DDRB |= (1<<DDB7); //OC0A PB7 as output
|
||||
//Clear OC0A on Compare Match, set OC0A at TOP
|
||||
//TCCR0A |= (1<<COM0A1);
|
||||
TCCR0A |= (1<<COM0A0) | (1<<COM0A1);
|
||||
|
||||
//Mode 3
|
||||
//Fast PWM, TOP = 0xFF, Update at TOP, TOV flag on MAX
|
||||
TCCR0A |= (1<<WGM00) | (1<<WGM01);
|
||||
|
||||
//Clock No prescaling
|
||||
TCCR0B |= (1<<CS00);
|
||||
|
||||
/* Hardware Initialization */
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
//LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
//LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
bool ConfigSuccess = true;
|
||||
ConfigSuccess &= HID_Device_ConfigureEndpoints(&Generic_HID_Interface);
|
||||
USB_Device_EnableSOFEvents();
|
||||
|
||||
//LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Control Request reception event. */
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Generic_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Generic_HID_Interface);
|
||||
}
|
||||
|
||||
/** HID class driver callback function for the creation of HID reports to the host.
|
||||
*
|
||||
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
|
||||
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
|
||||
* \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature
|
||||
* \param[out] ReportData Pointer to a buffer where the created report should be stored
|
||||
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent)
|
||||
*
|
||||
* \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent
|
||||
*/
|
||||
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize)
|
||||
{
|
||||
uint8_t* Data = (uint8_t*)ReportData;
|
||||
Data[0] = PowerState;
|
||||
Data[1] = BrightnessLevel;
|
||||
*ReportSize = GENERIC_REPORT_SIZE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** HID class driver callback function for the processing of HID reports from the host.
|
||||
*
|
||||
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
|
||||
* \param[in] ReportID Report ID of the received report from the host
|
||||
* \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature
|
||||
* \param[in] ReportData Pointer to a buffer where the received report has been stored
|
||||
* \param[in] ReportSize Size in bytes of the received HID report
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, const uint8_t ReportType, const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
uint8_t* Data = (uint8_t*)ReportData;
|
||||
|
||||
//printf("Size = %d - ", ReportSize);
|
||||
//printf("Data = %x-%x\r\n", Data[0],Data[1]);
|
||||
|
||||
if ((bool)Data[0] != PowerState)
|
||||
{
|
||||
PowerState = (bool)Data[0];
|
||||
if (PowerState == true)
|
||||
{
|
||||
//Enable PB7 Timer Compare
|
||||
TCCR0A |= (1<<COM0A1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Disable PB7 Timer Compare
|
||||
TCCR0A &= ~(1<<COM0A1);
|
||||
}
|
||||
}
|
||||
|
||||
BrightnessLevel = Data[1];
|
||||
OCR0A = (255 - BrightnessLevel);
|
||||
}
|
||||
|
||||
80
H2003-V1_USB_PWM/H2003.h
Normal file
80
H2003-V1_USB_PWM/H2003.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for GenericHID.c.
|
||||
*/
|
||||
|
||||
#ifndef _GENERICHID_H_
|
||||
#define _H2003_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
//#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
#include <LUFA/Drivers/Peripheral/Serial.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
//#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
//#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
//#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
//#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_ControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, const uint8_t ReportType, const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
||||
143
H2003-V1_USB_PWM/HostTestApp/test_generic_hid_libusb.js
Normal file
143
H2003-V1_USB_PWM/HostTestApp/test_generic_hid_libusb.js
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// LUFA Library
|
||||
// Copyright (C) Dean Camera, 2017.
|
||||
//
|
||||
// dean [at] fourwalledcubicle [dot] com
|
||||
// www.lufa-lib.org
|
||||
|
||||
// LUFA Generic HID device demo host test script. This script will send a
|
||||
// continuous stream of generic reports to the device, to show a variable LED
|
||||
// pattern on the target board. Send and received report data is printed to
|
||||
// the terminal.
|
||||
//
|
||||
// You have to install the usb and async modules prior to executing this script:
|
||||
// apt-get install libusb-1.0-0-dev
|
||||
// npm install usb async sprintf
|
||||
|
||||
var usb = require('usb');
|
||||
var async = require('async');
|
||||
var sprintf = require('sprintf');
|
||||
|
||||
var deviceVid = 0x03EB;
|
||||
var devicePid = 0x204F;
|
||||
var reportLength = 8;
|
||||
|
||||
function getAndInitHidDeviceAndInterface()
|
||||
{
|
||||
device = usb.findByIds(deviceVid, devicePid);
|
||||
if (!device) {
|
||||
console.log('No device found');
|
||||
process.exit(1);
|
||||
}
|
||||
device.open();
|
||||
|
||||
var hidInterface = device.interface(0);
|
||||
if (hidInterface.isKernelDriverActive()) {
|
||||
hidInterface.detachKernelDriver();
|
||||
}
|
||||
hidInterface.claim();
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
setConfiguration(0, function(error, data) {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
return {hidDevice:device, hidInterface:hidInterface};
|
||||
}
|
||||
|
||||
function read(hidInterface, callback)
|
||||
{
|
||||
endpoint = hidInterface.endpoints[0];
|
||||
endpoint.transfer(reportLength, function(error, data) {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
} else {
|
||||
console.log("Received LED Pattern:", data.slice(0, 4));
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function write(hidDevice, message, callback)
|
||||
{
|
||||
hidDevice.controlTransfer( // Send a Set Report control request
|
||||
parseInt('00100001', 2), // bmRequestType (constant for this control request)
|
||||
0x09, // bmRequest (constant for this control request)
|
||||
0x0809, // wValue (MSB is report type, LSB is report number)
|
||||
0, // wIndex (interface number)
|
||||
message, // message to be sent
|
||||
function(error, data) { // callback to be executed upon finishing the transfer
|
||||
console.log("Sent LED Pattern:", message.slice(1, 5))
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function setConfiguration(configurationNumber, callback)
|
||||
{
|
||||
device.controlTransfer( // Send a Set Configuration control request
|
||||
parseInt('00000000', 2), // bmRequestType
|
||||
0x09, // bmRequest
|
||||
0, // wValue (Configuration value)
|
||||
0, // wIndex
|
||||
new Buffer(0), // message to be sent
|
||||
callback // callback to be executed upon finishing the transfer
|
||||
);
|
||||
}
|
||||
|
||||
// @TODO: Fix this function because apparently it doesn't work for some reason.
|
||||
function getStringDescriptor(stringId, languageId, callback)
|
||||
{
|
||||
var STRING_DESCRIPTOR_TYPE = 0x03;
|
||||
var wValue = (STRING_DESCRIPTOR_TYPE << 8) | stringId;
|
||||
|
||||
device.controlTransfer( // Send a Get Descriptor control request
|
||||
parseInt('10000000', 2), // bmRequestType
|
||||
0x06, // bmRequest
|
||||
wValue, // wValue
|
||||
languageId, // wIndex
|
||||
64, // response length
|
||||
callback // callback to be executed upon finishing the transfer
|
||||
);
|
||||
}
|
||||
|
||||
function setNextPattern()
|
||||
{
|
||||
var pattern = [
|
||||
hidInterface.interface,
|
||||
(p >> 3) & 1,
|
||||
(p >> 2) & 1,
|
||||
(p >> 1) & 1,
|
||||
(p >> 0) & 1
|
||||
];
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
write(hidDevice, new Buffer(pattern), callback);
|
||||
},
|
||||
function(callback) {
|
||||
read(hidInterface, callback);
|
||||
},
|
||||
function(callback) {
|
||||
p = (p + 1) % 16
|
||||
setTimeout(setNextPattern, 200);
|
||||
callback();
|
||||
}]);
|
||||
}
|
||||
|
||||
var hidDeviceAndInterface = getAndInitHidDeviceAndInterface();
|
||||
var hidDevice = hidDeviceAndInterface.hidDevice
|
||||
var hidInterface = hidDeviceAndInterface.hidInterface;
|
||||
|
||||
console.log(sprintf("Connected to device 0x%04X/0x%04X - %s [%s]",
|
||||
hidDevice.deviceDescriptor.idVendor,
|
||||
hidDevice.deviceDescriptor.idProduct,
|
||||
hidDevice.deviceDescriptor.iProduct,
|
||||
hidDevice.deviceDescriptor.iManufacturer));
|
||||
|
||||
p = 0
|
||||
setNextPattern();
|
||||
98
H2003-V1_USB_PWM/HostTestApp/test_generic_hid_libusb.py
Normal file
98
H2003-V1_USB_PWM/HostTestApp/test_generic_hid_libusb.py
Normal file
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
"""
|
||||
|
||||
"""
|
||||
LUFA Generic HID device demo host test script. This script will send a
|
||||
continuous stream of generic reports to the device, to show a variable LED
|
||||
pattern on the target board. Send and received report data is printed to
|
||||
the terminal.
|
||||
|
||||
Requires the PyUSB library (http://sourceforge.net/apps/trac/pyusb/).
|
||||
"""
|
||||
|
||||
import sys
|
||||
from time import sleep
|
||||
import usb.core
|
||||
import usb.util
|
||||
|
||||
# Generic HID device VID, PID and report payload length (length is increased
|
||||
# by one to account for the Report ID byte that must be pre-pended)
|
||||
device_vid = 0x03EB
|
||||
device_pid = 0x204F
|
||||
|
||||
def get_and_init_hid_device():
|
||||
device = usb.core.find(idVendor=device_vid, idProduct=device_pid)
|
||||
|
||||
if device is None:
|
||||
sys.exit("Could not find USB device.")
|
||||
|
||||
if device.is_kernel_driver_active(0):
|
||||
try:
|
||||
device.detach_kernel_driver(0)
|
||||
except usb.core.USBError as exception:
|
||||
sys.exit("Could not detatch kernel driver: %s" % str(exception))
|
||||
|
||||
try:
|
||||
device.set_configuration()
|
||||
except usb.core.USBError as exception:
|
||||
sys.exit("Could not set configuration: %s" % str(exception))
|
||||
|
||||
return device
|
||||
|
||||
def send_led_pattern(device, led1, led2, led3, led4):
|
||||
# Report data for the demo is LED on/off data
|
||||
report_data = [led1, led2, led3, led4]
|
||||
|
||||
# Send the generated report to the device
|
||||
number_of_bytes_written = device.ctrl_transfer( # Set Report control request
|
||||
0b00100001, # bmRequestType (constant for this control request)
|
||||
0x09, # bmRequest (constant for this control request)
|
||||
0, # wValue (MSB is report type, LSB is report number)
|
||||
0, # wIndex (interface number)
|
||||
report_data # report data to be sent
|
||||
);
|
||||
assert number_of_bytes_written == len(report_data)
|
||||
|
||||
print("Sent LED Pattern: {0}".format(report_data))
|
||||
|
||||
def receive_led_pattern(hid_device):
|
||||
endpoint = hid_device[0][(0,0)][0]
|
||||
report_data = hid_device.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize)
|
||||
return list(report_data)
|
||||
|
||||
def main():
|
||||
hid_device = get_and_init_hid_device()
|
||||
|
||||
print("Connected to device 0x%04X/0x%04X - %s [%s]" %
|
||||
(hid_device.idVendor, hid_device.idProduct,
|
||||
usb.util.get_string(hid_device, 256, hid_device.iProduct),
|
||||
usb.util.get_string(hid_device, 256, hid_device.iManufacturer)))
|
||||
|
||||
p = 0
|
||||
while (True):
|
||||
# Convert the current pattern index to a bit-mask and send
|
||||
send_led_pattern(hid_device,
|
||||
(p >> 3) & 1,
|
||||
(p >> 2) & 1,
|
||||
(p >> 1) & 1,
|
||||
(p >> 0) & 1)
|
||||
|
||||
# Receive and print the current LED pattern
|
||||
led_pattern = receive_led_pattern(hid_device)[0:4]
|
||||
print("Received LED Pattern: {0}".format(led_pattern))
|
||||
|
||||
# Compute next LED pattern in sequence
|
||||
p = (p + 1) % 16
|
||||
|
||||
# Delay a bit for visual effect
|
||||
sleep(.2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
96
H2003-V1_USB_PWM/HostTestApp/test_generic_hid_winusb.py
Normal file
96
H2003-V1_USB_PWM/HostTestApp/test_generic_hid_winusb.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
"""
|
||||
|
||||
"""
|
||||
LUFA Generic HID device demo host test script. This script will send a
|
||||
continuous stream of generic reports to the device, to show a variable LED
|
||||
pattern on the target board. Send and received report data is printed to
|
||||
the terminal.
|
||||
|
||||
Requires the pywinusb library (https://pypi.python.org/pypi/pywinusb/).
|
||||
"""
|
||||
|
||||
import sys
|
||||
from time import sleep
|
||||
import pywinusb.hid as hid
|
||||
|
||||
# Generic HID device VID, PID and report payload length (length is increased
|
||||
# by one to account for the Report ID byte that must be pre-pended)
|
||||
device_vid = 0x03EB
|
||||
device_pid = 0x204F
|
||||
report_length = 1 + 8
|
||||
|
||||
|
||||
def get_hid_device_handle():
|
||||
hid_device_filter = hid.HidDeviceFilter(vendor_id=device_vid,
|
||||
product_id=device_pid)
|
||||
|
||||
valid_hid_devices = hid_device_filter.get_devices()
|
||||
|
||||
if len(valid_hid_devices) is 0:
|
||||
return None
|
||||
else:
|
||||
return valid_hid_devices[0]
|
||||
|
||||
|
||||
def send_led_pattern(device, led1, led2, led3, led4):
|
||||
# Report data for the demo is the report ID (always zero) followed by the
|
||||
# LED on/off data
|
||||
report_data = [0, led1, led2, led3, led4]
|
||||
|
||||
# Zero-extend the array to the length the report should be
|
||||
report_data.extend([0] * (report_length - len(report_data)))
|
||||
|
||||
# Send the generated report to the device
|
||||
device.send_output_report(report_data)
|
||||
|
||||
print("Sent LED Pattern: {0}".format(report_data[1:5]))
|
||||
|
||||
|
||||
def received_led_pattern(report_data):
|
||||
print("Received LED Pattern: {0}".format(report_data[1:5]))
|
||||
|
||||
|
||||
def main():
|
||||
hid_device = get_hid_device_handle()
|
||||
|
||||
if hid_device is None:
|
||||
print("No valid HID device found.")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
hid_device.open()
|
||||
|
||||
print("Connected to device 0x%04X/0x%04X - %s [%s]" %
|
||||
(hid_device.vendor_id, hid_device.product_id,
|
||||
hid_device.product_name, hid_device.vendor_name))
|
||||
|
||||
# Set up the HID input report handler to receive reports
|
||||
hid_device.set_raw_data_handler(received_led_pattern)
|
||||
|
||||
p = 0
|
||||
while (hid_device.is_plugged()):
|
||||
# Convert the current pattern index to a bit-mask and send
|
||||
send_led_pattern(hid_device,
|
||||
(p >> 3) & 1,
|
||||
(p >> 2) & 1,
|
||||
(p >> 1) & 1,
|
||||
(p >> 0) & 1)
|
||||
|
||||
# Compute next LED pattern in sequence
|
||||
p = (p + 1) % 16
|
||||
|
||||
# Delay a bit for visual effect
|
||||
sleep(.2)
|
||||
|
||||
finally:
|
||||
hid_device.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
2396
H2003-V1_USB_PWM/doxyfile
Normal file
2396
H2003-V1_USB_PWM/doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
185
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/ArchitectureSpecific.h
Normal file
185
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/ArchitectureSpecific.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Architecture specific definitions relating to specific processor architectures.
|
||||
*
|
||||
* \copydetails Group_ArchitectureSpecific
|
||||
*
|
||||
* \note Do not include this file directly, rather include the Common.h header file instead to gain this file's
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common
|
||||
* \defgroup Group_ArchitectureSpecific Architecture Specific Definitions
|
||||
* \brief Architecture specific definitions relating to specific processor architectures.
|
||||
*
|
||||
* Architecture specific macros, functions and other definitions, which relate to specific architectures. This
|
||||
* definitions may or may not be available in some form on other architectures, and thus should be protected by
|
||||
* preprocessor checks in portable code to prevent compile errors.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LUFA_ARCHSPEC_H__
|
||||
#define __LUFA_ARCHSPEC_H__
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_COMMON_H)
|
||||
#error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
|
||||
#endif
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
#if (ARCH == ARCH_AVR8) || (ARCH == ARCH_XMEGA) || defined(__DOXYGEN__)
|
||||
#if (ARCH == ARCH_AVR8) || defined(__DOXYGEN__)
|
||||
/** Re-enables the AVR's JTAG bus in software, until a system reset. This will re-enable JTAG debugging
|
||||
* interface after is has been disabled in software via \ref JTAG_DISABLE().
|
||||
*
|
||||
* \note This macro is not available for all architectures.
|
||||
*/
|
||||
#define JTAG_ENABLE() do { \
|
||||
__asm__ __volatile__ ( \
|
||||
"in __tmp_reg__,__SREG__" "\n\t" \
|
||||
"cli" "\n\t" \
|
||||
"out %1, %0" "\n\t" \
|
||||
"out __SREG__, __tmp_reg__" "\n\t" \
|
||||
"out %1, %0" "\n\t" \
|
||||
: \
|
||||
: "r" (MCUCR & ~(1 << JTD)), \
|
||||
"M" (_SFR_IO_ADDR(MCUCR)) \
|
||||
: "r0"); \
|
||||
} while (0)
|
||||
|
||||
/** Disables the AVR's JTAG bus in software, until a system reset. This will override the current JTAG
|
||||
* status as set by the JTAGEN fuse, disabling JTAG debugging and reverting the JTAG pins back to GPIO
|
||||
* mode.
|
||||
*
|
||||
* \note This macro is not available for all architectures.
|
||||
*/
|
||||
#define JTAG_DISABLE() do { \
|
||||
__asm__ __volatile__ ( \
|
||||
"in __tmp_reg__,__SREG__" "\n\t" \
|
||||
"cli" "\n\t" \
|
||||
"out %1, %0" "\n\t" \
|
||||
"out __SREG__, __tmp_reg__" "\n\t" \
|
||||
"out %1, %0" "\n\t" \
|
||||
: \
|
||||
: "r" (MCUCR | (1 << JTD)), \
|
||||
"M" (_SFR_IO_ADDR(MCUCR)) \
|
||||
: "r0"); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/** Defines a volatile \c NOP statement which cannot be optimized out by the compiler, and thus can always
|
||||
* be set as a breakpoint in the resulting code. Useful for debugging purposes, where the optimizer
|
||||
* removes/reorders code to the point where break points cannot reliably be set.
|
||||
*
|
||||
* \note This macro is not available for all architectures.
|
||||
*/
|
||||
#define JTAG_DEBUG_POINT() __asm__ __volatile__ ("nop" ::)
|
||||
|
||||
/** Defines an explicit JTAG break point in the resulting binary via the assembly \c BREAK statement. When
|
||||
* a JTAG is used, this causes the program execution to halt when reached until manually resumed.
|
||||
*
|
||||
* \note This macro is not available for all architectures.
|
||||
*/
|
||||
#define JTAG_DEBUG_BREAK() __asm__ __volatile__ ("break" ::)
|
||||
|
||||
/** Macro for testing condition "x" and breaking via \ref JTAG_DEBUG_BREAK() if the condition is false.
|
||||
*
|
||||
* \note This macro is not available for all architectures.
|
||||
*
|
||||
* \param[in] Condition Condition that will be evaluated.
|
||||
*/
|
||||
#define JTAG_ASSERT(Condition) do { \
|
||||
if (!(Condition)) \
|
||||
JTAG_DEBUG_BREAK(); \
|
||||
} while (0)
|
||||
|
||||
/** Macro for testing condition \c "x" and writing debug data to the stdout stream if \c false. The stdout stream
|
||||
* must be pre-initialized before this macro is run and linked to an output device, such as the microcontroller's
|
||||
* USART peripheral.
|
||||
*
|
||||
* The output takes the form "{FILENAME}: Function {FUNCTION NAME}, Line {LINE NUMBER}: Assertion {Condition} failed."
|
||||
*
|
||||
* \note This macro is not available for all architectures.
|
||||
*
|
||||
* \param[in] Condition Condition that will be evaluated,
|
||||
*/
|
||||
#define STDOUT_ASSERT(Condition) do { \
|
||||
if (!(Condition)) \
|
||||
printf_P(PSTR("%s: Function \"%s\", Line %d: " \
|
||||
"Assertion \"%s\" failed.\r\n"), \
|
||||
__FILE__, __func__, __LINE__, #Condition); \
|
||||
} while (0)
|
||||
|
||||
#if !defined(pgm_read_ptr) || defined(__DOXYGEN__)
|
||||
/** Reads a pointer out of PROGMEM space on the AVR8 architecture. This is a wrapper for the avr-libc
|
||||
* \c pgm_read_word() macro with a \c void* cast, so that its value can be assigned directly to a
|
||||
* pointer variable or used in pointer arithmetic without further casting in C.
|
||||
*
|
||||
* \note This macro is not available for all architectures.
|
||||
*
|
||||
* \param[in] Address Address of the pointer to read.
|
||||
*
|
||||
* \return Pointer retrieved from PROGMEM space.
|
||||
*/
|
||||
#define pgm_read_ptr(Address) (void*)pgm_read_word(Address)
|
||||
#endif
|
||||
#elif (ARCH == ARCH_UC3)
|
||||
#define JTAG_DEBUG_POINT() __asm__ __volatile__ ("nop" ::)
|
||||
#define JTAG_DEBUG_BREAK() __asm__ __volatile__ ("breakpoint" ::)
|
||||
#define JTAG_ASSERT(Condition) do { \
|
||||
if (!(Condition)) \
|
||||
JTAG_DEBUG_BREAK(); \
|
||||
} while (0)
|
||||
#define STDOUT_ASSERT(Condition) do { \
|
||||
if (!(Condition)) \
|
||||
printf("%s: Function \"%s\", Line %d: " \
|
||||
"Assertion \"%s\" failed.\r\n", \
|
||||
__FILE__, __func__, __LINE__, #Condition); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
84
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Architectures.h
Normal file
84
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Architectures.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Supported library architecture defines.
|
||||
*
|
||||
* \copydetails Group_Architectures
|
||||
*
|
||||
* \note Do not include this file directly, rather include the Common.h header file instead to gain this file's
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common
|
||||
* \defgroup Group_Architectures Hardware Architectures
|
||||
* \brief Supported library architecture defines.
|
||||
*
|
||||
* Architecture macros for selecting the desired target microcontroller architecture. One of these values should be
|
||||
* defined as the value of \c ARCH in the user project makefile via the \c -D compiler switch to GCC, to select the
|
||||
* target architecture.
|
||||
*
|
||||
* The selected architecture should remain consistent with the makefile \c ARCH value, which is used to select the
|
||||
* underlying driver source files for each architecture.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LUFA_ARCHITECTURES_H__
|
||||
#define __LUFA_ARCHITECTURES_H__
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_COMMON_H)
|
||||
#error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Selects the Atmel 8-bit AVR (AT90USB* and ATMEGA*U* chips) architecture. */
|
||||
#define ARCH_AVR8 0
|
||||
|
||||
/** Selects the Atmel 32-bit UC3 AVR (AT32UC3* chips) architecture. */
|
||||
#define ARCH_UC3 1
|
||||
|
||||
/** Selects the Atmel XMEGA AVR (ATXMEGA* chips) architecture. */
|
||||
#define ARCH_XMEGA 2
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
#define ARCH_ ARCH_AVR8
|
||||
|
||||
#if !defined(ARCH)
|
||||
#define ARCH ARCH_AVR8
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
150
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Attributes.h
Normal file
150
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Attributes.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Special function/variable attribute macros.
|
||||
*
|
||||
* \copydetails Group_FuncVarAttributes
|
||||
*
|
||||
* \note Do not include this file directly, rather include the Common.h header file instead to gain this file's
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common
|
||||
* \defgroup Group_FuncVarAttributes Function/Variable Attributes
|
||||
* \brief Special function/variable attribute macros.
|
||||
*
|
||||
* This module contains macros for applying specific attributes to functions and variables to control various
|
||||
* optimizer and code generation features of the compiler. Attributes may be placed in the function prototype
|
||||
* or variable declaration in any order, and multiple attributes can be specified for a single item via a space
|
||||
* separated list.
|
||||
*
|
||||
* On incompatible versions of GCC or on other compilers, these macros evaluate to nothing unless they are
|
||||
* critical to the code's function and thus must throw a compile error when used.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LUFA_ATTR_H__
|
||||
#define __LUFA_ATTR_H__
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_COMMON_H)
|
||||
#error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
#if (__GNUC__ >= 3) || defined(__DOXYGEN__)
|
||||
/** Indicates to the compiler that the function can not ever return, so that any stack restoring or
|
||||
* return code may be omitted by the compiler in the resulting binary.
|
||||
*/
|
||||
#define ATTR_NO_RETURN __attribute__ ((noreturn))
|
||||
|
||||
/** Indicates that the function returns a value which should not be ignored by the user code. When
|
||||
* applied, any ignored return value from calling the function will produce a compiler warning.
|
||||
*/
|
||||
#define ATTR_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
|
||||
|
||||
/** Indicates that the specified parameters of the function are pointers which should never be \c NULL.
|
||||
* When applied as a 1-based comma separated list the compiler will emit a warning if the specified
|
||||
* parameters are known at compiler time to be \c NULL at the point of calling the function.
|
||||
*/
|
||||
#define ATTR_NON_NULL_PTR_ARG(...) __attribute__ ((nonnull (__VA_ARGS__)))
|
||||
|
||||
/** Removes any preamble or postamble from the function. When used, the function will not have any
|
||||
* register or stack saving code. This should be used with caution, and when used the programmer
|
||||
* is responsible for maintaining stack and register integrity.
|
||||
*/
|
||||
#define ATTR_NAKED __attribute__ ((naked))
|
||||
|
||||
/** Prevents the compiler from considering a specified function for in-lining. When applied, the given
|
||||
* function will not be in-lined under any circumstances.
|
||||
*/
|
||||
#define ATTR_NO_INLINE __attribute__ ((noinline))
|
||||
|
||||
/** Forces the compiler to inline the specified function. When applied, the given function will be
|
||||
* in-lined under all circumstances.
|
||||
*/
|
||||
#define ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
|
||||
|
||||
/** Indicates that the specified function is pure, in that it has no side-effects other than global
|
||||
* or parameter variable access.
|
||||
*/
|
||||
#define ATTR_PURE __attribute__ ((pure))
|
||||
|
||||
/** Indicates that the specified function is constant, in that it has no side effects other than
|
||||
* parameter access.
|
||||
*/
|
||||
#define ATTR_CONST __attribute__ ((const))
|
||||
|
||||
/** Marks a given function as deprecated, which produces a warning if the function is called. */
|
||||
#define ATTR_DEPRECATED __attribute__ ((deprecated))
|
||||
|
||||
/** Marks a function as a weak reference, which can be overridden by other functions with an
|
||||
* identical name (in which case the weak reference is discarded at link time).
|
||||
*/
|
||||
#define ATTR_WEAK __attribute__ ((weak))
|
||||
#endif
|
||||
|
||||
/** Forces the compiler to not automatically zero the given global variable on startup, so that the
|
||||
* current RAM contents is retained. Under most conditions this value will be random due to the
|
||||
* behavior of volatile memory once power is removed, but may be used in some specific circumstances,
|
||||
* like the passing of values back after a system watchdog reset.
|
||||
*/
|
||||
#define ATTR_NO_INIT __attribute__ ((section (".noinit")))
|
||||
|
||||
/** Places the function in one of the initialization sections, which execute before the main function
|
||||
* of the application. Refer to the avr-libc manual for more information on the initialization sections.
|
||||
*
|
||||
* \param[in] SectionIndex Initialization section number where the function should be placed.
|
||||
*/
|
||||
#define ATTR_INIT_SECTION(SectionIndex) __attribute__ ((used, naked, section (".init" #SectionIndex )))
|
||||
|
||||
/** Marks a function as an alias for another function.
|
||||
*
|
||||
* \param[in] Func Name of the function which the given function name should alias.
|
||||
*/
|
||||
#define ATTR_ALIAS(Func) __attribute__ ((alias( #Func )))
|
||||
|
||||
/** Marks a variable or struct element for packing into the smallest space available, omitting any
|
||||
* alignment bytes usually added between fields to optimize field accesses.
|
||||
*/
|
||||
#define ATTR_PACKED __attribute__ ((packed))
|
||||
|
||||
/** Indicates the minimum alignment in bytes for a variable or struct element.
|
||||
*
|
||||
* \param[in] Bytes Minimum number of bytes the item should be aligned to.
|
||||
*/
|
||||
#define ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
260
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/BoardTypes.h
Normal file
260
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/BoardTypes.h
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Supported pre-made board hardware defines.
|
||||
*
|
||||
* \copydetails Group_BoardTypes
|
||||
*
|
||||
* \note Do not include this file directly, rather include the Common.h header file instead to gain this file's
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common
|
||||
* \defgroup Group_BoardTypes Board Types
|
||||
* \brief Supported pre-made board hardware defines.
|
||||
*
|
||||
* Board macros for indicating the chosen physical board hardware to the library. These macros should be used when
|
||||
* defining the \c BOARD token to the chosen hardware via the \c -D switch in the project makefile. If a custom
|
||||
* board is used, the \ref BOARD_NONE or \ref BOARD_USER values should be selected.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LUFA_BOARDTYPES_H__
|
||||
#define __LUFA_BOARDTYPES_H__
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_COMMON_H)
|
||||
#error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Selects the user-defined board drivers, which should be placed in the user project's folder
|
||||
* under a directory named \c /Board/. Each board driver should be named identically to the LUFA
|
||||
* master board driver (i.e., driver in the \c LUFA/Drivers/Board directory) so that the library
|
||||
* can correctly identify it.
|
||||
*/
|
||||
#define BOARD_USER 0
|
||||
|
||||
/** Disables board drivers when operation will not be adversely affected (e.g. LEDs) - use of board drivers
|
||||
* such as the Joystick driver, where the removal would adversely affect the code's operation is still disallowed. */
|
||||
#define BOARD_NONE 1
|
||||
|
||||
/** Selects the USBKEY specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */
|
||||
#define BOARD_USBKEY 2
|
||||
|
||||
/** Selects the STK525 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */
|
||||
#define BOARD_STK525 3
|
||||
|
||||
/** Selects the STK526 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */
|
||||
#define BOARD_STK526 4
|
||||
|
||||
/** Selects the RZUSBSTICK specific board drivers, including the driver for the boards LEDs. */
|
||||
#define BOARD_RZUSBSTICK 5
|
||||
|
||||
/** Selects the ATAVRUSBRF01 specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_ATAVRUSBRF01 6
|
||||
|
||||
/** Selects the BUMBLEB specific board drivers, using the officially recommended peripheral layout. */
|
||||
#define BOARD_BUMBLEB 7
|
||||
|
||||
/** Selects the XPLAIN (Revision 2 or newer) specific board drivers, including LED and Dataflash drivers. */
|
||||
#define BOARD_XPLAIN 8
|
||||
|
||||
/** Selects the XPLAIN (Revision 1) specific board drivers, including LED and Dataflash drivers. */
|
||||
#define BOARD_XPLAIN_REV1 9
|
||||
|
||||
/** Selects the EVK527 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */
|
||||
#define BOARD_EVK527 10
|
||||
|
||||
/** Selects the Teensy version 1.x specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_TEENSY 11
|
||||
|
||||
/** Selects the USBTINY MKII specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_USBTINYMKII 12
|
||||
|
||||
/** Selects the Benito specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_BENITO 13
|
||||
|
||||
/** Selects the JM-DB-U2 specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_JMDBU2 14
|
||||
|
||||
/** Selects the Olimex AVR-USB-162 specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_OLIMEX162 15
|
||||
|
||||
/** Selects the UDIP specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_UDIP 16
|
||||
|
||||
/** Selects the BUI specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_BUI 17
|
||||
|
||||
/** Selects the Arduino Uno specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_UNO 18
|
||||
|
||||
/** Selects the Busware CUL V3 specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_CULV3 19
|
||||
|
||||
/** Selects the Blackcat USB JTAG specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_BLACKCAT 20
|
||||
|
||||
/** Selects the Maximus specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_MAXIMUS 21
|
||||
|
||||
/** Selects the Minimus specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_MINIMUS 22
|
||||
|
||||
/** Selects the Adafruit U4 specific board drivers, including the Button driver. */
|
||||
#define BOARD_ADAFRUITU4 23
|
||||
|
||||
/** Selects the Microsin AVR-USB162 specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_MICROSIN162 24
|
||||
|
||||
/** Selects the Kernel Concepts USBFOO specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_USBFOO 25
|
||||
|
||||
/** Selects the Sparkfun ATMEGA8U2 specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_SPARKFUN8U2 26
|
||||
|
||||
/** Selects the Atmel EVK1101 specific board drivers, including the Button, Joystick and LED drivers. */
|
||||
#define BOARD_EVK1101 27
|
||||
|
||||
/** Selects the Busware TUL specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_TUL 28
|
||||
|
||||
/** Selects the Atmel EVK1100 specific board drivers, including the Button, Joystick and LED drivers. */
|
||||
#define BOARD_EVK1100 29
|
||||
|
||||
/** Selects the Atmel EVK1104 specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_EVK1104 30
|
||||
|
||||
/** Selects the Atmel XMEGA A3BU Xplained specific board drivers, including Dataflash, Button and LED drivers. */
|
||||
#define BOARD_A3BU_XPLAINED 31
|
||||
|
||||
/** Selects the Teensy version 2.x specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_TEENSY2 32
|
||||
|
||||
/** Selects the USB2AX version 1 and 2 specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_USB2AX 33
|
||||
|
||||
/** Selects the USB2AX version 3 specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_USB2AX_V3 34
|
||||
|
||||
/** Selects the Micropendous 32U2 specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_MICROPENDOUS_32U2 35
|
||||
|
||||
/** Selects the Micropendous A specific board drivers, including the driver for the board Button. */
|
||||
#define BOARD_MICROPENDOUS_A 36
|
||||
|
||||
/** Selects the Micropendous 1 specific board drivers, including the driver for the board Button. */
|
||||
#define BOARD_MICROPENDOUS_1 37
|
||||
|
||||
/** Selects the Micropendous 2 specific board drivers, including the driver for the board Button. */
|
||||
#define BOARD_MICROPENDOUS_2 38
|
||||
|
||||
/** Selects the Micropendous 3 specific board drivers, including the driver for the board Button. */
|
||||
#define BOARD_MICROPENDOUS_3 39
|
||||
|
||||
/** Selects the Micropendous 4 specific board drivers, including the driver for the board Button. */
|
||||
#define BOARD_MICROPENDOUS_4 40
|
||||
|
||||
/** Selects the Micropendous DIP specific board drivers, including the driver for the board Button. */
|
||||
#define BOARD_MICROPENDOUS_DIP 41
|
||||
|
||||
/** Selects the Micropendous (Arduino-like) revision 1 specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_MICROPENDOUS_REV1 42
|
||||
|
||||
/** Selects the Micropendous (Arduino-like) revision 2 specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_MICROPENDOUS_REV2 43
|
||||
|
||||
/** Selects the XMEGA B1 Xplained specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_B1_XPLAINED 44
|
||||
|
||||
/** Selects the Bitwizard Multio specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_MULTIO 45
|
||||
|
||||
/** Selects the Bitwizard Big-Multio specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_BIGMULTIO 46
|
||||
|
||||
/** Selects the DorkbotPDX Duce specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_DUCE 47
|
||||
|
||||
/** Selects the Olimex AVR-USB-32U4 specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_OLIMEX32U4 48
|
||||
|
||||
/** Selects the Olimex AVR-USB-T32U4 specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_OLIMEXT32U4 49
|
||||
|
||||
/** Selects the Olimex AVR-ISP-MK2 specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_OLIMEXISPMK2 50
|
||||
|
||||
/** Selects the Arduino Leonardo specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_LEONARDO 51
|
||||
|
||||
/** Selects the UC3-A3 Xplained specific board drivers, including the Button and LED drivers. */
|
||||
#define BOARD_UC3A3_XPLAINED 52
|
||||
|
||||
/** Selects the USB2AX version 3.1 specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_USB2AX_V31 53
|
||||
|
||||
/** Selects the Stange-ISP specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_STANGE_ISP 54
|
||||
|
||||
/** Selects the XMEGA C3 XPLAINED specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_C3_XPLAINED 55
|
||||
|
||||
/** Selects the U2S specific board drivers, including the Button and LEDs drivers. */
|
||||
#define BOARD_U2S 56
|
||||
|
||||
/** Selects the Arduino YUN specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_YUN 57
|
||||
|
||||
/** Selects the Arduino Micro specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_MICRO 58
|
||||
|
||||
/** Selects the Pololu A-Star Micro specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_POLOLUMICRO 59
|
||||
|
||||
/** Selects the Atmel Xplained-MINI specific board drivers, including the driver for the board LEDs. */
|
||||
#define BOARD_XPLAINED_MINI 60
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
#define BOARD_ BOARD_NONE
|
||||
|
||||
#if !defined(BOARD)
|
||||
#define BOARD BOARD_NONE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
393
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Common.h
Normal file
393
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Common.h
Normal file
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \dir
|
||||
* \brief Common library header files.
|
||||
*
|
||||
* This folder contains header files which are common to all parts of the LUFA library. They may be used freely in
|
||||
* user applications.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common library convenience headers, macros and functions.
|
||||
*
|
||||
* \copydetails Group_Common
|
||||
*/
|
||||
|
||||
/** \defgroup Group_Common Common Utility Headers - LUFA/Drivers/Common/Common.h
|
||||
* \brief Common library convenience headers, macros and functions.
|
||||
*
|
||||
* Common utility headers containing macros, functions, enums and types which are common to all
|
||||
* aspects of the library.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \defgroup Group_GlobalInt Global Interrupt Macros
|
||||
* \brief Convenience macros for the management of interrupts globally within the device.
|
||||
*
|
||||
* Macros and functions to create and control global interrupts within the device.
|
||||
*/
|
||||
|
||||
#ifndef __LUFA_COMMON_H__
|
||||
#define __LUFA_COMMON_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_COMMON_H
|
||||
|
||||
/* Includes: */
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "Architectures.h"
|
||||
#include "BoardTypes.h"
|
||||
#include "ArchitectureSpecific.h"
|
||||
#include "CompilerSpecific.h"
|
||||
#include "Attributes.h"
|
||||
|
||||
#if defined(USE_LUFA_CONFIG_HEADER)
|
||||
#include "LUFAConfig.h"
|
||||
#endif
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Architecture specific utility includes: */
|
||||
#if defined(__DOXYGEN__)
|
||||
/** Type define for an unsigned integer the same width as the selected architecture's machine register.
|
||||
* This is distinct from the non-specific standard int data type, whose width is machine dependant but
|
||||
* which may not reflect the actual machine register width on some targets (e.g. AVR8).
|
||||
*/
|
||||
typedef MACHINE_REG_t uint_reg_t;
|
||||
#elif (ARCH == ARCH_AVR8)
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/boot.h>
|
||||
#include <math.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
typedef uint8_t uint_reg_t;
|
||||
|
||||
#define ARCH_HAS_EEPROM_ADDRESS_SPACE
|
||||
#define ARCH_HAS_FLASH_ADDRESS_SPACE
|
||||
#define ARCH_HAS_MULTI_ADDRESS_SPACE
|
||||
#define ARCH_LITTLE_ENDIAN
|
||||
|
||||
#include "Endianness.h"
|
||||
#elif (ARCH == ARCH_UC3)
|
||||
#include <avr32/io.h>
|
||||
#include <math.h>
|
||||
|
||||
// === TODO: Find abstracted way to handle these ===
|
||||
#define PROGMEM
|
||||
#define pgm_read_byte(x) *x
|
||||
#define memcmp_P(...) memcmp(__VA_ARGS__)
|
||||
#define memcpy_P(...) memcpy(__VA_ARGS__)
|
||||
// =================================================
|
||||
|
||||
typedef uint32_t uint_reg_t;
|
||||
|
||||
#define ARCH_BIG_ENDIAN
|
||||
|
||||
#include "Endianness.h"
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <math.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
typedef uint8_t uint_reg_t;
|
||||
|
||||
#define ARCH_HAS_EEPROM_ADDRESS_SPACE
|
||||
#define ARCH_HAS_FLASH_ADDRESS_SPACE
|
||||
#define ARCH_HAS_MULTI_ADDRESS_SPACE
|
||||
#define ARCH_LITTLE_ENDIAN
|
||||
|
||||
#include "Endianness.h"
|
||||
#else
|
||||
#error Unknown device architecture specified.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
// Obsolete, retained for compatibility with user code
|
||||
#define MACROS do
|
||||
#define MACROE while (0)
|
||||
#endif
|
||||
|
||||
/** Convenience macro to determine the larger of two values.
|
||||
*
|
||||
* \attention This macro should only be used with operands that do not have side effects from being evaluated
|
||||
* multiple times.
|
||||
*
|
||||
* \param[in] x First value to compare
|
||||
* \param[in] y First value to compare
|
||||
*
|
||||
* \return The larger of the two input parameters
|
||||
*/
|
||||
#if !defined(MAX) || defined(__DOXYGEN__)
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
/** Convenience macro to determine the smaller of two values.
|
||||
*
|
||||
* \attention This macro should only be used with operands that do not have side effects from being evaluated
|
||||
* multiple times.
|
||||
*
|
||||
* \param[in] x First value to compare.
|
||||
* \param[in] y First value to compare.
|
||||
*
|
||||
* \return The smaller of the two input parameters
|
||||
*/
|
||||
#if !defined(MIN) || defined(__DOXYGEN__)
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#if !defined(STRINGIFY) || defined(__DOXYGEN__)
|
||||
/** Converts the given input into a string, via the C Preprocessor. This macro puts literal quotation
|
||||
* marks around the input, converting the source into a string literal.
|
||||
*
|
||||
* \param[in] x Input to convert into a string literal.
|
||||
*
|
||||
* \return String version of the input.
|
||||
*/
|
||||
#define STRINGIFY(x) #x
|
||||
|
||||
/** Converts the given input into a string after macro expansion, via the C Preprocessor. This macro puts
|
||||
* literal quotation marks around the expanded input, converting the source into a string literal.
|
||||
*
|
||||
* \param[in] x Input to expand and convert into a string literal.
|
||||
*
|
||||
* \return String version of the expanded input.
|
||||
*/
|
||||
#define STRINGIFY_EXPANDED(x) STRINGIFY(x)
|
||||
#endif
|
||||
|
||||
#if !defined(CONCAT) || defined(__DOXYGEN__)
|
||||
/** Concatenates the given input into a single token, via the C Preprocessor.
|
||||
*
|
||||
* \param[in] x First item to concatenate.
|
||||
* \param[in] y Second item to concatenate.
|
||||
*
|
||||
* \return Concatenated version of the input.
|
||||
*/
|
||||
#define CONCAT(x, y) x ## y
|
||||
|
||||
/** CConcatenates the given input into a single token after macro expansion, via the C Preprocessor.
|
||||
*
|
||||
* \param[in] x First item to concatenate.
|
||||
* \param[in] y Second item to concatenate.
|
||||
*
|
||||
* \return Concatenated version of the expanded input.
|
||||
*/
|
||||
#define CONCAT_EXPANDED(x, y) CONCAT(x, y)
|
||||
#endif
|
||||
|
||||
#if !defined(ISR) || defined(__DOXYGEN__)
|
||||
/** Macro for the definition of interrupt service routines, so that the compiler can insert the required
|
||||
* prologue and epilogue code to properly manage the interrupt routine without affecting the main thread's
|
||||
* state with unintentional side-effects.
|
||||
*
|
||||
* Interrupt handlers written using this macro may still need to be registered with the microcontroller's
|
||||
* Interrupt Controller (if present) before they will properly handle incoming interrupt events.
|
||||
*
|
||||
* \note This macro is only supplied on some architectures, where the standard library does not include a valid
|
||||
* definition. If an existing definition exists, the alternative definition here will be ignored.
|
||||
*
|
||||
* \ingroup Group_GlobalInt
|
||||
*
|
||||
* \param[in] Name Unique name of the interrupt service routine.
|
||||
*/
|
||||
#define ISR(Name, ...) void Name (void) __attribute__((__interrupt__)) __VA_ARGS__; void Name (void)
|
||||
#endif
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Function to reverse the individual bits in a byte - i.e. bit 7 is moved to bit 0, bit 6 to bit 1,
|
||||
* etc.
|
||||
*
|
||||
* \param[in] Byte Byte of data whose bits are to be reversed.
|
||||
*
|
||||
* \return Input data with the individual bits reversed (mirrored).
|
||||
*/
|
||||
static inline uint8_t BitReverse(uint8_t Byte) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
|
||||
static inline uint8_t BitReverse(uint8_t Byte)
|
||||
{
|
||||
Byte = (((Byte & 0xF0) >> 4) | ((Byte & 0x0F) << 4));
|
||||
Byte = (((Byte & 0xCC) >> 2) | ((Byte & 0x33) << 2));
|
||||
Byte = (((Byte & 0xAA) >> 1) | ((Byte & 0x55) << 1));
|
||||
|
||||
return Byte;
|
||||
}
|
||||
|
||||
/** Function to perform a blocking delay for a specified number of milliseconds. The actual delay will be
|
||||
* at a minimum the specified number of milliseconds, however due to loop overhead and internal calculations
|
||||
* may be slightly higher.
|
||||
*
|
||||
* \param[in] Milliseconds Number of milliseconds to delay
|
||||
*/
|
||||
static inline void Delay_MS(uint16_t Milliseconds) ATTR_ALWAYS_INLINE;
|
||||
static inline void Delay_MS(uint16_t Milliseconds)
|
||||
{
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
if (GCC_IS_COMPILE_CONST(Milliseconds))
|
||||
{
|
||||
_delay_ms(Milliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (Milliseconds--)
|
||||
_delay_ms(1);
|
||||
}
|
||||
#elif (ARCH == ARCH_UC3)
|
||||
while (Milliseconds--)
|
||||
{
|
||||
__builtin_mtsr(AVR32_COUNT, 0);
|
||||
while ((uint32_t)__builtin_mfsr(AVR32_COUNT) < (F_CPU / 1000));
|
||||
}
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
if (GCC_IS_COMPILE_CONST(Milliseconds))
|
||||
{
|
||||
_delay_ms(Milliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (Milliseconds--)
|
||||
_delay_ms(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Retrieves a mask which contains the current state of the global interrupts for the device. This
|
||||
* value can be stored before altering the global interrupt enable state, before restoring the
|
||||
* flag(s) back to their previous values after a critical section using \ref SetGlobalInterruptMask().
|
||||
*
|
||||
* \ingroup Group_GlobalInt
|
||||
*
|
||||
* \return Mask containing the current Global Interrupt Enable Mask bit(s).
|
||||
*/
|
||||
static inline uint_reg_t GetGlobalInterruptMask(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint_reg_t GetGlobalInterruptMask(void)
|
||||
{
|
||||
GCC_MEMORY_BARRIER();
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
return SREG;
|
||||
#elif (ARCH == ARCH_UC3)
|
||||
return __builtin_mfsr(AVR32_SR);
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
return SREG;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Sets the global interrupt enable state of the microcontroller to the mask passed into the function.
|
||||
* This can be combined with \ref GetGlobalInterruptMask() to save and restore the Global Interrupt Enable
|
||||
* Mask bit(s) of the device after a critical section has completed.
|
||||
*
|
||||
* \ingroup Group_GlobalInt
|
||||
*
|
||||
* \param[in] GlobalIntState Global Interrupt Enable Mask value to use
|
||||
*/
|
||||
static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState) ATTR_ALWAYS_INLINE;
|
||||
static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState)
|
||||
{
|
||||
GCC_MEMORY_BARRIER();
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
SREG = GlobalIntState;
|
||||
#elif (ARCH == ARCH_UC3)
|
||||
if (GlobalIntState & AVR32_SR_GM)
|
||||
__builtin_ssrf(AVR32_SR_GM_OFFSET);
|
||||
else
|
||||
__builtin_csrf(AVR32_SR_GM_OFFSET);
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
SREG = GlobalIntState;
|
||||
#endif
|
||||
|
||||
GCC_MEMORY_BARRIER();
|
||||
}
|
||||
|
||||
/** Enables global interrupt handling for the device, allowing interrupts to be handled.
|
||||
*
|
||||
* \ingroup Group_GlobalInt
|
||||
*/
|
||||
static inline void GlobalInterruptEnable(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void GlobalInterruptEnable(void)
|
||||
{
|
||||
GCC_MEMORY_BARRIER();
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
sei();
|
||||
#elif (ARCH == ARCH_UC3)
|
||||
__builtin_csrf(AVR32_SR_GM_OFFSET);
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
sei();
|
||||
#endif
|
||||
|
||||
GCC_MEMORY_BARRIER();
|
||||
}
|
||||
|
||||
/** Disabled global interrupt handling for the device, preventing interrupts from being handled.
|
||||
*
|
||||
* \ingroup Group_GlobalInt
|
||||
*/
|
||||
static inline void GlobalInterruptDisable(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void GlobalInterruptDisable(void)
|
||||
{
|
||||
GCC_MEMORY_BARRIER();
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
cli();
|
||||
#elif (ARCH == ARCH_UC3)
|
||||
__builtin_ssrf(AVR32_SR_GM_OFFSET);
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
cli();
|
||||
#endif
|
||||
|
||||
GCC_MEMORY_BARRIER();
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
97
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/CompilerSpecific.h
Normal file
97
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/CompilerSpecific.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Compiler specific definitions for code optimization and correctness.
|
||||
*
|
||||
* \copydetails Group_CompilerSpecific
|
||||
*
|
||||
* \note Do not include this file directly, rather include the Common.h header file instead to gain this file's
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common
|
||||
* \defgroup Group_CompilerSpecific Compiler Specific Definitions
|
||||
* \brief Compiler specific definitions for code optimization and correctness.
|
||||
*
|
||||
* Compiler specific definitions to expose certain compiler features which may increase the level of code optimization
|
||||
* for a specific compiler, or correct certain issues that may be present such as memory barriers for use in conjunction
|
||||
* with atomic variable access.
|
||||
*
|
||||
* Where possible, on alternative compilers, these macros will either have no effect, or default to returning a sane value
|
||||
* so that they can be used in existing code without the need for extra compiler checks in the user application code.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LUFA_COMPILERSPEC_H__
|
||||
#define __LUFA_COMPILERSPEC_H__
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_COMMON_H)
|
||||
#error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
#if defined(__GNUC__) || defined(__DOXYGEN__)
|
||||
/** Forces GCC to use pointer indirection (via the device's pointer register pairs) when accessing the given
|
||||
* struct pointer. In some cases GCC will emit non-optimal assembly code when accessing a structure through
|
||||
* a pointer, resulting in a larger binary. When this macro is used on a (non \c const) structure pointer before
|
||||
* use, it will force GCC to use pointer indirection on the elements rather than direct store and load
|
||||
* instructions.
|
||||
*
|
||||
* \param[in, out] StructPtr Pointer to a structure which is to be forced into indirect access mode.
|
||||
*/
|
||||
#define GCC_FORCE_POINTER_ACCESS(StructPtr) __asm__ __volatile__("" : "=b" (StructPtr) : "0" (StructPtr))
|
||||
|
||||
/** Forces GCC to create a memory barrier, ensuring that memory accesses are not reordered past the barrier point.
|
||||
* This can be used before ordering-critical operations, to ensure that the compiler does not re-order the resulting
|
||||
* assembly output in an unexpected manner on sections of code that are ordering-specific.
|
||||
*/
|
||||
#define GCC_MEMORY_BARRIER() __asm__ __volatile__("" ::: "memory");
|
||||
|
||||
/** Determines if the specified value can be determined at compile-time to be a constant value when compiling under GCC.
|
||||
*
|
||||
* \param[in] x Value to check compile-time constantness of.
|
||||
*
|
||||
* \return Boolean \c true if the given value is known to be a compile time constant, \c false otherwise.
|
||||
*/
|
||||
#define GCC_IS_COMPILE_CONST(x) __builtin_constant_p(x)
|
||||
#else
|
||||
#define GCC_FORCE_POINTER_ACCESS(StructPtr)
|
||||
#define GCC_MEMORY_BARRIER()
|
||||
#define GCC_IS_COMPILE_CONST(x) 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
493
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Endianness.h
Normal file
493
H2003-V1_USB_PWM/src/LUFA/LUFA/Common/Endianness.h
Normal file
@@ -0,0 +1,493 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Endianness and Byte Ordering macros and functions.
|
||||
*
|
||||
* \copydetails Group_Endianness
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Endianness
|
||||
* \defgroup Group_ByteSwapping Byte Reordering
|
||||
* \brief Macros and functions for forced byte reordering.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Endianness
|
||||
* \defgroup Group_EndianConversion Endianness Conversion
|
||||
* \brief Macros and functions for automatic endianness conversion.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common
|
||||
* \defgroup Group_Endianness Endianness and Byte Ordering
|
||||
* \brief Convenience macros and functions relating to byte (re-)ordering
|
||||
*
|
||||
* Common library convenience macros and functions relating to byte (re-)ordering.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LUFA_ENDIANNESS_H__
|
||||
#define __LUFA_ENDIANNESS_H__
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_COMMON_H)
|
||||
#error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
|
||||
#endif
|
||||
|
||||
#if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN))
|
||||
#error ARCH_BIG_ENDIAN or ARCH_LITTLE_ENDIAN not set for the specified architecture.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Swaps the byte ordering of a 16-bit value at compile-time. Do not use this macro for swapping byte orderings
|
||||
* of dynamic values computed at runtime, use \ref SwapEndian_16() instead. The result of this macro can be used
|
||||
* inside struct or other variable initializers outside of a function, something that is not possible with the
|
||||
* inline function variant.
|
||||
*
|
||||
* \hideinitializer
|
||||
*
|
||||
* \ingroup Group_ByteSwapping
|
||||
*
|
||||
* \param[in] x 16-bit value whose byte ordering is to be swapped.
|
||||
*
|
||||
* \return Input value with the byte ordering reversed.
|
||||
*/
|
||||
#define SWAPENDIAN_16(x) (uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
|
||||
|
||||
/** Swaps the byte ordering of a 32-bit value at compile-time. Do not use this macro for swapping byte orderings
|
||||
* of dynamic values computed at runtime- use \ref SwapEndian_32() instead. The result of this macro can be used
|
||||
* inside struct or other variable initializers outside of a function, something that is not possible with the
|
||||
* inline function variant.
|
||||
*
|
||||
* \hideinitializer
|
||||
*
|
||||
* \ingroup Group_ByteSwapping
|
||||
*
|
||||
* \param[in] x 32-bit value whose byte ordering is to be swapped.
|
||||
*
|
||||
* \return Input value with the byte ordering reversed.
|
||||
*/
|
||||
#define SWAPENDIAN_32(x) (uint32_t)((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \
|
||||
(((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL))
|
||||
|
||||
#if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu)
|
||||
#define le16_to_cpu(x) SwapEndian_16(x)
|
||||
#define le32_to_cpu(x) SwapEndian_32(x)
|
||||
#define be16_to_cpu(x) (x)
|
||||
#define be32_to_cpu(x) (x)
|
||||
#define cpu_to_le16(x) SwapEndian_16(x)
|
||||
#define cpu_to_le32(x) SwapEndian_32(x)
|
||||
#define cpu_to_be16(x) (x)
|
||||
#define cpu_to_be32(x) (x)
|
||||
#define LE16_TO_CPU(x) SWAPENDIAN_16(x)
|
||||
#define LE32_TO_CPU(x) SWAPENDIAN_32(x)
|
||||
#define BE16_TO_CPU(x) (x)
|
||||
#define BE32_TO_CPU(x) (x)
|
||||
#define CPU_TO_LE16(x) SWAPENDIAN_16(x)
|
||||
#define CPU_TO_LE32(x) SWAPENDIAN_32(x)
|
||||
#define CPU_TO_BE16(x) (x)
|
||||
#define CPU_TO_BE32(x) (x)
|
||||
#elif !defined(le16_to_cpu)
|
||||
/** \name Run-time endianness conversion */
|
||||
//@{
|
||||
|
||||
/** Performs a conversion between a Little Endian encoded 16-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref LE16_TO_CPU instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define le16_to_cpu(x) (x)
|
||||
|
||||
/** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref LE32_TO_CPU instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define le32_to_cpu(x) (x)
|
||||
|
||||
/** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref BE16_TO_CPU instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define be16_to_cpu(x) SwapEndian_16(x)
|
||||
|
||||
/** Performs a conversion between a Big Endian encoded 32-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref BE32_TO_CPU instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define be32_to_cpu(x) SwapEndian_32(x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
|
||||
* is in Little Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref CPU_TO_LE16 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define cpu_to_le16(x) (x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
|
||||
* is in Little Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref CPU_TO_LE32 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define cpu_to_le32(x) (x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
|
||||
* is in Big Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref CPU_TO_BE16 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define cpu_to_be16(x) SwapEndian_16(x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
|
||||
* is in Big Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for run-time conversion of data - for compile-time endianness
|
||||
* conversion, use \ref CPU_TO_BE32 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define cpu_to_be32(x) SwapEndian_32(x)
|
||||
|
||||
//@}
|
||||
|
||||
/** \name Compile-time endianness conversion */
|
||||
//@{
|
||||
|
||||
/** Performs a conversion between a Little Endian encoded 16-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run time endianness
|
||||
* conversion, use \ref le16_to_cpu instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define LE16_TO_CPU(x) (x)
|
||||
|
||||
/** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run time endianness
|
||||
* conversion, use \ref le32_to_cpu instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define LE32_TO_CPU(x) (x)
|
||||
|
||||
/** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run-time endianness
|
||||
* conversion, use \ref be16_to_cpu instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define BE16_TO_CPU(x) SWAPENDIAN_16(x)
|
||||
|
||||
/** Performs a conversion between a Big Endian encoded 32-bit piece of data and the
|
||||
* Endianness of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run-time endianness
|
||||
* conversion, use \ref be32_to_cpu instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define BE32_TO_CPU(x) SWAPENDIAN_32(x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
|
||||
* is in Little Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run-time endianness
|
||||
* conversion, use \ref cpu_to_le16 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define CPU_TO_LE16(x) (x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
|
||||
* is in Little Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On little endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run-time endianness
|
||||
* conversion, use \ref cpu_to_le32 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define CPU_TO_LE32(x) (x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
|
||||
* is in Big Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run-time endianness
|
||||
* conversion, use \ref cpu_to_be16 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define CPU_TO_BE16(x) SWAPENDIAN_16(x)
|
||||
|
||||
/** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
|
||||
* is in Big Endian format regardless of the currently selected CPU architecture.
|
||||
*
|
||||
* On big endian architectures, this macro does nothing.
|
||||
*
|
||||
* \note This macro is designed for compile-time conversion of data - for run-time endianness
|
||||
* conversion, use \ref cpu_to_be32 instead.
|
||||
*
|
||||
* \ingroup Group_EndianConversion
|
||||
*
|
||||
* \param[in] x Data to perform the endianness conversion on.
|
||||
*
|
||||
* \return Endian corrected version of the input value.
|
||||
*/
|
||||
#define CPU_TO_BE32(x) SWAPENDIAN_32(x)
|
||||
|
||||
//! @}
|
||||
#endif
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Function to reverse the byte ordering of the individual bytes in a 16 bit value.
|
||||
*
|
||||
* \ingroup Group_ByteSwapping
|
||||
*
|
||||
* \param[in] Word Word of data whose bytes are to be swapped.
|
||||
*
|
||||
* \return Input data with the individual bytes reversed.
|
||||
*/
|
||||
static inline uint16_t SwapEndian_16(const uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYS_INLINE;
|
||||
static inline uint16_t SwapEndian_16(const uint16_t Word)
|
||||
{
|
||||
if (GCC_IS_COMPILE_CONST(Word))
|
||||
return SWAPENDIAN_16(Word);
|
||||
|
||||
uint8_t Temp;
|
||||
|
||||
union
|
||||
{
|
||||
uint16_t Word;
|
||||
uint8_t Bytes[2];
|
||||
} Data;
|
||||
|
||||
Data.Word = Word;
|
||||
|
||||
Temp = Data.Bytes[0];
|
||||
Data.Bytes[0] = Data.Bytes[1];
|
||||
Data.Bytes[1] = Temp;
|
||||
|
||||
return Data.Word;
|
||||
}
|
||||
|
||||
/** Function to reverse the byte ordering of the individual bytes in a 32 bit value.
|
||||
*
|
||||
* \ingroup Group_ByteSwapping
|
||||
*
|
||||
* \param[in] DWord Double word of data whose bytes are to be swapped.
|
||||
*
|
||||
* \return Input data with the individual bytes reversed.
|
||||
*/
|
||||
static inline uint32_t SwapEndian_32(const uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYS_INLINE;
|
||||
static inline uint32_t SwapEndian_32(const uint32_t DWord)
|
||||
{
|
||||
if (GCC_IS_COMPILE_CONST(DWord))
|
||||
return SWAPENDIAN_32(DWord);
|
||||
|
||||
uint8_t Temp;
|
||||
|
||||
union
|
||||
{
|
||||
uint32_t DWord;
|
||||
uint8_t Bytes[4];
|
||||
} Data;
|
||||
|
||||
Data.DWord = DWord;
|
||||
|
||||
Temp = Data.Bytes[0];
|
||||
Data.Bytes[0] = Data.Bytes[3];
|
||||
Data.Bytes[3] = Temp;
|
||||
|
||||
Temp = Data.Bytes[1];
|
||||
Data.Bytes[1] = Data.Bytes[2];
|
||||
Data.Bytes[2] = Temp;
|
||||
|
||||
return Data.DWord;
|
||||
}
|
||||
|
||||
/** Function to reverse the byte ordering of the individual bytes in a n byte value.
|
||||
*
|
||||
* \ingroup Group_ByteSwapping
|
||||
*
|
||||
* \param[in,out] Data Pointer to a number containing an even number of bytes to be reversed.
|
||||
* \param[in] Length Length of the data in bytes.
|
||||
*
|
||||
* \return Input data with the individual bytes reversed.
|
||||
*/
|
||||
static inline void SwapEndian_n(void* const Data,
|
||||
uint8_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline void SwapEndian_n(void* const Data,
|
||||
uint8_t Length)
|
||||
{
|
||||
uint8_t* CurrDataPos = (uint8_t*)Data;
|
||||
|
||||
while (Length > 1)
|
||||
{
|
||||
uint8_t Temp = *CurrDataPos;
|
||||
*CurrDataPos = *(CurrDataPos + Length - 1);
|
||||
*(CurrDataPos + Length - 1) = Temp;
|
||||
|
||||
CurrDataPos++;
|
||||
Length -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
171
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Board/Board.h
Normal file
171
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Board/Board.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Board hardware information driver.
|
||||
*
|
||||
* This file is the master dispatch header file for the board-specific information driver, to give information
|
||||
* on the hardware contained on a specific board.
|
||||
*
|
||||
* User code should include this file, which will in turn include the correct board driver header file for the
|
||||
* currently selected board.
|
||||
*
|
||||
* If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/Board.h file in the user project
|
||||
* directory.
|
||||
*
|
||||
* For possible \c BOARD makefile values, see \ref Group_BoardTypes.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_BoardDrivers
|
||||
* \defgroup Group_BoardInfo Board Information Driver - LUFA/Drivers/Board/Board.h
|
||||
* \brief Board hardware information driver.
|
||||
*
|
||||
* \section Sec_BoardInfo_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - None
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __BOARD_H__
|
||||
#define __BOARD_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_BOARD_H
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
#if (BOARD == BOARD_USBKEY)
|
||||
#include "AVR8/USBKEY/Board.h"
|
||||
#elif (BOARD == BOARD_STK525)
|
||||
#include "AVR8/STK525/Board.h"
|
||||
#elif (BOARD == BOARD_STK526)
|
||||
#include "AVR8/STK526/Board.h"
|
||||
#elif (BOARD == BOARD_RZUSBSTICK)
|
||||
#include "AVR8/RZUSBSTICK/Board.h"
|
||||
#elif (BOARD == BOARD_ATAVRUSBRF01)
|
||||
#include "AVR8/ATAVRUSBRF01/Board.h"
|
||||
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
|
||||
#include "AVR8/XPLAIN/Board.h"
|
||||
#elif (BOARD == BOARD_BUMBLEB)
|
||||
#include "AVR8/BUMBLEB/Board.h"
|
||||
#elif (BOARD == BOARD_EVK527)
|
||||
#include "AVR8/EVK527/Board.h"
|
||||
#elif ((BOARD == BOARD_TEENSY) || (BOARD == BOARD_TEENSY2))
|
||||
#include "AVR8/TEENSY/Board.h"
|
||||
#elif (BOARD == BOARD_USBTINYMKII)
|
||||
#include "AVR8/USBTINYMKII/Board.h"
|
||||
#elif (BOARD == BOARD_BENITO)
|
||||
#include "AVR8/BENITO/Board.h"
|
||||
#elif (BOARD == BOARD_JMDBU2)
|
||||
#include "AVR8/JMDBU2/Board.h"
|
||||
#elif (BOARD == BOARD_OLIMEX162)
|
||||
#include "AVR8/OLIMEX162/Board.h"
|
||||
#elif (BOARD == BOARD_USBFOO)
|
||||
#include "AVR8/USBFOO/Board.h"
|
||||
#elif (BOARD == BOARD_UDIP)
|
||||
#include "AVR8/UDIP/Board.h"
|
||||
#elif (BOARD == BOARD_BUI)
|
||||
#include "AVR8/BUI/Board.h"
|
||||
#elif (BOARD == BOARD_UNO)
|
||||
#include "AVR8/UNO/Board.h"
|
||||
#elif (BOARD == BOARD_CULV3)
|
||||
#include "AVR8/CULV3/Board.h"
|
||||
#elif (BOARD == BOARD_BLACKCAT)
|
||||
#include "AVR8/BLACKCAT/Board.h"
|
||||
#elif (BOARD == BOARD_MAXIMUS)
|
||||
#include "AVR8/MAXIMUS/Board.h"
|
||||
#elif (BOARD == BOARD_MINIMUS)
|
||||
#include "AVR8/MINIMUS/Board.h"
|
||||
#elif (BOARD == BOARD_ADAFRUITU4)
|
||||
#include "AVR8/ADAFRUITU4/Board.h"
|
||||
#elif (BOARD == BOARD_MICROSIN162)
|
||||
#include "AVR8/MICROSIN162/Board.h"
|
||||
#elif (BOARD == BOARD_SPARKFUN8U2)
|
||||
#include "AVR8/SPARKFUN8U2/Board.h"
|
||||
#elif (BOARD == BOARD_EVK1101)
|
||||
#include "UC3/EVK1101/Board.h"
|
||||
#elif (BOARD == BOARD_TUL)
|
||||
#include "AVR8/TUL/Board.h"
|
||||
#elif (BOARD == BOARD_EVK1100)
|
||||
#include "UC3/EVK1100/Board.h"
|
||||
#elif (BOARD == BOARD_EVK1104)
|
||||
#include "UC3/EVK1104/Board.h"
|
||||
#elif (BOARD == BOARD_A3BU_XPLAINED)
|
||||
#include "XMEGA/A3BU_XPLAINED/Board.h"
|
||||
#elif ((BOARD == BOARD_USB2AX) || (BOARD == BOARD_USB2AX_V3) || (BOARD == BOARD_USB2AX_V31))
|
||||
#include "AVR8/USB2AX/Board.h"
|
||||
#elif ((BOARD == BOARD_MICROPENDOUS_REV1) || (BOARD == BOARD_MICROPENDOUS_REV2) || \
|
||||
(BOARD == BOARD_MICROPENDOUS_32U2) || (BOARD == BOARD_MICROPENDOUS_A) || \
|
||||
(BOARD == BOARD_MICROPENDOUS_1) || (BOARD == BOARD_MICROPENDOUS_2) || \
|
||||
(BOARD == BOARD_MICROPENDOUS_3) || (BOARD == BOARD_MICROPENDOUS_4) || \
|
||||
(BOARD == BOARD_MICROPENDOUS_DIP))
|
||||
#include "AVR8/MICROPENDOUS/Board.h"
|
||||
#elif (BOARD == BOARD_B1_XPLAINED)
|
||||
#include "XMEGA/B1_XPLAINED/Board.h"
|
||||
#elif (BOARD == BOARD_MULTIO)
|
||||
#include "AVR8/MULTIO/Board.h"
|
||||
#elif (BOARD == BOARD_BIGMULTIO)
|
||||
#include "AVR8/BIGMULTIO/Board.h"
|
||||
#elif (BOARD == BOARD_DUCE)
|
||||
#include "AVR8/DUCE/Board.h"
|
||||
#elif (BOARD == BOARD_OLIMEX32U4)
|
||||
#include "AVR8/OLIMEX32U4/Board.h"
|
||||
#elif (BOARD == BOARD_OLIMEXT32U4)
|
||||
#include "AVR8/OLIMEXT32U4/Board.h"
|
||||
#elif (BOARD == BOARD_OLIMEXISPMK2)
|
||||
#include "AVR8/OLIMEXISPMK2/Board.h"
|
||||
#elif (BOARD == BOARD_LEONARDO)
|
||||
#include "AVR8/LEONARDO/Board.h"
|
||||
#elif (BOARD == BOARD_UC3A3_XPLAINED)
|
||||
#include "UC3/UC3A3_XPLAINED/Board.h"
|
||||
#elif (BOARD == BOARD_STANGE_ISP)
|
||||
#include "AVR8/STANGE_ISP/Board.h"
|
||||
#elif (BOARD == BOARD_C3_XPLAINED)
|
||||
#include "XMEGA/C3_XPLAINED/Board.h"
|
||||
#elif (BOARD == BOARD_U2S)
|
||||
#include "AVR8/U2S/Board.h"
|
||||
#elif (BOARD == BOARD_YUN)
|
||||
#include "AVR8/YUN/Board.h"
|
||||
#elif (BOARD == BOARD_MICRO)
|
||||
#include "AVR8/MICRO/Board.h"
|
||||
#elif (BOARD == BOARD_POLOLUMICRO)
|
||||
#include "AVR8/POLOLUMICRO/Board.h"
|
||||
#elif (BOARD == BOARD_XPLAINED_MINI)
|
||||
#include "AVR8/XPLAINED_MINI/Board.h"
|
||||
#else
|
||||
#include "Board/Board.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
302
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Board/LEDs.h
Normal file
302
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Board/LEDs.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LED board hardware driver.
|
||||
*
|
||||
* This file is the master dispatch header file for the board-specific LED driver, for boards containing user
|
||||
* controllable LEDs.
|
||||
*
|
||||
* User code should include this file, which will in turn include the correct LED driver header file for the
|
||||
* currently selected board.
|
||||
*
|
||||
* If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/LEDs.h file in the user project
|
||||
* directory.
|
||||
*
|
||||
* For possible \c BOARD makefile values, see \ref Group_BoardTypes.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_BoardDrivers
|
||||
* \defgroup Group_LEDs LEDs Driver - LUFA/Drivers/Board/LEDs.h
|
||||
* \brief LED board hardware driver.
|
||||
*
|
||||
* \section Sec_LEDs_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - None
|
||||
*
|
||||
* \section Sec_LEDs_ModDescription Module Description
|
||||
* Hardware LEDs driver. This provides an easy to use driver for the hardware LEDs present on many boards. It
|
||||
* provides an interface to configure, test and change the status of all the board LEDs.
|
||||
*
|
||||
* If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/LEDs.h file in the user project
|
||||
* directory. Otherwise, it will include the appropriate built-in board driver header file. If the BOARD value
|
||||
* is set to \c BOARD_NONE, this driver is silently disabled.
|
||||
*
|
||||
* For possible \c BOARD makefile values, see \ref Group_BoardTypes.
|
||||
*
|
||||
* \note To make code as compatible as possible, it is assumed that all boards carry a minimum of four LEDs. If
|
||||
* a board contains less than four LEDs, the remaining LED masks are defined to 0 so as to have no effect.
|
||||
* If other behavior is desired, either alias the remaining LED masks to existing LED masks via the -D
|
||||
* switch in the project makefile, or alias them to nothing in the makefile to cause compilation errors when
|
||||
* a non-existing LED is referenced in application code. Note that this means that it is possible to make
|
||||
* compatible code for a board with no LEDs by making a board LED driver (see \ref Page_WritingBoardDrivers)
|
||||
* which contains only stub functions and defines no LEDs.
|
||||
*
|
||||
* \section Sec_LEDs_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* \code
|
||||
* // Initialize the board LED driver before first use
|
||||
* LEDs_Init();
|
||||
*
|
||||
* // Turn on each of the four LEDs in turn
|
||||
* LEDs_SetAllLEDs(LEDS_LED1);
|
||||
* Delay_MS(500);
|
||||
* LEDs_SetAllLEDs(LEDS_LED2);
|
||||
* Delay_MS(500);
|
||||
* LEDs_SetAllLEDs(LEDS_LED3);
|
||||
* Delay_MS(500);
|
||||
* LEDs_SetAllLEDs(LEDS_LED4);
|
||||
* Delay_MS(500);
|
||||
*
|
||||
* // Turn on all LEDs
|
||||
* LEDs_SetAllLEDs(LEDS_ALL_LEDS);
|
||||
* Delay_MS(1000);
|
||||
*
|
||||
* // Turn on LED 1, turn off LED 2, leaving LEDs 3 and 4 in their current state
|
||||
* LEDs_ChangeLEDs((LEDS_LED1 | LEDS_LED2), LEDS_LED1);
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LEDS_H__
|
||||
#define __LEDS_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_LEDS_H
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
#if (BOARD == BOARD_NONE)
|
||||
static inline void LEDs_Init(void) {}
|
||||
static inline void LEDs_Disable(void) {}
|
||||
static inline void LEDs_TurnOnLEDs(const uint_reg_t LEDMask) {}
|
||||
static inline void LEDs_TurnOffLEDs(const uint_reg_t LEDMask) {}
|
||||
static inline void LEDs_SetAllLEDs(const uint_reg_t LEDMask) {}
|
||||
static inline void LEDs_ChangeLEDs(const uint_reg_t LEDMask, const uint_reg_t ActiveMask) {}
|
||||
static inline void LEDs_ToggleLEDs(const uint_reg_t LEDMask) {}
|
||||
static inline uint_reg_t LEDs_GetLEDs(void) { return 0; }
|
||||
#elif (BOARD == BOARD_USBKEY)
|
||||
#include "AVR8/USBKEY/LEDs.h"
|
||||
#elif (BOARD == BOARD_STK525)
|
||||
#include "AVR8/STK525/LEDs.h"
|
||||
#elif (BOARD == BOARD_STK526)
|
||||
#include "AVR8/STK526/LEDs.h"
|
||||
#elif (BOARD == BOARD_RZUSBSTICK)
|
||||
#include "AVR8/RZUSBSTICK/LEDs.h"
|
||||
#elif (BOARD == BOARD_ATAVRUSBRF01)
|
||||
#include "AVR8/ATAVRUSBRF01/LEDs.h"
|
||||
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
|
||||
#include "AVR8/XPLAIN/LEDs.h"
|
||||
#elif (BOARD == BOARD_BUMBLEB)
|
||||
#include "AVR8/BUMBLEB/LEDs.h"
|
||||
#elif (BOARD == BOARD_EVK527)
|
||||
#include "AVR8/EVK527/LEDs.h"
|
||||
#elif ((BOARD == BOARD_TEENSY) || (BOARD == BOARD_TEENSY2))
|
||||
#include "AVR8/TEENSY/LEDs.h"
|
||||
#elif (BOARD == BOARD_USBTINYMKII)
|
||||
#include "AVR8/USBTINYMKII/LEDs.h"
|
||||
#elif (BOARD == BOARD_BENITO)
|
||||
#include "AVR8/BENITO/LEDs.h"
|
||||
#elif (BOARD == BOARD_JMDBU2)
|
||||
#include "AVR8/JMDBU2/LEDs.h"
|
||||
#elif (BOARD == BOARD_OLIMEX162)
|
||||
#include "AVR8/OLIMEX162/LEDs.h"
|
||||
#elif (BOARD == BOARD_USBFOO)
|
||||
#include "AVR8/USBFOO/LEDs.h"
|
||||
#elif (BOARD == BOARD_UDIP)
|
||||
#include "AVR8/UDIP/LEDs.h"
|
||||
#elif (BOARD == BOARD_BUI)
|
||||
#include "AVR8/BUI/LEDs.h"
|
||||
#elif (BOARD == BOARD_UNO)
|
||||
#include "AVR8/UNO/LEDs.h"
|
||||
#elif (BOARD == BOARD_CULV3)
|
||||
#include "AVR8/CULV3/LEDs.h"
|
||||
#elif (BOARD == BOARD_BLACKCAT)
|
||||
#include "AVR8/BLACKCAT/LEDs.h"
|
||||
#elif (BOARD == BOARD_MAXIMUS)
|
||||
#include "AVR8/MAXIMUS/LEDs.h"
|
||||
#elif (BOARD == BOARD_MINIMUS)
|
||||
#include "AVR8/MINIMUS/LEDs.h"
|
||||
#elif (BOARD == BOARD_ADAFRUITU4)
|
||||
#include "AVR8/ADAFRUITU4/LEDs.h"
|
||||
#elif (BOARD == BOARD_MICROSIN162)
|
||||
#include "AVR8/MICROSIN162/LEDs.h"
|
||||
#elif (BOARD == BOARD_SPARKFUN8U2)
|
||||
#include "AVR8/SPARKFUN8U2/LEDs.h"
|
||||
#elif (BOARD == BOARD_EVK1101)
|
||||
#include "UC3/EVK1101/LEDs.h"
|
||||
#elif (BOARD == BOARD_TUL)
|
||||
#include "AVR8/TUL/LEDs.h"
|
||||
#elif (BOARD == BOARD_EVK1100)
|
||||
#include "UC3/EVK1100/LEDs.h"
|
||||
#elif (BOARD == BOARD_EVK1104)
|
||||
#include "UC3/EVK1104/LEDs.h"
|
||||
#elif (BOARD == BOARD_A3BU_XPLAINED)
|
||||
#include "XMEGA/A3BU_XPLAINED/LEDs.h"
|
||||
#elif ((BOARD == BOARD_USB2AX) || (BOARD == BOARD_USB2AX_V3) || (BOARD == BOARD_USB2AX_V31))
|
||||
#include "AVR8/USB2AX/LEDs.h"
|
||||
#elif ((BOARD == BOARD_MICROPENDOUS_REV1) || (BOARD == BOARD_MICROPENDOUS_REV2) || \
|
||||
(BOARD == BOARD_MICROPENDOUS_32U2))
|
||||
#include "AVR8/MICROPENDOUS/LEDs.h"
|
||||
#elif (BOARD == BOARD_B1_XPLAINED)
|
||||
#include "XMEGA/B1_XPLAINED/LEDs.h"
|
||||
#elif (BOARD == BOARD_MULTIO)
|
||||
#include "AVR8/MULTIO/LEDs.h"
|
||||
#elif (BOARD == BOARD_BIGMULTIO)
|
||||
#include "AVR8/BIGMULTIO/LEDs.h"
|
||||
#elif (BOARD == BOARD_DUCE)
|
||||
#include "AVR8/DUCE/LEDs.h"
|
||||
#elif (BOARD == BOARD_OLIMEX32U4)
|
||||
#include "AVR8/OLIMEX32U4/LEDs.h"
|
||||
#elif (BOARD == BOARD_OLIMEXT32U4)
|
||||
#include "AVR8/OLIMEXT32U4/LEDs.h"
|
||||
#elif (BOARD == BOARD_OLIMEXISPMK2)
|
||||
#include "AVR8/OLIMEXISPMK2/LEDs.h"
|
||||
#elif (BOARD == BOARD_LEONARDO)
|
||||
#include "AVR8/LEONARDO/LEDs.h"
|
||||
#elif (BOARD == BOARD_UC3A3_XPLAINED)
|
||||
#include "UC3/UC3A3_XPLAINED/LEDs.h"
|
||||
#elif (BOARD == BOARD_STANGE_ISP)
|
||||
#include "AVR8/STANGE_ISP/LEDs.h"
|
||||
#elif (BOARD == BOARD_C3_XPLAINED)
|
||||
#include "XMEGA/C3_XPLAINED/LEDs.h"
|
||||
#elif (BOARD == BOARD_U2S)
|
||||
#include "AVR8/U2S/LEDs.h"
|
||||
#elif (BOARD == BOARD_YUN)
|
||||
#include "AVR8/YUN/LEDs.h"
|
||||
#elif (BOARD == BOARD_MICRO)
|
||||
#include "AVR8/MICRO/LEDs.h"
|
||||
#elif (BOARD == BOARD_POLOLUMICRO)
|
||||
#include "AVR8/POLOLUMICRO/LEDs.h"
|
||||
#elif (BOARD == BOARD_XPLAINED_MINI)
|
||||
#include "AVR8/XPLAINED_MINI/LEDs.h"
|
||||
#else
|
||||
#include "Board/LEDs.h"
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
#if !defined(LEDS_NO_LEDS)
|
||||
#define LEDS_NO_LEDS 0
|
||||
#endif
|
||||
|
||||
#if !defined(LEDS_ALL_LEDS)
|
||||
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4)
|
||||
#endif
|
||||
|
||||
#if !defined(LEDS_LED1)
|
||||
#define LEDS_LED1 0
|
||||
#endif
|
||||
|
||||
#if !defined(LEDS_LED2)
|
||||
#define LEDS_LED2 0
|
||||
#endif
|
||||
|
||||
#if !defined(LEDS_LED3)
|
||||
#define LEDS_LED3 0
|
||||
#endif
|
||||
|
||||
#if !defined(LEDS_LED4)
|
||||
#define LEDS_LED4 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Pseudo-Functions for Doxygen: */
|
||||
#if defined(__DOXYGEN__)
|
||||
/** Initializes the board LED driver so that the LEDs can be controlled. This sets the appropriate port
|
||||
* I/O pins as outputs, and sets the LEDs to default to off.
|
||||
*
|
||||
* This must be called before any LED driver functions are used.
|
||||
*/
|
||||
static inline void LEDs_Init(void);
|
||||
|
||||
/** Disables the board LED driver, releasing the I/O pins back to their default high-impedance input mode. */
|
||||
static inline void LEDs_Disable(void);
|
||||
|
||||
/** Turns on the LEDs specified in the given LED mask.
|
||||
*
|
||||
* \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file).
|
||||
*/
|
||||
static inline void LEDs_TurnOnLEDs(const uint_reg_t LEDMask);
|
||||
|
||||
/** Turns off the LEDs specified in the given LED mask.
|
||||
*
|
||||
* \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file).
|
||||
*/
|
||||
static inline void LEDs_TurnOffLEDs(const uint_reg_t LEDMask);
|
||||
|
||||
/** Turns off all LEDs not specified in the given LED mask, and turns on all the LEDs in the given LED
|
||||
* mask.
|
||||
*
|
||||
* \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file).
|
||||
*/
|
||||
static inline void LEDs_SetAllLEDs(const uint_reg_t LEDMask);
|
||||
|
||||
/** Turns off all LEDs in the LED mask that are not set in the active mask, and turns on all the LEDs
|
||||
* specified in both the LED and active masks.
|
||||
*
|
||||
* \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file).
|
||||
* \param[in] ActiveMask Mask of whether the LEDs in the LED mask should be turned on or off.
|
||||
*/
|
||||
static inline void LEDs_ChangeLEDs(const uint_reg_t LEDMask,
|
||||
const uint_reg_t ActiveMask);
|
||||
|
||||
/** Toggles all LEDs in the LED mask, leaving all others in their current states.
|
||||
*
|
||||
* \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file).
|
||||
*/
|
||||
static inline void LEDs_ToggleLEDs(const uint_reg_t LEDMask);
|
||||
|
||||
/** Returns the status of all the board LEDs; set LED masks in the return value indicate that the
|
||||
* corresponding LED is on.
|
||||
*
|
||||
* \return Mask of \c LEDS_LED* constants indicating which of the board LEDs are currently turned on.
|
||||
*/
|
||||
static inline uint_reg_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
100
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/AT45DB321C.h
Normal file
100
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/AT45DB321C.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Command constants for the Atmel AT45DB321C Dataflash.
|
||||
* \copydetails Group_AT45DB321C
|
||||
*/
|
||||
|
||||
/** \ingroup Group_MiscDrivers
|
||||
* \defgroup Group_AT45DB321C Atmel AT45DB321C Dataflash Commands - LUFA/Drivers/Misc/AT45DB321C.h
|
||||
* \brief Command constants for the Atmel AT45DB321C Dataflash.
|
||||
*
|
||||
* Dataflash command constants for the Atmel AT45DB321C Dataflash IC.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __AT45DB321C_CMDS_H__
|
||||
#define __AT45DB321C_CMDS_H__
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name Dataflash Status Values */
|
||||
/**@{*/
|
||||
#define DF_STATUS_READY (1 << 7)
|
||||
#define DF_STATUS_COMPMISMATCH (1 << 6)
|
||||
#define DF_STATUS_SECTORPROTECTION_ON (1 << 1)
|
||||
/**@}*/
|
||||
|
||||
/** \name Dataflash Commands */
|
||||
/**@{*/
|
||||
#define DF_CMD_GETSTATUS 0xD7
|
||||
|
||||
#define DF_CMD_MAINMEMTOBUFF1 0x53
|
||||
#define DF_CMD_MAINMEMTOBUFF2 0x55
|
||||
#define DF_CMD_MAINMEMTOBUFF1COMP 0x60
|
||||
#define DF_CMD_MAINMEMTOBUFF2COMP 0x61
|
||||
#define DF_CMD_AUTOREWRITEBUFF1 0x58
|
||||
#define DF_CMD_AUTOREWRITEBUFF2 0x59
|
||||
|
||||
#define DF_CMD_MAINMEMPAGEREAD 0xD2
|
||||
#define DF_CMD_CONTARRAYREAD_LF 0xE8
|
||||
#define DF_CMD_BUFF1READ_LF 0xD4
|
||||
#define DF_CMD_BUFF2READ_LF 0xD6
|
||||
|
||||
#define DF_CMD_BUFF1WRITE 0x84
|
||||
#define DF_CMD_BUFF2WRITE 0x87
|
||||
#define DF_CMD_BUFF1TOMAINMEMWITHERASE 0x83
|
||||
#define DF_CMD_BUFF2TOMAINMEMWITHERASE 0x86
|
||||
#define DF_CMD_BUFF1TOMAINMEM 0x88
|
||||
#define DF_CMD_BUFF2TOMAINMEM 0x89
|
||||
#define DF_CMD_MAINMEMPAGETHROUGHBUFF1 0x82
|
||||
#define DF_CMD_MAINMEMPAGETHROUGHBUFF2 0x85
|
||||
|
||||
#define DF_CMD_PAGEERASE 0x81
|
||||
#define DF_CMD_BLOCKERASE 0x50
|
||||
|
||||
#define DF_CMD_SECTORPROTECTIONOFF ((char[]){0x3D, 0x2A, 0x7F, 0xCF})
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE1 0x3D
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE2 0x2A
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE3 0x7F
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE4 0xCF
|
||||
|
||||
#define DF_CMD_READMANUFACTURERDEVICEINFO 0x9F
|
||||
/**@}*/
|
||||
|
||||
/** Manufacturer code for Atmel Corporation, returned by Atmel Dataflash ICs in response to the \c DF_CMD_READMANUFACTURERDEVICEINFO command. */
|
||||
#define DF_MANUFACTURER_ATMEL 0x1F
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
116
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/AT45DB642D.h
Normal file
116
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/AT45DB642D.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Command constants for the Atmel AT45DB642D Dataflash.
|
||||
* \copydetails Group_AT45DB642D
|
||||
*/
|
||||
|
||||
/** \ingroup Group_MiscDrivers
|
||||
* \defgroup Group_AT45DB642D Atmel AT45DB642D Dataflash Commands - LUFA/Drivers/Misc/AT45DB642D.h
|
||||
* \brief Command constants for the Atmel AT45DB642D Dataflash.
|
||||
*
|
||||
* Dataflash command constants for the Atmel AT45DB642D Dataflash IC.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __AT45DB642D_CMDS_H__
|
||||
#define __AT45DB642D_CMDS_H__
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name Dataflash Status Values */
|
||||
/**@{*/
|
||||
#define DF_STATUS_READY (1 << 7)
|
||||
#define DF_STATUS_COMPMISMATCH (1 << 6)
|
||||
#define DF_STATUS_SECTORPROTECTION_ON (1 << 1)
|
||||
#define DF_STATUS_BINARYPAGESIZE_ON (1 << 0)
|
||||
/**@}*/
|
||||
|
||||
/** \name Dataflash Commands */
|
||||
/**@{*/
|
||||
#define DF_CMD_GETSTATUS 0xD7
|
||||
#define DF_CMD_POWERDOWN 0xB9
|
||||
#define DF_CMD_WAKEUP 0xAB
|
||||
|
||||
#define DF_CMD_MAINMEMTOBUFF1 0x53
|
||||
#define DF_CMD_MAINMEMTOBUFF2 0x55
|
||||
#define DF_CMD_MAINMEMTOBUFF1COMP 0x60
|
||||
#define DF_CMD_MAINMEMTOBUFF2COMP 0x61
|
||||
#define DF_CMD_AUTOREWRITEBUFF1 0x58
|
||||
#define DF_CMD_AUTOREWRITEBUFF2 0x59
|
||||
|
||||
#define DF_CMD_MAINMEMPAGEREAD 0xD2
|
||||
#define DF_CMD_CONTARRAYREAD_LF 0x03
|
||||
#define DF_CMD_BUFF1READ_LF 0xD1
|
||||
#define DF_CMD_BUFF2READ_LF 0xD3
|
||||
|
||||
#define DF_CMD_BUFF1WRITE 0x84
|
||||
#define DF_CMD_BUFF2WRITE 0x87
|
||||
#define DF_CMD_BUFF1TOMAINMEMWITHERASE 0x83
|
||||
#define DF_CMD_BUFF2TOMAINMEMWITHERASE 0x86
|
||||
#define DF_CMD_BUFF1TOMAINMEM 0x88
|
||||
#define DF_CMD_BUFF2TOMAINMEM 0x89
|
||||
#define DF_CMD_MAINMEMPAGETHROUGHBUFF1 0x82
|
||||
#define DF_CMD_MAINMEMPAGETHROUGHBUFF2 0x85
|
||||
|
||||
#define DF_CMD_PAGEERASE 0x81
|
||||
#define DF_CMD_BLOCKERASE 0x50
|
||||
#define DF_CMD_SECTORERASE 0x7C
|
||||
|
||||
#define DF_CMD_CHIPERASE ((char[]){0xC7, 0x94, 0x80, 0x9A})
|
||||
#define DF_CMD_CHIPERASE_BYTE1 0xC7
|
||||
#define DF_CMD_CHIPERASE_BYTE2 0x94
|
||||
#define DF_CMD_CHIPERASE_BYTE3 0x80
|
||||
#define DF_CMD_CHIPERASE_BYTE4 0x9A
|
||||
|
||||
#define DF_CMD_SECTORPROTECTIONOFF ((char[]){0x3D, 0x2A, 0x7F, 0x9A})
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE1 0x3D
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE2 0x2A
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE3 0x7F
|
||||
#define DF_CMD_SECTORPROTECTIONOFF_BYTE4 0x9A
|
||||
|
||||
#define DF_CMD_BINARYPAGESIZEMODEON ((char[]){0x3D, 0x2A, 0x80, 0xA6})
|
||||
#define DF_CMD_BINARYPAGESIZEMODEON_BYTE1 0x3D
|
||||
#define DF_CMD_BINARYPAGESIZEMODEON_BYTE2 0x2A
|
||||
#define DF_CMD_BINARYPAGESIZEMODEON_BYTE3 0x80
|
||||
#define DF_CMD_BINARYPAGESIZEMODEON_BYTE4 0xA6
|
||||
|
||||
#define DF_CMD_READMANUFACTURERDEVICEINFO 0x9F
|
||||
/**@}*/
|
||||
|
||||
/** Manufacturer code for Atmel Corporation, returned by Atmel Dataflash ICs in response to the \c DF_CMD_READMANUFACTURERDEVICEINFO command. */
|
||||
#define DF_MANUFACTURER_ATMEL 0x1F
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
308
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/RingBuffer.h
Normal file
308
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/RingBuffer.h
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Lightweight ring (circular) buffer, for fast insertion/deletion of bytes.
|
||||
*
|
||||
* Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of
|
||||
* different sizes to suit different needs.
|
||||
*
|
||||
* Note that for each buffer, insertion and removal operations may occur at the same time (via
|
||||
* a multi-threaded ISR based system) however the same kind of operation (two or more insertions
|
||||
* or deletions) must not overlap. If there is possibility of two or more of the same kind of
|
||||
* operating occurring at the same point in time, atomic (mutex) locking should be used.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_MiscDrivers
|
||||
* \defgroup Group_RingBuff Generic Byte Ring Buffer - LUFA/Drivers/Misc/RingBuffer.h
|
||||
* \brief Lightweight ring buffer, for fast insertion/deletion of bytes.
|
||||
*
|
||||
* \section Sec_RingBuff_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - None
|
||||
*
|
||||
* \section Sec_RingBuff_ModDescription Module Description
|
||||
* Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of
|
||||
* different sizes to suit different needs.
|
||||
*
|
||||
* Note that for each buffer, insertion and removal operations may occur at the same time (via
|
||||
* a multi-threaded ISR based system) however the same kind of operation (two or more insertions
|
||||
* or deletions) must not overlap. If there is possibility of two or more of the same kind of
|
||||
* operating occurring at the same point in time, atomic (mutex) locking should be used.
|
||||
*
|
||||
* \section Sec_RingBuff_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* \code
|
||||
* // Create the buffer structure and its underlying storage array
|
||||
* RingBuffer_t Buffer;
|
||||
* uint8_t BufferData[128];
|
||||
*
|
||||
* // Initialize the buffer with the created storage array
|
||||
* RingBuffer_InitBuffer(&Buffer, BufferData, sizeof(BufferData));
|
||||
*
|
||||
* // Insert some data into the buffer
|
||||
* RingBuffer_Insert(&Buffer, 'H');
|
||||
* RingBuffer_Insert(&Buffer, 'E');
|
||||
* RingBuffer_Insert(&Buffer, 'L');
|
||||
* RingBuffer_Insert(&Buffer, 'L');
|
||||
* RingBuffer_Insert(&Buffer, 'O');
|
||||
*
|
||||
* // Cache the number of stored bytes in the buffer
|
||||
* uint16_t BufferCount = RingBuffer_GetCount(&Buffer);
|
||||
*
|
||||
* // Printer stored data length
|
||||
* printf("Buffer Length: %d, Buffer Data: \r\n", BufferCount);
|
||||
*
|
||||
* // Print contents of the buffer one character at a time
|
||||
* while (BufferCount--)
|
||||
* putc(RingBuffer_Remove(&Buffer));
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __RING_BUFFER_H__
|
||||
#define __RING_BUFFER_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief Ring Buffer Management Structure.
|
||||
*
|
||||
* Type define for a new ring buffer object. Buffers should be initialized via a call to
|
||||
* \ref RingBuffer_InitBuffer() before use.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t* In; /**< Current storage location in the circular buffer. */
|
||||
uint8_t* Out; /**< Current retrieval location in the circular buffer. */
|
||||
uint8_t* Start; /**< Pointer to the start of the buffer's underlying storage array. */
|
||||
uint8_t* End; /**< Pointer to the end of the buffer's underlying storage array. */
|
||||
uint16_t Size; /**< Size of the buffer's underlying storage array. */
|
||||
uint16_t Count; /**< Number of bytes currently stored in the buffer. */
|
||||
} RingBuffer_t;
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Initializes a ring buffer ready for use. Buffers must be initialized via this function
|
||||
* before any operations are called upon them. Already initialized buffers may be reset
|
||||
* by re-initializing them using this function.
|
||||
*
|
||||
* \param[out] Buffer Pointer to a ring buffer structure to initialize.
|
||||
* \param[out] DataPtr Pointer to a global array that will hold the data stored into the ring buffer.
|
||||
* \param[out] Size Maximum number of bytes that can be stored in the underlying data array.
|
||||
*/
|
||||
static inline void RingBuffer_InitBuffer(RingBuffer_t* Buffer,
|
||||
uint8_t* const DataPtr,
|
||||
const uint16_t Size) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
static inline void RingBuffer_InitBuffer(RingBuffer_t* Buffer,
|
||||
uint8_t* const DataPtr,
|
||||
const uint16_t Size)
|
||||
{
|
||||
GCC_FORCE_POINTER_ACCESS(Buffer);
|
||||
|
||||
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
|
||||
GlobalInterruptDisable();
|
||||
|
||||
Buffer->In = DataPtr;
|
||||
Buffer->Out = DataPtr;
|
||||
Buffer->Start = &DataPtr[0];
|
||||
Buffer->End = &DataPtr[Size];
|
||||
Buffer->Size = Size;
|
||||
Buffer->Count = 0;
|
||||
|
||||
SetGlobalInterruptMask(CurrentGlobalInt);
|
||||
}
|
||||
|
||||
/** Retrieves the current number of bytes stored in a particular buffer. This value is computed
|
||||
* by entering an atomic lock on the buffer, so that the buffer cannot be modified while the
|
||||
* computation takes place. This value should be cached when reading out the contents of the buffer,
|
||||
* so that as small a time as possible is spent in an atomic lock.
|
||||
*
|
||||
* \note The value returned by this function is guaranteed to only be the minimum number of bytes
|
||||
* stored in the given buffer; this value may change as other threads write new data, thus
|
||||
* the returned number should be used only to determine how many successive reads may safely
|
||||
* be performed on the buffer.
|
||||
*
|
||||
* \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed.
|
||||
*
|
||||
* \return Number of bytes currently stored in the buffer.
|
||||
*/
|
||||
static inline uint16_t RingBuffer_GetCount(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline uint16_t RingBuffer_GetCount(RingBuffer_t* const Buffer)
|
||||
{
|
||||
uint16_t Count;
|
||||
|
||||
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
|
||||
GlobalInterruptDisable();
|
||||
|
||||
Count = Buffer->Count;
|
||||
|
||||
SetGlobalInterruptMask(CurrentGlobalInt);
|
||||
return Count;
|
||||
}
|
||||
|
||||
/** Retrieves the free space in a particular buffer. This value is computed by entering an atomic lock
|
||||
* on the buffer, so that the buffer cannot be modified while the computation takes place.
|
||||
*
|
||||
* \note The value returned by this function is guaranteed to only be the maximum number of bytes
|
||||
* free in the given buffer; this value may change as other threads write new data, thus
|
||||
* the returned number should be used only to determine how many successive writes may safely
|
||||
* be performed on the buffer when there is a single writer thread.
|
||||
*
|
||||
* \param[in] Buffer Pointer to a ring buffer structure whose free count is to be computed.
|
||||
*
|
||||
* \return Number of free bytes in the buffer.
|
||||
*/
|
||||
static inline uint16_t RingBuffer_GetFreeCount(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline uint16_t RingBuffer_GetFreeCount(RingBuffer_t* const Buffer)
|
||||
{
|
||||
return (Buffer->Size - RingBuffer_GetCount(Buffer));
|
||||
}
|
||||
|
||||
/** Atomically determines if the specified ring buffer contains any data. This should
|
||||
* be tested before removing data from the buffer, to ensure that the buffer does not
|
||||
* underflow.
|
||||
*
|
||||
* If the data is to be removed in a loop, store the total number of bytes stored in the
|
||||
* buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable
|
||||
* to reduce the time spent in atomicity locks.
|
||||
*
|
||||
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into.
|
||||
*
|
||||
* \return Boolean \c true if the buffer contains no free space, \c false otherwise.
|
||||
*/
|
||||
static inline bool RingBuffer_IsEmpty(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline bool RingBuffer_IsEmpty(RingBuffer_t* const Buffer)
|
||||
{
|
||||
return (RingBuffer_GetCount(Buffer) == 0);
|
||||
}
|
||||
|
||||
/** Atomically determines if the specified ring buffer contains any free space. This should
|
||||
* be tested before storing data to the buffer, to ensure that no data is lost due to a
|
||||
* buffer overrun.
|
||||
*
|
||||
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into.
|
||||
*
|
||||
* \return Boolean \c true if the buffer contains no free space, \c false otherwise.
|
||||
*/
|
||||
static inline bool RingBuffer_IsFull(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline bool RingBuffer_IsFull(RingBuffer_t* const Buffer)
|
||||
{
|
||||
return (RingBuffer_GetCount(Buffer) == Buffer->Size);
|
||||
}
|
||||
|
||||
/** Inserts an element into the ring buffer.
|
||||
*
|
||||
* \warning Only one execution thread (main program thread or an ISR) may insert into a single buffer
|
||||
* otherwise data corruption may occur. Insertion and removal may occur from different execution
|
||||
* threads.
|
||||
*
|
||||
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into.
|
||||
* \param[in] Data Data element to insert into the buffer.
|
||||
*/
|
||||
static inline void RingBuffer_Insert(RingBuffer_t* Buffer,
|
||||
const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline void RingBuffer_Insert(RingBuffer_t* Buffer,
|
||||
const uint8_t Data)
|
||||
{
|
||||
GCC_FORCE_POINTER_ACCESS(Buffer);
|
||||
|
||||
*Buffer->In = Data;
|
||||
|
||||
if (++Buffer->In == Buffer->End)
|
||||
Buffer->In = Buffer->Start;
|
||||
|
||||
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
|
||||
GlobalInterruptDisable();
|
||||
|
||||
Buffer->Count++;
|
||||
|
||||
SetGlobalInterruptMask(CurrentGlobalInt);
|
||||
}
|
||||
|
||||
/** Removes an element from the ring buffer.
|
||||
*
|
||||
* \warning Only one execution thread (main program thread or an ISR) may remove from a single buffer
|
||||
* otherwise data corruption may occur. Insertion and removal may occur from different execution
|
||||
* threads.
|
||||
*
|
||||
* \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from.
|
||||
*
|
||||
* \return Next data element stored in the buffer.
|
||||
*/
|
||||
static inline uint8_t RingBuffer_Remove(RingBuffer_t* Buffer) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline uint8_t RingBuffer_Remove(RingBuffer_t* Buffer)
|
||||
{
|
||||
GCC_FORCE_POINTER_ACCESS(Buffer);
|
||||
|
||||
uint8_t Data = *Buffer->Out;
|
||||
|
||||
if (++Buffer->Out == Buffer->End)
|
||||
Buffer->Out = Buffer->Start;
|
||||
|
||||
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
|
||||
GlobalInterruptDisable();
|
||||
|
||||
Buffer->Count--;
|
||||
|
||||
SetGlobalInterruptMask(CurrentGlobalInt);
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
/** Returns the next element stored in the ring buffer, without removing it.
|
||||
*
|
||||
* \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from.
|
||||
*
|
||||
* \return Next data element stored in the buffer.
|
||||
*/
|
||||
static inline uint8_t RingBuffer_Peek(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline uint8_t RingBuffer_Peek(RingBuffer_t* const Buffer)
|
||||
{
|
||||
return *Buffer->Out;
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
231
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/TerminalCodes.h
Normal file
231
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Misc/TerminalCodes.h
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief ANSI terminal special escape code macros.
|
||||
*
|
||||
* ANSI terminal compatible escape sequences. These escape sequences are designed to be concatenated with existing
|
||||
* strings to modify their display on a compatible terminal application.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_MiscDrivers
|
||||
* \defgroup Group_Terminal ANSI Terminal Escape Codes - LUFA/Drivers/Misc/TerminalCodes.h
|
||||
* \brief ANSI terminal special escape code macros.
|
||||
*
|
||||
* \section Sec_Terminal_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - None
|
||||
*
|
||||
* \section Sec_Terminal_ModDescription Module Description
|
||||
* Escape code macros for ANSI compliant text terminals.
|
||||
*
|
||||
* \note If desired, the macro \c DISABLE_TERMINAL_CODES can be defined in the project makefile and passed to the GCC
|
||||
* compiler via the -D switch to disable the terminal codes without modifying the source, for use with non
|
||||
* compatible terminals (any terminal codes then equate to empty strings).
|
||||
*
|
||||
* \section Sec_Terminal_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* \code
|
||||
* printf("Normal String, "
|
||||
* ESC_BOLD_ON "Bold String, "
|
||||
* ESC_UNDERLINE_ON "Bold and Underlined String"
|
||||
* ESC_RESET ESC_FG_BLUE ESC_BG_YELLOW "Normal Blue-on-Yellow String");
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __TERMINALCODES_H__
|
||||
#define __TERMINALCODES_H__
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
#if !defined(DISABLE_TERMINAL_CODES)
|
||||
/** Creates an ANSI escape sequence with the specified payload.
|
||||
*
|
||||
* \param[in] EscapeSeq Payload to encode as an ANSI escape sequence, a \c ESC_* mask.
|
||||
*/
|
||||
#define ANSI_ESCAPE_SEQUENCE(EscapeSeq) "\33[" EscapeSeq
|
||||
#else
|
||||
#define ANSI_ESCAPE_SEQUENCE(EscapeSeq)
|
||||
#endif
|
||||
|
||||
/** \name Text Display Modifier Control Sequences */
|
||||
/**@{*/
|
||||
/** Turns on bold so that any following text is printed to the terminal in bold. */
|
||||
#define ESC_BOLD_ON ANSI_ESCAPE_SEQUENCE("1m")
|
||||
|
||||
/** Turns on italics so that any following text is printed to the terminal in italics. */
|
||||
#define ESC_ITALICS_ON ANSI_ESCAPE_SEQUENCE("3m")
|
||||
|
||||
/** Turns on underline so that any following text is printed to the terminal underlined. */
|
||||
#define ESC_UNDERLINE_ON ANSI_ESCAPE_SEQUENCE("4m")
|
||||
|
||||
/** Turns on inverse so that any following text is printed to the terminal in inverted colours. */
|
||||
#define ESC_INVERSE_ON ANSI_ESCAPE_SEQUENCE("7m")
|
||||
|
||||
/** Turns on strike-through so that any following text is printed to the terminal with a line through the
|
||||
* center.
|
||||
*/
|
||||
#define ESC_STRIKETHROUGH_ON ANSI_ESCAPE_SEQUENCE("9m")
|
||||
|
||||
/** Turns off bold so that any following text is printed to the terminal in non bold. */
|
||||
#define ESC_BOLD_OFF ANSI_ESCAPE_SEQUENCE("22m")
|
||||
|
||||
/** Turns off italics so that any following text is printed to the terminal in non italics. */
|
||||
#define ESC_ITALICS_OFF ANSI_ESCAPE_SEQUENCE("23m")
|
||||
|
||||
/** Turns off underline so that any following text is printed to the terminal non underlined. */
|
||||
#define ESC_UNDERLINE_OFF ANSI_ESCAPE_SEQUENCE("24m")
|
||||
|
||||
/** Turns off inverse so that any following text is printed to the terminal in non inverted colours. */
|
||||
#define ESC_INVERSE_OFF ANSI_ESCAPE_SEQUENCE("27m")
|
||||
|
||||
/** Turns off strike-through so that any following text is printed to the terminal without a line through
|
||||
* the center.
|
||||
*/
|
||||
#define ESC_STRIKETHROUGH_OFF ANSI_ESCAPE_SEQUENCE("29m")
|
||||
/**@}*/
|
||||
|
||||
/** \name Text Colour Control Sequences */
|
||||
/**@{*/
|
||||
/** Sets the foreground (text) colour to black. */
|
||||
#define ESC_FG_BLACK ANSI_ESCAPE_SEQUENCE("30m")
|
||||
|
||||
/** Sets the foreground (text) colour to red. */
|
||||
#define ESC_FG_RED ANSI_ESCAPE_SEQUENCE("31m")
|
||||
|
||||
/** Sets the foreground (text) colour to green. */
|
||||
#define ESC_FG_GREEN ANSI_ESCAPE_SEQUENCE("32m")
|
||||
|
||||
/** Sets the foreground (text) colour to yellow. */
|
||||
#define ESC_FG_YELLOW ANSI_ESCAPE_SEQUENCE("33m")
|
||||
|
||||
/** Sets the foreground (text) colour to blue. */
|
||||
#define ESC_FG_BLUE ANSI_ESCAPE_SEQUENCE("34m")
|
||||
|
||||
/** Sets the foreground (text) colour to magenta. */
|
||||
#define ESC_FG_MAGENTA ANSI_ESCAPE_SEQUENCE("35m")
|
||||
|
||||
/** Sets the foreground (text) colour to cyan. */
|
||||
#define ESC_FG_CYAN ANSI_ESCAPE_SEQUENCE("36m")
|
||||
|
||||
/** Sets the foreground (text) colour to white. */
|
||||
#define ESC_FG_WHITE ANSI_ESCAPE_SEQUENCE("37m")
|
||||
|
||||
/** Sets the foreground (text) colour to the terminal's default. */
|
||||
#define ESC_FG_DEFAULT ANSI_ESCAPE_SEQUENCE("39m")
|
||||
|
||||
/** Sets the text background colour to black. */
|
||||
#define ESC_BG_BLACK ANSI_ESCAPE_SEQUENCE("40m")
|
||||
|
||||
/** Sets the text background colour to red. */
|
||||
#define ESC_BG_RED ANSI_ESCAPE_SEQUENCE("41m")
|
||||
|
||||
/** Sets the text background colour to green. */
|
||||
#define ESC_BG_GREEN ANSI_ESCAPE_SEQUENCE("42m")
|
||||
|
||||
/** Sets the text background colour to yellow. */
|
||||
#define ESC_BG_YELLOW ANSI_ESCAPE_SEQUENCE("43m")
|
||||
|
||||
/** Sets the text background colour to blue. */
|
||||
#define ESC_BG_BLUE ANSI_ESCAPE_SEQUENCE("44m")
|
||||
|
||||
/** Sets the text background colour to magenta. */
|
||||
#define ESC_BG_MAGENTA ANSI_ESCAPE_SEQUENCE("45m")
|
||||
|
||||
/** Sets the text background colour to cyan. */
|
||||
#define ESC_BG_CYAN ANSI_ESCAPE_SEQUENCE("46m")
|
||||
|
||||
/** Sets the text background colour to white. */
|
||||
#define ESC_BG_WHITE ANSI_ESCAPE_SEQUENCE("47m")
|
||||
|
||||
/** Sets the text background colour to the terminal's default. */
|
||||
#define ESC_BG_DEFAULT ANSI_ESCAPE_SEQUENCE("49m")
|
||||
/**@}*/
|
||||
|
||||
/** \name Cursor Positioning Control Sequences */
|
||||
/**@{*/
|
||||
/** Saves the current cursor position so that it may be restored with \ref ESC_CURSOR_POS_RESTORE. */
|
||||
#define ESC_CURSOR_POS_SAVE ANSI_ESCAPE_SEQUENCE("s")
|
||||
|
||||
/** Restores the cursor position to the last position saved with \ref ESC_CURSOR_POS_SAVE. */
|
||||
#define ESC_CURSOR_POS_RESTORE ANSI_ESCAPE_SEQUENCE("u")
|
||||
|
||||
/** Sets the cursor position to the given line and column.
|
||||
*
|
||||
* \param[in] Line Line number to position the cursor at.
|
||||
* \param[in] Column Column number to position the cursor at.
|
||||
*/
|
||||
#define ESC_CURSOR_POS(Line, Column) ANSI_ESCAPE_SEQUENCE(#Line ";" #Column "H")
|
||||
|
||||
/** Moves the cursor up the given number of lines.
|
||||
*
|
||||
* \param[in] Lines Number of lines to move the cursor position
|
||||
*/
|
||||
#define ESC_CURSOR_UP(Lines) ANSI_ESCAPE_SEQUENCE(#Lines "A")
|
||||
|
||||
/** Moves the cursor down the given number of lines.
|
||||
*
|
||||
* \param[in] Lines Number of lines to move the cursor position
|
||||
*/
|
||||
#define ESC_CURSOR_DOWN(Lines) ANSI_ESCAPE_SEQUENCE(#Lines "B")
|
||||
|
||||
/** Moves the cursor to the right the given number of columns.
|
||||
*
|
||||
* \param[in] Columns Number of columns to move the cursor position
|
||||
*/
|
||||
#define ESC_CURSOR_FORWARD(Columns) ANSI_ESCAPE_SEQUENCE(#Columns "C")
|
||||
|
||||
/** Moves the cursor to the left the given number of columns.
|
||||
*
|
||||
* \param[in] Columns Number of columns to move the cursor position
|
||||
*/
|
||||
#define ESC_CURSOR_BACKWARD(Columns) ANSI_ESCAPE_SEQUENCE(#Columns "D")
|
||||
/**@}*/
|
||||
|
||||
/** \name Miscellaneous Control Sequences */
|
||||
/**@{*/
|
||||
/** Resets any escape sequence modifiers back to their defaults. */
|
||||
#define ESC_RESET ANSI_ESCAPE_SEQUENCE("0m")
|
||||
|
||||
/** Erases the entire display, returning the cursor to the top left. */
|
||||
#define ESC_ERASE_DISPLAY ANSI_ESCAPE_SEQUENCE("2J")
|
||||
|
||||
/** Erases the current line, returning the cursor to the far left. */
|
||||
#define ESC_ERASE_LINE ANSI_ESCAPE_SEQUENCE("K")
|
||||
/**@}*/
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
75
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/ADC.h
Normal file
75
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/ADC.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Hardware Analogue-to-Digital converter driver.
|
||||
*
|
||||
* This file is the master dispatch header file for the device-specific ADC driver, for microcontrollers
|
||||
* containing an ADC.
|
||||
*
|
||||
* User code should include this file, which will in turn include the correct ADC driver header file for the
|
||||
* currently selected architecture and microcontroller model.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_PeripheralDrivers
|
||||
* \defgroup Group_ADC ADC Driver - LUFA/Drivers/Peripheral/ADC.h
|
||||
* \brief Hardware Analogue-to-Digital converter driver.
|
||||
*
|
||||
* \section Sec_ADC_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - None
|
||||
*
|
||||
* \section Sec_ADC_ModDescription Module Description
|
||||
* Hardware ADC driver. This module provides an easy to use driver for the hardware ADC
|
||||
* present on many microcontrollers, for the conversion of analogue signals into the
|
||||
* digital domain.
|
||||
*
|
||||
* \note The exact API for this driver may vary depending on the target used - see
|
||||
* individual target module documentation for the API specific to your target processor.
|
||||
*/
|
||||
|
||||
#ifndef __ADC_H__
|
||||
#define __ADC_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_ADC_H
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
/* Includes: */
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
#include "AVR8/ADC_AVR8.h"
|
||||
#else
|
||||
#error The ADC peripheral driver is not currently available for your selected architecture.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief ADC Peripheral Driver (AVR8)
|
||||
*
|
||||
* On-chip Analogue-to-Digital converter (ADC) driver for supported U4, U6 and U7 model AVRs that contain an ADC
|
||||
* peripheral internally.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the ADC driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/ADC.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_ADC
|
||||
* \defgroup Group_ADC_AVR8 ADC Peripheral Driver (AVR8)
|
||||
*
|
||||
* \section Sec_ADC_AVR8_ModDescription Module Description
|
||||
* On-chip Analogue-to-Digital converter (ADC) driver for supported U4, U6 and U7 model AVRs that contain an ADC
|
||||
* peripheral internally.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the ADC driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/ADC.h.
|
||||
*
|
||||
* \section Sec_ADC_AVR8_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* \code
|
||||
* // Initialize the ADC driver before first use
|
||||
* ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
|
||||
*
|
||||
* // Must setup the ADC channel to read beforehand
|
||||
* ADC_SetupChannel(1);
|
||||
*
|
||||
* // Perform a single conversion of the ADC channel 1
|
||||
* ADC_GetChannelReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ADC_CHANNEL1);
|
||||
* printf("Conversion Result: %d\r\n", ADC_GetResult());
|
||||
*
|
||||
* // Start reading ADC channel 1 in free running (continuous conversion) mode
|
||||
* ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ADC_CHANNEL1);
|
||||
* for (;;)
|
||||
* {
|
||||
* while (!(ADC_IsReadingComplete())) {};
|
||||
* printf("Conversion Result: %d\r\n", ADC_GetResult());
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __ADC_AVR8_H__
|
||||
#define __ADC_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_ADC_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Peripheral/ADC.h instead.
|
||||
#endif
|
||||
|
||||
#if !(defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
|
||||
defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \
|
||||
defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
#error The ADC peripheral driver is not currently available for your selected microcontroller model.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name ADC Reference Configuration Masks */
|
||||
/**@{*/
|
||||
/** Reference mask, for using the voltage present at the AVR's AREF pin for the ADC reference. */
|
||||
#define ADC_REFERENCE_AREF 0
|
||||
|
||||
/** Reference mask, for using the voltage present at the AVR's AVCC pin for the ADC reference. */
|
||||
#define ADC_REFERENCE_AVCC (1 << REFS0)
|
||||
|
||||
/** Reference mask, for using the internally generated 2.56V reference voltage as the ADC reference. */
|
||||
#define ADC_REFERENCE_INT2560MV ((1 << REFS1) | (1 << REFS0))
|
||||
/**@}*/
|
||||
|
||||
/** \name ADC Result Adjustment Configuration Masks */
|
||||
/**@{*/
|
||||
/** Left-adjusts the 10-bit ADC result, so that the upper 8 bits of the value returned by the
|
||||
* \ref ADC_GetResult() macro contain the 8 most significant bits of the result.
|
||||
*/
|
||||
#define ADC_LEFT_ADJUSTED (1 << ADLAR)
|
||||
|
||||
/** Right-adjusts the 10-bit ADC result, so that the lower 8 bits of the value returned by the
|
||||
* \ref ADC_GetResult() macro contain the 8 least significant bits of the result.
|
||||
*/
|
||||
#define ADC_RIGHT_ADJUSTED (0 << ADLAR)
|
||||
/**@}*/
|
||||
|
||||
/** \name ADC Mode Configuration Masks */
|
||||
/**@{*/
|
||||
/** Sets the ADC mode to free running, so that conversions take place continuously as fast as the ADC
|
||||
* is capable of at the given input clock speed.
|
||||
*/
|
||||
#define ADC_FREE_RUNNING (1 << ADATE)
|
||||
|
||||
/** Sets the ADC mode to single conversion, so that only a single conversion will take place before
|
||||
* the ADC returns to idle.
|
||||
*/
|
||||
#define ADC_SINGLE_CONVERSION (0 << ADATE)
|
||||
/**@}*/
|
||||
|
||||
/** \name ADC Prescaler Configuration Masks */
|
||||
/**@{*/
|
||||
/** Sets the ADC input clock to prescale by a factor of 2 the AVR's system clock. */
|
||||
#define ADC_PRESCALE_2 (1 << ADPS0)
|
||||
|
||||
/** Sets the ADC input clock to prescale by a factor of 4 the AVR's system clock. */
|
||||
#define ADC_PRESCALE_4 (1 << ADPS1)
|
||||
|
||||
/** Sets the ADC input clock to prescale by a factor of 8 the AVR's system clock. */
|
||||
#define ADC_PRESCALE_8 ((1 << ADPS0) | (1 << ADPS1))
|
||||
|
||||
/** Sets the ADC input clock to prescale by a factor of 16 the AVR's system clock. */
|
||||
#define ADC_PRESCALE_16 (1 << ADPS2)
|
||||
|
||||
/** Sets the ADC input clock to prescale by a factor of 32 the AVR's system clock. */
|
||||
#define ADC_PRESCALE_32 ((1 << ADPS2) | (1 << ADPS0))
|
||||
|
||||
/** Sets the ADC input clock to prescale by a factor of 64 the AVR's system clock. */
|
||||
#define ADC_PRESCALE_64 ((1 << ADPS2) | (1 << ADPS1))
|
||||
|
||||
/** Sets the ADC input clock to prescale by a factor of 128 the AVR's system clock. */
|
||||
#define ADC_PRESCALE_128 ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0))
|
||||
/**@}*/
|
||||
|
||||
/** \name ADC MUX Masks */
|
||||
/**@{*/
|
||||
/** MUX mask define for the ADC0 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
|
||||
#define ADC_CHANNEL0 (0x00 << MUX0)
|
||||
|
||||
/** MUX mask define for the ADC1 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
|
||||
#define ADC_CHANNEL1 (0x01 << MUX0)
|
||||
|
||||
#if (!(defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) || defined(__DOXYGEN__))
|
||||
/** MUX mask define for the ADC2 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL2 (0x02 << MUX0)
|
||||
|
||||
/** MUX mask define for the ADC3 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL3 (0x03 << MUX0)
|
||||
#endif
|
||||
|
||||
/** MUX mask define for the ADC4 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
|
||||
#define ADC_CHANNEL4 (0x04 << MUX0)
|
||||
|
||||
/** MUX mask define for the ADC5 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
|
||||
#define ADC_CHANNEL5 (0x05 << MUX0)
|
||||
|
||||
/** MUX mask define for the ADC6 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
|
||||
#define ADC_CHANNEL6 (0x06 << MUX0)
|
||||
|
||||
/** MUX mask define for the ADC7 channel of the ADC. See \ref ADC_StartReading and \ref ADC_GetChannelReading. */
|
||||
#define ADC_CHANNEL7 (0x07 << MUX0)
|
||||
|
||||
#if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__DOXYGEN__))
|
||||
/** MUX mask define for the ADC8 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL8 ((1 << 8) | (0x00 << MUX0))
|
||||
|
||||
/** MUX mask define for the ADC9 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL9 ((1 << 8) | (0x01 << MUX0))
|
||||
|
||||
/** MUX mask define for the ADC10 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL10 ((1 << 8) | (0x02 << MUX0))
|
||||
|
||||
/** MUX mask define for the ADC11 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL11 ((1 << 8) | (0x03 << MUX0))
|
||||
|
||||
/** MUX mask define for the ADC12 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL12 ((1 << 8) | (0x04 << MUX0))
|
||||
|
||||
/** MUX mask define for the ADC13 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_CHANNEL13 ((1 << 8) | (0x05 << MUX0))
|
||||
|
||||
/** MUX mask define for the internal temperature sensor channel of the ADC. See \ref ADC_StartReading() and
|
||||
* \ref ADC_GetChannelReading().
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ADC_INT_TEMP_SENS ((1 << 8) | (0x07 << MUX0))
|
||||
#endif
|
||||
|
||||
/** MUX mask define for the internal 1.1V band-gap channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
|
||||
#define ADC_1100MV_BANDGAP (0x1E << MUX0)
|
||||
|
||||
/** Retrieves the ADC MUX mask for the given ADC channel number.
|
||||
*
|
||||
* \attention This macro will only work correctly on channel numbers that are compile-time
|
||||
* constants defined by the preprocessor.
|
||||
*
|
||||
* \param[in] Channel Index of the ADC channel whose MUX mask is to be retrieved.
|
||||
*/
|
||||
#define ADC_GET_CHANNEL_MASK(Channel) CONCAT_EXPANDED(ADC_CHANNEL, Channel)
|
||||
/**@}*/
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Configures the given ADC channel, ready for ADC conversions. This function sets the
|
||||
* associated port pin as an input and disables the digital portion of the I/O to reduce
|
||||
* power consumption.
|
||||
*
|
||||
* \note This must only be called for ADC channels with are connected to a physical port
|
||||
* pin of the AVR, denoted by its special alternative function ADCx.
|
||||
*
|
||||
* \warning The channel number must be specified as an integer, and <b>not</b> a \c ADC_CHANNEL* mask.
|
||||
*
|
||||
* \param[in] ChannelIndex ADC channel number to set up for conversions.
|
||||
*/
|
||||
static inline void ADC_SetupChannel(const uint8_t ChannelIndex)
|
||||
{
|
||||
#if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
|
||||
defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__))
|
||||
DDRF &= ~(1 << ChannelIndex);
|
||||
DIDR0 |= (1 << ChannelIndex);
|
||||
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
if (ChannelIndex < 8)
|
||||
{
|
||||
DDRF &= ~(1 << ChannelIndex);
|
||||
DIDR0 |= (1 << ChannelIndex);
|
||||
}
|
||||
else if (ChannelIndex == 8)
|
||||
{
|
||||
DDRD &= ~(1 << 4);
|
||||
DIDR2 |= (1 << 0);
|
||||
}
|
||||
else if (ChannelIndex < 11)
|
||||
{
|
||||
DDRD &= ~(1 << (ChannelIndex - 3));
|
||||
DIDR2 |= (1 << (ChannelIndex - 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
DDRB &= ~(1 << (ChannelIndex - 7));
|
||||
DIDR2 |= (1 << (ChannelIndex - 8));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** De-configures the given ADC channel, re-enabling digital I/O mode instead of analog. This
|
||||
* function sets the associated port pin as an input and re-enabled the digital portion of
|
||||
* the I/O.
|
||||
*
|
||||
* \note This must only be called for ADC channels with are connected to a physical port
|
||||
* pin of the AVR, denoted by its special alternative function ADCx.
|
||||
*
|
||||
* \warning The channel number must be specified as an integer, and <b>not</b> a \c ADC_CHANNEL* mask.
|
||||
*
|
||||
* \param[in] ChannelIndex ADC channel number to set up for conversions.
|
||||
*/
|
||||
static inline void ADC_DisableChannel(const uint8_t ChannelIndex)
|
||||
{
|
||||
#if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
|
||||
defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__))
|
||||
DDRF &= ~(1 << ChannelIndex);
|
||||
DIDR0 &= ~(1 << ChannelIndex);
|
||||
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
if (ChannelIndex < 8)
|
||||
{
|
||||
DDRF &= ~(1 << ChannelIndex);
|
||||
DIDR0 &= ~(1 << ChannelIndex);
|
||||
}
|
||||
else if (ChannelIndex == 8)
|
||||
{
|
||||
DDRD &= ~(1 << 4);
|
||||
DIDR2 &= ~(1 << 0);
|
||||
}
|
||||
else if (ChannelIndex < 11)
|
||||
{
|
||||
DDRD &= ~(1 << (ChannelIndex - 3));
|
||||
DIDR2 &= ~(1 << (ChannelIndex - 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
DDRB &= ~(1 << (ChannelIndex - 7));
|
||||
DIDR2 &= ~(1 << (ChannelIndex - 8));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Starts the reading of the given channel, but does not wait until the conversion has completed.
|
||||
* Once executed, the conversion status can be determined via the \ref ADC_IsReadingComplete() macro and
|
||||
* the result read via the \ref ADC_GetResult() macro.
|
||||
*
|
||||
* If the ADC has been initialized in free running mode, calling this function once will begin the repeated
|
||||
* conversions. If the ADC is in single conversion mode (or the channel to convert from is to be changed),
|
||||
* this function must be called each time a conversion is to take place.
|
||||
*
|
||||
* \param[in] MUXMask ADC channel mask, reference mask and adjustment mask.
|
||||
*/
|
||||
static inline void ADC_StartReading(const uint16_t MUXMask)
|
||||
{
|
||||
ADMUX = MUXMask;
|
||||
|
||||
#if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__DOXYGEN__))
|
||||
if (MUXMask & (1 << 8))
|
||||
ADCSRB |= (1 << MUX5);
|
||||
else
|
||||
ADCSRB &= ~(1 << MUX5);
|
||||
#endif
|
||||
|
||||
ADCSRA |= (1 << ADSC);
|
||||
}
|
||||
|
||||
/** Indicates if the current ADC conversion is completed, or still in progress.
|
||||
*
|
||||
* \return Boolean \c false if the reading is still taking place, or true if the conversion is
|
||||
* complete and ready to be read out with \ref ADC_GetResult().
|
||||
*/
|
||||
static inline bool ADC_IsReadingComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool ADC_IsReadingComplete(void)
|
||||
{
|
||||
return ((ADCSRA & (1 << ADIF)) ? true : false);
|
||||
}
|
||||
|
||||
/** Retrieves the conversion value of the last completed ADC conversion and clears the reading
|
||||
* completion flag.
|
||||
*
|
||||
* \return The result of the last ADC conversion as an unsigned value.
|
||||
*/
|
||||
static inline uint16_t ADC_GetResult(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint16_t ADC_GetResult(void)
|
||||
{
|
||||
ADCSRA |= (1 << ADIF);
|
||||
return ADC;
|
||||
}
|
||||
|
||||
/** Performs a complete single reading from channel, including a polling spin-loop to wait for the
|
||||
* conversion to complete, and the returning of the converted value.
|
||||
*
|
||||
* \note For free running mode, the automated conversions should be initialized with a single call
|
||||
* to \ref ADC_StartReading() to select the channel and begin the automated conversions, and
|
||||
* the results read directly from the \ref ADC_GetResult() instead to reduce overhead.
|
||||
*
|
||||
* \param[in] MUXMask Mask comprising of an ADC channel mask, reference mask and adjustment mask.
|
||||
*
|
||||
* \return Converted ADC result for the given ADC channel.
|
||||
*/
|
||||
static inline uint16_t ADC_GetChannelReading(const uint16_t MUXMask) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint16_t ADC_GetChannelReading(const uint16_t MUXMask)
|
||||
{
|
||||
ADC_StartReading(MUXMask);
|
||||
|
||||
while (!(ADC_IsReadingComplete()));
|
||||
|
||||
return ADC_GetResult();
|
||||
}
|
||||
|
||||
/** Initializes the ADC, ready for conversions. This must be called before any other ADC operations.
|
||||
* The "mode" parameter should be a mask comprised of a conversion mode (free running or single) and
|
||||
* prescaler masks.
|
||||
*
|
||||
* \param[in] Mode Mask of ADC prescale and mode settings.
|
||||
*/
|
||||
static inline void ADC_Init(const uint8_t Mode) ATTR_ALWAYS_INLINE;
|
||||
static inline void ADC_Init(const uint8_t Mode)
|
||||
{
|
||||
ADCSRA = ((1 << ADEN) | Mode);
|
||||
}
|
||||
|
||||
/** Turns off the ADC. If this is called, any further ADC operations will require a call to
|
||||
* \ref ADC_Init() before the ADC can be used again.
|
||||
*/
|
||||
static inline void ADC_Disable(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void ADC_Disable(void)
|
||||
{
|
||||
ADCSRA = 0;
|
||||
}
|
||||
|
||||
/** Indicates if the ADC is currently enabled.
|
||||
*
|
||||
* \return Boolean \c true if the ADC subsystem is currently enabled, \c false otherwise.
|
||||
*/
|
||||
static inline bool ADC_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool ADC_GetStatus(void)
|
||||
{
|
||||
return ((ADCSRA & (1 << ADEN)) ? true : false);
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief SPI Peripheral Driver (AVR8)
|
||||
*
|
||||
* On-chip SPI driver for the 8-bit AVR microcontrollers.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the SPI driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/SPI.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_SPI
|
||||
* \defgroup Group_SPI_AVR8 SPI Peripheral Driver (AVR8)
|
||||
*
|
||||
* \section Sec_SPI_AVR8_ModDescription Module Description
|
||||
* Driver for the hardware SPI port available on most 8-bit AVR microcontroller models. This
|
||||
* module provides an easy to use driver for the setup and transfer of data over the
|
||||
* AVR's SPI port.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the SPI driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/SPI.h.
|
||||
*
|
||||
* \section Sec_SPI_AVR8_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* \code
|
||||
* // Initialize the SPI driver before first use
|
||||
* SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_FALLING |
|
||||
* SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
|
||||
*
|
||||
* // Send several bytes, ignoring the returned data
|
||||
* SPI_SendByte(0x01);
|
||||
* SPI_SendByte(0x02);
|
||||
* SPI_SendByte(0x03);
|
||||
*
|
||||
* // Receive several bytes, sending a dummy 0x00 byte each time
|
||||
* uint8_t Byte1 = SPI_ReceiveByte();
|
||||
* uint8_t Byte2 = SPI_ReceiveByte();
|
||||
* uint8_t Byte3 = SPI_ReceiveByte();
|
||||
*
|
||||
* // Send a byte, and store the received byte from the same transaction
|
||||
* uint8_t ResponseByte = SPI_TransferByte(0xDC);
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __SPI_AVR8_H__
|
||||
#define __SPI_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_SPI_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Peripheral/SPI.h instead.
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define SPI_USE_DOUBLESPEED (1 << SPE)
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name SPI Prescaler Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 2. */
|
||||
#define SPI_SPEED_FCPU_DIV_2 SPI_USE_DOUBLESPEED
|
||||
|
||||
/** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 4. */
|
||||
#define SPI_SPEED_FCPU_DIV_4 0
|
||||
|
||||
/** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 8. */
|
||||
#define SPI_SPEED_FCPU_DIV_8 (SPI_USE_DOUBLESPEED | (1 << SPR0))
|
||||
|
||||
/** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 16. */
|
||||
#define SPI_SPEED_FCPU_DIV_16 (1 << SPR0)
|
||||
|
||||
/** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 32. */
|
||||
#define SPI_SPEED_FCPU_DIV_32 (SPI_USE_DOUBLESPEED | (1 << SPR1))
|
||||
|
||||
/** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 64. */
|
||||
#define SPI_SPEED_FCPU_DIV_64 (SPI_USE_DOUBLESPEED | (1 << SPR1) | (1 << SPR0))
|
||||
|
||||
/** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 128. */
|
||||
#define SPI_SPEED_FCPU_DIV_128 ((1 << SPR1) | (1 << SPR0))
|
||||
/**@}*/
|
||||
|
||||
/** \name SPI SCK Polarity Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the rising edge. */
|
||||
#define SPI_SCK_LEAD_RISING (0 << CPOL)
|
||||
|
||||
/** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the falling edge. */
|
||||
#define SPI_SCK_LEAD_FALLING (1 << CPOL)
|
||||
/**@}*/
|
||||
|
||||
/** \name SPI Sample Edge Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should sampled on the leading edge. */
|
||||
#define SPI_SAMPLE_LEADING (0 << CPHA)
|
||||
|
||||
/** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should be sampled on the trailing edge. */
|
||||
#define SPI_SAMPLE_TRAILING (1 << CPHA)
|
||||
/**@}*/
|
||||
|
||||
/** \name SPI Data Ordering Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out MSB first. */
|
||||
#define SPI_ORDER_MSB_FIRST (0 << DORD)
|
||||
|
||||
/** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out LSB first. */
|
||||
#define SPI_ORDER_LSB_FIRST (1 << DORD)
|
||||
/**@}*/
|
||||
|
||||
/** \name SPI Mode Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */
|
||||
#define SPI_MODE_SLAVE (0 << MSTR)
|
||||
|
||||
/** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */
|
||||
#define SPI_MODE_MASTER (1 << MSTR)
|
||||
/**@}*/
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Initializes the SPI subsystem, ready for transfers. Must be called before calling any other
|
||||
* SPI routines.
|
||||
*
|
||||
* \param[in] SPIOptions SPI Options, a mask consisting of one of each of the \c SPI_SPEED_*,
|
||||
* \c SPI_SCK_*, \c SPI_SAMPLE_*, \c SPI_ORDER_* and \c SPI_MODE_* masks.
|
||||
*/
|
||||
static inline void SPI_Init(const uint8_t SPIOptions);
|
||||
static inline void SPI_Init(const uint8_t SPIOptions)
|
||||
{
|
||||
/* Prevent high rise times on PB.0 (/SS) from forcing a change to SPI slave mode */
|
||||
DDRB |= (1 << 0);
|
||||
PORTB |= (1 << 0);
|
||||
|
||||
DDRB |= ((1 << 1) | (1 << 2));
|
||||
DDRB &= ~(1 << 3);
|
||||
PORTB |= (1 << 3);
|
||||
|
||||
if (SPIOptions & SPI_USE_DOUBLESPEED)
|
||||
SPSR |= (1 << SPI2X);
|
||||
else
|
||||
SPSR &= ~(1 << SPI2X);
|
||||
|
||||
/* Switch /SS to input mode after configuration to allow for forced mode changes */
|
||||
DDRB &= ~(1 << 0);
|
||||
|
||||
SPCR = ((1 << SPE) | SPIOptions);
|
||||
}
|
||||
|
||||
/** Turns off the SPI driver, disabling and returning used hardware to their default configuration. */
|
||||
static inline void SPI_Disable(void);
|
||||
static inline void SPI_Disable(void)
|
||||
{
|
||||
DDRB &= ~((1 << 1) | (1 << 2));
|
||||
PORTB &= ~((1 << 0) | (1 << 3));
|
||||
|
||||
SPCR = 0;
|
||||
SPSR = 0;
|
||||
}
|
||||
|
||||
/** Retrieves the currently selected SPI mode, once the SPI interface has been configured.
|
||||
*
|
||||
* \return \ref SPI_MODE_MASTER if the interface is currently in SPI Master mode, \ref SPI_MODE_SLAVE otherwise
|
||||
*/
|
||||
static inline uint8_t SPI_GetCurrentMode(void) ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t SPI_GetCurrentMode(void)
|
||||
{
|
||||
return (SPCR & SPI_MODE_MASTER);
|
||||
}
|
||||
|
||||
/** Sends and receives a byte through the SPI interface, blocking until the transfer is complete.
|
||||
*
|
||||
* \param[in] Byte Byte to send through the SPI interface.
|
||||
*
|
||||
* \return Response byte from the attached SPI device.
|
||||
*/
|
||||
static inline uint8_t SPI_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t SPI_TransferByte(const uint8_t Byte)
|
||||
{
|
||||
SPDR = Byte;
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
/** Sends a byte through the SPI interface, blocking until the transfer is complete. The response
|
||||
* byte sent to from the attached SPI device is ignored.
|
||||
*
|
||||
* \param[in] Byte Byte to send through the SPI interface.
|
||||
*/
|
||||
static inline void SPI_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
|
||||
static inline void SPI_SendByte(const uint8_t Byte)
|
||||
{
|
||||
SPDR = Byte;
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
}
|
||||
|
||||
/** Sends a dummy byte through the SPI interface, blocking until the transfer is complete. The response
|
||||
* byte from the attached SPI device is returned.
|
||||
*
|
||||
* \return The response byte from the attached SPI device.
|
||||
*/
|
||||
static inline uint8_t SPI_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t SPI_ReceiveByte(void)
|
||||
{
|
||||
SPDR = 0x00;
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master SPI Mode Serial USART Peripheral Driver (XMEGA)
|
||||
*
|
||||
* On-chip Master SPI mode USART driver for the XMEGA AVR microcontrollers.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the SPI Master
|
||||
* Mode USART driver dispatch header located in LUFA/Drivers/Peripheral/Serial.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_SerialSPI
|
||||
* \defgroup Group_SerialSPI_AVR8 Master SPI Mode Serial USART Peripheral Driver (AVR8)
|
||||
*
|
||||
* \section Sec_SerialSPI_AVR8_ModDescription Module Description
|
||||
* On-chip serial USART driver for the 8-bit AVR8 microcontrollers.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the SPI Master
|
||||
* driver dispatch header located in LUFA/Drivers/Peripheral/SerialSPI.h.
|
||||
*
|
||||
* \section Sec_SerialSPI_AVR8_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* \code
|
||||
* // Initialize the Master SPI mode USART driver before first use, with 1Mbit baud
|
||||
* SerialSPI_Init((USART_SPI_SCK_LEAD_RISING | USART_SPI_SAMPLE_LEADING | USART_SPI_ORDER_MSB_FIRST), 1000000);
|
||||
*
|
||||
* // Send several bytes, ignoring the returned data
|
||||
* SerialSPI_SendByte(0x01);
|
||||
* SerialSPI_SendByte(0x02);
|
||||
* SerialSPI_SendByte(0x03);
|
||||
*
|
||||
* // Receive several bytes, sending a dummy 0x00 byte each time
|
||||
* uint8_t Byte1 = SerialSPI_ReceiveByte();
|
||||
* uint8_t Byte2 = SerialSPI_ReceiveByte();
|
||||
* uint8_t Byte3 = SerialSPI_ReceiveByte();
|
||||
*
|
||||
* // Send a byte, and store the received byte from the same transaction
|
||||
* uint8_t ResponseByte = SerialSPI_TransferByte(0xDC);
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __SERIAL_SPI_AVR8_H__
|
||||
#define __SERIAL_SPI_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_SERIAL_SPI_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead.
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
#define SERIAL_SPI_UBBRVAL(Baud) ((Baud < (F_CPU / 2)) ? ((F_CPU / (2 * Baud)) - 1) : 0)
|
||||
|
||||
/* Master USART SPI mode flag definitions missing in the AVR8 toolchain */
|
||||
#if !defined(UCPHA1)
|
||||
#define UCPHA1 1
|
||||
#endif
|
||||
#if !defined(UDORD1)
|
||||
#define UDORD1 2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name SPI SCK Polarity Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the rising edge. */
|
||||
#define USART_SPI_SCK_LEAD_RISING (0 << UCPOL1)
|
||||
|
||||
/** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the falling edge. */
|
||||
#define USART_SPI_SCK_LEAD_FALLING (1 << UCPOL1)
|
||||
/**@}*/
|
||||
|
||||
/** \name SPI Sample Edge Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should sampled on the leading edge. */
|
||||
#define USART_SPI_SAMPLE_LEADING (0 << UCPHA1)
|
||||
|
||||
/** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should be sampled on the trailing edge. */
|
||||
#define USART_SPI_SAMPLE_TRAILING (1 << UCPHA1)
|
||||
/**@}*/
|
||||
|
||||
/** \name SPI Data Ordering Configuration Masks */
|
||||
/**@{*/
|
||||
/** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out MSB first. */
|
||||
#define USART_SPI_ORDER_MSB_FIRST (0 << UDORD1)
|
||||
|
||||
/** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out LSB first. */
|
||||
#define USART_SPI_ORDER_LSB_FIRST (1 << UDORD1)
|
||||
/**@}*/
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Initialize the USART module in Master SPI mode.
|
||||
*
|
||||
* \param[in] SPIOptions USART SPI Options, a mask consisting of one of each of the \c USART_SPI_SCK_*,
|
||||
* \c USART_SPI_SAMPLE_* and \c USART_SPI_ORDER_* masks.
|
||||
* \param[in] BaudRate SPI baud rate, in bits per second.
|
||||
*/
|
||||
static inline void SerialSPI_Init(const uint8_t SPIOptions,
|
||||
const uint32_t BaudRate)
|
||||
{
|
||||
DDRD |= ((1 << 3) | (1 << 5));
|
||||
PORTD |= (1 << 2);
|
||||
|
||||
UCSR1C = ((1 << UMSEL11) | (1 << UMSEL10) | SPIOptions);
|
||||
UCSR1B = ((1 << TXEN1) | (1 << RXEN1));
|
||||
|
||||
UBRR1 = SERIAL_SPI_UBBRVAL(BaudRate);
|
||||
}
|
||||
|
||||
/** Turns off the USART driver, disabling and returning used hardware to their default configuration. */
|
||||
static inline void SerialSPI_Disable(void)
|
||||
{
|
||||
UCSR1B = 0;
|
||||
UCSR1A = 0;
|
||||
UCSR1C = 0;
|
||||
|
||||
UBRR1 = 0;
|
||||
|
||||
DDRD &= ~((1 << 3) | (1 << 5));
|
||||
PORTD &= ~(1 << 2);
|
||||
}
|
||||
|
||||
/** Sends and receives a byte through the USART SPI interface, blocking until the transfer is complete.
|
||||
*
|
||||
* \param[in] DataByte Byte to send through the USART SPI interface.
|
||||
*
|
||||
* \return Response byte from the attached SPI device.
|
||||
*/
|
||||
static inline uint8_t SerialSPI_TransferByte(const uint8_t DataByte)
|
||||
{
|
||||
UDR1 = DataByte;
|
||||
while (!(UCSR1A & (1 << TXC1)));
|
||||
UCSR1A = (1 << TXC1);
|
||||
return UDR1;
|
||||
}
|
||||
|
||||
/** Sends a byte through the USART SPI interface, blocking until the transfer is complete. The response
|
||||
* byte sent to from the attached SPI device is ignored.
|
||||
*
|
||||
* \param[in] DataByte Byte to send through the USART SPI interface.
|
||||
*/
|
||||
static inline void SerialSPI_SendByte(const uint8_t DataByte)
|
||||
{
|
||||
SerialSPI_TransferByte(DataByte);
|
||||
}
|
||||
|
||||
/** Sends a dummy byte through the USART SPI interface, blocking until the transfer is complete. The response
|
||||
* byte from the attached SPI device is returned.
|
||||
*
|
||||
* \return The response byte from the attached SPI device.
|
||||
*/
|
||||
static inline uint8_t SerialSPI_ReceiveByte(void)
|
||||
{
|
||||
return SerialSPI_TransferByte(0);
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
#define __INCLUDE_FROM_SERIAL_C
|
||||
#include "../Serial.h"
|
||||
|
||||
FILE USARTSerialStream;
|
||||
|
||||
int Serial_putchar(char DataByte,
|
||||
FILE *Stream)
|
||||
{
|
||||
(void)Stream;
|
||||
|
||||
Serial_SendByte(DataByte);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Serial_getchar(FILE *Stream)
|
||||
{
|
||||
(void)Stream;
|
||||
|
||||
if (!(Serial_IsCharReceived()))
|
||||
return _FDEV_EOF;
|
||||
|
||||
return Serial_ReceiveByte();
|
||||
}
|
||||
|
||||
int Serial_getchar_Blocking(FILE *Stream)
|
||||
{
|
||||
(void)Stream;
|
||||
|
||||
while (!(Serial_IsCharReceived()));
|
||||
return Serial_ReceiveByte();
|
||||
}
|
||||
|
||||
void Serial_SendString_P(const char* FlashStringPtr)
|
||||
{
|
||||
uint8_t CurrByte;
|
||||
|
||||
while ((CurrByte = pgm_read_byte(FlashStringPtr)) != 0x00)
|
||||
{
|
||||
Serial_SendByte(CurrByte);
|
||||
FlashStringPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
void Serial_SendString(const char* StringPtr)
|
||||
{
|
||||
uint8_t CurrByte;
|
||||
|
||||
while ((CurrByte = *StringPtr) != 0x00)
|
||||
{
|
||||
Serial_SendByte(CurrByte);
|
||||
StringPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
void Serial_SendData(const void* Buffer,
|
||||
uint16_t Length)
|
||||
{
|
||||
uint8_t* CurrByte = (uint8_t*)Buffer;
|
||||
|
||||
while (Length--)
|
||||
Serial_SendByte(*(CurrByte++));
|
||||
}
|
||||
|
||||
void Serial_CreateStream(FILE* Stream)
|
||||
{
|
||||
if (!(Stream))
|
||||
{
|
||||
Stream = &USARTSerialStream;
|
||||
stdin = Stream;
|
||||
stdout = Stream;
|
||||
}
|
||||
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar, _FDEV_SETUP_RW);
|
||||
}
|
||||
|
||||
void Serial_CreateBlockingStream(FILE* Stream)
|
||||
{
|
||||
if (!(Stream))
|
||||
{
|
||||
Stream = &USARTSerialStream;
|
||||
stdin = Stream;
|
||||
stdout = Stream;
|
||||
}
|
||||
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar_Blocking, _FDEV_SETUP_RW);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Serial USART Peripheral Driver (AVR8)
|
||||
*
|
||||
* On-chip serial USART driver for the 8-bit AVR microcontrollers.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USART driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/Serial.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Serial
|
||||
* \defgroup Group_Serial_AVR8 Serial USART Peripheral Driver (AVR8)
|
||||
*
|
||||
* \section Sec_Serial_AVR8_ModDescription Module Description
|
||||
* On-chip serial USART driver for the 8-bit AVR microcontrollers.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USART driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/Serial.h.
|
||||
*
|
||||
* \section Sec_Serial_AVR8_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* \code
|
||||
* // Initialize the serial USART driver before first use, with 9600 baud (and no double-speed mode)
|
||||
* Serial_Init(9600, false);
|
||||
*
|
||||
* // Send a string through the USART
|
||||
* Serial_SendString("Test String\r\n");
|
||||
*
|
||||
* // Send a raw byte through the USART
|
||||
* Serial_SendByte(0xDC);
|
||||
*
|
||||
* // Receive a byte through the USART (or -1 if no data received)
|
||||
* int16_t DataByte = Serial_ReceiveByte();
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __SERIAL_AVR8_H__
|
||||
#define __SERIAL_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../../Misc/TerminalCodes.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_SERIAL_H) && !defined(__INCLUDE_FROM_SERIAL_C)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead.
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* External Variables: */
|
||||
extern FILE USARTSerialStream;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int Serial_putchar(char DataByte,
|
||||
FILE *Stream);
|
||||
int Serial_getchar(FILE *Stream);
|
||||
int Serial_getchar_Blocking(FILE *Stream);
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is
|
||||
* not set.
|
||||
*
|
||||
* \param[in] Baud Target serial UART baud rate.
|
||||
*
|
||||
* \return Closest UBRR register value for the given UART frequency.
|
||||
*/
|
||||
#define SERIAL_UBBRVAL(Baud) ((((F_CPU / 16) + (Baud / 2)) / (Baud)) - 1)
|
||||
|
||||
/** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is
|
||||
* set.
|
||||
*
|
||||
* \param[in] Baud Target serial UART baud rate.
|
||||
*
|
||||
* \return Closest UBRR register value for the given UART frequency.
|
||||
*/
|
||||
#define SERIAL_2X_UBBRVAL(Baud) ((((F_CPU / 8) + (Baud / 2)) / (Baud)) - 1)
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Transmits a given NUL terminated string located in program space (FLASH) through the USART.
|
||||
*
|
||||
* \param[in] FlashStringPtr Pointer to a string located in program space.
|
||||
*/
|
||||
void Serial_SendString_P(const char* FlashStringPtr) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Transmits a given NUL terminated string located in SRAM memory through the USART.
|
||||
*
|
||||
* \param[in] StringPtr Pointer to a string located in SRAM space.
|
||||
*/
|
||||
void Serial_SendString(const char* StringPtr) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Transmits a given buffer located in SRAM memory through the USART.
|
||||
*
|
||||
* \param[in] Buffer Pointer to a buffer containing the data to send.
|
||||
* \param[in] Length Length of the data to send, in bytes.
|
||||
*/
|
||||
void Serial_SendData(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Creates a standard character stream from the USART so that it can be used with all the regular functions
|
||||
* in the avr-libc \c <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created
|
||||
* stream is bidirectional and can be used for both input and output functions.
|
||||
*
|
||||
* Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
|
||||
* fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
|
||||
* be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
|
||||
* line buffering.
|
||||
*
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout
|
||||
* and \c stdin will be configured to use the USART.
|
||||
*
|
||||
* \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used.
|
||||
*/
|
||||
void Serial_CreateStream(FILE* Stream);
|
||||
|
||||
/** Identical to \ref Serial_CreateStream(), except that reads are blocking until the calling stream function terminates
|
||||
* the transfer.
|
||||
*
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout
|
||||
* and \c stdin will be configured to use the USART.
|
||||
*
|
||||
* \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used.
|
||||
*/
|
||||
void Serial_CreateBlockingStream(FILE* Stream);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Initializes the USART, ready for serial data transmission and reception. This initializes the interface to
|
||||
* standard 8-bit, no parity, 1 stop bit settings suitable for most applications.
|
||||
*
|
||||
* \param[in] BaudRate Serial baud rate, in bits per second. This should be the target baud rate regardless of the
|
||||
* \c DoubleSpeed parameter's value.
|
||||
* \param[in] DoubleSpeed Enables double speed mode when set, halving the sample time to double the baud rate.
|
||||
*/
|
||||
static inline void Serial_Init(const uint32_t BaudRate,
|
||||
const bool DoubleSpeed);
|
||||
static inline void Serial_Init(const uint32_t BaudRate,
|
||||
const bool DoubleSpeed)
|
||||
{
|
||||
UBRR1 = (DoubleSpeed ? SERIAL_2X_UBBRVAL(BaudRate) : SERIAL_UBBRVAL(BaudRate));
|
||||
|
||||
UCSR1C = ((1 << UCSZ11) | (1 << UCSZ10));
|
||||
UCSR1A = (DoubleSpeed ? (1 << U2X1) : 0);
|
||||
UCSR1B = ((1 << TXEN1) | (1 << RXEN1));
|
||||
|
||||
DDRD |= (1 << 3);
|
||||
PORTD |= (1 << 2);
|
||||
}
|
||||
|
||||
/** Turns off the USART driver, disabling and returning used hardware to their default configuration. */
|
||||
static inline void Serial_Disable(void);
|
||||
static inline void Serial_Disable(void)
|
||||
{
|
||||
UCSR1B = 0;
|
||||
UCSR1A = 0;
|
||||
UCSR1C = 0;
|
||||
|
||||
UBRR1 = 0;
|
||||
|
||||
DDRD &= ~(1 << 3);
|
||||
PORTD &= ~(1 << 2);
|
||||
}
|
||||
|
||||
/** Indicates whether a character has been received through the USART.
|
||||
*
|
||||
* \return Boolean \c true if a character has been received, \c false otherwise.
|
||||
*/
|
||||
static inline bool Serial_IsCharReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Serial_IsCharReceived(void)
|
||||
{
|
||||
return ((UCSR1A & (1 << RXC1)) ? true : false);
|
||||
}
|
||||
|
||||
/** Indicates whether there is hardware buffer space for a new transmit on the USART. This
|
||||
* function can be used to determine if a call to \ref Serial_SendByte() will block in advance.
|
||||
*
|
||||
* \return Boolean \c true if a character can be queued for transmission immediately, \c false otherwise.
|
||||
*/
|
||||
static inline bool Serial_IsSendReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Serial_IsSendReady(void)
|
||||
{
|
||||
return ((UCSR1A & (1 << UDRE1)) ? true : false);
|
||||
}
|
||||
|
||||
/** Indicates whether the hardware USART transmit buffer is completely empty, indicating all
|
||||
* pending transmissions have completed.
|
||||
*
|
||||
* \return Boolean \c true if no characters are buffered for transmission, \c false otherwise.
|
||||
*/
|
||||
static inline bool Serial_IsSendComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Serial_IsSendComplete(void)
|
||||
{
|
||||
return ((UCSR1A & (1 << TXC1)) ? true : false);
|
||||
}
|
||||
|
||||
/** Transmits a given byte through the USART.
|
||||
*
|
||||
* \note If no buffer space is available in the hardware USART, this function will block. To check if
|
||||
* space is available before calling this function, see \ref Serial_IsSendReady().
|
||||
*
|
||||
* \param[in] DataByte Byte to transmit through the USART.
|
||||
*/
|
||||
static inline void Serial_SendByte(const char DataByte) ATTR_ALWAYS_INLINE;
|
||||
static inline void Serial_SendByte(const char DataByte)
|
||||
{
|
||||
while (!(Serial_IsSendReady()));
|
||||
UDR1 = DataByte;
|
||||
}
|
||||
|
||||
/** Receives the next byte from the USART.
|
||||
*
|
||||
* \return Next byte received from the USART, or a negative value if no byte has been received.
|
||||
*/
|
||||
static inline int16_t Serial_ReceiveByte(void) ATTR_ALWAYS_INLINE;
|
||||
static inline int16_t Serial_ReceiveByte(void)
|
||||
{
|
||||
if (!(Serial_IsCharReceived()))
|
||||
return -1;
|
||||
|
||||
return UDR1;
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#if (ARCH == ARCH_AVR8) && defined(TWCR)
|
||||
|
||||
#define __INCLUDE_FROM_TWI_C
|
||||
#include "../TWI.h"
|
||||
|
||||
uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
|
||||
const uint8_t TimeoutMS)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
bool BusCaptured = false;
|
||||
uint16_t TimeoutRemaining;
|
||||
|
||||
TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));
|
||||
|
||||
TimeoutRemaining = (TimeoutMS * 100);
|
||||
while (TimeoutRemaining && !(BusCaptured))
|
||||
{
|
||||
if (TWCR & (1 << TWINT))
|
||||
{
|
||||
switch (TWSR & TW_STATUS_MASK)
|
||||
{
|
||||
case TW_START:
|
||||
case TW_REP_START:
|
||||
BusCaptured = true;
|
||||
break;
|
||||
case TW_MT_ARB_LOST:
|
||||
TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));
|
||||
continue;
|
||||
default:
|
||||
TWCR = (1 << TWEN);
|
||||
return TWI_ERROR_BusFault;
|
||||
}
|
||||
}
|
||||
|
||||
_delay_us(10);
|
||||
TimeoutRemaining--;
|
||||
}
|
||||
|
||||
if (!(TimeoutRemaining))
|
||||
{
|
||||
TWCR = (1 << TWEN);
|
||||
return TWI_ERROR_BusCaptureTimeout;
|
||||
}
|
||||
|
||||
TWDR = SlaveAddress;
|
||||
TWCR = ((1 << TWINT) | (1 << TWEN));
|
||||
|
||||
TimeoutRemaining = (TimeoutMS * 100);
|
||||
while (TimeoutRemaining)
|
||||
{
|
||||
if (TWCR & (1 << TWINT))
|
||||
break;
|
||||
|
||||
_delay_us(10);
|
||||
TimeoutRemaining--;
|
||||
}
|
||||
|
||||
if (!(TimeoutRemaining))
|
||||
return TWI_ERROR_SlaveResponseTimeout;
|
||||
|
||||
switch (TWSR & TW_STATUS_MASK)
|
||||
{
|
||||
case TW_MT_SLA_ACK:
|
||||
case TW_MR_SLA_ACK:
|
||||
return TWI_ERROR_NoError;
|
||||
default:
|
||||
TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN));
|
||||
return TWI_ERROR_SlaveNotReady;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TWI_SendByte(const uint8_t Byte)
|
||||
{
|
||||
TWDR = Byte;
|
||||
TWCR = ((1 << TWINT) | (1 << TWEN));
|
||||
while (!(TWCR & (1 << TWINT)));
|
||||
|
||||
return ((TWSR & TW_STATUS_MASK) == TW_MT_DATA_ACK);
|
||||
}
|
||||
|
||||
bool TWI_ReceiveByte(uint8_t* const Byte,
|
||||
const bool LastByte)
|
||||
{
|
||||
uint8_t TWCRMask;
|
||||
|
||||
if (LastByte)
|
||||
TWCRMask = ((1 << TWINT) | (1 << TWEN));
|
||||
else
|
||||
TWCRMask = ((1 << TWINT) | (1 << TWEN) | (1 << TWEA));
|
||||
|
||||
TWCR = TWCRMask;
|
||||
while (!(TWCR & (1 << TWINT)));
|
||||
*Byte = TWDR;
|
||||
|
||||
uint8_t Status = (TWSR & TW_STATUS_MASK);
|
||||
|
||||
return ((LastByte) ? (Status == TW_MR_DATA_NACK) : (Status == TW_MR_DATA_ACK));
|
||||
}
|
||||
|
||||
uint8_t TWI_ReadPacket(const uint8_t SlaveAddress,
|
||||
const uint8_t TimeoutMS,
|
||||
const uint8_t* InternalAddress,
|
||||
uint8_t InternalAddressLen,
|
||||
uint8_t* Buffer,
|
||||
uint16_t Length)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
|
||||
TimeoutMS)) == TWI_ERROR_NoError)
|
||||
{
|
||||
while (InternalAddressLen--)
|
||||
{
|
||||
if (!(TWI_SendByte(*(InternalAddress++))))
|
||||
{
|
||||
ErrorCode = TWI_ERROR_SlaveNAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_READ,
|
||||
TimeoutMS)) == TWI_ERROR_NoError)
|
||||
{
|
||||
while (Length--)
|
||||
{
|
||||
if (!(TWI_ReceiveByte(Buffer++, (Length == 0))))
|
||||
{
|
||||
ErrorCode = TWI_ERROR_SlaveNAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TWI_StopTransmission();
|
||||
}
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t TWI_WritePacket(const uint8_t SlaveAddress,
|
||||
const uint8_t TimeoutMS,
|
||||
const uint8_t* InternalAddress,
|
||||
uint8_t InternalAddressLen,
|
||||
const uint8_t* Buffer,
|
||||
uint16_t Length)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE,
|
||||
TimeoutMS)) == TWI_ERROR_NoError)
|
||||
{
|
||||
while (InternalAddressLen--)
|
||||
{
|
||||
if (!(TWI_SendByte(*(InternalAddress++))))
|
||||
{
|
||||
ErrorCode = TWI_ERROR_SlaveNAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(TWI_SendByte(*(Buffer++))))
|
||||
{
|
||||
ErrorCode = TWI_ERROR_SlaveNAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TWI_StopTransmission();
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief TWI Peripheral Driver (AVR8)
|
||||
*
|
||||
* On-chip TWI driver for the 8-bit AVR microcontrollers.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the TWI driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/TWI.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_TWI
|
||||
* \defgroup Group_TWI_AVR8 TWI Peripheral Driver (AVR8)
|
||||
*
|
||||
* \section Sec_TWI_AVR8_ModDescription Module Description
|
||||
* Master mode TWI driver for the 8-bit AVR microcontrollers which contain a hardware TWI module.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the TWI driver
|
||||
* dispatch header located in LUFA/Drivers/Peripheral/TWI.h.
|
||||
*
|
||||
* \section Sec_TWI_AVR8_ExampleUsage Example Usage
|
||||
* The following snippet is an example of how this module may be used within a typical
|
||||
* application.
|
||||
*
|
||||
* <b>Low Level API Example:</b>
|
||||
* \code
|
||||
* // Initialize the TWI driver before first use at 200KHz
|
||||
* TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 200000));
|
||||
*
|
||||
* // Start a write session to device at device address 0xA0, internal address 0xDC with a 10ms timeout
|
||||
* if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_WRITE, 10) == TWI_ERROR_NoError)
|
||||
* {
|
||||
* TWI_SendByte(0xDC);
|
||||
*
|
||||
* TWI_SendByte(0x01);
|
||||
* TWI_SendByte(0x02);
|
||||
* TWI_SendByte(0x03);
|
||||
*
|
||||
* // Must stop transmission afterwards to release the bus
|
||||
* TWI_StopTransmission();
|
||||
* }
|
||||
*
|
||||
* // Start a read session to device at address 0xA0, internal address 0xDC with a 10ms timeout
|
||||
* if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_WRITE, 10) == TWI_ERROR_NoError)
|
||||
* {
|
||||
* TWI_SendByte(0xDC);
|
||||
* TWI_StopTransmission();
|
||||
*
|
||||
* if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_READ, 10) == TWI_ERROR_NoError)
|
||||
* {
|
||||
* uint8_t Byte1, Byte2, Byte3;
|
||||
*
|
||||
* // Read three bytes, acknowledge after the third byte is received
|
||||
* TWI_ReceiveByte(&Byte1, false);
|
||||
* TWI_ReceiveByte(&Byte2, false);
|
||||
* TWI_ReceiveByte(&Byte3, true);
|
||||
*
|
||||
* // Must stop transmission afterwards to release the bus
|
||||
* TWI_StopTransmission();
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* <b>High Level API Example:</b>
|
||||
* \code
|
||||
* // Initialize the TWI driver before first use at 200KHz
|
||||
* TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 200000));
|
||||
*
|
||||
* // Start a write session to device at device address 0xA0, internal address 0xDC with a 10ms timeout
|
||||
* uint8_t InternalWriteAddress = 0xDC;
|
||||
* uint8_t WritePacket[3] = {0x01, 0x02, 0x03};
|
||||
*
|
||||
* TWI_WritePacket(0xA0, 10, &InternalWriteAddress, sizeof(InternalWriteAddress),
|
||||
* &WritePacket, sizeof(WritePacket);
|
||||
*
|
||||
* // Start a read session to device at address 0xA0, internal address 0xDC with a 10ms timeout
|
||||
* uint8_t InternalReadAddress = 0xDC;
|
||||
* uint8_t ReadPacket[3];
|
||||
*
|
||||
* TWI_ReadPacket(0xA0, 10, &InternalReadAddress, sizeof(InternalReadAddress),
|
||||
* &ReadPacket, sizeof(ReadPacket);
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __TWI_AVR8_H__
|
||||
#define __TWI_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <util/twi.h>
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_TWI_H) && !defined(__INCLUDE_FROM_TWI_C)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Peripheral/TWI.h instead.
|
||||
#endif
|
||||
|
||||
#if !(defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
|
||||
defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \
|
||||
defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
#error The TWI peripheral driver is not currently available for your selected microcontroller model.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** TWI slave device address mask for a read session. Mask with a slave device base address to obtain
|
||||
* the correct TWI bus address for the slave device when reading data from it.
|
||||
*/
|
||||
#define TWI_ADDRESS_READ 0x01
|
||||
|
||||
/** TWI slave device address mask for a write session. Mask with a slave device base address to obtain
|
||||
* the correct TWI bus address for the slave device when writing data to it.
|
||||
*/
|
||||
#define TWI_ADDRESS_WRITE 0x00
|
||||
|
||||
/** Mask to retrieve the base address for a TWI device, which can then be ORed with \ref TWI_ADDRESS_READ
|
||||
* or \ref TWI_ADDRESS_WRITE to obtain the device's read and write address respectively.
|
||||
*/
|
||||
#define TWI_DEVICE_ADDRESS_MASK 0xFE
|
||||
|
||||
/** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 1. */
|
||||
#define TWI_BIT_PRESCALE_1 ((0 << TWPS1) | (0 << TWPS0))
|
||||
|
||||
/** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 4. */
|
||||
#define TWI_BIT_PRESCALE_4 ((0 << TWPS1) | (1 << TWPS0))
|
||||
|
||||
/** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 16. */
|
||||
#define TWI_BIT_PRESCALE_16 ((1 << TWPS1) | (0 << TWPS0))
|
||||
|
||||
/** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 64. */
|
||||
#define TWI_BIT_PRESCALE_64 ((1 << TWPS1) | (1 << TWPS0))
|
||||
|
||||
/** Calculates the length of each bit on the TWI bus for a given target frequency. This may be used with
|
||||
* the \ref TWI_Init() function to convert a bus frequency to a number of clocks for the \c BitLength
|
||||
* parameter.
|
||||
*
|
||||
* \param[in] Prescale Prescaler set on the TWI bus.
|
||||
* \param[in] Frequency Desired TWI bus frequency in Hz.
|
||||
*
|
||||
* \return Bit length in clocks for the given TWI bus frequency at the given prescaler value.
|
||||
*/
|
||||
#define TWI_BITLENGTH_FROM_FREQ(Prescale, Frequency) ((((F_CPU / (Prescale)) / (Frequency)) - 16) / 2)
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible return codes of the TWI transfer start routine and other dependant TWI functions. */
|
||||
enum TWI_ErrorCodes_t
|
||||
{
|
||||
TWI_ERROR_NoError = 0, /**< Indicates that the command completed successfully. */
|
||||
TWI_ERROR_BusFault = 1, /**< A TWI bus fault occurred while attempting to capture the bus. */
|
||||
TWI_ERROR_BusCaptureTimeout = 2, /**< A timeout occurred whilst waiting for the bus to be ready. */
|
||||
TWI_ERROR_SlaveResponseTimeout = 3, /**< No ACK received at the nominated slave address within the timeout period. */
|
||||
TWI_ERROR_SlaveNotReady = 4, /**< Slave NAKed the TWI bus START condition. */
|
||||
TWI_ERROR_SlaveNAK = 5, /**< Slave NAKed whilst attempting to send data to the device. */
|
||||
};
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Initializes the TWI hardware into master mode, ready for data transmission and reception. This must be
|
||||
* before any other TWI operations.
|
||||
*
|
||||
* The generated SCL frequency will be according to the formula <pre>F_CPU / (16 + 2 * BitLength + 4 ^ Prescale)</pre>.
|
||||
*
|
||||
* \attention The value of the \c BitLength parameter should not be set below 10 or invalid bus conditions may
|
||||
* occur, as indicated in the AVR8 microcontroller datasheet.
|
||||
*
|
||||
* \param[in] Prescale Prescaler to use when determining the bus frequency, a \c TWI_BIT_PRESCALE_* value.
|
||||
* \param[in] BitLength Length of the bits sent on the bus.
|
||||
*/
|
||||
static inline void TWI_Init(const uint8_t Prescale,
|
||||
const uint8_t BitLength) ATTR_ALWAYS_INLINE;
|
||||
static inline void TWI_Init(const uint8_t Prescale,
|
||||
const uint8_t BitLength)
|
||||
{
|
||||
TWCR |= (1 << TWEN);
|
||||
TWSR = Prescale;
|
||||
TWBR = BitLength;
|
||||
}
|
||||
|
||||
/** Turns off the TWI driver hardware. If this is called, any further TWI operations will require a call to
|
||||
* \ref TWI_Init() before the TWI can be used again.
|
||||
*/
|
||||
static inline void TWI_Disable(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void TWI_Disable(void)
|
||||
{
|
||||
TWCR &= ~(1 << TWEN);
|
||||
}
|
||||
|
||||
/** Sends a TWI STOP onto the TWI bus, terminating communication with the currently addressed device. */
|
||||
static inline void TWI_StopTransmission(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void TWI_StopTransmission(void)
|
||||
{
|
||||
TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN));
|
||||
}
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Begins a master mode TWI bus communication with the given slave device address.
|
||||
*
|
||||
* \param[in] SlaveAddress Address of the slave TWI device to communicate with.
|
||||
* \param[in] TimeoutMS Timeout period within which the slave must respond, in milliseconds.
|
||||
*
|
||||
* \return A value from the \ref TWI_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t TWI_StartTransmission(const uint8_t SlaveAddress,
|
||||
const uint8_t TimeoutMS);
|
||||
|
||||
/** Sends a byte to the currently addressed device on the TWI bus.
|
||||
*
|
||||
* \param[in] Byte Byte to send to the currently addressed device
|
||||
*
|
||||
* \return Boolean \c true if the recipient ACKed the byte, \c false otherwise
|
||||
*/
|
||||
bool TWI_SendByte(const uint8_t Byte);
|
||||
|
||||
/** Receives a byte from the currently addressed device on the TWI bus.
|
||||
*
|
||||
* \param[in] Byte Location where the read byte is to be stored.
|
||||
* \param[in] LastByte Indicates if the byte should be ACKed if false, NAKed if true.
|
||||
*
|
||||
* \return Boolean \c true if the byte reception successfully completed, \c false otherwise.
|
||||
*/
|
||||
bool TWI_ReceiveByte(uint8_t* const Byte,
|
||||
const bool LastByte) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** High level function to perform a complete packet transfer over the TWI bus to the specified
|
||||
* device.
|
||||
*
|
||||
* \param[in] SlaveAddress Base address of the TWI slave device to communicate with.
|
||||
* \param[in] TimeoutMS Timeout for bus capture and slave START ACK, in milliseconds.
|
||||
* \param[in] InternalAddress Pointer to a location where the internal slave read start address is stored.
|
||||
* \param[in] InternalAddressLen Size of the internal device address, in bytes.
|
||||
* \param[in] Buffer Pointer to a buffer where the read packet data is to be stored.
|
||||
* \param[in] Length Size of the packet to read, in bytes.
|
||||
*
|
||||
* \return A value from the \ref TWI_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t TWI_ReadPacket(const uint8_t SlaveAddress,
|
||||
const uint8_t TimeoutMS,
|
||||
const uint8_t* InternalAddress,
|
||||
uint8_t InternalAddressLen,
|
||||
uint8_t* Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** High level function to perform a complete packet transfer over the TWI bus from the specified
|
||||
* device.
|
||||
*
|
||||
* \param[in] SlaveAddress Base address of the TWI slave device to communicate with
|
||||
* \param[in] TimeoutMS Timeout for bus capture and slave START ACK, in milliseconds
|
||||
* \param[in] InternalAddress Pointer to a location where the internal slave write start address is stored
|
||||
* \param[in] InternalAddressLen Size of the internal device address, in bytes
|
||||
* \param[in] Buffer Pointer to a buffer where the packet data to send is stored
|
||||
* \param[in] Length Size of the packet to send, in bytes
|
||||
*
|
||||
* \return A value from the \ref TWI_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t TWI_WritePacket(const uint8_t SlaveAddress,
|
||||
const uint8_t TimeoutMS,
|
||||
const uint8_t* InternalAddress,
|
||||
uint8_t InternalAddressLen,
|
||||
const uint8_t* Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
76
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/SPI.h
Normal file
76
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/SPI.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Hardware Serial Peripheral Interface driver.
|
||||
*
|
||||
* This file is the master dispatch header file for the device-specific SPI driver, for microcontrollers
|
||||
* containing a hardware SPI.
|
||||
*
|
||||
* User code should include this file, which will in turn include the correct SPI driver header file for the
|
||||
* currently selected architecture and microcontroller model.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_PeripheralDrivers
|
||||
* \defgroup Group_SPI SPI Driver - LUFA/Drivers/Peripheral/SPI.h
|
||||
* \brief Hardware Serial Peripheral Interface driver.
|
||||
*
|
||||
* \section Sec_SPI_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - None
|
||||
*
|
||||
* \section Sec_SPI_ModDescription Module Description
|
||||
* Hardware SPI driver. This module provides an easy to use driver for the setup and transfer of data over
|
||||
* the selected architecture and microcontroller model's SPI port.
|
||||
*
|
||||
* \note The exact API for this driver may vary depending on the target used - see
|
||||
* individual target module documentation for the API specific to your target processor.
|
||||
*/
|
||||
|
||||
#ifndef __SPI_H__
|
||||
#define __SPI_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_SPI_H
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
/* Includes: */
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
#include "AVR8/SPI_AVR8.h"
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
#include "XMEGA/SPI_XMEGA.h"
|
||||
#else
|
||||
#error The SPI peripheral driver is not currently available for your selected architecture.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
76
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/Serial.h
Normal file
76
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/Serial.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Hardware Serial USART driver.
|
||||
*
|
||||
* This file is the master dispatch header file for the device-specific USART driver, for microcontrollers
|
||||
* containing a hardware USART.
|
||||
*
|
||||
* User code should include this file, which will in turn include the correct ADC driver header file for the
|
||||
* currently selected architecture and microcontroller model.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_PeripheralDrivers
|
||||
* \defgroup Group_Serial Serial USART Driver - LUFA/Drivers/Peripheral/Serial.h
|
||||
* \brief Hardware Serial USART driver.
|
||||
*
|
||||
* \section Sec_Serial_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/Peripheral/<i>ARCH</i>/Serial_<i>ARCH</i>.c <i>(Makefile source module name: LUFA_SRC_SERIAL)</i>
|
||||
*
|
||||
* \section Sec_Serial_ModDescription Module Description
|
||||
* Hardware serial USART driver. This module provides an easy to use driver for the setup and transfer
|
||||
* of data over the selected architecture and microcontroller model's USART port.
|
||||
*
|
||||
* \note The exact API for this driver may vary depending on the target used - see
|
||||
* individual target module documentation for the API specific to your target processor.
|
||||
*/
|
||||
|
||||
#ifndef __SERIAL_H__
|
||||
#define __SERIAL_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_SERIAL_H
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
/* Includes: */
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
#include "AVR8/Serial_AVR8.h"
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
#include "XMEGA/Serial_XMEGA.h"
|
||||
#else
|
||||
#error The Serial peripheral driver is not currently available for your selected architecture.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Hardware SPI Master Mode Serial USART driver.
|
||||
*
|
||||
* This file is the master dispatch header file for the device-specific SPI Master Mode USART driver, for
|
||||
* microcontrollers containing a hardware USART capable of operating in a Master SPI mode.
|
||||
*
|
||||
* User code should include this file, which will in turn include the correct ADC driver header file for the
|
||||
* currently selected architecture and microcontroller model.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_PeripheralDrivers
|
||||
* \defgroup Group_SerialSPI Master SPI Mode Serial USART Driver - LUFA/Drivers/Peripheral/SerialSPI.h
|
||||
* \brief Hardware SPI Master Mode Serial USART driver.
|
||||
*
|
||||
* \section Sec_SerialSPI_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - None
|
||||
*
|
||||
* \section Sec_SerialSPI_ModDescription Module Description
|
||||
* Hardware SPI Master Mode serial USART driver. This module provides an easy to use driver for the setup and transfer
|
||||
* of data over the selected architecture and microcontroller model's USART port, using a SPI framing format.
|
||||
*
|
||||
* \note The exact API for this driver may vary depending on the target used - see
|
||||
* individual target module documentation for the API specific to your target processor.
|
||||
*/
|
||||
|
||||
#ifndef __SERIAL_SPI_H__
|
||||
#define __SERIAL_SPI_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_SERIAL_SPI_H
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
/* Includes: */
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
#include "AVR8/SerialSPI_AVR8.h"
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
#include "XMEGA/SerialSPI_XMEGA.h"
|
||||
#else
|
||||
#error The Serial SPI Master Mode peripheral driver is not currently available for your selected architecture.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
76
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/TWI.h
Normal file
76
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/Peripheral/TWI.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2020.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2020 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Hardware Two Wire Interface (I2C) driver.
|
||||
*
|
||||
* This file is the master dispatch header file for the device-specific SPI driver, for microcontrollers
|
||||
* containing a hardware TWI.
|
||||
*
|
||||
* User code should include this file, which will in turn include the correct TWI driver header file for the
|
||||
* currently selected architecture and microcontroller model.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_PeripheralDrivers
|
||||
* \defgroup Group_TWI TWI Driver - LUFA/Drivers/Peripheral/TWI.h
|
||||
* \brief Hardware Two Wire Interface (I2C) driver.
|
||||
*
|
||||
* \section Sec_TWI_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/Peripheral/<i>ARCH</i>/TWI_<i>ARCH</i>.c <i>(Makefile source module name: LUFA_SRC_TWI)</i>
|
||||
*
|
||||
* \section Sec_TWI_ModDescription Module Description
|
||||
* Hardware TWI driver. This module provides an easy to use driver for the setup and transfer of data over
|
||||
* the selected architecture and microcontroller model's TWI bus port.
|
||||
*
|
||||
* \note The exact API for this driver may vary depending on the target used - see
|
||||
* individual target module documentation for the API specific to your target processor.
|
||||
*/
|
||||
|
||||
#ifndef __TWI_H__
|
||||
#define __TWI_H__
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_TWI_H
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Common/Common.h"
|
||||
|
||||
/* Includes: */
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
#include "AVR8/TWI_AVR8.h"
|
||||
#elif (ARCH == ARCH_XMEGA)
|
||||
#include "XMEGA/TWI_XMEGA.h"
|
||||
#else
|
||||
#error The TWI peripheral driver is not currently available for your selected architecture.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB Android Open Accessory Class driver.
|
||||
*
|
||||
* Master include file for the library USB Android Open Accessory Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassAOA Android Open Accessory Class Driver
|
||||
* \brief USB class driver for the Google Android Open Accessory class standard.
|
||||
*
|
||||
* \section Sec_USBClassAOA_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassAOA_ModDescription Module Description
|
||||
* Android Open Accessory Class Driver module. This module contains an internal implementation of the USB Android Open Accessory
|
||||
* Class, for Host USB mode. User applications can use this class driver instead of implementing the Android Open Accessory Class
|
||||
* manually via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Host using the USB Android Open Accessory Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _AOA_CLASS_H_
|
||||
#define _AOA_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_AOA_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/AndroidAccessoryClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB Audio 1.0 Class driver.
|
||||
*
|
||||
* Master include file for the library USB Audio 1.0 Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassAudio Audio 1.0 Class Driver
|
||||
* \brief USB class driver for the USB-IF Audio 1.0 class standard.
|
||||
*
|
||||
* \section Sec_USBClassAudio_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/AudioClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassAudio_ModDescription Module Description
|
||||
* Audio 1.0 Class Driver module. This module contains an internal implementation of the USB Audio 1.0 Class, for both
|
||||
* Device and Host USB modes. User applications can use this class driver instead of implementing the Audio 1.0 class
|
||||
* manually via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Hosts or Devices using the USB Audio 1.0 Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_CLASS_H_
|
||||
#define _AUDIO_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_AUDIO_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "Device/AudioClassDevice.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/AudioClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
81
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Class/CDCClass.h
Normal file
81
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Class/CDCClass.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB CDC-ACM Class driver.
|
||||
*
|
||||
* Master include file for the library USB CDC Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassCDC CDC-ACM (Virtual Serial) Class Driver
|
||||
* \brief USB class driver for the USB-IF CDC-ACM (Virtual Serial) class standard.
|
||||
*
|
||||
* \section Sec_USBClassCDC_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/CDCClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassCDC_ModDescription Module Description
|
||||
* CDC Class Driver module. This module contains an internal implementation of the USB CDC-ACM class Virtual Serial
|
||||
* Ports, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
|
||||
* CDC class manually via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Hosts or Devices using the USB CDC Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CDC_CLASS_H_
|
||||
#define _CDC_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_CDC_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "Device/CDCClassDevice.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/CDCClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB Android Open Accessory Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB Android Open Accessory Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassAOA
|
||||
* \defgroup Group_USBClassAOACommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassAOACommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* Android Open Accessory Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _AOA_CLASS_COMMON_H_
|
||||
#define _AOA_CLASS_COMMON_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_AOA_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory mode. */
|
||||
#define ANDROID_ACCESSORY_PRODUCT_ID 0x2D00
|
||||
|
||||
/** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory and Android Debug mode. */
|
||||
#define ANDROID_ACCESSORY_ADB_PRODUCT_ID 0x2D01
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the
|
||||
* Android Open Accessory class.
|
||||
*/
|
||||
enum AOA_Descriptor_ClassSubclassProtocol_t
|
||||
{
|
||||
AOA_CSCP_AOADataClass = 0xFF, /**< Descriptor Class value indicating that the device or interface
|
||||
* belongs to the AOA data class.
|
||||
*/
|
||||
AOA_CSCP_AOADataSubclass = 0xFF, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* belongs to AOA data subclass.
|
||||
*/
|
||||
AOA_CSCP_AOADataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to the AOA data class protocol.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the Android Open Accessory class specific control requests that can be issued by the USB bus host. */
|
||||
enum AOA_ClassRequests_t
|
||||
{
|
||||
AOA_REQ_GetAccessoryProtocol = 0x33, /**< Android Open Accessory control request to retrieve the device's supported Accessory Protocol version. */
|
||||
AOA_REQ_SendString = 0x34, /**< Android Open Accessory control request to set an accessory property string in the device. */
|
||||
AOA_REQ_StartAccessoryMode = 0x35, /**< Android Open Accessory control request to switch the device into Accessory mode. */
|
||||
};
|
||||
|
||||
/** Enum for the possible Android Open Accessory property string indexes. */
|
||||
enum AOA_Strings_t
|
||||
{
|
||||
AOA_STRING_Manufacturer = 0, /**< Index of the Manufacturer property string. */
|
||||
AOA_STRING_Model = 1, /**< Index of the Model Name property string. */
|
||||
AOA_STRING_Description = 2, /**< Index of the Description property string. */
|
||||
AOA_STRING_Version = 3, /**< Index of the Version Number property string. */
|
||||
AOA_STRING_URI = 4, /**< Index of the URI Information property string. */
|
||||
AOA_STRING_Serial = 5, /**< Index of the Serial Number property string. */
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
AOA_STRING_TOTAL_STRINGS
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Enum for the possible Android Open Accessory protocol versions. */
|
||||
enum AOA_Protocols_t
|
||||
{
|
||||
AOA_PROTOCOL_AccessoryV1 = 0x0001, /**< Android Open Accessory version 1. */
|
||||
AOA_PROTOCOL_AccessoryV2 = 0x0002, /**< Android Open Accessory version 2. */
|
||||
};
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -0,0 +1,780 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB Audio 1.0 Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB Audio 1.0 Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassAudio
|
||||
* \defgroup Group_USBClassAudioCommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassAudioCommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* Audio 1.0 Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_CLASS_COMMON_H_
|
||||
#define _AUDIO_CLASS_COMMON_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** \name Audio Channel Masks */
|
||||
//@{
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_LEFT_FRONT (1 << 0)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_RIGHT_FRONT (1 << 1)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_CENTER_FRONT (1 << 2)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_LOW_FREQ_ENHANCE (1 << 3)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_LEFT_SURROUND (1 << 4)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_RIGHT_SURROUND (1 << 5)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_LEFT_OF_CENTER (1 << 6)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_RIGHT_OF_CENTER (1 << 7)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_SURROUND (1 << 8)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_SIDE_LEFT (1 << 9)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_SIDE_RIGHT (1 << 10)
|
||||
|
||||
/** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_CHANNEL_TOP (1 << 11)
|
||||
//@}
|
||||
|
||||
/** \name Audio Feature Masks */
|
||||
//@{
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_MUTE (1 << 0)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_VOLUME (1 << 1)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_BASS (1 << 2)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_MID (1 << 3)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_TREBLE (1 << 4)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_GRAPHIC_EQUALIZER (1 << 5)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_AUTOMATIC_GAIN (1 << 6)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_DELAY (1 << 7)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_BASS_BOOST (1 << 8)
|
||||
|
||||
/** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_FEATURE_BASS_LOUDNESS (1 << 9)
|
||||
//@}
|
||||
|
||||
/** \name Audio Terminal Types */
|
||||
//@{
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_UNDEFINED 0x0100
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_STREAMING 0x0101
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_VENDOR 0x01FF
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_UNDEFINED 0x0200
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_MIC 0x0201
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_DESKTOP_MIC 0x0202
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_PERSONAL_MIC 0x0203
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_OMNIDIR_MIC 0x0204
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_MIC_ARRAY 0x0205
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_PROCESSING_MIC 0x0206
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_IN_OUT_UNDEFINED 0x0300
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_OUT_SPEAKER 0x0301
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_OUT_HEADPHONES 0x0302
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_OUT_HEAD_MOUNTED 0x0303
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_OUT_DESKTOP 0x0304
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_OUT_ROOM 0x0305
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_OUT_COMMUNICATION 0x0306
|
||||
|
||||
/** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
|
||||
#define AUDIO_TERMINAL_OUT_LOWFREQ 0x0307
|
||||
//@}
|
||||
|
||||
/** Convenience macro to fill a 24-bit \ref USB_Audio_SampleFreq_t structure with the given sample rate as a 24-bit number.
|
||||
*
|
||||
* \param[in] freq Required audio sampling frequency in HZ
|
||||
*/
|
||||
#define AUDIO_SAMPLE_FREQ(freq) {.Byte1 = ((uint32_t)freq & 0xFF), .Byte2 = (((uint32_t)freq >> 8) & 0xFF), .Byte3 = (((uint32_t)freq >> 16) & 0xFF)}
|
||||
|
||||
/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
|
||||
* accepts only filled endpoint packets of audio samples.
|
||||
*/
|
||||
#define AUDIO_EP_FULL_PACKETS_ONLY (1 << 7)
|
||||
|
||||
/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
|
||||
* will accept partially filled endpoint packets of audio samples.
|
||||
*/
|
||||
#define AUDIO_EP_ACCEPTS_SMALL_PACKETS (0 << 7)
|
||||
|
||||
/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
|
||||
* allows for sampling frequency adjustments to be made via control requests directed at the endpoint.
|
||||
*/
|
||||
#define AUDIO_EP_SAMPLE_FREQ_CONTROL (1 << 0)
|
||||
|
||||
/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
|
||||
* allows for pitch adjustments to be made via control requests directed at the endpoint.
|
||||
*/
|
||||
#define AUDIO_EP_PITCH_CONTROL (1 << 1)
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Audio
|
||||
* device class.
|
||||
*/
|
||||
enum Audio_Descriptor_ClassSubclassProtocol_t
|
||||
{
|
||||
AUDIO_CSCP_AudioClass = 0x01, /**< Descriptor Class value indicating that the device or
|
||||
* interface belongs to the USB Audio 1.0 class.
|
||||
*/
|
||||
AUDIO_CSCP_ControlSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or
|
||||
* interface belongs to the Audio Control subclass.
|
||||
*/
|
||||
AUDIO_CSCP_ControlProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or
|
||||
* interface belongs to the Audio Control protocol.
|
||||
*/
|
||||
AUDIO_CSCP_AudioStreamingSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or
|
||||
* interface belongs to the MIDI Streaming subclass.
|
||||
*/
|
||||
AUDIO_CSCP_MIDIStreamingSubclass = 0x03, /**< Descriptor Subclass value indicating that the device or
|
||||
* interface belongs to the Audio streaming subclass.
|
||||
*/
|
||||
AUDIO_CSCP_StreamingProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or
|
||||
* interface belongs to the Streaming Audio protocol.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Audio class specific interface description subtypes, for the Audio Control interface. */
|
||||
enum Audio_CSInterface_AC_SubTypes_t
|
||||
{
|
||||
AUDIO_DSUBTYPE_CSInterface_Header = 0x01, /**< Audio class specific control interface header. */
|
||||
AUDIO_DSUBTYPE_CSInterface_InputTerminal = 0x02, /**< Audio class specific control interface Input Terminal. */
|
||||
AUDIO_DSUBTYPE_CSInterface_OutputTerminal = 0x03, /**< Audio class specific control interface Output Terminal. */
|
||||
AUDIO_DSUBTYPE_CSInterface_Mixer = 0x04, /**< Audio class specific control interface Mixer Unit. */
|
||||
AUDIO_DSUBTYPE_CSInterface_Selector = 0x05, /**< Audio class specific control interface Selector Unit. */
|
||||
AUDIO_DSUBTYPE_CSInterface_Feature = 0x06, /**< Audio class specific control interface Feature Unit. */
|
||||
AUDIO_DSUBTYPE_CSInterface_Processing = 0x07, /**< Audio class specific control interface Processing Unit. */
|
||||
AUDIO_DSUBTYPE_CSInterface_Extension = 0x08, /**< Audio class specific control interface Extension Unit. */
|
||||
};
|
||||
|
||||
/** Audio class specific interface description subtypes, for the Audio Streaming interface. */
|
||||
enum Audio_CSInterface_AS_SubTypes_t
|
||||
{
|
||||
AUDIO_DSUBTYPE_CSInterface_General = 0x01, /**< Audio class specific streaming interface general descriptor. */
|
||||
AUDIO_DSUBTYPE_CSInterface_FormatType = 0x02, /**< Audio class specific streaming interface format type descriptor. */
|
||||
AUDIO_DSUBTYPE_CSInterface_FormatSpecific = 0x03, /**< Audio class specific streaming interface format information descriptor. */
|
||||
};
|
||||
|
||||
/** Audio class specific endpoint description subtypes, for the Audio Streaming interface. */
|
||||
enum Audio_CSEndpoint_SubTypes_t
|
||||
{
|
||||
AUDIO_DSUBTYPE_CSEndpoint_General = 0x01, /**< Audio class specific endpoint general descriptor. */
|
||||
};
|
||||
|
||||
/** Enum for the Audio class specific control requests that can be issued by the USB bus host. */
|
||||
enum Audio_ClassRequests_t
|
||||
{
|
||||
AUDIO_REQ_SetCurrent = 0x01, /**< Audio class-specific request to set the current value of a parameter within the device. */
|
||||
AUDIO_REQ_SetMinimum = 0x02, /**< Audio class-specific request to set the minimum value of a parameter within the device. */
|
||||
AUDIO_REQ_SetMaximum = 0x03, /**< Audio class-specific request to set the maximum value of a parameter within the device. */
|
||||
AUDIO_REQ_SetResolution = 0x04, /**< Audio class-specific request to set the resolution value of a parameter within the device. */
|
||||
AUDIO_REQ_SetMemory = 0x05, /**< Audio class-specific request to set the memory value of a parameter within the device. */
|
||||
AUDIO_REQ_GetCurrent = 0x81, /**< Audio class-specific request to get the current value of a parameter within the device. */
|
||||
AUDIO_REQ_GetMinimum = 0x82, /**< Audio class-specific request to get the minimum value of a parameter within the device. */
|
||||
AUDIO_REQ_GetMaximum = 0x83, /**< Audio class-specific request to get the maximum value of a parameter within the device. */
|
||||
AUDIO_REQ_GetResolution = 0x84, /**< Audio class-specific request to get the resolution value of a parameter within the device. */
|
||||
AUDIO_REQ_GetMemory = 0x85, /**< Audio class-specific request to get the memory value of a parameter within the device. */
|
||||
AUDIO_REQ_GetStatus = 0xFF, /**< Audio class-specific request to get the device status. */
|
||||
};
|
||||
|
||||
/** Enum for Audio class specific Endpoint control modifiers which can be set and retrieved by a USB host, if the corresponding
|
||||
* endpoint control is indicated to be supported in the Endpoint's Audio-class specific endpoint descriptor.
|
||||
*/
|
||||
enum Audio_EndpointControls_t
|
||||
{
|
||||
AUDIO_EPCONTROL_SamplingFreq = 0x01, /**< Sampling frequency adjustment of the endpoint. */
|
||||
AUDIO_EPCONTROL_Pitch = 0x02, /**< Pitch adjustment of the endpoint. */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief Audio class-specific Input Terminal Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device
|
||||
* contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example,
|
||||
* a USB endpoint). See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_InputTerminal_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal.
|
||||
*/
|
||||
|
||||
uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
|
||||
uint16_t TerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */
|
||||
uint8_t AssociatedOutputTerminal; /**< ID of associated output terminal, for physically grouped terminals
|
||||
* such as the speaker and microphone of a phone handset.
|
||||
*/
|
||||
uint8_t TotalChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */
|
||||
uint16_t ChannelConfig; /**< \c CHANNEL_* masks indicating what channel layout is supported by this terminal. */
|
||||
|
||||
uint8_t ChannelStrIndex; /**< Index of a string descriptor describing this channel within the device. */
|
||||
uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_Audio_Descriptor_InputTerminal_t;
|
||||
|
||||
/** \brief Audio class-specific Input Terminal Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device
|
||||
* contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example,
|
||||
* a USB endpoint). See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_InputTerminal_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal.
|
||||
*/
|
||||
uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
|
||||
uint16_t wTerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */
|
||||
uint8_t bAssocTerminal; /**< ID of associated output terminal, for physically grouped terminals
|
||||
* such as the speaker and microphone of a phone handset.
|
||||
*/
|
||||
uint8_t bNrChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */
|
||||
uint16_t wChannelConfig; /**< \c CHANNEL_* masks indicating what channel layout is supported by this terminal. */
|
||||
|
||||
uint8_t iChannelNames; /**< Index of a string descriptor describing this channel within the device. */
|
||||
uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_InputTerminal_t;
|
||||
|
||||
/** \brief Audio class-specific Output Terminal Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device
|
||||
* contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example,
|
||||
* a USB endpoint). See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_OutputTerminal_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal.
|
||||
*/
|
||||
|
||||
uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
|
||||
uint16_t TerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */
|
||||
uint8_t AssociatedInputTerminal; /**< ID of associated input terminal, for physically grouped terminals
|
||||
* such as the speaker and microphone of a phone handset.
|
||||
*/
|
||||
uint8_t SourceID; /**< ID value of the unit this terminal's audio is sourced from. */
|
||||
|
||||
uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_Audio_Descriptor_OutputTerminal_t;
|
||||
|
||||
/** \brief Audio class-specific Output Terminal Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device
|
||||
* contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example,
|
||||
* a USB endpoint). See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_OutputTerminal_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSInterface_AC_SubTypes_t enum.
|
||||
*/
|
||||
uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
|
||||
uint16_t wTerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */
|
||||
uint8_t bAssocTerminal; /**< ID of associated input terminal, for physically grouped terminals
|
||||
* such as the speaker and microphone of a phone handset.
|
||||
*/
|
||||
uint8_t bSourceID; /**< ID value of the unit this terminal's audio is sourced from. */
|
||||
|
||||
uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_OutputTerminal_t;
|
||||
|
||||
/** \brief Audio class-specific Interface Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to
|
||||
* supply extra information about the audio device's layout to the host. See the USB Audio specification for more
|
||||
* details.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_Interface_AC_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
|
||||
*/
|
||||
|
||||
uint16_t ACSpecification; /**< Binary Coded Decimal value, indicating the supported Audio Class specification version.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
|
||||
|
||||
uint8_t InCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */
|
||||
uint8_t InterfaceNumber; /**< Interface number of the associated Audio Streaming interface. */
|
||||
} ATTR_PACKED USB_Audio_Descriptor_Interface_AC_t;
|
||||
|
||||
/** \brief Audio class-specific Interface Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to
|
||||
* supply extra information about the audio device's layout to the host. See the USB Audio specification for more
|
||||
* details.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_Interface_AC_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
|
||||
*/
|
||||
|
||||
uint16_t bcdADC; /**< Binary coded decimal value, indicating the supported Audio Class specification version.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
|
||||
|
||||
uint8_t bInCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */
|
||||
uint8_t bInterfaceNumbers; /**< Interface number of the associated Audio Streaming interface. */
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_Interface_AC_t;
|
||||
|
||||
/** \brief Audio class-specific Feature Unit Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features
|
||||
* are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio
|
||||
* specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_FeatureUnit_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_Feature.
|
||||
*/
|
||||
|
||||
uint8_t UnitID; /**< ID value of this feature unit - must be a unique value within the device. */
|
||||
uint8_t SourceID; /**< Source ID value of the audio source input into this feature unit. */
|
||||
|
||||
uint8_t ControlSize; /**< Size of each element in the \c ChannelControls array. */
|
||||
uint8_t ChannelControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */
|
||||
|
||||
uint8_t FeatureUnitStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_Audio_Descriptor_FeatureUnit_t;
|
||||
|
||||
/** \brief Audio class-specific Feature Unit Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features
|
||||
* are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio
|
||||
* specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_FeatureUnit_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_Feature.
|
||||
*/
|
||||
|
||||
uint8_t bUnitID; /**< ID value of this feature unit - must be a unique value within the device. */
|
||||
uint8_t bSourceID; /**< Source ID value of the audio source input into this feature unit. */
|
||||
|
||||
uint8_t bControlSize; /**< Size of each element in the \c ChannelControls array. */
|
||||
uint8_t bmaControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */
|
||||
|
||||
uint8_t iFeature; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_FeatureUnit_t;
|
||||
|
||||
/** \brief Audio class-specific Streaming Audio Interface Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific streaming interface descriptor. This indicates to the host
|
||||
* how audio streams within the device are formatted. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_Interface_AS_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
|
||||
*/
|
||||
|
||||
uint8_t TerminalLink; /**< ID value of the output terminal this descriptor is describing. */
|
||||
|
||||
uint8_t FrameDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */
|
||||
uint16_t AudioFormat; /**< Format of the audio stream, see Audio Device Formats specification. */
|
||||
} ATTR_PACKED USB_Audio_Descriptor_Interface_AS_t;
|
||||
|
||||
/** \brief Audio class-specific Streaming Audio Interface Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific streaming interface descriptor. This indicates to the host
|
||||
* how audio streams within the device are formatted. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_Interface_AS_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
|
||||
*/
|
||||
|
||||
uint8_t bTerminalLink; /**< ID value of the output terminal this descriptor is describing. */
|
||||
|
||||
uint8_t bDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */
|
||||
uint16_t wFormatTag; /**< Format of the audio stream, see Audio Device Formats specification. */
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_Interface_AS_t;
|
||||
|
||||
/** \brief Audio class-specific Format Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
|
||||
* about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used
|
||||
* in the device's audio streams. See the USB Audio specification for more details.
|
||||
*
|
||||
* \attention This descriptor <b>must</b> be followed by one or more \ref USB_Audio_SampleFreq_t elements containing
|
||||
* the continuous or discrete sample frequencies.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_Format_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType.
|
||||
*/
|
||||
|
||||
uint8_t FormatType; /**< Format of the audio stream, see Audio Device Formats specification. */
|
||||
uint8_t Channels; /**< Total number of discrete channels in the stream. */
|
||||
|
||||
uint8_t SubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */
|
||||
uint8_t BitResolution; /**< Bits of resolution of each channel's samples in the stream. */
|
||||
|
||||
uint8_t TotalDiscreteSampleRates; /**< Total number of discrete sample frequencies supported by the device. When
|
||||
* zero, this must be followed by the lower and upper continuous sampling
|
||||
* frequencies supported by the device; otherwise, this must be followed
|
||||
* by the given number of discrete sampling frequencies supported.
|
||||
*/
|
||||
} ATTR_PACKED USB_Audio_Descriptor_Format_t;
|
||||
|
||||
/** \brief 24-Bit Audio Frequency Structure.
|
||||
*
|
||||
* Type define for a 24-bit audio sample frequency structure. As GCC does not contain a built in 24-bit datatype,
|
||||
* this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Byte1; /**< Lowest 8 bits of the 24-bit value. */
|
||||
uint8_t Byte2; /**< Middle 8 bits of the 24-bit value. */
|
||||
uint8_t Byte3; /**< Upper 8 bits of the 24-bit value. */
|
||||
} ATTR_PACKED USB_Audio_SampleFreq_t;
|
||||
|
||||
/** \brief Audio class-specific Format Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
|
||||
* about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used
|
||||
* in the device's audio streams. See the USB Audio specification for more details.
|
||||
*
|
||||
* \attention This descriptor <b>must</b> be followed by one or more 24-bit integer elements containing the continuous
|
||||
* or discrete sample frequencies.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_Format_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
|
||||
*/
|
||||
|
||||
uint8_t bFormatType; /**< Format of the audio stream, see Audio Device Formats specification. */
|
||||
uint8_t bNrChannels; /**< Total number of discrete channels in the stream. */
|
||||
|
||||
uint8_t bSubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */
|
||||
uint8_t bBitResolution; /**< Bits of resolution of each channel's samples in the stream. */
|
||||
|
||||
uint8_t bSampleFrequencyType; /**< Total number of sample frequencies supported by the device. When
|
||||
* zero, this must be followed by the lower and upper continuous sampling
|
||||
* frequencies supported by the device; otherwise, this must be followed
|
||||
* by the given number of discrete sampling frequencies supported.
|
||||
*/
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_Format_t;
|
||||
|
||||
/** \brief Audio class-specific Streaming Endpoint Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint
|
||||
* descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Std_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Endpoint_t Endpoint; /**< Standard endpoint descriptor describing the audio endpoint. */
|
||||
|
||||
uint8_t Refresh; /**< Always set to zero for Audio class devices. */
|
||||
uint8_t SyncEndpointNumber; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */
|
||||
} ATTR_PACKED USB_Audio_Descriptor_StreamEndpoint_Std_t;
|
||||
|
||||
/** \brief Audio class-specific Streaming Endpoint Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint
|
||||
* descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_StreamEndpoint_Std_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a
|
||||
* value given by the specific class.
|
||||
*/
|
||||
uint8_t bEndpointAddress; /**< Logical address of the endpoint within the device for the current
|
||||
* configuration, including direction mask.
|
||||
*/
|
||||
uint8_t bmAttributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (\c EP_TYPE_*)
|
||||
* and attributes (\c ENDPOINT_ATTR_*) masks.
|
||||
*/
|
||||
uint16_t wMaxPacketSize; /**< Size of the endpoint bank, in bytes. This indicates the maximum packet size
|
||||
* that the endpoint can receive at a time.
|
||||
*/
|
||||
uint8_t bInterval; /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT or
|
||||
* ISOCHRONOUS type.
|
||||
*/
|
||||
|
||||
uint8_t bRefresh; /**< Always set to zero for Audio class devices. */
|
||||
uint8_t bSynchAddress; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_StreamEndpoint_Std_t;
|
||||
|
||||
/** \brief Audio class-specific Extended Endpoint Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific extended endpoint descriptor. This contains extra information
|
||||
* on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio
|
||||
* class-specific extended endpoint descriptor. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Spc_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSEndpoint_SubTypes_t enum.
|
||||
*/
|
||||
|
||||
uint8_t Attributes; /**< Audio class-specific endpoint attributes, such as \ref AUDIO_EP_FULL_PACKETS_ONLY. */
|
||||
|
||||
uint8_t LockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */
|
||||
uint16_t LockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */
|
||||
} ATTR_PACKED USB_Audio_Descriptor_StreamEndpoint_Spc_t;
|
||||
|
||||
/** \brief Audio class-specific Extended Endpoint Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific extended endpoint descriptor. This contains extra information
|
||||
* on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio
|
||||
* class-specific extended endpoint descriptor. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_Audio_Descriptor_StreamEndpoint_Spc_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
|
||||
* a value from the \ref Audio_CSEndpoint_SubTypes_t enum.
|
||||
*/
|
||||
|
||||
uint8_t bmAttributes; /**< Audio class-specific endpoint attributes, such as \ref AUDIO_EP_FULL_PACKETS_ONLY. */
|
||||
|
||||
uint8_t bLockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */
|
||||
uint16_t wLockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */
|
||||
} ATTR_PACKED USB_Audio_StdDescriptor_StreamEndpoint_Spc_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB CDC Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB CDC Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassCDC
|
||||
* \defgroup Group_USBClassCDCCommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassCDCCommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* CDC Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CDC_CLASS_COMMON_H_
|
||||
#define _CDC_CLASS_COMMON_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** \name Virtual Control Line Masks */
|
||||
//@{
|
||||
/** Mask for the DTR handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request
|
||||
* from the host, to indicate that the DTR line state should be high.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_OUT_DTR (1 << 0)
|
||||
|
||||
/** Mask for the RTS handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request
|
||||
* from the host, to indicate that the RTS line state should be high.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_OUT_RTS (1 << 1)
|
||||
|
||||
/** Mask for the DCD handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
|
||||
* from the device to the host, to indicate that the DCD line state is currently high.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_IN_DCD (1 << 0)
|
||||
|
||||
/** Mask for the DSR handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
|
||||
* from the device to the host, to indicate that the DSR line state is currently high.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_IN_DSR (1 << 1)
|
||||
|
||||
/** Mask for the BREAK handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
|
||||
* from the device to the host, to indicate that the BREAK line state is currently high.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_IN_BREAK (1 << 2)
|
||||
|
||||
/** Mask for the RING handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
|
||||
* from the device to the host, to indicate that the RING line state is currently high.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_IN_RING (1 << 3)
|
||||
|
||||
/** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host,
|
||||
* to indicate that a framing error has occurred on the virtual serial port.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_IN_FRAMEERROR (1 << 4)
|
||||
|
||||
/** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host,
|
||||
* to indicate that a parity error has occurred on the virtual serial port.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_IN_PARITYERROR (1 << 5)
|
||||
|
||||
/** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host,
|
||||
* to indicate that a data overrun error has occurred on the virtual serial port.
|
||||
*/
|
||||
#define CDC_CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
|
||||
//@}
|
||||
|
||||
/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
|
||||
* uniform structure but variable sized data payloads, thus cannot be represented accurately by
|
||||
* a single \c typedef \c struct. A macro is used instead so that functional descriptors can be created
|
||||
* easily by specifying the size of the payload. This allows \c sizeof() to work correctly.
|
||||
*
|
||||
* \param[in] DataSize Size in bytes of the CDC functional descriptor's data payload.
|
||||
*/
|
||||
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
|
||||
struct \
|
||||
{ \
|
||||
USB_Descriptor_Header_t Header; \
|
||||
uint8_t SubType; \
|
||||
uint8_t Data[DataSize]; \
|
||||
}
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the CDC
|
||||
* device class.
|
||||
*/
|
||||
enum CDC_Descriptor_ClassSubclassProtocol_t
|
||||
{
|
||||
CDC_CSCP_CDCClass = 0x02, /**< Descriptor Class value indicating that the device or interface
|
||||
* belongs to the CDC class.
|
||||
*/
|
||||
CDC_CSCP_NoSpecificSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* belongs to no specific subclass of the CDC class.
|
||||
*/
|
||||
CDC_CSCP_ACMSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* belongs to the Abstract Control Model CDC subclass.
|
||||
*/
|
||||
CDC_CSCP_ATCommandProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to the AT Command protocol of the CDC class.
|
||||
*/
|
||||
CDC_CSCP_NoSpecificProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to no specific protocol of the CDC class.
|
||||
*/
|
||||
CDC_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to a vendor-specific protocol of the CDC class.
|
||||
*/
|
||||
CDC_CSCP_CDCDataClass = 0x0A, /**< Descriptor Class value indicating that the device or interface
|
||||
* belongs to the CDC Data class.
|
||||
*/
|
||||
CDC_CSCP_NoDataSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* belongs to no specific subclass of the CDC data class.
|
||||
*/
|
||||
CDC_CSCP_NoDataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to no specific protocol of the CDC data class.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the CDC class specific control requests that can be issued by the USB bus host. */
|
||||
enum CDC_ClassRequests_t
|
||||
{
|
||||
CDC_REQ_SendEncapsulatedCommand = 0x00, /**< CDC class-specific request to send an encapsulated command to the device. */
|
||||
CDC_REQ_GetEncapsulatedResponse = 0x01, /**< CDC class-specific request to retrieve an encapsulated command response from the device. */
|
||||
CDC_REQ_SetLineEncoding = 0x20, /**< CDC class-specific request to set the current virtual serial port configuration settings. */
|
||||
CDC_REQ_GetLineEncoding = 0x21, /**< CDC class-specific request to get the current virtual serial port configuration settings. */
|
||||
CDC_REQ_SetControlLineState = 0x22, /**< CDC class-specific request to set the current virtual serial port handshake line states. */
|
||||
CDC_REQ_SendBreak = 0x23, /**< CDC class-specific request to send a break to the receiver via the carrier channel. */
|
||||
};
|
||||
|
||||
/** Enum for the CDC class specific notification requests that can be issued by a CDC device to a host. */
|
||||
enum CDC_ClassNotifications_t
|
||||
{
|
||||
CDC_NOTIF_SerialState = 0x20, /**< Notification type constant for a change in the virtual serial port
|
||||
* handshake line states, for use with a \ref USB_Request_Header_t
|
||||
* notification structure when sent to the host via the CDC notification
|
||||
* endpoint.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the CDC class specific interface descriptor subtypes. */
|
||||
enum CDC_DescriptorSubtypes_t
|
||||
{
|
||||
CDC_DSUBTYPE_CSInterface_Header = 0x00, /**< CDC class-specific Header functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_CallManagement = 0x01, /**< CDC class-specific Call Management functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_ACM = 0x02, /**< CDC class-specific Abstract Control Model functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_DirectLine = 0x03, /**< CDC class-specific Direct Line functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_TelephoneRinger = 0x04, /**< CDC class-specific Telephone Ringer functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_TelephoneCall = 0x05, /**< CDC class-specific Telephone Call functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_Union = 0x06, /**< CDC class-specific Union functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_CountrySelection = 0x07, /**< CDC class-specific Country Selection functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_TelephoneOpModes = 0x08, /**< CDC class-specific Telephone Operation Modes functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_USBTerminal = 0x09, /**< CDC class-specific USB Terminal functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_NetworkChannel = 0x0A, /**< CDC class-specific Network Channel functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_ProtocolUnit = 0x0B, /**< CDC class-specific Protocol Unit functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_ExtensionUnit = 0x0C, /**< CDC class-specific Extension Unit functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_MultiChannel = 0x0D, /**< CDC class-specific Multi-Channel Management functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_CAPI = 0x0E, /**< CDC class-specific Common ISDN API functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_Ethernet = 0x0F, /**< CDC class-specific Ethernet functional descriptor. */
|
||||
CDC_DSUBTYPE_CSInterface_ATM = 0x10, /**< CDC class-specific Asynchronous Transfer Mode functional descriptor. */
|
||||
};
|
||||
|
||||
/** Enum for the possible line encoding formats of a virtual serial port. */
|
||||
enum CDC_LineEncodingFormats_t
|
||||
{
|
||||
CDC_LINEENCODING_OneStopBit = 0, /**< Each frame contains one stop bit. */
|
||||
CDC_LINEENCODING_OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits. */
|
||||
CDC_LINEENCODING_TwoStopBits = 2, /**< Each frame contains two stop bits. */
|
||||
};
|
||||
|
||||
/** Enum for the possible line encoding parity settings of a virtual serial port. */
|
||||
enum CDC_LineEncodingParity_t
|
||||
{
|
||||
CDC_PARITY_None = 0, /**< No parity bit mode on each frame. */
|
||||
CDC_PARITY_Odd = 1, /**< Odd parity bit mode on each frame. */
|
||||
CDC_PARITY_Even = 2, /**< Even parity bit mode on each frame. */
|
||||
CDC_PARITY_Mark = 3, /**< Mark parity bit mode on each frame. */
|
||||
CDC_PARITY_Space = 4, /**< Space parity bit mode on each frame. */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief CDC class-specific Functional Header Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device
|
||||
* contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration.
|
||||
* See the CDC class specification for more details.
|
||||
*
|
||||
* \see \ref USB_CDC_StdDescriptor_FunctionalHeader_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors,
|
||||
* must be \ref CDC_DSUBTYPE_CSInterface_Header.
|
||||
*/
|
||||
uint16_t CDCSpecification; /**< Version number of the CDC specification implemented by the device,
|
||||
* encoded in BCD format.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
} ATTR_PACKED USB_CDC_Descriptor_FunctionalHeader_t;
|
||||
|
||||
/** \brief CDC class-specific Functional Header Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device
|
||||
* contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration.
|
||||
* See the CDC class specification for more details.
|
||||
*
|
||||
* \see \ref USB_CDC_Descriptor_FunctionalHeader_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors,
|
||||
* must be \ref CDC_DSUBTYPE_CSInterface_Header.
|
||||
*/
|
||||
uint16_t bcdCDC; /**< Version number of the CDC specification implemented by the device, encoded in BCD format.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
} ATTR_PACKED USB_CDC_StdDescriptor_FunctionalHeader_t;
|
||||
|
||||
/** \brief CDC class-specific Functional ACM Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface
|
||||
* supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details.
|
||||
*
|
||||
* \see \ref USB_CDC_StdDescriptor_FunctionalACM_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors,
|
||||
* must be \ref CDC_DSUBTYPE_CSInterface_ACM.
|
||||
*/
|
||||
uint8_t Capabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices,
|
||||
* this should be set to a fixed value of \c 0x06 - for other capabilities, refer
|
||||
* to the CDC ACM specification.
|
||||
*/
|
||||
} ATTR_PACKED USB_CDC_Descriptor_FunctionalACM_t;
|
||||
|
||||
/** \brief CDC class-specific Functional ACM Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface
|
||||
* supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details.
|
||||
*
|
||||
* \see \ref USB_CDC_Descriptor_FunctionalACM_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors,
|
||||
* must be \ref CDC_DSUBTYPE_CSInterface_ACM.
|
||||
*/
|
||||
uint8_t bmCapabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices,
|
||||
* this should be set to a fixed value of 0x06 - for other capabilities, refer
|
||||
* to the CDC ACM specification.
|
||||
*/
|
||||
} ATTR_PACKED USB_CDC_StdDescriptor_FunctionalACM_t;
|
||||
|
||||
/** \brief CDC class-specific Functional Union Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific
|
||||
* CDC control and data interfaces are related. See the CDC class specification for more details.
|
||||
*
|
||||
* \see \ref USB_CDC_StdDescriptor_FunctionalUnion_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors,
|
||||
* must be \ref CDC_DSUBTYPE_CSInterface_Union.
|
||||
*/
|
||||
uint8_t MasterInterfaceNumber; /**< Interface number of the CDC Control interface. */
|
||||
uint8_t SlaveInterfaceNumber; /**< Interface number of the CDC Data interface. */
|
||||
} ATTR_PACKED USB_CDC_Descriptor_FunctionalUnion_t;
|
||||
|
||||
/** \brief CDC class-specific Functional Union Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific
|
||||
* CDC control and data interfaces are related. See the CDC class specification for more details.
|
||||
*
|
||||
* \see \ref USB_CDC_Descriptor_FunctionalUnion_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors,
|
||||
* must be \ref CDC_DSUBTYPE_CSInterface_Union.
|
||||
*/
|
||||
uint8_t bMasterInterface; /**< Interface number of the CDC Control interface. */
|
||||
uint8_t bSlaveInterface0; /**< Interface number of the CDC Data interface. */
|
||||
} ATTR_PACKED USB_CDC_StdDescriptor_FunctionalUnion_t;
|
||||
|
||||
/** \brief CDC Virtual Serial Port Line Encoding Settings Structure.
|
||||
*
|
||||
* Type define for a CDC Line Encoding structure, used to hold the various encoding parameters for a virtual
|
||||
* serial port.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second. */
|
||||
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
|
||||
* \ref CDC_LineEncodingFormats_t enum.
|
||||
*/
|
||||
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
|
||||
* \ref CDC_LineEncodingParity_t enum.
|
||||
*/
|
||||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port. */
|
||||
} ATTR_PACKED CDC_LineEncoding_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,681 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB HID Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB HID Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassHID
|
||||
* \defgroup Group_USBClassHIDCommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassHIDCommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* HID Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HID_CLASS_COMMON_H_
|
||||
#define _HID_CLASS_COMMON_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
#include "HIDParser.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_HID_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** \name Keyboard Standard Report Modifier Masks */
|
||||
//@{
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left control key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_LEFTCTRL (1 << 0)
|
||||
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left shift key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_LEFTSHIFT (1 << 1)
|
||||
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left alt key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_LEFTALT (1 << 2)
|
||||
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's left GUI key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_LEFTGUI (1 << 3)
|
||||
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right control key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_RIGHTCTRL (1 << 4)
|
||||
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right shift key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_RIGHTSHIFT (1 << 5)
|
||||
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right alt key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_RIGHTALT (1 << 6)
|
||||
|
||||
/** Constant for a keyboard report modifier byte, indicating that the keyboard's right GUI key is currently pressed. */
|
||||
#define HID_KEYBOARD_MODIFIER_RIGHTGUI (1 << 7)
|
||||
//@}
|
||||
|
||||
/** \name Keyboard Standard Report LED Masks */
|
||||
//@{
|
||||
/** Constant for a keyboard output report LED byte, indicating that the host's NUM LOCK mode is currently set. */
|
||||
#define HID_KEYBOARD_LED_NUMLOCK (1 << 0)
|
||||
|
||||
/** Constant for a keyboard output report LED byte, indicating that the host's CAPS LOCK mode is currently set. */
|
||||
#define HID_KEYBOARD_LED_CAPSLOCK (1 << 1)
|
||||
|
||||
/** Constant for a keyboard output report LED byte, indicating that the host's SCROLL LOCK mode is currently set. */
|
||||
#define HID_KEYBOARD_LED_SCROLLLOCK (1 << 2)
|
||||
|
||||
/** Constant for a keyboard output report LED byte, indicating that the host's COMPOSE mode is currently set. */
|
||||
#define HID_KEYBOARD_LED_COMPOSE (1 << 3)
|
||||
|
||||
/** Constant for a keyboard output report LED byte, indicating that the host's KANA mode is currently set. */
|
||||
#define HID_KEYBOARD_LED_KANA (1 << 4)
|
||||
//@}
|
||||
|
||||
/** \name Keyboard Standard Report Key Scan-codes */
|
||||
//@{
|
||||
#define HID_KEYBOARD_SC_ERROR_ROLLOVER 0x01
|
||||
#define HID_KEYBOARD_SC_POST_FAIL 0x02
|
||||
#define HID_KEYBOARD_SC_ERROR_UNDEFINED 0x03
|
||||
#define HID_KEYBOARD_SC_A 0x04
|
||||
#define HID_KEYBOARD_SC_B 0x05
|
||||
#define HID_KEYBOARD_SC_C 0x06
|
||||
#define HID_KEYBOARD_SC_D 0x07
|
||||
#define HID_KEYBOARD_SC_E 0x08
|
||||
#define HID_KEYBOARD_SC_F 0x09
|
||||
#define HID_KEYBOARD_SC_G 0x0A
|
||||
#define HID_KEYBOARD_SC_H 0x0B
|
||||
#define HID_KEYBOARD_SC_I 0x0C
|
||||
#define HID_KEYBOARD_SC_J 0x0D
|
||||
#define HID_KEYBOARD_SC_K 0x0E
|
||||
#define HID_KEYBOARD_SC_L 0x0F
|
||||
#define HID_KEYBOARD_SC_M 0x10
|
||||
#define HID_KEYBOARD_SC_N 0x11
|
||||
#define HID_KEYBOARD_SC_O 0x12
|
||||
#define HID_KEYBOARD_SC_P 0x13
|
||||
#define HID_KEYBOARD_SC_Q 0x14
|
||||
#define HID_KEYBOARD_SC_R 0x15
|
||||
#define HID_KEYBOARD_SC_S 0x16
|
||||
#define HID_KEYBOARD_SC_T 0x17
|
||||
#define HID_KEYBOARD_SC_U 0x18
|
||||
#define HID_KEYBOARD_SC_V 0x19
|
||||
#define HID_KEYBOARD_SC_W 0x1A
|
||||
#define HID_KEYBOARD_SC_X 0x1B
|
||||
#define HID_KEYBOARD_SC_Y 0x1C
|
||||
#define HID_KEYBOARD_SC_Z 0x1D
|
||||
#define HID_KEYBOARD_SC_1_AND_EXCLAMATION 0x1E
|
||||
#define HID_KEYBOARD_SC_2_AND_AT 0x1F
|
||||
#define HID_KEYBOARD_SC_3_AND_HASHMARK 0x20
|
||||
#define HID_KEYBOARD_SC_4_AND_DOLLAR 0x21
|
||||
#define HID_KEYBOARD_SC_5_AND_PERCENTAGE 0x22
|
||||
#define HID_KEYBOARD_SC_6_AND_CARET 0x23
|
||||
#define HID_KEYBOARD_SC_7_AND_AMPERSAND 0x24
|
||||
#define HID_KEYBOARD_SC_8_AND_ASTERISK 0x25
|
||||
#define HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS 0x26
|
||||
#define HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS 0x27
|
||||
#define HID_KEYBOARD_SC_ENTER 0x28
|
||||
#define HID_KEYBOARD_SC_ESCAPE 0x29
|
||||
#define HID_KEYBOARD_SC_BACKSPACE 0x2A
|
||||
#define HID_KEYBOARD_SC_TAB 0x2B
|
||||
#define HID_KEYBOARD_SC_SPACE 0x2C
|
||||
#define HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE 0x2D
|
||||
#define HID_KEYBOARD_SC_EQUAL_AND_PLUS 0x2E
|
||||
#define HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE 0x2F
|
||||
#define HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE 0x30
|
||||
#define HID_KEYBOARD_SC_BACKSLASH_AND_PIPE 0x31
|
||||
#define HID_KEYBOARD_SC_NON_US_HASHMARK_AND_TILDE 0x32
|
||||
#define HID_KEYBOARD_SC_SEMICOLON_AND_COLON 0x33
|
||||
#define HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE 0x34
|
||||
#define HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE 0x35
|
||||
#define HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN 0x36
|
||||
#define HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN 0x37
|
||||
#define HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK 0x38
|
||||
#define HID_KEYBOARD_SC_CAPS_LOCK 0x39
|
||||
#define HID_KEYBOARD_SC_F1 0x3A
|
||||
#define HID_KEYBOARD_SC_F2 0x3B
|
||||
#define HID_KEYBOARD_SC_F3 0x3C
|
||||
#define HID_KEYBOARD_SC_F4 0x3D
|
||||
#define HID_KEYBOARD_SC_F5 0x3E
|
||||
#define HID_KEYBOARD_SC_F6 0x3F
|
||||
#define HID_KEYBOARD_SC_F7 0x40
|
||||
#define HID_KEYBOARD_SC_F8 0x41
|
||||
#define HID_KEYBOARD_SC_F9 0x42
|
||||
#define HID_KEYBOARD_SC_F10 0x43
|
||||
#define HID_KEYBOARD_SC_F11 0x44
|
||||
#define HID_KEYBOARD_SC_F12 0x45
|
||||
#define HID_KEYBOARD_SC_PRINT_SCREEN 0x46
|
||||
#define HID_KEYBOARD_SC_SCROLL_LOCK 0x47
|
||||
#define HID_KEYBOARD_SC_PAUSE 0x48
|
||||
#define HID_KEYBOARD_SC_INSERT 0x49
|
||||
#define HID_KEYBOARD_SC_HOME 0x4A
|
||||
#define HID_KEYBOARD_SC_PAGE_UP 0x4B
|
||||
#define HID_KEYBOARD_SC_DELETE 0x4C
|
||||
#define HID_KEYBOARD_SC_END 0x4D
|
||||
#define HID_KEYBOARD_SC_PAGE_DOWN 0x4E
|
||||
#define HID_KEYBOARD_SC_RIGHT_ARROW 0x4F
|
||||
#define HID_KEYBOARD_SC_LEFT_ARROW 0x50
|
||||
#define HID_KEYBOARD_SC_DOWN_ARROW 0x51
|
||||
#define HID_KEYBOARD_SC_UP_ARROW 0x52
|
||||
#define HID_KEYBOARD_SC_NUM_LOCK 0x53
|
||||
#define HID_KEYBOARD_SC_KEYPAD_SLASH 0x54
|
||||
#define HID_KEYBOARD_SC_KEYPAD_ASTERISK 0x55
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MINUS 0x56
|
||||
#define HID_KEYBOARD_SC_KEYPAD_PLUS 0x57
|
||||
#define HID_KEYBOARD_SC_KEYPAD_ENTER 0x58
|
||||
#define HID_KEYBOARD_SC_KEYPAD_1_AND_END 0x59
|
||||
#define HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW 0x5A
|
||||
#define HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN 0x5B
|
||||
#define HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW 0x5C
|
||||
#define HID_KEYBOARD_SC_KEYPAD_5 0x5D
|
||||
#define HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW 0x5E
|
||||
#define HID_KEYBOARD_SC_KEYPAD_7_AND_HOME 0x5F
|
||||
#define HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW 0x60
|
||||
#define HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP 0x61
|
||||
#define HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT 0x62
|
||||
#define HID_KEYBOARD_SC_KEYPAD_DOT_AND_DELETE 0x63
|
||||
#define HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE 0x64
|
||||
#define HID_KEYBOARD_SC_APPLICATION 0x65
|
||||
#define HID_KEYBOARD_SC_POWER 0x66
|
||||
#define HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN 0x67
|
||||
#define HID_KEYBOARD_SC_F13 0x68
|
||||
#define HID_KEYBOARD_SC_F14 0x69
|
||||
#define HID_KEYBOARD_SC_F15 0x6A
|
||||
#define HID_KEYBOARD_SC_F16 0x6B
|
||||
#define HID_KEYBOARD_SC_F17 0x6C
|
||||
#define HID_KEYBOARD_SC_F18 0x6D
|
||||
#define HID_KEYBOARD_SC_F19 0x6E
|
||||
#define HID_KEYBOARD_SC_F20 0x6F
|
||||
#define HID_KEYBOARD_SC_F21 0x70
|
||||
#define HID_KEYBOARD_SC_F22 0x71
|
||||
#define HID_KEYBOARD_SC_F23 0x72
|
||||
#define HID_KEYBOARD_SC_F24 0x73
|
||||
#define HID_KEYBOARD_SC_EXECUTE 0x74
|
||||
#define HID_KEYBOARD_SC_HELP 0x75
|
||||
#define HID_KEYBOARD_SC_MENU 0x76
|
||||
#define HID_KEYBOARD_SC_SELECT 0x77
|
||||
#define HID_KEYBOARD_SC_STOP 0x78
|
||||
#define HID_KEYBOARD_SC_AGAIN 0x79
|
||||
#define HID_KEYBOARD_SC_UNDO 0x7A
|
||||
#define HID_KEYBOARD_SC_CUT 0x7B
|
||||
#define HID_KEYBOARD_SC_COPY 0x7C
|
||||
#define HID_KEYBOARD_SC_PASTE 0x7D
|
||||
#define HID_KEYBOARD_SC_FIND 0x7E
|
||||
#define HID_KEYBOARD_SC_MUTE 0x7F
|
||||
#define HID_KEYBOARD_SC_VOLUME_UP 0x80
|
||||
#define HID_KEYBOARD_SC_VOLUME_DOWN 0x81
|
||||
#define HID_KEYBOARD_SC_LOCKING_CAPS_LOCK 0x82
|
||||
#define HID_KEYBOARD_SC_LOCKING_NUM_LOCK 0x83
|
||||
#define HID_KEYBOARD_SC_LOCKING_SCROLL_LOCK 0x84
|
||||
#define HID_KEYBOARD_SC_KEYPAD_COMMA 0x85
|
||||
#define HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN_AS400 0x86
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL1 0x87
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL2 0x88
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL3 0x89
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL4 0x8A
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL5 0x8B
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL6 0x8C
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL7 0x8D
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL8 0x8E
|
||||
#define HID_KEYBOARD_SC_INTERNATIONAL9 0x8F
|
||||
#define HID_KEYBOARD_SC_LANG1 0x90
|
||||
#define HID_KEYBOARD_SC_LANG2 0x91
|
||||
#define HID_KEYBOARD_SC_LANG3 0x92
|
||||
#define HID_KEYBOARD_SC_LANG4 0x93
|
||||
#define HID_KEYBOARD_SC_LANG5 0x94
|
||||
#define HID_KEYBOARD_SC_LANG6 0x95
|
||||
#define HID_KEYBOARD_SC_LANG7 0x96
|
||||
#define HID_KEYBOARD_SC_LANG8 0x97
|
||||
#define HID_KEYBOARD_SC_LANG9 0x98
|
||||
#define HID_KEYBOARD_SC_ALTERNATE_ERASE 0x99
|
||||
#define HID_KEYBOARD_SC_SYSREQ 0x9A
|
||||
#define HID_KEYBOARD_SC_CANCEL 0x9B
|
||||
#define HID_KEYBOARD_SC_CLEAR 0x9C
|
||||
#define HID_KEYBOARD_SC_PRIOR 0x9D
|
||||
#define HID_KEYBOARD_SC_RETURN 0x9E
|
||||
#define HID_KEYBOARD_SC_SEPARATOR 0x9F
|
||||
#define HID_KEYBOARD_SC_OUT 0xA0
|
||||
#define HID_KEYBOARD_SC_OPER 0xA1
|
||||
#define HID_KEYBOARD_SC_CLEAR_AND_AGAIN 0xA2
|
||||
#define HID_KEYBOARD_SC_CRSEL_AND_PROPS 0xA3
|
||||
#define HID_KEYBOARD_SC_EXSEL 0xA4
|
||||
#define HID_KEYBOARD_SC_KEYPAD_00 0xB0
|
||||
#define HID_KEYBOARD_SC_KEYPAD_000 0xB1
|
||||
#define HID_KEYBOARD_SC_THOUSANDS_SEPARATOR 0xB2
|
||||
#define HID_KEYBOARD_SC_DECIMAL_SEPARATOR 0xB3
|
||||
#define HID_KEYBOARD_SC_CURRENCY_UNIT 0xB4
|
||||
#define HID_KEYBOARD_SC_CURRENCY_SUB_UNIT 0xB5
|
||||
#define HID_KEYBOARD_SC_KEYPAD_OPENING_PARENTHESIS 0xB6
|
||||
#define HID_KEYBOARD_SC_KEYPAD_CLOSING_PARENTHESIS 0xB7
|
||||
#define HID_KEYBOARD_SC_KEYPAD_OPENING_BRACE 0xB8
|
||||
#define HID_KEYBOARD_SC_KEYPAD_CLOSING_BRACE 0xB9
|
||||
#define HID_KEYBOARD_SC_KEYPAD_TAB 0xBA
|
||||
#define HID_KEYBOARD_SC_KEYPAD_BACKSPACE 0xBB
|
||||
#define HID_KEYBOARD_SC_KEYPAD_A 0xBC
|
||||
#define HID_KEYBOARD_SC_KEYPAD_B 0xBD
|
||||
#define HID_KEYBOARD_SC_KEYPAD_C 0xBE
|
||||
#define HID_KEYBOARD_SC_KEYPAD_D 0xBF
|
||||
#define HID_KEYBOARD_SC_KEYPAD_E 0xC0
|
||||
#define HID_KEYBOARD_SC_KEYPAD_F 0xC1
|
||||
#define HID_KEYBOARD_SC_KEYPAD_XOR 0xC2
|
||||
#define HID_KEYBOARD_SC_KEYPAD_CARET 0xC3
|
||||
#define HID_KEYBOARD_SC_KEYPAD_PERCENTAGE 0xC4
|
||||
#define HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN 0xC5
|
||||
#define HID_KEYBOARD_SC_KEYPAD_GREATER_THAN_SIGN 0xC6
|
||||
#define HID_KEYBOARD_SC_KEYPAD_AMP 0xC7
|
||||
#define HID_KEYBOARD_SC_KEYPAD_AMP_AMP 0xC8
|
||||
#define HID_KEYBOARD_SC_KEYPAD_PIPE 0xC9
|
||||
#define HID_KEYBOARD_SC_KEYPAD_PIPE_PIPE 0xCA
|
||||
#define HID_KEYBOARD_SC_KEYPAD_COLON 0xCB
|
||||
#define HID_KEYBOARD_SC_KEYPAD_HASHMARK 0xCC
|
||||
#define HID_KEYBOARD_SC_KEYPAD_SPACE 0xCD
|
||||
#define HID_KEYBOARD_SC_KEYPAD_AT 0xCE
|
||||
#define HID_KEYBOARD_SC_KEYPAD_EXCLAMATION_SIGN 0xCF
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MEMORY_STORE 0xD0
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MEMORY_RECALL 0xD1
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MEMORY_CLEAR 0xD2
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MEMORY_ADD 0xD3
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MEMORY_SUBTRACT 0xD4
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MEMORY_MULTIPLY 0xD5
|
||||
#define HID_KEYBOARD_SC_KEYPAD_MEMORY_DIVIDE 0xD6
|
||||
#define HID_KEYBOARD_SC_KEYPAD_PLUS_AND_MINUS 0xD7
|
||||
#define HID_KEYBOARD_SC_KEYPAD_CLEAR 0xD8
|
||||
#define HID_KEYBOARD_SC_KEYPAD_CLEAR_ENTRY 0xD9
|
||||
#define HID_KEYBOARD_SC_KEYPAD_BINARY 0xDA
|
||||
#define HID_KEYBOARD_SC_KEYPAD_OCTAL 0xDB
|
||||
#define HID_KEYBOARD_SC_KEYPAD_DECIMAL 0xDC
|
||||
#define HID_KEYBOARD_SC_KEYPAD_HEXADECIMAL 0xDD
|
||||
#define HID_KEYBOARD_SC_LEFT_CONTROL 0xE0
|
||||
#define HID_KEYBOARD_SC_LEFT_SHIFT 0xE1
|
||||
#define HID_KEYBOARD_SC_LEFT_ALT 0xE2
|
||||
#define HID_KEYBOARD_SC_LEFT_GUI 0xE3
|
||||
#define HID_KEYBOARD_SC_RIGHT_CONTROL 0xE4
|
||||
#define HID_KEYBOARD_SC_RIGHT_SHIFT 0xE5
|
||||
#define HID_KEYBOARD_SC_RIGHT_ALT 0xE6
|
||||
#define HID_KEYBOARD_SC_RIGHT_GUI 0xE7
|
||||
#define HID_KEYBOARD_SC_MEDIA_PLAY 0xE8
|
||||
#define HID_KEYBOARD_SC_MEDIA_STOP 0xE9
|
||||
#define HID_KEYBOARD_SC_MEDIA_PREVIOUS_TRACK 0xEA
|
||||
#define HID_KEYBOARD_SC_MEDIA_NEXT_TRACK 0xEB
|
||||
#define HID_KEYBOARD_SC_MEDIA_EJECT 0xEC
|
||||
#define HID_KEYBOARD_SC_MEDIA_VOLUME_UP 0xED
|
||||
#define HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN 0xEE
|
||||
#define HID_KEYBOARD_SC_MEDIA_MUTE 0xEF
|
||||
#define HID_KEYBOARD_SC_MEDIA_WWW 0xF0
|
||||
#define HID_KEYBOARD_SC_MEDIA_BACKWARD 0xF1
|
||||
#define HID_KEYBOARD_SC_MEDIA_FORWARD 0xF2
|
||||
#define HID_KEYBOARD_SC_MEDIA_CANCEL 0xF3
|
||||
#define HID_KEYBOARD_SC_MEDIA_SEARCH 0xF4
|
||||
#define HID_KEYBOARD_SC_MEDIA_SLEEP 0xF8
|
||||
#define HID_KEYBOARD_SC_MEDIA_LOCK 0xF9
|
||||
#define HID_KEYBOARD_SC_MEDIA_RELOAD 0xFA
|
||||
#define HID_KEYBOARD_SC_MEDIA_CALCULATOR 0xFB
|
||||
//@}
|
||||
|
||||
/** \name Common HID Device Report Descriptors */
|
||||
//@{
|
||||
/** \hideinitializer
|
||||
* A list of HID report item array elements that describe a typical HID USB Joystick. The resulting report
|
||||
* descriptor is structured according to the following layout:
|
||||
*
|
||||
* \code
|
||||
* struct
|
||||
* {
|
||||
* intA_t X; // Signed X axis value
|
||||
* intA_t Y; // Signed Y axis value
|
||||
* intA_t Z; // Signed Z axis value
|
||||
* uintB_t Buttons; // Pressed buttons bitmask
|
||||
* } Joystick_Report;
|
||||
* \endcode
|
||||
*
|
||||
* Where \c uintA_t is a type large enough to hold the ranges of the signed \c MinAxisVal and \c MaxAxisVal values,
|
||||
* and \c intB_t is a type large enough to hold one bit per button.
|
||||
*
|
||||
* \param[in] MinAxisVal Minimum logical axis value (16-bit).
|
||||
* \param[in] MaxAxisVal Maximum logical axis value (16-bit).
|
||||
* \param[in] MinPhysicalVal Minimum physical axis value, for movement resolution calculations (16-bit).
|
||||
* \param[in] MaxPhysicalVal Maximum physical axis value, for movement resolution calculations (16-bit).
|
||||
* \param[in] Buttons Total number of buttons in the device (8-bit).
|
||||
*/
|
||||
#define HID_DESCRIPTOR_JOYSTICK(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons) \
|
||||
HID_RI_USAGE_PAGE(8, 0x01), \
|
||||
HID_RI_USAGE(8, 0x04), \
|
||||
HID_RI_COLLECTION(8, 0x01), \
|
||||
HID_RI_USAGE(8, 0x01), \
|
||||
HID_RI_COLLECTION(8, 0x00), \
|
||||
HID_RI_USAGE(8, 0x30), \
|
||||
HID_RI_USAGE(8, 0x31), \
|
||||
HID_RI_USAGE(8, 0x32), \
|
||||
HID_RI_LOGICAL_MINIMUM(16, MinAxisVal), \
|
||||
HID_RI_LOGICAL_MAXIMUM(16, MaxAxisVal), \
|
||||
HID_RI_PHYSICAL_MINIMUM(16, MinPhysicalVal), \
|
||||
HID_RI_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \
|
||||
HID_RI_REPORT_COUNT(8, 3), \
|
||||
HID_RI_REPORT_SIZE(8, (((MinAxisVal >= -128) && (MaxAxisVal <= 127)) ? 8 : 16)), \
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
|
||||
HID_RI_END_COLLECTION(0), \
|
||||
HID_RI_USAGE_PAGE(8, 0x09), \
|
||||
HID_RI_USAGE_MINIMUM(8, 0x01), \
|
||||
HID_RI_USAGE_MAXIMUM(8, Buttons), \
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), \
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0x01), \
|
||||
HID_RI_REPORT_SIZE(8, 0x01), \
|
||||
HID_RI_REPORT_COUNT(8, Buttons), \
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
|
||||
HID_RI_REPORT_SIZE(8, (Buttons % 8) ? (8 - (Buttons % 8)) : 0), \
|
||||
HID_RI_REPORT_COUNT(8, 0x01), \
|
||||
HID_RI_INPUT(8, HID_IOF_CONSTANT), \
|
||||
HID_RI_END_COLLECTION(0)
|
||||
|
||||
/** \hideinitializer
|
||||
* A list of HID report item array elements that describe a typical HID USB keyboard. The resulting report descriptor
|
||||
* is compatible with \ref USB_KeyboardReport_Data_t when \c MaxKeys is equal to 6. For other values, the report will
|
||||
* be structured according to the following layout:
|
||||
*
|
||||
* \code
|
||||
* struct
|
||||
* {
|
||||
* uint8_t Modifier; // Keyboard modifier byte indicating pressed modifier keys (\c HID_KEYBOARD_MODIFER_* masks)
|
||||
* uint8_t Reserved; // Reserved for OEM use, always set to 0.
|
||||
* uint8_t KeyCode[MaxKeys]; // Length determined by the number of keys that can be reported
|
||||
* } Keyboard_Report;
|
||||
* \endcode
|
||||
*
|
||||
* \param[in] MaxKeys Number of simultaneous keys that can be reported at the one time (8-bit).
|
||||
*/
|
||||
#define HID_DESCRIPTOR_KEYBOARD(MaxKeys) \
|
||||
HID_RI_USAGE_PAGE(8, 0x01), \
|
||||
HID_RI_USAGE(8, 0x06), \
|
||||
HID_RI_COLLECTION(8, 0x01), \
|
||||
HID_RI_USAGE_PAGE(8, 0x07), \
|
||||
HID_RI_USAGE_MINIMUM(8, 0xE0), \
|
||||
HID_RI_USAGE_MAXIMUM(8, 0xE7), \
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), \
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0x01), \
|
||||
HID_RI_REPORT_SIZE(8, 0x01), \
|
||||
HID_RI_REPORT_COUNT(8, 0x08), \
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
|
||||
HID_RI_REPORT_COUNT(8, 0x01), \
|
||||
HID_RI_REPORT_SIZE(8, 0x08), \
|
||||
HID_RI_INPUT(8, HID_IOF_CONSTANT), \
|
||||
HID_RI_USAGE_PAGE(8, 0x08), \
|
||||
HID_RI_USAGE_MINIMUM(8, 0x01), \
|
||||
HID_RI_USAGE_MAXIMUM(8, 0x05), \
|
||||
HID_RI_REPORT_COUNT(8, 0x05), \
|
||||
HID_RI_REPORT_SIZE(8, 0x01), \
|
||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \
|
||||
HID_RI_REPORT_COUNT(8, 0x01), \
|
||||
HID_RI_REPORT_SIZE(8, 0x03), \
|
||||
HID_RI_OUTPUT(8, HID_IOF_CONSTANT), \
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), \
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0xFF), \
|
||||
HID_RI_USAGE_PAGE(8, 0x07), \
|
||||
HID_RI_USAGE_MINIMUM(8, 0x00), \
|
||||
HID_RI_USAGE_MAXIMUM(8, 0xFF), \
|
||||
HID_RI_REPORT_COUNT(8, MaxKeys), \
|
||||
HID_RI_REPORT_SIZE(8, 0x08), \
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), \
|
||||
HID_RI_END_COLLECTION(0)
|
||||
|
||||
/** \hideinitializer
|
||||
* A list of HID report item array elements that describe a typical HID USB mouse. The resulting report descriptor
|
||||
* is compatible with \ref USB_MouseReport_Data_t if the \c MinAxisVal and \c MaxAxisVal values fit within a \c int8_t range
|
||||
* and the number of Buttons is less than 8. For other values, the report is structured according to the following layout:
|
||||
*
|
||||
* \code
|
||||
* struct
|
||||
* {
|
||||
* uintA_t Buttons; // Pressed buttons bitmask
|
||||
* intB_t X; // X axis value
|
||||
* intB_t Y; // Y axis value
|
||||
* } Mouse_Report;
|
||||
* \endcode
|
||||
*
|
||||
* 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
|
||||
* ranges of the signed \c MinAxisVal and \c MaxAxisVal values.
|
||||
*
|
||||
* \param[in] MinAxisVal Minimum X/Y logical axis value (16-bit).
|
||||
* \param[in] MaxAxisVal Maximum X/Y logical axis value (16-bit).
|
||||
* \param[in] MinPhysicalVal Minimum X/Y physical axis value, for movement resolution calculations (16-bit).
|
||||
* \param[in] MaxPhysicalVal Maximum X/Y physical axis value, for movement resolution calculations (16-bit).
|
||||
* \param[in] Buttons Total number of buttons in the device (8-bit).
|
||||
* \param[in] AbsoluteCoords Boolean \c true to use absolute X/Y coordinates (e.g. touchscreen).
|
||||
*/
|
||||
#define HID_DESCRIPTOR_MOUSE(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons, AbsoluteCoords) \
|
||||
HID_RI_USAGE_PAGE(8, 0x01), \
|
||||
HID_RI_USAGE(8, 0x02), \
|
||||
HID_RI_COLLECTION(8, 0x01), \
|
||||
HID_RI_USAGE(8, 0x01), \
|
||||
HID_RI_COLLECTION(8, 0x00), \
|
||||
HID_RI_USAGE_PAGE(8, 0x09), \
|
||||
HID_RI_USAGE_MINIMUM(8, 0x01), \
|
||||
HID_RI_USAGE_MAXIMUM(8, Buttons), \
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), \
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0x01), \
|
||||
HID_RI_REPORT_COUNT(8, Buttons), \
|
||||
HID_RI_REPORT_SIZE(8, 0x01), \
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
|
||||
HID_RI_REPORT_COUNT(8, 0x01), \
|
||||
HID_RI_REPORT_SIZE(8, (Buttons % 8) ? (8 - (Buttons % 8)) : 0), \
|
||||
HID_RI_INPUT(8, HID_IOF_CONSTANT), \
|
||||
HID_RI_USAGE_PAGE(8, 0x01), \
|
||||
HID_RI_USAGE(8, 0x30), \
|
||||
HID_RI_USAGE(8, 0x31), \
|
||||
HID_RI_LOGICAL_MINIMUM(16, MinAxisVal), \
|
||||
HID_RI_LOGICAL_MAXIMUM(16, MaxAxisVal), \
|
||||
HID_RI_PHYSICAL_MINIMUM(16, MinPhysicalVal), \
|
||||
HID_RI_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \
|
||||
HID_RI_REPORT_COUNT(8, 0x02), \
|
||||
HID_RI_REPORT_SIZE(8, (((MinAxisVal >= -128) && (MaxAxisVal <= 127)) ? 8 : 16)), \
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | (AbsoluteCoords ? HID_IOF_ABSOLUTE : HID_IOF_RELATIVE)), \
|
||||
HID_RI_END_COLLECTION(0), \
|
||||
HID_RI_END_COLLECTION(0)
|
||||
|
||||
/** \hideinitializer
|
||||
* A list of HID report item array elements that describe a typical Vendor Defined byte array HID report descriptor,
|
||||
* used for transporting arbitrary data between the USB host and device via HID reports. The resulting report should be
|
||||
* a \c uint8_t byte array of the specified length in both Device to Host (IN) and Host to Device (OUT) directions.
|
||||
*
|
||||
* \param[in] VendorPageNum Vendor Defined HID Usage Page index, ranging from 0x00 to 0xFF.
|
||||
* \param[in] CollectionUsage Vendor Usage for the encompassing report IN and OUT collection, ranging from 0x00 to 0xFF.
|
||||
* \param[in] DataINUsage Vendor Usage for the IN report data, ranging from 0x00 to 0xFF.
|
||||
* \param[in] DataOUTUsage Vendor Usage for the OUT report data, ranging from 0x00 to 0xFF.
|
||||
* \param[in] NumBytes Length of the data IN and OUT reports.
|
||||
*/
|
||||
#define HID_DESCRIPTOR_VENDOR(VendorPageNum, CollectionUsage, DataINUsage, DataOUTUsage, NumBytes) \
|
||||
HID_RI_USAGE_PAGE(16, (0xFF00 | VendorPageNum)), \
|
||||
HID_RI_USAGE(8, CollectionUsage), \
|
||||
HID_RI_COLLECTION(8, 0x01), \
|
||||
HID_RI_USAGE(8, DataINUsage), \
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), \
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), \
|
||||
HID_RI_REPORT_SIZE(8, 0x08), \
|
||||
HID_RI_REPORT_COUNT(8, NumBytes), \
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
|
||||
HID_RI_USAGE(8, DataOUTUsage), \
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00), \
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF), \
|
||||
HID_RI_REPORT_SIZE(8, 0x08), \
|
||||
HID_RI_REPORT_COUNT(8, NumBytes), \
|
||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \
|
||||
HID_RI_END_COLLECTION(0)
|
||||
//@}
|
||||
|
||||
/* Type Defines: */
|
||||
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the HID
|
||||
* device class.
|
||||
*/
|
||||
enum HID_Descriptor_ClassSubclassProtocol_t
|
||||
{
|
||||
HID_CSCP_HIDClass = 0x03, /**< Descriptor Class value indicating that the device or interface
|
||||
* belongs to the HID class.
|
||||
*/
|
||||
HID_CSCP_NonBootSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* does not implement a HID boot protocol.
|
||||
*/
|
||||
HID_CSCP_BootSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* implements a HID boot protocol.
|
||||
*/
|
||||
HID_CSCP_NonBootProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* does not belong to a HID boot protocol.
|
||||
*/
|
||||
HID_CSCP_KeyboardBootProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to the Keyboard HID boot protocol.
|
||||
*/
|
||||
HID_CSCP_MouseBootProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to the Mouse HID boot protocol.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the HID class specific control requests that can be issued by the USB bus host. */
|
||||
enum HID_ClassRequests_t
|
||||
{
|
||||
HID_REQ_GetReport = 0x01, /**< HID class-specific Request to get the current HID report from the device. */
|
||||
HID_REQ_GetIdle = 0x02, /**< HID class-specific Request to get the current device idle count. */
|
||||
HID_REQ_GetProtocol = 0x03, /**< HID class-specific Request to get the current HID report protocol mode. */
|
||||
HID_REQ_SetReport = 0x09, /**< HID class-specific Request to set the current HID report to the device. */
|
||||
HID_REQ_SetIdle = 0x0A, /**< HID class-specific Request to set the device's idle count. */
|
||||
HID_REQ_SetProtocol = 0x0B, /**< HID class-specific Request to set the current HID report protocol mode. */
|
||||
};
|
||||
|
||||
/** Enum for the HID class specific descriptor types. */
|
||||
enum HID_DescriptorTypes_t
|
||||
{
|
||||
HID_DTYPE_HID = 0x21, /**< Descriptor header type value, to indicate a HID class HID descriptor. */
|
||||
HID_DTYPE_Report = 0x22, /**< Descriptor header type value, to indicate a HID class HID report descriptor. */
|
||||
};
|
||||
|
||||
/** Enum for the different types of HID reports. */
|
||||
enum HID_ReportItemTypes_t
|
||||
{
|
||||
HID_REPORT_ITEM_In = 0, /**< Indicates that the item is an IN report type. */
|
||||
HID_REPORT_ITEM_Out = 1, /**< Indicates that the item is an OUT report type. */
|
||||
HID_REPORT_ITEM_Feature = 2, /**< Indicates that the item is a FEATURE report type. */
|
||||
};
|
||||
|
||||
/** \brief HID class-specific HID Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID
|
||||
* specification for details on the structure elements.
|
||||
*
|
||||
* \see \ref USB_HID_StdDescriptor_HID_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
|
||||
uint16_t HIDSpec; /**< BCD encoded version that the HID descriptor and device complies to.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
uint8_t CountryCode; /**< Country code of the localized device, or zero if universal. */
|
||||
|
||||
uint8_t TotalReportDescriptors; /**< Total number of HID report descriptors for the interface. */
|
||||
|
||||
uint8_t HIDReportType; /**< Type of HID report, set to \ref HID_DTYPE_Report. */
|
||||
uint16_t HIDReportLength; /**< Length of the associated HID report descriptor, in bytes. */
|
||||
} ATTR_PACKED USB_HID_Descriptor_HID_t;
|
||||
|
||||
/** \brief HID class-specific HID Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID
|
||||
* specification for details on the structure elements.
|
||||
*
|
||||
* \see \ref USB_HID_Descriptor_HID_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint16_t bcdHID; /**< BCD encoded version that the HID descriptor and device complies to.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
uint8_t bCountryCode; /**< Country code of the localized device, or zero if universal. */
|
||||
|
||||
uint8_t bNumDescriptors; /**< Total number of HID report descriptors for the interface. */
|
||||
|
||||
uint8_t bDescriptorType2; /**< Type of HID report, set to \ref HID_DTYPE_Report. */
|
||||
uint16_t wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */
|
||||
} ATTR_PACKED USB_HID_StdDescriptor_HID_t;
|
||||
|
||||
/** \brief Standard HID Boot Protocol Mouse Report.
|
||||
*
|
||||
* Type define for a standard Boot Protocol Mouse report
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Button; /**< Button mask for currently pressed buttons in the mouse. */
|
||||
int8_t X; /**< Current delta X movement of the mouse. */
|
||||
int8_t Y; /**< Current delta Y movement on the mouse. */
|
||||
} ATTR_PACKED USB_MouseReport_Data_t;
|
||||
|
||||
/** \brief Standard HID Boot Protocol Keyboard Report.
|
||||
*
|
||||
* Type define for a standard Boot Protocol Keyboard report
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of
|
||||
* \c HID_KEYBOARD_MODIFER_* masks).
|
||||
*/
|
||||
uint8_t Reserved; /**< Reserved for OEM use, always set to 0. */
|
||||
uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys. */
|
||||
} ATTR_PACKED USB_KeyboardReport_Data_t;
|
||||
|
||||
/** Type define for the data type used to store HID report descriptor elements. */
|
||||
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_HID_DRIVER
|
||||
#include "HIDParser.h"
|
||||
|
||||
uint8_t USB_ProcessHIDReport(const uint8_t* ReportData,
|
||||
uint16_t ReportSize,
|
||||
HID_ReportInfo_t* const ParserData)
|
||||
{
|
||||
HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH];
|
||||
HID_StateTable_t* CurrStateTable = &StateTable[0];
|
||||
HID_CollectionPath_t* CurrCollectionPath = NULL;
|
||||
HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0];
|
||||
uint16_t UsageList[HID_USAGE_STACK_DEPTH];
|
||||
uint8_t UsageListSize = 0;
|
||||
HID_MinMax_t UsageMinMax = {0, 0};
|
||||
|
||||
memset(ParserData, 0x00, sizeof(HID_ReportInfo_t));
|
||||
memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));
|
||||
memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
|
||||
|
||||
ParserData->TotalDeviceReports = 1;
|
||||
|
||||
while (ReportSize)
|
||||
{
|
||||
uint8_t HIDReportItem = *ReportData;
|
||||
uint32_t ReportItemData;
|
||||
|
||||
ReportData++;
|
||||
ReportSize--;
|
||||
|
||||
switch (HIDReportItem & HID_RI_DATA_SIZE_MASK)
|
||||
{
|
||||
case HID_RI_DATA_BITS_32:
|
||||
ReportItemData = (((uint32_t)ReportData[3] << 24) | ((uint32_t)ReportData[2] << 16) |
|
||||
((uint16_t)ReportData[1] << 8) | ReportData[0]);
|
||||
ReportSize -= 4;
|
||||
ReportData += 4;
|
||||
break;
|
||||
|
||||
case HID_RI_DATA_BITS_16:
|
||||
ReportItemData = (((uint16_t)ReportData[1] << 8) | (ReportData[0]));
|
||||
ReportSize -= 2;
|
||||
ReportData += 2;
|
||||
break;
|
||||
|
||||
case HID_RI_DATA_BITS_8:
|
||||
ReportItemData = ReportData[0];
|
||||
ReportSize -= 1;
|
||||
ReportData += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ReportItemData = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK))
|
||||
{
|
||||
case HID_RI_PUSH(0):
|
||||
if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH - 1])
|
||||
return HID_PARSE_HIDStackOverflow;
|
||||
|
||||
memcpy((CurrStateTable + 1),
|
||||
CurrStateTable,
|
||||
sizeof(HID_ReportItem_t));
|
||||
|
||||
CurrStateTable++;
|
||||
break;
|
||||
|
||||
case HID_RI_POP(0):
|
||||
if (CurrStateTable == &StateTable[0])
|
||||
return HID_PARSE_HIDStackUnderflow;
|
||||
|
||||
CurrStateTable--;
|
||||
break;
|
||||
|
||||
case HID_RI_USAGE_PAGE(0):
|
||||
if ((HIDReportItem & HID_RI_DATA_SIZE_MASK) == HID_RI_DATA_BITS_32)
|
||||
CurrStateTable->Attributes.Usage.Page = (ReportItemData >> 16);
|
||||
|
||||
CurrStateTable->Attributes.Usage.Page = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_LOGICAL_MINIMUM(0):
|
||||
CurrStateTable->Attributes.Logical.Minimum = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_LOGICAL_MAXIMUM(0):
|
||||
CurrStateTable->Attributes.Logical.Maximum = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_PHYSICAL_MINIMUM(0):
|
||||
CurrStateTable->Attributes.Physical.Minimum = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_PHYSICAL_MAXIMUM(0):
|
||||
CurrStateTable->Attributes.Physical.Maximum = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_UNIT_EXPONENT(0):
|
||||
CurrStateTable->Attributes.Unit.Exponent = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_UNIT(0):
|
||||
CurrStateTable->Attributes.Unit.Type = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_REPORT_SIZE(0):
|
||||
CurrStateTable->Attributes.BitSize = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_REPORT_COUNT(0):
|
||||
CurrStateTable->ReportCount = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_REPORT_ID(0):
|
||||
CurrStateTable->ReportID = ReportItemData;
|
||||
|
||||
if (ParserData->UsingReportIDs)
|
||||
{
|
||||
CurrReportIDInfo = NULL;
|
||||
|
||||
for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++)
|
||||
{
|
||||
if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID)
|
||||
{
|
||||
CurrReportIDInfo = &ParserData->ReportIDSizes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrReportIDInfo == NULL)
|
||||
{
|
||||
if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS)
|
||||
return HID_PARSE_InsufficientReportIDItems;
|
||||
|
||||
CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++];
|
||||
memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
|
||||
}
|
||||
}
|
||||
|
||||
ParserData->UsingReportIDs = true;
|
||||
|
||||
CurrReportIDInfo->ReportID = CurrStateTable->ReportID;
|
||||
break;
|
||||
|
||||
case HID_RI_USAGE(0):
|
||||
if (UsageListSize == HID_USAGE_STACK_DEPTH)
|
||||
return HID_PARSE_UsageListOverflow;
|
||||
|
||||
UsageList[UsageListSize++] = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_USAGE_MINIMUM(0):
|
||||
UsageMinMax.Minimum = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_USAGE_MAXIMUM(0):
|
||||
UsageMinMax.Maximum = ReportItemData;
|
||||
break;
|
||||
|
||||
case HID_RI_COLLECTION(0):
|
||||
if (CurrCollectionPath == NULL)
|
||||
{
|
||||
CurrCollectionPath = &ParserData->CollectionPaths[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath;
|
||||
|
||||
CurrCollectionPath = &ParserData->CollectionPaths[1];
|
||||
|
||||
while (CurrCollectionPath->Parent != NULL)
|
||||
{
|
||||
if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1])
|
||||
return HID_PARSE_InsufficientCollectionPaths;
|
||||
|
||||
CurrCollectionPath++;
|
||||
}
|
||||
|
||||
CurrCollectionPath->Parent = ParentCollectionPath;
|
||||
}
|
||||
|
||||
CurrCollectionPath->Type = ReportItemData;
|
||||
CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page;
|
||||
|
||||
if (UsageListSize)
|
||||
{
|
||||
CurrCollectionPath->Usage.Usage = UsageList[0];
|
||||
|
||||
for (uint8_t i = 1; i < UsageListSize; i++)
|
||||
UsageList[i - 1] = UsageList[i];
|
||||
|
||||
UsageListSize--;
|
||||
}
|
||||
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
|
||||
{
|
||||
CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HID_RI_END_COLLECTION(0):
|
||||
if (CurrCollectionPath == NULL)
|
||||
return HID_PARSE_UnexpectedEndCollection;
|
||||
|
||||
CurrCollectionPath = CurrCollectionPath->Parent;
|
||||
break;
|
||||
|
||||
case HID_RI_INPUT(0):
|
||||
case HID_RI_OUTPUT(0):
|
||||
case HID_RI_FEATURE(0):
|
||||
for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++)
|
||||
{
|
||||
HID_ReportItem_t NewReportItem;
|
||||
|
||||
memcpy(&NewReportItem.Attributes,
|
||||
&CurrStateTable->Attributes,
|
||||
sizeof(HID_ReportItem_Attributes_t));
|
||||
|
||||
NewReportItem.ItemFlags = ReportItemData;
|
||||
NewReportItem.CollectionPath = CurrCollectionPath;
|
||||
NewReportItem.ReportID = CurrStateTable->ReportID;
|
||||
|
||||
if (UsageListSize)
|
||||
{
|
||||
NewReportItem.Attributes.Usage.Usage = UsageList[0];
|
||||
|
||||
for (uint8_t i = 1; i < UsageListSize; i++)
|
||||
UsageList[i - 1] = UsageList[i];
|
||||
|
||||
UsageListSize--;
|
||||
}
|
||||
else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
|
||||
{
|
||||
NewReportItem.Attributes.Usage.Usage = UsageMinMax.Minimum++;
|
||||
}
|
||||
|
||||
uint8_t ItemTypeTag = (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK));
|
||||
|
||||
if (ItemTypeTag == HID_RI_INPUT(0))
|
||||
NewReportItem.ItemType = HID_REPORT_ITEM_In;
|
||||
else if (ItemTypeTag == HID_RI_OUTPUT(0))
|
||||
NewReportItem.ItemType = HID_REPORT_ITEM_Out;
|
||||
else
|
||||
NewReportItem.ItemType = HID_REPORT_ITEM_Feature;
|
||||
|
||||
NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType];
|
||||
|
||||
CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize;
|
||||
|
||||
ParserData->LargestReportSizeBits = MAX(ParserData->LargestReportSizeBits, CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType]);
|
||||
|
||||
if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS)
|
||||
return HID_PARSE_InsufficientReportItems;
|
||||
|
||||
memcpy(&ParserData->ReportItems[ParserData->TotalReportItems],
|
||||
&NewReportItem, sizeof(HID_ReportItem_t));
|
||||
|
||||
if (!(ReportItemData & HID_IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem))
|
||||
ParserData->TotalReportItems++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((HIDReportItem & HID_RI_TYPE_MASK) == HID_RI_TYPE_MAIN)
|
||||
{
|
||||
UsageMinMax.Minimum = 0;
|
||||
UsageMinMax.Maximum = 0;
|
||||
UsageListSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ParserData->TotalReportItems))
|
||||
return HID_PARSE_NoUnfilteredReportItems;
|
||||
|
||||
return HID_PARSE_Successful;
|
||||
}
|
||||
|
||||
bool USB_GetHIDReportItemInfo(const uint8_t* ReportData,
|
||||
HID_ReportItem_t* const ReportItem)
|
||||
{
|
||||
if (ReportItem == NULL)
|
||||
return false;
|
||||
|
||||
uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
|
||||
uint16_t CurrentBit = ReportItem->BitOffset;
|
||||
uint32_t BitMask = (1 << 0);
|
||||
|
||||
if (ReportItem->ReportID)
|
||||
{
|
||||
if (ReportItem->ReportID != ReportData[0])
|
||||
return false;
|
||||
|
||||
ReportData++;
|
||||
}
|
||||
|
||||
ReportItem->PreviousValue = ReportItem->Value;
|
||||
ReportItem->Value = 0;
|
||||
|
||||
while (DataBitsRem--)
|
||||
{
|
||||
if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8)))
|
||||
ReportItem->Value |= BitMask;
|
||||
|
||||
CurrentBit++;
|
||||
BitMask <<= 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void USB_SetHIDReportItemInfo(uint8_t* ReportData,
|
||||
HID_ReportItem_t* const ReportItem)
|
||||
{
|
||||
if (ReportItem == NULL)
|
||||
return;
|
||||
|
||||
uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
|
||||
uint16_t CurrentBit = ReportItem->BitOffset;
|
||||
uint32_t BitMask = (1 << 0);
|
||||
|
||||
if (ReportItem->ReportID)
|
||||
{
|
||||
ReportData[0] = ReportItem->ReportID;
|
||||
ReportData++;
|
||||
}
|
||||
|
||||
ReportItem->PreviousValue = ReportItem->Value;
|
||||
|
||||
while (DataBitsRem--)
|
||||
{
|
||||
if (ReportItem->Value & BitMask)
|
||||
ReportData[CurrentBit / 8] |= (1 << (CurrentBit % 8));
|
||||
|
||||
CurrentBit++;
|
||||
BitMask <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData,
|
||||
const uint8_t ReportID,
|
||||
const uint8_t ReportType)
|
||||
{
|
||||
for (uint8_t i = 0; i < HID_MAX_REPORT_IDS; i++)
|
||||
{
|
||||
uint16_t ReportSizeBits = ParserData->ReportIDSizes[i].ReportSizeBits[ReportType];
|
||||
|
||||
if (ParserData->ReportIDSizes[i].ReportID == ReportID)
|
||||
return (ReportSizeBits / 8) + ((ReportSizeBits % 8) ? 1 : 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief USB Human Interface Device (HID) Class report descriptor parser.
|
||||
*
|
||||
* This file allows for the easy parsing of complex HID report descriptors, which describes the data that
|
||||
* a HID device transmits to the host. It also provides an easy API for extracting and processing the data
|
||||
* elements inside a HID report sent from an attached HID device.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USB
|
||||
* \defgroup Group_HIDParser HID Report Parser
|
||||
* \brief USB Human Interface Device (HID) Class report descriptor parser.
|
||||
*
|
||||
* \section Sec_HIDParser_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/HIDParser.c <i>(Makefile source module name: LUFA_SRC_USB)</i>
|
||||
*
|
||||
* \section Sec_HIDParser_ModDescription Module Description
|
||||
* Human Interface Device (HID) class report descriptor parser. This module implements a parser than is
|
||||
* capable of processing a complete HID report descriptor, and outputting a flat structure containing the
|
||||
* contents of the report in an a more friendly format. The parsed data may then be further processed and used
|
||||
* within an application to process sent and received HID reports to and from an attached HID device.
|
||||
*
|
||||
* A HID report descriptor consists of a set of HID report items, which describe the function and layout
|
||||
* of data exchanged between a HID device and a host, including both the physical encoding of each item
|
||||
* (such as a button, key press or joystick axis) in the sent and received data packets - known as "reports" -
|
||||
* as well as other information about each item such as the usages, data range, physical location and other
|
||||
* characteristics. In this way a HID device can retain a high degree of flexibility in its capabilities, as it
|
||||
* is not forced to comply with a given report layout or feature-set.
|
||||
*
|
||||
* This module also contains routines for the processing of data in an actual HID report, using the parsed report
|
||||
* descriptor data as a guide for the encoding.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __HIDPARSER_H__
|
||||
#define __HIDPARSER_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../../Common/Common.h"
|
||||
|
||||
#include "HIDReportData.h"
|
||||
#include "HIDClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
#if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__)
|
||||
/** Constant indicating the maximum stack depth of the state table. A larger state table
|
||||
* allows for more PUSH/POP report items to be nested, but consumes more memory. By default
|
||||
* this is set to 2 levels (allowing non-nested PUSH items) but this can be overridden by
|
||||
* defining \c HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the
|
||||
* define to the compiler using the -D compiler switch.
|
||||
*/
|
||||
#define HID_STATETABLE_STACK_DEPTH 2
|
||||
#endif
|
||||
|
||||
#if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__)
|
||||
/** Constant indicating the maximum stack depth of the usage table. A larger usage table
|
||||
* allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than
|
||||
* one, but requires more stack space. By default this is set to 8 levels (allowing for a report
|
||||
* item with a count of 8) but this can be overridden by defining \c HID_USAGE_STACK_DEPTH to another
|
||||
* value in the user project makefile, passing the define to the compiler using the -D compiler
|
||||
* switch.
|
||||
*/
|
||||
#define HID_USAGE_STACK_DEPTH 8
|
||||
#endif
|
||||
|
||||
#if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__)
|
||||
/** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be
|
||||
* processed in the report item descriptor. A large value allows for more COLLECTION items to be
|
||||
* processed, but consumes more memory. By default this is set to 10 collections, but this can be
|
||||
* overridden by defining \c HID_MAX_COLLECTIONS to another value in the user project makefile, passing
|
||||
* the define to the compiler using the -D compiler switch.
|
||||
*/
|
||||
#define HID_MAX_COLLECTIONS 10
|
||||
#endif
|
||||
|
||||
#if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__)
|
||||
/** Constant indicating the maximum number of report items (IN, OUT or FEATURE) that can be processed
|
||||
* in the report item descriptor and stored in the user HID Report Info structure. A large value allows
|
||||
* for more report items to be stored, but consumes more memory. By default this is set to 20 items,
|
||||
* but this can be overridden by defining \c HID_MAX_REPORTITEMS to another value in the user project
|
||||
* makefile, and passing the define to the compiler using the -D compiler switch.
|
||||
*/
|
||||
#define HID_MAX_REPORTITEMS 20
|
||||
#endif
|
||||
|
||||
#if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__)
|
||||
/** Constant indicating the maximum number of unique report IDs that can be processed in the report item
|
||||
* descriptor for the report size information array in the user HID Report Info structure. A large value
|
||||
* allows for more report ID report sizes to be stored, but consumes more memory. By default this is set
|
||||
* to 10 items, but this can be overridden by defining \c HID_MAX_REPORT_IDS to another value in the user project
|
||||
* makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE
|
||||
* items sharing the same report ID consume only one size item in the array.
|
||||
*/
|
||||
#define HID_MAX_REPORT_IDS 10
|
||||
#endif
|
||||
|
||||
/** Returns the value a given HID report item (once its value has been fetched via \ref USB_GetHIDReportItemInfo())
|
||||
* left-aligned to the given data type. This allows for signed data to be interpreted correctly, by shifting the data
|
||||
* leftwards until the data's sign bit is in the correct position.
|
||||
*
|
||||
* \param[in] ReportItem HID Report Item whose retrieved value is to be aligned.
|
||||
* \param[in] Type Data type to align the HID report item's value to.
|
||||
*
|
||||
* \return Left-aligned data of the given report item's pre-retrieved value for the given datatype.
|
||||
*/
|
||||
#define HID_ALIGN_DATA(ReportItem, Type) ((Type)(ReportItem->Value << ((8 * sizeof(Type)) - ReportItem->Attributes.BitSize)))
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function. */
|
||||
enum HID_Parse_ErrorCodes_t
|
||||
{
|
||||
HID_PARSE_Successful = 0, /**< Successful parse of the HID report descriptor, no error. */
|
||||
HID_PARSE_HIDStackOverflow = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */
|
||||
HID_PARSE_HIDStackUnderflow = 2, /**< A POP was found when the state table stack was empty. */
|
||||
HID_PARSE_InsufficientReportItems = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */
|
||||
HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */
|
||||
HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */
|
||||
HID_PARSE_UsageListOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
|
||||
HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */
|
||||
HID_PARSE_NoUnfilteredReportItems = 8, /**< All report items from the device were filtered by the filtering callback routine. */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief HID Parser Report Item Min/Max Structure.
|
||||
*
|
||||
* Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Minimum; /**< Minimum value for the attribute. */
|
||||
uint32_t Maximum; /**< Maximum value for the attribute. */
|
||||
} HID_MinMax_t;
|
||||
|
||||
/** \brief HID Parser Report Item Unit Structure.
|
||||
*
|
||||
* Type define for the Unit attributes of a report item.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Type; /**< Unit type (refer to HID specifications for details). */
|
||||
uint8_t Exponent; /**< Unit exponent (refer to HID specifications for details). */
|
||||
} HID_Unit_t;
|
||||
|
||||
/** \brief HID Parser Report Item Usage Structure.
|
||||
*
|
||||
* Type define for the Usage attributes of a report item.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Page; /**< Usage page of the report item. */
|
||||
uint16_t Usage; /**< Usage of the report item. */
|
||||
} HID_Usage_t;
|
||||
|
||||
/** \brief HID Parser Report Item Collection Path Structure.
|
||||
*
|
||||
* Type define for a COLLECTION object. Contains the collection attributes and a reference to the
|
||||
* parent collection if any.
|
||||
*/
|
||||
typedef struct HID_CollectionPath
|
||||
{
|
||||
uint8_t Type; /**< Collection type (e.g. "Generic Desktop"). */
|
||||
HID_Usage_t Usage; /**< Collection usage. */
|
||||
struct HID_CollectionPath* Parent; /**< Reference to parent collection, or \c NULL if root collection. */
|
||||
} HID_CollectionPath_t;
|
||||
|
||||
/** \brief HID Parser Report Item Attributes Structure.
|
||||
*
|
||||
* Type define for all the data attributes of a report item, except flags.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t BitSize; /**< Size in bits of the report item's data. */
|
||||
|
||||
HID_Usage_t Usage; /**< Usage of the report item. */
|
||||
HID_Unit_t Unit; /**< Unit type and exponent of the report item. */
|
||||
HID_MinMax_t Logical; /**< Logical minimum and maximum of the report item. */
|
||||
HID_MinMax_t Physical; /**< Physical minimum and maximum of the report item. */
|
||||
} HID_ReportItem_Attributes_t;
|
||||
|
||||
/** \brief HID Parser Report Item Details Structure.
|
||||
*
|
||||
* Type define for a report item (IN, OUT or FEATURE) layout attributes and other details.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t BitOffset; /**< Bit offset in the IN, OUT or FEATURE report of the item. */
|
||||
uint8_t ItemType; /**< Report item type, a value in \ref HID_ReportItemTypes_t. */
|
||||
uint16_t ItemFlags; /**< Item data flags, a mask of \c HID_IOF_* constants. */
|
||||
uint8_t ReportID; /**< Report ID this item belongs to, or 0x00 if device has only one report */
|
||||
HID_CollectionPath_t* CollectionPath; /**< Collection path of the item. */
|
||||
|
||||
HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */
|
||||
|
||||
uint32_t Value; /**< Current value of the report item - use \ref HID_ALIGN_DATA() when processing
|
||||
* a retrieved value so that it is aligned to a specific type.
|
||||
*/
|
||||
uint32_t PreviousValue; /**< Previous value of the report item. */
|
||||
} HID_ReportItem_t;
|
||||
|
||||
/** \brief HID Parser Report Size Structure.
|
||||
*
|
||||
* Type define for a report item size information structure, to retain the size of a device's reports by ID.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ReportID; /**< Report ID of the report within the HID interface. */
|
||||
uint16_t ReportSizeBits[3]; /**< Total number of bits in each report type for the given Report ID,
|
||||
* indexed by the \ref HID_ReportItemTypes_t enum.
|
||||
*/
|
||||
} HID_ReportSizeInfo_t;
|
||||
|
||||
/** \brief HID Parser State Structure.
|
||||
*
|
||||
* Type define for a complete processed HID report, including all report item data and collections.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t TotalReportItems; /**< Total number of report items stored in the \c ReportItems array. */
|
||||
HID_ReportItem_t ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including all IN, OUT
|
||||
* and FEATURE items.
|
||||
*/
|
||||
HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced
|
||||
* by the report items.
|
||||
*/
|
||||
uint8_t TotalDeviceReports; /**< Number of reports within the HID interface */
|
||||
HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /**< Report sizes for each report in the interface */
|
||||
uint16_t LargestReportSizeBits; /**< Largest report that the attached device will generate, in bits */
|
||||
bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID
|
||||
* element in its HID report descriptor.
|
||||
*/
|
||||
} HID_ReportInfo_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Function to process a given HID report returned from an attached device, and store it into a given
|
||||
* \ref HID_ReportInfo_t structure.
|
||||
*
|
||||
* \param[in] ReportData Buffer containing the device's HID report table.
|
||||
* \param[in] ReportSize Size in bytes of the HID report table.
|
||||
* \param[out] ParserData Pointer to a \ref HID_ReportInfo_t instance for the parser output.
|
||||
*
|
||||
* \return A value in the \ref HID_Parse_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t USB_ProcessHIDReport(const uint8_t* ReportData,
|
||||
uint16_t ReportSize,
|
||||
HID_ReportInfo_t* const ParserData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Extracts the given report item's value out of the given HID report and places it into the Value
|
||||
* member of the report item's \ref HID_ReportItem_t structure.
|
||||
*
|
||||
* When called on a report with an item that exists in that report, this copies the report item's \c Value
|
||||
* to its \c PreviousValue element for easy checking to see if an item's value has changed before processing
|
||||
* a report. If the given item does not exist in the report, the function does not modify the report item's
|
||||
* data.
|
||||
*
|
||||
* \param[in] ReportData Buffer containing an IN or FEATURE report from an attached device.
|
||||
* \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array.
|
||||
*
|
||||
* \returns Boolean \c true if the item to retrieve was located in the given report, \c false otherwise.
|
||||
*/
|
||||
bool USB_GetHIDReportItemInfo(const uint8_t* ReportData,
|
||||
HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Retrieves the given report item's value out of the \c Value member of the report item's
|
||||
* \ref HID_ReportItem_t structure and places it into the correct position in the HID report
|
||||
* buffer. The report buffer is assumed to have the appropriate bits cleared before calling
|
||||
* this function (i.e., the buffer should be explicitly cleared before report values are added).
|
||||
*
|
||||
* When called, this copies the report item's \c Value element to its \c PreviousValue element for easy
|
||||
* checking to see if an item's value has changed before sending a report.
|
||||
*
|
||||
* If the device has multiple HID reports, the first byte in the report is set to the report ID of the given item.
|
||||
*
|
||||
* \param[out] ReportData Buffer holding the current OUT or FEATURE report data.
|
||||
* \param[in] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array.
|
||||
*/
|
||||
void USB_SetHIDReportItemInfo(uint8_t* ReportData,
|
||||
HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Retrieves the size of a given HID report in bytes from its Report ID.
|
||||
*
|
||||
* \param[in] ParserData Pointer to a \ref HID_ReportInfo_t instance containing the parser output.
|
||||
* \param[in] ReportID Report ID of the report whose size is to be determined.
|
||||
* \param[in] ReportType Type of the report whose size is to be determined, a value from the
|
||||
* \ref HID_ReportItemTypes_t enum.
|
||||
*
|
||||
* \return Size of the report in bytes, or \c 0 if the report does not exist.
|
||||
*/
|
||||
uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData,
|
||||
const uint8_t ReportID,
|
||||
const uint8_t ReportType) ATTR_CONST ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Callback routine for the HID Report Parser. This callback <b>must</b> be implemented by the user code when
|
||||
* the parser is used, to determine what report IN, OUT and FEATURE item's information is stored into the user
|
||||
* \ref HID_ReportInfo_t structure. This can be used to filter only those items the application will be using, so that
|
||||
* no RAM is wasted storing the attributes for report items which will never be referenced by the application.
|
||||
*
|
||||
* Report item pointers passed to this callback function may be cached by the user application for later use
|
||||
* when processing report items. This provides faster report processing in the user application than would
|
||||
* a search of the entire parsed report item table for each received or sent report.
|
||||
*
|
||||
* \param[in] CurrentItem Pointer to the current report item for user checking.
|
||||
*
|
||||
* \return Boolean \c true if the item should be stored into the \ref HID_ReportInfo_t structure, \c false if
|
||||
* it should be ignored.
|
||||
*/
|
||||
bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Type Defines: */
|
||||
typedef struct
|
||||
{
|
||||
HID_ReportItem_Attributes_t Attributes;
|
||||
uint8_t ReportCount;
|
||||
uint8_t ReportID;
|
||||
} HID_StateTable_t;
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Constants for HID report item attributes.
|
||||
*
|
||||
* HID report item constants for report item attributes. Refer to the HID specification for
|
||||
* details on each flag's meaning when applied to an IN, OUT or FEATURE item.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_HIDParser
|
||||
* \defgroup Group_HIDReportItemConst HID Report Descriptor Item Constants
|
||||
*
|
||||
* General HID constant definitions for HID Report Descriptor elements.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __HIDREPORTDATA_H__
|
||||
#define __HIDREPORTDATA_H__
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define HID_RI_DATA_SIZE_MASK 0x03
|
||||
#define HID_RI_TYPE_MASK 0x0C
|
||||
#define HID_RI_TAG_MASK 0xF0
|
||||
|
||||
#define HID_RI_TYPE_MAIN 0x00
|
||||
#define HID_RI_TYPE_GLOBAL 0x04
|
||||
#define HID_RI_TYPE_LOCAL 0x08
|
||||
|
||||
#define HID_RI_DATA_BITS_0 0x00
|
||||
#define HID_RI_DATA_BITS_8 0x01
|
||||
#define HID_RI_DATA_BITS_16 0x02
|
||||
#define HID_RI_DATA_BITS_32 0x03
|
||||
#define HID_RI_DATA_BITS(DataBits) CONCAT_EXPANDED(HID_RI_DATA_BITS_, DataBits)
|
||||
|
||||
#define _HID_RI_ENCODE_0(Data)
|
||||
#define _HID_RI_ENCODE_8(Data) , (Data & 0xFF)
|
||||
#define _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_8(Data) _HID_RI_ENCODE_8(Data >> 8)
|
||||
#define _HID_RI_ENCODE_32(Data) _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_16(Data >> 16)
|
||||
#define _HID_RI_ENCODE(DataBits, ...) CONCAT_EXPANDED(_HID_RI_ENCODE_, DataBits(__VA_ARGS__))
|
||||
|
||||
#define _HID_RI_ENTRY(Type, Tag, DataBits, ...) (Type | Tag | HID_RI_DATA_BITS(DataBits)) _HID_RI_ENCODE(DataBits, (__VA_ARGS__))
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name HID Input, Output and Feature Report Descriptor Item Flags */
|
||||
//@{
|
||||
#define HID_IOF_CONSTANT (1 << 0)
|
||||
#define HID_IOF_DATA (0 << 0)
|
||||
#define HID_IOF_VARIABLE (1 << 1)
|
||||
#define HID_IOF_ARRAY (0 << 1)
|
||||
#define HID_IOF_RELATIVE (1 << 2)
|
||||
#define HID_IOF_ABSOLUTE (0 << 2)
|
||||
#define HID_IOF_WRAP (1 << 3)
|
||||
#define HID_IOF_NO_WRAP (0 << 3)
|
||||
#define HID_IOF_NON_LINEAR (1 << 4)
|
||||
#define HID_IOF_LINEAR (0 << 4)
|
||||
#define HID_IOF_NO_PREFERRED_STATE (1 << 5)
|
||||
#define HID_IOF_PREFERRED_STATE (0 << 5)
|
||||
#define HID_IOF_NULLSTATE (1 << 6)
|
||||
#define HID_IOF_NO_NULL_POSITION (0 << 6)
|
||||
#define HID_IOF_VOLATILE (1 << 7)
|
||||
#define HID_IOF_NON_VOLATILE (0 << 7)
|
||||
#define HID_IOF_BUFFERED_BYTES (1 << 8)
|
||||
#define HID_IOF_BITFIELD (0 << 8)
|
||||
//@}
|
||||
|
||||
/** \name HID Report Descriptor Item Macros */
|
||||
//@{
|
||||
#define HID_RI_INPUT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0x80, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_OUTPUT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0x90, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_COLLECTION(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xA0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_FEATURE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xB0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_END_COLLECTION(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xC0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE_PAGE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x00, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_LOGICAL_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x10, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_LOGICAL_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x20, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_PHYSICAL_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x30, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_PHYSICAL_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x40, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_UNIT_EXPONENT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x50, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_UNIT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x60, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_REPORT_SIZE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x70, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_REPORT_ID(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x80, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_REPORT_COUNT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x90, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_PUSH(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xA0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_POP(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xB0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x00, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x10, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x20, DataBits, __VA_ARGS__)
|
||||
//@}
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB MIDI Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB MIDI Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassMIDI
|
||||
* \defgroup Group_USBClassMIDICommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassMIDICommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* MIDI Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MIDI_CLASS_COMMON_H_
|
||||
#define _MIDI_CLASS_COMMON_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_AUDIO_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
#include "AudioClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** \name MIDI Command Values
|
||||
* See http://www.midi.org/techspecs/midimessages.php for more information.
|
||||
*/
|
||||
//@{
|
||||
/** MIDI command for System Exclusive (SysEx) single event that has one byte of data total. */
|
||||
#define MIDI_COMMAND_SYSEX_1BYTE MIDI_COMMAND_SYSEX_END_1BYTE
|
||||
|
||||
/** MIDI command for System Exclusive (SysEx) single event that has two bytes of data total. */
|
||||
#define MIDI_COMMAND_SYSEX_2BYTE 0x20
|
||||
|
||||
/** MIDI command for System Exclusive (SysEx) single event that has three bytes of data total. */
|
||||
#define MIDI_COMMAND_SYSEX_3BYTE 0x30
|
||||
|
||||
/** MIDI command for System Exclusive (SysEx) stream event that has at least four bytes of data total. */
|
||||
#define MIDI_COMMAND_SYSEX_START_3BYTE 0x40
|
||||
|
||||
/** MIDI command for System Exclusive (SysEx) stream event terminator with one remaining data byte. */
|
||||
#define MIDI_COMMAND_SYSEX_END_1BYTE 0x50
|
||||
|
||||
/** MIDI command for System Exclusive (SysEx) stream event terminator with two remaining data bytes. */
|
||||
#define MIDI_COMMAND_SYSEX_END_2BYTE 0x60
|
||||
|
||||
/** MIDI command for System Exclusive (SysEx) stream event terminator with three remaining data bytes. */
|
||||
#define MIDI_COMMAND_SYSEX_END_3BYTE 0x70
|
||||
|
||||
/** MIDI command for a note off (deactivation) event. */
|
||||
#define MIDI_COMMAND_NOTE_OFF 0x80
|
||||
|
||||
/** MIDI command for a note on (activation) event. */
|
||||
#define MIDI_COMMAND_NOTE_ON 0x90
|
||||
|
||||
/** MIDI command for a note pressure change event. */
|
||||
#define MIDI_COMMAND_NOTE_PRESSURE 0xA0
|
||||
|
||||
/** MIDI command for a control change event. */
|
||||
#define MIDI_COMMAND_CONTROL_CHANGE 0xB0
|
||||
|
||||
/** MIDI command for a control change event. */
|
||||
#define MIDI_COMMAND_PROGRAM_CHANGE 0xC0
|
||||
|
||||
/** MIDI command for a channel pressure change event. */
|
||||
#define MIDI_COMMAND_CHANNEL_PRESSURE 0xD0
|
||||
|
||||
/** MIDI command for a pitch change event. */
|
||||
#define MIDI_COMMAND_PITCH_WHEEL_CHANGE 0xE0
|
||||
//@}
|
||||
|
||||
/** Standard key press velocity value used for all note events. */
|
||||
#define MIDI_STANDARD_VELOCITY 64
|
||||
|
||||
/** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel
|
||||
* addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address.
|
||||
*
|
||||
* \param[in] channel MIDI channel number to address.
|
||||
*
|
||||
* \return Constructed MIDI channel ID.
|
||||
*/
|
||||
#define MIDI_CHANNEL(channel) ((channel) - 1)
|
||||
|
||||
/** Constructs a MIDI event ID from a given MIDI command and a virtual MIDI cable index. This can then be
|
||||
* used to create and decode \ref MIDI_EventPacket_t MIDI event packets.
|
||||
*
|
||||
* \param[in] virtualcable Index of the virtual MIDI cable the event relates to
|
||||
* \param[in] command MIDI command to send through the virtual MIDI cable
|
||||
*
|
||||
* \return Constructed MIDI event ID.
|
||||
*/
|
||||
#define MIDI_EVENT(virtualcable, command) (((virtualcable) << 4) | ((command) >> 4))
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible MIDI jack types in a MIDI device jack descriptor. */
|
||||
enum MIDI_JackTypes_t
|
||||
{
|
||||
MIDI_JACKTYPE_Embedded = 0x01, /**< MIDI class descriptor jack type value for an embedded (logical) MIDI input or output jack. */
|
||||
MIDI_JACKTYPE_External = 0x02, /**< MIDI class descriptor jack type value for an external (physical) MIDI input or output jack. */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief MIDI class-specific Streaming Interface Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host
|
||||
* how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors.
|
||||
* See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_MIDI_StdDescriptor_AudioInterface_AS_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint16_t AudioSpecification; /**< Binary coded decimal value, indicating the supported Audio Class
|
||||
* specification version.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
|
||||
} ATTR_PACKED USB_MIDI_Descriptor_AudioInterface_AS_t;
|
||||
|
||||
/** \brief MIDI class-specific Streaming Interface Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host
|
||||
* how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors.
|
||||
* See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_MIDI_Descriptor_AudioInterface_AS_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint16_t bcdMSC; /**< Binary coded decimal value, indicating the supported MIDI Class specification version.
|
||||
*
|
||||
* \see \ref VERSION_BCD() utility macro.
|
||||
*/
|
||||
uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
|
||||
} ATTR_PACKED USB_MIDI_StdDescriptor_AudioInterface_AS_t;
|
||||
|
||||
/** \brief MIDI class-specific Input Jack Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either
|
||||
* a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint).
|
||||
*
|
||||
* \see \ref USB_MIDI_StdDescriptor_InputJack_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint8_t JackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */
|
||||
uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */
|
||||
|
||||
uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_MIDI_Descriptor_InputJack_t;
|
||||
|
||||
/** \brief MIDI class-specific Input Jack Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either
|
||||
* a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint).
|
||||
*
|
||||
* \see \ref USB_MIDI_Descriptor_InputJack_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint8_t bJackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */
|
||||
uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */
|
||||
|
||||
uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_MIDI_StdDescriptor_InputJack_t;
|
||||
|
||||
/** \brief MIDI class-specific Output Jack Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either
|
||||
* a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint).
|
||||
*
|
||||
* \see \ref USB_MIDI_StdDescriptor_OutputJack_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint8_t JackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */
|
||||
uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */
|
||||
|
||||
uint8_t NumberOfPins; /**< Number of output channels within the jack, either physical or logical. */
|
||||
uint8_t SourceJackID[1]; /**< ID of each output pin's source data jack. */
|
||||
uint8_t SourcePinID[1]; /**< Pin number in the input jack of each output pin's source data. */
|
||||
|
||||
uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_MIDI_Descriptor_OutputJack_t;
|
||||
|
||||
/** \brief MIDI class-specific Output Jack Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either
|
||||
* a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint).
|
||||
*
|
||||
* \see \ref USB_MIDI_Descriptor_OutputJack_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint8_t bJackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */
|
||||
uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */
|
||||
|
||||
uint8_t bNrInputPins; /**< Number of output channels within the jack, either physical or logical. */
|
||||
uint8_t baSourceID[1]; /**< ID of each output pin's source data jack. */
|
||||
uint8_t baSourcePin[1]; /**< Pin number in the input jack of each output pin's source data. */
|
||||
|
||||
uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */
|
||||
} ATTR_PACKED USB_MIDI_StdDescriptor_OutputJack_t;
|
||||
|
||||
/** \brief Audio class-specific Jack Endpoint Descriptor (LUFA naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information
|
||||
* on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio
|
||||
* class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_MIDI_StdDescriptor_Jack_Endpoint_t for the version of this type with standard element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
|
||||
uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint8_t TotalEmbeddedJacks; /**< Total number of jacks inside this endpoint. */
|
||||
uint8_t AssociatedJackID[1]; /**< IDs of each jack inside the endpoint. */
|
||||
} ATTR_PACKED USB_MIDI_Descriptor_Jack_Endpoint_t;
|
||||
|
||||
/** \brief Audio class-specific Jack Endpoint Descriptor (USB-IF naming conventions).
|
||||
*
|
||||
* Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information
|
||||
* on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio
|
||||
* class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details.
|
||||
*
|
||||
* \see \ref USB_MIDI_Descriptor_Jack_Endpoint_t for the version of this type with non-standard LUFA specific
|
||||
* element names.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
|
||||
|
||||
uint8_t bNumEmbMIDIJack; /**< Total number of jacks inside this endpoint. */
|
||||
uint8_t bAssocJackID[1]; /**< IDs of each jack inside the endpoint. */
|
||||
} ATTR_PACKED USB_MIDI_StdDescriptor_Jack_Endpoint_t;
|
||||
|
||||
/** \brief MIDI Class Driver Event Packet.
|
||||
*
|
||||
* Type define for a USB MIDI event packet, used to encapsulate sent and received MIDI messages from a USB MIDI interface.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Event; /**< MIDI event type, constructed with the \ref MIDI_EVENT() macro. */
|
||||
|
||||
uint8_t Data1; /**< First byte of data in the MIDI event. */
|
||||
uint8_t Data2; /**< Second byte of data in the MIDI event. */
|
||||
uint8_t Data3; /**< Third byte of data in the MIDI event. */
|
||||
} ATTR_PACKED MIDI_EventPacket_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB Mass Storage Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB Mass Storage Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassMS
|
||||
* \defgroup Group_USBClassMSCommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassMSCommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* Mass Storage Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MS_CLASS_COMMON_H_
|
||||
#define _MS_CLASS_COMMON_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_MS_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
|
||||
#define MS_CBW_SIGNATURE 0x43425355UL
|
||||
|
||||
/** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
|
||||
#define MS_CSW_SIGNATURE 0x53425355UL
|
||||
|
||||
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
|
||||
#define MS_COMMAND_DIR_DATA_OUT (0 << 7)
|
||||
|
||||
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
|
||||
#define MS_COMMAND_DIR_DATA_IN (1 << 7)
|
||||
|
||||
/** \name SCSI Commands*/
|
||||
//@{
|
||||
/** SCSI Command Code for an INQUIRY command. */
|
||||
#define SCSI_CMD_INQUIRY 0x12
|
||||
|
||||
/** SCSI Command Code for a REQUEST SENSE command. */
|
||||
#define SCSI_CMD_REQUEST_SENSE 0x03
|
||||
|
||||
/** SCSI Command Code for a TEST UNIT READY command. */
|
||||
#define SCSI_CMD_TEST_UNIT_READY 0x00
|
||||
|
||||
/** SCSI Command Code for a READ CAPACITY (10) command. */
|
||||
#define SCSI_CMD_READ_CAPACITY_10 0x25
|
||||
|
||||
/** SCSI Command Code for a START STOP UNIT command. */
|
||||
#define SCSI_CMD_START_STOP_UNIT 0x1B
|
||||
|
||||
/** SCSI Command Code for a SEND DIAGNOSTIC command. */
|
||||
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
|
||||
|
||||
/** SCSI Command Code for a PREVENT ALLOW MEDIUM REMOVAL command. */
|
||||
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
|
||||
|
||||
/** SCSI Command Code for a WRITE (10) command. */
|
||||
#define SCSI_CMD_WRITE_10 0x2A
|
||||
|
||||
/** SCSI Command Code for a READ (10) command. */
|
||||
#define SCSI_CMD_READ_10 0x28
|
||||
|
||||
/** SCSI Command Code for a WRITE (6) command. */
|
||||
#define SCSI_CMD_WRITE_6 0x0A
|
||||
|
||||
/** SCSI Command Code for a READ (6) command. */
|
||||
#define SCSI_CMD_READ_6 0x08
|
||||
|
||||
/** SCSI Command Code for a VERIFY (10) command. */
|
||||
#define SCSI_CMD_VERIFY_10 0x2F
|
||||
|
||||
/** SCSI Command Code for a MODE SENSE (6) command. */
|
||||
#define SCSI_CMD_MODE_SENSE_6 0x1A
|
||||
|
||||
/** SCSI Command Code for a MODE SENSE (10) command. */
|
||||
#define SCSI_CMD_MODE_SENSE_10 0x5A
|
||||
//@}
|
||||
|
||||
/** \name SCSI Sense Key Values */
|
||||
//@{
|
||||
/** SCSI Sense Code to indicate no error has occurred. */
|
||||
#define SCSI_SENSE_KEY_GOOD 0x00
|
||||
|
||||
/** SCSI Sense Code to indicate that the device has recovered from an error. */
|
||||
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
|
||||
/** SCSI Sense Code to indicate that the device is not ready for a new command. */
|
||||
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
||||
|
||||
/** SCSI Sense Code to indicate an error whilst accessing the medium. */
|
||||
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
|
||||
/** SCSI Sense Code to indicate a hardware error has occurred. */
|
||||
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
|
||||
/** SCSI Sense Code to indicate that an illegal request has been issued. */
|
||||
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
|
||||
/** SCSI Sense Code to indicate that the unit requires attention from the host to indicate
|
||||
* a reset event, medium removal or other condition.
|
||||
*/
|
||||
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
|
||||
/** SCSI Sense Code to indicate that a write attempt on a protected block has been made. */
|
||||
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
||||
|
||||
/** SCSI Sense Code to indicate an error while trying to write to a write-once medium. */
|
||||
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
||||
|
||||
/** SCSI Sense Code to indicate a vendor specific error has occurred. */
|
||||
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
||||
|
||||
/** SCSI Sense Code to indicate that an EXTENDED COPY command has aborted due to an error. */
|
||||
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
||||
|
||||
/** SCSI Sense Code to indicate that the device has aborted the issued command. */
|
||||
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
|
||||
/** SCSI Sense Code to indicate an attempt to write past the end of a partition has been made. */
|
||||
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
|
||||
/** SCSI Sense Code to indicate that the source data did not match the data read from the medium. */
|
||||
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
||||
//@}
|
||||
|
||||
/** \name SCSI Additional Sense Codes */
|
||||
//@{
|
||||
/** SCSI Additional Sense Code to indicate no additional sense information is available. */
|
||||
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
|
||||
|
||||
/** SCSI Additional Sense Code to indicate that the logical unit (LUN) addressed is not ready. */
|
||||
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
|
||||
|
||||
/** SCSI Additional Sense Code to indicate an invalid field was encountered while processing the issued command. */
|
||||
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
|
||||
|
||||
/** SCSI Additional Sense Code to indicate that a medium that was previously indicated as not ready has now
|
||||
* become ready for use.
|
||||
*/
|
||||
#define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28
|
||||
|
||||
/** SCSI Additional Sense Code to indicate that an attempt to write to a protected area was made. */
|
||||
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
|
||||
|
||||
/** SCSI Additional Sense Code to indicate an error whilst formatting the device medium. */
|
||||
#define SCSI_ASENSE_FORMAT_ERROR 0x31
|
||||
|
||||
/** SCSI Additional Sense Code to indicate an invalid command was issued. */
|
||||
#define SCSI_ASENSE_INVALID_COMMAND 0x20
|
||||
|
||||
/** SCSI Additional Sense Code to indicate a write to a block out outside of the medium's range was issued. */
|
||||
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
|
||||
|
||||
/** SCSI Additional Sense Code to indicate that no removable medium is inserted into the device. */
|
||||
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
|
||||
//@}
|
||||
|
||||
/** \name SCSI Additional Sense Key Code Qualifiers */
|
||||
//@{
|
||||
/** SCSI Additional Sense Qualifier Code to indicate no additional sense qualifier information is available. */
|
||||
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
|
||||
|
||||
/** SCSI Additional Sense Qualifier Code to indicate that a medium format command failed to complete. */
|
||||
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
|
||||
|
||||
/** SCSI Additional Sense Qualifier Code to indicate that an initializing command must be issued before the issued
|
||||
* command can be executed.
|
||||
*/
|
||||
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
|
||||
/** SCSI Additional Sense Qualifier Code to indicate that an operation is currently in progress. */
|
||||
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
|
||||
//@}
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Mass
|
||||
* Storage device class.
|
||||
*/
|
||||
enum MS_Descriptor_ClassSubclassProtocol_t
|
||||
{
|
||||
MS_CSCP_MassStorageClass = 0x08, /**< Descriptor Class value indicating that the device or interface
|
||||
* belongs to the Mass Storage class.
|
||||
*/
|
||||
MS_CSCP_SCSITransparentSubclass = 0x06, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* belongs to the SCSI Transparent Command Set subclass of the Mass
|
||||
* storage class.
|
||||
*/
|
||||
MS_CSCP_BulkOnlyTransportProtocol = 0x50, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to the Bulk Only Transport protocol of the Mass Storage class.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the Mass Storage class specific control requests that can be issued by the USB bus host. */
|
||||
enum MS_ClassRequests_t
|
||||
{
|
||||
MS_REQ_GetMaxLUN = 0xFE, /**< Mass Storage class-specific request to retrieve the total number of Logical
|
||||
* Units (drives) in the SCSI device.
|
||||
*/
|
||||
MS_REQ_MassStorageReset = 0xFF, /**< Mass Storage class-specific request to reset the Mass Storage interface,
|
||||
* ready for the next command.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the possible command status wrapper return status codes. */
|
||||
enum MS_CommandStatusCodes_t
|
||||
{
|
||||
MS_SCSI_COMMAND_Pass = 0, /**< Command completed with no error */
|
||||
MS_SCSI_COMMAND_Fail = 1, /**< Command failed to complete - host may check the exact error via a
|
||||
* SCSI REQUEST SENSE command.
|
||||
*/
|
||||
MS_SCSI_COMMAND_PhaseError = 2, /**< Command failed due to being invalid in the current phase. */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief Mass Storage Class Command Block Wrapper.
|
||||
*
|
||||
* Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Signature; /**< Command block signature, must be \ref MS_CBW_SIGNATURE to indicate a valid Command Block. */
|
||||
uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */
|
||||
uint32_t DataTransferLength; /**< Length of the optional data portion of the issued command, in bytes. */
|
||||
uint8_t Flags; /**< Command block flags, indicating command data direction. */
|
||||
uint8_t LUN; /**< Logical Unit number this command is issued to. */
|
||||
uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array. */
|
||||
uint8_t SCSICommandData[16]; /**< Issued SCSI command in the Command Block. */
|
||||
} ATTR_PACKED MS_CommandBlockWrapper_t;
|
||||
|
||||
/** \brief Mass Storage Class Command Status Wrapper.
|
||||
*
|
||||
* Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Signature; /**< Status block signature, must be \ref MS_CSW_SIGNATURE to indicate a valid Command Status. */
|
||||
uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */
|
||||
uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command. */
|
||||
uint8_t Status; /**< Status code of the issued command - a value from the \ref MS_CommandStatusCodes_t enum. */
|
||||
} ATTR_PACKED MS_CommandStatusWrapper_t;
|
||||
|
||||
/** \brief Mass Storage Class SCSI Sense Structure
|
||||
*
|
||||
* Type define for a SCSI Sense structure. Structures of this type are filled out by the
|
||||
* device via the \ref MS_Host_RequestSense() function, indicating the current sense data of the
|
||||
* device (giving explicit error codes for the last issued command). For details of the
|
||||
* structure contents, refer to the SCSI specifications.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ResponseCode;
|
||||
|
||||
uint8_t SegmentNumber;
|
||||
|
||||
unsigned SenseKey : 4;
|
||||
unsigned Reserved : 1;
|
||||
unsigned ILI : 1;
|
||||
unsigned EOM : 1;
|
||||
unsigned FileMark : 1;
|
||||
|
||||
uint8_t Information[4];
|
||||
uint8_t AdditionalLength;
|
||||
uint8_t CmdSpecificInformation[4];
|
||||
uint8_t AdditionalSenseCode;
|
||||
uint8_t AdditionalSenseQualifier;
|
||||
uint8_t FieldReplaceableUnitCode;
|
||||
uint8_t SenseKeySpecific[3];
|
||||
} ATTR_PACKED SCSI_Request_Sense_Response_t;
|
||||
|
||||
/** \brief Mass Storage Class SCSI Inquiry Structure.
|
||||
*
|
||||
* Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
|
||||
* device via the \ref MS_Host_GetInquiryData() function, retrieving the attached device's
|
||||
* information.
|
||||
*
|
||||
* For details of the structure contents, refer to the SCSI specifications.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned DeviceType : 5;
|
||||
unsigned PeripheralQualifier : 3;
|
||||
|
||||
unsigned Reserved : 7;
|
||||
unsigned Removable : 1;
|
||||
|
||||
uint8_t Version;
|
||||
|
||||
unsigned ResponseDataFormat : 4;
|
||||
unsigned Reserved2 : 1;
|
||||
unsigned NormACA : 1;
|
||||
unsigned TrmTsk : 1;
|
||||
unsigned AERC : 1;
|
||||
|
||||
uint8_t AdditionalLength;
|
||||
uint8_t Reserved3[2];
|
||||
|
||||
unsigned SoftReset : 1;
|
||||
unsigned CmdQue : 1;
|
||||
unsigned Reserved4 : 1;
|
||||
unsigned Linked : 1;
|
||||
unsigned Sync : 1;
|
||||
unsigned WideBus16Bit : 1;
|
||||
unsigned WideBus32Bit : 1;
|
||||
unsigned RelAddr : 1;
|
||||
|
||||
uint8_t VendorID[8];
|
||||
uint8_t ProductID[16];
|
||||
uint8_t RevisionID[4];
|
||||
} ATTR_PACKED SCSI_Inquiry_Response_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB Printer Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB Printer Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassPrinter
|
||||
* \defgroup Group_USBClassPrinterCommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassPrinterCommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* Printer Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PRINTER_CLASS_COMMON_H_
|
||||
#define _PRINTER_CLASS_COMMON_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** \name Virtual Printer Status Line Masks */
|
||||
//@{
|
||||
/** Port status mask for a printer device, indicating that an error has *not* occurred. */
|
||||
#define PRNT_PORTSTATUS_NOTERROR (1 << 3)
|
||||
|
||||
/** Port status mask for a printer device, indicating that the device is currently selected. */
|
||||
#define PRNT_PORTSTATUS_SELECT (1 << 4)
|
||||
|
||||
/** Port status mask for a printer device, indicating that the device is currently out of paper. */
|
||||
#define PRNT_PORTSTATUS_PAPEREMPTY (1 << 5)
|
||||
//@}
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Printer
|
||||
* device class.
|
||||
*/
|
||||
enum PRNT_Descriptor_ClassSubclassProtocol_t
|
||||
{
|
||||
PRNT_CSCP_PrinterClass = 0x07, /**< Descriptor Class value indicating that the device or interface
|
||||
* belongs to the Printer class.
|
||||
*/
|
||||
PRNT_CSCP_PrinterSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* belongs to the Printer subclass.
|
||||
*/
|
||||
PRNT_CSCP_BidirectionalProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to the Bidirectional protocol of the Printer class.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the Printer class specific control requests that can be issued by the USB bus host. */
|
||||
enum PRNT_ClassRequests_t
|
||||
{
|
||||
PRNT_REQ_GetDeviceID = 0x00, /**< Printer class-specific request to retrieve the Unicode ID
|
||||
* string of the device, containing the device's name, manufacturer
|
||||
* and supported printer languages.
|
||||
*/
|
||||
PRNT_REQ_GetPortStatus = 0x01, /**< Printer class-specific request to get the current status of the
|
||||
* virtual printer port, for device selection and ready states.
|
||||
*/
|
||||
PRNT_REQ_SoftReset = 0x02, /**< Printer class-specific request to reset the device, ready for new
|
||||
* printer commands.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB RNDIS Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB RNDIS Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassRNDIS
|
||||
* \defgroup Group_USBClassRNDISCommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassRNDISCommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* RNDIS Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_CLASS_COMMON_H_
|
||||
#define _RNDIS_CLASS_COMMON_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_CDC_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
#include "CDCClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** Additional error code for RNDIS functions when a device returns a logical command failure. */
|
||||
#define RNDIS_ERROR_LOGICAL_CMD_FAILED 0x80
|
||||
|
||||
/** Implemented RNDIS Version Major. */
|
||||
#define REMOTE_NDIS_VERSION_MAJOR 0x01
|
||||
|
||||
/** Implemented RNDIS Version Minor. */
|
||||
#define REMOTE_NDIS_VERSION_MINOR 0x00
|
||||
|
||||
/** \name RNDIS Message Values */
|
||||
//@{
|
||||
#define REMOTE_NDIS_PACKET_MSG 0x00000001UL
|
||||
#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL
|
||||
#define REMOTE_NDIS_HALT_MSG 0x00000003UL
|
||||
#define REMOTE_NDIS_QUERY_MSG 0x00000004UL
|
||||
#define REMOTE_NDIS_SET_MSG 0x00000005UL
|
||||
#define REMOTE_NDIS_RESET_MSG 0x00000006UL
|
||||
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL
|
||||
//@}
|
||||
|
||||
/** \name RNDIS Response Values */
|
||||
//@{
|
||||
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL
|
||||
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL
|
||||
#define REMOTE_NDIS_SET_CMPLT 0x80000005UL
|
||||
#define REMOTE_NDIS_RESET_CMPLT 0x80000006UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL
|
||||
//@}
|
||||
|
||||
/** \name RNDIS Status Values */
|
||||
//@{
|
||||
#define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL
|
||||
#define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL
|
||||
#define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL
|
||||
#define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
|
||||
//@}
|
||||
|
||||
/** \name RNDIS Media States */
|
||||
//@{
|
||||
#define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
|
||||
#define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
|
||||
//@}
|
||||
|
||||
/** \name RNDIS Media Types */
|
||||
//@{
|
||||
#define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
|
||||
//@}
|
||||
|
||||
/** \name RNDIS Connection Types */
|
||||
//@{
|
||||
#define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
|
||||
#define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
|
||||
//@}
|
||||
|
||||
/** \name RNDIS Packet Types */
|
||||
//@{
|
||||
#define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL
|
||||
#define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL
|
||||
#define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL
|
||||
#define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL
|
||||
#define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL
|
||||
#define REMOTE_NDIS_PACKET_SMT 0x00000040UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL
|
||||
#define REMOTE_NDIS_PACKET_GROUP 0x00001000UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
|
||||
#define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL
|
||||
#define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL
|
||||
//@}
|
||||
|
||||
/** \name RNDIS OID Values */
|
||||
//@{
|
||||
#define OID_GEN_SUPPORTED_LIST 0x00010101UL
|
||||
#define OID_GEN_HARDWARE_STATUS 0x00010102UL
|
||||
#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
|
||||
#define OID_GEN_MEDIA_IN_USE 0x00010104UL
|
||||
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_LINK_SPEED 0x00010107UL
|
||||
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
|
||||
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
|
||||
#define OID_GEN_VENDOR_ID 0x0001010CUL
|
||||
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
|
||||
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
|
||||
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
|
||||
#define OID_GEN_XMIT_OK 0x00020101UL
|
||||
#define OID_GEN_RCV_OK 0x00020102UL
|
||||
#define OID_GEN_XMIT_ERROR 0x00020103UL
|
||||
#define OID_GEN_RCV_ERROR 0x00020104UL
|
||||
#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
|
||||
#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
|
||||
#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
|
||||
#define OID_802_3_MULTICAST_LIST 0x01010103UL
|
||||
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
|
||||
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
|
||||
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
|
||||
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
|
||||
//@}
|
||||
|
||||
/** Maximum size in bytes of an Ethernet frame according to the Ethernet standard. */
|
||||
#define ETHERNET_FRAME_SIZE_MAX 1500
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the RNDIS class specific control requests that can be issued by the USB bus host. */
|
||||
enum RNDIS_ClassRequests_t
|
||||
{
|
||||
RNDIS_REQ_SendEncapsulatedCommand = 0x00, /**< RNDIS request to issue a host-to-device NDIS command. */
|
||||
RNDIS_REQ_GetEncapsulatedResponse = 0x01, /**< RNDIS request to issue a device-to-host NDIS response. */
|
||||
};
|
||||
|
||||
/** Enum for the possible NDIS adapter states. */
|
||||
enum RNDIS_States_t
|
||||
{
|
||||
RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized. */
|
||||
RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers. */
|
||||
RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers. */
|
||||
};
|
||||
|
||||
/** Enum for the RNDIS class specific notification requests that can be issued by a RNDIS device to a host. */
|
||||
enum RNDIS_ClassNotifications_t
|
||||
{
|
||||
RNDIS_NOTIF_ResponseAvailable = 0x01, /**< Notification request value for a RNDIS Response Available notification. */
|
||||
};
|
||||
|
||||
/** Enum for the NDIS hardware states. */
|
||||
enum NDIS_Hardware_Status_t
|
||||
{
|
||||
NDIS_HardwareStatus_Ready, /**< Hardware Ready to accept commands from the host. */
|
||||
NDIS_HardwareStatus_Initializing, /**< Hardware busy initializing. */
|
||||
NDIS_HardwareStatus_Reset, /**< Hardware reset. */
|
||||
NDIS_HardwareStatus_Closing, /**< Hardware currently closing. */
|
||||
NDIS_HardwareStatus_NotReady /**< Hardware not ready to accept commands from the host. */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief MAC Address Structure.
|
||||
*
|
||||
* Type define for a physical MAC address of a device on a network.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Octets[6]; /**< Individual bytes of a MAC address */
|
||||
} ATTR_PACKED MAC_Address_t;
|
||||
|
||||
/** \brief RNDIS Common Message Header Structure.
|
||||
*
|
||||
* Type define for a RNDIS message header, sent before RNDIS messages.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType; /**< RNDIS message type, a \c REMOTE_NDIS_*_MSG constant */
|
||||
uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
|
||||
} ATTR_PACKED RNDIS_Message_Header_t;
|
||||
|
||||
/** \brief RNDIS Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t DataOffset;
|
||||
uint32_t DataLength;
|
||||
uint32_t OOBDataOffset;
|
||||
uint32_t OOBDataLength;
|
||||
uint32_t NumOOBDataElements;
|
||||
uint32_t PerPacketInfoOffset;
|
||||
uint32_t PerPacketInfoLength;
|
||||
uint32_t VcHandle;
|
||||
uint32_t Reserved;
|
||||
} ATTR_PACKED RNDIS_Packet_Message_t;
|
||||
|
||||
/** \brief RNDIS Initialization Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS Initialize command message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t MaxTransferSize;
|
||||
} ATTR_PACKED RNDIS_Initialize_Message_t;
|
||||
|
||||
/** \brief RNDIS Initialize Complete Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS Initialize Complete response message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t DeviceFlags;
|
||||
uint32_t Medium;
|
||||
uint32_t MaxPacketsPerTransfer;
|
||||
uint32_t MaxTransferSize;
|
||||
uint32_t PacketAlignmentFactor;
|
||||
uint32_t AFListOffset;
|
||||
uint32_t AFListSize;
|
||||
} ATTR_PACKED RNDIS_Initialize_Complete_t;
|
||||
|
||||
/** \brief RNDIS Keep Alive Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS Keep Alive command message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
} ATTR_PACKED RNDIS_KeepAlive_Message_t;
|
||||
|
||||
/** \brief RNDIS Keep Alive Complete Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS Keep Alive Complete response message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} ATTR_PACKED RNDIS_KeepAlive_Complete_t;
|
||||
|
||||
/** \brief RNDIS Reset Complete Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS Reset Complete response message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t AddressingReset;
|
||||
} ATTR_PACKED RNDIS_Reset_Complete_t;
|
||||
|
||||
/** \brief RNDIS OID Property Set Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS OID Property Set command message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} ATTR_PACKED RNDIS_Set_Message_t;
|
||||
|
||||
/** \brief RNDIS OID Property Set Complete Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS OID Property Set Complete response message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} ATTR_PACKED RNDIS_Set_Complete_t;
|
||||
|
||||
/** \brief RNDIS OID Property Query Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS OID Property Query command message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} ATTR_PACKED RNDIS_Query_Message_t;
|
||||
|
||||
/** \brief RNDIS OID Property Query Complete Message Structure.
|
||||
*
|
||||
* Type define for a RNDIS OID Property Query Complete response message.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
} ATTR_PACKED RNDIS_Query_Complete_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Common definitions and declarations for the library USB Still Image Class driver.
|
||||
*
|
||||
* Common definitions and declarations for the library USB Still Image Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassSI
|
||||
* \defgroup Group_USBClassSICommon Common Class Definitions
|
||||
*
|
||||
* \section Sec_USBClassSICommon_ModDescription Module Description
|
||||
* Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
|
||||
* Still Image Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SI_CLASS_COMMON_H_
|
||||
#define _SI_CLASS_COMMON_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../Core/StdDescriptors.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_SI_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** Length in bytes of a given Unicode string's character length.
|
||||
*
|
||||
* \param[in] Chars Total number of Unicode characters in the string.
|
||||
*
|
||||
* \return Number of bytes of the given unicode string.
|
||||
*/
|
||||
#define UNICODE_STRING_LENGTH(Chars) ((Chars) << 1)
|
||||
|
||||
/** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
|
||||
* a command container.
|
||||
*
|
||||
* \param[in] Params Number of parameters which are to be sent in the \c Param field of the container.
|
||||
*/
|
||||
#define PIMA_COMMAND_SIZE(Params) ((sizeof(PIMA_Container_t) - 12) + ((Params) * sizeof(uint32_t)))
|
||||
|
||||
/** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
|
||||
* a data container.
|
||||
*
|
||||
* \param[in] DataLen Length in bytes of the data in the container.
|
||||
*/
|
||||
#define PIMA_DATA_SIZE(DataLen) ((sizeof(PIMA_Container_t) - 12) + (DataLen))
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible PIMA contains types. */
|
||||
enum PIMA_Container_Types_t
|
||||
{
|
||||
PIMA_CONTAINER_Undefined = 0, /**< Undefined container type. */
|
||||
PIMA_CONTAINER_CommandBlock = 1, /**< Command Block container type. */
|
||||
PIMA_CONTAINER_DataBlock = 2, /**< Data Block container type. */
|
||||
PIMA_CONTAINER_ResponseBlock = 3, /**< Response container type. */
|
||||
PIMA_CONTAINER_EventBlock = 4, /**< Event Block container type. */
|
||||
};
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the
|
||||
* Still Image device class.
|
||||
*/
|
||||
enum SI_Descriptor_ClassSubclassProtocol_t
|
||||
{
|
||||
SI_CSCP_StillImageClass = 0x06, /**< Descriptor Class value indicating that the device or interface
|
||||
* belongs to the Still Image class.
|
||||
*/
|
||||
SI_CSCP_StillImageSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface
|
||||
* belongs to the Still Image subclass.
|
||||
*/
|
||||
SI_CSCP_BulkOnlyProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface
|
||||
* belongs to the Bulk Only Transport protocol of the Still Image class.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enums for the possible status codes of a returned Response Block from an attached PIMA compliant Still Image device. */
|
||||
enum PIMA_ResponseCodes_t
|
||||
{
|
||||
PIMA_RESPONSE_OK = 1, /**< Response code indicating no error in the issued command. */
|
||||
PIMA_RESPONSE_GeneralError = 2, /**< Response code indicating a general error while processing the
|
||||
* issued command.
|
||||
*/
|
||||
PIMA_RESPONSE_SessionNotOpen = 3, /**< Response code indicating that the sent command requires an open
|
||||
* session before being issued.
|
||||
*/
|
||||
PIMA_RESPONSE_InvalidTransaction = 4, /**< Response code indicating an invalid transaction occurred. */
|
||||
PIMA_RESPONSE_OperationNotSupported = 5, /**< Response code indicating that the issued command is not supported
|
||||
* by the attached device.
|
||||
*/
|
||||
PIMA_RESPONSE_ParameterNotSupported = 6, /**< Response code indicating that one or more of the issued command's
|
||||
* parameters are not supported by the device.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief PIMA Still Image Device Command/Response Container.
|
||||
*
|
||||
* Type define for a PIMA container, use to send commands and receive responses to and from an
|
||||
* attached Still Image device.
|
||||
*
|
||||
* \note Regardless of CPU architecture, these values should be stored as little endian.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t DataLength; /**< Length of the container and data, in bytes. */
|
||||
uint16_t Type; /**< Container type, a value from the \ref PIMA_Container_Types_t enum. */
|
||||
uint16_t Code; /**< Command, event or response code of the container. */
|
||||
uint32_t TransactionID; /**< Unique container ID to link blocks together. */
|
||||
uint32_t Params[3]; /**< Block parameters to be issued along with the block code (command blocks only). */
|
||||
} ATTR_PACKED PIMA_Container_t;
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define __INCLUDE_FROM_AUDIO_DRIVER
|
||||
#define __INCLUDE_FROM_AUDIO_DEVICE_C
|
||||
#include "AudioClassDevice.h"
|
||||
|
||||
void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
|
||||
{
|
||||
uint8_t InterfaceIndex = (USB_ControlRequest.wIndex & 0xFF);
|
||||
|
||||
if ((InterfaceIndex != AudioInterfaceInfo->Config.ControlInterfaceNumber) &&
|
||||
(InterfaceIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
|
||||
{
|
||||
uint8_t EndpointAddress = (USB_ControlRequest.wIndex & 0xFF);
|
||||
|
||||
if ((EndpointAddress != AudioInterfaceInfo->Config.DataINEndpoint.Address) &&
|
||||
(EndpointAddress != AudioInterfaceInfo->Config.DataOUTEndpoint.Address))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case REQ_SetInterface:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
|
||||
EVENT_Audio_Device_StreamStartStop(AudioInterfaceInfo);
|
||||
}
|
||||
|
||||
break;
|
||||
case AUDIO_REQ_GetStatus:
|
||||
if ((USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) ||
|
||||
(USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT)))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
case AUDIO_REQ_SetCurrent:
|
||||
case AUDIO_REQ_SetMinimum:
|
||||
case AUDIO_REQ_SetMaximum:
|
||||
case AUDIO_REQ_SetResolution:
|
||||
if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
|
||||
{
|
||||
uint8_t EndpointProperty = USB_ControlRequest.bRequest;
|
||||
uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex;
|
||||
uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8);
|
||||
|
||||
if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
|
||||
EndpointControl, NULL, NULL))
|
||||
{
|
||||
uint16_t ValueLength = USB_ControlRequest.wLength;
|
||||
uint8_t Value[ValueLength];
|
||||
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Read_Control_Stream_LE(Value, ValueLength);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
|
||||
EndpointControl, &ValueLength, Value);
|
||||
}
|
||||
}
|
||||
else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
|
||||
{
|
||||
uint8_t Property = USB_ControlRequest.bRequest;
|
||||
uint8_t Entity = (USB_ControlRequest.wIndex >> 8);
|
||||
uint16_t Parameter = USB_ControlRequest.wValue;
|
||||
|
||||
if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
|
||||
Parameter, NULL, NULL))
|
||||
{
|
||||
uint16_t ValueLength = USB_ControlRequest.wLength;
|
||||
uint8_t Value[ValueLength];
|
||||
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Read_Control_Stream_LE(Value, ValueLength);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
|
||||
Parameter, &ValueLength, Value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case AUDIO_REQ_GetCurrent:
|
||||
case AUDIO_REQ_GetMinimum:
|
||||
case AUDIO_REQ_GetMaximum:
|
||||
case AUDIO_REQ_GetResolution:
|
||||
if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
|
||||
{
|
||||
uint8_t EndpointProperty = USB_ControlRequest.bRequest;
|
||||
uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex;
|
||||
uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8);
|
||||
uint16_t ValueLength = USB_ControlRequest.wLength;
|
||||
uint8_t Value[ValueLength];
|
||||
|
||||
if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
|
||||
EndpointControl, &ValueLength, Value))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Write_Control_Stream_LE(Value, ValueLength);
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
}
|
||||
else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
|
||||
{
|
||||
uint8_t Property = USB_ControlRequest.bRequest;
|
||||
uint8_t Entity = (USB_ControlRequest.wIndex >> 8);
|
||||
uint16_t Parameter = USB_ControlRequest.wValue;
|
||||
uint16_t ValueLength = USB_ControlRequest.wLength;
|
||||
uint8_t Value[ValueLength];
|
||||
|
||||
if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
|
||||
Parameter, &ValueLength, Value))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Write_Control_Stream_LE(Value, ValueLength);
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
|
||||
|
||||
AudioInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_ISOCHRONOUS;
|
||||
AudioInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_ISOCHRONOUS;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataINEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataOUTEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Audio_Device_Event_Stub(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Device mode driver for the library USB Audio 1.0 Class driver.
|
||||
*
|
||||
* Device mode driver for the library USB Audio 1.0 Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassAudio
|
||||
* \defgroup Group_USBClassAudioDevice Audio 1.0 Class Device Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassAudioDevice_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassAudioDevice_ModDescription Module Description
|
||||
* Device Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_CLASS_DEVICE_H_
|
||||
#define _AUDIO_CLASS_DEVICE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/AudioClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief Audio Class Device Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made for each Audio interface
|
||||
* within the user application, and passed to each of the Audio class driver functions as the
|
||||
* \c AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Index of the Audio Control interface within the device this
|
||||
* structure controls.
|
||||
*/
|
||||
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this
|
||||
* structure controls.
|
||||
*/
|
||||
|
||||
USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
|
||||
USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
|
||||
* of the Audio Streaming interface.
|
||||
*/
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* are reset to their defaults when the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_Audio_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
|
||||
* given Audio interface is selected.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
|
||||
*/
|
||||
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_Device_ControlRequest() event.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*/
|
||||
void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented
|
||||
* in the user application to handle property manipulations on streaming audio endpoints.
|
||||
*
|
||||
* When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for
|
||||
* the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations
|
||||
* to indicate the size of the retrieved data.
|
||||
*
|
||||
* \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value
|
||||
* of the \c DataLength parameter.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t.
|
||||
* \param[in] EndpointAddress Address of the streaming endpoint whose property is being referenced.
|
||||
* \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t.
|
||||
* \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum
|
||||
* length of the retrieved data. When NULL, the function should return whether the given property
|
||||
* and parameter is valid for the requested endpoint without reading or modifying the Data buffer.
|
||||
* \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where
|
||||
* the retrieved data is to be stored for GET operations.
|
||||
*
|
||||
* \return Boolean \c true if the property GET/SET was successful, \c false otherwise
|
||||
*/
|
||||
bool CALLBACK_Audio_Device_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const uint8_t EndpointProperty,
|
||||
const uint8_t EndpointAddress,
|
||||
const uint8_t EndpointControl,
|
||||
uint16_t* const DataLength,
|
||||
uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Audio class driver callback for the setting and retrieval of streaming interface properties. This callback must be implemented
|
||||
* in the user application to handle property manipulations on streaming audio interfaces.
|
||||
*
|
||||
* When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for
|
||||
* the given entity and should return as fast as possible. When non-NULL, this value may be altered for GET operations
|
||||
* to indicate the size of the retrieved data.
|
||||
*
|
||||
* \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value
|
||||
* of the \c DataLength parameter.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] Property Property of the interface to get or set, a value from \ref Audio_ClassRequests_t.
|
||||
* \param[in] EntityAddress Address of the audio entity whose property is being referenced.
|
||||
* \param[in] Parameter Parameter of the entity to get or set, specific to each type of entity (see USB Audio specification).
|
||||
* \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum
|
||||
* length of the retrieved data. When NULL, the function should return whether the given property
|
||||
* and parameter is valid for the requested endpoint without reading or modifying the Data buffer.
|
||||
* \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where
|
||||
* the retrieved data is to be stored for GET operations.
|
||||
*
|
||||
* \return Boolean \c true if the property GET/SET was successful, \c false otherwise
|
||||
*/
|
||||
bool CALLBACK_Audio_Device_GetSetInterfaceProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const uint8_t Property,
|
||||
const uint8_t EntityAddress,
|
||||
const uint16_t Parameter,
|
||||
uint16_t* const DataLength,
|
||||
uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Audio class driver event for an Audio Stream start/stop change. This event fires each time the device receives a stream enable or
|
||||
* disable control request from the host, to start and stop the audio stream. The current state of the stream can be determined by the
|
||||
* State.InterfaceEnabled value inside the Audio interface structure passed as a parameter.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*/
|
||||
void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*/
|
||||
static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
(void)AudioInterfaceInfo;
|
||||
}
|
||||
|
||||
/** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming
|
||||
* OUT endpoint ready for reading.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise.
|
||||
*/
|
||||
static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
|
||||
return false;
|
||||
|
||||
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
return Endpoint_IsOUTReceived();
|
||||
}
|
||||
|
||||
/** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects
|
||||
* the streaming IN endpoint ready for writing.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise.
|
||||
*/
|
||||
static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
|
||||
return false;
|
||||
|
||||
Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
return Endpoint_IsINReady();
|
||||
}
|
||||
|
||||
/** Reads the next 8-bit audio sample from the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
|
||||
* that the correct endpoint is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Signed 8-bit audio sample from the audio interface.
|
||||
*/
|
||||
static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
int8_t Sample;
|
||||
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Sample = Endpoint_Read_8();
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
return Sample;
|
||||
}
|
||||
|
||||
/** Reads the next 16-bit audio sample from the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
|
||||
* that the correct endpoint is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Signed 16-bit audio sample from the audio interface.
|
||||
*/
|
||||
static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
int16_t Sample;
|
||||
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Sample = (int16_t)Endpoint_Read_16_LE();
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
return Sample;
|
||||
}
|
||||
|
||||
/** Reads the next 24-bit audio sample from the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
|
||||
* that the correct endpoint is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Signed 24-bit audio sample from the audio interface.
|
||||
*/
|
||||
static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
{
|
||||
int32_t Sample;
|
||||
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Sample = (((uint32_t)Endpoint_Read_8() << 16) | Endpoint_Read_16_LE());
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
return Sample;
|
||||
}
|
||||
|
||||
/** Writes the next 8-bit audio sample to the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
|
||||
* ensure that the correct endpoint is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] Sample Signed 8-bit audio sample.
|
||||
*/
|
||||
static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const int8_t Sample)
|
||||
{
|
||||
Endpoint_Write_8(Sample);
|
||||
|
||||
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
/** Writes the next 16-bit audio sample to the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
|
||||
* ensure that the correct endpoint is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] Sample Signed 16-bit audio sample.
|
||||
*/
|
||||
static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const int16_t Sample)
|
||||
{
|
||||
Endpoint_Write_16_LE(Sample);
|
||||
|
||||
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
/** Writes the next 24-bit audio sample to the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
|
||||
* ensure that the correct endpoint is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] Sample Signed 24-bit audio sample.
|
||||
*/
|
||||
static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
|
||||
const int32_t Sample)
|
||||
{
|
||||
Endpoint_Write_16_LE(Sample);
|
||||
Endpoint_Write_8(Sample >> 16);
|
||||
|
||||
if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_AUDIO_DEVICE_C)
|
||||
void Audio_Device_Event_Stub(void) ATTR_CONST;
|
||||
|
||||
void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
|
||||
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(Audio_Device_Event_Stub);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define __INCLUDE_FROM_CDC_DRIVER
|
||||
#define __INCLUDE_FROM_CDC_DEVICE_C
|
||||
#include "CDCClassDevice.h"
|
||||
|
||||
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case CDC_REQ_GetLineEncoding:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
while (!(Endpoint_IsINReady()));
|
||||
|
||||
Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
|
||||
Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat);
|
||||
Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType);
|
||||
Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits);
|
||||
|
||||
Endpoint_ClearIN();
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
case CDC_REQ_SetLineEncoding:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
while (!(Endpoint_IsOUTReceived()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE();
|
||||
CDCInterfaceInfo->State.LineEncoding.CharFormat = Endpoint_Read_8();
|
||||
CDCInterfaceInfo->State.LineEncoding.ParityType = Endpoint_Read_8();
|
||||
CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8();
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
|
||||
}
|
||||
|
||||
break;
|
||||
case CDC_REQ_SetControlLineState:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
|
||||
|
||||
EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
|
||||
}
|
||||
|
||||
break;
|
||||
case CDC_REQ_SendBreak:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
|
||||
|
||||
CDCInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
|
||||
CDCInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
|
||||
CDCInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataINEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataOUTEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.NotificationEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return;
|
||||
|
||||
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsINReady())
|
||||
CDC_Device_Flush(CDCInterfaceInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const char* const String)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
return Endpoint_Write_Stream_LE(String, strlen(String), NULL);
|
||||
}
|
||||
|
||||
uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const char* const String)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
return Endpoint_Write_PStream_LE(String, strlen_P(String), NULL);
|
||||
}
|
||||
|
||||
uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
return Endpoint_Write_Stream_LE(Buffer, Length, NULL);
|
||||
}
|
||||
|
||||
uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
return Endpoint_Write_PStream_LE(Buffer, Length, NULL);
|
||||
}
|
||||
|
||||
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const uint8_t Data)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearIN();
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Endpoint_Write_8(Data);
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
|
||||
bool BankFull = !(Endpoint_IsReadWriteAllowed());
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
if (BankFull)
|
||||
{
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return 0;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsOUTReceived())
|
||||
{
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Endpoint_BytesInEndpoint();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return -1;
|
||||
|
||||
int16_t ReceivedByte = -1;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsOUTReceived())
|
||||
{
|
||||
if (Endpoint_BytesInEndpoint())
|
||||
ReceivedByte = Endpoint_Read_8();
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpoint.Address);
|
||||
|
||||
USB_Request_Header_t Notification = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = CDC_NOTIF_SerialState,
|
||||
.wValue = CPU_TO_LE16(0),
|
||||
.wIndex = CPU_TO_LE16(0),
|
||||
.wLength = CPU_TO_LE16(sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost)),
|
||||
};
|
||||
|
||||
Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
|
||||
Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
|
||||
sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
|
||||
NULL);
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, CDCInterfaceInfo);
|
||||
}
|
||||
|
||||
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, CDCInterfaceInfo);
|
||||
}
|
||||
|
||||
static int CDC_Device_putchar(char c,
|
||||
FILE* Stream)
|
||||
{
|
||||
return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
|
||||
}
|
||||
|
||||
static int CDC_Device_getchar(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
|
||||
|
||||
if (ReceivedByte < 0)
|
||||
return _FDEV_EOF;
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
static int CDC_Device_getchar_Blocking(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte;
|
||||
|
||||
while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0)
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return _FDEV_EOF;
|
||||
|
||||
CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CDC_Device_Event_Stub(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Device mode driver for the library USB CDC Class driver.
|
||||
*
|
||||
* Device mode driver for the library USB CDC Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassCDC
|
||||
* \defgroup Group_USBClassCDCDevice CDC Class Device Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassCDCDevice_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassCDCDevice_ModDescription Module Description
|
||||
* Device Mode USB Class driver framework interface, for the CDC USB Class driver.
|
||||
*
|
||||
* \note There are several major drawbacks to the CDC-ACM standard USB class, however
|
||||
* it is very standardized and thus usually available as a built-in driver on
|
||||
* most platforms, and so is a better choice than a proprietary serial class.
|
||||
*
|
||||
* One major issue with CDC-ACM is that it requires two Interface descriptors,
|
||||
* which will upset most hosts when part of a multi-function "Composite" USB
|
||||
* device. This is because each interface will be loaded into a separate driver
|
||||
* instance, causing the two interfaces be become unlinked. To prevent this, you
|
||||
* should use the "Interface Association Descriptor" addendum to the USB 2.0 standard
|
||||
* which is available on most OSes when creating Composite devices.
|
||||
*
|
||||
* Another major oversight is that there is no mechanism for the host to notify the
|
||||
* device that there is a data sink on the host side ready to accept data. This
|
||||
* means that the device may try to send data while the host isn't listening, causing
|
||||
* lengthy blocking timeouts in the transmission routines. It is thus highly recommended
|
||||
* that the virtual serial line DTR (Data Terminal Ready) signal be used where possible
|
||||
* to determine if a host application is ready for data.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CDC_CLASS_DEVICE_H_
|
||||
#define _CDC_CLASS_DEVICE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/CDCClassCommon.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief CDC Class Device Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made for each CDC interface
|
||||
* within the user application, and passed to each of the CDC class driver functions as the
|
||||
* CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */
|
||||
|
||||
USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
|
||||
USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
|
||||
USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_*
|
||||
* masks. This value is updated each time \ref CDC_Device_USBTask() is called.
|
||||
*/
|
||||
uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_*
|
||||
* masks - to notify the host of changes to these values, call the
|
||||
* \ref CDC_Device_SendControlLineStateChange() function.
|
||||
*/
|
||||
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
|
||||
|
||||
CDC_LineEncoding_t LineEncoding; /**< Line encoding used in the virtual serial port, for the device's information.
|
||||
* This is generally only used if the virtual serial port data is to be
|
||||
* reconstructed on a physical UART.
|
||||
*/
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* are reset to their defaults when the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_CDC_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
|
||||
* the given CDC interface is selected.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
|
||||
*/
|
||||
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_Device_ControlRequest() event.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** General management task for a given CDC class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
|
||||
* line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
|
||||
* user program by declaring a handler function with the same name and parameters listed here. The new line encoding
|
||||
* settings are available in the \c LineEncoding structure inside the CDC interface structure passed as a parameter.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
|
||||
* control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
|
||||
* user program by declaring a handler function with the same name and parameters listed here. The new control line states
|
||||
* are available in the \c ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as
|
||||
* a mask of \c CDC_CONTROL_LINE_OUT_* masks.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** CDC class driver event for a send break request sent to the device from the host. This is generally used to separate
|
||||
* data or to indicate a special condition to the receiving device.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in] Duration Duration of the break that has been sent by the host, in milliseconds.
|
||||
*/
|
||||
void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
|
||||
* called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
|
||||
* becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
|
||||
* for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer containing the data to send to the device.
|
||||
* \param[in] Length Length of the data to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given data buffer from PROGMEM space to the attached USB host, if connected. If a host is not connected when the
|
||||
* function is called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint
|
||||
* bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
|
||||
* for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer containing the data to send to the device.
|
||||
* \param[in] Length Length of the data to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
|
||||
* the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
|
||||
* the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
|
||||
* the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in] String Pointer to the null terminated string to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given null terminated string from PROGMEM space to the attached USB host, if connected. If a host is not connected
|
||||
* when the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
|
||||
* the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
|
||||
* the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in] String Pointer to the null terminated string to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
|
||||
* byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
|
||||
* \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
|
||||
* packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in] Data Byte of data to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Determines the number of bytes received by the CDC interface from the host, waiting to be read. This indicates the number
|
||||
* of bytes in the OUT endpoint bank only, and thus the number of calls to \ref CDC_Device_ReceiveByte() which are guaranteed to
|
||||
* succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint
|
||||
* bank will not be released back to the USB controller until all bytes are read.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*
|
||||
* \return Total number of buffered bytes received from the host.
|
||||
*/
|
||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
|
||||
* returns a negative value. The \ref CDC_Device_BytesReceived() function may be queried in advance to determine how many
|
||||
* bytes are currently buffered in the CDC interface's data receive endpoint bank, and thus how many repeated calls to this
|
||||
* function which are guaranteed to succeed.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*
|
||||
* \return Next received byte from the host, or a negative value if no data received.
|
||||
*/
|
||||
int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
|
||||
* control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist
|
||||
* until they are cleared via a second notification. This should be called each time the CDC class driver's
|
||||
* \c ControlLineStates.DeviceToHost value is updated to push the new states to the USB host.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
*/
|
||||
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
#if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__)
|
||||
/** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular
|
||||
* functions in the standard <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created
|
||||
* stream is bidirectional and can be used for both input and output functions.
|
||||
*
|
||||
* Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
|
||||
* fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
|
||||
* be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
|
||||
* line buffering.
|
||||
*
|
||||
* \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions
|
||||
* to the given CDC interface.
|
||||
* \n\n
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Identical to \ref CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
|
||||
* the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_CDC_DEVICE_C)
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
static int CDC_Device_putchar(char c,
|
||||
FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
|
||||
static int CDC_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static int CDC_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
|
||||
void CDC_Device_Event_Stub(void) ATTR_CONST;
|
||||
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
|
||||
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
|
||||
void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
|
||||
const uint8_t Duration) ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_ALIAS(CDC_Device_Event_Stub);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define __INCLUDE_FROM_HID_DRIVER
|
||||
#define __INCLUDE_FROM_HID_DEVICE_C
|
||||
#include "HIDClassDevice.h"
|
||||
|
||||
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case HID_REQ_GetReport:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
uint16_t ReportSize = 0;
|
||||
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
|
||||
uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
|
||||
uint8_t ReportData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
|
||||
|
||||
memset(ReportData, 0, sizeof(ReportData));
|
||||
|
||||
CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType, ReportData, &ReportSize);
|
||||
|
||||
if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
|
||||
{
|
||||
memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData,
|
||||
HIDInterfaceInfo->Config.PrevReportINBufferSize);
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
|
||||
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
if (ReportID)
|
||||
Endpoint_Write_8(ReportID);
|
||||
|
||||
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_SetReport:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
uint16_t ReportSize = USB_ControlRequest.wLength;
|
||||
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
|
||||
uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
|
||||
uint8_t ReportData[ReportSize];
|
||||
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Read_Control_Stream_LE(ReportData, ReportSize);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType,
|
||||
&ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_GetProtocol:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol);
|
||||
Endpoint_ClearIN();
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_SetProtocol:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_SetIdle:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_GetIdle:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2);
|
||||
Endpoint_ClearIN();
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
|
||||
{
|
||||
memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
|
||||
HIDInterfaceInfo->State.UsingReportProtocol = true;
|
||||
HIDInterfaceInfo->State.IdleCount = 500;
|
||||
|
||||
HIDInterfaceInfo->Config.ReportINEndpoint.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&HIDInterfaceInfo->Config.ReportINEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (HIDInterfaceInfo->State.PrevFrameNum == USB_Device_GetFrameNumber())
|
||||
{
|
||||
#if defined(USB_DEVICE_OPT_LOWSPEED)
|
||||
if (!(USB_Options & USB_DEVICE_OPT_LOWSPEED))
|
||||
return;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsReadWriteAllowed())
|
||||
{
|
||||
uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
|
||||
uint8_t ReportID = 0;
|
||||
uint16_t ReportINSize = 0;
|
||||
|
||||
memset(ReportINData, 0, sizeof(ReportINData));
|
||||
|
||||
bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In,
|
||||
ReportINData, &ReportINSize);
|
||||
bool StatesChanged = false;
|
||||
bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
|
||||
|
||||
if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
|
||||
{
|
||||
StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
|
||||
memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
|
||||
}
|
||||
|
||||
if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
|
||||
{
|
||||
HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
|
||||
|
||||
Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address);
|
||||
|
||||
if (ReportID)
|
||||
Endpoint_Write_8(ReportID);
|
||||
|
||||
Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NULL);
|
||||
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
HIDInterfaceInfo->State.PrevFrameNum = USB_Device_GetFrameNumber();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Device mode driver for the library USB HID Class driver.
|
||||
*
|
||||
* Device mode driver for the library USB HID Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassHID
|
||||
* \defgroup Group_USBClassHIDDevice HID Class Device Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassHIDDevice_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassHIDDevice_ModDescription Module Description
|
||||
* Device Mode USB Class driver framework interface, for the HID USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HID_CLASS_DEVICE_H_
|
||||
#define _HID_CLASS_DEVICE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/HIDClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_HID_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief HID Class Device Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made for each HID interface
|
||||
* within the user application, and passed to each of the HID class driver functions as the
|
||||
* \c HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information.
|
||||
*
|
||||
* \note Due to technical limitations, the HID device class driver does not utilize a separate OUT
|
||||
* endpoint for host->device communications. Instead, the host->device data (if any) is sent to
|
||||
* the device via the control endpoint.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device. */
|
||||
|
||||
USB_Endpoint_Table_t ReportINEndpoint; /**< Data IN HID report endpoint configuration table. */
|
||||
|
||||
void* PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be
|
||||
* stored by the driver, for comparison purposes to detect report changes that
|
||||
* must be sent immediately to the host. This should point to a buffer big enough
|
||||
* to hold the largest HID input report sent from the HID interface. If this is set
|
||||
* to \c NULL, it is up to the user to force transfers when needed in the
|
||||
* \ref CALLBACK_HID_Device_CreateHIDReport() callback function.
|
||||
*
|
||||
* \note Due to the single buffer, the internal driver can only correctly compare
|
||||
* subsequent reports with identical report IDs. In multiple report devices,
|
||||
* this buffer should be set to \c NULL and the decision to send reports made
|
||||
* by the user application instead.
|
||||
*/
|
||||
uint8_t PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a
|
||||
* second buffer of the same size within the driver so that subsequent reports
|
||||
* can be compared. If the user app is to determine when reports are to be sent
|
||||
* exclusively (i.e. \c PrevReportINBuffer is \c NULL) this value must still be
|
||||
* set to the size of the largest report the device can issue to the host.
|
||||
*/
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode. */
|
||||
uint16_t PrevFrameNum; /**< Frame number of the previous HID report packet opportunity. */
|
||||
uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host. */
|
||||
uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this
|
||||
* should be decremented by the user application if non-zero each millisecond. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* are reset to their defaults when the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_HID_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
* containing the given HID interface is selected.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
|
||||
*/
|
||||
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_Device_ControlRequest() event.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
*/
|
||||
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** General management task for a given HID class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
*/
|
||||
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either
|
||||
* HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
|
||||
* user is responsible for the creation of the next HID input report to be sent to the host.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
* \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero,
|
||||
* this should be set to the report ID of the generated HID input report (if any). If multiple
|
||||
* reports are not sent via the given HID interface, this parameter should be ignored.
|
||||
* \param[in] ReportType Type of HID report to generate, either \ref HID_REPORT_ITEM_In or \ref HID_REPORT_ITEM_Feature.
|
||||
* \param[out] ReportData Pointer to a buffer where the generated HID report should be stored.
|
||||
* \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent.
|
||||
*
|
||||
* \return Boolean \c true to force the sending of the report even if it is identical to the previous report and still within
|
||||
* the idle period (useful for devices which report relative movement), \c false otherwise.
|
||||
*/
|
||||
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
|
||||
uint8_t* const ReportID,
|
||||
const uint8_t ReportType,
|
||||
void* ReportData,
|
||||
uint16_t* const ReportSize) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5);
|
||||
|
||||
/** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to
|
||||
* either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
|
||||
* the user is responsible for the processing of the received HID output report from the host.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
* \param[in] ReportID Report ID of the received output report. If multiple reports are not received via the given HID
|
||||
* interface, this parameter should be ignored.
|
||||
* \param[in] ReportType Type of received HID report, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature.
|
||||
* \param[in] ReportData Pointer to a buffer where the received HID report is stored.
|
||||
* \param[in] ReportSize Size in bytes of the received report from the host.
|
||||
*/
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
|
||||
const uint8_t ReportID,
|
||||
const uint8_t ReportType,
|
||||
const void* ReportData,
|
||||
const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(4);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
|
||||
* decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
|
||||
* that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via
|
||||
* \ref USB_Device_EnableSOFEvents().
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
|
||||
*/
|
||||
static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_ALWAYS_INLINE ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
|
||||
{
|
||||
if (HIDInterfaceInfo->State.IdleMSRemaining)
|
||||
HIDInterfaceInfo->State.IdleMSRemaining--;
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define __INCLUDE_FROM_MIDI_DRIVER
|
||||
#define __INCLUDE_FROM_MIDI_DEVICE_C
|
||||
#include "MIDIClassDevice.h"
|
||||
|
||||
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
|
||||
{
|
||||
memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
|
||||
|
||||
MIDIInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
|
||||
MIDIInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataINEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataOUTEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return;
|
||||
|
||||
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsINReady())
|
||||
MIDI_Device_Flush(MIDIInterfaceInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
|
||||
const MIDI_EventPacket_t* const Event)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != ENDPOINT_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
Endpoint_ClearIN();
|
||||
|
||||
return ENDPOINT_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (Endpoint_BytesInEndpoint())
|
||||
{
|
||||
Endpoint_ClearIN();
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
|
||||
MIDI_EventPacket_t* const Event)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return false;
|
||||
|
||||
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
if (!(Endpoint_IsOUTReceived()))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
return false;
|
||||
|
||||
Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL);
|
||||
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Device mode driver for the library USB MIDI Class driver.
|
||||
*
|
||||
* Device mode driver for the library USB MIDI Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassMIDI
|
||||
* \defgroup Group_USBClassMIDIDevice MIDI Class Device Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassMIDIDevice_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassMIDIDevice_ModDescription Module Description
|
||||
* Device Mode USB Class driver framework interface, for the MIDI USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MIDI_CLASS_DEVICE_H_
|
||||
#define _MIDI_CLASS_DEVICE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/MIDIClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Define: */
|
||||
/** \brief MIDI Class Device Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made for each MIDI interface
|
||||
* within the user application, and passed to each of the MIDI class driver functions as the
|
||||
* \c MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls. */
|
||||
|
||||
USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
|
||||
USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t RESERVED; // No state information for this class
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* are reset to their defaults when the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_MIDI_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
* containing the given MIDI interface is selected.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
|
||||
*/
|
||||
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** General management task for a given MIDI class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
*/
|
||||
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the
|
||||
* endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple
|
||||
* MIDI events to be packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
* \param[in] Event Pointer to a populated \ref MIDI_EventPacket_t structure containing the MIDI event to send.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
|
||||
const MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
|
||||
/** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the
|
||||
* \ref MIDI_Device_SendEventPacket() function's packing behavior, to flush queued events.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains
|
||||
* multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
* \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed.
|
||||
*
|
||||
* \return Boolean \c true if a MIDI event packet was received, \c false otherwise.
|
||||
*/
|
||||
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
|
||||
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_Device_ControlRequest() event.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
*/
|
||||
static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
|
||||
{
|
||||
(void)MIDIInterfaceInfo;
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define __INCLUDE_FROM_MS_DRIVER
|
||||
#define __INCLUDE_FROM_MASSSTORAGE_DEVICE_C
|
||||
#include "MassStorageClassDevice.h"
|
||||
|
||||
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case MS_REQ_MassStorageReset:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
MSInterfaceInfo->State.IsMassStoreReset = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case MS_REQ_GetMaxLUN:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_Write_8(MSInterfaceInfo->Config.TotalLUNs - 1);
|
||||
Endpoint_ClearIN();
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
|
||||
|
||||
MSInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
|
||||
MSInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataINEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataOUTEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsOUTReceived())
|
||||
{
|
||||
if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
|
||||
{
|
||||
if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
bool SCSICommandResult = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo);
|
||||
|
||||
MSInterfaceInfo->State.CommandStatus.Status = (SCSICommandResult) ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail;
|
||||
MSInterfaceInfo->State.CommandStatus.Signature = CPU_TO_LE32(MS_CSW_SIGNATURE);
|
||||
MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag;
|
||||
MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;
|
||||
|
||||
if (!(SCSICommandResult) && (le32_to_cpu(MSInterfaceInfo->State.CommandStatus.DataTransferResidue)))
|
||||
Endpoint_StallTransaction();
|
||||
|
||||
MS_Device_ReturnCommandStatus(MSInterfaceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
{
|
||||
Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
Endpoint_ClearStall();
|
||||
Endpoint_ResetDataToggle();
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
Endpoint_ClearStall();
|
||||
Endpoint_ResetDataToggle();
|
||||
|
||||
MSInterfaceInfo->State.IsMassStoreReset = false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
uint16_t BytesProcessed;
|
||||
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
BytesProcessed = 0;
|
||||
while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock,
|
||||
(sizeof(MS_CommandBlockWrapper_t) - 16), &BytesProcessed) ==
|
||||
ENDPOINT_RWSTREAM_IncompleteTransfer)
|
||||
{
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((MSInterfaceInfo->State.CommandBlock.Signature != CPU_TO_LE32(MS_CBW_SIGNATURE)) ||
|
||||
(MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) ||
|
||||
(MSInterfaceInfo->State.CommandBlock.Flags & 0x1F) ||
|
||||
(MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0) ||
|
||||
(MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16))
|
||||
{
|
||||
Endpoint_StallTransaction();
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
Endpoint_StallTransaction();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BytesProcessed = 0;
|
||||
while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData,
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandLength, &BytesProcessed) ==
|
||||
ENDPOINT_RWSTREAM_IncompleteTransfer)
|
||||
{
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return false;
|
||||
}
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
while (Endpoint_IsStalled())
|
||||
{
|
||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
USB_USBTask();
|
||||
#endif
|
||||
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
while (Endpoint_IsStalled())
|
||||
{
|
||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
USB_USBTask();
|
||||
#endif
|
||||
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t BytesProcessed = 0;
|
||||
while (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus,
|
||||
sizeof(MS_CommandStatusWrapper_t), &BytesProcessed) ==
|
||||
ENDPOINT_RWSTREAM_IncompleteTransfer)
|
||||
{
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Device mode driver for the library USB Mass Storage Class driver.
|
||||
*
|
||||
* Device mode driver for the library USB Mass Storage Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassMS
|
||||
* \defgroup Group_USBClassMSDevice Mass Storage Class Device Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassMSDevice_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassMSDevice_ModDescription Module Description
|
||||
* Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MS_CLASS_DEVICE_H_
|
||||
#define _MS_CLASS_DEVICE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/MassStorageClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_MS_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief Mass Storage Class Device Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made for each Mass Storage interface
|
||||
* within the user application, and passed to each of the Mass Storage class driver functions as the
|
||||
* \c MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device. */
|
||||
|
||||
USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
|
||||
USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
|
||||
|
||||
uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
MS_CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI
|
||||
* command from the host which is to be processed.
|
||||
*/
|
||||
MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate
|
||||
* the issued command's success or failure to the host.
|
||||
*/
|
||||
volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
|
||||
* and that all current Mass Storage operations should immediately abort.
|
||||
*/
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* are reset to their defaults when the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_MS_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
* containing the given Mass Storage interface is selected.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
|
||||
*/
|
||||
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_Device_ControlRequest() event.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
|
||||
*/
|
||||
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state.
|
||||
*/
|
||||
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
|
||||
* host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
|
||||
* for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure
|
||||
* inside the Mass Storage class state structure passed as a parameter to the callback function.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the SCSI command was successfully processed, \c false otherwise.
|
||||
*/
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_MASSSTORAGE_DEVICE_C)
|
||||
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define __INCLUDE_FROM_PRINTER_DRIVER
|
||||
#define __INCLUDE_FROM_PRINTER_DEVICE_C
|
||||
#include "PrinterClassDevice.h"
|
||||
|
||||
void PRNT_Device_ProcessControlRequest(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != PRNTInterfaceInfo->Config.InterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case PRNT_REQ_GetDeviceID:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t IEEEStringLen = strlen(PRNTInterfaceInfo->Config.IEEE1284String);
|
||||
Endpoint_Write_16_BE(IEEEStringLen);
|
||||
Endpoint_Write_Control_Stream_LE(PRNTInterfaceInfo->Config.IEEE1284String, IEEEStringLen);
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
case PRNT_REQ_GetPortStatus:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_Write_8(PRNTInterfaceInfo->State.PortStatus);
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
case PRNT_REQ_SoftReset:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
PRNTInterfaceInfo->State.IsPrinterReset = true;
|
||||
|
||||
EVENT_PRNT_Device_SoftReset(PRNTInterfaceInfo);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool PRNT_Device_ConfigureEndpoints(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
|
||||
PRNTInterfaceInfo->State.PortStatus = PRNT_PORTSTATUS_NOTERROR | PRNT_PORTSTATUS_SELECT;
|
||||
|
||||
PRNTInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
|
||||
PRNTInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&PRNTInterfaceInfo->Config.DataINEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&PRNTInterfaceInfo->Config.DataOUTEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PRNT_Device_USBTask(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return;
|
||||
|
||||
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsINReady())
|
||||
PRNT_Device_Flush(PRNTInterfaceInfo);
|
||||
#endif
|
||||
|
||||
if (PRNTInterfaceInfo->State.IsPrinterReset)
|
||||
{
|
||||
Endpoint_ResetEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
Endpoint_ResetEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
Endpoint_ClearStall();
|
||||
Endpoint_ResetDataToggle();
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
Endpoint_ClearStall();
|
||||
Endpoint_ResetDataToggle();
|
||||
|
||||
PRNTInterfaceInfo->State.IsPrinterReset = false;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t PRNT_Device_SendString(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
const char* const String)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
return Endpoint_Write_Stream_LE(String, strlen(String), NULL);
|
||||
}
|
||||
|
||||
uint8_t PRNT_Device_SendData(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
return Endpoint_Write_Stream_LE(Buffer, Length, NULL);
|
||||
}
|
||||
|
||||
uint8_t PRNT_Device_SendByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
const uint8_t Data)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearIN();
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Endpoint_Write_8(Data);
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t PRNT_Device_Flush(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
|
||||
bool BankFull = !(Endpoint_IsReadWriteAllowed());
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
if (BankFull)
|
||||
{
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint16_t PRNT_Device_BytesReceived(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return 0;
|
||||
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsOUTReceived())
|
||||
{
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Endpoint_BytesInEndpoint();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t PRNT_Device_ReceiveByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return -1;
|
||||
|
||||
int16_t ReceivedByte = -1;
|
||||
|
||||
Endpoint_SelectEndpoint(PRNTInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsOUTReceived())
|
||||
{
|
||||
if (Endpoint_BytesInEndpoint())
|
||||
ReceivedByte = Endpoint_Read_8();
|
||||
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
void PRNT_Device_CreateStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(PRNT_Device_putchar, PRNT_Device_getchar, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, PRNTInterfaceInfo);
|
||||
}
|
||||
|
||||
void PRNT_Device_CreateBlockingStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(PRNT_Device_putchar, PRNT_Device_getchar_Blocking, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, PRNTInterfaceInfo);
|
||||
}
|
||||
|
||||
static int PRNT_Device_putchar(char c,
|
||||
FILE* Stream)
|
||||
{
|
||||
return PRNT_Device_SendByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
|
||||
}
|
||||
|
||||
static int PRNT_Device_getchar(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte = PRNT_Device_ReceiveByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream));
|
||||
|
||||
if (ReceivedByte < 0)
|
||||
return _FDEV_EOF;
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
static int PRNT_Device_getchar_Blocking(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte;
|
||||
|
||||
while ((ReceivedByte = PRNT_Device_ReceiveByte((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream))) < 0)
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return _FDEV_EOF;
|
||||
|
||||
PRNT_Device_USBTask((USB_ClassInfo_PRNT_Device_t*)fdev_get_udata(Stream));
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
#endif
|
||||
|
||||
void PRNT_Device_Event_Stub(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Device mode driver for the library USB Printer Class driver.
|
||||
*
|
||||
* Device mode driver for the library USB Printer Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassPrinter
|
||||
* \defgroup Group_USBClassPrinterDevice Printer Class Device Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassPrinterDevice_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/PrinterClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassPrinterDevice_ModDescription Module Description
|
||||
* Device Mode USB Class driver framework interface, for the Printer USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PRINTER_CLASS_DEVICE_H_
|
||||
#define _PRINTER_CLASS_DEVICE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/PrinterClassCommon.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief Printer Class Device Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made for each Printer interface
|
||||
* within the user application, and passed to each of the Printer class driver functions as the
|
||||
* PRNTInterfaceInfo parameter. This stores each Printer interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t InterfaceNumber; /**< Interface number of the Printer interface within the device. */
|
||||
|
||||
USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
|
||||
USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
|
||||
|
||||
char* IEEE1284String; /**< IEEE 1284 identification string, sent to the host during enumeration
|
||||
* to identify the printer model, manufacturer and other characteristics.
|
||||
*/
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint8_t PortStatus; /**< Current status of the Printer virtual port, a collection of \c PRNT_PORTSTATUS_*
|
||||
* bitmask values.
|
||||
*/
|
||||
|
||||
volatile bool IsPrinterReset; /**< Flag indicating that the host has requested that the Printer interface be reset
|
||||
* and that all current Mass Storage operations should immediately abort.
|
||||
*/
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* are reset to their defaults when the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_PRNT_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given Printer interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
|
||||
* the given Printer interface is selected.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
|
||||
*/
|
||||
bool PRNT_Device_ConfigureEndpoints(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Processes incoming control requests from the host, that are directed to the given Printer class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_Device_ControlRequest() event.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
*/
|
||||
void PRNT_Device_ProcessControlRequest(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** General management task for a given Printer class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
*/
|
||||
void PRNT_Device_USBTask(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Printer class driver event for a soft reset request on a Printer interface. This event fires each time the host
|
||||
* requests a reset of the printer interface's internal state, and may be hooked in the user program by declaring a
|
||||
* handler function with the same name and parameters listed here.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
*/
|
||||
void EVENT_PRNT_Device_SoftReset(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
|
||||
* called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
|
||||
* becomes full, or the \ref PRNT_Device_Flush() function is called to flush the pending data to the host. This allows
|
||||
* for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer containing the data to send to the device.
|
||||
* \param[in] Length Length of the data to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Device_SendData(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
|
||||
* the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
|
||||
* the endpoint bank becomes full, or the \ref PRNT_Device_Flush() function is called to flush the pending data to
|
||||
* the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
* \param[in] String Pointer to the null terminated string to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Device_SendString(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
|
||||
* byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
|
||||
* \ref PRNT_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
|
||||
* packed into a single endpoint packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
* \param[in] Data Byte of data to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Device_SendByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Determines the number of bytes received by the Printer interface from the host, waiting to be read. This indicates the number
|
||||
* of bytes in the OUT endpoint bank only, and thus the number of calls to \ref PRNT_Device_ReceiveByte() which are guaranteed to
|
||||
* succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint
|
||||
* bank will not be released back to the USB controller until all bytes are read.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
*
|
||||
* \return Total number of buffered bytes received from the host.
|
||||
*/
|
||||
uint16_t PRNT_Device_BytesReceived(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
|
||||
* returns a negative value. The \ref PRNT_Device_BytesReceived() function may be queried in advance to determine how many
|
||||
* bytes are currently buffered in the Printer interface's data receive endpoint bank, and thus how many repeated calls to this
|
||||
* function which are guaranteed to succeed.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
*
|
||||
* \return Next received byte from the host, or a negative value if no data received.
|
||||
*/
|
||||
int16_t PRNT_Device_ReceiveByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Device_Flush(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
#if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__)
|
||||
/** Creates a standard character stream for the given Printer Device instance so that it can be used with all the regular
|
||||
* functions in the standard <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created
|
||||
* stream is bidirectional and can be used for both input and output functions.
|
||||
*
|
||||
* Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
|
||||
* fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
|
||||
* be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
|
||||
* line buffering.
|
||||
*
|
||||
* \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions
|
||||
* to the given Printer interface.
|
||||
* \n\n
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void PRNT_Device_CreateStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Identical to \ref PRNT_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
|
||||
* the transfer. While blocking, the USB and Printer service tasks are called repeatedly to maintain USB communications.
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void PRNT_Device_CreateBlockingStream(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_PRINTER_DEVICE_C)
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
static int PRNT_Device_putchar(char c,
|
||||
FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
|
||||
static int PRNT_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static int PRNT_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
|
||||
void PRNT_Device_Event_Stub(void) ATTR_CONST;
|
||||
|
||||
void EVENT_PRNT_Device_SoftReset(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo)
|
||||
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(PRNT_Device_Event_Stub);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define __INCLUDE_FROM_RNDIS_DRIVER
|
||||
#define __INCLUDE_FROM_RNDIS_DEVICE_C
|
||||
#include "RNDISClassDevice.h"
|
||||
|
||||
static const uint32_t PROGMEM AdapterSupportedOIDList[] =
|
||||
{
|
||||
CPU_TO_LE32(OID_GEN_SUPPORTED_LIST),
|
||||
CPU_TO_LE32(OID_GEN_PHYSICAL_MEDIUM),
|
||||
CPU_TO_LE32(OID_GEN_HARDWARE_STATUS),
|
||||
CPU_TO_LE32(OID_GEN_MEDIA_SUPPORTED),
|
||||
CPU_TO_LE32(OID_GEN_MEDIA_IN_USE),
|
||||
CPU_TO_LE32(OID_GEN_MAXIMUM_FRAME_SIZE),
|
||||
CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
|
||||
CPU_TO_LE32(OID_GEN_LINK_SPEED),
|
||||
CPU_TO_LE32(OID_GEN_TRANSMIT_BLOCK_SIZE),
|
||||
CPU_TO_LE32(OID_GEN_RECEIVE_BLOCK_SIZE),
|
||||
CPU_TO_LE32(OID_GEN_VENDOR_ID),
|
||||
CPU_TO_LE32(OID_GEN_VENDOR_DESCRIPTION),
|
||||
CPU_TO_LE32(OID_GEN_CURRENT_PACKET_FILTER),
|
||||
CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
|
||||
CPU_TO_LE32(OID_GEN_MEDIA_CONNECT_STATUS),
|
||||
CPU_TO_LE32(OID_GEN_XMIT_OK),
|
||||
CPU_TO_LE32(OID_GEN_RCV_OK),
|
||||
CPU_TO_LE32(OID_GEN_XMIT_ERROR),
|
||||
CPU_TO_LE32(OID_GEN_RCV_ERROR),
|
||||
CPU_TO_LE32(OID_GEN_RCV_NO_BUFFER),
|
||||
CPU_TO_LE32(OID_802_3_PERMANENT_ADDRESS),
|
||||
CPU_TO_LE32(OID_802_3_CURRENT_ADDRESS),
|
||||
CPU_TO_LE32(OID_802_3_MULTICAST_LIST),
|
||||
CPU_TO_LE32(OID_802_3_MAXIMUM_LIST_SIZE),
|
||||
CPU_TO_LE32(OID_802_3_RCV_ERROR_ALIGNMENT),
|
||||
CPU_TO_LE32(OID_802_3_XMIT_ONE_COLLISION),
|
||||
CPU_TO_LE32(OID_802_3_XMIT_MORE_COLLISIONS),
|
||||
};
|
||||
|
||||
void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
if (!(Endpoint_IsSETUPReceived()))
|
||||
return;
|
||||
|
||||
if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
|
||||
return;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case RNDIS_REQ_SendEncapsulatedCommand:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, USB_ControlRequest.wLength);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
|
||||
}
|
||||
|
||||
break;
|
||||
case RNDIS_REQ_GetEncapsulatedResponse:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
|
||||
if (!(MessageHeader->MessageLength))
|
||||
{
|
||||
RNDISInterfaceInfo->Config.MessageBuffer[0] = 0;
|
||||
MessageHeader->MessageLength = CPU_TO_LE32(1);
|
||||
}
|
||||
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, le32_to_cpu(MessageHeader->MessageLength));
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
MessageHeader->MessageLength = CPU_TO_LE32(0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
|
||||
|
||||
RNDISInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
|
||||
RNDISInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
|
||||
RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (RNDISInterfaceInfo->Config.MessageBuffer == NULL)
|
||||
return false;
|
||||
|
||||
if (RNDISInterfaceInfo->Config.MessageBufferLength < RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH)
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataOUTEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.NotificationEndpoint, 1)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return;
|
||||
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpoint.Address);
|
||||
|
||||
if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
|
||||
{
|
||||
USB_Request_Header_t Notification = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = RNDIS_NOTIF_ResponseAvailable,
|
||||
.wValue = CPU_TO_LE16(0),
|
||||
.wIndex = CPU_TO_LE16(0),
|
||||
.wLength = CPU_TO_LE16(0),
|
||||
};
|
||||
|
||||
Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
RNDISInterfaceInfo->State.ResponseReady = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
|
||||
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
|
||||
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
|
||||
switch (le32_to_cpu(MessageHeader->MessageType))
|
||||
{
|
||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_Initialize_Message_t* INITIALIZE_Message =
|
||||
(RNDIS_Initialize_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
RNDIS_Initialize_Complete_t* INITIALIZE_Response =
|
||||
(RNDIS_Initialize_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
|
||||
INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT);
|
||||
INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t));
|
||||
INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
|
||||
INITIALIZE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
|
||||
|
||||
INITIALIZE_Response->MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR);
|
||||
INITIALIZE_Response->MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR);
|
||||
INITIALIZE_Response->DeviceFlags = CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS);
|
||||
INITIALIZE_Response->Medium = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
|
||||
INITIALIZE_Response->MaxPacketsPerTransfer = CPU_TO_LE32(1);
|
||||
INITIALIZE_Response->MaxTransferSize = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
|
||||
INITIALIZE_Response->PacketAlignmentFactor = CPU_TO_LE32(0);
|
||||
INITIALIZE_Response->AFListOffset = CPU_TO_LE32(0);
|
||||
INITIALIZE_Response->AFListSize = CPU_TO_LE32(0);
|
||||
|
||||
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
|
||||
break;
|
||||
case REMOTE_NDIS_HALT_MSG:
|
||||
RNDISInterfaceInfo->State.ResponseReady = false;
|
||||
|
||||
MessageHeader->MessageLength = CPU_TO_LE32(0);
|
||||
|
||||
RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
|
||||
break;
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid);
|
||||
|
||||
void* QueryData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
le32_to_cpu(QUERY_Message->InformationBufferOffset)];
|
||||
void* ResponseData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Query_Complete_t)];
|
||||
uint16_t ResponseSize;
|
||||
|
||||
QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT);
|
||||
|
||||
if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, le32_to_cpu(QUERY_Message->InformationBufferLength),
|
||||
ResponseData, &ResponseSize))
|
||||
{
|
||||
QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
|
||||
QUERY_Response->MessageLength = cpu_to_le32(sizeof(RNDIS_Query_Complete_t) + ResponseSize);
|
||||
|
||||
QUERY_Response->InformationBufferLength = CPU_TO_LE32(ResponseSize);
|
||||
QUERY_Response->InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED);
|
||||
QUERY_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t));
|
||||
|
||||
QUERY_Response->InformationBufferLength = CPU_TO_LE32(0);
|
||||
QUERY_Response->InformationBufferOffset = CPU_TO_LE32(0);
|
||||
}
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid);
|
||||
|
||||
SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT);
|
||||
SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t));
|
||||
SET_Response->RequestId = SET_Message->RequestId;
|
||||
|
||||
void* SetData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
le32_to_cpu(SET_Message->InformationBufferOffset)];
|
||||
|
||||
SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
|
||||
le32_to_cpu(SET_Message->InformationBufferLength)) ?
|
||||
REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
case REMOTE_NDIS_RESET_MSG:
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
|
||||
RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT);
|
||||
RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t));
|
||||
RESET_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
|
||||
RESET_Response->AddressingReset = CPU_TO_LE32(0);
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||
RNDISInterfaceInfo->State.ResponseReady = true;
|
||||
|
||||
RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
|
||||
(RNDIS_KeepAlive_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
|
||||
(RNDIS_KeepAlive_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
|
||||
|
||||
KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT);
|
||||
KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t));
|
||||
KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
|
||||
KEEPALIVE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
const uint32_t OId,
|
||||
void* const QueryData,
|
||||
const uint16_t QuerySize,
|
||||
void* ResponseData,
|
||||
uint16_t* const ResponseSize)
|
||||
{
|
||||
(void)QueryData;
|
||||
(void)QuerySize;
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_SUPPORTED_LIST:
|
||||
*ResponseSize = sizeof(AdapterSupportedOIDList);
|
||||
|
||||
memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
|
||||
|
||||
return true;
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate that the device is a true ethernet link */
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(0);
|
||||
|
||||
return true;
|
||||
case OID_GEN_HARDWARE_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(NDIS_HardwareStatus_Ready);
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_ID:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(0x00FFFFFF);
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX);
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
*ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
|
||||
|
||||
memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED);
|
||||
|
||||
return true;
|
||||
case OID_GEN_LINK_SPEED:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate 10Mb/s link speed */
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(100000);
|
||||
|
||||
return true;
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
*ResponseSize = sizeof(MAC_Address_t);
|
||||
|
||||
memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
|
||||
|
||||
return true;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate only one multicast address supported */
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(1);
|
||||
|
||||
return true;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
*((uint32_t*)ResponseData) = cpu_to_le32(RNDISInterfaceInfo->State.CurrPacketFilter);
|
||||
|
||||
return true;
|
||||
case OID_GEN_XMIT_OK:
|
||||
case OID_GEN_RCV_OK:
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
case OID_GEN_RCV_ERROR:
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Unused statistic OIDs - always return 0 for each */
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(0);
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
|
||||
*((uint32_t*)ResponseData) = CPU_TO_LE32(RNDISInterfaceInfo->Config.MessageBufferLength + ETHERNET_FRAME_SIZE_MAX);
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
const uint32_t OId,
|
||||
const void* SetData,
|
||||
const uint16_t SetSize)
|
||||
{
|
||||
(void)SetSize;
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
RNDISInterfaceInfo->State.CurrPacketFilter = le32_to_cpu(*((uint32_t*)SetData));
|
||||
RNDISInterfaceInfo->State.CurrRNDISState = (RNDISInterfaceInfo->State.CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Initialized;
|
||||
|
||||
return true;
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
/* Do nothing - throw away the value from the host as it is unused */
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) ||
|
||||
(RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
return Endpoint_IsOUTReceived();
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
uint16_t* const PacketLength)
|
||||
{
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) ||
|
||||
(RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
|
||||
{
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
|
||||
|
||||
*PacketLength = 0;
|
||||
|
||||
if (!(Endpoint_IsOUTReceived()))
|
||||
return ENDPOINT_RWSTREAM_NoError;
|
||||
|
||||
RNDIS_Packet_Message_t RNDISPacketHeader;
|
||||
Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
|
||||
|
||||
if (le32_to_cpu(RNDISPacketHeader.DataLength) > ETHERNET_FRAME_SIZE_MAX)
|
||||
{
|
||||
Endpoint_StallTransaction();
|
||||
|
||||
return RNDIS_ERROR_LOGICAL_CMD_FAILED;
|
||||
}
|
||||
|
||||
*PacketLength = (uint16_t)le32_to_cpu(RNDISPacketHeader.DataLength);
|
||||
|
||||
Endpoint_Read_Stream_LE(Buffer, *PacketLength, NULL);
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
return ENDPOINT_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t PacketLength)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_DeviceState != DEVICE_STATE_Configured) ||
|
||||
(RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
|
||||
{
|
||||
return ENDPOINT_RWSTREAM_DeviceDisconnected;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpoint.Address);
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
RNDIS_Packet_Message_t RNDISPacketHeader;
|
||||
|
||||
memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
|
||||
|
||||
RNDISPacketHeader.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG);
|
||||
RNDISPacketHeader.MessageLength = cpu_to_le32(sizeof(RNDIS_Packet_Message_t) + PacketLength);
|
||||
RNDISPacketHeader.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
|
||||
RNDISPacketHeader.DataLength = cpu_to_le32(PacketLength);
|
||||
|
||||
Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
|
||||
Endpoint_Write_Stream_LE(Buffer, PacketLength, NULL);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
return ENDPOINT_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Device mode driver for the library USB RNDIS Class driver.
|
||||
*
|
||||
* Device mode driver for the library USB RNDIS Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassRNDIS
|
||||
* \defgroup Group_USBClassRNDISDevice RNDIS Class Device Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassRNDISDevice_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassRNDISDevice_ModDescription Module Description
|
||||
* Device Mode USB Class driver framework interface, for the RNDIS USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_CLASS_DEVICE_H_
|
||||
#define _RNDIS_CLASS_DEVICE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/RNDISClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief RNDIS Class Device Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made for each RNDIS interface
|
||||
* within the user application, and passed to each of the RNDIS class driver functions as the
|
||||
* \c RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t ControlInterfaceNumber; /**< Interface number of the RNDIS control interface within the device. */
|
||||
|
||||
USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
|
||||
USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
|
||||
USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */
|
||||
|
||||
char* AdapterVendorDescription; /**< String description of the adapter vendor. */
|
||||
MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */
|
||||
|
||||
uint8_t* MessageBuffer; /**< Buffer where RNDIS messages can be stored by the internal driver. This
|
||||
* should be at least 132 bytes in length for minimal functionality. */
|
||||
uint16_t MessageBufferLength; /**< Length in bytes of the \ref MessageBuffer RNDIS buffer. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */
|
||||
uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */
|
||||
uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* are reset to their defaults when the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_RNDIS_Device_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library
|
||||
* \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
|
||||
* containing the given RNDIS interface is selected.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
|
||||
*/
|
||||
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be
|
||||
* linked to the library \ref EVENT_USB_Device_ControlRequest() event.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
|
||||
*/
|
||||
void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** General management task for a given RNDIS class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
|
||||
*/
|
||||
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Determines if a packet is currently waiting for the device to read in and process.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise.
|
||||
*/
|
||||
bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave
|
||||
* only the packet contents for processing by the device in the nominated buffer.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state.
|
||||
* \param[out] Buffer Pointer to a buffer where the packer data is to be written to.
|
||||
* \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
uint16_t* const PacketLength) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
|
||||
*
|
||||
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer where the packer data is to be read from.
|
||||
* \param[in] PacketLength Length in bytes of the packet to send.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t PacketLength) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_Query_Complete_t)
|
||||
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_RNDIS_DEVICE_C)
|
||||
static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1);
|
||||
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
const uint32_t OId,
|
||||
void* const QueryData,
|
||||
const uint16_t QuerySize,
|
||||
void* ResponseData,
|
||||
uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6);
|
||||
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
|
||||
const uint32_t OId,
|
||||
const void* SetData,
|
||||
const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(3);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
82
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Class/HIDClass.h
Normal file
82
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Class/HIDClass.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB HID Class driver.
|
||||
*
|
||||
* Master include file for the library USB HID Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassHID HID Class Driver
|
||||
* \brief USB class driver for the USB-IF Human Interface Device (HID) class standard.
|
||||
*
|
||||
* \section Sec_USBClassHID_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/HIDClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/HIDParser.c <i>(Makefile source module name: LUFA_SRC_USB)</i>
|
||||
*
|
||||
* \section Sec_USBClassHID_ModDescription Module Description
|
||||
* HID Class Driver module. This module contains an internal implementation of the USB HID Class, for both Device
|
||||
* and Host USB modes. User applications can use this class driver instead of implementing the HID class manually
|
||||
* via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Hosts or Devices using the USB HID Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HID_CLASS_H_
|
||||
#define _HID_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_HID_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "Device/HIDClassDevice.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/HIDClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_AOA_DRIVER
|
||||
#define __INCLUDE_FROM_ANDROIDACCESSORY_HOST_C
|
||||
#include "AndroidAccessoryClassHost.h"
|
||||
|
||||
bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const USB_Descriptor_Device_t* const DeviceDescriptor,
|
||||
bool* const NeedModeSwitch)
|
||||
{
|
||||
(void)AOAInterfaceInfo;
|
||||
|
||||
if (DeviceDescriptor->Header.Type != DTYPE_Device)
|
||||
return false;
|
||||
|
||||
*NeedModeSwitch = ((DeviceDescriptor->ProductID != ANDROID_ACCESSORY_PRODUCT_ID) &&
|
||||
(DeviceDescriptor->ProductID != ANDROID_ACCESSORY_ADB_PRODUCT_ID));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* AOAInterface = NULL;
|
||||
|
||||
memset(&AOAInterfaceInfo->State, 0x00, sizeof(AOAInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return AOA_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_AOA_Host_NextAndroidAccessoryInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return AOA_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
AOAInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint))
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_AOA_Host_NextInterfaceBulkEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return AOA_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
DataINEndpoint = EndpointData;
|
||||
else
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
|
||||
AOAInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
AOAInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
AOAInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
AOAInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
AOAInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
AOAInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return AOA_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return AOA_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
AOAInterfaceInfo->State.IsActive = true;
|
||||
AOAInterfaceInfo->State.InterfaceNumber = AOAInterface->InterfaceNumber;
|
||||
|
||||
return AOA_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == AOA_CSCP_AOADataClass) &&
|
||||
(Interface->SubClass == AOA_CSCP_AOADataSubclass) &&
|
||||
(Interface->Protocol == AOA_CSCP_AOADataProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress))))
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
|
||||
return;
|
||||
|
||||
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
|
||||
AOA_Host_Flush(AOAInterfaceInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
uint16_t AccessoryProtocol;
|
||||
if ((ErrorCode = AOA_Host_GetAccessoryProtocol(&AccessoryProtocol)) != HOST_WAITERROR_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
if ((AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV1)) && (AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV2)))
|
||||
return AOA_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
for (uint8_t PropertyIndex = 0; PropertyIndex < AOA_STRING_TOTAL_STRINGS; PropertyIndex++)
|
||||
{
|
||||
if ((ErrorCode = AOA_Host_SendPropertyString(AOAInterfaceInfo, PropertyIndex)) != HOST_WAITERROR_Successful)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE),
|
||||
.bRequest = AOA_REQ_StartAccessoryMode,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE),
|
||||
.bRequest = AOA_REQ_GetAccessoryProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = sizeof(uint16_t),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
return USB_Host_SendControlRequest(Protocol);
|
||||
}
|
||||
|
||||
static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const uint8_t StringIndex)
|
||||
{
|
||||
const char* String = AOAInterfaceInfo->Config.PropertyStrings[StringIndex];
|
||||
|
||||
if (String == NULL)
|
||||
String = "";
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE),
|
||||
.bRequest = AOA_REQ_SendString,
|
||||
.wValue = 0,
|
||||
.wIndex = StringIndex,
|
||||
.wLength = (strlen(String) + 1),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
return USB_Host_SendControlRequest((char*)String);
|
||||
}
|
||||
|
||||
uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
|
||||
Pipe_Unfreeze();
|
||||
ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL);
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const char* const String)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
|
||||
Pipe_Unfreeze();
|
||||
ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL);
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const uint8_t Data)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearOUT();
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_Write_8(Data);
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
|
||||
return 0;
|
||||
|
||||
Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
{
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return Pipe_BytesInPipe();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_Freeze();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
|
||||
return -1;
|
||||
|
||||
int16_t ReceivedByte = -1;
|
||||
|
||||
Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
if (Pipe_BytesInPipe())
|
||||
ReceivedByte = Pipe_Read_8();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
return PIPE_READYWAIT_NoError;
|
||||
|
||||
bool BankFull = !(Pipe_IsReadWriteAllowed());
|
||||
|
||||
Pipe_ClearOUT();
|
||||
|
||||
if (BankFull)
|
||||
{
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearOUT();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, AOAInterfaceInfo);
|
||||
}
|
||||
|
||||
void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar_Blocking, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, AOAInterfaceInfo);
|
||||
}
|
||||
|
||||
static int AOA_Host_putchar(char c,
|
||||
FILE* Stream)
|
||||
{
|
||||
return AOA_Host_SendByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
|
||||
}
|
||||
|
||||
static int AOA_Host_getchar(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream));
|
||||
|
||||
if (ReceivedByte < 0)
|
||||
return _FDEV_EOF;
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
static int AOA_Host_getchar_Blocking(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte;
|
||||
|
||||
while ((ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream))) < 0)
|
||||
{
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
return _FDEV_EOF;
|
||||
|
||||
AOA_Host_USBTask((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream));
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB Android Open Accessory Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB Android Open Accessory Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassAOA
|
||||
* \defgroup Group_USBClassAndroidAccessoryHost Android Open Accessory Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassAndroidAccessoryHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassAndroidAccessoryHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the Android Open Accessory USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __AOA_CLASS_HOST_H__
|
||||
#define __AOA_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/AndroidAccessoryClassCommon.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_AOA_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Error code for some Android Open Accessory Host functions, indicating a logical (and not hardware) error. */
|
||||
#define AOA_ERROR_LOGICAL_CMD_FAILED 0x80
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief Android Open Accessory Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the Android Open Accessory class driver functions as the \c AOAInterfaceInfo
|
||||
* parameter. This stores each Android Open Accessory interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
|
||||
char* PropertyStrings[AOA_STRING_TOTAL_STRINGS]; /**< Android Accessory property strings, sent to identify the accessory when the
|
||||
* Android device is switched into Open Accessory mode. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref AOA_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t InterfaceNumber; /**< Interface index of the AOA interface within the attached device. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_AOA_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref AOA_Host_ConfigurePipes() function. */
|
||||
enum AOA_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
AOA_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
AOA_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
AOA_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Android Open Accessory interface was not found in the device's Configuration Descriptor. */
|
||||
AOA_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** General management task for a given Android Open Accessory host class interface, required for the correct operation of the interface.
|
||||
* This should be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing an Android Open Accessory Class host configuration and state.
|
||||
*/
|
||||
void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Validates a device descriptor, to check if the device is a valid Android device, and if it is currently in Android Open Accessory mode.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state.
|
||||
* \param[in] DeviceDescriptor Pointer a buffer containing the attached device's Device Descriptor.
|
||||
* \param[out] NeedModeSwitch Pointer to a boolean where the mode switch requirement of the attached device is to be stored.
|
||||
*
|
||||
* \return Boolean \c true if the attached device is a valid Android device, \c false otherwise.
|
||||
*/
|
||||
bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const USB_Descriptor_Device_t* const DeviceDescriptor,
|
||||
bool* const NeedModeSwitch) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Host interface configuration routine, to configure a given Android Open Accessory host interface instance using the Configuration
|
||||
* Descriptor read from an attached USB device. This function automatically updates the given Android Open Accessory Host instance's
|
||||
* state values and configures the pipes required to communicate with the interface if it is found within the device. This should be
|
||||
* called once after the stack has enumerated the attached device, while the host state machine is in the Addressed state.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref AOA_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Starts Accessory Mode in the attached Android device. This function will validate the device's Android Open Accessory protocol
|
||||
* version, send the configured property strings, and request a switch to Android Open Accessory mode.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum, or \ref AOA_ERROR_LOGICAL_CMD_FAILED if a logical error occurred..
|
||||
*/
|
||||
uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is
|
||||
* called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank
|
||||
* becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows for
|
||||
* multiple bytes to be packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer containing the data to send to the device.
|
||||
* \param[in] Length Length of the data to send to the device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the
|
||||
* function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe
|
||||
* bank becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows
|
||||
* for multiple bytes to be packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state.
|
||||
* \param[in] String Pointer to the null terminated string to send to the device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the
|
||||
* byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the
|
||||
* \ref AOA_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
|
||||
* packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state.
|
||||
* \param[in] Data Byte of data to send to the device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Determines the number of bytes received by the AOA interface from the device, waiting to be read. This indicates the number
|
||||
* of bytes in the IN pipe bank only, and thus the number of calls to \ref AOA_Host_ReceiveByte() which are guaranteed to succeed
|
||||
* immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be
|
||||
* released back to the USB controller until all bytes are read.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state.
|
||||
*
|
||||
* \return Total number of buffered bytes received from the device.
|
||||
*/
|
||||
uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function
|
||||
* returns a negative value. The \ref AOA_Host_BytesReceived() function may be queried in advance to determine how many bytes
|
||||
* are currently buffered in the AOA interface's data receive pipe.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state.
|
||||
*
|
||||
* \return Next received byte from the device, or a negative value if no data received.
|
||||
*/
|
||||
int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Creates a standard character stream for the given AOA Device instance so that it can be used with all the regular
|
||||
* functions in the standard \c <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created
|
||||
* stream is bidirectional and can be used for both input and output functions.
|
||||
*
|
||||
* Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
|
||||
* fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
|
||||
* be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
|
||||
* line buffering.
|
||||
*
|
||||
* \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions
|
||||
* to the given AOA interface.
|
||||
* \n\n
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Identical to \ref AOA_Host_CreateStream(), except that reads are blocking until the calling stream function terminates
|
||||
* the transfer. While blocking, the USB and AOA service tasks are called repeatedly to maintain USB communications.
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_ANDROIDACCESSORY_HOST_C)
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
static int AOA_Host_putchar(char c,
|
||||
FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
|
||||
static int AOA_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static int AOA_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
|
||||
static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo,
|
||||
const uint8_t StringIndex) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_AUDIO_DRIVER
|
||||
#define __INCLUDE_FROM_AUDIO_HOST_C
|
||||
#include "AudioClassHost.h"
|
||||
|
||||
uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* AudioControlInterface = NULL;
|
||||
USB_Descriptor_Interface_t* AudioStreamingInterface = NULL;
|
||||
|
||||
memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return AUDIO_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
while ((AudioInterfaceInfo->Config.DataINPipe.Address && !(DataINEndpoint)) ||
|
||||
(AudioInterfaceInfo->Config.DataOUTPipe.Address && !(DataOUTEndpoint)))
|
||||
{
|
||||
if (!(AudioControlInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (!(AudioControlInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_Audio_Host_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return AUDIO_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
AudioControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return AUDIO_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
}
|
||||
|
||||
AudioStreamingInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
DataINEndpoint = EndpointData;
|
||||
else
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
|
||||
AudioInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
AudioInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
AudioInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_ISOCHRONOUS;
|
||||
AudioInterfaceInfo->Config.DataINPipe.Banks = 2;
|
||||
|
||||
AudioInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
AudioInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
AudioInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_ISOCHRONOUS;
|
||||
AudioInterfaceInfo->Config.DataOUTPipe.Banks = 2;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&AudioInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return AUDIO_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&AudioInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return AUDIO_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
AudioInterfaceInfo->State.ControlInterfaceNumber = AudioControlInterface->InterfaceNumber;
|
||||
AudioInterfaceInfo->State.StreamingInterfaceNumber = AudioStreamingInterface->InterfaceNumber;
|
||||
AudioInterfaceInfo->State.EnabledStreamingAltIndex = AudioStreamingInterface->AlternateSetting;
|
||||
AudioInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return AUDIO_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
|
||||
(Interface->SubClass == AUDIO_CSCP_ControlSubclass) &&
|
||||
(Interface->Protocol == AUDIO_CSCP_ControlProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
|
||||
(Interface->SubClass == AUDIO_CSCP_AudioStreamingSubclass) &&
|
||||
(Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((Endpoint->Attributes & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS)
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const bool EnableStreaming)
|
||||
{
|
||||
if (!(AudioInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
return USB_Host_SetInterfaceAltSetting(AudioInterfaceInfo->State.StreamingInterfaceNumber,
|
||||
EnableStreaming ? AudioInterfaceInfo->State.EnabledStreamingAltIndex : 0);
|
||||
}
|
||||
|
||||
uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const uint8_t DataPipeIndex,
|
||||
const uint8_t EndpointProperty,
|
||||
const uint8_t EndpointControl,
|
||||
const uint16_t DataLength,
|
||||
void* const Data)
|
||||
{
|
||||
if (!(AudioInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
uint8_t RequestType;
|
||||
uint8_t EndpointAddress;
|
||||
|
||||
if (EndpointProperty & 0x80)
|
||||
RequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT);
|
||||
else
|
||||
RequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT);
|
||||
|
||||
Pipe_SelectPipe(DataPipeIndex);
|
||||
EndpointAddress = Pipe_GetBoundEndpointAddress();
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = RequestType,
|
||||
.bRequest = EndpointProperty,
|
||||
.wValue = ((uint16_t)EndpointControl << 8),
|
||||
.wIndex = EndpointAddress,
|
||||
.wLength = DataLength,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB Audio 1.0 Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB Audio 1.0 Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassAudio
|
||||
* \defgroup Group_USBClassAudioHost Audio 1.0 Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassAudioHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/AudioClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassAudioHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __AUDIO_CLASS_HOST_H__
|
||||
#define __AUDIO_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/AudioClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief Audio Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the Audio class driver functions as the \c AudioInterfaceInfo parameter. This
|
||||
* stores each Audio interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref Audio_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t ControlInterfaceNumber; /**< Interface index of the Audio Control interface within the attached device. */
|
||||
uint8_t StreamingInterfaceNumber; /**< Interface index of the Audio Streaming interface within the attached device. */
|
||||
|
||||
uint8_t EnabledStreamingAltIndex; /**< Alternative setting index of the Audio Streaming interface when the stream is enabled. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_Audio_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref Audio_Host_ConfigurePipes() function. */
|
||||
enum AUDIO_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
AUDIO_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
AUDIO_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
AUDIO_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible AUDIO interface was not found in the device's Configuration Descriptor. */
|
||||
AUDIO_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Host interface configuration routine, to configure a given Audio host interface instance using the Configuration
|
||||
* Descriptor read from an attached USB device. This function automatically updates the given Audio Host instance's
|
||||
* state values and configures the pipes required to communicate with the interface if it is found within the
|
||||
* device. This should be called once after the stack has enumerated the attached device, while the host state
|
||||
* machine is in the Addressed state.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref AUDIO_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Starts or stops the audio streaming for the given configured Audio Host interface, allowing for audio samples to be
|
||||
* send and/or received.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state.
|
||||
* \param[in] EnableStreaming Boolean true to enable streaming of the specified interface, \c false to disable
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const bool EnableStreaming) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Gets or sets the specified property of a streaming audio class endpoint that is bound to a pipe in the given
|
||||
* class instance.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state.
|
||||
* \param[in] DataPipeIndex Index of the data pipe whose bound endpoint is to be altered.
|
||||
* \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t.
|
||||
* \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t.
|
||||
* \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum
|
||||
* length of the retrieved data.
|
||||
* \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where
|
||||
* the retrieved data is to be stored for GET operations.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const uint8_t DataPipeIndex,
|
||||
const uint8_t EndpointProperty,
|
||||
const uint8_t EndpointControl,
|
||||
const uint16_t DataLength,
|
||||
void* const Data) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** General management task for a given Audio host class interface, required for the correct operation of
|
||||
* the interface. This should be called frequently in the main program loop, before the master USB management task
|
||||
* \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state.
|
||||
*/
|
||||
static inline void Audio_Host_USBTask(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Host_USBTask(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
{
|
||||
(void)AudioInterfaceInfo;
|
||||
}
|
||||
|
||||
/** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming
|
||||
* IN pipe ready for reading.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise.
|
||||
*/
|
||||
static inline bool Audio_Host_IsSampleReceived(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline bool Audio_Host_IsSampleReceived(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AudioInterfaceInfo->State.IsActive))
|
||||
return false;
|
||||
|
||||
bool SampleReceived = false;
|
||||
|
||||
Pipe_SelectPipe(AudioInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
SampleReceived = Pipe_IsINReceived();
|
||||
Pipe_Freeze();
|
||||
|
||||
return SampleReceived;
|
||||
}
|
||||
|
||||
/** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects
|
||||
* the streaming OUT pipe ready for writing.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise.
|
||||
*/
|
||||
static inline bool Audio_Host_IsReadyForNextSample(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline bool Audio_Host_IsReadyForNextSample(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(AudioInterfaceInfo->State.IsActive))
|
||||
return false;
|
||||
|
||||
Pipe_SelectPipe(AudioInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
return Pipe_IsOUTReady();
|
||||
}
|
||||
|
||||
/** Reads the next 8-bit audio sample from the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure
|
||||
* that the correct pipe is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Signed 8-bit audio sample from the audio interface.
|
||||
*/
|
||||
static inline int8_t Audio_Host_ReadSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline int8_t Audio_Host_ReadSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
{
|
||||
int8_t Sample;
|
||||
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Sample = Pipe_Read_8();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
return Sample;
|
||||
}
|
||||
|
||||
/** Reads the next 16-bit audio sample from the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure
|
||||
* that the correct pipe is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Signed 16-bit audio sample from the audio interface.
|
||||
*/
|
||||
static inline int16_t Audio_Host_ReadSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline int16_t Audio_Host_ReadSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
{
|
||||
int16_t Sample;
|
||||
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Sample = (int16_t)Pipe_Read_16_LE();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
return Sample;
|
||||
}
|
||||
|
||||
/** Reads the next 24-bit audio sample from the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure
|
||||
* that the correct pipe is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
*
|
||||
* \return Signed 24-bit audio sample from the audio interface.
|
||||
*/
|
||||
static inline int32_t Audio_Host_ReadSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline int32_t Audio_Host_ReadSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo)
|
||||
{
|
||||
int32_t Sample;
|
||||
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Sample = (((uint32_t)Pipe_Read_8() << 16) | Pipe_Read_16_LE());
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
return Sample;
|
||||
}
|
||||
|
||||
/** Writes the next 8-bit audio sample to the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to
|
||||
* ensure that the correct pipe is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] Sample Signed 8-bit audio sample.
|
||||
*/
|
||||
static inline void Audio_Host_WriteSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Host_WriteSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const int8_t Sample)
|
||||
{
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Pipe_Write_8(Sample);
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
Pipe_ClearOUT();
|
||||
Pipe_WaitUntilReady();
|
||||
Pipe_Freeze();
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes the next 16-bit audio sample to the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to
|
||||
* ensure that the correct pipe is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] Sample Signed 16-bit audio sample.
|
||||
*/
|
||||
static inline void Audio_Host_WriteSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Host_WriteSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const int16_t Sample)
|
||||
{
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Pipe_Write_16_LE(Sample);
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
Pipe_ClearOUT();
|
||||
Pipe_WaitUntilReady();
|
||||
Pipe_Freeze();
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes the next 24-bit audio sample to the current audio interface.
|
||||
*
|
||||
* \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to
|
||||
* ensure that the correct pipe is selected and ready for data.
|
||||
*
|
||||
* \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
|
||||
* \param[in] Sample Signed 24-bit audio sample.
|
||||
*/
|
||||
static inline void Audio_Host_WriteSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void Audio_Host_WriteSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
|
||||
const int32_t Sample)
|
||||
{
|
||||
(void)AudioInterfaceInfo;
|
||||
|
||||
Pipe_Write_16_LE(Sample);
|
||||
Pipe_Write_8(Sample >> 16);
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
Pipe_ClearOUT();
|
||||
Pipe_WaitUntilReady();
|
||||
Pipe_Freeze();
|
||||
}
|
||||
}
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_AUDIO_HOST_C)
|
||||
static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_CDC_DRIVER
|
||||
#define __INCLUDE_FROM_CDC_HOST_C
|
||||
#include "CDCClassHost.h"
|
||||
|
||||
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* CDCControlInterface = NULL;
|
||||
|
||||
memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return CDC_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint))
|
||||
{
|
||||
if (!(CDCControlInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (NotificationEndpoint)
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return CDC_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return CDC_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
CDCControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
NotificationEndpoint = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
{
|
||||
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
|
||||
NotificationEndpoint = EndpointData;
|
||||
else
|
||||
DataINEndpoint = EndpointData;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
}
|
||||
|
||||
CDCInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
CDCInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
CDCInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
CDCInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
CDCInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
CDCInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
CDCInterfaceInfo->Config.NotificationPipe.Size = le16_to_cpu(NotificationEndpoint->EndpointSize);
|
||||
CDCInterfaceInfo->Config.NotificationPipe.EndpointAddress = NotificationEndpoint->EndpointAddress;
|
||||
CDCInterfaceInfo->Config.NotificationPipe.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return CDC_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return CDC_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.NotificationPipe, 1)))
|
||||
return CDC_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
CDCInterfaceInfo->State.ControlInterfaceNumber = CDCControlInterface->InterfaceNumber;
|
||||
CDCInterfaceInfo->State.ControlLineStates.HostToDevice = (CDC_CONTROL_LINE_OUT_RTS | CDC_CONTROL_LINE_OUT_DTR);
|
||||
CDCInterfaceInfo->State.ControlLineStates.DeviceToHost = (CDC_CONTROL_LINE_IN_DCD | CDC_CONTROL_LINE_IN_DSR);
|
||||
CDCInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return CDC_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == CDC_CSCP_CDCClass) &&
|
||||
(Interface->SubClass == CDC_CSCP_ACMSubclass) &&
|
||||
(Interface->Protocol == CDC_CSCP_ATCommandProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == CDC_CSCP_CDCDataClass) &&
|
||||
(Interface->SubClass == CDC_CSCP_NoDataSubclass) &&
|
||||
(Interface->Protocol == CDC_CSCP_NoDataProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
|
||||
!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
USB_Request_Header_t Notification;
|
||||
Pipe_Read_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
|
||||
|
||||
if ((Notification.bRequest == CDC_NOTIF_SerialState) &&
|
||||
(Notification.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)))
|
||||
{
|
||||
Pipe_Read_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
|
||||
sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
|
||||
NULL);
|
||||
|
||||
Pipe_ClearIN();
|
||||
|
||||
EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
|
||||
CDC_Host_Flush(CDCInterfaceInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = CDC_REQ_SetLineEncoding,
|
||||
.wValue = 0,
|
||||
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
|
||||
.wLength = sizeof(CDCInterfaceInfo->State.LineEncoding),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(&CDCInterfaceInfo->State.LineEncoding);
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = CDC_REQ_SetControlLineState,
|
||||
.wValue = CDCInterfaceInfo->State.ControlLineStates.HostToDevice,
|
||||
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const uint8_t Duration)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = CDC_REQ_SendBreak,
|
||||
.wValue = Duration,
|
||||
.wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
|
||||
Pipe_Unfreeze();
|
||||
ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL);
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
|
||||
Pipe_Unfreeze();
|
||||
ErrorCode = Pipe_Write_PStream_LE(Buffer, Length, NULL);
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const char* const String)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
|
||||
Pipe_Unfreeze();
|
||||
ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL);
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const char* const String)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
|
||||
Pipe_Unfreeze();
|
||||
ErrorCode = Pipe_Write_PStream_LE(String, strlen_P(String), NULL);
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const uint8_t Data)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearOUT();
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_Write_8(Data);
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return 0;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
{
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return Pipe_BytesInPipe();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_Freeze();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return -1;
|
||||
|
||||
int16_t ReceivedByte = -1;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
if (Pipe_BytesInPipe())
|
||||
ReceivedByte = Pipe_Read_8();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
return PIPE_READYWAIT_NoError;
|
||||
|
||||
bool BankFull = !(Pipe_IsReadWriteAllowed());
|
||||
|
||||
Pipe_ClearOUT();
|
||||
|
||||
if (BankFull)
|
||||
{
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearOUT();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, CDCInterfaceInfo);
|
||||
}
|
||||
|
||||
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream)
|
||||
{
|
||||
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
|
||||
fdev_set_udata(Stream, CDCInterfaceInfo);
|
||||
}
|
||||
|
||||
static int CDC_Host_putchar(char c,
|
||||
FILE* Stream)
|
||||
{
|
||||
return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
|
||||
}
|
||||
|
||||
static int CDC_Host_getchar(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
|
||||
|
||||
if (ReceivedByte < 0)
|
||||
return _FDEV_EOF;
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
static int CDC_Host_getchar_Blocking(FILE* Stream)
|
||||
{
|
||||
int16_t ReceivedByte;
|
||||
|
||||
while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0)
|
||||
{
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
return _FDEV_EOF;
|
||||
|
||||
CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CDC_Host_Event_Stub(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB CDC Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB CDC Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassCDC
|
||||
* \defgroup Group_USBClassCDCHost CDC Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassCDCHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/CDCClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassCDCHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the CDC USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __CDC_CLASS_HOST_H__
|
||||
#define __CDC_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/CDCClassCommon.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_CDC_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief CDC Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the CDC class driver functions as the \c CDCInterfaceInfo parameter. This
|
||||
* stores each CDC interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
USB_Pipe_Table_t NotificationPipe; /**< Notification IN Pipe configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref CDC_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device. */
|
||||
|
||||
struct
|
||||
{
|
||||
uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_*
|
||||
* masks - to notify the device of changes to these values, call the
|
||||
* \ref CDC_Host_SendControlLineStateChange() function.
|
||||
*/
|
||||
uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_*
|
||||
* masks. This value is updated each time \ref CDC_Host_USBTask() is called.
|
||||
*/
|
||||
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
|
||||
|
||||
CDC_LineEncoding_t LineEncoding; /**< Line encoding used in the virtual serial port, for the device's information.
|
||||
* This is generally only used if the virtual serial port data is to be
|
||||
* reconstructed on a physical UART. When set by the host application, the
|
||||
* \ref CDC_Host_SetLineEncoding() function must be called to push the changes
|
||||
* to the device.
|
||||
*/
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_CDC_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref CDC_Host_ConfigurePipes() function. */
|
||||
enum CDC_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
CDC_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
CDC_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor. */
|
||||
CDC_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** General management task for a given CDC host class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state.
|
||||
*/
|
||||
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Host interface configuration routine, to configure a given CDC host interface instance using the Configuration
|
||||
* Descriptor read from an attached USB device. This function automatically updates the given CDC Host instance's
|
||||
* state values and configures the pipes required to communicate with the interface if it is found within the device.
|
||||
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
|
||||
* the Addressed state.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref CDC_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Sets the line encoding for the attached device's virtual serial port. This should be called when the \c LineEncoding
|
||||
* values of the interface have been changed to push the new settings to the USB device.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a Serial Control Line State Change notification to the device. This should be called when the virtual serial
|
||||
* control lines (DTR, RTS, etc.) have changed states. Line states persist until they are cleared via a second
|
||||
* notification. This should be called each time the CDC class driver's \c ControlLineStates.HostToDevice value is updated
|
||||
* to push the new states to the USB device.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a Send Break request to the device. This is generally used to separate data or to indicate a special condition
|
||||
* to the receiving device.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
* \param[in] Duration Duration of the break, in milliseconds.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is
|
||||
* called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank
|
||||
* becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows for
|
||||
* multiple bytes to be packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer containing the data to send to the device.
|
||||
* \param[in] Length Length of the data to send to the device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a given data buffer from PROGMEM space to the attached USB device, if connected. If a device is not connected when the
|
||||
* function is called, the string is discarded. Bytes will be queued for transmission to the host until either the pipe
|
||||
* bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows
|
||||
* for multiple bytes to be packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer containing the data to send to the device.
|
||||
* \param[in] Length Length of the data to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const void* const Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the
|
||||
* function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe
|
||||
* bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows
|
||||
* for multiple bytes to be packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
* \param[in] String Pointer to the null terminated string to send to the device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given null terminated string from PROGMEM space to the attached USB device, if connected. If a device is not connected
|
||||
* when the function is called, the string is discarded. Bytes will be queued for transmission to the device until either
|
||||
* the pipe bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to
|
||||
* the device. This allows for multiple bytes to be packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or
|
||||
* the call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
* \param[in] String Pointer to the null terminated string to send to the host.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the
|
||||
* byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the
|
||||
* \ref CDC_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
|
||||
* packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
* \param[in] Data Byte of data to send to the device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Determines the number of bytes received by the CDC interface from the device, waiting to be read. This indicates the number
|
||||
* of bytes in the IN pipe bank only, and thus the number of calls to \ref CDC_Host_ReceiveByte() which are guaranteed to succeed
|
||||
* immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be
|
||||
* released back to the USB controller until all bytes are read.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
*
|
||||
* \return Total number of buffered bytes received from the device.
|
||||
*/
|
||||
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function
|
||||
* returns a negative value. The \ref CDC_Host_BytesReceived() function may be queried in advance to determine how many bytes
|
||||
* are currently buffered in the CDC interface's data receive pipe.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
*
|
||||
* \return Next received byte from the device, or a negative value if no data received.
|
||||
*/
|
||||
int16_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
#if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__)
|
||||
/** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular
|
||||
* functions in the standard \c <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created
|
||||
* stream is bidirectional and can be used for both input and output functions.
|
||||
*
|
||||
* Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
|
||||
* fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
|
||||
* be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
|
||||
* line buffering.
|
||||
*
|
||||
* \note The created stream can be given as \c stdout if desired to direct the standard output from all \c <stdio.h> functions
|
||||
* to the given CDC interface.
|
||||
* \n\n
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Identical to \ref CDC_Host_CreateStream(), except that reads are blocking until the calling stream function terminates
|
||||
* the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
|
||||
*
|
||||
* \note This function is not available on all microcontroller architectures.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
|
||||
* \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
|
||||
*/
|
||||
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
|
||||
FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
#endif
|
||||
|
||||
/** CDC class driver event for a control line state change on a CDC host interface. This event fires each time the device notifies
|
||||
* the host of a control line state change (containing the virtual serial control line states, such as DCD) and may be hooked in the
|
||||
* user program by declaring a handler function with the same name and parameters listed here. The new control line states
|
||||
* are available in the \c ControlLineStates.DeviceToHost value inside the CDC host interface structure passed as a parameter, set as
|
||||
* a mask of \c CDC_CONTROL_LINE_IN_* masks.
|
||||
*
|
||||
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
|
||||
*/
|
||||
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_CDC_HOST_C)
|
||||
#if defined(FDEV_SETUP_STREAM)
|
||||
static int CDC_Host_putchar(char c,
|
||||
FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
|
||||
static int CDC_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static int CDC_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
|
||||
void CDC_Host_Event_Stub(void) ATTR_CONST;
|
||||
|
||||
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
||||
ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Host_Event_Stub);
|
||||
|
||||
static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_HID_DRIVER
|
||||
#define __INCLUDE_FROM_HID_HOST_C
|
||||
#include "HIDClassHost.h"
|
||||
|
||||
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* HIDInterface = NULL;
|
||||
USB_HID_Descriptor_HID_t* HIDDescriptor = NULL;
|
||||
|
||||
memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return HID_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint))
|
||||
{
|
||||
if (!(HIDInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (DataINEndpoint)
|
||||
break;
|
||||
|
||||
do
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return HID_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
HIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
} while (HIDInterfaceInfo->Config.HIDInterfaceProtocol &&
|
||||
(HIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol));
|
||||
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_HID_Host_NextHIDDescriptor) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return HID_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
HIDDescriptor = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_HID_Descriptor_HID_t);
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
DataINEndpoint = EndpointData;
|
||||
else
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
|
||||
HIDInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
HIDInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
HIDInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&HIDInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return HID_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (DataOUTEndpoint)
|
||||
{
|
||||
HIDInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
HIDInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
HIDInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&HIDInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return HID_ENUMERROR_PipeConfigurationFailed;
|
||||
}
|
||||
|
||||
HIDInterfaceInfo->State.InterfaceNumber = HIDInterface->InterfaceNumber;
|
||||
HIDInterfaceInfo->State.HIDReportSize = LE16_TO_CPU(HIDDescriptor->HIDReportLength);
|
||||
HIDInterfaceInfo->State.SupportsBootProtocol = (HIDInterface->SubClass != HID_CSCP_NonBootProtocol);
|
||||
HIDInterfaceInfo->State.LargestReportSize = 8;
|
||||
HIDInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return HID_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_HID_Host_NextHIDInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if (Interface->Class == HID_CSCP_HIDClass)
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_HID_Host_NextHIDDescriptor(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == HID_DTYPE_HID)
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
else
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
const uint8_t ReportID,
|
||||
void* Buffer)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetReport,
|
||||
.wValue = ((HID_REPORT_ITEM_In + 1) << 8) | ReportID,
|
||||
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
void* Buffer)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
uint16_t ReportSize;
|
||||
uint8_t* BufferPos = Buffer;
|
||||
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
if (!(HIDInterfaceInfo->State.UsingBootProtocol))
|
||||
{
|
||||
uint8_t ReportID = 0;
|
||||
|
||||
if (HIDInterfaceInfo->Config.HIDParserData->UsingReportIDs)
|
||||
{
|
||||
ReportID = Pipe_Read_8();
|
||||
*(BufferPos++) = ReportID;
|
||||
}
|
||||
|
||||
ReportSize = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ReportSize = Pipe_BytesInPipe();
|
||||
}
|
||||
|
||||
if ((ErrorCode = Pipe_Read_Stream_LE(BufferPos, ReportSize, NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
const uint8_t ReportID,
|
||||
#endif
|
||||
const uint8_t ReportType,
|
||||
void* Buffer,
|
||||
const uint16_t ReportSize)
|
||||
{
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
|
||||
if (HIDInterfaceInfo->State.DeviceUsesOUTPipe && (ReportType == HID_REPORT_ITEM_Out))
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (ReportID)
|
||||
Pipe_Write_Stream_LE(&ReportID, sizeof(ReportID), NULL);
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, ReportSize, NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearOUT();
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetReport,
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
.wValue = ((ReportType + 1) << 8) | ReportID,
|
||||
#else
|
||||
.wValue = ((ReportType + 1) << 8),
|
||||
#endif
|
||||
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = ReportSize,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
|
||||
return false;
|
||||
|
||||
bool ReportReceived;
|
||||
|
||||
Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
ReportReceived = Pipe_IsINReceived();
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ReportReceived;
|
||||
}
|
||||
|
||||
uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if (!(HIDInterfaceInfo->State.SupportsBootProtocol))
|
||||
return HID_ERROR_LOGICAL;
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
HIDInterfaceInfo->State.LargestReportSize = 8;
|
||||
HIDInterfaceInfo->State.UsingBootProtocol = true;
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
uint8_t HID_Host_SetIdlePeriod(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
const uint16_t MS)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetIdle,
|
||||
.wValue = ((MS << 6) & 0xFF00),
|
||||
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
uint8_t HIDReportData[HIDInterfaceInfo->State.HIDReportSize];
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (HID_DTYPE_Report << 8),
|
||||
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = HIDInterfaceInfo->State.HIDReportSize,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
if (HIDInterfaceInfo->State.UsingBootProtocol)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 1,
|
||||
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
HIDInterfaceInfo->State.UsingBootProtocol = false;
|
||||
}
|
||||
|
||||
if (HIDInterfaceInfo->Config.HIDParserData == NULL)
|
||||
return HID_ERROR_LOGICAL;
|
||||
|
||||
if ((ErrorCode = USB_ProcessHIDReport(HIDReportData, HIDInterfaceInfo->State.HIDReportSize,
|
||||
HIDInterfaceInfo->Config.HIDParserData)) != HID_PARSE_Successful)
|
||||
{
|
||||
return HID_ERROR_LOGICAL | ErrorCode;
|
||||
}
|
||||
|
||||
uint16_t LargestReportSizeBits = HIDInterfaceInfo->Config.HIDParserData->LargestReportSizeBits;
|
||||
HIDInterfaceInfo->State.LargestReportSize = (LargestReportSizeBits >> 3) + ((LargestReportSizeBits & 0x07) != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB HID Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB HID Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassHID
|
||||
* \defgroup Group_USBClassHIDHost HID Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassHIDHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/HIDClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassHIDHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the HID USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __HID_CLASS_HOST_H__
|
||||
#define __HID_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/HIDClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_HID_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Error code for some HID Host functions, indicating a logical (and not hardware) error. */
|
||||
#define HID_ERROR_LOGICAL 0x80
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief HID Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the HID class driver functions as the \c HIDInterfaceInfo parameter. This
|
||||
* stores each HID interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
|
||||
uint8_t HIDInterfaceProtocol; /**< HID interface protocol value to match against if a specific
|
||||
* boot subclass protocol is required, a protocol value from the
|
||||
* \ref HID_Descriptor_ClassSubclassProtocol_t enum.
|
||||
*/
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
HID_ReportInfo_t* HIDParserData; /**< HID parser data to store the parsed HID report data, when boot protocol
|
||||
* is not used.
|
||||
*
|
||||
* \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined,
|
||||
* this field is unavailable.
|
||||
*/
|
||||
#endif
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t InterfaceNumber; /**< Interface index of the HID interface within the attached device. */
|
||||
|
||||
bool SupportsBootProtocol; /**< Indicates if the current interface instance supports the HID Boot
|
||||
* Protocol when enabled via \ref HID_Host_SetBootProtocol().
|
||||
*/
|
||||
bool DeviceUsesOUTPipe; /**< Indicates if the current interface instance uses a separate OUT data pipe for
|
||||
* OUT reports, or if OUT reports are sent via the control pipe instead.
|
||||
*/
|
||||
bool UsingBootProtocol; /**< Indicates that the interface is currently initialized in Boot Protocol mode */
|
||||
uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device. */
|
||||
|
||||
uint8_t LargestReportSize; /**< Largest report the device will send, in bytes. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_HID_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */
|
||||
enum HID_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
HID_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
HID_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor. */
|
||||
HID_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Host interface configuration routine, to configure a given HID host interface instance using the Configuration
|
||||
* Descriptor read from an attached USB device. This function automatically updates the given HID Host instance's
|
||||
* state values and configures the pipes required to communicate with the interface if it is found within the
|
||||
* device. This should be called once after the stack has enumerated the attached device, while the host state
|
||||
* machine is in the Addressed state.
|
||||
*
|
||||
* \attention Once the device pipes are configured, the HID device's reporting protocol <b>must</b> be set via a call
|
||||
* to either the \ref HID_Host_SetBootProtocol() or \ref HID_Host_SetReportProtocol() function.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref HID_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
|
||||
/** Receives a HID IN report from the attached HID device, when a report has been received on the HID IN Data pipe.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \attention The destination buffer should be large enough to accommodate the largest report that the attached device
|
||||
* can generate.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
* \param[in] Buffer Buffer to store the received report into.
|
||||
*
|
||||
* \return An error code from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
/** Receives a HID IN report from the attached device, by the report ID.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
* \param[in] ReportID Report ID of the received report if ControlRequest is false, set by the to the Report ID to fetch.
|
||||
* \param[in] Buffer Buffer to store the received report into.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
const uint8_t ReportID,
|
||||
void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
#endif
|
||||
|
||||
/** Sends an OUT or FEATURE report to the currently attached HID device, using the device's OUT pipe if available,
|
||||
* or the device's Control pipe if not.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, the ReportID parameter is removed
|
||||
* from the parameter list of this function.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
* \param[in] ReportID Report ID of the report to send to the device, or 0 if the device does not use report IDs.
|
||||
* \param[in] ReportType Type of report to issue to the device, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature.
|
||||
* \param[in] Buffer Buffer containing the report to send to the attached device.
|
||||
* \param[in] ReportSize Report size in bytes to send to the attached device.
|
||||
*
|
||||
* \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the DeviceUsesOUTPipe flag is set in
|
||||
* the interface's state structure, a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise.
|
||||
*/
|
||||
uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
const uint8_t ReportID,
|
||||
#endif
|
||||
const uint8_t ReportType,
|
||||
void* Buffer,
|
||||
const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1)
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
ATTR_NON_NULL_PTR_ARG(4);
|
||||
#else
|
||||
ATTR_NON_NULL_PTR_ARG(3);
|
||||
#endif
|
||||
|
||||
/** Determines if a HID IN report has been received from the attached device on the data IN pipe.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if a report has been received, \c false otherwise.
|
||||
*/
|
||||
bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices.
|
||||
*
|
||||
* \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method must still be called
|
||||
* to explicitly place the attached device into boot protocol mode before use.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
*
|
||||
* \return \ref HID_ERROR_LOGICAL if the device does not support Boot Protocol mode, a value from the
|
||||
* \ref USB_Host_SendControlErrorCodes_t enum otherwise.
|
||||
*/
|
||||
uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sets the idle period for the attached HID device to the specified interval. The HID idle period determines the rate
|
||||
* at which the device should send a report, when no state changes have occurred; i.e. on HID keyboards, this sets the
|
||||
* hardware key repeat interval.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
* \param[in] MS Idle period as a multiple of four milliseconds, zero to disable hardware repeats
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t HID_Host_SetIdlePeriod(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
|
||||
const uint16_t MS) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
|
||||
/** Switches the attached HID device's reporting protocol over to the standard Report protocol mode. This also retrieves
|
||||
* and parses the device's HID report descriptor, so that the size of each report can be determined in advance.
|
||||
*
|
||||
* \attention Whether this function is used or not, the \ref CALLBACK_HIDParser_FilterHIDReportItem() callback from the HID
|
||||
* Report Parser this function references <b>must</b> be implemented in the user code.
|
||||
*
|
||||
* \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum if an error occurs while retrieving the HID
|
||||
* Report descriptor or the setting of the Report protocol, \ref HID_ERROR_LOGICAL if the HID interface does
|
||||
* not have a valid \ref HID_ReportInfo_t structure set in its configuration, a mask of \ref HID_ERROR_LOGICAL
|
||||
* and a value from the \ref HID_Parse_ErrorCodes_t otherwise.
|
||||
*/
|
||||
uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
|
||||
/* Inline Functions: */
|
||||
/** General management task for a given Human Interface Class host class interface, required for the correct operation of
|
||||
* the interface. This should be called frequently in the main program loop, before the master USB management task
|
||||
* \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
|
||||
*/
|
||||
static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
|
||||
{
|
||||
(void)HIDInterfaceInfo;
|
||||
}
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_HID_HOST_C)
|
||||
static uint8_t DCOMP_HID_Host_NextHIDInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_HID_Host_NextHIDDescriptor(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_MIDI_DRIVER
|
||||
#define __INCLUDE_FROM_MIDI_HOST_C
|
||||
#include "MIDIClassHost.h"
|
||||
|
||||
uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* MIDIInterface = NULL;
|
||||
|
||||
memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return MIDI_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint))
|
||||
{
|
||||
if (!(MIDIInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return MIDI_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
MIDIInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
DataINEndpoint = EndpointData;
|
||||
else
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
|
||||
MIDIInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
MIDIInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
MIDIInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
MIDIInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
MIDIInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
MIDIInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return MIDI_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return MIDI_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
MIDIInterfaceInfo->State.InterfaceNumber = MIDIInterface->InterfaceNumber;
|
||||
MIDIInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return MIDI_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
|
||||
(Interface->SubClass == AUDIO_CSCP_MIDIStreamingSubclass) &&
|
||||
(Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
|
||||
return;
|
||||
|
||||
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
|
||||
MIDI_Host_Flush(MIDIInterfaceInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_BytesInPipe())
|
||||
{
|
||||
Pipe_ClearOUT();
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return ErrorCode;
|
||||
}
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
|
||||
MIDI_EventPacket_t* const Event)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
Pipe_ClearOUT();
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
|
||||
MIDI_EventPacket_t* const Event)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
bool DataReady = false;
|
||||
|
||||
Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
if (Pipe_BytesInPipe())
|
||||
{
|
||||
Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL);
|
||||
DataReady = true;
|
||||
}
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return DataReady;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB MIDI Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB MIDI Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassMIDI
|
||||
* \defgroup Group_USBClassMIDIHost MIDI Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassMIDIHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/MIDIClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassMIDIHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the MIDI USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __MIDI_CLASS_HOST_H__
|
||||
#define __MIDI_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/MIDIClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief MIDI Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the MIDI class driver functions as the \c MIDIInterfaceInfo parameter. This
|
||||
* stores each MIDI interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t InterfaceNumber; /**< Interface index of the MIDI interface within the attached device. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_MIDI_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref MIDI_Host_ConfigurePipes() function. */
|
||||
enum MIDI_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
MIDI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
MIDI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
MIDI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor. */
|
||||
MIDI_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Host interface configuration routine, to configure a given MIDI host interface instance using the Configuration
|
||||
* Descriptor read from an attached USB device. This function automatically updates the given MIDI Host instance's
|
||||
* state values and configures the pipes required to communicate with the interface if it is found within the device.
|
||||
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
|
||||
* the Addressed state.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref MIDI_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** General management task for a given MIDI host class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state.
|
||||
*/
|
||||
void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a MIDI event packet to the device. If no device is connected, the event packet is discarded.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
* \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
|
||||
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Flushes the MIDI send buffer, sending any queued MIDI events to the device. This should be called to override the
|
||||
* \ref MIDI_Host_SendEventPacket() function's packing behavior, to flush queued events. Events are queued into the
|
||||
* pipe bank until either the pipe bank is full, or \ref MIDI_Host_Flush() is called. This allows for multiple MIDI
|
||||
* events to be packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Receives a MIDI event packet from the device.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
|
||||
* \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed.
|
||||
*
|
||||
* \return Boolean \c true if a MIDI event packet was received, \c false otherwise.
|
||||
*/
|
||||
bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
|
||||
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_MIDI_HOST_C)
|
||||
static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,579 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_MS_DRIVER
|
||||
#define __INCLUDE_FROM_MASSSTORAGE_HOST_C
|
||||
#include "MassStorageClassHost.h"
|
||||
|
||||
uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* MassStorageInterface = NULL;
|
||||
|
||||
memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return MS_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint))
|
||||
{
|
||||
if (!(MassStorageInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_MS_Host_NextMSInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_MS_Host_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return MS_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
MassStorageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
DataINEndpoint = EndpointData;
|
||||
else
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
|
||||
MSInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
MSInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
MSInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
MSInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
MSInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
MSInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&MSInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return MS_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&MSInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return MS_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
MSInterfaceInfo->State.InterfaceNumber = MassStorageInterface->InterfaceNumber;
|
||||
MSInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return MS_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == MS_CSCP_MassStorageClass) &&
|
||||
(Interface->SubClass == MS_CSCP_SCSITransparentSubclass) &&
|
||||
(Interface->Protocol == MS_CSCP_BulkOnlyTransportProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress))))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
MS_CommandBlockWrapper_t* const SCSICommandBlock,
|
||||
const void* const BufferPtr)
|
||||
{
|
||||
uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
|
||||
|
||||
if (++MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF)
|
||||
MSInterfaceInfo->State.TransactionTag = 1;
|
||||
|
||||
SCSICommandBlock->Signature = CPU_TO_LE32(MS_CBW_SIGNATURE);
|
||||
SCSICommandBlock->Tag = cpu_to_le32(MSInterfaceInfo->State.TransactionTag);
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t),
|
||||
NULL)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_ClearOUT();
|
||||
Pipe_WaitUntilReady();
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
if (BufferPtr != NULL)
|
||||
{
|
||||
ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr);
|
||||
|
||||
if ((ErrorCode != PIPE_RWSTREAM_NoError) && (ErrorCode != PIPE_RWSTREAM_PipeStalled))
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return ErrorCode;
|
||||
}
|
||||
}
|
||||
|
||||
MS_CommandStatusWrapper_t SCSIStatusBlock;
|
||||
return MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSIStatusBlock);
|
||||
}
|
||||
|
||||
static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
|
||||
{
|
||||
uint16_t TimeoutMSRem = MS_COMMAND_DATA_TIMEOUT_MS;
|
||||
uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber();
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
while (!(Pipe_IsINReceived()))
|
||||
{
|
||||
uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber();
|
||||
|
||||
if (CurrentFrameNumber != PreviousFrameNumber)
|
||||
{
|
||||
PreviousFrameNumber = CurrentFrameNumber;
|
||||
|
||||
if (!(TimeoutMSRem--))
|
||||
return PIPE_RWSTREAM_Timeout;
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsStalled())
|
||||
{
|
||||
USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
|
||||
return PIPE_RWSTREAM_PipeStalled;
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsStalled())
|
||||
{
|
||||
USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
|
||||
return PIPE_RWSTREAM_PipeStalled;
|
||||
}
|
||||
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Freeze();
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
MS_CommandBlockWrapper_t* const SCSICommandBlock,
|
||||
void* BufferPtr)
|
||||
{
|
||||
uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
|
||||
uint16_t BytesRem = le32_to_cpu(SCSICommandBlock->DataTransferLength);
|
||||
|
||||
if (SCSICommandBlock->Flags & MS_COMMAND_DIR_DATA_IN)
|
||||
{
|
||||
if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearOUT();
|
||||
|
||||
while (!(Pipe_IsOUTReady()))
|
||||
{
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
}
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
MS_CommandStatusWrapper_t* const SCSICommandStatus)
|
||||
{
|
||||
uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
|
||||
|
||||
if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t),
|
||||
NULL)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
|
||||
if (SCSICommandStatus->Status != MS_SCSI_COMMAND_Pass)
|
||||
ErrorCode = MS_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = MS_REQ_MassStorageReset,
|
||||
.wValue = 0,
|
||||
.wIndex = MSInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address);
|
||||
|
||||
if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
|
||||
if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
uint8_t* const MaxLUNIndex)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = MS_REQ_GetMaxLUN,
|
||||
.wValue = 0,
|
||||
.wIndex = MSInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = 1,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled)
|
||||
{
|
||||
*MaxLUNIndex = 0;
|
||||
ErrorCode = HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
SCSI_Inquiry_Response_t* const InquiryData)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
|
||||
{
|
||||
.DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Inquiry_Response_t)),
|
||||
.Flags = MS_COMMAND_DIR_DATA_IN,
|
||||
.LUN = LUNIndex,
|
||||
.SCSICommandLength = 6,
|
||||
.SCSICommandData =
|
||||
{
|
||||
SCSI_CMD_INQUIRY,
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
sizeof(SCSI_Inquiry_Response_t), // Allocation Length
|
||||
0x00 // Unused (control)
|
||||
}
|
||||
};
|
||||
|
||||
return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, InquiryData);
|
||||
}
|
||||
|
||||
uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
|
||||
{
|
||||
.DataTransferLength = CPU_TO_LE32(0),
|
||||
.Flags = MS_COMMAND_DIR_DATA_IN,
|
||||
.LUN = LUNIndex,
|
||||
.SCSICommandLength = 6,
|
||||
.SCSICommandData =
|
||||
{
|
||||
SCSI_CMD_TEST_UNIT_READY,
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
0x00 // Unused (control)
|
||||
}
|
||||
};
|
||||
|
||||
return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL);
|
||||
}
|
||||
|
||||
uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
SCSI_Capacity_t* const DeviceCapacity)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
|
||||
{
|
||||
.DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Capacity_t)),
|
||||
.Flags = MS_COMMAND_DIR_DATA_IN,
|
||||
.LUN = LUNIndex,
|
||||
.SCSICommandLength = 10,
|
||||
.SCSICommandData =
|
||||
{
|
||||
SCSI_CMD_READ_CAPACITY_10,
|
||||
0x00, // Reserved
|
||||
0x00, // MSB of Logical block address
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, // LSB of Logical block address
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
0x00, // Partial Medium Indicator
|
||||
0x00 // Unused (control)
|
||||
}
|
||||
};
|
||||
|
||||
if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, DeviceCapacity)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
DeviceCapacity->Blocks = BE32_TO_CPU(DeviceCapacity->Blocks);
|
||||
DeviceCapacity->BlockSize = BE32_TO_CPU(DeviceCapacity->BlockSize);
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
SCSI_Request_Sense_Response_t* const SenseData)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
|
||||
{
|
||||
.DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Request_Sense_Response_t)),
|
||||
.Flags = MS_COMMAND_DIR_DATA_IN,
|
||||
.LUN = LUNIndex,
|
||||
.SCSICommandLength = 6,
|
||||
.SCSICommandData =
|
||||
{
|
||||
SCSI_CMD_REQUEST_SENSE,
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
sizeof(SCSI_Request_Sense_Response_t), // Allocation Length
|
||||
0x00 // Unused (control)
|
||||
}
|
||||
};
|
||||
|
||||
return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, SenseData);
|
||||
}
|
||||
|
||||
uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
const bool PreventRemoval)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
|
||||
{
|
||||
.DataTransferLength = CPU_TO_LE32(0),
|
||||
.Flags = MS_COMMAND_DIR_DATA_OUT,
|
||||
.LUN = LUNIndex,
|
||||
.SCSICommandLength = 6,
|
||||
.SCSICommandData =
|
||||
{
|
||||
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL,
|
||||
0x00, // Reserved
|
||||
0x00, // Reserved
|
||||
PreventRemoval, // Prevent flag
|
||||
0x00, // Reserved
|
||||
0x00 // Unused (control)
|
||||
}
|
||||
};
|
||||
|
||||
return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL);
|
||||
}
|
||||
|
||||
uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
const uint32_t BlockAddress,
|
||||
const uint8_t Blocks,
|
||||
const uint16_t BlockSize,
|
||||
void* BlockBuffer)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
|
||||
{
|
||||
.DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize),
|
||||
.Flags = MS_COMMAND_DIR_DATA_IN,
|
||||
.LUN = LUNIndex,
|
||||
.SCSICommandLength = 10,
|
||||
.SCSICommandData =
|
||||
{
|
||||
SCSI_CMD_READ_10,
|
||||
0x00, // Unused (control bits, all off)
|
||||
(BlockAddress >> 24), // MSB of Block Address
|
||||
(BlockAddress >> 16),
|
||||
(BlockAddress >> 8),
|
||||
(BlockAddress & 0xFF), // LSB of Block Address
|
||||
0x00, // Reserved
|
||||
0x00, // MSB of Total Blocks to Read
|
||||
Blocks, // LSB of Total Blocks to Read
|
||||
0x00 // Unused (control)
|
||||
}
|
||||
};
|
||||
|
||||
return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer);
|
||||
}
|
||||
|
||||
uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
const uint32_t BlockAddress,
|
||||
const uint8_t Blocks,
|
||||
const uint16_t BlockSize,
|
||||
const void* BlockBuffer)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
|
||||
return HOST_SENDCONTROL_DeviceDisconnected;
|
||||
|
||||
MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
|
||||
{
|
||||
.DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize),
|
||||
.Flags = MS_COMMAND_DIR_DATA_OUT,
|
||||
.LUN = LUNIndex,
|
||||
.SCSICommandLength = 10,
|
||||
.SCSICommandData =
|
||||
{
|
||||
SCSI_CMD_WRITE_10,
|
||||
0x00, // Unused (control bits, all off)
|
||||
(BlockAddress >> 24), // MSB of Block Address
|
||||
(BlockAddress >> 16),
|
||||
(BlockAddress >> 8),
|
||||
(BlockAddress & 0xFF), // LSB of Block Address
|
||||
0x00, // Reserved
|
||||
0x00, // MSB of Total Blocks to Write
|
||||
Blocks, // LSB of Total Blocks to Write
|
||||
0x00 // Unused (control)
|
||||
}
|
||||
};
|
||||
|
||||
return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB Mass Storage Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB Mass Storage Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassMS
|
||||
* \defgroup Group_USBClassMassStorageHost Mass Storage Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassMassStorageHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassMassStorageHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __MS_CLASS_HOST_H__
|
||||
#define __MS_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/MassStorageClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_MS_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error. */
|
||||
#define MS_ERROR_LOGICAL_CMD_FAILED 0x80
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief Mass Storage Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the Mass Storage class driver functions as the \c MSInterfaceInfo parameter. This
|
||||
* stores each Mass Storage interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */
|
||||
|
||||
uint32_t TransactionTag; /**< Current transaction tag for data synchronizing of packets. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_MS_Host_t;
|
||||
|
||||
/** \brief SCSI Device LUN Capacity Structure.
|
||||
*
|
||||
* SCSI capacity structure, to hold the total capacity of the device in both the number
|
||||
* of blocks in the current LUN, and the size of each block. This structure is filled by
|
||||
* the device when the \ref MS_Host_ReadDeviceCapacity() function is called.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device. */
|
||||
uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN. */
|
||||
} SCSI_Capacity_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref MS_Host_ConfigurePipes() function. */
|
||||
enum MS_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
MS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor. */
|
||||
MS_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Host interface configuration routine, to configure a given Mass Storage host interface instance using the
|
||||
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass
|
||||
* Storage Host instance's state values and configures the pipes required to communicate with the interface if it
|
||||
* is found within the device. This should be called once after the stack has enumerated the attached device, while
|
||||
* the host state machine is in the Addressed state.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref MS_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface
|
||||
* and readying it for the next Mass Storage command. This should be called after a failed SCSI request to
|
||||
* ensure the attached Mass Storage device is ready to receive the next command.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a GET MAX LUN control request to the attached device, retrieving the index of the highest LUN (Logical
|
||||
* UNit, a logical drive) in the device. This value can then be used in the other functions of the Mass Storage
|
||||
* Host mode Class driver to address a specific LUN within the device.
|
||||
*
|
||||
* \note Some devices do not support this request, and will STALL it when issued. To get around this,
|
||||
* on unsupported devices the max LUN index will be reported as zero and no error will be returned
|
||||
* if the device STALLs the request.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[out] MaxLUNIndex Pointer to a location where the highest LUN index value should be stored.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
uint8_t* const MaxLUNIndex) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Retrieves the Mass Storage device's inquiry data for the specified LUN, indicating the device characteristics and
|
||||
* properties.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[in] LUNIndex LUN index within the device the command is being issued to.
|
||||
* \param[out] InquiryData Location where the read inquiry data should be stored.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED.
|
||||
*/
|
||||
uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
SCSI_Inquiry_Response_t* const InquiryData) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Sends a TEST UNIT READY command to the device, to determine if it is ready to accept other SCSI commands.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[in] LUNIndex LUN index within the device the command is being issued to.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
|
||||
*/
|
||||
uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Retrieves the total capacity of the attached USB Mass Storage device, in blocks, and block size.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[in] LUNIndex LUN index within the device the command is being issued to.
|
||||
* \param[out] DeviceCapacity Pointer to the location where the capacity information should be stored.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
|
||||
*/
|
||||
uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
SCSI_Capacity_t* const DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Retrieves the device sense data, indicating the current device state and error codes for the previously
|
||||
* issued command.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[in] LUNIndex LUN index within the device the command is being issued to.
|
||||
* \param[out] SenseData Pointer to the location where the sense information should be stored.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
|
||||
*/
|
||||
uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
SCSI_Request_Sense_Response_t* const SenseData) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Issues a PREVENT MEDIUM REMOVAL command, to logically (or, depending on the type of device, physically) lock
|
||||
* the device from removal so that blocks of data on the medium can be read or altered.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[in] LUNIndex LUN index within the device the command is being issued to.
|
||||
* \param[in] PreventRemoval Boolean \c true if the device should be locked from removal, \c false otherwise.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
|
||||
*/
|
||||
uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
const bool PreventRemoval) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads blocks of data from the attached Mass Storage device's medium.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[in] LUNIndex LUN index within the device the command is being issued to.
|
||||
* \param[in] BlockAddress Starting block address within the device to read from.
|
||||
* \param[in] Blocks Total number of blocks to read.
|
||||
* \param[in] BlockSize Size in bytes of each block within the device.
|
||||
* \param[out] BlockBuffer Pointer to where the read data from the device should be stored.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
|
||||
*/
|
||||
uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
const uint32_t BlockAddress,
|
||||
const uint8_t Blocks,
|
||||
const uint16_t BlockSize,
|
||||
void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
|
||||
|
||||
/** Writes blocks of data to the attached Mass Storage device's medium.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
|
||||
* \param[in] LUNIndex LUN index within the device the command is being issued to.
|
||||
* \param[in] BlockAddress Starting block address within the device to write to.
|
||||
* \param[in] Blocks Total number of blocks to read.
|
||||
* \param[in] BlockSize Size in bytes of each block within the device.
|
||||
* \param[in] BlockBuffer Pointer to where the data to write should be sourced from.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
|
||||
*/
|
||||
uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
const uint8_t LUNIndex,
|
||||
const uint32_t BlockAddress,
|
||||
const uint8_t Blocks,
|
||||
const uint16_t BlockSize,
|
||||
const void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** General management task for a given Mass Storage host class interface, required for the correct operation of
|
||||
* the interface. This should be called frequently in the main program loop, before the master USB management task
|
||||
* \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] MSInterfaceInfo Pointer to a structure containing an Mass Storage Class host configuration and state.
|
||||
*/
|
||||
static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
|
||||
{
|
||||
(void)MSInterfaceInfo;
|
||||
}
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define MS_COMMAND_DATA_TIMEOUT_MS 10000
|
||||
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_MASSSTORAGE_HOST_C)
|
||||
static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
MS_CommandBlockWrapper_t* const SCSICommandBlock,
|
||||
const void* const BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
MS_CommandBlockWrapper_t* const SCSICommandBlock,
|
||||
void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
|
||||
MS_CommandStatusWrapper_t* const SCSICommandStatus)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_PRINTER_DRIVER
|
||||
#define __INCLUDE_FROM_PRINTER_HOST_C
|
||||
#include "PrinterClassHost.h"
|
||||
|
||||
uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* PrinterInterface = NULL;
|
||||
|
||||
memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return PRNT_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint))
|
||||
{
|
||||
if (!(PrinterInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_PRNT_Host_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return PRNT_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
PrinterInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
DataINEndpoint = EndpointData;
|
||||
else
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
|
||||
PRNTInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
PRNTInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
PRNTInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
PRNTInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
PRNTInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
PRNTInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&PRNTInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return PRNT_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&PRNTInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return PRNT_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber;
|
||||
PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting;
|
||||
PRNTInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return PRNT_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == PRNT_CSCP_PrinterClass) &&
|
||||
(Interface->SubClass == PRNT_CSCP_PrinterSubclass) &&
|
||||
(Interface->Protocol == PRNT_CSCP_BidirectionalProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if (EndpointType == EP_TYPE_BULK)
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
|
||||
return;
|
||||
|
||||
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
|
||||
PRNT_Host_Flush(PRNTInterfaceInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if (PRNTInterfaceInfo->State.AlternateSetting)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PRNTInterfaceInfo->State.InterfaceNumber,
|
||||
PRNTInterfaceInfo->State.AlternateSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
}
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
uint8_t* const PortStatus)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = PRNT_REQ_GetPortStatus,
|
||||
.wValue = 0,
|
||||
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = sizeof(uint8_t),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
return USB_Host_SendControlRequest(PortStatus);
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = PRNT_REQ_SoftReset,
|
||||
.wValue = 0,
|
||||
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
return PIPE_READYWAIT_NoError;
|
||||
|
||||
bool BankFull = !(Pipe_IsReadWriteAllowed());
|
||||
|
||||
Pipe_ClearOUT();
|
||||
|
||||
if (BankFull)
|
||||
{
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearOUT();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
const uint8_t Data)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearOUT();
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_Write_8(Data);
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
const char* const String)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearOUT();
|
||||
|
||||
ErrorCode = Pipe_WaitUntilReady();
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
const void* Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
Pipe_ClearOUT();
|
||||
|
||||
ErrorCode = Pipe_WaitUntilReady();
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
|
||||
return 0;
|
||||
|
||||
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
{
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return Pipe_BytesInPipe();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_Freeze();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
int16_t ReceivedByte = -1;
|
||||
|
||||
Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
if (Pipe_BytesInPipe())
|
||||
ReceivedByte = Pipe_Read_8();
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ReceivedByte;
|
||||
}
|
||||
|
||||
uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
char* const DeviceIDString,
|
||||
const uint16_t BufferSize)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
uint16_t DeviceIDStringLength = 0;
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = PRNT_REQ_GetDeviceID,
|
||||
.wValue = 0,
|
||||
.wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
|
||||
.wLength = sizeof(DeviceIDStringLength),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
if (!(DeviceIDStringLength))
|
||||
{
|
||||
DeviceIDString[0] = 0x00;
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
DeviceIDStringLength = be16_to_cpu(DeviceIDStringLength);
|
||||
|
||||
if (DeviceIDStringLength > BufferSize)
|
||||
DeviceIDStringLength = BufferSize;
|
||||
|
||||
USB_ControlRequest.wLength = DeviceIDStringLength;
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2);
|
||||
|
||||
DeviceIDString[DeviceIDStringLength - 2] = 0x00;
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB Printer Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB Printer Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassPrinter
|
||||
* \defgroup Group_USBClassPrinterHost Printer Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassPrinterHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/PrinterClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassPrinterHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the Printer USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __PRINTER_CLASS_HOST_H__
|
||||
#define __PRINTER_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/PrinterClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief Printer Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the Printer class driver functions as the \c PRNTInterfaceInfo parameter. This
|
||||
* stores each Printer interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref PRNT_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t InterfaceNumber; /**< Interface index of the Printer interface within the attached device. */
|
||||
uint8_t AlternateSetting; /**< Alternate setting within the Printer Interface in the attached device. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_PRNT_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref PRNT_Host_ConfigurePipes() function. */
|
||||
enum PRNT_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
PRNT_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor. */
|
||||
PRNT_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Host interface configuration routine, to configure a given Printer host interface instance using the
|
||||
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Printer
|
||||
* instance's state values and configures the pipes required to communicate with the interface if it is found within
|
||||
* the device. This should be called once after the stack has enumerated the attached device, while the host state
|
||||
* machine is in the Addressed state.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref PRNT_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** General management task for a given Printer host class interface, required for the correct operation of
|
||||
* the interface. This should be called frequently in the main program loop, before the master USB management task
|
||||
* \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
*/
|
||||
void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Configures the printer to enable Bidirectional mode, if it is not already in this mode. This should be called
|
||||
* once the connected device's configuration has been set, to ensure the printer is ready to accept commands.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Retrieves the status of the virtual Printer port's inbound status lines. The result can then be masked against the
|
||||
* \c PRNT_PORTSTATUS_* macros to determine the printer port's status.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
* \param[out] PortStatus Location where the retrieved port status should be stored.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
uint8_t* const PortStatus)
|
||||
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Soft-resets the attached printer, readying it for new commands.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends the given null terminated string to the attached printer's input endpoint.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
* \param[in] String Pointer to a null terminated string to send.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends the given raw data stream to the attached printer's input endpoint. This should contain commands that the
|
||||
* printer is able to understand - for example, PCL data. Not all printers accept all printer languages; see
|
||||
* \ref PRNT_Host_GetDeviceID() for details on determining acceptable languages for an attached printer.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer containing the raw command stream to send to the printer.
|
||||
* \param[in] Length Size in bytes of the command stream to be sent.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
const void* Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the
|
||||
* byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the
|
||||
* \ref PRNT_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
|
||||
* packed into a single pipe packet, increasing data throughput.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
* \param[in] Data Byte of data to send to the device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Determines the number of bytes received by the printer interface from the device, waiting to be read. This indicates the number
|
||||
* of bytes in the IN pipe bank only, and thus the number of calls to \ref PRNT_Host_ReceiveByte() which are guaranteed to succeed
|
||||
* immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be
|
||||
* released back to the USB controller until all bytes are read.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
*
|
||||
* \return Total number of buffered bytes received from the device.
|
||||
*/
|
||||
uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function
|
||||
* returns a negative value. The \ref PRNT_Host_BytesReceived() function may be queried in advance to determine how many bytes
|
||||
* are currently buffered in the Printer interface's data receive pipe.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
*
|
||||
* \return Next received byte from the device, or a negative value if no data received.
|
||||
*/
|
||||
int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Retrieves the attached printer device's ID string, formatted according to IEEE 1284. This string is sent as a
|
||||
* Unicode string from the device and is automatically converted to an ASCII encoded C string by this function, thus
|
||||
* the maximum reportable string length is two less than the size given (to accommodate the Unicode string length
|
||||
* bytes which are removed).
|
||||
*
|
||||
* This string, when supported, contains the model, manufacturer and acceptable printer languages for the attached device.
|
||||
*
|
||||
* \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
|
||||
* \param[out] DeviceIDString Pointer to a buffer where the Device ID string should be stored, in ASCII format.
|
||||
* \param[in] BufferSize Size in bytes of the buffer allocated for the Device ID string.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
|
||||
char* const DeviceIDString,
|
||||
const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_PRINTER_HOST_C)
|
||||
static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_RNDIS_DRIVER
|
||||
#define __INCLUDE_FROM_RNDIS_HOST_C
|
||||
#include "RNDISClassHost.h"
|
||||
|
||||
uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* RNDISControlInterface = NULL;
|
||||
|
||||
memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return RNDIS_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint))
|
||||
{
|
||||
if (!(RNDISControlInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (NotificationEndpoint)
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return RNDIS_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return RNDIS_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
NotificationEndpoint = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
{
|
||||
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
|
||||
NotificationEndpoint = EndpointData;
|
||||
else
|
||||
DataINEndpoint = EndpointData;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
}
|
||||
|
||||
RNDISInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
RNDISInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
RNDISInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
RNDISInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
RNDISInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
RNDISInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
RNDISInterfaceInfo->Config.NotificationPipe.Size = le16_to_cpu(NotificationEndpoint->EndpointSize);
|
||||
RNDISInterfaceInfo->Config.NotificationPipe.EndpointAddress = NotificationEndpoint->EndpointAddress;
|
||||
RNDISInterfaceInfo->Config.NotificationPipe.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return RNDIS_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return RNDIS_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.NotificationPipe, 1)))
|
||||
return RNDIS_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
RNDISInterfaceInfo->State.ControlInterfaceNumber = RNDISControlInterface->InterfaceNumber;
|
||||
RNDISInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return RNDIS_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == CDC_CSCP_CDCClass) &&
|
||||
(Interface->SubClass == CDC_CSCP_ACMSubclass) &&
|
||||
(Interface->Protocol == CDC_CSCP_VendorSpecificProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor,
|
||||
USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == CDC_CSCP_CDCDataClass) &&
|
||||
(Interface->SubClass == CDC_CSCP_NoDataSubclass) &&
|
||||
(Interface->Protocol == CDC_CSCP_NoDataProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
|
||||
!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = RNDIS_REQ_SendEncapsulatedCommand,
|
||||
.wValue = 0,
|
||||
.wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
|
||||
.wLength = Length,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
|
||||
static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = RNDIS_REQ_GetEncapsulatedResponse,
|
||||
.wValue = 0,
|
||||
.wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
|
||||
.wLength = Length,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
RNDIS_KeepAlive_Message_t KeepAliveMessage;
|
||||
RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse;
|
||||
|
||||
KeepAliveMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_MSG);
|
||||
KeepAliveMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Message_t));
|
||||
KeepAliveMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
|
||||
|
||||
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &KeepAliveMessage,
|
||||
sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &KeepAliveMessageResponse,
|
||||
sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
RNDIS_Initialize_Message_t InitMessage;
|
||||
RNDIS_Initialize_Complete_t InitMessageResponse;
|
||||
|
||||
InitMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_MSG);
|
||||
InitMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Message_t));
|
||||
InitMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
|
||||
|
||||
InitMessage.MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR);
|
||||
InitMessage.MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR);
|
||||
InitMessage.MaxTransferSize = cpu_to_le32(RNDISInterfaceInfo->Config.HostMaxPacketSize);
|
||||
|
||||
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &InitMessage,
|
||||
sizeof(RNDIS_Initialize_Message_t))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &InitMessageResponse,
|
||||
sizeof(RNDIS_Initialize_Complete_t))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if (InitMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS))
|
||||
return RNDIS_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
RNDISInterfaceInfo->State.DeviceMaxPacketSize = le32_to_cpu(InitMessageResponse.MaxTransferSize);
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
const uint32_t Oid,
|
||||
void* Buffer,
|
||||
const uint16_t Length)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
struct
|
||||
{
|
||||
RNDIS_Set_Message_t SetMessage;
|
||||
uint8_t ContiguousBuffer[Length];
|
||||
} SetMessageData;
|
||||
|
||||
RNDIS_Set_Complete_t SetMessageResponse;
|
||||
|
||||
SetMessageData.SetMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_MSG);
|
||||
SetMessageData.SetMessage.MessageLength = cpu_to_le32(sizeof(RNDIS_Set_Message_t) + Length);
|
||||
SetMessageData.SetMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
|
||||
|
||||
SetMessageData.SetMessage.Oid = cpu_to_le32(Oid);
|
||||
SetMessageData.SetMessage.InformationBufferLength = cpu_to_le32(Length);
|
||||
SetMessageData.SetMessage.InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Set_Message_t) - sizeof(RNDIS_Message_Header_t));
|
||||
SetMessageData.SetMessage.DeviceVcHandle = CPU_TO_LE32(0);
|
||||
|
||||
memcpy(&SetMessageData.ContiguousBuffer, Buffer, Length);
|
||||
|
||||
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &SetMessageData,
|
||||
(sizeof(RNDIS_Set_Message_t) + Length))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &SetMessageResponse,
|
||||
sizeof(RNDIS_Set_Complete_t))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if (SetMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS))
|
||||
return RNDIS_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
const uint32_t Oid,
|
||||
void* Buffer,
|
||||
const uint16_t MaxLength)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
RNDIS_Query_Message_t QueryMessage;
|
||||
|
||||
struct
|
||||
{
|
||||
RNDIS_Query_Complete_t QueryMessageResponse;
|
||||
uint8_t ContiguousBuffer[MaxLength];
|
||||
} QueryMessageResponseData;
|
||||
|
||||
QueryMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_MSG);
|
||||
QueryMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Message_t));
|
||||
QueryMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
|
||||
|
||||
QueryMessage.Oid = cpu_to_le32(Oid);
|
||||
QueryMessage.InformationBufferLength = CPU_TO_LE32(0);
|
||||
QueryMessage.InformationBufferOffset = CPU_TO_LE32(0);
|
||||
QueryMessage.DeviceVcHandle = CPU_TO_LE32(0);
|
||||
|
||||
if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &QueryMessage,
|
||||
sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &QueryMessageResponseData,
|
||||
sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if (QueryMessageResponseData.QueryMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS))
|
||||
return RNDIS_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
memcpy(Buffer, &QueryMessageResponseData.ContiguousBuffer, MaxLength);
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
bool PacketWaiting;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
|
||||
return false;
|
||||
|
||||
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address);
|
||||
|
||||
Pipe_Unfreeze();
|
||||
PacketWaiting = Pipe_IsINReceived();
|
||||
Pipe_Freeze();
|
||||
|
||||
return PacketWaiting;
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
uint16_t* const PacketLength)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
if (Pipe_IsINReceived())
|
||||
Pipe_ClearIN();
|
||||
|
||||
*PacketLength = 0;
|
||||
Pipe_Freeze();
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
RNDIS_Packet_Message_t DeviceMessage;
|
||||
|
||||
if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
|
||||
NULL)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
*PacketLength = (uint16_t)le32_to_cpu(DeviceMessage.DataLength);
|
||||
|
||||
Pipe_Discard_Stream(le32_to_cpu(DeviceMessage.DataOffset) -
|
||||
(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)),
|
||||
NULL);
|
||||
|
||||
Pipe_Read_Stream_LE(Buffer, *PacketLength, NULL);
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t PacketLength)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
RNDIS_Packet_Message_t DeviceMessage;
|
||||
|
||||
memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t));
|
||||
DeviceMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG);
|
||||
DeviceMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + PacketLength);
|
||||
DeviceMessage.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
|
||||
DeviceMessage.DataLength = cpu_to_le32(PacketLength);
|
||||
|
||||
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
|
||||
NULL)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_Write_Stream_LE(Buffer, PacketLength, NULL);
|
||||
Pipe_ClearOUT();
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB RNDIS Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB RNDIS Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassRNDIS
|
||||
* \defgroup Group_USBClassRNDISHost RNDIS Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassRNDISHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/RNDISClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassRNDISHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the Microsoft RNDIS Ethernet
|
||||
* USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __RNDIS_CLASS_HOST_H__
|
||||
#define __RNDIS_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/RNDISClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** \brief RNDIS Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the RNDIS class driver functions as the \c RNDISInterfaceInfo parameter. This
|
||||
* stores each RNDIS interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
USB_Pipe_Table_t NotificationPipe; /**< Notification IN Pipe configuration table. */
|
||||
|
||||
uint32_t HostMaxPacketSize; /**< Maximum size of a packet which can be buffered by the host. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref RNDIS_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t ControlInterfaceNumber; /**< Interface index of the RNDIS control interface within the attached device. */
|
||||
|
||||
uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device. */
|
||||
|
||||
uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_RNDIS_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref RNDIS_Host_ConfigurePipes() function. */
|
||||
enum RNDIS_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
RNDIS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
RNDIS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
RNDIS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor. */
|
||||
RNDIS_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Host interface configuration routine, to configure a given RNDIS host interface instance using the Configuration
|
||||
* Descriptor read from an attached USB device. This function automatically updates the given RNDIS Host instance's
|
||||
* state values and configures the pipes required to communicate with the interface if it is found within the device.
|
||||
* This should be called once after the stack has enumerated the attached device, while the host state machine is in
|
||||
* the Addressed state.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref RNDIS_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Sends a RNDIS KEEPALIVE command to the device, to ensure that it does not enter standby mode after periods
|
||||
* of long inactivity.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the device returned a
|
||||
* logical command failure.
|
||||
*/
|
||||
uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Initializes the attached RNDIS device's RNDIS interface. This should be called after the device's pipes have been
|
||||
* configured via the call to \ref RNDIS_Host_ConfigurePipes().
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the
|
||||
* device returned a logical command failure.
|
||||
*/
|
||||
uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sets a given RNDIS property of an attached RNDIS device.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
* \param[in] Oid OID number of the parameter to set.
|
||||
* \param[in] Buffer Pointer to where the property data is to be sourced from.
|
||||
* \param[in] Length Length in bytes of the property data to sent to the device.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the
|
||||
* device returned a logical command failure.
|
||||
*/
|
||||
uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
const uint32_t Oid,
|
||||
void* Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Gets a given RNDIS property of an attached RNDIS device.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
* \param[in] Oid OID number of the parameter to get.
|
||||
* \param[in] Buffer Pointer to where the property data is to be written to.
|
||||
* \param[in] MaxLength Length in bytes of the destination buffer size.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the
|
||||
* device returned a logical command failure.
|
||||
*/
|
||||
uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
const uint32_t Oid,
|
||||
void* Buffer,
|
||||
const uint16_t MaxLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Determines if a packet is currently waiting for the host to read in and process.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise.
|
||||
*/
|
||||
bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave
|
||||
* only the packet contents for processing by the host in the nominated buffer.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
* \param[out] Buffer Pointer to a buffer where the packer data is to be written to.
|
||||
* \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
uint16_t* const PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2)
|
||||
ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer where the packer data is to be read from.
|
||||
* \param[in] PacketLength Length in bytes of the packet to send.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** General management task for a given RNDIS host class interface, required for the correct operation of the interface. This should
|
||||
* be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
|
||||
*/
|
||||
static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
|
||||
{
|
||||
(void)RNDISInterfaceInfo;
|
||||
}
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_RNDIS_HOST_C)
|
||||
static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(2);
|
||||
static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_SI_DRIVER
|
||||
#define __INCLUDE_FROM_STILLIMAGE_HOST_C
|
||||
#include "StillImageClassHost.h"
|
||||
|
||||
uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* EventsEndpoint = NULL;
|
||||
USB_Descriptor_Interface_t* StillImageInterface = NULL;
|
||||
|
||||
memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return SI_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(EventsEndpoint))
|
||||
{
|
||||
if (!(StillImageInterface) ||
|
||||
USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_SI_Host_NextSIInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return SI_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
StillImageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
|
||||
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
EventsEndpoint = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
|
||||
{
|
||||
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
|
||||
EventsEndpoint = EndpointData;
|
||||
else
|
||||
DataINEndpoint = EndpointData;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
}
|
||||
|
||||
SIInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize);
|
||||
SIInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
|
||||
SIInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
SIInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
|
||||
SIInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
|
||||
SIInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
|
||||
|
||||
SIInterfaceInfo->Config.EventsPipe.Size = le16_to_cpu(EventsEndpoint->EndpointSize);
|
||||
SIInterfaceInfo->Config.EventsPipe.EndpointAddress = EventsEndpoint->EndpointAddress;
|
||||
SIInterfaceInfo->Config.EventsPipe.Type = EP_TYPE_INTERRUPT;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.DataINPipe, 1)))
|
||||
return SI_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.DataOUTPipe, 1)))
|
||||
return SI_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.EventsPipe, 1)))
|
||||
return SI_ENUMERROR_PipeConfigurationFailed;
|
||||
|
||||
SIInterfaceInfo->State.InterfaceNumber = StillImageInterface->InterfaceNumber;
|
||||
SIInterfaceInfo->State.IsActive = true;
|
||||
|
||||
return SI_ENUMERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t DCOMP_SI_Host_NextSIInterface(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
|
||||
|
||||
if ((Interface->Class == SI_CSCP_StillImageClass) &&
|
||||
(Interface->SubClass == SI_CSCP_StillImageSubclass) &&
|
||||
(Interface->Protocol == SI_CSCP_BulkOnlyProtocol))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
{
|
||||
USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
|
||||
|
||||
if (Header->Type == DTYPE_Endpoint)
|
||||
{
|
||||
USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
|
||||
|
||||
uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
|
||||
(!(Pipe_IsEndpointBound(Endpoint->EndpointAddress))))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
}
|
||||
else if (Header->Type == DTYPE_Interface)
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Fail;
|
||||
}
|
||||
|
||||
return DESCRIPTOR_SEARCH_NotFound;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
PIMA_Container_t* const PIMAHeader)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
if (SIInterfaceInfo->State.IsSessionOpen)
|
||||
PIMAHeader->TransactionID = cpu_to_le32(SIInterfaceInfo->State.TransactionID++);
|
||||
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
|
||||
|
||||
if (ParamBytes)
|
||||
{
|
||||
if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NULL)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_ClearOUT();
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
PIMA_Container_t* const PIMAHeader)
|
||||
{
|
||||
uint16_t TimeoutMSRem = SI_COMMAND_DATA_TIMEOUT_MS;
|
||||
uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber();
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
while (!(Pipe_IsINReceived()))
|
||||
{
|
||||
uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber();
|
||||
|
||||
if (CurrentFrameNumber != PreviousFrameNumber)
|
||||
{
|
||||
PreviousFrameNumber = CurrentFrameNumber;
|
||||
|
||||
if (!(TimeoutMSRem--))
|
||||
return PIPE_RWSTREAM_Timeout;
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsStalled())
|
||||
{
|
||||
USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
|
||||
return PIPE_RWSTREAM_PipeStalled;
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsStalled())
|
||||
{
|
||||
USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
|
||||
return PIPE_RWSTREAM_PipeStalled;
|
||||
}
|
||||
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
}
|
||||
|
||||
Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NULL);
|
||||
|
||||
if (PIMAHeader->Type == CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock))
|
||||
{
|
||||
uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
|
||||
|
||||
if (ParamBytes)
|
||||
Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NULL);
|
||||
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
const void* Buffer,
|
||||
const uint16_t Bytes)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
ErrorCode = Pipe_Write_Stream_LE(Buffer, Bytes, NULL);
|
||||
|
||||
Pipe_ClearOUT();
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t Bytes)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NULL);
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
|
||||
{
|
||||
bool IsEventReceived = false;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return false;
|
||||
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
IsEventReceived = true;
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return IsEventReceived;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
PIMA_Container_t* const PIMAHeader)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipe.Address);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
ErrorCode = Pipe_Read_Stream_LE(PIMAHeader, sizeof(PIMA_Container_t), NULL);
|
||||
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
SIInterfaceInfo->State.TransactionID = 0;
|
||||
SIInterfaceInfo->State.IsSessionOpen = false;
|
||||
|
||||
PIMA_Container_t PIMABlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = CPU_TO_LE32(PIMA_COMMAND_SIZE(1)),
|
||||
.Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock),
|
||||
.Code = CPU_TO_LE16(0x1002),
|
||||
.Params = {CPU_TO_LE32(1)},
|
||||
};
|
||||
|
||||
if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001)))
|
||||
return SI_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
SIInterfaceInfo->State.IsSessionOpen = true;
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
PIMA_Container_t PIMABlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = CPU_TO_LE32(PIMA_COMMAND_SIZE(1)),
|
||||
.Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock),
|
||||
.Code = CPU_TO_LE16(0x1003),
|
||||
.Params = {CPU_TO_LE32(1)},
|
||||
};
|
||||
|
||||
if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
SIInterfaceInfo->State.IsSessionOpen = false;
|
||||
|
||||
if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001)))
|
||||
return SI_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
const uint16_t Operation,
|
||||
const uint8_t TotalParams,
|
||||
uint32_t* const Params)
|
||||
{
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
PIMA_Container_t PIMABlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = cpu_to_le32(PIMA_COMMAND_SIZE(TotalParams)),
|
||||
.Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock),
|
||||
.Code = cpu_to_le16(Operation),
|
||||
};
|
||||
|
||||
memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams);
|
||||
|
||||
if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
PIMA_Container_t PIMABlock;
|
||||
|
||||
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
|
||||
return PIPE_RWSTREAM_DeviceDisconnected;
|
||||
|
||||
if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
|
||||
return ErrorCode;
|
||||
|
||||
if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001)))
|
||||
return SI_ERROR_LOGICAL_CMD_FAILED;
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Host mode driver for the library USB Still Image Class driver.
|
||||
*
|
||||
* Host mode driver for the library USB Still Image Class driver.
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB module driver
|
||||
* dispatch header located in LUFA/Drivers/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassSI
|
||||
* \defgroup Group_USBClassStillImageHost Still Image Class Host Mode Driver
|
||||
*
|
||||
* \section Sec_USBClassStillImageHost_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/StillImageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassStillImageHost_ModDescription Module Description
|
||||
* Host Mode USB Class driver framework interface, for the Still Image USB Class driver.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __SI_CLASS_HOST_H__
|
||||
#define __SI_CLASS_HOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../USB.h"
|
||||
#include "../Common/StillImageClassCommon.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_SI_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Error code for some Still Image Host functions, indicating a logical (and not hardware) error. */
|
||||
#define SI_ERROR_LOGICAL_CMD_FAILED 0x80
|
||||
|
||||
/* Type Defines: */
|
||||
/** \brief Still Image Class Host Mode Configuration and State Structure.
|
||||
*
|
||||
* Class state structure. An instance of this structure should be made within the user application,
|
||||
* and passed to each of the Still Image class driver functions as the \c SIInterfaceInfo parameter. This
|
||||
* stores each Still Image interface's configuration and state information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */
|
||||
USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */
|
||||
USB_Pipe_Table_t EventsPipe; /**< Event notification IN Pipe configuration table. */
|
||||
} Config; /**< Config data for the USB class interface within the device. All elements in this section
|
||||
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
|
||||
* after \ref SI_Host_ConfigurePipes() is called and the Host state machine is in the
|
||||
* Configured state.
|
||||
*/
|
||||
uint8_t InterfaceNumber; /**< Interface index of the Still Image interface within the attached device. */
|
||||
|
||||
bool IsSessionOpen; /**< Indicates if a PIMA session is currently open with the attached device. */
|
||||
uint32_t TransactionID; /**< Transaction ID for the next transaction to send to the device. */
|
||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||
* the interface is enumerated.
|
||||
*/
|
||||
} USB_ClassInfo_SI_Host_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error codes returned by the \ref SI_Host_ConfigurePipes() function. */
|
||||
enum SI_Host_EnumerationFailure_ErrorCodes_t
|
||||
{
|
||||
SI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
|
||||
SI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
|
||||
SI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's
|
||||
* Configuration Descriptor.
|
||||
*/
|
||||
SI_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Host interface configuration routine, to configure a given Still Image host interface instance using the
|
||||
* Configuration Descriptor read from an attached USB device. This function automatically updates the given Still
|
||||
* Image Host instance's state values and configures the pipes required to communicate with the interface if it is
|
||||
* found within the device. This should be called once after the stack has enumerated the attached device, while
|
||||
* the host state machine is in the Addressed state.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
* \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
|
||||
* \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor.
|
||||
*
|
||||
* \return A value from the \ref SI_Host_EnumerationFailure_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands
|
||||
* are issued to the device. Only one session can be open at the one time.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
|
||||
* returned a logical command failure.
|
||||
*/
|
||||
uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Closes an already opened PIMA session with the attached device. This should be used after all session-orientated
|
||||
* PIMA commands have been issued to the device.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
|
||||
* returned a logical command failure.
|
||||
*/
|
||||
uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Sends a raw PIMA block header to the device, filling out the transaction ID automatically. This can be used to send
|
||||
* arbitrary PIMA blocks to the device with or without parameters.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
* \param[in] PIMAHeader Pointer to a PIMA container structure that is to be sent.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Receives a raw PIMA block header from the device. This can be used to receive arbitrary PIMA blocks from the device with
|
||||
* or without parameters.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
* \param[out] PIMAHeader Pointer to a PIMA container structure where the received block is to be stored.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends a given PIMA command to the attached device, filling out the PIMA command header's Transaction ID automatically.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
* \param[in] Operation PIMA operation code to issue to the device.
|
||||
* \param[in] TotalParams Total number of 32-bit parameters to send to the device in the issued command block.
|
||||
* \param[in] Params Pointer to an array of 32-bit values containing the parameters to send in the command block.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
|
||||
* returned a logical command failure.
|
||||
*/
|
||||
uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
const uint16_t Operation,
|
||||
const uint8_t TotalParams,
|
||||
uint32_t* const Params) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Receives and checks a response block from the attached Still Image device, once a command has been issued and all data
|
||||
* associated with the command has been transferred.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
|
||||
* returned a logical command failure.
|
||||
*/
|
||||
uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Indicates if the device has issued a PIMA event block to the host via the asynchronous events pipe.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
*
|
||||
* \return Boolean \c true if an event is waiting to be read, \c false otherwise.
|
||||
*/
|
||||
bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Receives an asynchronous event block from the device via the asynchronous events pipe.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
* \param[out] PIMAHeader Pointer to a PIMA container structure where the event should be stored.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
|
||||
* returned a logical command failure.
|
||||
*/
|
||||
uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
|
||||
ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Sends arbitrary data to the attached device, for use in the data phase of PIMA commands which require data
|
||||
* transfer beyond the regular PIMA command block parameters.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
* \param[in] Buffer Pointer to a buffer where the data to send has been stored.
|
||||
* \param[in] Bytes Length in bytes of the data in the buffer to send to the attached device.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
const void* Buffer,
|
||||
const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/** Receives arbitrary data from the attached device, for use in the data phase of PIMA commands which require data
|
||||
* transfer beyond the regular PIMA command block parameters.
|
||||
*
|
||||
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
|
||||
* call will fail.
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
* \param[out] Buffer Pointer to a buffer where the received data is to be stored.
|
||||
* \param[in] Bytes Length in bytes of the data to read.
|
||||
*
|
||||
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
void* Buffer,
|
||||
const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** General management task for a given Still Image host class interface, required for the correct operation of the
|
||||
* interface. This should be called frequently in the main program loop, before the master USB management task
|
||||
* \ref USB_USBTask().
|
||||
*
|
||||
* \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
|
||||
*/
|
||||
static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
|
||||
static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
|
||||
{
|
||||
(void)SIInterfaceInfo;
|
||||
}
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define SI_COMMAND_DATA_TIMEOUT_MS 10000
|
||||
|
||||
/* Function Prototypes: */
|
||||
#if defined(__INCLUDE_FROM_STILLIMAGE_HOST_C)
|
||||
static uint8_t DCOMP_SI_Host_NextSIInterface(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
static uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
84
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Class/MIDIClass.h
Normal file
84
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Class/MIDIClass.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB MIDI Class driver.
|
||||
*
|
||||
* Master include file for the library USB MIDI Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassMIDI MIDI Class Driver
|
||||
* \brief USB class driver for the USB-IF MIDI class standard.
|
||||
*
|
||||
* \section Sec_USBClassMIDI_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/MIDIClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassMIDI_ModDescription Module Description
|
||||
* MIDI Class Driver module. This module contains an internal implementation of the USB MIDI Class, for both Device
|
||||
* and Host USB modes. User applications can use this class driver instead of implementing the MIDI class manually
|
||||
* via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Hosts or Devices using the USB MIDI Class.
|
||||
*
|
||||
* \note The USB MIDI class is actually a special case of the regular Audio class, thus this module depends on
|
||||
* structure definitions from the \ref Group_USBClassAudioDevice class driver module.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MIDI_CLASS_H_
|
||||
#define _MIDI_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_MIDI_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "Device/MIDIClassDevice.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/MIDIClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB Mass Storage Class driver.
|
||||
*
|
||||
* Master include file for the library USB Mass Storage Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassMS Mass Storage Class Driver
|
||||
* \brief USB class driver for the USB-IF Bulk-Only Transport Mass Storage class standard.
|
||||
*
|
||||
* \section Sec_USBClassMS_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassMS_ModDescription Module Description
|
||||
* Mass Storage Class Driver module. This module contains an internal implementation of the USB Mass Storage Class, for both
|
||||
* Device and Host USB modes. User applications can use this class driver instead of implementing the Mass Storage class
|
||||
* manually via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Hosts or Devices using the USB Mass Storage Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MS_CLASS_H_
|
||||
#define _MS_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_MS_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "Device/MassStorageClassDevice.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/MassStorageClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB Printer Class driver.
|
||||
*
|
||||
* Master include file for the library USB Printer Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassPrinter Printer Class Driver
|
||||
* \brief USB class driver for the USB-IF Printer class standard.
|
||||
*
|
||||
* \section Sec_USBClassPrinter_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/PrinterClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/PrinterClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassPrinter_ModDescription Module Description
|
||||
* Printer Class Driver module. This module contains an internal implementation of the USB Printer Class, for the base
|
||||
* USB Printer transport layer for USB Host mode only. Note that printers are free to implement whatever printer language
|
||||
* they choose on top of this (e.g. Postscript), and so this driver exposes low level data transport functions only rather
|
||||
* than high level raster or text functions. User applications can use this class driver instead of implementing the Printer
|
||||
* class manually via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Devices using the USB Printer Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PRINTER_CLASS_H_
|
||||
#define _PRINTER_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_PRINTER_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "Device/PrinterClassDevice.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/PrinterClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB RNDIS Class driver.
|
||||
*
|
||||
* Master include file for the library USB RNDIS Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassRNDIS RNDIS (Networking) Class Driver
|
||||
* \brief USB class driver for the Microsoft Remote Network Driver Interface Specification (RNDIS) class standard.
|
||||
*
|
||||
* \section Sec_USBClassRNDIS_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
* - LUFA/Drivers/USB/Class/Host/RNDISClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassRNDIS_ModDescription Module Description
|
||||
* RNDIS Class Driver module. This module contains an internal implementation of the Microsoft USB RNDIS Networking
|
||||
* Class, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
|
||||
* RNDIS class manually via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Hosts using the USB RNDIS Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_CLASS_H_
|
||||
#define _RNDIS_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_RNDIS_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "Device/RNDISClassDevice.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/RNDISClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Master include file for the library USB Still Image Class driver.
|
||||
*
|
||||
* Master include file for the library USB Still Image Class driver, for both host and device modes, where available.
|
||||
*
|
||||
* This file should be included in all user projects making use of this optional class driver, instead of
|
||||
* including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_USBClassDrivers
|
||||
* \defgroup Group_USBClassSI Still Image Class Driver
|
||||
* \brief USB class driver for the USB-IF Still Image (PIMA-compliant) class standard.
|
||||
*
|
||||
* \section Sec_USBClassSI_Dependencies Module Source Dependencies
|
||||
* The following files must be built with any user project that uses this module:
|
||||
* - LUFA/Drivers/USB/Class/Host/StillImageClassHost.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
|
||||
*
|
||||
* \section Sec_USBClassSI_ModDescription Module Description
|
||||
* Still Image Class Driver module. This module contains an internal implementation of the USB Still Image Class,
|
||||
* for USB Host mode only. User applications can use this class driver instead of implementing the Still Image class
|
||||
* manually via the low-level LUFA APIs.
|
||||
*
|
||||
* This module is designed to simplify the user code by exposing only the required interface needed to interface with
|
||||
* Devices using the USB Still Image Class.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SI_CLASS_H_
|
||||
#define _SI_CLASS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#define __INCLUDE_FROM_SI_DRIVER
|
||||
|
||||
/* Includes: */
|
||||
#include "../Core/USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#include "Host/StillImageClassHost.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "../../../../Common/Common.h"
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#include "../Device.h"
|
||||
|
||||
void USB_Device_SendRemoteWakeup(void)
|
||||
{
|
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL))
|
||||
{
|
||||
USB_PLL_On();
|
||||
while (!(USB_PLL_IsReady()));
|
||||
}
|
||||
|
||||
USB_CLK_Unfreeze();
|
||||
|
||||
UDCON |= (1 << RMWKUP);
|
||||
while (UDCON & (1 << RMWKUP));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief USB Device definitions for the AVR8 microcontrollers.
|
||||
* \copydetails Group_Device_AVR8
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB driver
|
||||
* dispatch header located in LUFA/Drivers/USB/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Device
|
||||
* \defgroup Group_Device_AVR8 Device Management (AVR8)
|
||||
* \brief USB Device definitions for the AVR8 microcontrollers.
|
||||
*
|
||||
* Architecture specific USB Device definitions for the Atmel 8-bit AVR microcontrollers.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __USBDEVICE_AVR8_H__
|
||||
#define __USBDEVICE_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../../Common/Common.h"
|
||||
#include "../USBController.h"
|
||||
#include "../StdDescriptors.h"
|
||||
#include "../USBInterrupt.h"
|
||||
#include "../Endpoint.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
|
||||
#endif
|
||||
|
||||
#if (defined(USE_RAM_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS))
|
||||
#error USE_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive.
|
||||
#endif
|
||||
|
||||
#if (defined(USE_FLASH_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS))
|
||||
#error USE_FLASH_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive.
|
||||
#endif
|
||||
|
||||
#if (defined(USE_FLASH_DESCRIPTORS) && defined(USE_RAM_DESCRIPTORS))
|
||||
#error USE_FLASH_DESCRIPTORS and USE_RAM_DESCRIPTORS are mutually exclusive.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name USB Device Mode Option Masks */
|
||||
//@{
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__)
|
||||
/** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the
|
||||
* USB interface should be initialized in low speed (1.5Mb/s) mode.
|
||||
*
|
||||
* \note Low Speed mode is not available on all USB AVR models.
|
||||
* \n
|
||||
*
|
||||
* \note Restrictions apply on the number, size and type of endpoints which can be used
|
||||
* when running in low speed mode - please refer to the USB 2.0 specification.
|
||||
*/
|
||||
#define USB_DEVICE_OPT_LOWSPEED (1 << 0)
|
||||
#endif
|
||||
|
||||
/** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the
|
||||
* USB interface should be initialized in full speed (12Mb/s) mode.
|
||||
*/
|
||||
#define USB_DEVICE_OPT_FULLSPEED (0 << 0)
|
||||
//@}
|
||||
|
||||
#if (!defined(NO_INTERNAL_SERIAL) && \
|
||||
(defined(USB_SERIES_7_AVR) || defined(USB_SERIES_6_AVR) || \
|
||||
defined(USB_SERIES_4_AVR) || defined(USB_SERIES_2_AVR) || \
|
||||
defined(__DOXYGEN__)))
|
||||
/** String descriptor index for the device's unique serial number string descriptor within the device.
|
||||
* This unique serial number is used by the host to associate resources to the device (such as drivers or COM port
|
||||
* number allocations) to a device regardless of the port it is plugged in to on the host. Some microcontrollers contain
|
||||
* a unique serial number internally, and setting the device descriptors serial number string index to this value
|
||||
* will cause it to use the internal serial number.
|
||||
*
|
||||
* On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial
|
||||
* number for the device.
|
||||
*/
|
||||
#define USE_INTERNAL_SERIAL 0xDC
|
||||
|
||||
/** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller
|
||||
* model.
|
||||
*/
|
||||
#define INTERNAL_SERIAL_LENGTH_BITS 80
|
||||
|
||||
/** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller
|
||||
* model.
|
||||
*/
|
||||
#define INTERNAL_SERIAL_START_ADDRESS 0x0E
|
||||
#else
|
||||
#define USE_INTERNAL_SERIAL NO_DESCRIPTOR
|
||||
|
||||
#define INTERNAL_SERIAL_LENGTH_BITS 0
|
||||
#define INTERNAL_SERIAL_START_ADDRESS 0
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Sends a Remote Wakeup request to the host. This signals to the host that the device should
|
||||
* be taken out of suspended mode, and communications should resume.
|
||||
*
|
||||
* Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the
|
||||
* host computer when the host has suspended all USB devices to enter a low power state.
|
||||
*
|
||||
* \attention This function should only be used if the device has indicated to the host that it
|
||||
* supports the Remote Wakeup feature in the device descriptors, and should only be
|
||||
* issued if the host is currently allowing remote wakeup events from the device (i.e.,
|
||||
* the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP
|
||||
* compile time option is used, this function is unavailable.
|
||||
* \n\n
|
||||
*
|
||||
* \attention The USB clock must be running for this function to operate. If the stack is initialized with
|
||||
* the \ref USB_OPT_MANUAL_PLL option enabled, the user must ensure that the PLL is running
|
||||
* before attempting to call this function.
|
||||
*
|
||||
* \see \ref Group_StdDescriptors for more information on the RMWAKEUP feature and device descriptors.
|
||||
*/
|
||||
void USB_Device_SendRemoteWakeup(void);
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Returns the current USB frame number, when in device mode. Every millisecond the USB bus is active (i.e. enumerated to a host)
|
||||
* the frame number is incremented by one.
|
||||
*
|
||||
* \return Current USB frame number from the USB controller.
|
||||
*/
|
||||
static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint16_t USB_Device_GetFrameNumber(void)
|
||||
{
|
||||
return UDFNUM;
|
||||
}
|
||||
|
||||
#if !defined(NO_SOF_EVENTS)
|
||||
/** Enables the device mode Start Of Frame events. When enabled, this causes the
|
||||
* \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus,
|
||||
* at the start of each USB frame when enumerated in device mode.
|
||||
*
|
||||
* \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined.
|
||||
*/
|
||||
static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Device_EnableSOFEvents(void)
|
||||
{
|
||||
USB_INT_Enable(USB_INT_SOFI);
|
||||
}
|
||||
|
||||
/** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the
|
||||
* \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode.
|
||||
*
|
||||
* \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined.
|
||||
*/
|
||||
static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Device_DisableSOFEvents(void)
|
||||
{
|
||||
USB_INT_Disable(USB_INT_SOFI);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Inline Functions: */
|
||||
#if defined(USB_DEVICE_OPT_LOWSPEED)
|
||||
static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Device_SetLowSpeed(void)
|
||||
{
|
||||
UDCON |= (1 << LSM);
|
||||
}
|
||||
|
||||
static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Device_SetFullSpeed(void)
|
||||
{
|
||||
UDCON &= ~(1 << LSM);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Device_SetDeviceAddress(const uint8_t Address)
|
||||
{
|
||||
UDADDR = (UDADDR & (1 << ADDEN)) | (Address & 0x7F);
|
||||
}
|
||||
|
||||
static inline void USB_Device_EnableDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Device_EnableDeviceAddress(const uint8_t Address)
|
||||
{
|
||||
(void)Address;
|
||||
|
||||
UDADDR |= (1 << ADDEN);
|
||||
}
|
||||
|
||||
static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
|
||||
static inline bool USB_Device_IsAddressSet(void)
|
||||
{
|
||||
return (UDADDR & (1 << ADDEN));
|
||||
}
|
||||
|
||||
#if (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
|
||||
static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) ATTR_NON_NULL_PTR_ARG(1);
|
||||
static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString)
|
||||
{
|
||||
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
|
||||
GlobalInterruptDisable();
|
||||
|
||||
uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS;
|
||||
|
||||
for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++)
|
||||
{
|
||||
uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
|
||||
|
||||
if (SerialCharNum & 0x01)
|
||||
{
|
||||
SerialByte >>= 4;
|
||||
SigReadAddress++;
|
||||
}
|
||||
|
||||
SerialByte &= 0x0F;
|
||||
|
||||
UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ?
|
||||
(('A' - 10) + SerialByte) : ('0' + SerialByte));
|
||||
}
|
||||
|
||||
SetGlobalInterruptMask(CurrentGlobalInt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "../../../../Common/Common.h"
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#include "EndpointStream_AVR8.h"
|
||||
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
uint8_t Endpoint_Discard_Stream(uint16_t Length,
|
||||
uint16_t* const BytesProcessed)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
uint16_t BytesInTransfer = 0;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
if (BytesProcessed != NULL)
|
||||
Length -= *BytesProcessed;
|
||||
|
||||
while (Length)
|
||||
{
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
if (BytesProcessed != NULL)
|
||||
{
|
||||
*BytesProcessed += BytesInTransfer;
|
||||
return ENDPOINT_RWSTREAM_IncompleteTransfer;
|
||||
}
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
Endpoint_Discard_8();
|
||||
|
||||
Length--;
|
||||
BytesInTransfer++;
|
||||
}
|
||||
}
|
||||
|
||||
return ENDPOINT_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Null_Stream(uint16_t Length,
|
||||
uint16_t* const BytesProcessed)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
uint16_t BytesInTransfer = 0;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
if (BytesProcessed != NULL)
|
||||
Length -= *BytesProcessed;
|
||||
|
||||
while (Length)
|
||||
{
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearIN();
|
||||
|
||||
if (BytesProcessed != NULL)
|
||||
{
|
||||
*BytesProcessed += BytesInTransfer;
|
||||
return ENDPOINT_RWSTREAM_IncompleteTransfer;
|
||||
}
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
Endpoint_Write_8(0);
|
||||
|
||||
Length--;
|
||||
BytesInTransfer++;
|
||||
}
|
||||
}
|
||||
|
||||
return ENDPOINT_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations,
|
||||
* so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE
|
||||
#define TEMPLATE_BUFFER_TYPE const void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr)
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE
|
||||
#define TEMPLATE_BUFFER_TYPE const void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr)
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE
|
||||
#define TEMPLATE_BUFFER_TYPE void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8()
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE
|
||||
#define TEMPLATE_BUFFER_TYPE void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8()
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE
|
||||
#define TEMPLATE_BUFFER_TYPE const void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE
|
||||
#define TEMPLATE_BUFFER_TYPE const void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE)
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE
|
||||
#define TEMPLATE_BUFFER_TYPE const void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE
|
||||
#define TEMPLATE_BUFFER_TYPE const void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE
|
||||
#define TEMPLATE_BUFFER_TYPE void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8())
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE
|
||||
#define TEMPLATE_BUFFER_TYPE void*
|
||||
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8())
|
||||
#include "Template/Template_Endpoint_RW.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr)
|
||||
#include "Template/Template_Endpoint_Control_W.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr)
|
||||
#include "Template/Template_Endpoint_Control_W.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8()
|
||||
#include "Template/Template_Endpoint_Control_R.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8()
|
||||
#include "Template/Template_Endpoint_Control_R.c"
|
||||
|
||||
#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_Control_W.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_Control_W.c"
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE)
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_Control_W.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr))
|
||||
#include "Template/Template_Endpoint_Control_W.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) 0
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8())
|
||||
#include "Template/Template_Endpoint_Control_R.c"
|
||||
|
||||
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE
|
||||
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
|
||||
#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
|
||||
#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8())
|
||||
#include "Template/Template_Endpoint_Control_R.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Endpoint data stream transmission and reception management for the AVR8 microcontrollers.
|
||||
* \copydetails Group_EndpointStreamRW_AVR8
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB driver
|
||||
* dispatch header located in LUFA/Drivers/USB/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_EndpointStreamRW
|
||||
* \defgroup Group_EndpointStreamRW_AVR8 Read/Write of Multi-Byte Streams (AVR8)
|
||||
* \brief Endpoint data stream transmission and reception management for the Atmel AVR8 architecture.
|
||||
*
|
||||
* Functions, macros, variables, enums and types related to data reading and writing of data streams from
|
||||
* and to endpoints.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __ENDPOINT_STREAM_AVR8_H__
|
||||
#define __ENDPOINT_STREAM_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../../Common/Common.h"
|
||||
#include "../USBMode.h"
|
||||
#include "../USBTask.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Function Prototypes: */
|
||||
/** \name Stream functions for null data */
|
||||
//@{
|
||||
|
||||
/** Reads and discards the given number of bytes from the currently selected endpoint's bank,
|
||||
* discarding fully read packets from the host as needed. The last packet is not automatically
|
||||
* discarded once the remaining bytes has been read; the user is responsible for manually
|
||||
* discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro.
|
||||
*
|
||||
* If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
|
||||
* failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
|
||||
* storage location, the transfer will instead be performed as a series of chunks. Each time
|
||||
* the endpoint bank becomes empty while there is still data to process (and after the current
|
||||
* packet has been acknowledged) the BytesProcessed location will be updated with the total number
|
||||
* of bytes processed in the stream, and the function will exit with an error code of
|
||||
* \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
|
||||
* in the user code - to continue the transfer, call the function again with identical parameters
|
||||
* and it will resume until the BytesProcessed value reaches the total transfer length.
|
||||
*
|
||||
* <b>Single Stream Transfer Example:</b>
|
||||
* \code
|
||||
* uint8_t ErrorCode;
|
||||
*
|
||||
* if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* <b>Partial Stream Transfers Example:</b>
|
||||
* \code
|
||||
* uint8_t ErrorCode;
|
||||
* uint16_t BytesProcessed;
|
||||
*
|
||||
* BytesProcessed = 0;
|
||||
* while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
|
||||
* {
|
||||
* // Stream not yet complete - do other actions here, abort if required
|
||||
* }
|
||||
*
|
||||
* if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param[in] Length Number of bytes to discard via the currently selected endpoint.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be read at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Discard_Stream(uint16_t Length,
|
||||
uint16_t* const BytesProcessed);
|
||||
|
||||
/** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending
|
||||
* full packets to the host as needed. The last packet is not automatically sent once the
|
||||
* remaining bytes have been written; the user is responsible for manually sending the last
|
||||
* packet to the host via the \ref Endpoint_ClearIN() macro.
|
||||
*
|
||||
* If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
|
||||
* failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
|
||||
* storage location, the transfer will instead be performed as a series of chunks. Each time
|
||||
* the endpoint bank becomes full while there is still data to process (and after the current
|
||||
* packet transmission has been initiated) the BytesProcessed location will be updated with the
|
||||
* total number of bytes processed in the stream, and the function will exit with an error code of
|
||||
* \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
|
||||
* in the user code - to continue the transfer, call the function again with identical parameters
|
||||
* and it will resume until the BytesProcessed value reaches the total transfer length.
|
||||
*
|
||||
* <b>Single Stream Transfer Example:</b>
|
||||
* \code
|
||||
* uint8_t ErrorCode;
|
||||
*
|
||||
* if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* <b>Partial Stream Transfers Example:</b>
|
||||
* \code
|
||||
* uint8_t ErrorCode;
|
||||
* uint16_t BytesProcessed;
|
||||
*
|
||||
* BytesProcessed = 0;
|
||||
* while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
|
||||
* {
|
||||
* // Stream not yet complete - do other actions here, abort if required
|
||||
* }
|
||||
*
|
||||
* if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param[in] Length Number of zero bytes to send via the currently selected endpoint.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be read at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Null_Stream(uint16_t Length,
|
||||
uint16_t* const BytesProcessed);
|
||||
|
||||
//@}
|
||||
|
||||
/** \name Stream functions for RAM source/destination data */
|
||||
//@{
|
||||
|
||||
/** Writes the given number of bytes to the endpoint from the given buffer in little endian,
|
||||
* sending full packets to the host as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* \ref Endpoint_ClearIN() macro.
|
||||
*
|
||||
* If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
|
||||
* failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
|
||||
* storage location, the transfer will instead be performed as a series of chunks. Each time
|
||||
* the endpoint bank becomes full while there is still data to process (and after the current
|
||||
* packet transmission has been initiated) the BytesProcessed location will be updated with the
|
||||
* total number of bytes processed in the stream, and the function will exit with an error code of
|
||||
* \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
|
||||
* in the user code - to continue the transfer, call the function again with identical parameters
|
||||
* and it will resume until the BytesProcessed value reaches the total transfer length.
|
||||
*
|
||||
* <b>Single Stream Transfer Example:</b>
|
||||
* \code
|
||||
* uint8_t DataStream[512];
|
||||
* uint8_t ErrorCode;
|
||||
*
|
||||
* if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream),
|
||||
* NULL)) != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* <b>Partial Stream Transfers Example:</b>
|
||||
* \code
|
||||
* uint8_t DataStream[512];
|
||||
* uint8_t ErrorCode;
|
||||
* uint16_t BytesProcessed;
|
||||
*
|
||||
* BytesProcessed = 0;
|
||||
* while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream),
|
||||
* &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
|
||||
* {
|
||||
* // Stream not yet complete - do other actions here, abort if required
|
||||
* }
|
||||
*
|
||||
* if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be written at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Stream_LE(const void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Writes the given number of bytes to the endpoint from the given buffer in big endian,
|
||||
* sending full packets to the host as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* \ref Endpoint_ClearIN() macro.
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be written at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Stream_BE(const void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the endpoint from the given buffer in little endian,
|
||||
* discarding fully read packets from the host as needed. The last packet is not automatically
|
||||
* discarded once the remaining bytes has been read; the user is responsible for manually
|
||||
* discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro.
|
||||
*
|
||||
* If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
|
||||
* failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
|
||||
* storage location, the transfer will instead be performed as a series of chunks. Each time
|
||||
* the endpoint bank becomes empty while there is still data to process (and after the current
|
||||
* packet has been acknowledged) the BytesProcessed location will be updated with the total number
|
||||
* of bytes processed in the stream, and the function will exit with an error code of
|
||||
* \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
|
||||
* in the user code - to continue the transfer, call the function again with identical parameters
|
||||
* and it will resume until the BytesProcessed value reaches the total transfer length.
|
||||
*
|
||||
* <b>Single Stream Transfer Example:</b>
|
||||
* \code
|
||||
* uint8_t DataStream[512];
|
||||
* uint8_t ErrorCode;
|
||||
*
|
||||
* if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream),
|
||||
* NULL)) != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* <b>Partial Stream Transfers Example:</b>
|
||||
* \code
|
||||
* uint8_t DataStream[512];
|
||||
* uint8_t ErrorCode;
|
||||
* uint16_t BytesProcessed;
|
||||
*
|
||||
* BytesProcessed = 0;
|
||||
* while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream),
|
||||
* &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
|
||||
* {
|
||||
* // Stream not yet complete - do other actions here, abort if required
|
||||
* }
|
||||
*
|
||||
* if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
|
||||
* {
|
||||
* // Stream failed to complete - check ErrorCode here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be read at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Stream_LE(void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the endpoint from the given buffer in big endian,
|
||||
* discarding fully read packets from the host as needed. The last packet is not automatically
|
||||
* discarded once the remaining bytes has been read; the user is responsible for manually
|
||||
* discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro.
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be read at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Stream_BE(void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian,
|
||||
* sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared
|
||||
* in both failure and success states; the user is responsible for manually clearing the status OUT packet
|
||||
* to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro.
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian,
|
||||
* sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared
|
||||
* in both failure and success states; the user is responsible for manually clearing the status OUT packet
|
||||
* to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro.
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian,
|
||||
* discarding fully read packets from the host as needed. The device IN acknowledgement is not
|
||||
* automatically sent after success or failure states; the user is responsible for manually sending the
|
||||
* status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro.
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian,
|
||||
* discarding fully read packets from the host as needed. The device IN acknowledgement is not
|
||||
* automatically sent after success or failure states; the user is responsible for manually sending the
|
||||
* status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro.
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
//@}
|
||||
|
||||
/** \name Stream functions for EEPROM source/destination data */
|
||||
//@{
|
||||
|
||||
/** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE().
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be written at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_EStream_LE(const void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE().
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be written at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_EStream_BE(const void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** EEPROM buffer destination version of \ref Endpoint_Read_Stream_LE().
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be read at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_EStream_LE(void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** EEPROM buffer destination version of \ref Endpoint_Read_Stream_BE().
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be read at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_EStream_BE(void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE.
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
* \n\n
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_EStream_LE(const void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE().
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
* \n\n
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_EStream_BE(const void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE().
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
* \n\n
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Control_EStream_LE(void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE().
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
* \n\n
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[out] Buffer Pointer to the destination data buffer to write to.
|
||||
* \param[in] Length Number of bytes to send via the currently selected endpoint.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Control_EStream_BE(void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
//@}
|
||||
|
||||
/** \name Stream functions for PROGMEM source/destination data */
|
||||
//@{
|
||||
|
||||
/** FLASH buffer source version of \ref Endpoint_Write_Stream_LE().
|
||||
*
|
||||
* \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be written at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_PStream_LE(const void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** FLASH buffer source version of \ref Endpoint_Write_Stream_BE().
|
||||
*
|
||||
* \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
|
||||
* transaction should be updated, \c NULL if the entire stream should be written at once.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_PStream_BE(const void* const Buffer,
|
||||
uint16_t Length,
|
||||
uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE().
|
||||
*
|
||||
* \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
* \n\n
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_PStream_LE(const void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE().
|
||||
*
|
||||
* \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
|
||||
*
|
||||
* \note This function automatically sends the last packet in the data stage of the transaction; when the
|
||||
* function returns, the user is responsible for clearing the <b>status</b> stage of the transaction.
|
||||
* Note that the status stage packet is sent or received in the opposite direction of the data flow.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
* \n\n
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param[in] Buffer Pointer to the source data buffer to read from.
|
||||
* \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_PStream_BE(const void* const Buffer,
|
||||
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
//@}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "../../../../Common/Common.h"
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#include "../Endpoint.h"
|
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
||||
#endif
|
||||
|
||||
bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table,
|
||||
const uint8_t Entries)
|
||||
{
|
||||
for (uint8_t i = 0; i < Entries; i++)
|
||||
{
|
||||
if (!(Table[i].Address))
|
||||
continue;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
|
||||
const uint8_t UECFG0XData,
|
||||
const uint8_t UECFG1XData)
|
||||
{
|
||||
#if defined(CONTROL_ONLY_DEVICE) || defined(ORDERED_EP_CONFIG)
|
||||
Endpoint_SelectEndpoint(Number);
|
||||
Endpoint_EnableEndpoint();
|
||||
|
||||
UECFG1X = 0;
|
||||
UECFG0X = UECFG0XData;
|
||||
UECFG1X = UECFG1XData;
|
||||
|
||||
return Endpoint_IsConfigured();
|
||||
#else
|
||||
for (uint8_t EPNum = Number; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
|
||||
{
|
||||
uint8_t UECFG0XTemp;
|
||||
uint8_t UECFG1XTemp;
|
||||
uint8_t UEIENXTemp;
|
||||
|
||||
Endpoint_SelectEndpoint(EPNum);
|
||||
|
||||
if (EPNum == Number)
|
||||
{
|
||||
UECFG0XTemp = UECFG0XData;
|
||||
UECFG1XTemp = UECFG1XData;
|
||||
UEIENXTemp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UECFG0XTemp = UECFG0X;
|
||||
UECFG1XTemp = UECFG1X;
|
||||
UEIENXTemp = UEIENX;
|
||||
}
|
||||
|
||||
if (!(UECFG1XTemp & (1 << ALLOC)))
|
||||
continue;
|
||||
|
||||
Endpoint_DisableEndpoint();
|
||||
UECFG1X &= ~(1 << ALLOC);
|
||||
|
||||
Endpoint_EnableEndpoint();
|
||||
UECFG0X = UECFG0XTemp;
|
||||
UECFG1X = UECFG1XTemp;
|
||||
UEIENX = UEIENXTemp;
|
||||
|
||||
if (!(Endpoint_IsConfigured()))
|
||||
return false;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(Number);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Endpoint_ClearEndpoints(void)
|
||||
{
|
||||
UEINT = 0;
|
||||
|
||||
for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
|
||||
{
|
||||
Endpoint_SelectEndpoint(EPNum);
|
||||
UEIENX = 0;
|
||||
UEINTX = 0;
|
||||
UECFG1X = 0;
|
||||
Endpoint_DisableEndpoint();
|
||||
}
|
||||
}
|
||||
|
||||
void Endpoint_ClearStatusStage(void)
|
||||
{
|
||||
if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST)
|
||||
{
|
||||
while (!(Endpoint_IsOUTReceived()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
uint8_t Endpoint_WaitUntilReady(void)
|
||||
{
|
||||
#if (USB_STREAM_TIMEOUT_MS < 0xFF)
|
||||
uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
|
||||
#else
|
||||
uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
|
||||
#endif
|
||||
|
||||
uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
|
||||
{
|
||||
if (Endpoint_IsINReady())
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Endpoint_IsOUTReceived())
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t USB_DeviceState_LCL = USB_DeviceState;
|
||||
|
||||
if (USB_DeviceState_LCL == DEVICE_STATE_Unattached)
|
||||
return ENDPOINT_READYWAIT_DeviceDisconnected;
|
||||
else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended)
|
||||
return ENDPOINT_READYWAIT_BusSuspended;
|
||||
else if (Endpoint_IsStalled())
|
||||
return ENDPOINT_READYWAIT_EndpointStalled;
|
||||
|
||||
uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber();
|
||||
|
||||
if (CurrentFrameNumber != PreviousFrameNumber)
|
||||
{
|
||||
PreviousFrameNumber = CurrentFrameNumber;
|
||||
|
||||
if (!(TimeoutMSRem--))
|
||||
return ENDPOINT_READYWAIT_Timeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,819 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief USB Endpoint definitions for the AVR8 microcontrollers.
|
||||
* \copydetails Group_EndpointManagement_AVR8
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB driver
|
||||
* dispatch header located in LUFA/Drivers/USB/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_EndpointRW
|
||||
* \defgroup Group_EndpointRW_AVR8 Endpoint Data Reading and Writing (AVR8)
|
||||
* \brief Endpoint data read/write definitions for the Atmel AVR8 architecture.
|
||||
*
|
||||
* Functions, macros, variables, enums and types related to data reading and writing from and to endpoints.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_EndpointPrimitiveRW
|
||||
* \defgroup Group_EndpointPrimitiveRW_AVR8 Read/Write of Primitive Data Types (AVR8)
|
||||
* \brief Endpoint primitive read/write definitions for the Atmel AVR8 architecture.
|
||||
*
|
||||
* Functions, macros, variables, enums and types related to data reading and writing of primitive data types
|
||||
* from and to endpoints.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_EndpointPacketManagement
|
||||
* \defgroup Group_EndpointPacketManagement_AVR8 Endpoint Packet Management (AVR8)
|
||||
* \brief Endpoint packet management definitions for the Atmel AVR8 architecture.
|
||||
*
|
||||
* Functions, macros, variables, enums and types related to packet management of endpoints.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_EndpointManagement
|
||||
* \defgroup Group_EndpointManagement_AVR8 Endpoint Management (AVR8)
|
||||
* \brief Endpoint management definitions for the Atmel AVR8 architecture.
|
||||
*
|
||||
* Functions, macros and enums related to endpoint management when in USB Device mode. This
|
||||
* module contains the endpoint management macros, as well as endpoint interrupt and data
|
||||
* send/receive functions for various data types.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __ENDPOINT_AVR8_H__
|
||||
#define __ENDPOINT_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../../Common/Common.h"
|
||||
#include "../USBTask.h"
|
||||
#include "../USBInterrupt.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Inline Functions: */
|
||||
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
|
||||
ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes)
|
||||
{
|
||||
uint8_t MaskVal = 0;
|
||||
uint16_t CheckBytes = 8;
|
||||
|
||||
while (CheckBytes < Bytes)
|
||||
{
|
||||
MaskVal++;
|
||||
CheckBytes <<= 1;
|
||||
}
|
||||
|
||||
return (MaskVal << EPSIZE0);
|
||||
}
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Endpoint_ClearEndpoints(void);
|
||||
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
|
||||
const uint8_t UECFG0XData,
|
||||
const uint8_t UECFG1XData);
|
||||
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
|
||||
/** Default size of the default control endpoint's bank, until altered by the control endpoint bank size
|
||||
* value in the device descriptor. Not available if the \c FIXED_CONTROL_ENDPOINT_SIZE token is defined.
|
||||
*/
|
||||
#define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8
|
||||
#endif
|
||||
|
||||
#if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__)
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__)
|
||||
/** Total number of endpoints (including the default control endpoint at address 0) which may
|
||||
* be used in the device. Different USB AVR models support different amounts of endpoints,
|
||||
* this value reflects the maximum number of endpoints for the currently selected AVR model.
|
||||
*/
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 7
|
||||
#else
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 5
|
||||
#endif
|
||||
#else
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 1
|
||||
#endif
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error return codes of the \ref Endpoint_WaitUntilReady() function.
|
||||
*
|
||||
* \ingroup Group_EndpointRW_AVR8
|
||||
*/
|
||||
enum Endpoint_WaitUntilReady_ErrorCodes_t
|
||||
{
|
||||
ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */
|
||||
ENDPOINT_READYWAIT_EndpointStalled = 1, /**< The endpoint was stalled during the stream
|
||||
* transfer by the host or device.
|
||||
*/
|
||||
ENDPOINT_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while
|
||||
* waiting for the endpoint to become ready.
|
||||
*/
|
||||
ENDPOINT_READYWAIT_BusSuspended = 3, /**< The USB bus has been suspended by the host and
|
||||
* no USB endpoint traffic can occur until the bus
|
||||
* has resumed.
|
||||
*/
|
||||
ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet
|
||||
* within the software timeout period set by the
|
||||
* \ref USB_STREAM_TIMEOUT_MS macro.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Configures the specified endpoint address with the given endpoint type, bank size and number of hardware
|
||||
* banks. Once configured, the endpoint may be read from or written to, depending on its direction.
|
||||
*
|
||||
* \param[in] Address Endpoint address to configure.
|
||||
*
|
||||
* \param[in] Type Type of endpoint to configure, a \c EP_TYPE_* mask. Not all endpoint types
|
||||
* are available on Low Speed USB devices - refer to the USB 2.0 specification.
|
||||
*
|
||||
* \param[in] Size Size of the endpoint's bank, where packets are stored before they are transmitted
|
||||
* to the USB host, or after they have been received from the USB host (depending on
|
||||
* the endpoint's data direction). The bank size must indicate the maximum packet size
|
||||
* that the endpoint can handle.
|
||||
*
|
||||
* \param[in] Banks Number of banks to use for the endpoint being configured.
|
||||
*
|
||||
* \attention When the \c ORDERED_EP_CONFIG compile time option is used, Endpoints <b>must</b> be configured in
|
||||
* ascending order, or bank corruption will occur.
|
||||
*
|
||||
* \note Different endpoints may have different maximum packet sizes based on the endpoint's index - please
|
||||
* refer to the chosen microcontroller model's datasheet to determine the maximum bank size for each endpoint.
|
||||
* \n\n
|
||||
*
|
||||
* \note The default control endpoint should not be manually configured by the user application, as
|
||||
* it is automatically configured by the library internally.
|
||||
* \n\n
|
||||
*
|
||||
* \note This routine will automatically select the specified endpoint upon success. Upon failure, the endpoint
|
||||
* which failed to reconfigure correctly will be selected.
|
||||
*
|
||||
* \return Boolean \c true if the configuration succeeded, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address,
|
||||
const uint8_t Type,
|
||||
const uint16_t Size,
|
||||
const uint8_t Banks) ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address,
|
||||
const uint8_t Type,
|
||||
const uint16_t Size,
|
||||
const uint8_t Banks)
|
||||
{
|
||||
uint8_t Number = (Address & ENDPOINT_EPNUM_MASK);
|
||||
|
||||
if (Number >= ENDPOINT_TOTAL_ENDPOINTS)
|
||||
return false;
|
||||
|
||||
return Endpoint_ConfigureEndpoint_Prv(Number,
|
||||
((Type << EPTYPE0) | ((Address & ENDPOINT_DIR_IN) ? (1 << EPDIR) : 0)),
|
||||
((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Endpoint_BytesToEPSizeMask(Size)));
|
||||
}
|
||||
|
||||
/** Indicates the number of bytes currently stored in the current endpoint's selected bank.
|
||||
*
|
||||
* \ingroup Group_EndpointRW_AVR8
|
||||
*
|
||||
* \return Total number of bytes in the currently selected Endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint16_t Endpoint_BytesInEndpoint(void)
|
||||
{
|
||||
#if (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
|
||||
return UEBCX;
|
||||
#elif defined(USB_SERIES_4_AVR)
|
||||
return (((uint16_t)UEBCHX << 8) | UEBCLX);
|
||||
#elif defined(USB_SERIES_2_AVR)
|
||||
return UEBCLX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Determines the currently selected endpoint's direction.
|
||||
*
|
||||
* \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_GetEndpointDirection(void)
|
||||
{
|
||||
return (UECFG0X & (1 << EPDIR)) ? ENDPOINT_DIR_IN : ENDPOINT_DIR_OUT;
|
||||
}
|
||||
|
||||
/** Get the endpoint address of the currently selected endpoint. This is typically used to save
|
||||
* the currently selected endpoint so that it can be restored after another endpoint has been
|
||||
* manipulated.
|
||||
*
|
||||
* \return Index of the currently selected endpoint.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_GetCurrentEndpoint(void)
|
||||
{
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
return ((UENUM & ENDPOINT_EPNUM_MASK) | Endpoint_GetEndpointDirection());
|
||||
#else
|
||||
return ENDPOINT_CONTROLEP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Selects the given endpoint address.
|
||||
*
|
||||
* Any endpoint operations which do not require the endpoint address to be indicated will operate on
|
||||
* the currently selected endpoint.
|
||||
*
|
||||
* \param[in] Address Endpoint address to select.
|
||||
*/
|
||||
static inline void Endpoint_SelectEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_SelectEndpoint(const uint8_t Address)
|
||||
{
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
UENUM = (Address & ENDPOINT_EPNUM_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
|
||||
* data In and Out pointers to the bank's contents.
|
||||
*
|
||||
* \param[in] Address Endpoint address whose FIFO buffers are to be reset.
|
||||
*/
|
||||
static inline void Endpoint_ResetEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ResetEndpoint(const uint8_t Address)
|
||||
{
|
||||
UERST = (1 << (Address & ENDPOINT_EPNUM_MASK));
|
||||
UERST = 0;
|
||||
}
|
||||
|
||||
/** Enables the currently selected endpoint so that data can be sent and received through it to
|
||||
* and from a host.
|
||||
*
|
||||
* \note Endpoints must first be configured properly via \ref Endpoint_ConfigureEndpoint().
|
||||
*/
|
||||
static inline void Endpoint_EnableEndpoint(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_EnableEndpoint(void)
|
||||
{
|
||||
UECONX |= (1 << EPEN);
|
||||
}
|
||||
|
||||
/** Disables the currently selected endpoint so that data cannot be sent and received through it
|
||||
* to and from a host.
|
||||
*/
|
||||
static inline void Endpoint_DisableEndpoint(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_DisableEndpoint(void)
|
||||
{
|
||||
UECONX &= ~(1 << EPEN);
|
||||
}
|
||||
|
||||
/** Determines if the currently selected endpoint is enabled, but not necessarily configured.
|
||||
*
|
||||
* \return Boolean \c true if the currently selected endpoint is enabled, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_IsEnabled(void)
|
||||
{
|
||||
return ((UECONX & (1 << EPEN)) ? true : false);
|
||||
}
|
||||
|
||||
/** Retrieves the number of busy banks in the currently selected endpoint, which have been queued for
|
||||
* transmission via the \ref Endpoint_ClearIN() command, or are awaiting acknowledgment via the
|
||||
* \ref Endpoint_ClearOUT() command.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*
|
||||
* \return Total number of busy banks in the selected endpoint.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetBusyBanks(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t Endpoint_GetBusyBanks(void)
|
||||
{
|
||||
return (UESTA0X & (0x03 << NBUSYBK0));
|
||||
}
|
||||
|
||||
/** Aborts all pending IN transactions on the currently selected endpoint, once the bank
|
||||
* has been queued for transmission to the host via \ref Endpoint_ClearIN(). This function
|
||||
* will terminate all queued transactions, resetting the endpoint banks ready for a new
|
||||
* packet.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*/
|
||||
static inline void Endpoint_AbortPendingIN(void)
|
||||
{
|
||||
while (Endpoint_GetBusyBanks() != 0)
|
||||
{
|
||||
UEINTX |= (1 << RXOUTI);
|
||||
while (UEINTX & (1 << RXOUTI));
|
||||
}
|
||||
}
|
||||
|
||||
/** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint
|
||||
* bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN
|
||||
* direction). This function will return false if an error has occurred in the endpoint, if the endpoint
|
||||
* is an OUT direction and no packet (or an empty packet) has been received, or if the endpoint is an IN
|
||||
* direction and the endpoint bank is full.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*
|
||||
* \return Boolean \c true if the currently selected endpoint may be read from or written to, depending
|
||||
* on its direction.
|
||||
*/
|
||||
static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_IsReadWriteAllowed(void)
|
||||
{
|
||||
return ((UEINTX & (1 << RWAL)) ? true : false);
|
||||
}
|
||||
|
||||
/** Determines if the currently selected endpoint is configured.
|
||||
*
|
||||
* \return Boolean \c true if the currently selected endpoint has been configured, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_IsConfigured(void)
|
||||
{
|
||||
return ((UESTA0X & (1 << CFGOK)) ? true : false);
|
||||
}
|
||||
|
||||
/** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
|
||||
* interrupt duration has elapsed. Which endpoints have interrupted can be determined by
|
||||
* masking the return value against <tt>(1 << <i>{Endpoint Number}</i>)</tt>.
|
||||
*
|
||||
* \return Mask whose bits indicate which endpoints have interrupted.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetEndpointInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_GetEndpointInterrupts(void)
|
||||
{
|
||||
return UEINT;
|
||||
}
|
||||
|
||||
/** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type
|
||||
* endpoints).
|
||||
*
|
||||
* \param[in] Address Address of the endpoint whose interrupt flag should be tested.
|
||||
*
|
||||
* \return Boolean \c true if the specified endpoint has interrupted, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address)
|
||||
{
|
||||
return ((Endpoint_GetEndpointInterrupts() & (1 << (Address & ENDPOINT_EPNUM_MASK))) ? true : false);
|
||||
}
|
||||
|
||||
/** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*
|
||||
* \return Boolean \c true if the current endpoint is ready for an IN packet, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_IsINReady(void)
|
||||
{
|
||||
return ((UEINTX & (1 << TXINI)) ? true : false);
|
||||
}
|
||||
|
||||
/** Determines if the selected OUT endpoint has received new packet from the host.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*
|
||||
* \return Boolean \c true if current endpoint is has received an OUT packet, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_IsOUTReceived(void)
|
||||
{
|
||||
return ((UEINTX & (1 << RXOUTI)) ? true : false);
|
||||
}
|
||||
|
||||
/** Determines if the current CONTROL type endpoint has received a SETUP packet.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*
|
||||
* \return Boolean \c true if the selected endpoint has received a SETUP packet, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_IsSETUPReceived(void)
|
||||
{
|
||||
return ((UEINTX & (1 << RXSTPI)) ? true : false);
|
||||
}
|
||||
|
||||
/** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
|
||||
* endpoint for the next packet.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*
|
||||
* \note This is not applicable for non CONTROL type endpoints.
|
||||
*/
|
||||
static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ClearSETUP(void)
|
||||
{
|
||||
UEINTX &= ~(1 << RXSTPI);
|
||||
}
|
||||
|
||||
/** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
|
||||
* next packet and switching to the alternative endpoint bank if double banked.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*/
|
||||
static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ClearIN(void)
|
||||
{
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
UEINTX &= ~((1 << TXINI) | (1 << FIFOCON));
|
||||
#else
|
||||
UEINTX &= ~(1 << TXINI);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
|
||||
* for the next packet and switching to the alternative endpoint bank if double banked.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*/
|
||||
static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ClearOUT(void)
|
||||
{
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON));
|
||||
#else
|
||||
UEINTX &= ~(1 << RXOUTI);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
|
||||
* indicated endpoint and that the current transfer sequence should be aborted. This provides a
|
||||
* way for devices to indicate invalid commands to the host so that the current transfer can be
|
||||
* aborted and the host can begin its own recovery sequence.
|
||||
*
|
||||
* The currently selected endpoint remains stalled until either the \ref Endpoint_ClearStall() macro
|
||||
* is called, or the host issues a CLEAR FEATURE request to the device for the currently selected
|
||||
* endpoint.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*/
|
||||
static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_StallTransaction(void)
|
||||
{
|
||||
UECONX |= (1 << STALLRQ);
|
||||
}
|
||||
|
||||
/** Clears the STALL condition on the currently selected endpoint.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*/
|
||||
static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ClearStall(void)
|
||||
{
|
||||
UECONX |= (1 << STALLRQC);
|
||||
}
|
||||
|
||||
/** Determines if the currently selected endpoint is stalled, \c false otherwise.
|
||||
*
|
||||
* \ingroup Group_EndpointPacketManagement_AVR8
|
||||
*
|
||||
* \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_IsStalled(void)
|
||||
{
|
||||
return ((UECONX & (1 << STALLRQ)) ? true : false);
|
||||
}
|
||||
|
||||
/** Resets the data toggle of the currently selected endpoint. */
|
||||
static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ResetDataToggle(void)
|
||||
{
|
||||
UECONX |= (1 << RSTDT);
|
||||
}
|
||||
|
||||
/** Sets the direction of the currently selected endpoint.
|
||||
*
|
||||
* \param[in] DirectionMask New endpoint direction, as a \c ENDPOINT_DIR_* mask.
|
||||
*/
|
||||
static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask)
|
||||
{
|
||||
UECFG0X = ((UECFG0X & ~(1 << EPDIR)) | (DirectionMask ? (1 << EPDIR) : 0));
|
||||
}
|
||||
|
||||
/** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \return Next byte in the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline uint8_t Endpoint_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_Read_8(void)
|
||||
{
|
||||
return UEDATX;
|
||||
}
|
||||
|
||||
/** Writes one byte to the currently selected endpoint's bank, for IN direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \param[in] Data Data to write into the the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline void Endpoint_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Write_8(const uint8_t Data)
|
||||
{
|
||||
UEDATX = Data;
|
||||
}
|
||||
|
||||
/** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*/
|
||||
static inline void Endpoint_Discard_8(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Discard_8(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UEDATX;
|
||||
|
||||
(void)Dummy;
|
||||
}
|
||||
|
||||
/** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \return Next two bytes in the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline uint16_t Endpoint_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint16_t Endpoint_Read_16_LE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint16_t Value;
|
||||
uint8_t Bytes[2];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[0] = UEDATX;
|
||||
Data.Bytes[1] = UEDATX;
|
||||
|
||||
return Data.Value;
|
||||
}
|
||||
|
||||
/** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \return Next two bytes in the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline uint16_t Endpoint_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint16_t Endpoint_Read_16_BE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint16_t Value;
|
||||
uint8_t Bytes[2];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[1] = UEDATX;
|
||||
Data.Bytes[0] = UEDATX;
|
||||
|
||||
return Data.Value;
|
||||
}
|
||||
|
||||
/** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \param[in] Data Data to write to the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Write_16_LE(const uint16_t Data)
|
||||
{
|
||||
UEDATX = (Data & 0xFF);
|
||||
UEDATX = (Data >> 8);
|
||||
}
|
||||
|
||||
/** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \param[in] Data Data to write to the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline void Endpoint_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Write_16_BE(const uint16_t Data)
|
||||
{
|
||||
UEDATX = (Data >> 8);
|
||||
UEDATX = (Data & 0xFF);
|
||||
}
|
||||
|
||||
/** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*/
|
||||
static inline void Endpoint_Discard_16(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Discard_16(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
|
||||
(void)Dummy;
|
||||
}
|
||||
|
||||
/** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \return Next four bytes in the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint32_t Endpoint_Read_32_LE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t Value;
|
||||
uint8_t Bytes[4];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[0] = UEDATX;
|
||||
Data.Bytes[1] = UEDATX;
|
||||
Data.Bytes[2] = UEDATX;
|
||||
Data.Bytes[3] = UEDATX;
|
||||
|
||||
return Data.Value;
|
||||
}
|
||||
|
||||
/** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \return Next four bytes in the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline uint32_t Endpoint_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint32_t Endpoint_Read_32_BE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t Value;
|
||||
uint8_t Bytes[4];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[3] = UEDATX;
|
||||
Data.Bytes[2] = UEDATX;
|
||||
Data.Bytes[1] = UEDATX;
|
||||
Data.Bytes[0] = UEDATX;
|
||||
|
||||
return Data.Value;
|
||||
}
|
||||
|
||||
/** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \param[in] Data Data to write to the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Write_32_LE(const uint32_t Data)
|
||||
{
|
||||
UEDATX = (Data & 0xFF);
|
||||
UEDATX = (Data >> 8);
|
||||
UEDATX = (Data >> 16);
|
||||
UEDATX = (Data >> 24);
|
||||
}
|
||||
|
||||
/** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
|
||||
* direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*
|
||||
* \param[in] Data Data to write to the currently selected endpoint's FIFO buffer.
|
||||
*/
|
||||
static inline void Endpoint_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Write_32_BE(const uint32_t Data)
|
||||
{
|
||||
UEDATX = (Data >> 24);
|
||||
UEDATX = (Data >> 16);
|
||||
UEDATX = (Data >> 8);
|
||||
UEDATX = (Data & 0xFF);
|
||||
}
|
||||
|
||||
/** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8
|
||||
*/
|
||||
static inline void Endpoint_Discard_32(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_Discard_32(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
|
||||
(void)Dummy;
|
||||
}
|
||||
|
||||
/* External Variables: */
|
||||
/** Global indicating the maximum packet size of the default control endpoint located at address
|
||||
* 0 in the device. This value is set to the value indicated in the device descriptor in the user
|
||||
* project once the USB interface is initialized into device mode.
|
||||
*
|
||||
* If space is an issue, it is possible to fix this to a static value by defining the control
|
||||
* endpoint size in the \c FIXED_CONTROL_ENDPOINT_SIZE token passed to the compiler in the makefile
|
||||
* via the -D switch. When a fixed control endpoint size is used, the size is no longer dynamically
|
||||
* read from the descriptors at runtime and instead fixed to the given value. When used, it is
|
||||
* important that the descriptor control endpoint size value matches the size given as the
|
||||
* \c FIXED_CONTROL_ENDPOINT_SIZE token - it is recommended that the \c FIXED_CONTROL_ENDPOINT_SIZE token
|
||||
* be used in the device descriptors to ensure this.
|
||||
*
|
||||
* \attention This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
|
||||
extern uint8_t USB_Device_ControlEndpointSize;
|
||||
#else
|
||||
#define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures a table of endpoint descriptions, in sequence. This function can be used to configure multiple
|
||||
* endpoints at the same time.
|
||||
*
|
||||
* \note Endpoints with a zero address will be ignored, thus this function cannot be used to configure the
|
||||
* control endpoint.
|
||||
*
|
||||
* \param[in] Table Pointer to a table of endpoint descriptions.
|
||||
* \param[in] Entries Number of entries in the endpoint table to configure.
|
||||
*
|
||||
* \return Boolean \c true if all endpoints configured successfully, \c false otherwise.
|
||||
*/
|
||||
bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table,
|
||||
const uint8_t Entries);
|
||||
|
||||
/** Completes the status stage of a control transfer on a CONTROL type endpoint automatically,
|
||||
* with respect to the data direction. This is a convenience function which can be used to
|
||||
* simplify user control request handling.
|
||||
*
|
||||
* \note This routine should not be called on non CONTROL type endpoints.
|
||||
*/
|
||||
void Endpoint_ClearStatusStage(void);
|
||||
|
||||
/** Spin-loops until the currently selected non-control endpoint is ready for the next packet of data
|
||||
* to be read or written to it.
|
||||
*
|
||||
* \note This routine should not be called on CONTROL type endpoints.
|
||||
*
|
||||
* \ingroup Group_EndpointRW_AVR8
|
||||
*
|
||||
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_WaitUntilReady(void);
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
297
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
Normal file
297
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "../../../../Common/Common.h"
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER
|
||||
#include "../USBMode.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define __INCLUDE_FROM_HOST_C
|
||||
#include "../Host.h"
|
||||
|
||||
void USB_Host_ProcessNextHostState(void)
|
||||
{
|
||||
uint8_t ErrorCode = HOST_ENUMERROR_NoError;
|
||||
uint8_t SubErrorCode = HOST_ENUMERROR_NoError;
|
||||
|
||||
static uint16_t WaitMSRemaining;
|
||||
static uint8_t PostWaitState;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_WaitForDevice:
|
||||
if (WaitMSRemaining)
|
||||
{
|
||||
if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
|
||||
{
|
||||
USB_HostState = PostWaitState;
|
||||
ErrorCode = HOST_ENUMERROR_WaitStage;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(--WaitMSRemaining))
|
||||
USB_HostState = PostWaitState;
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_STATE_Powered:
|
||||
WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS;
|
||||
|
||||
USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle;
|
||||
break;
|
||||
case HOST_STATE_Powered_WaitForDeviceSettle:
|
||||
if (WaitMSRemaining--)
|
||||
{
|
||||
Delay_MS(1);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_Host_VBUS_Manual_Off();
|
||||
|
||||
USB_OTGPAD_On();
|
||||
USB_Host_VBUS_Auto_Enable();
|
||||
USB_Host_VBUS_Auto_On();
|
||||
|
||||
#if defined(NO_AUTO_VBUS_MANAGEMENT)
|
||||
USB_Host_VBUS_Manual_Enable();
|
||||
USB_Host_VBUS_Manual_On();
|
||||
#endif
|
||||
|
||||
USB_HostState = HOST_STATE_Powered_WaitForConnect;
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_STATE_Powered_WaitForConnect:
|
||||
if (USB_INT_HasOccurred(USB_INT_DCONNI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_DCONNI);
|
||||
USB_INT_Clear(USB_INT_DDISCI);
|
||||
|
||||
USB_INT_Clear(USB_INT_VBERRI);
|
||||
USB_INT_Enable(USB_INT_VBERRI);
|
||||
|
||||
USB_Host_ResumeBus();
|
||||
Pipe_ClearPipes();
|
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset);
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_STATE_Powered_DoReset:
|
||||
USB_Host_ResetDevice();
|
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe);
|
||||
break;
|
||||
case HOST_STATE_Powered_ConfigPipe:
|
||||
if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, PIPE_CONTROLPIPE_DEFAULT_SIZE, 1)))
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_PipeConfigError;
|
||||
SubErrorCode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
USB_HostState = HOST_STATE_Default;
|
||||
break;
|
||||
case HOST_STATE_Default:
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (DTYPE_Device << 8),
|
||||
.wIndex = 0,
|
||||
.wLength = 8,
|
||||
};
|
||||
|
||||
uint8_t DataBuffer[8];
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_ControlError;
|
||||
break;
|
||||
}
|
||||
|
||||
USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
|
||||
|
||||
USB_Host_ResetDevice();
|
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset);
|
||||
break;
|
||||
case HOST_STATE_Default_PostReset:
|
||||
if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, USB_Host_ControlPipeSize, 1)))
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_PipeConfigError;
|
||||
SubErrorCode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_SetAddress,
|
||||
.wValue = USB_HOST_DEVICEADDRESS,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
if ((SubErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_ControlError;
|
||||
break;
|
||||
}
|
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet);
|
||||
break;
|
||||
case HOST_STATE_Default_PostAddressSet:
|
||||
USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);
|
||||
|
||||
USB_HostState = HOST_STATE_Addressed;
|
||||
|
||||
EVENT_USB_Host_DeviceEnumerationComplete();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached))
|
||||
{
|
||||
EVENT_USB_Host_DeviceEnumerationFailed(ErrorCode, SubErrorCode);
|
||||
|
||||
USB_Host_VBUS_Auto_Off();
|
||||
|
||||
EVENT_USB_Host_DeviceUnattached();
|
||||
|
||||
USB_ResetInterface();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t USB_Host_WaitMS(uint8_t MS)
|
||||
{
|
||||
bool BusSuspended = USB_Host_IsBusSuspended();
|
||||
uint8_t ErrorCode = HOST_WAITERROR_Successful;
|
||||
bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
|
||||
|
||||
USB_INT_Disable(USB_INT_HSOFI);
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
|
||||
USB_Host_ResumeBus();
|
||||
|
||||
while (MS)
|
||||
{
|
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
MS--;
|
||||
}
|
||||
|
||||
if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode != USB_MODE_Host))
|
||||
{
|
||||
ErrorCode = HOST_WAITERROR_DeviceDisconnect;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (Pipe_IsError())
|
||||
{
|
||||
Pipe_ClearError();
|
||||
ErrorCode = HOST_WAITERROR_PipeError;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (Pipe_IsStalled())
|
||||
{
|
||||
Pipe_ClearStall();
|
||||
ErrorCode = HOST_WAITERROR_SetupStalled;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (BusSuspended)
|
||||
USB_Host_SuspendBus();
|
||||
|
||||
if (HSOFIEnabled)
|
||||
USB_INT_Enable(USB_INT_HSOFI);
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
static void USB_Host_ResetDevice(void)
|
||||
{
|
||||
bool BusSuspended = USB_Host_IsBusSuspended();
|
||||
|
||||
USB_INT_Disable(USB_INT_DDISCI);
|
||||
|
||||
USB_Host_ResetBus();
|
||||
while (!(USB_Host_IsBusResetComplete()));
|
||||
USB_Host_ResumeBus();
|
||||
|
||||
USB_Host_ConfigurationNumber = 0;
|
||||
|
||||
bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
|
||||
|
||||
USB_INT_Disable(USB_INT_HSOFI);
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
|
||||
for (uint8_t MSRem = 10; MSRem != 0; MSRem--)
|
||||
{
|
||||
/* Workaround for powerless-pull-up devices. After a USB bus reset,
|
||||
all disconnection interrupts are suppressed while a USB frame is
|
||||
looked for - if it is found within 10ms, the device is still
|
||||
present. */
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
USB_INT_Clear(USB_INT_DDISCI);
|
||||
break;
|
||||
}
|
||||
|
||||
Delay_MS(1);
|
||||
}
|
||||
|
||||
if (HSOFIEnabled)
|
||||
USB_INT_Enable(USB_INT_HSOFI);
|
||||
|
||||
if (BusSuspended)
|
||||
USB_Host_SuspendBus();
|
||||
|
||||
USB_INT_Enable(USB_INT_DDISCI);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
372
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h
Normal file
372
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief USB Host definitions for the AVR8 microcontrollers.
|
||||
* \copydetails Group_Host_AVR8
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB driver
|
||||
* dispatch header located in LUFA/Drivers/USB/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Host
|
||||
* \defgroup Group_Host_AVR8 Host Management (AVR8)
|
||||
* \brief USB Host definitions for the AVR8 microcontrollers.
|
||||
*
|
||||
* Architecture specific USB Host definitions for the Atmel 8-bit AVR microcontrollers.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __USBHOST_AVR8_H__
|
||||
#define __USBHOST_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../../Common/Common.h"
|
||||
#include "../StdDescriptors.h"
|
||||
#include "../Pipe.h"
|
||||
#include "../USBInterrupt.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
|
||||
#endif
|
||||
|
||||
#if defined(INVERTED_VBUS_ENABLE_LINE) && !defined(NO_AUTO_VBUS_MANAGEMENT)
|
||||
#error The INVERTED_VBUS_ENABLE_LINE compile option requires NO_AUTO_VBUS_MANAGEMENT for the AVR8 architecture.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Indicates the fixed USB device address which any attached device is enumerated to when in
|
||||
* host mode. As only one USB device may be attached to the AVR in host mode at any one time
|
||||
* and that the address used is not important (other than the fact that it is non-zero), a
|
||||
* fixed value is specified by the library.
|
||||
*/
|
||||
#define USB_HOST_DEVICEADDRESS 1
|
||||
|
||||
#if !defined(HOST_DEVICE_SETTLE_DELAY_MS) || defined(__DOXYGEN__)
|
||||
/** Constant for the delay in milliseconds after a device is connected before the library
|
||||
* will start the enumeration process. Some devices require a delay of up to 5 seconds
|
||||
* after connection before the enumeration process can start or incorrect operation will
|
||||
* occur.
|
||||
*
|
||||
* The default delay value may be overridden in the user project makefile by defining the
|
||||
* \c HOST_DEVICE_SETTLE_DELAY_MS token to the required delay in milliseconds, and passed to the
|
||||
* compiler using the -D switch.
|
||||
*/
|
||||
#define HOST_DEVICE_SETTLE_DELAY_MS 1000
|
||||
#endif
|
||||
|
||||
/** Enum for the error codes for the \ref EVENT_USB_Host_HostError() event.
|
||||
*
|
||||
* \see \ref Group_Events for more information on this event.
|
||||
*/
|
||||
enum USB_Host_ErrorCodes_t
|
||||
{
|
||||
HOST_ERROR_VBusVoltageDip = 0, /**< VBUS voltage dipped to an unacceptable level. This
|
||||
* error may be the result of an attached device drawing
|
||||
* too much current from the VBUS line, or due to the
|
||||
* AVR's power source being unable to supply sufficient
|
||||
* current.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the error codes for the \ref EVENT_USB_Host_DeviceEnumerationFailed() event.
|
||||
*
|
||||
* \see \ref Group_Events for more information on this event.
|
||||
*/
|
||||
enum USB_Host_EnumerationErrorCodes_t
|
||||
{
|
||||
HOST_ENUMERROR_NoError = 0, /**< No error occurred. Used internally, this is not a valid
|
||||
* ErrorCode parameter value for the \ref EVENT_USB_Host_DeviceEnumerationFailed()
|
||||
* event.
|
||||
*/
|
||||
HOST_ENUMERROR_WaitStage = 1, /**< One of the delays between enumeration steps failed
|
||||
* to complete successfully, due to a timeout or other
|
||||
* error.
|
||||
*/
|
||||
HOST_ENUMERROR_NoDeviceDetected = 2, /**< No device was detected, despite the USB data lines
|
||||
* indicating the attachment of a device.
|
||||
*/
|
||||
HOST_ENUMERROR_ControlError = 3, /**< One of the enumeration control requests failed to
|
||||
* complete successfully.
|
||||
*/
|
||||
HOST_ENUMERROR_PipeConfigError = 4, /**< The default control pipe (address 0) failed to
|
||||
* configure correctly.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Returns the current USB frame number, when in host mode. Every millisecond the USB bus is active (i.e. not suspended)
|
||||
* the frame number is incremented by one.
|
||||
*
|
||||
* \return Current USB frame number from the USB controller.
|
||||
*/
|
||||
static inline uint16_t USB_Host_GetFrameNumber(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint16_t USB_Host_GetFrameNumber(void)
|
||||
{
|
||||
return UHFNUM;
|
||||
}
|
||||
|
||||
#if !defined(NO_SOF_EVENTS)
|
||||
/** Enables the host mode Start Of Frame events. When enabled, this causes the
|
||||
* \ref EVENT_USB_Host_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus,
|
||||
* at the start of each USB frame when a device is enumerated while in host mode.
|
||||
*
|
||||
* \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined.
|
||||
*/
|
||||
static inline void USB_Host_EnableSOFEvents(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_EnableSOFEvents(void)
|
||||
{
|
||||
USB_INT_Enable(USB_INT_HSOFI);
|
||||
}
|
||||
|
||||
/** Disables the host mode Start Of Frame events. When disabled, this stops the firing of the
|
||||
* \ref EVENT_USB_Host_StartOfFrame() event when enumerated in host mode.
|
||||
*
|
||||
* \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined.
|
||||
*/
|
||||
static inline void USB_Host_DisableSOFEvents(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_DisableSOFEvents(void)
|
||||
{
|
||||
USB_INT_Disable(USB_INT_HSOFI);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host.
|
||||
* USB bus resets leave the default control pipe configured (if already configured).
|
||||
*
|
||||
* If the USB bus has been suspended prior to issuing a bus reset, the attached device will be
|
||||
* woken up automatically and the bus resumed after the reset has been correctly issued.
|
||||
*/
|
||||
static inline void USB_Host_ResetBus(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_ResetBus(void)
|
||||
{
|
||||
UHCON |= (1 << RESET);
|
||||
}
|
||||
|
||||
/** Determines if a previously issued bus reset (via the \ref USB_Host_ResetBus() macro) has
|
||||
* completed.
|
||||
*
|
||||
* \return Boolean \c true if no bus reset is currently being sent, \c false otherwise.
|
||||
*/
|
||||
static inline bool USB_Host_IsBusResetComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool USB_Host_IsBusResetComplete(void)
|
||||
{
|
||||
return ((UHCON & (1 << RESET)) ? false : true);
|
||||
}
|
||||
|
||||
/** Resumes USB communications with an attached and enumerated device, by resuming the transmission
|
||||
* of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the
|
||||
* host and attached device may occur.
|
||||
*/
|
||||
static inline void USB_Host_ResumeBus(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_ResumeBus(void)
|
||||
{
|
||||
UHCON |= (1 << SOFEN);
|
||||
}
|
||||
|
||||
/** Suspends the USB bus, preventing any communications from occurring between the host and attached
|
||||
* device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
|
||||
* messages to the device.
|
||||
*
|
||||
* \attention While the USB bus is suspended, all USB interrupt sources are also disabled; this means that
|
||||
* some events (such as device disconnections) will not fire until the bus is resumed.
|
||||
*/
|
||||
static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_SuspendBus(void)
|
||||
{
|
||||
UHCON &= ~(1 << SOFEN);
|
||||
}
|
||||
|
||||
/** Determines if the USB bus has been suspended via the use of the \ref USB_Host_SuspendBus() macro,
|
||||
* false otherwise. While suspended, no USB communications can occur until the bus is resumed,
|
||||
* except for the Remote Wakeup event from the device if supported.
|
||||
*
|
||||
* \return Boolean \c true if the bus is currently suspended, \c false otherwise.
|
||||
*/
|
||||
static inline bool USB_Host_IsBusSuspended(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool USB_Host_IsBusSuspended(void)
|
||||
{
|
||||
return ((UHCON & (1 << SOFEN)) ? false : true);
|
||||
}
|
||||
|
||||
/** Determines if the attached device is currently enumerated in Full Speed mode (12Mb/s), or
|
||||
* false if the attached device is enumerated in Low Speed mode (1.5Mb/s).
|
||||
*
|
||||
* \return Boolean \c true if the attached device is enumerated in Full Speed mode, \c false otherwise.
|
||||
*/
|
||||
static inline bool USB_Host_IsDeviceFullSpeed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool USB_Host_IsDeviceFullSpeed(void)
|
||||
{
|
||||
return ((USBSTA & (1 << SPEED)) ? true : false);
|
||||
}
|
||||
|
||||
/** Determines if the attached device is currently issuing a Remote Wakeup request, requesting
|
||||
* that the host resume the USB bus and wake up the device, \c false otherwise.
|
||||
*
|
||||
* \return Boolean \c true if the attached device has sent a Remote Wakeup request, \c false otherwise.
|
||||
*/
|
||||
static inline bool USB_Host_IsRemoteWakeupSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool USB_Host_IsRemoteWakeupSent(void)
|
||||
{
|
||||
return ((UHINT & (1 << RXRSMI)) ? true : false);
|
||||
}
|
||||
|
||||
/** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */
|
||||
static inline void USB_Host_ClearRemoteWakeupSent(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_ClearRemoteWakeupSent(void)
|
||||
{
|
||||
UHINT &= ~(1 << RXRSMI);
|
||||
}
|
||||
|
||||
/** Accepts a Remote Wakeup request from an attached device. This must be issued in response to
|
||||
* a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to
|
||||
* be resumed.
|
||||
*/
|
||||
static inline void USB_Host_ResumeFromWakeupRequest(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_ResumeFromWakeupRequest(void)
|
||||
{
|
||||
UHCON |= (1 << RESUME);
|
||||
}
|
||||
|
||||
/** Determines if a resume from Remote Wakeup request is currently being sent to an attached
|
||||
* device.
|
||||
*
|
||||
* \return Boolean \c true if no resume request is currently being sent, \c false otherwise.
|
||||
*/
|
||||
static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool USB_Host_IsResumeFromWakeupRequestSent(void)
|
||||
{
|
||||
return ((UHCON & (1 << RESUME)) ? false : true);
|
||||
}
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
static inline void USB_Host_HostMode_On(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_HostMode_On(void)
|
||||
{
|
||||
USBCON |= (1 << HOST);
|
||||
}
|
||||
|
||||
static inline void USB_Host_HostMode_Off(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_HostMode_Off(void)
|
||||
{
|
||||
USBCON &= ~(1 << HOST);
|
||||
}
|
||||
|
||||
static inline void USB_Host_VBUS_Auto_Enable(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_VBUS_Auto_Enable(void)
|
||||
{
|
||||
OTGCON &= ~(1 << VBUSHWC);
|
||||
UHWCON |= (1 << UVCONE);
|
||||
}
|
||||
|
||||
static inline void USB_Host_VBUS_Manual_Enable(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_VBUS_Manual_Enable(void)
|
||||
{
|
||||
OTGCON |= (1 << VBUSHWC);
|
||||
UHWCON &= ~(1 << UVCONE);
|
||||
|
||||
DDRE |= (1 << 7);
|
||||
}
|
||||
|
||||
static inline void USB_Host_VBUS_Auto_On(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_VBUS_Auto_On(void)
|
||||
{
|
||||
OTGCON |= (1 << VBUSREQ);
|
||||
}
|
||||
|
||||
static inline void USB_Host_VBUS_Manual_On(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_VBUS_Manual_On(void)
|
||||
{
|
||||
#if defined(INVERTED_VBUS_ENABLE_LINE)
|
||||
PORTE &= ~(1 << 7);
|
||||
#else
|
||||
PORTE |= (1 << 7);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void USB_Host_VBUS_Auto_Off(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_VBUS_Auto_Off(void)
|
||||
{
|
||||
OTGCON |= (1 << VBUSRQC);
|
||||
}
|
||||
|
||||
static inline void USB_Host_VBUS_Manual_Off(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_VBUS_Manual_Off(void)
|
||||
{
|
||||
#if defined(INVERTED_VBUS_ENABLE_LINE)
|
||||
PORTE |= (1 << 7);
|
||||
#else
|
||||
PORTE &= ~(1 << 7);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void USB_Host_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_SetDeviceAddress(const uint8_t Address)
|
||||
{
|
||||
UHADDR = (Address & 0x7F);
|
||||
}
|
||||
|
||||
/* Enums: */
|
||||
enum USB_Host_WaitMSErrorCodes_t
|
||||
{
|
||||
HOST_WAITERROR_Successful = 0,
|
||||
HOST_WAITERROR_DeviceDisconnect = 1,
|
||||
HOST_WAITERROR_PipeError = 2,
|
||||
HOST_WAITERROR_SetupStalled = 3,
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
void USB_Host_ProcessNextHostState(void);
|
||||
uint8_t USB_Host_WaitMS(uint8_t MS);
|
||||
|
||||
#if defined(__INCLUDE_FROM_HOST_C)
|
||||
static void USB_Host_ResetDevice(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
159
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h
Normal file
159
H2003-V1_USB_PWM/src/LUFA/LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief USB OTG definitions for the AVR8 microcontrollers.
|
||||
* \copydetails Group_OTG_AVR8
|
||||
*
|
||||
* \note This file should not be included directly. It is automatically included as needed by the USB driver
|
||||
* dispatch header located in LUFA/Drivers/USB/USB.h.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_OTG
|
||||
* \defgroup Group_OTG_AVR8 USB On The Go (OTG) Management (AVR8)
|
||||
* \brief USB OTG definitions for the AVR8 microcontrollers.
|
||||
*
|
||||
* Architecture specific USB OTG definitions for the Atmel 8-bit AVR microcontrollers.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __USBOTG_AVR8_H__
|
||||
#define __USBOTG_AVR8_H__
|
||||
|
||||
/* Includes: */
|
||||
#include "../../../../Common/Common.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Mask for the VBUS pulsing method of SRP, supported by some OTG devices.
|
||||
*
|
||||
* \see \ref USB_OTG_Device_InitiateSRP().
|
||||
*/
|
||||
#define USB_OTG_SRP_VBUS (1 << SRPSEL)
|
||||
|
||||
/** Mask for the Data + pulsing method of SRP, supported by some OTG devices.
|
||||
*
|
||||
* \see \ref USB_OTG_Device_InitiateSRP().
|
||||
*/
|
||||
#define USB_OTG_STP_DATA 0
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Initiate a Host Negotiation Protocol request. This indicates to the other connected device
|
||||
* that the device wishes to change device/host roles.
|
||||
*/
|
||||
static inline void USB_OTG_Device_RequestHNP(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_OTG_Device_RequestHNP(void)
|
||||
{
|
||||
OTGCON |= (1 << HNPREQ);
|
||||
}
|
||||
|
||||
/** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other
|
||||
* connected device.
|
||||
*/
|
||||
static inline void USB_OTG_Device_CancelHNPRequest(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_OTG_Device_CancelHNPRequest(void)
|
||||
{
|
||||
OTGCON &= ~(1 << HNPREQ);
|
||||
}
|
||||
|
||||
/** Determines if the device is currently sending a HNP to an attached host.
|
||||
*
|
||||
* \return Boolean \c true if currently sending a HNP to the other connected device, \c false otherwise
|
||||
*/
|
||||
static inline bool USB_OTG_Device_IsSendingHNP(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool USB_OTG_Device_IsSendingHNP(void)
|
||||
{
|
||||
return ((OTGCON & (1 << HNPREQ)) ? true : false);
|
||||
}
|
||||
|
||||
/** Initiates a Session Request Protocol request. Most OTG devices turn off VBUS when the USB
|
||||
* interface is not in use, to conserve power. Sending a SRP to a USB OTG device running in
|
||||
* host mode indicates that VBUS should be applied and a session started.
|
||||
*
|
||||
* There are two different methods of sending a SRP - either pulses on the VBUS line, or by
|
||||
* pulsing the Data + line via the internal pull-up resistor.
|
||||
*
|
||||
* \param[in] SRPTypeMask Mask indicating the type of SRP to use, either \ref USB_OTG_SRP_VBUS or
|
||||
* \ref USB_OTG_STP_DATA.
|
||||
*/
|
||||
static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask)
|
||||
{
|
||||
OTGCON = ((OTGCON & ~(1 << SRPSEL)) | (SRPTypeMask | (1 << SRPREQ)));
|
||||
}
|
||||
|
||||
/** Accepts a HNP from a connected device, indicating that both devices should exchange
|
||||
* device/host roles.
|
||||
*/
|
||||
static inline void USB_OTG_Host_AcceptHNP(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_OTG_Host_AcceptHNP(void)
|
||||
{
|
||||
OTGCON |= (1 << HNPREQ);
|
||||
}
|
||||
|
||||
/** Rejects a HNP from a connected device, indicating that both devices should remain in their
|
||||
* current device/host roles.
|
||||
*/
|
||||
static inline void USB_OTG_Host_RejectHNP(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_OTG_Host_RejectHNP(void)
|
||||
{
|
||||
OTGCON &= ~(1 << HNPREQ);
|
||||
}
|
||||
|
||||
/** Indicates if the connected device is currently sending a HNP request.
|
||||
*
|
||||
* \return Boolean \c true if a HNP is currently being issued by the connected device, \c false otherwise.
|
||||
*/
|
||||
static inline bool USB_OTG_Host_IsHNPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool USB_OTG_Host_IsHNPReceived(void)
|
||||
{
|
||||
return ((OTGCON & (1 << HNPREQ)) ? true : false);
|
||||
}
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user