summaryrefslogtreecommitdiff
path: root/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII')
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.c156
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.h91
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.txt385
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.c302
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.h128
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/AppConfig.h70
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/LUFAConfig.h93
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c531
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.h81
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c370
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h147
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.c267
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.h105
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolConstants.h90
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c207
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h91
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c274
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h86
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c468
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h140
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c480
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h136
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c209
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h136
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/asf.xml90
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/doxyfile2364
-rw-r--r--tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/makefile39
27 files changed, 7536 insertions, 0 deletions
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.c
new file mode 100644
index 000000000..9cff5b421
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.c
@@ -0,0 +1,156 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 AVRISP project. This file contains the main tasks of
+ * the project and is responsible for the initial application hardware configuration.
+ */
+
+#include "AVRISP-MKII.h"
+
+/** 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();
+ V2Protocol_Init();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+ GlobalInterruptEnable();
+
+ for (;;)
+ {
+ #if (BOARD == BOARD_USBTINYMKII)
+ /* On the USBTINY-MKII target, there is a secondary LED which indicates the current selected power
+ mode - either VBUS, or sourced from the VTARGET pin of the programming connectors */
+ LEDs_ChangeLEDs(LEDMASK_VBUSPOWER, (PIND & (1 << 0)) ? 0 : LEDMASK_VBUSPOWER);
+ #endif
+
+ AVRISP_Task();
+ USB_USBTask();
+ }
+}
+
+/** Configures the board hardware and chip peripherals for the demo's functionality. */
+void SetupHardware(void)
+{
+#if (ARCH == ARCH_AVR8)
+ /* Disable watchdog if enabled by bootloader/fuses */
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ /* Disable clock division */
+ clock_prescale_set(clock_div_1);
+#endif
+
+ /* Hardware Initialization */
+ LEDs_Init();
+ #if defined(RESET_TOGGLES_LIBUSB_COMPAT)
+ UpdateCurrentCompatibilityMode();
+ #endif
+
+ /* USB Stack 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;
+
+ /* Setup AVRISP Data OUT endpoint */
+ ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_OUT_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1);
+
+ /* Setup AVRISP Data IN endpoint if it is using a physically different endpoint */
+ if ((AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK) != (AVRISP_DATA_OUT_EPADDR & ENDPOINT_EPNUM_MASK))
+ ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1);
+
+ /* Indicate endpoint configuration success or failure */
+ LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
+}
+
+/** Processes incoming V2 Protocol commands from the host, returning a response when required. */
+void AVRISP_Task(void)
+{
+ /* Device must be connected and configured for the task to run */
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return;
+
+ V2Params_UpdateParamValues();
+
+ Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPADDR);
+
+ /* Check to see if a V2 Protocol command has been received */
+ if (Endpoint_IsOUTReceived())
+ {
+ LEDs_SetAllLEDs(LEDMASK_BUSY);
+
+ /* Pass off processing of the V2 Protocol command to the V2 Protocol handler */
+ V2Protocol_ProcessCommand();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
+ }
+}
+
+/** 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.
+ *
+ * \param[in] wValue Descriptor type and index to retrieve
+ * \param[in] wIndex Sub-index to retrieve (such as a localized string language)
+ * \param[out] DescriptorAddress Address of the retrieved descriptor
+ * \param[out] DescriptorMemorySpace Memory space that the descriptor is stored in
+ *
+ * \return Length of the retrieved descriptor in bytes, or NO_DESCRIPTOR if the descriptor was not found
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress,
+ uint8_t* DescriptorMemorySpace)
+{
+ return AVRISP_GetDescriptor(wValue, wIndex, DescriptorAddress, DescriptorMemorySpace);
+}
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.h
new file mode 100644
index 000000000..70f86f41c
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.h
@@ -0,0 +1,91 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 AVRISP.c.
+ */
+
+#ifndef _AVRISP_H_
+#define _AVRISP_H_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/wdt.h>
+ #include <avr/interrupt.h>
+ #include <avr/power.h>
+
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Platform/Platform.h>
+
+ #if defined(ADC)
+ #include <LUFA/Drivers/Peripheral/ADC.h>
+ #endif
+
+ #include "AVRISPDescriptors.h"
+ #include "Lib/V2Protocol.h"
+ #include "Config/AppConfig.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_LED1 | LEDS_LED2)
+
+ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
+ #define LEDMASK_USB_READY LEDS_LED2
+
+ /** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
+ #define LEDMASK_USB_ERROR LEDS_LED1
+
+ /** LED mask for the library LED driver, to indicate that the USB interface is busy. */
+ #define LEDMASK_BUSY (LEDS_LED1 | LEDS_LED2)
+
+ /** LED mask for the library LED driver, to indicate that the target is being powered by VBUS. */
+ #define LEDMASK_VBUSPOWER LEDS_LED3
+
+ /* Function Prototypes: */
+ void SetupHardware(void);
+ void AVRISP_Task(void);
+
+ void EVENT_USB_Device_Connect(void);
+ void EVENT_USB_Device_Disconnect(void);
+ void EVENT_USB_Device_ConfigurationChanged(void);
+
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress,
+ uint8_t* const DescriptorMemorySpace)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3) ATTR_NON_NULL_PTR_ARG(4);
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.txt b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.txt
new file mode 100644
index 000000000..71ef387a1
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISP-MKII.txt
@@ -0,0 +1,385 @@
+/** \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 AVRISP MKII Programmer Project
+ *
+ * \section Sec_Compat Project Compatibility
+ *
+ * The following list indicates what microcontrollers are compatible with this project.
+ *
+ * \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) - <i>8KB versions with reduced features only</i>
+ *
+ * \section Sec_Info USB Information
+ *
+ * The following table gives a rundown of the USB utilization of this project.
+ *
+ * <table>
+ * <tr>
+ * <td><b>USB Mode:</b></td>
+ * <td>Device</td>
+ * </tr>
+ * <tr>
+ * <td><b>USB Class:</b></td>
+ * <td>Vendor Specific Class</td>
+ * </tr>
+ * <tr>
+ * <td><b>USB Subclass:</b></td>
+ * <td>N/A</td>
+ * </tr>
+ * <tr>
+ * <td><b>Relevant Standards:</b></td>
+ * <td>Atmel AVRISP MKII Protocol Specification</td>
+ * </tr>
+ * <tr>
+ * <td><b>Supported USB Speeds:</b></td>
+ * <td>Full Speed Mode</td>
+ * </tr>
+ * </table>
+ *
+ * \section Sec_Description Project Description
+ *
+ * Firmware for an Atmel Studio/AVR Studio compatible AVRISP-MKII clone programmer. This project will enable the USB
+ * AVR series of microcontrollers to act as a clone of the official Atmel AVRISP-MKII programmer, usable within
+ * Atmel Studio/AVR Studio or with any software capable of driving a real Atmel AVRISP-MKII programmer. In its most
+ * basic form, it allows for the programming of AVR TINY, MEGA and XMEGA devices aat the programmer's VCC voltage from
+ * within Atmel Studio/AVR Studio with no special hardware other than the USB AVR and the parts needed for the USB
+ * interface. If the user desires, more advanced circuits incorporating level conversion can be made to allow for the
+ * programming of target AVRs running at a different voltage to the programmer.
+ *
+ * This device spoofs Atmel's official AVRISP-MKII device PID so that it remains compatible with Atmel's AVRISP-MKII
+ * drivers. When prompted, direct your OS to install Atmel's AVRISP-MKII drivers provided with Atmel Studio/AVR Studio.
+ *
+ * Note that this design currently has the following limitations:
+ * - No reversed/shorted target connector detection and notification
+ * - A separate header is required for each of the ISP, PDI and TPI programming protocols that the user wishes to use
+ *
+ * On AVR models with an ADC converter, the USB AVR's AVCC pin should be tied to 5V (e.g. VBUS) and the
+ * \c VTARGET_ADC_CHANNEL token should be set to an appropriate ADC channel number in the project makefile for VTARGET
+ * detection to operate correctly. On models without an ADC converter, VTARGET will report a fixed 3.3V level at all times
+ * which should allow the programmer to remain compatible at the protocol level with all AVR devices.
+ *
+ * While this application can be compiled for USB AVRs with as little as 8KB of FLASH, for full functionality 16KB or more
+ * of FLASH is required. On 8KB devices, ISP or PDI/TPI protocol programming support can be disabled to reduce program size.
+ *
+ * \section Sec_KnownIssues Known Issues:
+ *
+ * \par Incompatible with newer AVRDUDE releases.
+ * Due to <a href="http://savannah.nongnu.org/bugs/index.php?40831">a change in 6.0.1 and never AVRDUDE releases</a>,
+ * these builds are incompatible with the AVRISP-MKII clone project. Use an older 5.x release until AVRDUDE is patched.
+ *
+ * \par XMEGA EEPROM programming fails in some cases.
+ * Several users have reported that XMEGA EEPROM programming fails unless the chip is erased first. If a non-blank EEPROM
+ * is present, writing further EEPROM data causes corruption.
+ * <a href="https://github.com/abcminiuser/lufa/issues/25">LUFA issue tracker entry</a>.
+ *
+ * \section Sec_Installation Installation
+ * The programmer supports multiple platforms, both Windows and Linux.
+ *
+ * \subsection SSec_LinuxInstallation Linux Installation
+ * On Linux systems, the programmer should be usable out of the box with no special setup other than (on some systems)
+ * editing of the system permissions to allow the programmer to be used from a non-elevated (root) context. The programmer
+ * is compatible with the free open source AVRDude programming software project.
+ *
+ * \subsection SSec_WindowsInstallation Windows Installation
+ * On Windows systems, due to an unfortunate limitation of the USB AVR devices and the driver used in the official AVR
+ * Studio/Atmel Studio platform, the programmer cannot be made compatible with AVRDude and AVR Studio/Atmel Studio at the
+ * same time. Instead, the programmer will be compatible with the official Atmel software by default, with a recompilation
+ * with the \c LIBUSB_DRIVER_COMPAT token (see \ref Sec_Options) being required to use the alternative libUSB driver
+ * compatibility mode that will allow the programmer to work under AVRDude on Windows.
+ *
+ * If compiled for Atmel Studio/AVR Studio compatibility, install the Jungo device drivers that ship with the Atmel software.
+ * If compiled in the alternative libUSB compatibility mode for AVRDude use, install the libUSB drivers that are included
+ * with your compiled copy of AVRDude, or create them using the libUSB-Win32 (http://sourceforge.net/projects/libusb-win32)
+ * project.
+ *
+ * For convenience, the programmer will report two different serial numbers depending on the firmware compatibility mode, so
+ * that the correct driver can be installed for the matching firmware. If the \c RESET_TOGGLES_LIBUSB_COMPAT compile option
+ * is used (see \ref Sec_Options) this allows for an easy way to automatically switch device drivers along with the firmware
+ * compatibility mode. The serials are:
+ *
+ * <table>
+ * <tr>
+ * <th><b>Serial Number:</b></th>
+ * <th><b>Compatibility Mode:</b></th>
+ * </tr>
+ * <tr>
+ * <td>000200012345</td>
+ * <td>Jungo (Atmel Studio) Compatibility</td>
+ * </tr>
+ * <tr>
+ * <td>000200112345</td>
+ * <td>libUSB Compatibility</td>
+ * </tr>
+ * </table>
+ *
+ * \section Sec_ISP ISP Connections
+ * Connections to the device for SPI programming (when enabled):
+ *
+ * <table>
+ * <tr>
+ * <th><b>Programmer Pin:</b></th>
+ * <th><b>Target Device Pin:</b></th>
+ * <th><b>ISP 6 Pin Layout:</b></th>
+ * </tr>
+ * <tr>
+ * <td>MISO</td>
+ * <td>PDO</td>
+ * <td>1</td>
+ * </tr>
+ * <tr>
+ * <td>ADCx <b><sup>1</sup></b></td>
+ * <td>VTARGET</td>
+ * <td>2</td>
+ * </tr>
+ * <tr>
+ * <td>SCLK</td>
+ * <td>SCLK</td>
+ * <td>3</td>
+ * </tr>
+ * <tr>
+ * <td>MOSI</td>
+ * <td>PDI</td>
+ * <td>4</td>
+ * </tr>
+ * <tr>
+ * <td>PORTx.y <b><sup>2</sup></b></td>
+ * <td>/RESET</td>
+ * <td>5</td>
+ * </tr>
+ * <tr>
+ * <td>GND</td>
+ * <td>GND</td>
+ * <td>6</td>
+ * </tr>
+ * </table>
+ *
+ * In addition, the AVR's OCR1A pin will generate a 4MHz clock, to act as an external rescue device clock if the
+ * fuses have been mis-set. To use the recovery clock, connect the OCR1A pin of the USB AVR to the target AVR's
+ * XTAL1 pin, and set the ISP programming speed to 125KHz (note: other ISP speeds will not work correctly).
+ *
+ * <b><sup>1</sup></b> <i>Optional, see \ref Sec_Options section - for USB AVRs with ADC modules only</i> \n
+ * <b><sup>2</sup></b> <i>See AUX line related tokens in the \ref Sec_Options section</i>
+ *
+ * \section Sec_PDI PDI Connections
+ * Connections to the device for PDI programming (when enabled):
+ *
+ * <table>
+ * <tr>
+ * <th><b>Programmer Pin:</b></th>
+ * <th><b>Target Device Pin:</b></th>
+ * <th><b>PDI 6 Pin Layout:</b></th>
+ * </tr>
+ * <tr>
+ * <td>Tx/Rx <b><sup>2</sup></b></td>
+ * <td>DATA</td>
+ * <td>1</td>
+ * </tr>
+ * <tr>
+ * <td>ADCx <b><sup>1</sup></b></td>
+ * <td>VTARGET</td>
+ * <td>2</td>
+ * </tr>
+ * <tr>
+ * <td>N/A</td>
+ * <td>N/A</td>
+ * <td>3</td>
+ * </tr>
+ * <tr>
+ * <td>N/A</td>
+ * <td>N/A</td>
+ * <td>4</td>
+ * </tr>
+ * <tr>
+ * <td>XCK</td>
+ * <td>CLOCK</td>
+ * <td>5</td>
+ * </tr>
+ * <tr>
+ * <td>GND</td>
+ * <td>GND</td>
+ * <td>6</td>
+ * </tr>
+ * </table>
+ *
+ * <b><sup>1</sup></b> <i>Optional, see \ref Sec_Options section - for USB AVRs with ADC modules only</i> \n
+ * <b><sup>2</sup></b> <i>The AVR's Tx and Rx become the DATA line when connected together via a pair of 220 ohm resistors</i> \n
+ *
+ * \section Sec_TPI TPI Connections
+ * Connections to the device for TPI programming (when enabled):
+ *
+ * <table>
+ * <tr>
+ * <th><b>Programmer Pin:</b></th>
+ * <th><b>Target Device Pin:</b></th>
+ * <th><b>TPI 6 Pin Layout:</b></th>
+ * </tr>
+ * <tr>
+ * <td>Tx/Rx <b><sup>2</sup></b></td>
+ * <td>DATA</td>
+ * <td>1</td>
+ * </tr>
+ * <tr>
+ * <td>ADCx <b><sup>1</sup></b></td>
+ * <td>VTARGET</td>
+ * <td>2</td>
+ * </tr>
+ * <tr>
+ * <td>XCK <b><sup>2</sup></b></td>
+ * <td>CLOCK</td>
+ * <td>3</td>
+ * </tr>
+ * <tr>
+ * <td>N/A</td>
+ * <td>N/A</td>
+ * <td>4</td>
+ * </tr>
+ * <tr>
+ * <td>PORTx.y <b><sup>3</sup></b></td>
+ * <td>/RESET</td>
+ * <td>5</td>
+ * </tr>
+ * <tr>
+ * <td>GND</td>
+ * <td>GND</td>
+ * <td>6</td>
+ * </tr>
+ * </table>
+ *
+ * <b><sup>1</sup></b> <i>Optional, see \ref Sec_Options section - for USB AVRs with ADC modules only</i> \n
+ * <b><sup>2</sup></b> <i>The AVR's Tx and Rx become the DATA line when connected together via a pair of 220 ohm resistors</i> \n
+ * <b><sup>3</sup></b> <i>See AUX line related tokens in the \ref Sec_Options section</i>
+ *
+ * \section Sec_Options Project Options
+ *
+ * The following defines can be found in this project, which can control the project 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>AUX_LINE_PORT</td>
+ * <td>AppConfig.h</td>
+ * <td>PORT register for the programmer's AUX target line. The use of this line varies between the programming protocols,
+ * but is generally used for the target's /RESET line.
+ * \n \n <i>Ignored when compiled for the XPLAIN board.</i></td>
+ * </tr>
+ * <tr>
+ * <td>AUX_LINE_PIN</td>
+ * <td>AppConfig.h</td>
+ * <td>PIN register for the programmer's AUX target line. The use of this line varies between the programming protocols,
+ * but is generally used for the target's /RESET line.
+ * \n \n <i>Ignored when compiled for the XPLAIN board.</i></td>
+ * </tr>
+ * <tr>
+ * <td>AUX_LINE_DDR</td>
+ * <td>AppConfig.h</td>
+ * <td>DDR register for the programmer's AUX target line. The use of this line varies between the programming protocols,
+ * but is generally used for the target's /RESET line.
+ * \n \n <i>Ignored when compiled for the XPLAIN board.</i></td>
+ * </tr>
+ * <tr>
+ * <td>AUX_LINE_MASK</td>
+ * <td>AppConfig.h</td>
+ * <td>Mask for the programmer's AUX target line. The use of this line varies between the programming protocols,
+ * but is generally used for the target's /RESET line. <b>Must not be the AVR's /SS pin</b>.
+ * \n \n <i>Ignored when compiled for the XPLAIN board.</i></td>
+ * </tr>
+ * <tr>
+ * <td>VTARGET_ADC_CHANNEL</td>
+ * <td>AppConfig.h</td>
+ * <td>ADC channel number (on supported AVRs) to use for VTARGET level detection, if NO_VTARGET_DETECT is not defined.
+ * \n \n <i>Ignored when compiled for targets lacking an ADC.</i></td>
+ * </tr>
+ * <tr>
+ * <td>ENABLE_ISP_PROTOCOL</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to enable SPI programming protocol support.
+ * \n \n <i>Ignored when compiled for the XPLAIN board.</i></td>
+ * </tr>
+ * <tr>
+ * <td>ENABLE_XPROG_PROTOCOL</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to enable PDI and TPI programming protocol support.
+ * \n \n <i>Ignored when compiled for the XPLAIN board.</i></td>
+ * </tr>
+ * <tr>
+ * <td>NO_VTARGET_DETECT</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to disable VTARGET sampling and reporting on AVR models with an ADC converter. This will cause the programmer
+ * to report a fixed 3.3V target voltage to the host regardless of the real target voltage.
+ * \n \n <i>Ignored when compiled for targets lacking an ADC.</i></td>
+ * </tr>
+ * <tr>
+ * <td>VTARGET_REF_VOLTS</td>
+ * <td>AppConfig.h</td>
+ * <td>Indicates the programmer AVR's AVCC reference voltage when measuring the target's supply voltage. Note that the supply
+ * voltage should never exceed the reference voltage on the programmer AVR without some form of protection to prevent damage
+ * to the ADC.
+ * \n \n <i>Ignored when compiled for targets lacking an ADC, or when NO_VTARGET_DETECT is defined.</i></td>
+ * </tr>
+ * <tr>
+ * <td>VTARGET_USE_INTERNAL_REF</td>
+ * <td>AppConfig.h</td>
+ * <td>Selects the internal 2.56V ADC reference voltage, instead of using the AVR's VREF pin. When enabled, this option will
+ * override the VTARGET_REF_VOLTS configuration option.
+ * \n \n <i>Ignored when compiled for targets lacking an ADC, or when NO_VTARGET_DETECT is defined.</i></td>
+ * </tr>
+ * <tr>
+ * <td>VTARGET_SCALE_FACTOR</td>
+ * <td>AppConfig.h</td>
+ * <td>Indicates the target's supply voltage scale factor when applied to the ADC. A simple resistive divider can be used on the
+ * ADC pin for measuring the target's supply voltage, so that voltages above the programmer AVR's AVCC reference voltage can be
+ * measured. This should be the reciprocal of the division performed - e.g. if the VTARGET voltage is halved, this should be set
+ * to 2.
+ * \n \n <i>Ignored when compiled for targets lacking an ADC, or when NO_VTARGET_DETECT is defined.</i></td>
+ * </tr>
+ * <tr>
+ * <td>LIBUSB_DRIVER_COMPAT</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to switch to a non-standard endpoint scheme, breaking compatibility with Atmel Studio/AVR Studio under Windows but
+ * making the code compatible with software such as avrdude (all platforms) that use the libUSB driver.
+ *
+ * \note This option is incompatible with \c RESET_TOGGLES_LIBUSB_COMPAT.</td>
+ * </tr>
+ * <tr>
+ * <td>RESET_TOGGLES_LIBUSB_COMPAT</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to make the /RESET line of the AVR toggle between Jungo and libUSB driver compatibility modes. Each time the AVR is
+ * reset externally via the reset pin, the compatibility mode will be toggled. The compatibility mode is preserved between
+ * power cycles and is not toggled via other forms of reset such as Watchdog or Brown Out.
+ *
+ * When this option is enabled, all board LEDs will flash twice on startup for Jungo compatibility mode, and five times for
+ * libUSB compatibility mode.
+ *
+ * \note This option is incompatible with \c LIBUSB_DRIVER_COMPAT.</td>
+ * </tr>
+ * <tr>
+ * <td>XCK_RESCUE_CLOCK_ENABLE</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to move the ISP rescue clock to the AVR's XCK pin instead of the OCR1A output pin. This is useful for existing programming
+ * hardware that does not expose the OCR1A pin of the AVR, but <i>may</i> cause some issues with PDI programming mode.</td>
+ * </tr>
+ * <tr>
+ * <td>INVERTED_ISP_MISO</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to invert the received data on the ISP MISO line. This is sometimes needed depending on the level translation hardware used,
+ * if the translator hardware inverts the received logic level.</td>
+ * </tr>
+ * <tr>
+ * <td>FIRMWARE_VERSION_MINOR</td>
+ * <td>AppConfig.h</td>
+ * <td>Define to set the minor firmware revision nunber reported to the host on request. By default this will use a firmware version compatible
+ * with the latest Atmel IDE version, however if desired the reported minor value can be adjusted here.</td>
+ * </tr>
+ * </table>
+ */
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.c
new file mode 100644
index 000000000..a098e7020
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.c
@@ -0,0 +1,302 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 "AVRISPDescriptors.h"
+
+#if defined(RESET_TOGGLES_LIBUSB_COMPAT) || defined(__DOXYGEN__)
+ /** Indicates if an external reset has occurred and the compatibility mode needs to be altered */
+ static bool AVRISP_NeedCompatibilitySwitch ATTR_NO_INIT;
+
+ /** Current AVRISP data IN endpoint address. */
+ uint8_t AVRISP_CurrDataINEndpointAddress;
+
+ /** Saved AVRISP data IN endpoint address in EEPROM. */
+ uint8_t AVRISP_CurrDataINEndpointAddress_EEPROM EEMEM;
+#endif
+
+/** 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 AVRISP_DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(1,1,0),
+ .Class = USB_CSCP_VendorSpecificClass,
+ .SubClass = USB_CSCP_NoDeviceSubclass,
+ .Protocol = USB_CSCP_NoDeviceProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x03EB,
+ .ProductID = 0x2104,
+ .ReleaseNumber = VERSION_BCD(2,0,0),
+
+ .ManufacturerStrIndex = AVRISP_STRING_ID_Manufacturer,
+ .ProductStrIndex = AVRISP_STRING_ID_Product,
+ .SerialNumStrIndex = AVRISP_STRING_ID_Serial,
+
+ .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.
+ */
+AVRISP_USB_Descriptor_Configuration_t AVRISP_ConfigurationDescriptor =
+{
+ .Config =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+ .TotalConfigurationSize = sizeof(AVRISP_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)
+ },
+
+ .AVRISP_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = INTERFACE_ID_AVRISP,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = USB_CSCP_VendorSpecificClass,
+ .SubClass = USB_CSCP_NoDeviceSubclass,
+ .Protocol = USB_CSCP_NoDeviceProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .AVRISP_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+#if defined(RESET_TOGGLES_LIBUSB_COMPAT)
+ .EndpointAddress = 0,
+#else
+ .EndpointAddress = AVRISP_DATA_IN_EPADDR,
+#endif
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = AVRISP_DATA_EPSIZE,
+ .PollingIntervalMS = 0x0A
+ },
+
+ .AVRISP_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = AVRISP_DATA_OUT_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = AVRISP_DATA_EPSIZE,
+ .PollingIntervalMS = 0x0A
+ },
+};
+
+/** 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 AVRISP_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 AVRISP_ManufacturerString = USB_STRING_DESCRIPTOR(L"ATMEL");
+
+/** 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 AVRISP_ProductString = USB_STRING_DESCRIPTOR(L"AVRISP mkII");
+
+/** Serial number string. This is a Unicode string containing the device's unique serial number, expressed as a
+ * series of uppercase hexadecimal digits.
+ */
+USB_Descriptor_String_t AVRISP_SerialString = USB_STRING_DESCRIPTOR(L"000200012345\0"
+ // Note: Real AVRISP-MKII has the embedded NUL byte, bug in firmware?
+);
+
+/** 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 AVRISP_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress,
+ uint8_t* DescriptorMemorySpace)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ *DescriptorMemorySpace = MEMSPACE_FLASH;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &AVRISP_DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ *DescriptorMemorySpace = MEMSPACE_RAM;
+ #if defined(RESET_TOGGLES_LIBUSB_COMPAT)
+ /* Update the configuration descriptor with the current endpoint address */
+ AVRISP_ConfigurationDescriptor.AVRISP_DataInEndpoint.EndpointAddress = AVRISP_CurrDataINEndpointAddress;
+ #endif
+
+ Address = &AVRISP_ConfigurationDescriptor;
+ Size = sizeof(AVRISP_USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case AVRISP_STRING_ID_Language:
+ Address = &AVRISP_LanguageString;
+ Size = pgm_read_byte(&AVRISP_LanguageString.Header.Size);
+ break;
+ case AVRISP_STRING_ID_Manufacturer:
+ Address = &AVRISP_ManufacturerString;
+ Size = pgm_read_byte(&AVRISP_ManufacturerString.Header.Size);
+ break;
+ case AVRISP_STRING_ID_Product:
+ Address = &AVRISP_ProductString;
+ Size = pgm_read_byte(&AVRISP_ProductString.Header.Size);
+ break;
+ case AVRISP_STRING_ID_Serial:
+ Address = &AVRISP_SerialString;
+ Size = AVRISP_SerialString.Header.Size;
+
+ /* Update serial number to have a different serial based on the current endpoint address */
+ ((uint16_t*)&AVRISP_SerialString.UnicodeString)[6] = cpu_to_le16('0' + (AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK));
+
+ *DescriptorMemorySpace = MEMSPACE_RAM;
+ break;
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
+#if defined(RESET_TOGGLES_LIBUSB_COMPAT) || defined(__DOXYGEN__)
+/** Checks the state of the system status register MCUSR and indicates via a flag if
+ * the current AVRISP driver compatibility mode needs to be reset.
+ *
+ * When the \c RESET_TOGGLES_LIBUSB_COMPAT compile time option is enabled, pulling
+ * the reset line of the AVR low will toggle between Jungo and libUSB compatibility
+ * modes. Other forms of reset (such as power on or watchdog) will not force a mode
+ * change.
+ */
+void CheckExternalReset(void)
+{
+ /* If an external reset occurred, we need to change compatibility mode */
+ AVRISP_NeedCompatibilitySwitch = (MCUSR == (1 << EXTRF));
+
+ MCUSR = 0;
+}
+
+/** Updates the device descriptors so that the correct compatibility mode is used
+ * when the \c RESET_TOGGLES_LIBUSB_COMPAT compile time option is enabled. This
+ * configures the programmer for either Jungo or libUSB driver compatibility. Each
+ * time the AVR is reset via pulling the reset line low the compatibility mode will
+ * be toggled. The current mode is stored in EEPROM and preserved through power
+ * cycles of the AVR.
+ */
+void UpdateCurrentCompatibilityMode(void)
+{
+ /* Load the current IN endpoint address stored in EEPROM */
+ AVRISP_CurrDataINEndpointAddress = eeprom_read_byte(&AVRISP_CurrDataINEndpointAddress_EEPROM);
+
+ /* Check if we need to switch compatibility modes */
+ if (AVRISP_NeedCompatibilitySwitch)
+ {
+ /* Toggle between compatibility modes */
+ AVRISP_CurrDataINEndpointAddress = (AVRISP_CurrDataINEndpointAddress == AVRISP_DATA_IN_EPADDR_LIBUSB) ?
+ AVRISP_DATA_IN_EPADDR_JUNGO : AVRISP_DATA_IN_EPADDR_LIBUSB;
+
+ /* Save the new mode into EEPROM */
+ eeprom_update_byte(&AVRISP_CurrDataINEndpointAddress_EEPROM, AVRISP_CurrDataINEndpointAddress);
+ }
+
+ LEDs_SetAllLEDs(LEDS_NO_LEDS);
+
+ /* Validate IN endpoint address and indicate current mode via LED flashes */
+ switch (AVRISP_CurrDataINEndpointAddress)
+ {
+ default:
+ /* Default to Jungo compatibility mode if saved EEPROM is invalid */
+ AVRISP_CurrDataINEndpointAddress = AVRISP_DATA_IN_EPADDR_JUNGO;
+ case AVRISP_DATA_IN_EPADDR_JUNGO:
+ /* Two flashes for Jungo compatibility mode */
+ for (uint8_t i = 0; i < 4; i++)
+ {
+ LEDs_ToggleLEDs(LEDS_ALL_LEDS);
+ Delay_MS(100);
+ }
+ break;
+ case AVRISP_DATA_IN_EPADDR_LIBUSB:
+ /* Five flashes for libUSB compatibility mode */
+ for (uint8_t i = 0; i < 10; i++)
+ {
+ LEDs_ToggleLEDs(LEDS_ALL_LEDS);
+ Delay_MS(100);
+ }
+ break;
+ }
+
+ Delay_MS(500);
+}
+#endif
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.h
new file mode 100644
index 000000000..40d711387
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/AVRISPDescriptors.h
@@ -0,0 +1,128 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 <LUFA/Drivers/Board/LEDs.h>
+
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if defined(LIBUSB_DRIVER_COMPAT) && defined(RESET_TOGGLES_LIBUSB_COMPAT)
+ #error LIBUSB_DRIVER_COMPAT and RESET_TOGGLES_LIBUSB_COMPAT are mutually exclusive.
+ #endif
+
+ /* Macros: */
+ /** Endpoint address of the AVRISP data OUT endpoint. */
+ #define AVRISP_DATA_OUT_EPADDR (ENDPOINT_DIR_OUT | 2)
+
+ /** Endpoint address of the AVRISP data IN endpoint, when in Jungo driver compatibility mode. */
+ #define AVRISP_DATA_IN_EPADDR_JUNGO (ENDPOINT_DIR_IN | 2)
+
+ /** Endpoint address of the AVRISP data IN endpoint, when in LibUSB driver compatibility mode. */
+ #define AVRISP_DATA_IN_EPADDR_LIBUSB (ENDPOINT_DIR_IN | 3)
+
+ #if defined(RESET_TOGGLES_LIBUSB_COMPAT)
+ #define AVRISP_DATA_IN_EPADDR AVRISP_CurrDataINEndpointAddress
+ #elif defined(LIBUSB_DRIVER_COMPAT)
+ #define AVRISP_DATA_IN_EPADDR AVRISP_DATA_IN_EPADDR_LIBUSB
+ #else
+ /** Endpoint address of the AVRISP data IN endpoint. */
+ #define AVRISP_DATA_IN_EPADDR AVRISP_DATA_IN_EPADDR_JUNGO
+ #endif
+
+ /** Size in bytes of the AVRISP data endpoint. */
+ #define AVRISP_DATA_EPSIZE 64
+
+ /* 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;
+
+ // Atmel AVRISP-MKII Interface
+ USB_Descriptor_Interface_t AVRISP_Interface;
+ USB_Descriptor_Endpoint_t AVRISP_DataInEndpoint;
+ USB_Descriptor_Endpoint_t AVRISP_DataOutEndpoint;
+ } AVRISP_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_AVRISP = 0, /**< AVRISP 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 AVRISP_StringDescriptors_t
+ {
+ AVRISP_STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
+ AVRISP_STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
+ AVRISP_STRING_ID_Product = 2, /**< Product string ID */
+ AVRISP_STRING_ID_Serial = 3, /**< Serial number string ID */
+ };
+
+ /* External Variables: */
+ #if defined(RESET_TOGGLES_LIBUSB_COMPAT)
+ extern uint8_t AVRISP_CurrDataINEndpointAddress;
+ #endif
+
+ /* Function Prototypes: */
+ uint16_t AVRISP_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress,
+ uint8_t* const DescriptorMemorySpace)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3) ATTR_NON_NULL_PTR_ARG(4);
+
+ #if defined(RESET_TOGGLES_LIBUSB_COMPAT)
+ void CheckExternalReset(void) ATTR_NAKED ATTR_INIT_SECTION(3);
+ void UpdateCurrentCompatibilityMode(void);
+ #endif
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/AppConfig.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/AppConfig.h
new file mode 100644
index 000000000..979b354c4
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/AppConfig.h
@@ -0,0 +1,70 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 Application Configuration Header File
+ *
+ * This is a header file which is be used to configure some of
+ * the application's compile time options, as an alternative to
+ * specifying the compile time constants supplied through a
+ * makefile or build system.
+ *
+ * For information on what each token does, refer to the
+ * \ref Sec_Options section of the application documentation.
+ */
+
+#ifndef _APP_CONFIG_H_
+#define _APP_CONFIG_H_
+
+ #define AUX_LINE_PORT PORTB
+ #define AUX_LINE_PIN PINB
+ #define AUX_LINE_DDR DDRB
+ #if (BOARD == BOARD_U2S)
+ #define AUX_LINE_MASK (1 << 0)
+ #else
+ #define AUX_LINE_MASK (1 << 4)
+ #endif
+
+ #define ENABLE_ISP_PROTOCOL
+ #define ENABLE_XPROG_PROTOCOL
+
+ #define VTARGET_ADC_CHANNEL 2
+ #define VTARGET_REF_VOLTS 5
+ #define VTARGET_SCALE_FACTOR 1
+// #define VTARGET_USE_INTERNAL_REF
+// #define NO_VTARGET_DETECT
+// #define XCK_RESCUE_CLOCK_ENABLE
+// #define INVERTED_ISP_MISO
+
+ #define LIBUSB_DRIVER_COMPAT
+// #define RESET_TOGGLES_LIBUSB_COMPAT
+// #define FIRMWARE_VERSION_MINOR 0x11
+
+#endif
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/LUFAConfig.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/LUFAConfig.h
new file mode 100644
index 000000000..9c1715ced
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Config/LUFAConfig.h
@@ -0,0 +1,93 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 LUFA Library Configuration Header File
+ *
+ * This header file is used to configure LUFA's compile time options,
+ * as an alternative to the compile time constants supplied through
+ * a makefile.
+ *
+ * For information on what each token does, refer to the LUFA
+ * manual section "Summary of Compile Tokens".
+ */
+
+#ifndef _LUFA_CONFIG_H_
+#define _LUFA_CONFIG_H_
+
+ #if (ARCH == ARCH_AVR8)
+
+ /* Non-USB Related Configuration Tokens: */
+// #define DISABLE_TERMINAL_CODES
+
+ /* USB Class Driver Related Tokens: */
+// #define HID_HOST_BOOT_PROTOCOL_ONLY
+// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
+// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
+// #define HID_MAX_COLLECTIONS {Insert Value Here}
+// #define HID_MAX_REPORTITEMS {Insert Value Here}
+// #define HID_MAX_REPORT_IDS {Insert Value Here}
+// #define NO_CLASS_DRIVER_AUTOFLUSH
+
+ /* General USB Driver Related Tokens: */
+ #define ORDERED_EP_CONFIG
+ #define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
+ #define USB_DEVICE_ONLY
+// #define USB_HOST_ONLY
+// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
+// #define NO_LIMITED_CONTROLLER_CONNECT
+ #define NO_SOF_EVENTS
+
+ /* USB Device Mode Driver Related Tokens: */
+// #define USE_RAM_DESCRIPTORS
+// #define USE_FLASH_DESCRIPTORS
+// #define USE_EEPROM_DESCRIPTORS
+ #define NO_INTERNAL_SERIAL
+ #define FIXED_CONTROL_ENDPOINT_SIZE 16
+ #define DEVICE_STATE_AS_GPIOR 0
+ #define FIXED_NUM_CONFIGURATIONS 1
+// #define CONTROL_ONLY_DEVICE
+// #define INTERRUPT_CONTROL_ENDPOINT
+ #define NO_DEVICE_REMOTE_WAKEUP
+ #define NO_DEVICE_SELF_POWER
+
+ /* USB Host Mode Driver Related Tokens: */
+// #define HOST_STATE_AS_GPIOR {Insert Value Here}
+// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
+// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
+// #define NO_AUTO_VBUS_MANAGEMENT
+// #define INVERTED_VBUS_ENABLE_LINE
+
+ #else
+
+ #error Unsupported architecture for this LUFA configuration file.
+
+ #endif
+#endif
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
new file mode 100644
index 000000000..60552564e
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -0,0 +1,531 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * ISP Protocol handler, to process V2 Protocol wrapped ISP commands used in Atmel programmer devices.
+ */
+
+#include "ISPProtocol.h"
+
+#if defined(ENABLE_ISP_PROTOCOL) || defined(__DOXYGEN__)
+
+/** Handler for the CMD_ENTER_PROGMODE_ISP command, which attempts to enter programming mode on
+ * the attached device, returning success or failure back to the host.
+ */
+void ISPProtocol_EnterISPMode(void)
+{
+ struct
+ {
+ uint8_t TimeoutMS;
+ uint8_t PinStabDelayMS;
+ uint8_t ExecutionDelayMS;
+ uint8_t SynchLoops;
+ uint8_t ByteDelay;
+ uint8_t PollValue;
+ uint8_t PollIndex;
+ uint8_t EnterProgBytes[4];
+ } Enter_ISP_Params;
+
+ Endpoint_Read_Stream_LE(&Enter_ISP_Params, sizeof(Enter_ISP_Params), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ uint8_t ResponseStatus = STATUS_CMD_FAILED;
+
+ CurrentAddress = 0;
+
+ /* Perform execution delay, initialize SPI bus */
+ ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS);
+ ISPTarget_EnableTargetISP();
+
+ ISPTarget_ChangeTargetResetLine(true);
+ ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
+
+ /* Continuously attempt to synchronize with the target until either the number of attempts specified
+ * by the host has exceeded, or the the device sends back the expected response values */
+ while (Enter_ISP_Params.SynchLoops-- && TimeoutTicksRemaining)
+ {
+ uint8_t ResponseBytes[4];
+
+ for (uint8_t RByte = 0; RByte < sizeof(ResponseBytes); RByte++)
+ {
+ ISPProtocol_DelayMS(Enter_ISP_Params.ByteDelay);
+ ResponseBytes[RByte] = ISPTarget_TransferByte(Enter_ISP_Params.EnterProgBytes[RByte]);
+ }
+
+ /* Check if polling disabled, or if the polled value matches the expected value */
+ if (!(Enter_ISP_Params.PollIndex) || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue))
+ {
+ ResponseStatus = STATUS_CMD_OK;
+ break;
+ }
+ else
+ {
+ ISPTarget_ChangeTargetResetLine(false);
+ ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
+ ISPTarget_ChangeTargetResetLine(true);
+ ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
+ }
+ }
+
+ Endpoint_Write_8(CMD_ENTER_PROGMODE_ISP);
+ Endpoint_Write_8(ResponseStatus);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_LEAVE_ISP command, which releases the target from programming mode. */
+void ISPProtocol_LeaveISPMode(void)
+{
+ struct
+ {
+ uint8_t PreDelayMS;
+ uint8_t PostDelayMS;
+ } Leave_ISP_Params;
+
+ Endpoint_Read_Stream_LE(&Leave_ISP_Params, sizeof(Leave_ISP_Params), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ /* Perform pre-exit delay, release the target /RESET, disable the SPI bus and perform the post-exit delay */
+ ISPProtocol_DelayMS(Leave_ISP_Params.PreDelayMS);
+ ISPTarget_ChangeTargetResetLine(false);
+ ISPTarget_DisableTargetISP();
+ ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS);
+
+ Endpoint_Write_8(CMD_LEAVE_PROGMODE_ISP);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_PROGRAM_FLASH_ISP and CMD_PROGRAM_EEPROM_ISP commands, writing out bytes,
+ * words or pages of data to the attached device.
+ *
+ * \param[in] V2Command Issued V2 Protocol command byte from the host
+ */
+void ISPProtocol_ProgramMemory(uint8_t V2Command)
+{
+ struct
+ {
+ uint16_t BytesToWrite;
+ uint8_t ProgrammingMode;
+ uint8_t DelayMS;
+ uint8_t ProgrammingCommands[3];
+ uint8_t PollValue1;
+ uint8_t PollValue2;
+ uint8_t ProgData[256]; // Note, the Jungo driver has a very short ACK timeout period, need to buffer the
+ } Write_Memory_Params; // whole page and ACK the packet as fast as possible to prevent it from aborting
+
+ Endpoint_Read_Stream_LE(&Write_Memory_Params, (sizeof(Write_Memory_Params) -
+ sizeof(Write_Memory_Params.ProgData)), NULL);
+ Write_Memory_Params.BytesToWrite = SwapEndian_16(Write_Memory_Params.BytesToWrite);
+
+ if (Write_Memory_Params.BytesToWrite > sizeof(Write_Memory_Params.ProgData))
+ {
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(V2Command);
+ Endpoint_Write_8(STATUS_CMD_FAILED);
+ Endpoint_ClearIN();
+ return;
+ }
+
+ Endpoint_Read_Stream_LE(&Write_Memory_Params.ProgData, Write_Memory_Params.BytesToWrite, NULL);
+
+ // The driver will terminate transfers that are a round multiple of the endpoint bank in size with a ZLP, need
+ // to catch this and discard it before continuing on with packet processing to prevent communication issues
+ if (((sizeof(uint8_t) + sizeof(Write_Memory_Params) - sizeof(Write_Memory_Params.ProgData)) +
+ Write_Memory_Params.BytesToWrite) % AVRISP_DATA_EPSIZE == 0)
+ {
+ Endpoint_ClearOUT();
+ Endpoint_WaitUntilReady();
+ }
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ uint8_t ProgrammingStatus = STATUS_CMD_OK;
+ uint8_t PollValue = (V2Command == CMD_PROGRAM_FLASH_ISP) ? Write_Memory_Params.PollValue1 :
+ Write_Memory_Params.PollValue2;
+ uint16_t PollAddress = 0;
+ uint8_t* NextWriteByte = Write_Memory_Params.ProgData;
+ uint16_t PageStartAddress = (CurrentAddress & 0xFFFF);
+
+ for (uint16_t CurrentByte = 0; CurrentByte < Write_Memory_Params.BytesToWrite; CurrentByte++)
+ {
+ uint8_t ByteToWrite = *(NextWriteByte++);
+ uint8_t ProgrammingMode = Write_Memory_Params.ProgrammingMode;
+
+ /* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
+ if (MustLoadExtendedAddress)
+ {
+ ISPTarget_LoadExtendedAddress();
+ MustLoadExtendedAddress = false;
+ }
+
+ ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
+ ISPTarget_SendByte(CurrentAddress >> 8);
+ ISPTarget_SendByte(CurrentAddress & 0xFF);
+ ISPTarget_SendByte(ByteToWrite);
+
+ /* AVR FLASH addressing requires us to modify the write command based on if we are writing a high
+ * or low byte at the current word address */
+ if (V2Command == CMD_PROGRAM_FLASH_ISP)
+ Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;
+
+ /* Check to see if we have a valid polling address */
+ if (!(PollAddress) && (ByteToWrite != PollValue))
+ {
+ if ((CurrentByte & 0x01) && (V2Command == CMD_PROGRAM_FLASH_ISP))
+ Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK;
+ else
+ Write_Memory_Params.ProgrammingCommands[2] &= ~READ_WRITE_HIGH_BYTE_MASK;
+
+ PollAddress = (CurrentAddress & 0xFFFF);
+ }
+
+ /* If in word programming mode, commit the byte to the target's memory */
+ if (!(ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK))
+ {
+ /* If the current polling address is invalid, switch to timed delay write completion mode */
+ if (!(PollAddress) && !(ProgrammingMode & PROG_MODE_WORD_READYBUSY_MASK))
+ ProgrammingMode = (ProgrammingMode & ~PROG_MODE_WORD_VALUE_MASK) | PROG_MODE_WORD_TIMEDELAY_MASK;
+
+ ProgrammingStatus = ISPTarget_WaitForProgComplete(ProgrammingMode, PollAddress, PollValue,
+ Write_Memory_Params.DelayMS,
+ Write_Memory_Params.ProgrammingCommands[2]);
+
+ /* Abort the programming loop early if the byte/word programming failed */
+ if (ProgrammingStatus != STATUS_CMD_OK)
+ break;
+
+ /* Must reset the polling address afterwards, so it is not erroneously used for the next byte */
+ PollAddress = 0;
+ }
+
+ /* EEPROM just increments the address each byte, flash needs to increment on each word and
+ * also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended
+ * address boundary has been crossed during FLASH memory programming */
+ if ((CurrentByte & 0x01) || (V2Command == CMD_PROGRAM_EEPROM_ISP))
+ {
+ CurrentAddress++;
+
+ if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
+ MustLoadExtendedAddress = true;
+ }
+ }
+
+ /* If the current page must be committed, send the PROGRAM PAGE command to the target */
+ if (Write_Memory_Params.ProgrammingMode & PROG_MODE_COMMIT_PAGE_MASK)
+ {
+ ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[1]);
+ ISPTarget_SendByte(PageStartAddress >> 8);
+ ISPTarget_SendByte(PageStartAddress & 0xFF);
+ ISPTarget_SendByte(0x00);
+
+ /* Check if polling is enabled and possible, if not switch to timed delay mode */
+ if ((Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_VALUE_MASK) && !(PollAddress))
+ {
+ Write_Memory_Params.ProgrammingMode = (Write_Memory_Params.ProgrammingMode & ~PROG_MODE_PAGED_VALUE_MASK) |
+ PROG_MODE_PAGED_TIMEDELAY_MASK;
+ }
+
+ ProgrammingStatus = ISPTarget_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
+ Write_Memory_Params.DelayMS,
+ Write_Memory_Params.ProgrammingCommands[2]);
+
+ /* Check to see if the FLASH address has crossed the extended address boundary */
+ if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
+ MustLoadExtendedAddress = true;
+ }
+
+ Endpoint_Write_8(V2Command);
+ Endpoint_Write_8(ProgrammingStatus);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_READ_FLASH_ISP and CMD_READ_EEPROM_ISP commands, reading in bytes,
+ * words or pages of data from the attached device.
+ *
+ * \param[in] V2Command Issued V2 Protocol command byte from the host
+ */
+void ISPProtocol_ReadMemory(uint8_t V2Command)
+{
+ struct
+ {
+ uint16_t BytesToRead;
+ uint8_t ReadMemoryCommand;
+ } Read_Memory_Params;
+
+ Endpoint_Read_Stream_LE(&Read_Memory_Params, sizeof(Read_Memory_Params), NULL);
+ Read_Memory_Params.BytesToRead = SwapEndian_16(Read_Memory_Params.BytesToRead);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(V2Command);
+ Endpoint_Write_8(STATUS_CMD_OK);
+
+ /* Read each byte from the device and write them to the packet for the host */
+ for (uint16_t CurrentByte = 0; CurrentByte < Read_Memory_Params.BytesToRead; CurrentByte++)
+ {
+ /* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
+ if (MustLoadExtendedAddress)
+ {
+ ISPTarget_LoadExtendedAddress();
+ MustLoadExtendedAddress = false;
+ }
+
+ /* Read the next byte from the desired memory space in the device */
+ ISPTarget_SendByte(Read_Memory_Params.ReadMemoryCommand);
+ ISPTarget_SendByte(CurrentAddress >> 8);
+ ISPTarget_SendByte(CurrentAddress & 0xFF);
+ Endpoint_Write_8(ISPTarget_ReceiveByte());
+
+ /* Check if the endpoint bank is currently full, if so send the packet */
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+ Endpoint_WaitUntilReady();
+ }
+
+ /* AVR FLASH addressing requires us to modify the read command based on if we are reading a high
+ * or low byte at the current word address */
+ if (V2Command == CMD_READ_FLASH_ISP)
+ Read_Memory_Params.ReadMemoryCommand ^= READ_WRITE_HIGH_BYTE_MASK;
+
+ /* EEPROM just increments the address each byte, flash needs to increment on each word and
+ * also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended
+ * address boundary has been crossed */
+ if ((CurrentByte & 0x01) || (V2Command == CMD_READ_EEPROM_ISP))
+ {
+ CurrentAddress++;
+
+ if ((V2Command != CMD_READ_EEPROM_ISP) && !(CurrentAddress & 0xFFFF))
+ MustLoadExtendedAddress = true;
+ }
+ }
+
+ Endpoint_Write_8(STATUS_CMD_OK);
+
+ bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
+ Endpoint_ClearIN();
+
+ /* Ensure last packet is a short packet to terminate the transfer */
+ if (IsEndpointFull)
+ {
+ Endpoint_WaitUntilReady();
+ Endpoint_ClearIN();
+ Endpoint_WaitUntilReady();
+ }
+}
+
+/** Handler for the CMD_CHI_ERASE_ISP command, clearing the target's FLASH memory. */
+void ISPProtocol_ChipErase(void)
+{
+ struct
+ {
+ uint8_t EraseDelayMS;
+ uint8_t PollMethod;
+ uint8_t EraseCommandBytes[4];
+ } Erase_Chip_Params;
+
+ Endpoint_Read_Stream_LE(&Erase_Chip_Params, sizeof(Erase_Chip_Params), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ uint8_t ResponseStatus = STATUS_CMD_OK;
+
+ /* Send the chip erase commands as given by the host to the device */
+ for (uint8_t SByte = 0; SByte < sizeof(Erase_Chip_Params.EraseCommandBytes); SByte++)
+ ISPTarget_SendByte(Erase_Chip_Params.EraseCommandBytes[SByte]);
+
+ /* Use appropriate command completion check as given by the host (delay or busy polling) */
+ if (!(Erase_Chip_Params.PollMethod))
+ ISPProtocol_DelayMS(Erase_Chip_Params.EraseDelayMS);
+ else
+ ResponseStatus = ISPTarget_WaitWhileTargetBusy();
+
+ Endpoint_Write_8(CMD_CHIP_ERASE_ISP);
+ Endpoint_Write_8(ResponseStatus);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_READ_FUSE_ISP, CMD_READ_LOCK_ISP, CMD_READ_SIGNATURE_ISP and CMD_READ_OSCCAL commands,
+ * reading the requested configuration byte from the device.
+ *
+ * \param[in] V2Command Issued V2 Protocol command byte from the host
+ */
+void ISPProtocol_ReadFuseLockSigOSCCAL(uint8_t V2Command)
+{
+ struct
+ {
+ uint8_t RetByte;
+ uint8_t ReadCommandBytes[4];
+ } Read_FuseLockSigOSCCAL_Params;
+
+ Endpoint_Read_Stream_LE(&Read_FuseLockSigOSCCAL_Params, sizeof(Read_FuseLockSigOSCCAL_Params), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ uint8_t ResponseBytes[4];
+
+ /* Send the Fuse or Lock byte read commands as given by the host to the device, store response */
+ for (uint8_t RByte = 0; RByte < sizeof(ResponseBytes); RByte++)
+ ResponseBytes[RByte] = ISPTarget_TransferByte(Read_FuseLockSigOSCCAL_Params.ReadCommandBytes[RByte]);
+
+ Endpoint_Write_8(V2Command);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_Write_8(ResponseBytes[Read_FuseLockSigOSCCAL_Params.RetByte - 1]);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_WRITE_FUSE_ISP and CMD_WRITE_LOCK_ISP commands, writing the requested configuration
+ * byte to the device.
+ *
+ * \param[in] V2Command Issued V2 Protocol command byte from the host
+ */
+void ISPProtocol_WriteFuseLock(uint8_t V2Command)
+{
+ struct
+ {
+ uint8_t WriteCommandBytes[4];
+ } Write_FuseLockSig_Params;
+
+ Endpoint_Read_Stream_LE(&Write_FuseLockSig_Params, sizeof(Write_FuseLockSig_Params), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ /* Send the Fuse or Lock byte program commands as given by the host to the device */
+ for (uint8_t SByte = 0; SByte < sizeof(Write_FuseLockSig_Params.WriteCommandBytes); SByte++)
+ ISPTarget_SendByte(Write_FuseLockSig_Params.WriteCommandBytes[SByte]);
+
+ Endpoint_Write_8(V2Command);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_SPI_MULTI command, writing and reading arbitrary SPI data to and from the attached device. */
+void ISPProtocol_SPIMulti(void)
+{
+ struct
+ {
+ uint8_t TxBytes;
+ uint8_t RxBytes;
+ uint8_t RxStartAddr;
+ uint8_t TxData[255];
+ } SPI_Multi_Params;
+
+ Endpoint_Read_Stream_LE(&SPI_Multi_Params, (sizeof(SPI_Multi_Params) - sizeof(SPI_Multi_Params.TxData)), NULL);
+ Endpoint_Read_Stream_LE(&SPI_Multi_Params.TxData, SPI_Multi_Params.TxBytes, NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(CMD_SPI_MULTI);
+ Endpoint_Write_8(STATUS_CMD_OK);
+
+ uint8_t CurrTxPos = 0;
+ uint8_t CurrRxPos = 0;
+
+ /* Write out bytes to transmit until the start of the bytes to receive is met */
+ while (CurrTxPos < SPI_Multi_Params.RxStartAddr)
+ {
+ if (CurrTxPos < SPI_Multi_Params.TxBytes)
+ ISPTarget_SendByte(SPI_Multi_Params.TxData[CurrTxPos]);
+ else
+ ISPTarget_SendByte(0);
+
+ CurrTxPos++;
+ }
+
+ /* Transmit remaining bytes with padding as needed, read in response bytes */
+ while (CurrRxPos < SPI_Multi_Params.RxBytes)
+ {
+ if (CurrTxPos < SPI_Multi_Params.TxBytes)
+ Endpoint_Write_8(ISPTarget_TransferByte(SPI_Multi_Params.TxData[CurrTxPos++]));
+ else
+ Endpoint_Write_8(ISPTarget_ReceiveByte());
+
+ /* Check to see if we have filled the endpoint bank and need to send the packet */
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+ Endpoint_WaitUntilReady();
+ }
+
+ CurrRxPos++;
+ }
+
+ Endpoint_Write_8(STATUS_CMD_OK);
+
+ bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
+ Endpoint_ClearIN();
+
+ /* Ensure last packet is a short packet to terminate the transfer */
+ if (IsEndpointFull)
+ {
+ Endpoint_WaitUntilReady();
+ Endpoint_ClearIN();
+ Endpoint_WaitUntilReady();
+ }
+}
+
+/** Blocking delay for a given number of milliseconds. This provides a simple wrapper around
+ * the avr-libc provided delay function, so that the delay function can be called with a
+ * constant value (to prevent run-time floating point operations being required).
+ *
+ * \param[in] DelayMS Number of milliseconds to delay for
+ */
+void ISPProtocol_DelayMS(uint8_t DelayMS)
+{
+ while (DelayMS-- && TimeoutTicksRemaining)
+ Delay_MS(1);
+}
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.h
new file mode 100644
index 000000000..29d2bf747
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.h
@@ -0,0 +1,81 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 ISPProtocol.c.
+ */
+
+#ifndef _ISP_PROTOCOL_
+#define _ISP_PROTOCOL_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <util/delay.h>
+
+ #include <LUFA/Drivers/USB/USB.h>
+
+ #include "../V2Protocol.h"
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+ #undef ENABLE_ISP_PROTOCOL
+
+ #if !defined(ENABLE_XPROG_PROTOCOL)
+ #define ENABLE_XPROG_PROTOCOL
+ #endif
+ #endif
+
+ /* Macros: */
+ /** Mask for the reading or writing of the high byte in a FLASH word when issuing a low-level programming command. */
+ #define READ_WRITE_HIGH_BYTE_MASK (1 << 3)
+
+ #define PROG_MODE_PAGED_WRITES_MASK (1 << 0)
+ #define PROG_MODE_WORD_TIMEDELAY_MASK (1 << 1)
+ #define PROG_MODE_WORD_VALUE_MASK (1 << 2)
+ #define PROG_MODE_WORD_READYBUSY_MASK (1 << 3)
+ #define PROG_MODE_PAGED_TIMEDELAY_MASK (1 << 4)
+ #define PROG_MODE_PAGED_VALUE_MASK (1 << 5)
+ #define PROG_MODE_PAGED_READYBUSY_MASK (1 << 6)
+ #define PROG_MODE_COMMIT_PAGE_MASK (1 << 7)
+
+ /* Function Prototypes: */
+ void ISPProtocol_EnterISPMode(void);
+ void ISPProtocol_LeaveISPMode(void);
+ void ISPProtocol_ProgramMemory(const uint8_t V2Command);
+ void ISPProtocol_ReadMemory(const uint8_t V2Command);
+ void ISPProtocol_ChipErase(void);
+ void ISPProtocol_ReadFuseLockSigOSCCAL(const uint8_t V2Command);
+ void ISPProtocol_WriteFuseLock(const uint8_t V2Command);
+ void ISPProtocol_SPIMulti(void);
+ void ISPProtocol_DelayMS(uint8_t DelayMS);
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c
new file mode 100644
index 000000000..6cfe01708
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c
@@ -0,0 +1,370 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * Target-related functions for the ISP Protocol decoder.
+ */
+
+#include "ISPTarget.h"
+
+#if defined(ENABLE_ISP_PROTOCOL) || defined(__DOXYGEN__)
+
+/** List of hardware SPI prescaler masks for possible AVRStudio ISP programming speeds.
+ *
+ * \hideinitializer
+ */
+static const uint8_t SPIMaskFromSCKDuration[] PROGMEM =
+{
+#if (F_CPU == 8000000)
+ SPI_SPEED_FCPU_DIV_2, // AVRStudio = 8MHz SPI, Actual = 4MHz SPI
+ SPI_SPEED_FCPU_DIV_2, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI
+ SPI_SPEED_FCPU_DIV_4, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI
+ SPI_SPEED_FCPU_DIV_8, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI
+ SPI_SPEED_FCPU_DIV_16, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI
+ SPI_SPEED_FCPU_DIV_32, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI
+ SPI_SPEED_FCPU_DIV_64, // AVRStudio = 125KHz SPI, Actual = 125KHz SPI
+#elif (F_CPU == 16000000)
+ SPI_SPEED_FCPU_DIV_2, // AVRStudio = 8MHz SPI, Actual = 8MHz SPI
+ SPI_SPEED_FCPU_DIV_4, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI
+ SPI_SPEED_FCPU_DIV_8, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI
+ SPI_SPEED_FCPU_DIV_16, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI
+ SPI_SPEED_FCPU_DIV_32, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI
+ SPI_SPEED_FCPU_DIV_64, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI
+ SPI_SPEED_FCPU_DIV_128 // AVRStudio = 125KHz SPI, Actual = 125KHz SPI
+#else
+ #error No SPI prescaler masks for chosen F_CPU speed.
+#endif
+};
+
+/** Lookup table to convert the slower ISP speeds into a compare value for the software SPI driver.
+ *
+ * \hideinitializer
+ */
+static const uint16_t TimerCompareFromSCKDuration[] PROGMEM =
+{
+ TIMER_COMP(96386), TIMER_COMP(89888), TIMER_COMP(84211), TIMER_COMP(79208), TIMER_COMP(74767),
+ TIMER_COMP(70797), TIMER_COMP(67227), TIMER_COMP(64000), TIMER_COMP(61069), TIMER_COMP(58395),
+ TIMER_COMP(55945), TIMER_COMP(51613), TIMER_COMP(49690), TIMER_COMP(47905), TIMER_COMP(46243),
+ TIMER_COMP(43244), TIMER_COMP(41885), TIMER_COMP(39409), TIMER_COMP(38278), TIMER_COMP(36200),
+ TIMER_COMP(34335), TIMER_COMP(32654), TIMER_COMP(31129), TIMER_COMP(29740), TIMER_COMP(28470),
+ TIMER_COMP(27304), TIMER_COMP(25724), TIMER_COMP(24768), TIMER_COMP(23461), TIMER_COMP(22285),
+ TIMER_COMP(21221), TIMER_COMP(20254), TIMER_COMP(19371), TIMER_COMP(18562), TIMER_COMP(17583),
+ TIMER_COMP(16914), TIMER_COMP(16097), TIMER_COMP(15356), TIMER_COMP(14520), TIMER_COMP(13914),
+ TIMER_COMP(13224), TIMER_COMP(12599), TIMER_COMP(12031), TIMER_COMP(11511), TIMER_COMP(10944),
+ TIMER_COMP(10431), TIMER_COMP(9963), TIMER_COMP(9468), TIMER_COMP(9081), TIMER_COMP(8612),
+ TIMER_COMP(8239), TIMER_COMP(7851), TIMER_COMP(7498), TIMER_COMP(7137), TIMER_COMP(6809),
+ TIMER_COMP(6478), TIMER_COMP(6178), TIMER_COMP(5879), TIMER_COMP(5607), TIMER_COMP(5359),
+ TIMER_COMP(5093), TIMER_COMP(4870), TIMER_COMP(4633), TIMER_COMP(4418), TIMER_COMP(4209),
+ TIMER_COMP(4019), TIMER_COMP(3823), TIMER_COMP(3645), TIMER_COMP(3474), TIMER_COMP(3310),
+ TIMER_COMP(3161), TIMER_COMP(3011), TIMER_COMP(2869), TIMER_COMP(2734), TIMER_COMP(2611),
+ TIMER_COMP(2484), TIMER_COMP(2369), TIMER_COMP(2257), TIMER_COMP(2152), TIMER_COMP(2052),
+ TIMER_COMP(1956), TIMER_COMP(1866), TIMER_COMP(1779), TIMER_COMP(1695), TIMER_COMP(1615),
+ TIMER_COMP(1539), TIMER_COMP(1468), TIMER_COMP(1398), TIMER_COMP(1333), TIMER_COMP(1271),
+ TIMER_COMP(1212), TIMER_COMP(1155), TIMER_COMP(1101), TIMER_COMP(1049), TIMER_COMP(1000),
+ TIMER_COMP(953), TIMER_COMP(909), TIMER_COMP(866), TIMER_COMP(826), TIMER_COMP(787),
+ TIMER_COMP(750), TIMER_COMP(715), TIMER_COMP(682), TIMER_COMP(650), TIMER_COMP(619),
+ TIMER_COMP(590), TIMER_COMP(563), TIMER_COMP(536), TIMER_COMP(511), TIMER_COMP(487),
+ TIMER_COMP(465), TIMER_COMP(443), TIMER_COMP(422), TIMER_COMP(402), TIMER_COMP(384),
+ TIMER_COMP(366), TIMER_COMP(349), TIMER_COMP(332), TIMER_COMP(317), TIMER_COMP(302),
+ TIMER_COMP(288), TIMER_COMP(274), TIMER_COMP(261), TIMER_COMP(249), TIMER_COMP(238),
+ TIMER_COMP(226), TIMER_COMP(216), TIMER_COMP(206), TIMER_COMP(196), TIMER_COMP(187),
+ TIMER_COMP(178), TIMER_COMP(170), TIMER_COMP(162), TIMER_COMP(154), TIMER_COMP(147),
+ TIMER_COMP(140), TIMER_COMP(134), TIMER_COMP(128), TIMER_COMP(122), TIMER_COMP(116),
+ TIMER_COMP(111), TIMER_COMP(105), TIMER_COMP(100), TIMER_COMP(95.4), TIMER_COMP(90.9),
+ TIMER_COMP(86.6), TIMER_COMP(82.6), TIMER_COMP(78.7), TIMER_COMP(75.0), TIMER_COMP(71.5),
+ TIMER_COMP(68.2), TIMER_COMP(65.0), TIMER_COMP(61.9), TIMER_COMP(59.0), TIMER_COMP(56.3),
+ TIMER_COMP(53.6), TIMER_COMP(51.1)
+};
+
+/** Currently selected SPI driver, either hardware (for fast ISP speeds) or software (for slower ISP speeds). */
+bool HardwareSPIMode = true;
+
+/** Software SPI data register for sending and receiving */
+static volatile uint8_t SoftSPI_Data;
+
+/** Number of bits left to transfer in the software SPI driver */
+static volatile uint8_t SoftSPI_BitsRemaining;
+
+
+/** ISR to handle software SPI transmission and reception */
+ISR(TIMER1_COMPA_vect, ISR_BLOCK)
+{
+ /* Check if rising edge (output next bit) or falling edge (read in next bit) */
+ if (!(PINB & (1 << 1)))
+ {
+ if (SoftSPI_Data & (1 << 7))
+ PORTB |= (1 << 2);
+ else
+ PORTB &= ~(1 << 2);
+ }
+ else
+ {
+ SoftSPI_Data <<= 1;
+
+ if (!(--SoftSPI_BitsRemaining))
+ {
+ TCCR1B = 0;
+ TIFR1 = (1 << OCF1A);
+ }
+
+ if (PINB & (1 << 3))
+ SoftSPI_Data |= (1 << 0);
+ }
+
+ /* Fast toggle of PORTB.1 via the PIN register (see datasheet) */
+ PINB |= (1 << 1);
+}
+
+/** Initializes the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for
+ * communication with the attached target.
+ */
+void ISPTarget_EnableTargetISP(void)
+{
+ uint8_t SCKDuration = V2Params_GetParameterValue(PARAM_SCK_DURATION);
+
+ if (SCKDuration < sizeof(SPIMaskFromSCKDuration))
+ {
+ HardwareSPIMode = true;
+
+ SPI_Init(pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST |
+ SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER);
+ }
+ else
+ {
+ HardwareSPIMode = false;
+
+ DDRB |= ((1 << 1) | (1 << 2));
+ PORTB |= ((1 << 0) | (1 << 3));
+
+ ISPTarget_ConfigureSoftwareSPI(SCKDuration);
+ }
+}
+
+/** Shuts down the current selected SPI driver (hardware or software, depending on the selected ISP speed) so that no
+ * further communications can occur until the driver is re-initialized.
+ */
+void ISPTarget_DisableTargetISP(void)
+{
+ if (HardwareSPIMode)
+ {
+ SPI_Disable();
+ }
+ else
+ {
+ DDRB &= ~((1 << 1) | (1 << 2));
+ PORTB &= ~((1 << 0) | (1 << 3));
+
+ /* Must re-enable rescue clock once software ISP has exited, as the timer for the rescue clock is
+ * re-purposed for software SPI */
+ ISPTarget_ConfigureRescueClock();
+ }
+}
+
+/** Configures the AVR to produce a 4MHz rescue clock out of the OCR1A pin of the AVR, so
+ * that it can be fed into the XTAL1 pin of an AVR whose fuses have been mis-configured for
+ * an external clock rather than a crystal. When used, the ISP speed must be 125KHz for this
+ * functionality to work correctly.
+ */
+void ISPTarget_ConfigureRescueClock(void)
+{
+ #if defined(XCK_RESCUE_CLOCK_ENABLE)
+ /* Configure XCK as an output for the specified AVR model */
+ DDRD |= (1 << 5);
+
+ /* Start USART to generate a 4MHz clock on the XCK pin */
+ UBRR1 = ((F_CPU / 2 / ISP_RESCUE_CLOCK_SPEED) - 1);
+ UCSR1B = (1 << TXEN1);
+ UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
+ #else
+ /* Configure OCR1A as an output for the specified AVR model */
+ #if defined(USB_SERIES_2_AVR)
+ DDRC |= (1 << 6);
+ #else
+ DDRB |= (1 << 5);
+ #endif
+
+ /* Start Timer 1 to generate a 4MHz clock on the OCR1A pin */
+ TIMSK1 = 0;
+ TCNT1 = 0;
+ OCR1A = ((F_CPU / 2 / ISP_RESCUE_CLOCK_SPEED) - 1);
+ TCCR1A = (1 << COM1A0);
+ TCCR1B = ((1 << WGM12) | (1 << CS10));
+ #endif
+}
+
+/** Configures the AVR's timer ready to produce software SPI for the slower ISP speeds that
+ * cannot be obtained when using the AVR's hardware SPI module.
+ *
+ * \param[in] SCKDuration Duration of the desired software ISP SCK clock
+ */
+void ISPTarget_ConfigureSoftwareSPI(const uint8_t SCKDuration)
+{
+ /* Configure Timer 1 for software SPI using the specified SCK duration */
+ TIMSK1 = (1 << OCIE1A);
+ TCNT1 = 0;
+ OCR1A = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]);
+ TCCR1A = 0;
+ TCCR1B = 0;
+}
+
+/** Sends and receives a single byte of data to and from the attached target via software SPI.
+ *
+ * \param[in] Byte Byte of data to send to the attached target
+ *
+ * \return Received byte of data from the attached target
+ */
+uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte)
+{
+ SoftSPI_Data = Byte;
+ SoftSPI_BitsRemaining = 8;
+
+ /* Set initial MOSI pin state according to the byte to be transferred */
+ if (SoftSPI_Data & (1 << 7))
+ PORTB |= (1 << 2);
+ else
+ PORTB &= ~(1 << 2);
+
+ TCNT1 = 0;
+ TCCR1B = ((1 << WGM12) | (1 << CS11));
+ while (SoftSPI_BitsRemaining && TimeoutTicksRemaining);
+ TCCR1B = 0;
+
+ return SoftSPI_Data;
+}
+
+/** Asserts or deasserts the target's reset line, using the correct polarity as set by the host using a SET PARAM command.
+ * When not asserted, the line is tristated so as not to interfere with normal device operation.
+ *
+ * \param[in] ResetTarget Boolean true when the target should be held in reset, \c false otherwise
+ */
+void ISPTarget_ChangeTargetResetLine(const bool ResetTarget)
+{
+ if (ResetTarget)
+ {
+ AUX_LINE_DDR |= AUX_LINE_MASK;
+
+ if (!(V2Params_GetParameterValue(PARAM_RESET_POLARITY)))
+ AUX_LINE_PORT |= AUX_LINE_MASK;
+ else
+ AUX_LINE_PORT &= ~AUX_LINE_MASK;
+ }
+ else
+ {
+ AUX_LINE_DDR &= ~AUX_LINE_MASK;
+ AUX_LINE_PORT &= ~AUX_LINE_MASK;
+ }
+}
+
+/** Waits until the target has completed the last operation, by continuously polling the device's
+ * BUSY flag until it is cleared, or until the command timeout period has expired.
+ *
+ * \return V2 Protocol status \ref STATUS_CMD_OK if the no timeout occurred, \ref STATUS_RDY_BSY_TOUT otherwise
+ */
+uint8_t ISPTarget_WaitWhileTargetBusy(void)
+{
+ do
+ {
+ ISPTarget_SendByte(0xF0);
+ ISPTarget_SendByte(0x00);
+ ISPTarget_SendByte(0x00);
+ }
+ while ((ISPTarget_ReceiveByte() & 0x01) && TimeoutTicksRemaining);
+
+ return (TimeoutTicksRemaining > 0) ? STATUS_CMD_OK : STATUS_RDY_BSY_TOUT;
+}
+
+/** Sends a low-level LOAD EXTENDED ADDRESS command to the target, for addressing of memory beyond the
+ * 64KB boundary. This sends the command with the correct address as indicated by the current address
+ * pointer variable set by the host when a SET ADDRESS command is issued.
+ */
+void ISPTarget_LoadExtendedAddress(void)
+{
+ ISPTarget_SendByte(LOAD_EXTENDED_ADDRESS_CMD);
+ ISPTarget_SendByte(0x00);
+ ISPTarget_SendByte(CurrentAddress >> 16);
+ ISPTarget_SendByte(0x00);
+}
+
+/** Waits until the last issued target memory programming command has completed, via the check mode given and using
+ * the given parameters.
+ *
+ * \param[in] ProgrammingMode Programming mode used and completion check to use, a mask of \c PROG_MODE_* constants
+ * \param[in] PollAddress Memory address to poll for completion if polling check mode used
+ * \param[in] PollValue Poll value to check against if polling check mode used
+ * \param[in] DelayMS Milliseconds to delay before returning if delay check mode used
+ * \param[in] ReadMemCommand Device low-level READ MEMORY command to send if value check mode used
+ *
+ * \return V2 Protocol status \ref STATUS_CMD_OK if the no timeout occurred, \ref STATUS_RDY_BSY_TOUT or
+ * \ref STATUS_CMD_TOUT otherwise
+ */
+uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode,
+ const uint16_t PollAddress,
+ const uint8_t PollValue,
+ const uint8_t DelayMS,
+ const uint8_t ReadMemCommand)
+{
+ uint8_t ProgrammingStatus = STATUS_CMD_OK;
+
+ /* Determine method of Programming Complete check */
+ switch (ProgrammingMode & ~(PROG_MODE_PAGED_WRITES_MASK | PROG_MODE_COMMIT_PAGE_MASK))
+ {
+ case PROG_MODE_WORD_TIMEDELAY_MASK:
+ case PROG_MODE_PAGED_TIMEDELAY_MASK:
+ ISPProtocol_DelayMS(DelayMS);
+ break;
+ case PROG_MODE_WORD_VALUE_MASK:
+ case PROG_MODE_PAGED_VALUE_MASK:
+ do
+ {
+ ISPTarget_SendByte(ReadMemCommand);
+ ISPTarget_SendByte(PollAddress >> 8);
+ ISPTarget_SendByte(PollAddress & 0xFF);
+ }
+ while ((ISPTarget_TransferByte(0x00) == PollValue) && TimeoutTicksRemaining);
+
+ if (!(TimeoutTicksRemaining))
+ ProgrammingStatus = STATUS_CMD_TOUT;
+
+ break;
+ case PROG_MODE_WORD_READYBUSY_MASK:
+ case PROG_MODE_PAGED_READYBUSY_MASK:
+ ProgrammingStatus = ISPTarget_WaitWhileTargetBusy();
+ break;
+ }
+
+ /* Program complete - reset timeout */
+ TimeoutTicksRemaining = COMMAND_TIMEOUT_TICKS;
+
+ return ProgrammingStatus;
+}
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h
new file mode 100644
index 000000000..1687abac1
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h
@@ -0,0 +1,147 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 ISPTarget.c.
+ */
+
+#ifndef _ISP_TARGET_
+#define _ISP_TARGET_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/pgmspace.h>
+ #include <util/delay.h>
+
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/Peripheral/SPI.h>
+
+ #include "../V2Protocol.h"
+ #include "ISPProtocol.h"
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+ #undef ENABLE_ISP_PROTOCOL
+
+ #if !defined(ENABLE_XPROG_PROTOCOL)
+ #define ENABLE_XPROG_PROTOCOL
+ #endif
+ #endif
+
+ /* Macros: */
+ /** Low level device command to issue an extended FLASH address, for devices with over 128KB of FLASH. */
+ #define LOAD_EXTENDED_ADDRESS_CMD 0x4D
+
+ /** Macro to convert an ISP frequency to a number of timer clock cycles for the software SPI driver. */
+ #define TIMER_COMP(freq) (((F_CPU / 8) / 2 / freq) - 1)
+
+ /** ISP rescue clock speed in Hz, for clocking targets with incorrectly set fuses. */
+ #define ISP_RESCUE_CLOCK_SPEED 4000000
+
+ /* External Variables: */
+ extern bool HardwareSPIMode;
+
+ /* Function Prototypes: */
+ void ISPTarget_EnableTargetISP(void);
+ void ISPTarget_DisableTargetISP(void);
+ void ISPTarget_ConfigureRescueClock(void);
+ void ISPTarget_ConfigureSoftwareSPI(const uint8_t SCKDuration);
+ uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte);
+ void ISPTarget_ChangeTargetResetLine(const bool ResetTarget);
+ uint8_t ISPTarget_WaitWhileTargetBusy(void);
+ void ISPTarget_LoadExtendedAddress(void);
+ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode,
+ const uint16_t PollAddress,
+ const uint8_t PollValue,
+ const uint8_t DelayMS,
+ const uint8_t ReadMemCommand);
+
+ /* Inline Functions: */
+ /** Sends a byte of ISP data to the attached target, using the appropriate SPI hardware or
+ * software routines depending on the selected ISP speed.
+ *
+ * \param[in] Byte Byte of data to send to the attached target
+ */
+ static inline void ISPTarget_SendByte(const uint8_t Byte)
+ {
+ if (HardwareSPIMode)
+ SPI_SendByte(Byte);
+ else
+ ISPTarget_TransferSoftSPIByte(Byte);
+ }
+
+ /** Receives a byte of ISP data from the attached target, using the appropriate
+ * SPI hardware or software routines depending on the selected ISP speed.
+ *
+ * \return Received byte of data from the attached target
+ */
+ static inline uint8_t ISPTarget_ReceiveByte(void)
+ {
+ uint8_t ReceivedByte;
+
+ if (HardwareSPIMode)
+ ReceivedByte = SPI_ReceiveByte();
+ else
+ ReceivedByte = ISPTarget_TransferSoftSPIByte(0x00);
+
+ #if defined(INVERTED_ISP_MISO)
+ return ~ReceivedByte;
+ #else
+ return ReceivedByte;
+ #endif
+ }
+
+ /** Sends and receives a byte of ISP data to and from the attached target, using the
+ * appropriate SPI hardware or software routines depending on the selected ISP speed.
+ *
+ * \param[in] Byte Byte of data to send to the attached target
+ *
+ * \return Received byte of data from the attached target
+ */
+ static inline uint8_t ISPTarget_TransferByte(const uint8_t Byte)
+ {
+ uint8_t ReceivedByte;
+
+ if (HardwareSPIMode)
+ ReceivedByte = SPI_TransferByte(Byte);
+ else
+ ReceivedByte = ISPTarget_TransferSoftSPIByte(Byte);
+
+ #if defined(INVERTED_ISP_MISO)
+ return ~ReceivedByte;
+ #else
+ return ReceivedByte;
+ #endif
+ }
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.c
new file mode 100644
index 000000000..a4fada724
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.c
@@ -0,0 +1,267 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * V2Protocol handler, to process V2 Protocol commands used in Atmel programmer devices.
+ */
+
+#define INCLUDE_FROM_V2PROTOCOL_C
+#include "V2Protocol.h"
+
+/** Current memory address for FLASH/EEPROM memory read/write commands */
+uint32_t CurrentAddress;
+
+/** Flag to indicate that the next read/write operation must update the device's current extended FLASH address */
+bool MustLoadExtendedAddress;
+
+
+/** ISR to manage timeouts whilst processing a V2Protocol command */
+ISR(TIMER0_COMPA_vect, ISR_NOBLOCK)
+{
+ if (TimeoutTicksRemaining)
+ TimeoutTicksRemaining--;
+ else
+ TCCR0B = 0;
+}
+
+/** Initializes the hardware and software associated with the V2 protocol command handling. */
+void V2Protocol_Init(void)
+{
+ #if defined(ADC) && !defined(NO_VTARGET_DETECT)
+ /* Initialize the ADC converter for VTARGET level detection on supported AVR models */
+ ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_128);
+ ADC_SetupChannel(VTARGET_ADC_CHANNEL);
+ ADC_StartReading(VTARGET_REF_MASK | ADC_RIGHT_ADJUSTED | VTARGET_ADC_CHANNEL_MASK);
+ #endif
+
+ /* Timeout timer initialization (~10ms period) */
+ OCR0A = (((F_CPU / 1024) / 100) - 1);
+ TCCR0A = (1 << WGM01);
+ TIMSK0 = (1 << OCIE0A);
+
+ V2Params_LoadNonVolatileParamValues();
+
+ #if defined(ENABLE_ISP_PROTOCOL)
+ ISPTarget_ConfigureRescueClock();
+ #endif
+}
+
+/** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host.
+ * This routine decodes the issued command and passes off the handling of the command to the
+ * appropriate function.
+ */
+void V2Protocol_ProcessCommand(void)
+{
+ uint8_t V2Command = Endpoint_Read_8();
+
+ /* Reset timeout counter duration and start the timer */
+ TimeoutTicksRemaining = COMMAND_TIMEOUT_TICKS;
+ TCCR0B = ((1 << CS02) | (1 << CS00));
+
+ switch (V2Command)
+ {
+ case CMD_SIGN_ON:
+ V2Protocol_SignOn();
+ break;
+ case CMD_SET_PARAMETER:
+ case CMD_GET_PARAMETER:
+ V2Protocol_GetSetParam(V2Command);
+ break;
+ case CMD_LOAD_ADDRESS:
+ V2Protocol_LoadAddress();
+ break;
+ case CMD_RESET_PROTECTION:
+ V2Protocol_ResetProtection();
+ break;
+#if defined(ENABLE_ISP_PROTOCOL)
+ case CMD_ENTER_PROGMODE_ISP:
+ ISPProtocol_EnterISPMode();
+ break;
+ case CMD_LEAVE_PROGMODE_ISP:
+ ISPProtocol_LeaveISPMode();
+ break;
+ case CMD_PROGRAM_FLASH_ISP:
+ case CMD_PROGRAM_EEPROM_ISP:
+ ISPProtocol_ProgramMemory(V2Command);
+ break;
+ case CMD_READ_FLASH_ISP:
+ case CMD_READ_EEPROM_ISP:
+ ISPProtocol_ReadMemory(V2Command);
+ break;
+ case CMD_CHIP_ERASE_ISP:
+ ISPProtocol_ChipErase();
+ break;
+ case CMD_READ_FUSE_ISP:
+ case CMD_READ_LOCK_ISP:
+ case CMD_READ_SIGNATURE_ISP:
+ case CMD_READ_OSCCAL_ISP:
+ ISPProtocol_ReadFuseLockSigOSCCAL(V2Command);
+ break;
+ case CMD_PROGRAM_FUSE_ISP:
+ case CMD_PROGRAM_LOCK_ISP:
+ ISPProtocol_WriteFuseLock(V2Command);
+ break;
+ case CMD_SPI_MULTI:
+ ISPProtocol_SPIMulti();
+ break;
+#endif
+#if defined(ENABLE_XPROG_PROTOCOL)
+ case CMD_XPROG_SETMODE:
+ XPROGProtocol_SetMode();
+ break;
+ case CMD_XPROG:
+ XPROGProtocol_Command();
+ break;
+#endif
+ default:
+ V2Protocol_UnknownCommand(V2Command);
+ break;
+ }
+
+ /* Disable the timeout management timer */
+ TCCR0B = 0;
+
+ Endpoint_WaitUntilReady();
+ Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
+}
+
+/** Handler for unknown V2 protocol commands. This discards all sent data and returns a
+ * STATUS_CMD_UNKNOWN status back to the host.
+ *
+ * \param[in] V2Command Issued V2 Protocol command byte from the host
+ */
+static void V2Protocol_UnknownCommand(const uint8_t V2Command)
+{
+ /* Discard all incoming data */
+ while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)
+ {
+ Endpoint_ClearOUT();
+ Endpoint_WaitUntilReady();
+ }
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(V2Command);
+ Endpoint_Write_8(STATUS_CMD_UNKNOWN);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_SIGN_ON command, returning the programmer ID string to the host. */
+static void V2Protocol_SignOn(void)
+{
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(CMD_SIGN_ON);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_Write_8(sizeof(PROGRAMMER_ID) - 1);
+ Endpoint_Write_Stream_LE(PROGRAMMER_ID, (sizeof(PROGRAMMER_ID) - 1), NULL);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_RESET_PROTECTION command, implemented as a dummy ACK function as
+ * no target short-circuit protection is currently implemented.
+ */
+static void V2Protocol_ResetProtection(void)
+{
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(CMD_RESET_PROTECTION);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_ClearIN();
+}
+
+
+/** Handler for the CMD_SET_PARAMETER and CMD_GET_PARAMETER commands from the host, setting or
+ * getting a device parameter's value from the parameter table.
+ *
+ * \param[in] V2Command Issued V2 Protocol command byte from the host
+ */
+static void V2Protocol_GetSetParam(const uint8_t V2Command)
+{
+ uint8_t ParamID = Endpoint_Read_8();
+ uint8_t ParamValue;
+
+ if (V2Command == CMD_SET_PARAMETER)
+ ParamValue = Endpoint_Read_8();
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(V2Command);
+
+ uint8_t ParamPrivs = V2Params_GetParameterPrivileges(ParamID);
+
+ if ((V2Command == CMD_SET_PARAMETER) && (ParamPrivs & PARAM_PRIV_WRITE))
+ {
+ Endpoint_Write_8(STATUS_CMD_OK);
+ V2Params_SetParameterValue(ParamID, ParamValue);
+ }
+ else if ((V2Command == CMD_GET_PARAMETER) && (ParamPrivs & PARAM_PRIV_READ))
+ {
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_Write_8(V2Params_GetParameterValue(ParamID));
+ }
+ else
+ {
+ Endpoint_Write_8(STATUS_CMD_FAILED);
+ }
+
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_LOAD_ADDRESS command, loading the given device address into a
+ * global storage variable for later use, and issuing LOAD EXTENDED ADDRESS commands
+ * to the attached device as required.
+ */
+static void V2Protocol_LoadAddress(void)
+{
+ Endpoint_Read_Stream_BE(&CurrentAddress, sizeof(CurrentAddress), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ if (CurrentAddress & (1UL << 31))
+ MustLoadExtendedAddress = true;
+
+ Endpoint_Write_8(CMD_LOAD_ADDRESS);
+ Endpoint_Write_8(STATUS_CMD_OK);
+ Endpoint_ClearIN();
+}
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.h
new file mode 100644
index 000000000..143e6965d
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.h
@@ -0,0 +1,105 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 V2Protocol.c.
+ */
+
+#ifndef _V2_PROTOCOL_
+#define _V2_PROTOCOL_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/interrupt.h>
+ #include <avr/wdt.h>
+
+ #include <LUFA/Drivers/USB/USB.h>
+
+ #include "../AVRISPDescriptors.h"
+ #include "V2ProtocolConstants.h"
+ #include "V2ProtocolParams.h"
+ #include "ISP/ISPProtocol.h"
+ #include "XPROG/XPROGProtocol.h"
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+ #undef ENABLE_ISP_PROTOCOL
+
+ #if !defined(ENABLE_XPROG_PROTOCOL)
+ #define ENABLE_XPROG_PROTOCOL
+ #endif
+ #endif
+
+ #if defined(USB_SERIES_4_AVR) && ((VTARGET_ADC_CHANNEL == 2) || (VTARGET_ADC_CHANNEL == 3)) && !defined(NO_VTARGET_DETECT)
+ #error The U4 AVR chips do not contain ADC channels 2 or 3. Please change VTARGET_ADC_CHANNEL or define NO_VTARGET_DETECT in the makefile.
+ #endif
+
+ #if defined(VTARGET_USE_INTERNAL_REF)
+ #undef VTARGET_REF_VOLTS
+ #define VTARGET_REF_VOLTS 2.56
+
+ #define VTARGET_REF_MASK ADC_REFERENCE_INT2560MV
+ #else
+ #define VTARGET_REF_MASK ADC_REFERENCE_AVCC
+ #endif
+
+ /* Macros: */
+ /** Programmer ID string, returned to the host during the CMD_SIGN_ON command processing. */
+ #define PROGRAMMER_ID "AVRISP_MK2"
+
+ /** Timeout period for each issued command from the host before it is aborted (in 10ms ticks). */
+ #define COMMAND_TIMEOUT_TICKS 100
+
+ /** Command timeout ticks remaining counter, GPIOR for speed. */
+ #define TimeoutTicksRemaining GPIOR1
+
+ /** MUX mask for the VTARGET ADC channel number. */
+ #define VTARGET_ADC_CHANNEL_MASK ADC_GET_CHANNEL_MASK(VTARGET_ADC_CHANNEL)
+
+ /* External Variables: */
+ extern uint32_t CurrentAddress;
+ extern bool MustLoadExtendedAddress;
+
+ /* Function Prototypes: */
+ void V2Protocol_Init(void);
+ void V2Protocol_ProcessCommand(void);
+
+ #if defined(INCLUDE_FROM_V2PROTOCOL_C)
+ static void V2Protocol_UnknownCommand(const uint8_t V2Command);
+ static void V2Protocol_SignOn(void);
+ static void V2Protocol_GetSetParam(const uint8_t V2Command);
+ static void V2Protocol_ResetProtection(void);
+ static void V2Protocol_LoadAddress(void);
+ #endif
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolConstants.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolConstants.h
new file mode 100644
index 000000000..efa8ee674
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolConstants.h
@@ -0,0 +1,90 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * Macros for the V2 Protocol Packet Commands and Responses.
+ */
+
+#ifndef _V2_PROTOCOL_CONSTANTS_
+#define _V2_PROTOCOL_CONSTANTS_
+
+ /* Macros: */
+ #define CMD_SIGN_ON 0x01
+ #define CMD_SET_PARAMETER 0x02
+ #define CMD_GET_PARAMETER 0x03
+ #define CMD_OSCCAL 0x05
+ #define CMD_LOAD_ADDRESS 0x06
+ #define CMD_FIRMWARE_UPGRADE 0x07
+ #define CMD_RESET_PROTECTION 0x0A
+ #define CMD_ENTER_PROGMODE_ISP 0x10
+ #define CMD_LEAVE_PROGMODE_ISP 0x11
+ #define CMD_CHIP_ERASE_ISP 0x12
+ #define CMD_PROGRAM_FLASH_ISP 0x13
+ #define CMD_READ_FLASH_ISP 0x14
+ #define CMD_PROGRAM_EEPROM_ISP 0x15
+ #define CMD_READ_EEPROM_ISP 0x16
+ #define CMD_PROGRAM_FUSE_ISP 0x17
+ #define CMD_READ_FUSE_ISP 0x18
+ #define CMD_PROGRAM_LOCK_ISP 0x19
+ #define CMD_READ_LOCK_ISP 0x1A
+ #define CMD_READ_SIGNATURE_ISP 0x1B
+ #define CMD_READ_OSCCAL_ISP 0x1C
+ #define CMD_SPI_MULTI 0x1D
+ #define CMD_XPROG 0x50
+ #define CMD_XPROG_SETMODE 0x51
+
+ #define STATUS_CMD_OK 0x00
+ #define STATUS_CMD_TOUT 0x80
+ #define STATUS_RDY_BSY_TOUT 0x81
+ #define STATUS_SET_PARAM_MISSING 0x82
+ #define STATUS_CMD_FAILED 0xC0
+ #define STATUS_CMD_UNKNOWN 0xC9
+ #define STATUS_CMD_ILLEGAL_PARAM 0xCA
+ #define STATUS_ISP_READY 0x00
+ #define STATUS_CONN_FAIL_MOSI 0x01
+ #define STATUS_CONN_FAIL_RST 0x02
+ #define STATUS_CONN_FAIL_SCK 0x04
+ #define STATUS_TGT_NOT_DETECTED 0x10
+ #define STATUS_TGT_REVERSE_INSERTED 0x20
+
+ #define PARAM_BUILD_NUMBER_LOW 0x80
+ #define PARAM_BUILD_NUMBER_HIGH 0x81
+ #define PARAM_HW_VER 0x90
+ #define PARAM_SW_MAJOR 0x91
+ #define PARAM_SW_MINOR 0x92
+ #define PARAM_VTARGET 0x94
+ #define PARAM_SCK_DURATION 0x98
+ #define PARAM_RESET_POLARITY 0x9E
+ #define PARAM_STATUS_TGT_CONN 0xA1
+ #define PARAM_DISCHARGEDELAY 0xA4
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c
new file mode 100644
index 000000000..2f287060c
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c
@@ -0,0 +1,207 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * V2Protocol parameter handler, to process V2 Protocol device parameters.
+ */
+
+#define INCLUDE_FROM_V2PROTOCOL_PARAMS_C
+#include "V2ProtocolParams.h"
+
+/* Non-Volatile Parameter Values for EEPROM storage */
+static uint8_t EEMEM EEPROM_Reset_Polarity = 0x01;
+
+/* Non-Volatile Parameter Values for EEPROM storage */
+static uint8_t EEMEM EEPROM_SCK_Duration = 0x06;
+
+/* Volatile Parameter Values for RAM storage */
+static ParameterItem_t ParameterTable[] =
+ {
+ { .ParamID = PARAM_BUILD_NUMBER_LOW,
+ .ParamPrivileges = PARAM_PRIV_READ,
+ .ParamValue = 0 },
+
+ { .ParamID = PARAM_BUILD_NUMBER_HIGH,
+ .ParamPrivileges = PARAM_PRIV_READ,
+ .ParamValue = 0 },
+
+ { .ParamID = PARAM_HW_VER,
+ .ParamPrivileges = PARAM_PRIV_READ,
+ .ParamValue = 0x00 },
+
+ { .ParamID = PARAM_SW_MAJOR,
+ .ParamPrivileges = PARAM_PRIV_READ,
+ .ParamValue = 0x01 },
+
+ { .ParamID = PARAM_SW_MINOR,
+ .ParamPrivileges = PARAM_PRIV_READ,
+ .ParamValue = FIRMWARE_VERSION_MINOR },
+
+ { .ParamID = PARAM_VTARGET,
+ .ParamPrivileges = PARAM_PRIV_READ,
+ .ParamValue = (uint8_t)(3.3 * 10) },
+
+ { .ParamID = PARAM_SCK_DURATION,
+ .ParamPrivileges = PARAM_PRIV_READ | PARAM_PRIV_WRITE,
+ .ParamValue = 6 },
+
+ { .ParamID = PARAM_RESET_POLARITY,
+ .ParamPrivileges = PARAM_PRIV_READ | PARAM_PRIV_WRITE,
+ .ParamValue = 0x01 },
+
+ { .ParamID = PARAM_STATUS_TGT_CONN,
+ .ParamPrivileges = PARAM_PRIV_READ,
+ .ParamValue = STATUS_ISP_READY },
+
+ { .ParamID = PARAM_DISCHARGEDELAY,
+ .ParamPrivileges = PARAM_PRIV_READ | PARAM_PRIV_WRITE,
+ .ParamValue = 0x00 },
+ };
+
+
+/** Loads saved non-volatile parameter values from the EEPROM into the parameter table, as needed. */
+void V2Params_LoadNonVolatileParamValues(void)
+{
+ /* Read parameter values that are stored in non-volatile EEPROM */
+ uint8_t ResetPolarity = eeprom_read_byte(&EEPROM_Reset_Polarity);
+ uint8_t SCKDuration = eeprom_read_byte(&EEPROM_SCK_Duration);
+
+ /* Update current parameter table if the EEPROM contents was not blank */
+ if (ResetPolarity != 0xFF)
+ V2Params_GetParamFromTable(PARAM_RESET_POLARITY)->ParamValue = ResetPolarity;
+
+ /* Update current parameter table if the EEPROM contents was not blank */
+ if (SCKDuration != 0xFF)
+ V2Params_GetParamFromTable(PARAM_SCK_DURATION)->ParamValue = SCKDuration;
+}
+
+/** Updates any parameter values that are sourced from hardware rather than explicitly set by the host, such as
+ * VTARGET levels from the ADC on supported AVR models.
+ */
+void V2Params_UpdateParamValues(void)
+{
+ #if (defined(ADC) && !defined(NO_VTARGET_DETECT))
+ /* Update VTARGET parameter with the latest ADC conversion of VTARGET on supported AVR models */
+ V2Params_GetParamFromTable(PARAM_VTARGET)->ParamValue = (((uint16_t)(VTARGET_REF_VOLTS * 10 * VTARGET_SCALE_FACTOR) * ADC_GetResult()) / 1024);
+ #endif
+}
+
+/** Retrieves the host PC read/write privileges for a given parameter in the parameter table. This should
+ * be called before calls to \ref V2Params_GetParameterValue() or \ref V2Params_SetParameterValue() when
+ * getting or setting parameter values in response to requests from the host.
+ *
+ * \param[in] ParamID Parameter ID whose privileges are to be retrieved from the table
+ *
+ * \return Privileges for the requested parameter, as a mask of \c PARAM_PRIV_* masks
+ */
+uint8_t V2Params_GetParameterPrivileges(const uint8_t ParamID)
+{
+ ParameterItem_t* const ParamInfo = V2Params_GetParamFromTable(ParamID);
+
+ if (ParamInfo == NULL)
+ return 0;
+
+ return ParamInfo->ParamPrivileges;
+}
+
+/** Retrieves the current value for a given parameter in the parameter table.
+ *
+ * \note This function does not first check for read privileges - if the value is being sent to the host via a
+ * GET PARAM command, \ref V2Params_GetParameterPrivileges() should be called first to ensure that the
+ * parameter is host-readable.
+ *
+ * \param[in] ParamID Parameter ID whose value is to be retrieved from the table
+ *
+ * \return Current value of the parameter in the table, or 0 if not found
+ */
+uint8_t V2Params_GetParameterValue(const uint8_t ParamID)
+{
+ ParameterItem_t* const ParamInfo = V2Params_GetParamFromTable(ParamID);
+
+ if (ParamInfo == NULL)
+ return 0;
+
+ return ParamInfo->ParamValue;
+}
+
+/** Sets the value for a given parameter in the parameter table.
+ *
+ * \note This function does not first check for write privileges - if the value is being sourced from the host
+ * via a SET PARAM command, \ref V2Params_GetParameterPrivileges() should be called first to ensure that the
+ * parameter is host-writable.
+ *
+ * \param[in] ParamID Parameter ID whose value is to be set in the table
+ * \param[in] Value New value to set the parameter to
+ *
+ * \return Pointer to the associated parameter information from the parameter table if found, NULL otherwise
+ */
+void V2Params_SetParameterValue(const uint8_t ParamID,
+ const uint8_t Value)
+{
+ ParameterItem_t* const ParamInfo = V2Params_GetParamFromTable(ParamID);
+
+ if (ParamInfo == NULL)
+ return;
+
+ ParamInfo->ParamValue = Value;
+
+ /* The target RESET line polarity is a non-volatile parameter, save to EEPROM when changed */
+ if (ParamID == PARAM_RESET_POLARITY)
+ eeprom_update_byte(&EEPROM_Reset_Polarity, Value);
+
+ /* The target SCK line period is a non-volatile parameter, save to EEPROM when changed */
+ if (ParamID == PARAM_SCK_DURATION)
+ eeprom_update_byte(&EEPROM_SCK_Duration, Value);
+}
+
+/** Retrieves a parameter entry (including ID, value and privileges) from the parameter table that matches the given
+ * parameter ID.
+ *
+ * \param[in] ParamID Parameter ID to find in the table
+ *
+ * \return Pointer to the associated parameter information from the parameter table if found, NULL otherwise
+ */
+static ParameterItem_t* const V2Params_GetParamFromTable(const uint8_t ParamID)
+{
+ ParameterItem_t* CurrTableItem = ParameterTable;
+
+ /* Find the parameter in the parameter table if present */
+ for (uint8_t TableIndex = 0; TableIndex < TABLE_PARAM_COUNT; TableIndex++)
+ {
+ if (ParamID == CurrTableItem->ParamID)
+ return CurrTableItem;
+
+ CurrTableItem++;
+ }
+
+ return NULL;
+}
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h
new file mode 100644
index 000000000..1155dbe4d
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h
@@ -0,0 +1,91 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 V2ProtocolParams.c.
+ */
+
+#ifndef _V2_PROTOCOL_PARAMS_
+#define _V2_PROTOCOL_PARAMS_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/eeprom.h>
+
+ #if defined(ADC)
+ #include <LUFA/Drivers/Peripheral/ADC.h>
+ #endif
+
+ #include "V2Protocol.h"
+ #include "V2ProtocolConstants.h"
+ #include "ISP/ISPTarget.h"
+ #include "Config/AppConfig.h"
+
+ /* Macros: */
+ /** Parameter privilege mask to allow the host PC to read the parameter's value. */
+ #define PARAM_PRIV_READ (1 << 0)
+
+ /** Parameter privilege mask to allow the host PC to change the parameter's value. */
+ #define PARAM_PRIV_WRITE (1 << 1)
+
+ /** Total number of parameters in the parameter table */
+ #define TABLE_PARAM_COUNT (sizeof(ParameterTable) / sizeof(ParameterTable[0]))
+
+ #if (!defined(FIRMWARE_VERSION_MINOR) || defined(__DOXYGEN__))
+ /** Minor firmware version, reported to the host on request; must match the version
+ * the host is expecting, or it (may) reject further communications with the programmer. */
+ #define FIRMWARE_VERSION_MINOR 0x17
+ #endif
+
+ /* Type Defines: */
+ /** Type define for a parameter table entry indicating a PC readable or writable device parameter. */
+ typedef struct
+ {
+ const uint8_t ParamID; /**< Parameter ID number to uniquely identify the parameter within the device */
+ const uint8_t ParamPrivileges; /**< Parameter privileges to allow the host to read or write the parameter's value */
+ uint8_t ParamValue; /**< Current parameter's value within the device */
+ } ParameterItem_t;
+
+ /* Function Prototypes: */
+ void V2Params_LoadNonVolatileParamValues(void);
+ void V2Params_UpdateParamValues(void);
+
+ uint8_t V2Params_GetParameterPrivileges(const uint8_t ParamID);
+ uint8_t V2Params_GetParameterValue(const uint8_t ParamID);
+ void V2Params_SetParameterValue(const uint8_t ParamID,
+ const uint8_t Value);
+
+ #if defined(INCLUDE_FROM_V2PROTOCOL_PARAMS_C)
+ static ParameterItem_t* const V2Params_GetParamFromTable(const uint8_t ParamID);
+ #endif
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c
new file mode 100644
index 000000000..277e58f2f
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c
@@ -0,0 +1,274 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * Target-related functions for the TINY target's NVM module.
+ */
+
+#define INCLUDE_FROM_TINYNVM_C
+#include "TINYNVM.h"
+
+#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
+
+/** Sends the given pointer address to the target's TPI pointer register */
+static void TINYNVM_SendPointerAddress(const uint16_t AbsoluteAddress)
+{
+ /* Send the given 16-bit address to the target, LSB first */
+ XPROGTarget_SendByte(TPI_CMD_SSTPR | 0);
+ XPROGTarget_SendByte(AbsoluteAddress & 0xFF);
+ XPROGTarget_SendByte(TPI_CMD_SSTPR | 1);
+ XPROGTarget_SendByte(AbsoluteAddress >> 8);
+}
+
+/** Sends a SIN command to the target with the specified I/O address, ready for the data byte to be written.
+ *
+ * \param[in] Address 6-bit I/O address to write to in the target's I/O memory space
+ */
+static void TINYNVM_SendReadNVMRegister(const uint8_t Address)
+{
+ /* The TPI command for reading from the I/O space uses strange addressing, where the I/O address's upper
+ * two bits of the 6-bit address are shifted left once - use function to reduce code size */
+ XPROGTarget_SendByte(TPI_CMD_SIN(Address));
+}
+
+/** Sends a SOUT command to the target with the specified I/O address, ready for the data byte to be read.
+ *
+ * \param[in] Address 6-bit I/O address to read from in the target's I/O memory space
+ */
+static void TINYNVM_SendWriteNVMRegister(const uint8_t Address)
+{
+ /* The TPI command for reading from the I/O space uses strange addressing, where the I/O address's upper
+ * two bits of the 6-bit address are shifted left once - use function to reduce code size */
+ XPROGTarget_SendByte(TPI_CMD_SOUT(Address));
+}
+
+/** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read.
+ *
+ * \return Boolean \c true if the NVM controller became ready within the timeout period, \c false otherwise
+ */
+bool TINYNVM_WaitWhileNVMBusBusy(void)
+{
+ /* Poll the STATUS register to check to see if NVM access has been enabled */
+ for (;;)
+ {
+ /* Send the SLDCS command to read the TPI STATUS register to see the NVM bus is active */
+ XPROGTarget_SendByte(TPI_CMD_SLDCS(TPI_REG_STATUS));
+
+ uint8_t StatusRegister = XPROGTarget_ReceiveByte();
+
+ /* We might have timed out waiting for the status register read response, check here */
+ if (!(TimeoutTicksRemaining))
+ return false;
+
+ /* Check the status register read response to see if the NVM bus is enabled */
+ if (StatusRegister & TPI_STATUS_NVM)
+ return true;
+ }
+}
+
+/** Waits while the target's NVM controller is busy performing an operation, exiting if the
+ * timeout period expires.
+ *
+ * \return Boolean \c true if the NVM controller became ready within the timeout period, \c false otherwise
+ */
+bool TINYNVM_WaitWhileNVMControllerBusy(void)
+{
+ /* Poll the STATUS register to check to see if NVM access has been enabled */
+ for (;;)
+ {
+ /* Send the SIN command to read the TPI STATUS register to see the NVM bus is busy */
+ TINYNVM_SendReadNVMRegister(XPROG_Param_NVMCSRRegAddr);
+
+ uint8_t StatusRegister = XPROGTarget_ReceiveByte();
+
+ /* We might have timed out waiting for the status register read response, check here */
+ if (!(TimeoutTicksRemaining))
+ return false;
+
+ /* Check to see if the BUSY flag is still set */
+ if (!(StatusRegister & (1 << 7)))
+ return true;
+ }
+}
+
+/** Enables the physical TPI interface on the target and enables access to the internal NVM controller.
+ *
+ * \return Boolean \c true if the TPI interface was enabled successfully, \c false otherwise
+ */
+bool TINYNVM_EnableTPI(void)
+{
+ /* Enable TPI programming mode with the attached target */
+ XPROGTarget_EnableTargetTPI();
+
+ /* Lower direction change guard time to 32 USART bits */
+ XPROGTarget_SendByte(TPI_CMD_SSTCS(TPI_REG_CTRL));
+ XPROGTarget_SendByte(0x02);
+
+ /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
+ XPROGTarget_SendByte(TPI_CMD_SKEY);
+ for (uint8_t i = sizeof(TPI_NVMENABLE_KEY); i > 0; i--)
+ XPROGTarget_SendByte(TPI_NVMENABLE_KEY[i - 1]);
+
+ /* Wait until the NVM bus becomes active */
+ return TINYNVM_WaitWhileNVMBusBusy();
+}
+
+/** Removes access to the target's NVM controller and physically disables the target's physical TPI interface. */
+void TINYNVM_DisableTPI(void)
+{
+ TINYNVM_WaitWhileNVMBusBusy();
+
+ do
+ {
+ /* Clear the NVMEN bit in the TPI STATUS register to disable TPI mode */
+ XPROGTarget_SendByte(TPI_CMD_SSTCS(TPI_REG_STATUS));
+ XPROGTarget_SendByte(0x00);
+
+ /* Read back the STATUS register, check to see if it took effect */
+ XPROGTarget_SendByte(TPI_CMD_SLDCS(TPI_REG_STATUS));
+ } while (XPROGTarget_ReceiveByte() != 0x00);
+
+ XPROGTarget_DisableTargetTPI();
+}
+
+/** Reads memory from the target's memory spaces.
+ *
+ * \param[in] ReadAddress Start address to read from within the target's address space
+ * \param[out] ReadBuffer Buffer to store read data into
+ * \param[in] ReadSize Length of the data to read from the device
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool TINYNVM_ReadMemory(const uint16_t ReadAddress,
+ uint8_t* ReadBuffer,
+ uint16_t ReadSize)
+{
+ /* Wait until the NVM controller is no longer busy */
+ if (!(TINYNVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Set the NVM control register to the NO OP command for memory reading */
+ TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
+ XPROGTarget_SendByte(TINY_NVM_CMD_NOOP);
+
+ /* Send the address of the location to read from */
+ TINYNVM_SendPointerAddress(ReadAddress);
+
+ while (ReadSize-- && TimeoutTicksRemaining)
+ {
+ /* Read the byte of data from the target */
+ XPROGTarget_SendByte(TPI_CMD_SLD(TPI_POINTER_INDIRECT_PI));
+ *(ReadBuffer++) = XPROGTarget_ReceiveByte();
+ }
+
+ return (TimeoutTicksRemaining > 0);
+}
+
+/** Writes word addressed memory to the target's memory spaces.
+ *
+ * \param[in] WriteAddress Start address to write to within the target's address space
+ * \param[in] WriteBuffer Buffer to source data from
+ * \param[in] WriteLength Total number of bytes to write to the device (must be an integer multiple of 2)
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool TINYNVM_WriteMemory(const uint16_t WriteAddress,
+ uint8_t* WriteBuffer,
+ uint16_t WriteLength)
+{
+ /* Wait until the NVM controller is no longer busy */
+ if (!(TINYNVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Must have an integer number of words to write - if extra byte, word-align via a dummy high byte */
+ if (WriteLength & 0x01)
+ WriteBuffer[WriteLength++] = 0xFF;
+
+ /* Set the NVM control register to the WORD WRITE command for memory writing */
+ TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
+ XPROGTarget_SendByte(TINY_NVM_CMD_WORDWRITE);
+
+ /* Send the address of the location to write to */
+ TINYNVM_SendPointerAddress(WriteAddress);
+
+ while (WriteLength)
+ {
+ /* Wait until the NVM controller is no longer busy */
+ if (!(TINYNVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Write the low byte of data to the target */
+ XPROGTarget_SendByte(TPI_CMD_SST(TPI_POINTER_INDIRECT_PI));
+ XPROGTarget_SendByte(*(WriteBuffer++));
+
+ /* Write the high byte of data to the target */
+ XPROGTarget_SendByte(TPI_CMD_SST(TPI_POINTER_INDIRECT_PI));
+ XPROGTarget_SendByte(*(WriteBuffer++));
+
+ /* Need to decrement the write length twice, since we wrote a whole two-byte word */
+ WriteLength -= 2;
+ }
+
+ return true;
+}
+
+/** Erases the target's memory space.
+ *
+ * \param[in] EraseCommand NVM erase command to send to the device
+ * \param[in] Address Address inside the memory space to erase
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool TINYNVM_EraseMemory(const uint8_t EraseCommand,
+ const uint16_t Address)
+{
+ /* Wait until the NVM controller is no longer busy */
+ if (!(TINYNVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Set the NVM control register to the target memory erase command */
+ TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
+ XPROGTarget_SendByte(EraseCommand);
+
+ /* Write to a high byte location within the target address space to start the erase process */
+ TINYNVM_SendPointerAddress(Address | 0x0001);
+ XPROGTarget_SendByte(TPI_CMD_SST(TPI_POINTER_INDIRECT));
+ XPROGTarget_SendByte(0x00);
+
+ /* Wait until the NVM controller is no longer busy */
+ if (!(TINYNVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ return true;
+}
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h
new file mode 100644
index 000000000..915c00cc5
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h
@@ -0,0 +1,86 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 TINYNVM.c.
+ */
+
+#ifndef _TINY_NVM_
+#define _TINY_NVM_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/interrupt.h>
+ #include <stdbool.h>
+
+ #include <LUFA/Common/Common.h>
+
+ #include "XPROGProtocol.h"
+ #include "XPROGTarget.h"
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+ #undef ENABLE_ISP_PROTOCOL
+
+ #if !defined(ENABLE_XPROG_PROTOCOL)
+ #define ENABLE_XPROG_PROTOCOL
+ #endif
+ #endif
+
+ /* Defines: */
+ #define TINY_NVM_CMD_NOOP 0x00
+ #define TINY_NVM_CMD_CHIPERASE 0x10
+ #define TINY_NVM_CMD_SECTIONERASE 0x14
+ #define TINY_NVM_CMD_WORDWRITE 0x1D
+
+ /* Function Prototypes: */
+ bool TINYNVM_WaitWhileNVMBusBusy(void);
+ bool TINYNVM_WaitWhileNVMControllerBusy(void);
+ bool TINYNVM_EnableTPI(void);
+ void TINYNVM_DisableTPI(void);
+ bool TINYNVM_ReadMemory(const uint16_t ReadAddress,
+ uint8_t* ReadBuffer,
+ uint16_t ReadLength);
+ bool TINYNVM_WriteMemory(const uint16_t WriteAddress,
+ uint8_t* WriteBuffer,
+ uint16_t WriteLength);
+ bool TINYNVM_EraseMemory(const uint8_t EraseCommand,
+ const uint16_t Address);
+
+ #if (defined(INCLUDE_FROM_TINYNVM_C) && defined(ENABLE_XPROG_PROTOCOL))
+ static void TINYNVM_SendReadNVMRegister(const uint8_t Address);
+ static void TINYNVM_SendWriteNVMRegister(const uint8_t Address);
+ static void TINYNVM_SendPointerAddress(const uint16_t AbsoluteAddress);
+ #endif
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
new file mode 100644
index 000000000..d0b5752fa
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
@@ -0,0 +1,468 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * Target-related functions for the XMEGA target's NVM module.
+ */
+
+#define INCLUDE_FROM_XMEGA_NVM_C
+#include "XMEGANVM.h"
+
+#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
+
+/** Sends the given 32-bit absolute address to the target.
+ *
+ * \param[in] AbsoluteAddress Absolute address to send to the target
+ */
+static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress)
+{
+ /* Send the given 32-bit address to the target, LSB first */
+ XPROGTarget_SendByte(AbsoluteAddress & 0xFF);
+ XPROGTarget_SendByte(AbsoluteAddress >> 8);
+ XPROGTarget_SendByte(AbsoluteAddress >> 16);
+ XPROGTarget_SendByte(AbsoluteAddress >> 24);
+}
+
+/** Sends the given NVM register address to the target.
+ *
+ * \param[in] Register NVM register whose absolute address is to be sent
+ */
+static void XMEGANVM_SendNVMRegAddress(const uint8_t Register)
+{
+ /* Determine the absolute register address from the NVM base memory address and the NVM register address */
+ uint32_t Address = XPROG_Param_NVMBase | Register;
+
+ /* Send the calculated 32-bit address to the target, LSB first */
+ XMEGANVM_SendAddress(Address);
+}
+
+/** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read or CRC
+ * calculation.
+ *
+ * \return Boolean \c true if the NVM controller became ready within the timeout period, \c false otherwise
+ */
+bool XMEGANVM_WaitWhileNVMBusBusy(void)
+{
+ /* Poll the STATUS register to check to see if NVM access has been enabled */
+ for (;;)
+ {
+ /* Send the LDCS command to read the PDI STATUS register to see the NVM bus is active */
+ XPROGTarget_SendByte(PDI_CMD_LDCS(PDI_REG_STATUS));
+
+ uint8_t StatusRegister = XPROGTarget_ReceiveByte();
+
+ /* We might have timed out waiting for the status register read response, check here */
+ if (!(TimeoutTicksRemaining))
+ return false;
+
+ /* Check the status register read response to see if the NVM bus is enabled */
+ if (StatusRegister & PDI_STATUS_NVM)
+ return true;
+ }
+}
+
+/** Waits while the target's NVM controller is busy performing an operation, exiting if the
+ * timeout period expires.
+ *
+ * \return Boolean \c true if the NVM controller became ready within the timeout period, \c false otherwise
+ */
+bool XMEGANVM_WaitWhileNVMControllerBusy(void)
+{
+ /* Preload the pointer register with the NVM STATUS register address to check the BUSY flag */
+ XPROGTarget_SendByte(PDI_CMD_ST(PDI_POINTER_DIRECT, PDI_DATASIZE_4BYTES));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_STATUS);
+
+ /* Poll the NVM STATUS register while the NVM controller is busy */
+ for (;;)
+ {
+ /* Fetch the current status value via the pointer register (without auto-increment afterwards) */
+ XPROGTarget_SendByte(PDI_CMD_LD(PDI_POINTER_INDIRECT, PDI_DATASIZE_1BYTE));
+
+ uint8_t StatusRegister = XPROGTarget_ReceiveByte();
+
+ /* We might have timed out waiting for the status register read response, check here */
+ if (!(TimeoutTicksRemaining))
+ return false;
+
+ /* Check to see if the BUSY flag is still set */
+ if (!(StatusRegister & (1 << 7)))
+ return true;
+ }
+}
+
+/** Enables the physical PDI interface on the target and enables access to the internal NVM controller.
+ *
+ * \return Boolean \c true if the PDI interface was enabled successfully, \c false otherwise
+ */
+bool XMEGANVM_EnablePDI(void)
+{
+ /* Enable PDI programming mode with the attached target */
+ XPROGTarget_EnableTargetPDI();
+
+ /* Store the RESET key into the RESET PDI register to keep the XMEGA in reset */
+ XPROGTarget_SendByte(PDI_CMD_STCS(PDI_REG_RESET));
+ XPROGTarget_SendByte(PDI_RESET_KEY);
+
+ /* Lower direction change guard time to 32 USART bits */
+ XPROGTarget_SendByte(PDI_CMD_STCS(PDI_REG_CTRL));
+ XPROGTarget_SendByte(0x02);
+
+ /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
+ XPROGTarget_SendByte(PDI_CMD_KEY);
+ for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--)
+ XPROGTarget_SendByte(PDI_NVMENABLE_KEY[i - 1]);
+
+ /* Wait until the NVM bus becomes active */
+ return XMEGANVM_WaitWhileNVMBusBusy();
+}
+
+/** Removes access to the target's NVM controller and physically disables the target's physical PDI interface. */
+void XMEGANVM_DisablePDI(void)
+{
+ XMEGANVM_WaitWhileNVMBusBusy();
+
+ /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run - must perform this until the
+ * change takes effect, as in some cases it takes multiple writes (silicon bug?).
+ */
+ do
+ {
+ /* Clear reset register */
+ XPROGTarget_SendByte(PDI_CMD_STCS(PDI_REG_RESET));
+ XPROGTarget_SendByte(0x00);
+
+ /* Read back the reset register, check to see if it took effect */
+ XPROGTarget_SendByte(PDI_CMD_LDCS(PDI_REG_RESET));
+ } while (XPROGTarget_ReceiveByte() != 0x00);
+
+ XPROGTarget_DisableTargetPDI();
+}
+
+/** Retrieves the CRC value of the given memory space.
+ *
+ * \param[in] CRCCommand NVM CRC command to issue to the target
+ * \param[out] CRCDest CRC Destination when read from the target
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand,
+ uint32_t* const CRCDest)
+{
+ *CRCDest = 0;
+
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Set the NVM command to the correct CRC read command */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(CRCCommand);
+
+ /* Set CMDEX bit in NVM CTRLA register to start the CRC generation */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
+ XPROGTarget_SendByte(XMEGA_NVM_BIT_CTRLA_CMDEX);
+
+ /* Wait until the NVM bus is ready again */
+ if (!(XMEGANVM_WaitWhileNVMBusBusy()))
+ return false;
+
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Load the PDI pointer register with the DAT0 register start address */
+ XPROGTarget_SendByte(PDI_CMD_ST(PDI_POINTER_DIRECT, PDI_DATASIZE_4BYTES));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT0);
+
+ /* Send the REPEAT command to grab the CRC bytes */
+ XPROGTarget_SendByte(PDI_CMD_REPEAT(PDI_DATASIZE_1BYTE));
+ XPROGTarget_SendByte(XMEGA_CRC_LENGTH_BYTES - 1);
+
+ /* Read in the CRC bytes from the target */
+ XPROGTarget_SendByte(PDI_CMD_LD(PDI_POINTER_INDIRECT_PI, PDI_DATASIZE_1BYTE));
+ for (uint8_t i = 0; i < XMEGA_CRC_LENGTH_BYTES; i++)
+ ((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte();
+
+ return (TimeoutTicksRemaining > 0);
+}
+
+/** Reads memory from the target's memory spaces.
+ *
+ * \param[in] ReadAddress Start address to read from within the target's address space
+ * \param[out] ReadBuffer Buffer to store read data into
+ * \param[in] ReadSize Number of bytes to read
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool XMEGANVM_ReadMemory(const uint32_t ReadAddress,
+ uint8_t* ReadBuffer,
+ uint16_t ReadSize)
+{
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Send the READNVM command to the NVM controller for reading of an arbitrary location */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(XMEGA_NVM_CMD_READNVM);
+
+ if (ReadSize > 1)
+ {
+ /* Load the PDI pointer register with the start address we want to read from */
+ XPROGTarget_SendByte(PDI_CMD_ST(PDI_POINTER_DIRECT, PDI_DATASIZE_4BYTES));
+ XMEGANVM_SendAddress(ReadAddress);
+
+ /* Send the REPEAT command with the specified number of bytes to read */
+ XPROGTarget_SendByte(PDI_CMD_REPEAT(PDI_DATASIZE_1BYTE));
+ XPROGTarget_SendByte(ReadSize - 1);
+
+ /* Send a LD command with indirect access and post-increment to read out the bytes */
+ XPROGTarget_SendByte(PDI_CMD_LD(PDI_POINTER_INDIRECT_PI, PDI_DATASIZE_1BYTE));
+ while (ReadSize-- && TimeoutTicksRemaining)
+ *(ReadBuffer++) = XPROGTarget_ReceiveByte();
+ }
+ else
+ {
+ /* Send a LDS command with the read address to read out the requested byte */
+ XPROGTarget_SendByte(PDI_CMD_LDS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendAddress(ReadAddress);
+ *(ReadBuffer++) = XPROGTarget_ReceiveByte();
+ }
+
+ return (TimeoutTicksRemaining > 0);
+}
+
+/** Writes byte addressed memory to the target's memory spaces.
+ *
+ * \param[in] WriteCommand Command to send to the device to write each memory byte
+ * \param[in] WriteAddress Address to write to within the target's address space
+ * \param[in] Byte Byte to write to the target
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool XMEGANVM_WriteByteMemory(const uint8_t WriteCommand,
+ const uint32_t WriteAddress,
+ const uint8_t Byte)
+{
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Send the memory write command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(WriteCommand);
+
+ /* Send new memory byte to the memory of the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendAddress(WriteAddress);
+ XPROGTarget_SendByte(Byte);
+
+ return true;
+}
+
+/** Writes page addressed memory to the target's memory spaces.
+ *
+ * \param[in] WriteBuffCommand Command to send to the device to write a byte to the memory page buffer
+ * \param[in] EraseBuffCommand Command to send to the device to erase the memory page buffer
+ * \param[in] WritePageCommand Command to send to the device to write the page buffer to the destination memory
+ * \param[in] PageMode Bitfield indicating what operations need to be executed on the specified page
+ * \param[in] WriteAddress Start address to write the page data to within the target's address space
+ * \param[in] WriteBuffer Buffer to source data from
+ * \param[in] WriteSize Number of bytes to write
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool XMEGANVM_WritePageMemory(const uint8_t WriteBuffCommand,
+ const uint8_t EraseBuffCommand,
+ const uint8_t WritePageCommand,
+ const uint8_t PageMode,
+ const uint32_t WriteAddress,
+ const uint8_t* WriteBuffer,
+ uint16_t WriteSize)
+{
+ if (PageMode & XPROG_PAGEMODE_ERASE)
+ {
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Send the memory buffer erase command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(EraseBuffCommand);
+
+ /* Set CMDEX bit in NVM CTRLA register to start the buffer erase */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
+ XPROGTarget_SendByte(XMEGA_NVM_BIT_CTRLA_CMDEX);
+ }
+
+ if (WriteSize)
+ {
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Send the memory buffer write command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(WriteBuffCommand);
+
+ /* Load the PDI pointer register with the start address we want to write to */
+ XPROGTarget_SendByte(PDI_CMD_ST(PDI_POINTER_DIRECT, PDI_DATASIZE_4BYTES));
+ XMEGANVM_SendAddress(WriteAddress);
+
+ /* Send the REPEAT command with the specified number of bytes to write */
+ XPROGTarget_SendByte(PDI_CMD_REPEAT(PDI_DATASIZE_1BYTE));
+ XPROGTarget_SendByte(WriteSize - 1);
+
+ /* Send a ST command with indirect access and post-increment to write the bytes */
+ XPROGTarget_SendByte(PDI_CMD_ST(PDI_POINTER_INDIRECT_PI, PDI_DATASIZE_1BYTE));
+ while (WriteSize--)
+ XPROGTarget_SendByte(*(WriteBuffer++));
+ }
+
+ if (PageMode & XPROG_PAGEMODE_WRITE)
+ {
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Send the memory write command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(WritePageCommand);
+
+ /* Send the address of the first page location to write the memory page */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendAddress(WriteAddress);
+ XPROGTarget_SendByte(0x00);
+ }
+
+ return true;
+}
+
+/** Erases a specific memory space of the target.
+ *
+ * \param[in] EraseCommand NVM erase command to send to the device
+ * \param[in] Address Address inside the memory space to erase
+ *
+ * \return Boolean \c true if the command sequence complete successfully
+ */
+bool XMEGANVM_EraseMemory(const uint8_t EraseCommand,
+ const uint32_t Address)
+{
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* EEPROM and Chip erasures are triggered differently to FLASH section erasures */
+ if (EraseCommand == XMEGA_NVM_CMD_CHIPERASE)
+ {
+ /* Send the memory erase command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(EraseCommand);
+
+ /* Set CMDEX bit in NVM CTRLA register to start the erase sequence */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
+ XPROGTarget_SendByte(XMEGA_NVM_BIT_CTRLA_CMDEX);
+ }
+ else if (EraseCommand == XMEGA_NVM_CMD_ERASEEEPROM)
+ {
+ /* Send the EEPROM page buffer erase command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF);
+
+ /* Set CMDEX bit in NVM CTRLA register to start the buffer erase */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
+ XPROGTarget_SendByte(XMEGA_NVM_BIT_CTRLA_CMDEX);
+
+ /* Wait until the NVM controller is no longer busy */
+ if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
+ return false;
+
+ /* Send the EEPROM memory buffer write command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF);
+
+ /* Load the PDI pointer register with the EEPROM page start address */
+ XPROGTarget_SendByte(PDI_CMD_ST(PDI_POINTER_DIRECT, PDI_DATASIZE_4BYTES));
+ XMEGANVM_SendAddress(Address);
+
+ /* Send the REPEAT command with the specified number of bytes to write */
+ XPROGTarget_SendByte(PDI_CMD_REPEAT(PDI_DATASIZE_1BYTE));
+ XPROGTarget_SendByte(XPROG_Param_EEPageSize - 1);
+
+ /* Send a ST command with indirect access and post-increment to tag each byte in the EEPROM page buffer */
+ XPROGTarget_SendByte(PDI_CMD_ST(PDI_POINTER_INDIRECT_PI, PDI_DATASIZE_1BYTE));
+ for (uint8_t PageByte = 0; PageByte < XPROG_Param_EEPageSize; PageByte++)
+ XPROGTarget_SendByte(0x00);
+
+ /* Send the memory erase command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(EraseCommand);
+
+ /* Set CMDEX bit in NVM CTRLA register to start the EEPROM erase sequence */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
+ XPROGTarget_SendByte(XMEGA_NVM_BIT_CTRLA_CMDEX);
+ }
+ else
+ {
+ /* Send the memory erase command to the target */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
+ XPROGTarget_SendByte(EraseCommand);
+
+ /* Other erase modes just need us to address a byte within the target memory space */
+ XPROGTarget_SendByte(PDI_CMD_STS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE));
+ XMEGANVM_SendAddress(Address);
+ XPROGTarget_SendByte(0x00);
+ }
+
+ /* Wait until the NVM bus is ready again */
+ if (!(XMEGANVM_WaitWhileNVMBusBusy()))
+ return false;
+
+ return true;
+}
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h
new file mode 100644
index 000000000..d038b6c0b
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h
@@ -0,0 +1,140 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 XMEGANVM.c.
+ */
+
+#ifndef _XMEGA_NVM_
+#define _XMEGA_NVM_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/interrupt.h>
+ #include <stdbool.h>
+
+ #include <LUFA/Common/Common.h>
+
+ #include "XPROGProtocol.h"
+ #include "XPROGTarget.h"
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+ #undef ENABLE_ISP_PROTOCOL
+
+ #if !defined(ENABLE_XPROG_PROTOCOL)
+ #define ENABLE_XPROG_PROTOCOL
+ #endif
+ #endif
+
+ /* Defines: */
+ #define XMEGA_CRC_LENGTH_BYTES 3
+
+ #define XMEGA_NVM_REG_ADDR0 0x00
+ #define XMEGA_NVM_REG_ADDR1 0x01
+ #define XMEGA_NVM_REG_ADDR2 0x02
+ #define XMEGA_NVM_REG_DAT0 0x04
+ #define XMEGA_NVM_REG_DAT1 0x05
+ #define XMEGA_NVM_REG_DAT2 0x06
+ #define XMEGA_NVM_REG_CMD 0x0A
+ #define XMEGA_NVM_REG_CTRLA 0x0B
+ #define XMEGA_NVM_REG_CTRLB 0x0C
+ #define XMEGA_NVM_REG_INTCTRL 0x0D
+ #define XMEGA_NVM_REG_STATUS 0x0F
+ #define XMEGA_NVM_REG_LOCKBITS 0x10
+
+ #define XMEGA_NVM_BIT_CTRLA_CMDEX (1 << 0)
+
+ #define XMEGA_NVM_CMD_NOOP 0x00
+ #define XMEGA_NVM_CMD_CHIPERASE 0x40
+ #define XMEGA_NVM_CMD_READNVM 0x43
+ #define XMEGA_NVM_CMD_LOADFLASHPAGEBUFF 0x23
+ #define XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF 0x26
+ #define XMEGA_NVM_CMD_ERASEFLASHPAGE 0x2B
+ #define XMEGA_NVM_CMD_WRITEFLASHPAGE 0x2E
+ #define XMEGA_NVM_CMD_ERASEWRITEFLASH 0x2F
+ #define XMEGA_NVM_CMD_FLASHCRC 0x78
+ #define XMEGA_NVM_CMD_ERASEAPPSEC 0x20
+ #define XMEGA_NVM_CMD_ERASEAPPSECPAGE 0x22
+ #define XMEGA_NVM_CMD_WRITEAPPSECPAGE 0x24
+ #define XMEGA_NVM_CMD_ERASEWRITEAPPSECPAGE 0x25
+ #define XMEGA_NVM_CMD_APPCRC 0x38
+ #define XMEGA_NVM_CMD_ERASEBOOTSEC 0x68
+ #define XMEGA_NVM_CMD_ERASEBOOTSECPAGE 0x2A
+ #define XMEGA_NVM_CMD_WRITEBOOTSECPAGE 0x2C
+ #define XMEGA_NVM_CMD_ERASEWRITEBOOTSECPAGE 0x2D
+ #define XMEGA_NVM_CMD_BOOTCRC 0x39
+ #define XMEGA_NVM_CMD_READUSERSIG 0x03
+ #define XMEGA_NVM_CMD_ERASEUSERSIG 0x18
+ #define XMEGA_NVM_CMD_WRITEUSERSIG 0x1A
+ #define XMEGA_NVM_CMD_READCALIBRATION 0x02
+ #define XMEGA_NVM_CMD_READFUSE 0x07
+ #define XMEGA_NVM_CMD_WRITEFUSE 0x4C
+ #define XMEGA_NVM_CMD_WRITELOCK 0x08
+ #define XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF 0x33
+ #define XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF 0x36
+ #define XMEGA_NVM_CMD_ERASEEEPROM 0x30
+ #define XMEGA_NVM_CMD_ERASEEEPROMPAGE 0x32
+ #define XMEGA_NVM_CMD_WRITEEEPROMPAGE 0x34
+ #define XMEGA_NVM_CMD_ERASEWRITEEEPROMPAGE 0x35
+ #define XMEGA_NVM_CMD_READEEPROM 0x06
+
+ /* Function Prototypes: */
+ bool XMEGANVM_WaitWhileNVMBusBusy(void);
+ bool XMEGANVM_WaitWhileNVMControllerBusy(void);
+ bool XMEGANVM_EnablePDI(void);
+ void XMEGANVM_DisablePDI(void);
+ bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand,
+ uint32_t* const CRCDest);
+ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress,
+ uint8_t* ReadBuffer,
+ uint16_t ReadSize);
+ bool XMEGANVM_WriteByteMemory(const uint8_t WriteCommand,
+ const uint32_t WriteAddress,
+ const uint8_t Byte);
+ bool XMEGANVM_WritePageMemory(const uint8_t WriteBuffCommand,
+ const uint8_t EraseBuffCommand,
+ const uint8_t WritePageCommand,
+ const uint8_t PageMode,
+ const uint32_t WriteAddress,
+ const uint8_t* WriteBuffer,
+ uint16_t WriteSize);
+ bool XMEGANVM_EraseMemory(const uint8_t EraseCommand,
+ const uint32_t Address);
+
+ #if defined(INCLUDE_FROM_XMEGANVM_C)
+ static void XMEGANVM_SendNVMRegAddress(const uint8_t Register);
+ static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress);
+ #endif
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
new file mode 100644
index 000000000..0915f97cc
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
@@ -0,0 +1,480 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * XPROG Protocol handler, to process V2 Protocol wrapped XPROG commands used in Atmel programmer devices.
+ */
+
+#define INCLUDE_FROM_XPROGPROTOCOL_C
+#include "XPROGProtocol.h"
+
+#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
+/** Base absolute address for the target's NVM controller for PDI programming */
+uint32_t XPROG_Param_NVMBase = 0x010001C0;
+
+/** Size in bytes of the target's EEPROM page */
+uint16_t XPROG_Param_EEPageSize = 32;
+
+/** Address of the TPI device's NVMCMD register for TPI programming */
+uint8_t XPROG_Param_NVMCMDRegAddr = 0x33;
+
+/** Address of the TPI device's NVMCSR register for TPI programming */
+uint8_t XPROG_Param_NVMCSRRegAddr = 0x32;
+
+/** Currently selected XPROG programming protocol */
+uint8_t XPROG_SelectedProtocol = XPROG_PROTOCOL_PDI;
+
+/** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI/TPI
+ * programming.
+ */
+void XPROGProtocol_SetMode(void)
+{
+ struct
+ {
+ uint8_t Protocol;
+ } SetMode_XPROG_Params;
+
+ Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ XPROG_SelectedProtocol = SetMode_XPROG_Params.Protocol;
+
+ Endpoint_Write_8(CMD_XPROG_SETMODE);
+ Endpoint_Write_8((SetMode_XPROG_Params.Protocol != XPROG_PROTOCOL_JTAG) ? STATUS_CMD_OK : STATUS_CMD_FAILED);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the CMD_XPROG command, which wraps up XPROG commands in a V2 wrapper which need to be
+ * removed and processed so that the underlying XPROG command can be handled.
+ */
+void XPROGProtocol_Command(void)
+{
+ uint8_t XPROGCommand = Endpoint_Read_8();
+
+ switch (XPROGCommand)
+ {
+ case XPROG_CMD_ENTER_PROGMODE:
+ XPROGProtocol_EnterXPROGMode();
+ break;
+ case XPROG_CMD_LEAVE_PROGMODE:
+ XPROGProtocol_LeaveXPROGMode();
+ break;
+ case XPROG_CMD_ERASE:
+ XPROGProtocol_Erase();
+ break;
+ case XPROG_CMD_WRITE_MEM:
+ XPROGProtocol_WriteMemory();
+ break;
+ case XPROG_CMD_READ_MEM:
+ XPROGProtocol_ReadMemory();
+ break;
+ case XPROG_CMD_CRC:
+ XPROGProtocol_ReadCRC();
+ break;
+ case XPROG_CMD_SET_PARAM:
+ XPROGProtocol_SetParam();
+ break;
+ }
+}
+
+/** Handler for the XPROG ENTER_PROGMODE command to establish a connection with the attached device. */
+static void XPROGProtocol_EnterXPROGMode(void)
+{
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ bool NVMBusEnabled = false;
+
+ if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
+ NVMBusEnabled = XMEGANVM_EnablePDI();
+ else if (XPROG_SelectedProtocol == XPROG_PROTOCOL_TPI)
+ NVMBusEnabled = TINYNVM_EnableTPI();
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPROG_CMD_ENTER_PROGMODE);
+ Endpoint_Write_8(NVMBusEnabled ? XPROG_ERR_OK : XPROG_ERR_FAILED);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the XPROG LEAVE_PROGMODE command to terminate the PDI programming connection with
+ * the attached device.
+ */
+static void XPROGProtocol_LeaveXPROGMode(void)
+{
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
+ XMEGANVM_DisablePDI();
+ else
+ TINYNVM_DisableTPI();
+
+ #if defined(XCK_RESCUE_CLOCK_ENABLE) && defined(ENABLE_ISP_PROTOCOL)
+ /* If the XCK rescue clock option is enabled, we need to restart it once the
+ * XPROG mode has been exited, since the XPROG protocol stops it after use. */
+ ISPTarget_ConfigureRescueClock();
+ #endif
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPROG_CMD_LEAVE_PROGMODE);
+ Endpoint_Write_8(XPROG_ERR_OK);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the XPRG ERASE command to erase a specific memory address space in the attached device. */
+static void XPROGProtocol_Erase(void)
+{
+ uint8_t ReturnStatus = XPROG_ERR_OK;
+
+ struct
+ {
+ uint8_t MemoryType;
+ uint32_t Address;
+ } Erase_XPROG_Params;
+
+ Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NULL);
+ Erase_XPROG_Params.Address = SwapEndian_32(Erase_XPROG_Params.Address);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ uint8_t EraseCommand;
+
+ if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
+ {
+ /* Determine which NVM command to send to the device depending on the memory to erase */
+ switch (Erase_XPROG_Params.MemoryType)
+ {
+ case XPROG_ERASE_CHIP:
+ EraseCommand = XMEGA_NVM_CMD_CHIPERASE;
+ break;
+ case XPROG_ERASE_APP:
+ EraseCommand = XMEGA_NVM_CMD_ERASEAPPSEC;
+ break;
+ case XPROG_ERASE_BOOT:
+ EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSEC;
+ break;
+ case XPROG_ERASE_EEPROM:
+ EraseCommand = XMEGA_NVM_CMD_ERASEEEPROM;
+ break;
+ case XPROG_ERASE_APP_PAGE:
+ EraseCommand = XMEGA_NVM_CMD_ERASEAPPSECPAGE;
+ break;
+ case XPROG_ERASE_BOOT_PAGE:
+ EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSECPAGE;
+ break;
+ case XPROG_ERASE_EEPROM_PAGE:
+ EraseCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGE;
+ break;
+ case XPROG_ERASE_USERSIG:
+ EraseCommand = XMEGA_NVM_CMD_ERASEUSERSIG;
+ break;
+ default:
+ EraseCommand = XMEGA_NVM_CMD_NOOP;
+ break;
+ }
+
+ /* Erase the target memory, indicate timeout if occurred */
+ if (!(XMEGANVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
+ ReturnStatus = XPROG_ERR_TIMEOUT;
+ }
+ else
+ {
+ if (Erase_XPROG_Params.MemoryType == XPROG_ERASE_CHIP)
+ EraseCommand = TINY_NVM_CMD_CHIPERASE;
+ else
+ EraseCommand = TINY_NVM_CMD_SECTIONERASE;
+
+ /* Erase the target memory, indicate timeout if occurred */
+ if (!(TINYNVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
+ ReturnStatus = XPROG_ERR_TIMEOUT;
+ }
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPROG_CMD_ERASE);
+ Endpoint_Write_8(ReturnStatus);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the XPROG WRITE_MEMORY command to write to a specific memory space within the attached device. */
+static void XPROGProtocol_WriteMemory(void)
+{
+ uint8_t ReturnStatus = XPROG_ERR_OK;
+
+ struct
+ {
+ uint8_t MemoryType;
+ uint8_t PageMode;
+ uint32_t Address;
+ uint16_t Length;
+ uint8_t ProgData[256];
+ } WriteMemory_XPROG_Params;
+
+ Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params, (sizeof(WriteMemory_XPROG_Params) -
+ sizeof(WriteMemory_XPROG_Params).ProgData), NULL);
+ WriteMemory_XPROG_Params.Address = SwapEndian_32(WriteMemory_XPROG_Params.Address);
+ WriteMemory_XPROG_Params.Length = SwapEndian_16(WriteMemory_XPROG_Params.Length);
+ Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NULL);
+
+ // The driver will terminate transfers that are a round multiple of the endpoint bank in size with a ZLP, need
+ // to catch this and discard it before continuing on with packet processing to prevent communication issues
+ if (((sizeof(uint8_t) + sizeof(WriteMemory_XPROG_Params) - sizeof(WriteMemory_XPROG_Params.ProgData)) +
+ WriteMemory_XPROG_Params.Length) % AVRISP_DATA_EPSIZE == 0)
+ {
+ Endpoint_ClearOUT();
+ Endpoint_WaitUntilReady();
+ }
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
+ {
+ /* Assume FLASH page programming by default, as it is the common case */
+ uint8_t WriteCommand = XMEGA_NVM_CMD_WRITEFLASHPAGE;
+ uint8_t WriteBuffCommand = XMEGA_NVM_CMD_LOADFLASHPAGEBUFF;
+ uint8_t EraseBuffCommand = XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF;
+ bool PagedMemory = true;
+
+ switch (WriteMemory_XPROG_Params.MemoryType)
+ {
+ case XPROG_MEM_TYPE_APPL:
+ WriteCommand = XMEGA_NVM_CMD_WRITEAPPSECPAGE;
+ break;
+ case XPROG_MEM_TYPE_BOOT:
+ WriteCommand = XMEGA_NVM_CMD_WRITEBOOTSECPAGE;
+ break;
+ case XPROG_MEM_TYPE_EEPROM:
+ WriteCommand = XMEGA_NVM_CMD_ERASEWRITEEEPROMPAGE;
+ WriteBuffCommand = XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF;
+ EraseBuffCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF;
+ break;
+ case XPROG_MEM_TYPE_USERSIG:
+ WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG;
+ break;
+ case XPROG_MEM_TYPE_FUSE:
+ WriteCommand = XMEGA_NVM_CMD_WRITEFUSE;
+ PagedMemory = false;
+ break;
+ case XPROG_MEM_TYPE_LOCKBITS:
+ WriteCommand = XMEGA_NVM_CMD_WRITELOCK;
+ PagedMemory = false;
+ break;
+ }
+
+ /* Send the appropriate memory write commands to the device, indicate timeout if occurred */
+ if ((PagedMemory && !(XMEGANVM_WritePageMemory(WriteBuffCommand, EraseBuffCommand, WriteCommand,
+ WriteMemory_XPROG_Params.PageMode, WriteMemory_XPROG_Params.Address,
+ WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length))) ||
+ (!PagedMemory && !(XMEGANVM_WriteByteMemory(WriteCommand, WriteMemory_XPROG_Params.Address,
+ WriteMemory_XPROG_Params.ProgData[0]))))
+ {
+ ReturnStatus = XPROG_ERR_TIMEOUT;
+ }
+ }
+ else
+ {
+ /* Send write command to the TPI device, indicate timeout if occurred */
+ if (!(TINYNVM_WriteMemory(WriteMemory_XPROG_Params.Address, WriteMemory_XPROG_Params.ProgData,
+ WriteMemory_XPROG_Params.Length)))
+ {
+ ReturnStatus = XPROG_ERR_TIMEOUT;
+ }
+ }
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPROG_CMD_WRITE_MEM);
+ Endpoint_Write_8(ReturnStatus);
+ Endpoint_ClearIN();
+}
+
+/** Handler for the XPROG READ_MEMORY command to read data from a specific address space within the
+ * attached device.
+ */
+static void XPROGProtocol_ReadMemory(void)
+{
+ uint8_t ReturnStatus = XPROG_ERR_OK;
+
+ struct
+ {
+ uint8_t MemoryType;
+ uint32_t Address;
+ uint16_t Length;
+ } ReadMemory_XPROG_Params;
+
+ Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NULL);
+ ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address);
+ ReadMemory_XPROG_Params.Length = SwapEndian_16(ReadMemory_XPROG_Params.Length);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ uint8_t ReadBuffer[256];
+
+ if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
+ {
+ /* Read the PDI target's memory, indicate timeout if occurred */
+ if (!(XMEGANVM_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length)))
+ ReturnStatus = XPROG_ERR_TIMEOUT;
+ }
+ else
+ {
+ /* Read the TPI target's memory, indicate timeout if occurred */
+ if (!(TINYNVM_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length)))
+ ReturnStatus = XPROG_ERR_TIMEOUT;
+ }
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPROG_CMD_READ_MEM);
+ Endpoint_Write_8(ReturnStatus);
+
+ if (ReturnStatus == XPROG_ERR_OK)
+ Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NULL);
+
+ Endpoint_ClearIN();
+}
+
+/** Handler for the XPROG CRC command to read a specific memory space's CRC value for comparison between the
+ * attached device's memory and a data set on the host.
+ */
+static void XPROGProtocol_ReadCRC(void)
+{
+ uint8_t ReturnStatus = XPROG_ERR_OK;
+
+ struct
+ {
+ uint8_t CRCType;
+ } ReadCRC_XPROG_Params;
+
+ Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NULL);
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ uint32_t MemoryCRC;
+
+ if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
+ {
+ uint8_t CRCCommand;
+
+ /* Determine which NVM command to send to the device depending on the memory to CRC */
+ switch (ReadCRC_XPROG_Params.CRCType)
+ {
+ case XPROG_CRC_APP:
+ CRCCommand = XMEGA_NVM_CMD_APPCRC;
+ break;
+ case XPROG_CRC_BOOT:
+ CRCCommand = XMEGA_NVM_CMD_BOOTCRC;
+ break;
+ default:
+ CRCCommand = XMEGA_NVM_CMD_FLASHCRC;
+ break;
+ }
+
+ /* Perform and retrieve the memory CRC, indicate timeout if occurred */
+ if (!(XMEGANVM_GetMemoryCRC(CRCCommand, &MemoryCRC)))
+ ReturnStatus = XPROG_ERR_TIMEOUT;
+ }
+ else
+ {
+ /* TPI does not support memory CRC */
+ ReturnStatus = XPROG_ERR_FAILED;
+ }
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPROG_CMD_CRC);
+ Endpoint_Write_8(ReturnStatus);
+
+ if (ReturnStatus == XPROG_ERR_OK)
+ {
+ Endpoint_Write_8(MemoryCRC >> 16);
+ Endpoint_Write_16_LE(MemoryCRC & 0xFFFF);
+ }
+
+ Endpoint_ClearIN();
+}
+
+/** Handler for the XPROG SET_PARAM command to set a XPROG parameter for use when communicating with the
+ * attached device.
+ */
+static void XPROGProtocol_SetParam(void)
+{
+ uint8_t ReturnStatus = XPROG_ERR_OK;
+
+ uint8_t XPROGParam = Endpoint_Read_8();
+
+ /* Determine which parameter is being set, store the new parameter value */
+ switch (XPROGParam)
+ {
+ case XPROG_PARAM_NVMBASE:
+ XPROG_Param_NVMBase = Endpoint_Read_32_BE();
+ break;
+ case XPROG_PARAM_EEPPAGESIZE:
+ XPROG_Param_EEPageSize = Endpoint_Read_16_BE();
+ break;
+ case XPROG_PARAM_NVMCMD_REG:
+ XPROG_Param_NVMCMDRegAddr = Endpoint_Read_8();
+ break;
+ case XPROG_PARAM_NVMCSR_REG:
+ XPROG_Param_NVMCSRRegAddr = Endpoint_Read_8();
+ break;
+ case XPROG_PARAM_UNKNOWN_1:
+ /* TODO: Undocumented parameter added in AVRStudio 5.1, purpose unknown. Must ACK and discard or
+ the communication with AVRStudio 5.1 will fail.
+ */
+ Endpoint_Discard_16();
+ break;
+ default:
+ ReturnStatus = XPROG_ERR_FAILED;
+ break;
+ }
+
+ Endpoint_ClearOUT();
+ Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPROG_CMD_SET_PARAM);
+ Endpoint_Write_8(ReturnStatus);
+ Endpoint_ClearIN();
+}
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h
new file mode 100644
index 000000000..830abc26d
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h
@@ -0,0 +1,136 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 XPROGProtocol.c.
+ */
+
+#ifndef _XPROG_PROTOCOL_
+#define _XPROG_PROTOCOL_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <util/delay.h>
+ #include <stdio.h>
+
+ #include <LUFA/Drivers/USB/USB.h>
+
+ #include "../V2Protocol.h"
+ #include "XMEGANVM.h"
+ #include "TINYNVM.h"
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+ /* On the XPLAIN board, we only need PDI programming
+ for the ATXMEGA128A1 - disable ISP to prevent hardware
+ damage and force-enable XPROG.
+ */
+ #undef ENABLE_ISP_PROTOCOL
+
+ #if !defined(ENABLE_XPROG_PROTOCOL)
+ #define ENABLE_XPROG_PROTOCOL
+ #endif
+ #endif
+
+ /* Macros: */
+ #define XPROG_CMD_ENTER_PROGMODE 0x01
+ #define XPROG_CMD_LEAVE_PROGMODE 0x02
+ #define XPROG_CMD_ERASE 0x03
+ #define XPROG_CMD_WRITE_MEM 0x04
+ #define XPROG_CMD_READ_MEM 0x05
+ #define XPROG_CMD_CRC 0x06
+ #define XPROG_CMD_SET_PARAM 0x07
+
+ #define XPROG_MEM_TYPE_APPL 1
+ #define XPROG_MEM_TYPE_BOOT 2
+ #define XPROG_MEM_TYPE_EEPROM 3
+ #define XPROG_MEM_TYPE_FUSE 4
+ #define XPROG_MEM_TYPE_LOCKBITS 5
+ #define XPROG_MEM_TYPE_USERSIG 6
+ #define XPROG_MEM_TYPE_FACTORY_CALIBRATION 7
+
+ #define XPROG_ERASE_CHIP 1
+ #define XPROG_ERASE_APP 2
+ #define XPROG_ERASE_BOOT 3
+ #define XPROG_ERASE_EEPROM 4
+ #define XPROG_ERASE_APP_PAGE 5
+ #define XPROG_ERASE_BOOT_PAGE 6
+ #define XPROG_ERASE_EEPROM_PAGE 7
+ #define XPROG_ERASE_USERSIG 8
+
+ #define XPROG_MEM_WRITE_ERASE 0
+ #define XPROG_MEM_WRITE_WRITE 1
+
+ #define XPROG_CRC_APP 1
+ #define XPROG_CRC_BOOT 2
+ #define XPROG_CRC_FLASH 3
+
+ #define XPROG_ERR_OK 0
+ #define XPROG_ERR_FAILED 1
+ #define XPROG_ERR_COLLISION 2
+ #define XPROG_ERR_TIMEOUT 3
+
+ #define XPROG_PARAM_NVMBASE 0x01
+ #define XPROG_PARAM_EEPPAGESIZE 0x02
+ #define XPROG_PARAM_NVMCMD_REG 0x03
+ #define XPROG_PARAM_NVMCSR_REG 0x04
+ #define XPROG_PARAM_UNKNOWN_1 0x05
+
+ #define XPROG_PROTOCOL_PDI 0x00
+ #define XPROG_PROTOCOL_JTAG 0x01
+ #define XPROG_PROTOCOL_TPI 0x02
+
+ #define XPROG_PAGEMODE_WRITE (1 << 1)
+ #define XPROG_PAGEMODE_ERASE (1 << 0)
+
+ /* External Variables: */
+ extern uint32_t XPROG_Param_NVMBase;
+ extern uint16_t XPROG_Param_EEPageSize;
+ extern uint8_t XPROG_Param_NVMCSRRegAddr;
+ extern uint8_t XPROG_Param_NVMCMDRegAddr;
+
+ /* Function Prototypes: */
+ void XPROGProtocol_SetMode(void);
+ void XPROGProtocol_Command(void);
+
+ #if (defined(INCLUDE_FROM_XPROGPROTOCOL_C) && defined(ENABLE_XPROG_PROTOCOL))
+ static void XPROGProtocol_EnterXPROGMode(void);
+ static void XPROGProtocol_LeaveXPROGMode(void);
+ static void XPROGProtocol_SetParam(void);
+ static void XPROGProtocol_Erase(void);
+ static void XPROGProtocol_WriteMemory(void);
+ static void XPROGProtocol_ReadMemory(void);
+ static void XPROGProtocol_ReadCRC(void);
+ #endif
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
new file mode 100644
index 000000000..75b43f0fe
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
@@ -0,0 +1,209 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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
+ *
+ * Target-related functions for the PDI Protocol decoder.
+ */
+
+#define INCLUDE_FROM_XPROGTARGET_C
+#include "XPROGTarget.h"
+
+#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
+
+/** Flag to indicate if the USART is currently in Tx or Rx mode. */
+bool IsSending;
+
+/** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */
+void XPROGTarget_EnableTargetPDI(void)
+{
+ IsSending = false;
+
+ /* Set Tx and XCK as outputs, Rx as input */
+ DDRD |= (1 << 5) | (1 << 3);
+ DDRD &= ~(1 << 2);
+
+ /* Set DATA line high for at least 90ns to disable /RESET functionality */
+ PORTD |= (1 << 3);
+ _delay_us(100);
+
+ /* Set up the synchronous USART for XMEGA communications - 8 data bits, even parity, 2 stop bits */
+ UBRR1 = ((F_CPU / 2 / XPROG_HARDWARE_SPEED) - 1);
+ UCSR1B = (1 << TXEN1);
+ UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
+
+ /* Send two IDLEs of 12 bits each to enable PDI interface (need at least 16 idle bits) */
+ XPROGTarget_SendIdle();
+ XPROGTarget_SendIdle();
+}
+
+/** Enables the target's TPI interface, holding the target in reset until TPI mode is exited. */
+void XPROGTarget_EnableTargetTPI(void)
+{
+ IsSending = false;
+
+ /* Set /RESET line low for at least 400ns to enable TPI functionality */
+ AUX_LINE_DDR |= AUX_LINE_MASK;
+ AUX_LINE_PORT &= ~AUX_LINE_MASK;
+ _delay_us(100);
+
+ /* Set Tx and XCK as outputs, Rx as input */
+ DDRD |= (1 << 5) | (1 << 3);
+ DDRD &= ~(1 << 2);
+
+ /* Set up the synchronous USART for TPI communications - 8 data bits, even parity, 2 stop bits */
+ UBRR1 = ((F_CPU / 2 / XPROG_HARDWARE_SPEED) - 1);
+ UCSR1B = (1 << TXEN1);
+ UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
+
+ /* Send two IDLEs of 12 bits each to enable TPI interface (need at least 16 idle bits) */
+ XPROGTarget_SendIdle();
+ XPROGTarget_SendIdle();
+}
+
+/** Disables the target's PDI interface, exits programming mode and starts the target's application. */
+void XPROGTarget_DisableTargetPDI(void)
+{
+ /* Switch to Rx mode to ensure that all pending transmissions are complete */
+ if (IsSending)
+ XPROGTarget_SetRxMode();
+
+ /* Turn off receiver and transmitter of the USART, clear settings */
+ UCSR1A = ((1 << TXC1) | (1 << RXC1));
+ UCSR1B = 0;
+ UCSR1C = 0;
+
+ /* Tristate all pins */
+ DDRD &= ~((1 << 5) | (1 << 3));
+ PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
+}
+
+/** Disables the target's TPI interface, exits programming mode and starts the target's application. */
+void XPROGTarget_DisableTargetTPI(void)
+{
+ /* Switch to Rx mode to ensure that all pending transmissions are complete */
+ if (IsSending)
+ XPROGTarget_SetRxMode();
+
+ /* Turn off receiver and transmitter of the USART, clear settings */
+ UCSR1A |= (1 << TXC1) | (1 << RXC1);
+ UCSR1B = 0;
+ UCSR1C = 0;
+
+ /* Set all USART lines as inputs, tristate */
+ DDRD &= ~((1 << 5) | (1 << 3));
+ PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
+
+ /* Tristate target /RESET line */
+ AUX_LINE_DDR &= ~AUX_LINE_MASK;
+ AUX_LINE_PORT &= ~AUX_LINE_MASK;
+}
+
+/** Sends a byte via the USART.
+ *
+ * \param[in] Byte Byte to send through the USART
+ */
+void XPROGTarget_SendByte(const uint8_t Byte)
+{
+ /* Switch to Tx mode if currently in Rx mode */
+ if (!(IsSending))
+ XPROGTarget_SetTxMode();
+
+ /* Wait until there is space in the hardware Tx buffer before writing */
+ while (!(UCSR1A & (1 << UDRE1)));
+ UCSR1A |= (1 << TXC1);
+ UDR1 = Byte;
+}
+
+/** Receives a byte via the hardware USART, blocking until data is received or timeout expired.
+ *
+ * \return Received byte from the USART
+ */
+uint8_t XPROGTarget_ReceiveByte(void)
+{
+ /* Switch to Rx mode if currently in Tx mode */
+ if (IsSending)
+ XPROGTarget_SetRxMode();
+
+ /* Wait until a byte has been received before reading */
+ while (!(UCSR1A & (1 << RXC1)) && TimeoutTicksRemaining);
+
+ return UDR1;
+}
+
+/** Sends an IDLE via the USART to the attached target, consisting of a full frame of idle bits. */
+void XPROGTarget_SendIdle(void)
+{
+ /* Switch to Tx mode if currently in Rx mode */
+ if (!(IsSending))
+ XPROGTarget_SetTxMode();
+
+ /* Need to do nothing for a full frame to send an IDLE */
+ for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++)
+ {
+ /* Wait for a full cycle of the clock */
+ while (PIND & (1 << 5));
+ while (!(PIND & (1 << 5)));
+ while (PIND & (1 << 5));
+ }
+}
+
+static void XPROGTarget_SetTxMode(void)
+{
+ /* Wait for a full cycle of the clock */
+ while (PIND & (1 << 5));
+ while (!(PIND & (1 << 5)));
+ while (PIND & (1 << 5));
+
+ PORTD |= (1 << 3);
+ DDRD |= (1 << 3);
+
+ UCSR1B &= ~(1 << RXEN1);
+ UCSR1B |= (1 << TXEN1);
+
+ IsSending = true;
+}
+
+static void XPROGTarget_SetRxMode(void)
+{
+ while (!(UCSR1A & (1 << TXC1)));
+ UCSR1A |= (1 << TXC1);
+
+ UCSR1B &= ~(1 << TXEN1);
+ UCSR1B |= (1 << RXEN1);
+
+ DDRD &= ~(1 << 3);
+ PORTD &= ~(1 << 3);
+
+ IsSending = false;
+}
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h
new file mode 100644
index 000000000..560d39d96
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h
@@ -0,0 +1,136 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2014.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2014 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 XPROGTarget.c.
+ */
+
+#ifndef _XPROG_TARGET_
+#define _XPROG_TARGET_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/interrupt.h>
+ #include <stdbool.h>
+
+ #include <LUFA/Common/Common.h>
+
+ #include "../V2Protocol.h"
+ #include "XPROGProtocol.h"
+ #include "Config/AppConfig.h"
+
+ /* Preprocessor Checks: */
+ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
+ #undef ENABLE_ISP_PROTOCOL
+
+ #if !defined(ENABLE_XPROG_PROTOCOL)
+ #define ENABLE_XPROG_PROTOCOL
+ #endif
+ #endif
+
+ /** Serial carrier TPI/PDI speed in Hz, when hardware TPI/PDI mode is used. */
+ #define XPROG_HARDWARE_SPEED 2000000
+
+ /** Total number of bits in a single USART frame. */
+ #define BITS_IN_USART_FRAME 12
+
+ /** \name PDI Related Constants
+ * @{
+ */
+ #define PDI_CMD_LDS(AddressSize, DataSize) (0x00 | ( AddressSize << 2) | DataSize)
+ #define PDI_CMD_LD(PointerAccess, DataSize) (0x20 | (PointerAccess << 2) | DataSize)
+ #define PDI_CMD_STS(AddressSize, DataSize) (0x40 | ( AddressSize << 2) | DataSize)
+ #define PDI_CMD_ST(PointerAccess, DataSize) (0x60 | (PointerAccess << 2) | DataSize)
+ #define PDI_CMD_LDCS(PDIReg) (0x80 | PDIReg)
+ #define PDI_CMD_REPEAT(DataSize) (0xA0 | DataSize)
+ #define PDI_CMD_STCS(PDIReg) (0xC0 | PDIReg)
+ #define PDI_CMD_KEY 0xE0
+
+ #define PDI_REG_STATUS 0
+ #define PDI_REG_RESET 1
+ #define PDI_REG_CTRL 2
+
+ #define PDI_STATUS_NVM (1 << 1)
+
+ #define PDI_RESET_KEY 0x59
+ #define PDI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
+
+ #define PDI_DATASIZE_1BYTE 0
+ #define PDI_DATASIZE_2BYTES 1
+ #define PDI_DATASIZE_3BYTES 2
+ #define PDI_DATASIZE_4BYTES 3
+
+ #define PDI_POINTER_INDIRECT 0
+ #define PDI_POINTER_INDIRECT_PI 1
+ #define PDI_POINTER_DIRECT 2
+ /** @} */
+
+ /** \name TPI Related Constants
+ * @{
+ */
+ #define TPI_CMD_SLD(PointerAccess) (0x20 | PointerAccess)
+ #define TPI_CMD_SST(PointerAccess) (0x60 | PointerAccess)
+ #define TPI_CMD_SSTPR 0x68
+ #define TPI_CMD_SIN(Address) (0x10 | ((Address & 0x30) << 1) | (Address & 0x0F))
+ #define TPI_CMD_SOUT(Address) (0x90 | ((Address & 0x30) << 1) | (Address & 0x0F))
+ #define TPI_CMD_SLDCS(TPIReg) (0x80 | TPIReg)
+ #define TPI_CMD_SSTCS(TPIReg) (0xC0 | TPIReg)
+ #define TPI_CMD_SKEY 0xE0
+
+ #define TPI_REG_STATUS 0x00
+ #define TPI_REG_CTRL 0x02
+ #define TPI_REG_ID 0x0F
+
+ #define TPI_STATUS_NVM (1 << 1)
+
+ #define TPI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
+
+ #define TPI_POINTER_INDIRECT 0
+ #define TPI_POINTER_INDIRECT_PI 4
+ /** @} */
+
+ /* Function Prototypes: */
+ void XPROGTarget_EnableTargetPDI(void);
+ void XPROGTarget_EnableTargetTPI(void);
+ void XPROGTarget_DisableTargetPDI(void);
+ void XPROGTarget_DisableTargetTPI(void);
+ void XPROGTarget_SendByte(const uint8_t Byte);
+ uint8_t XPROGTarget_ReceiveByte(void);
+ void XPROGTarget_SendIdle(void);
+ bool XPROGTarget_WaitWhileNVMBusBusy(void);
+
+ #if (defined(INCLUDE_FROM_XPROGTARGET_C) && defined(ENABLE_XPROG_PROTOCOL))
+ static void XPROGTarget_SetTxMode(void);
+ static void XPROGTarget_SetRxMode(void);
+ #endif
+
+#endif
+
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/asf.xml b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/asf.xml
new file mode 100644
index 000000000..d89b8852f
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/asf.xml
@@ -0,0 +1,90 @@
+<asf xmlversion="1.0">
+ <project caption="AVRISP-MKII Clone Programmer" id="lufa.projects.avrispmkii_clone.avr8">
+ <require idref="lufa.projects.avrispmkii_clone"/>
+ <require idref="lufa.boards.dummy.avr8"/>
+ <generator value="as5_8"/>
+
+ <device-support value="at90usb1287"/>
+ <config name="lufa.drivers.board.name" value="usbkey"/>
+
+ <build type="define" name="F_CPU" value="8000000UL"/>
+ <build type="define" name="F_USB" value="8000000UL"/>
+ </project>
+
+ <!-- Required by the XPLAIN Bridge project as well, so split into a meta module -->
+ <module type="meta" id="lufa.projects.avrispmkii_clone.src" caption="AVRISP-MKII Clone Programmer">
+ <info type="gui-flag" value="hidden"/>
+
+ <device-support-alias value="lufa_avr8"/>
+ <device-support-alias value="lufa_xmega"/>
+ <device-support-alias value="lufa_uc3"/>
+
+ <info type="gui-flag" value="move-to-root"/>
+
+ <build type="include-path" value="."/>
+
+ <build type="c-source" value="AVRISPDescriptors.c"/>
+ <build type="header-file" value="AVRISPDescriptors.h"/>
+
+ <build type="include-path" value="Lib"/>
+
+ <build type="header-file" value="Lib/V2ProtocolConstants.h"/>
+ <build type="c-source" value="Lib/V2Protocol.c"/>
+ <build type="header-file" value="Lib/V2Protocol.h"/>
+ <build type="c-source" value="Lib/V2ProtocolParams.c"/>
+ <build type="header-file" value="Lib/V2ProtocolParams.h"/>
+ <build type="c-source" value="Lib/ISP/ISPProtocol.c"/>
+ <build type="header-file" value="Lib/ISP/ISPProtocol.h"/>
+ <build type="c-source" value="Lib/ISP/ISPTarget.c"/>
+ <build type="header-file" value="Lib/ISP/ISPTarget.h"/>
+ <build type="c-source" value="Lib/XPROG/XPROGTarget.c"/>
+ <build type="header-file" value="Lib/XPROG/XPROGTarget.h"/>
+ <build type="c-source" value="Lib/XPROG/XPROGProtocol.c"/>
+ <build type="header-file" value="Lib/XPROG/XPROGProtocol.h"/>
+ <build type="c-source" value="Lib/XPROG/XMEGANVM.c"/>
+ <build type="header-file" value="Lib/XPROG/XMEGANVM.h"/>
+ <build type="c-source" value="Lib/XPROG/TINYNVM.c"/>
+ <build type="header-file" value="Lib/XPROG/TINYNVM.h"/>
+
+ <require idref="lufa.drivers.peripheral.adc"/>
+ <require idref="lufa.drivers.peripheral.spi"/>
+ </module>
+
+ <module type="application" id="lufa.projects.avrispmkii_clone" caption="AVRISP-MKII Clone Programmer">
+ <info type="description" value="summary">
+ Clone firmware of the Atmel AVRISP-MKII programmer.
+ </info>
+
+ <info type="gui-flag" value="move-to-root"/>
+
+ <info type="keyword" value="Technology">
+ <keyword value="Low Level APIs"/>
+ <keyword value="USB Device"/>
+ </info>
+
+ <device-support-alias value="lufa_avr8"/>
+ <device-support-alias value="lufa_xmega"/>
+ <device-support-alias value="lufa_uc3"/>
+
+ <build type="distribute" subtype="user-file" value="doxyfile"/>
+ <build type="distribute" subtype="user-file" value="AVRISP-MKII.txt"/>
+
+ <build type="c-source" value="AVRISP-MKII.c"/>
+ <build type="header-file" value="AVRISP-MKII.h"/>
+
+ <require idref="lufa.projects.avrispmkii_clone.src"/>
+
+ <build type="module-config" subtype="path" value="Config"/>
+ <build type="module-config" subtype="required-header-file" value="AppConfig.h"/>
+ <build type="header-file" value="Config/AppConfig.h"/>
+ <build type="header-file" value="Config/LUFAConfig.h"/>
+
+ <require idref="lufa.common"/>
+ <require idref="lufa.platform"/>
+ <require idref="lufa.drivers.usb"/>
+ <require idref="lufa.drivers.peripheral.adc"/>
+ <require idref="lufa.drivers.peripheral.spi"/>
+ <require idref="lufa.drivers.board"/>
+ <require idref="lufa.drivers.board.leds"/>
+ </module>
+</asf>
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/doxyfile b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/doxyfile
new file mode 100644
index 000000000..6c8698751
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/doxyfile
@@ -0,0 +1,2364 @@
+# Doxyfile 1.8.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "AVRISP-MKII Clone Programmer Project"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ./Documentation/
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = NO
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = ./
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS = *.h \
+ *.c \
+ *.txt
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE = Documentation/
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS = __* \
+ INCLUDE_FROM_*
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = NO
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = NO
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra stylesheet files is of importance (e.g. the last
+# stylesheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = YES
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = YES
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 1
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
+# for the replacement values of the other commands the user is refered to
+# HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED = __DOXYGEN__ \
+ PROGMEM
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME =
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = NO
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = NO
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = NO
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = NO
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = NO
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = NO
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+PLANTUML_JAR_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 15
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 2
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/makefile b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/makefile
new file mode 100644
index 000000000..c89648d5a
--- /dev/null
+++ b/tmk_core/protocol/lufa/LUFA-git/Projects/AVRISP-MKII/makefile
@@ -0,0 +1,39 @@
+#
+# LUFA Library
+# Copyright (C) Dean Camera, 2014.
+#
+# dean [at] fourwalledcubicle [dot] com
+# www.lufa-lib.org
+#
+# --------------------------------------
+# LUFA Project Makefile.
+# --------------------------------------
+
+# Run "make help" for target help.
+
+MCU = at90usb1287
+ARCH = AVR8
+BOARD = USBKEY
+F_CPU = 8000000
+F_USB = $(F_CPU)
+OPTIMIZATION = s
+TARGET = AVRISP-MKII
+SRC = $(TARGET).c AVRISPDescriptors.c Lib/V2Protocol.c Lib/V2ProtocolParams.c Lib/ISP/ISPProtocol.c Lib/ISP/ISPTarget.c Lib/XPROG/XPROGProtocol.c \
+ Lib/XPROG/XPROGTarget.c Lib/XPROG/XMEGANVM.c Lib/XPROG/TINYNVM.c $(LUFA_SRC_USB)
+LUFA_PATH = ../../LUFA
+CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
+LD_FLAGS =
+
+# Default target
+all:
+
+# Include LUFA build script makefiles
+include $(LUFA_PATH)/Build/lufa_core.mk
+include $(LUFA_PATH)/Build/lufa_sources.mk
+include $(LUFA_PATH)/Build/lufa_build.mk
+include $(LUFA_PATH)/Build/lufa_cppcheck.mk
+include $(LUFA_PATH)/Build/lufa_doxygen.mk
+include $(LUFA_PATH)/Build/lufa_dfu.mk
+include $(LUFA_PATH)/Build/lufa_hid.mk
+include $(LUFA_PATH)/Build/lufa_avrdude.mk
+include $(LUFA_PATH)/Build/lufa_atprogram.mk