From f6f2e8f3d089fc10ae8a29187d211fbd0ea33e28 Mon Sep 17 00:00:00 2001
From: Ben Z Yuan <bzy@mit.edu>
Date: Wed, 5 Dec 2018 13:19:26 -0500
Subject: [PATCH] v2 code artifacts

---
 firmware_v2/Config/LUFAConfig.h    | 126 +++++++++++++
 firmware_v2/Descriptors.c          | 245 +++++++++++++++++++++++++
 firmware_v2/Descriptors.h          | 110 ++++++++++++
 firmware_v2/LUFA VirtualSerial.inf |  66 +++++++
 firmware_v2/main.c                 | 278 +++++++++++++++++++++++++++++
 firmware_v2/main.h                 |  66 +++++++
 firmware_v2/makefile               |  54 ++++++
 plotter/main.py                    |  63 +++++++
 8 files changed, 1008 insertions(+)
 create mode 100644 firmware_v2/Config/LUFAConfig.h
 create mode 100644 firmware_v2/Descriptors.c
 create mode 100644 firmware_v2/Descriptors.h
 create mode 100644 firmware_v2/LUFA VirtualSerial.inf
 create mode 100644 firmware_v2/main.c
 create mode 100644 firmware_v2/main.h
 create mode 100644 firmware_v2/makefile
 create mode 100644 plotter/main.py

diff --git a/firmware_v2/Config/LUFAConfig.h b/firmware_v2/Config/LUFAConfig.h
new file mode 100644
index 0000000..0ec4635
--- /dev/null
+++ b/firmware_v2/Config/LUFAConfig.h
@@ -0,0 +1,126 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2017.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2017  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaims all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+/** \file
+ *  \brief 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      8
+//		#define DEVICE_STATE_AS_GPIOR            {Insert Value Here}
+		#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
+
+	#elif (ARCH == ARCH_XMEGA)
+
+		/* 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 USE_STATIC_OPTIONS               (USB_DEVICE_OPT_FULLSPEED | USB_OPT_RC32MCLKSRC | USB_OPT_BUSEVENT_PRIHIGH)
+//		#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      8
+//		#define DEVICE_STATE_AS_GPIOR            {Insert Value Here}
+		#define FIXED_NUM_CONFIGURATIONS         1
+//		#define CONTROL_ONLY_DEVICE
+		#define MAX_ENDPOINT_INDEX               4
+//		#define NO_DEVICE_REMOTE_WAKEUP
+//		#define NO_DEVICE_SELF_POWER
+
+	#else
+
+		#error Unsupported architecture for this LUFA configuration file.
+
+	#endif
+#endif
diff --git a/firmware_v2/Descriptors.c b/firmware_v2/Descriptors.c
new file mode 100644
index 0000000..5ec042c
--- /dev/null
+++ b/firmware_v2/Descriptors.c
@@ -0,0 +1,245 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2017.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2017  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaims all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+/** \file
+ *
+ *  USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ *  computer-readable structures which the host requests upon device enumeration, to determine
+ *  the device's capabilities and functions.
+ */
+
+#include "Descriptors.h"
+
+
+/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
+ *  device characteristics, including the supported USB version, control endpoint size and the
+ *  number of device configurations. The descriptor is read out by the USB host when the enumeration
+ *  process begins.
+ */
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+	.Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+	.USBSpecification       = VERSION_BCD(1,1,0),
+	.Class                  = CDC_CSCP_CDCClass,
+	.SubClass               = CDC_CSCP_NoSpecificSubclass,
+	.Protocol               = CDC_CSCP_NoSpecificProtocol,
+
+	.Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
+
+	.VendorID               = 0x03EB,
+	.ProductID              = 0x2044,
+	.ReleaseNumber          = VERSION_BCD(0,0,1),
+
+	.ManufacturerStrIndex   = STRING_ID_Manufacturer,
+	.ProductStrIndex        = STRING_ID_Product,
+	.SerialNumStrIndex      = USE_INTERNAL_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.
+ */
+const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
+{
+	.Config =
+		{
+			.Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+			.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+			.TotalInterfaces        = 2,
+
+			.ConfigurationNumber    = 1,
+			.ConfigurationStrIndex  = NO_DESCRIPTOR,
+
+			.ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+
+			.MaxPowerConsumption    = USB_CONFIG_POWER_MA(100)
+		},
+
+	.CDC_CCI_Interface =
+		{
+			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+			.InterfaceNumber        = INTERFACE_ID_CDC_CCI,
+			.AlternateSetting       = 0,
+
+			.TotalEndpoints         = 1,
+
+			.Class                  = CDC_CSCP_CDCClass,
+			.SubClass               = CDC_CSCP_ACMSubclass,
+			.Protocol               = CDC_CSCP_ATCommandProtocol,
+
+			.InterfaceStrIndex      = NO_DESCRIPTOR
+		},
+
+	.CDC_Functional_Header =
+		{
+			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+			.Subtype                = CDC_DSUBTYPE_CSInterface_Header,
+
+			.CDCSpecification       = VERSION_BCD(1,1,0),
+		},
+
+	.CDC_Functional_ACM =
+		{
+			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+			.Subtype                = CDC_DSUBTYPE_CSInterface_ACM,
+
+			.Capabilities           = 0x06,
+		},
+
+	.CDC_Functional_Union =
+		{
+			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+			.Subtype                = CDC_DSUBTYPE_CSInterface_Union,
+
+			.MasterInterfaceNumber  = INTERFACE_ID_CDC_CCI,
+			.SlaveInterfaceNumber   = INTERFACE_ID_CDC_DCI,
+		},
+
+	.CDC_NotificationEndpoint =
+		{
+			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+			.EndpointAddress        = CDC_NOTIFICATION_EPADDR,
+			.Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+			.EndpointSize           = CDC_NOTIFICATION_EPSIZE,
+			.PollingIntervalMS      = 0xFF
+		},
+
+	.CDC_DCI_Interface =
+		{
+			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+			.InterfaceNumber        = INTERFACE_ID_CDC_DCI,
+			.AlternateSetting       = 0,
+
+			.TotalEndpoints         = 2,
+
+			.Class                  = CDC_CSCP_CDCDataClass,
+			.SubClass               = CDC_CSCP_NoDataSubclass,
+			.Protocol               = CDC_CSCP_NoDataProtocol,
+
+			.InterfaceStrIndex      = NO_DESCRIPTOR
+		},
+
+	.CDC_DataOutEndpoint =
+		{
+			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+			.EndpointAddress        = CDC_RX_EPADDR,
+			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+			.EndpointSize           = CDC_TXRX_EPSIZE,
+			.PollingIntervalMS      = 0x05
+		},
+
+	.CDC_DataInEndpoint =
+		{
+			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+			.EndpointAddress        = CDC_TX_EPADDR,
+			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+			.EndpointSize           = CDC_TXRX_EPSIZE,
+			.PollingIntervalMS      = 0x05
+		}
+};
+
+/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
+ *  the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ *  via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
+
+/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
+ *  form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ *  Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera");
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ *  and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ *  Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA CDC Demo");
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ *  documentation) by the application code so that the address and size of a requested descriptor can be given
+ *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ *  USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+                                    const uint16_t wIndex,
+                                    const void** const DescriptorAddress)
+{
+	const uint8_t  DescriptorType   = (wValue >> 8);
+	const uint8_t  DescriptorNumber = (wValue & 0xFF);
+
+	const void* Address = NULL;
+	uint16_t    Size    = NO_DESCRIPTOR;
+
+	switch (DescriptorType)
+	{
+		case DTYPE_Device:
+			Address = &DeviceDescriptor;
+			Size    = sizeof(USB_Descriptor_Device_t);
+			break;
+		case DTYPE_Configuration:
+			Address = &ConfigurationDescriptor;
+			Size    = sizeof(USB_Descriptor_Configuration_t);
+			break;
+		case DTYPE_String:
+			switch (DescriptorNumber)
+			{
+				case STRING_ID_Language:
+					Address = &LanguageString;
+					Size    = pgm_read_byte(&LanguageString.Header.Size);
+					break;
+				case STRING_ID_Manufacturer:
+					Address = &ManufacturerString;
+					Size    = pgm_read_byte(&ManufacturerString.Header.Size);
+					break;
+				case STRING_ID_Product:
+					Address = &ProductString;
+					Size    = pgm_read_byte(&ProductString.Header.Size);
+					break;
+			}
+
+			break;
+	}
+
+	*DescriptorAddress = Address;
+	return Size;
+}
+
diff --git a/firmware_v2/Descriptors.h b/firmware_v2/Descriptors.h
new file mode 100644
index 0000000..5b4bf2a
--- /dev/null
+++ b/firmware_v2/Descriptors.h
@@ -0,0 +1,110 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2017.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2017  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaims all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+/** \file
+ *
+ *  Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+	/* Includes: */
+		#include <avr/pgmspace.h>
+
+		#include <LUFA/Drivers/USB/USB.h>
+
+	/* Macros: */
+		/** Endpoint address of the CDC device-to-host notification IN endpoint. */
+		#define CDC_NOTIFICATION_EPADDR        (ENDPOINT_DIR_IN  | 2)
+
+		/** Endpoint address of the CDC device-to-host data IN endpoint. */
+		#define CDC_TX_EPADDR                  (ENDPOINT_DIR_IN  | 3)
+
+		/** Endpoint address of the CDC host-to-device data OUT endpoint. */
+		#define CDC_RX_EPADDR                  (ENDPOINT_DIR_OUT | 4)
+
+		/** Size in bytes of the CDC device-to-host notification IN endpoint. */
+		#define CDC_NOTIFICATION_EPSIZE        8
+
+		/** Size in bytes of the CDC data IN and OUT endpoints. */
+		#define CDC_TXRX_EPSIZE                16
+
+	/* 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;
+
+			// CDC Control Interface
+			USB_Descriptor_Interface_t               CDC_CCI_Interface;
+			USB_CDC_Descriptor_FunctionalHeader_t    CDC_Functional_Header;
+			USB_CDC_Descriptor_FunctionalACM_t       CDC_Functional_ACM;
+			USB_CDC_Descriptor_FunctionalUnion_t     CDC_Functional_Union;
+			USB_Descriptor_Endpoint_t                CDC_NotificationEndpoint;
+
+			// CDC Data Interface
+			USB_Descriptor_Interface_t               CDC_DCI_Interface;
+			USB_Descriptor_Endpoint_t                CDC_DataOutEndpoint;
+			USB_Descriptor_Endpoint_t                CDC_DataInEndpoint;
+		} 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_CDC_CCI = 0, /**< CDC CCI interface descriptor ID */
+			INTERFACE_ID_CDC_DCI = 1, /**< CDC DCI interface descriptor ID */
+		};
+
+		/** Enum for the device string descriptor IDs within the device. Each string descriptor should
+		 *  have a unique ID index associated with it, which can be used to refer to the string from
+		 *  other descriptors.
+		 */
+		enum StringDescriptors_t
+		{
+			STRING_ID_Language     = 0, /**< Supported Languages string descriptor ID (must be zero) */
+			STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
+			STRING_ID_Product      = 2, /**< Product string ID */
+		};
+
+	/* Function Prototypes: */
+		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+		                                    const uint16_t wIndex,
+		                                    const void** const DescriptorAddress)
+		                                    ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/firmware_v2/LUFA VirtualSerial.inf b/firmware_v2/LUFA VirtualSerial.inf
new file mode 100644
index 0000000..21d2d12
--- /dev/null
+++ b/firmware_v2/LUFA VirtualSerial.inf	
@@ -0,0 +1,66 @@
+;************************************************************
+; Windows USB CDC ACM Setup File
+; Copyright (c) 2000 Microsoft Corporation
+;************************************************************
+
+[DefaultInstall]
+CopyINF="LUFA VirtualSerial.inf"
+
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%MFGNAME%
+DriverVer=7/1/2012,10.0.0.0
+
+[Manufacturer]
+%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64
+
+[SourceDisksNames]
+
+[SourceDisksFiles]
+
+[DestinationDirs]
+DefaultDestDir=12
+
+[DriverInstall]
+Include=mdmcpq.inf
+CopyFiles=FakeModemCopyFileSection
+AddReg=DriverInstall.AddReg
+
+[DriverInstall.Services]
+Include=mdmcpq.inf
+AddService=usbser, 0x00000002, LowerFilter_Service_Inst
+
+[DriverInstall.AddReg]
+HKR,,EnumPropPages32,,"msports.dll,SerialPortPropPageProvider"
+
+;------------------------------------------------------------------------------
+;  Vendor and Product ID Definitions
+;------------------------------------------------------------------------------
+; When developing your USB device, the VID and PID used in the PC side
+; application program and the firmware on the microcontroller must match.
+; Modify the below line to use your VID and PID.  Use the format as shown below.
+; Note: One INF file can be used for multiple devices with different VID and PIDs.
+; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
+;------------------------------------------------------------------------------
+[DeviceList]
+%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044
+
+[DeviceList.NTx86]
+%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044
+
+[DeviceList.NTamd64]
+%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044
+
+[DeviceList.NTia64]
+%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2044
+
+;------------------------------------------------------------------------------
+;  String Definitions
+;------------------------------------------------------------------------------
+;Modify these strings to customize your device
+;------------------------------------------------------------------------------
+[Strings]
+MFGNAME="http://www.lufa-lib.org"
+DESCRIPTION="LUFA CDC-ACM Virtual Serial Port"
\ No newline at end of file
diff --git a/firmware_v2/main.c b/firmware_v2/main.c
new file mode 100644
index 0000000..aeaa964
--- /dev/null
+++ b/firmware_v2/main.c
@@ -0,0 +1,278 @@
+/*
+						 LUFA Library
+		 Copyright (C) Dean Camera, 2017.
+
+	dean [at] fourwalledcubicle [dot] com
+					 www.lufa-lib.org
+*/
+
+/*
+	Copyright 2017	Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+	Permission to use, copy, modify, distribute, and sell this
+	software and its documentation for any purpose is hereby granted
+	without fee, provided that the above copyright notice appear in
+	all copies and that both that the copyright notice and this
+	permission notice and warranty disclaimer appear in supporting
+	documentation, and that the name of the author not be used in
+	advertising or publicity pertaining to distribution of the
+	software without specific, written prior permission.
+
+	The author disclaims all warranties with regard to this
+	software, including all implied warranties of merchantability
+	and fitness.	In no event shall the author be liable for any
+	special, indirect or consequential damages or any damages
+	whatsoever resulting from loss of use, data or profits, whether
+	in an action of contract, negligence or other tortious action,
+	arising out of or in connection with the use or performance of
+	this software.
+*/
+
+/** \file
+ *
+ *	Main source file for the FabScope firmware, derived from the LUFA
+ *	VirtualSerial demo.
+ */
+
+#include "main.h"
+#include <LUFA/Drivers/Peripheral/SPI.h>
+
+#define BUTTONPORT PORTC
+#define BUTTONPINOFFSET 3
+#define BUTTONPINCTRL PORTC_PIN3CTRL
+
+#define ADC_RVSPIN 1
+#define ADC_RVSPINCTRL PORTC_PIN1CTRL
+
+/** LUFA CDC Class driver interface configuration and state information. This structure is
+ *	passed to all CDC Class driver functions, so that multiple instances of the same class
+ *	within a device can be differentiated from one another.
+ */
+USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
+	{
+		.Config =
+			{
+				.ControlInterfaceNumber	 = INTERFACE_ID_CDC_CCI,
+				.DataINEndpoint					 =
+					{
+						.Address					= CDC_TX_EPADDR,
+						.Size						 = CDC_TXRX_EPSIZE,
+						.Banks						= 1,
+					},
+				.DataOUTEndpoint =
+					{
+						.Address					= CDC_RX_EPADDR,
+						.Size						 = CDC_TXRX_EPSIZE,
+						.Banks						= 1,
+					},
+				.NotificationEndpoint =
+					{
+						.Address					= CDC_NOTIFICATION_EPADDR,
+						.Size						 = CDC_NOTIFICATION_EPSIZE,
+						.Banks						= 1,
+					},
+			},
+	};
+
+/** Standard file stream for the CDC interface when set up, so that the virtual CDC COM port can be
+ *	used like any regular character stream in the C APIs.
+ */
+static FILE USBSerialStream;
+
+
+/* button latch state variable */
+static bool buttonState;
+static uint16_t buttonDebounce;
+
+#define BUTTONDEBOUNCETHRESH 10
+
+
+#define ADC_BUFSZ 512
+static uint16_t adc_buf[ADC_BUFSZ];
+
+static bool doUSBTask = false;
+
+
+/** 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)
+{
+	buttonState = false;
+	buttonDebounce = 0;
+
+	SetupHardware();
+
+	/* Create a regular character stream for the interface so that it can be used with the stdio.h functions */
+	CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream);
+
+	GlobalInterruptEnable();
+
+	for (;;)
+	{
+
+		// consume input bytes to prevent blocking (don't do anything with them yet)
+		CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
+
+		// take an ADC reading and emit it over serial
+		ADC_Read_Block();
+		fputc('A', &USBSerialStream);
+		fputc('A', &USBSerialStream);
+		//fwrite(adc_buf, sizeof(uint16_t), ADC_BUFSZ, &USBSerialStream);
+		for(int i = 0; i < ADC_BUFSZ; i++) {
+			fwrite(adc_buf + i, sizeof(uint16_t), 1, &USBSerialStream);
+		}
+		fputc('Z', &USBSerialStream);
+		fputc('Z', &USBSerialStream);
+
+		if(doUSBTask) {
+			CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
+			USB_USBTask();
+			doUSBTask = false;
+		}
+
+	}
+}
+
+uint8_t ReadSignatureByte(uint16_t Address)
+{
+		NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
+		uint8_t Result;
+		Result = pgm_read_byte((uint8_t *)Address);
+		NVM_CMD = NVM_CMD_NO_OPERATION_gc;
+		return Result;
+}
+
+void ADC_Init()
+{
+
+	/* set up CS / MOSI / SCK pin as output */
+	PORTC.DIR |= (1 << 4) | (1 << 5) | (1 << 7);
+	PORTC.OUT |= (1 << 4);
+
+	/* set up RVS line as input */
+	PORTC.DIR &= ~(1 << ADC_RVSPIN);
+	ADC_RVSPINCTRL = PORT_ISC_BOTHEDGES_gc;
+
+	SPI_Init(&SPIC, SPI_SPEED_FCPU_DIV_2 | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_RISING |
+                  SPI_SAMPLE_LEADING | SPI_MODE_MASTER);
+
+	/* "flush" the SPI line by one frame */
+	while(!(PORTC.IN &= (1 << ADC_RVSPIN)));
+	PORTC.OUT &= ~(1 << 4);
+	SPI_ReceiveByte(&SPIC);
+	SPI_ReceiveByte(&SPIC);
+	SPI_ReceiveByte(&SPIC);
+	SPI_ReceiveByte(&SPIC);
+	PORTC.OUT |= (1 << 4);
+}
+
+static uint8_t spi_rx_buf[4];
+
+inline uint16_t ADC_Read(void)
+{
+	while(!(PORTC.IN &= (1 << ADC_RVSPIN)));
+	PORTC.OUT &= ~(1 << 4);
+	spi_rx_buf[3] = SPI_ReceiveByte(&SPIC);
+	spi_rx_buf[2] = SPI_ReceiveByte(&SPIC);
+	spi_rx_buf[1] = SPI_ReceiveByte(&SPIC);
+	spi_rx_buf[0] = SPI_ReceiveByte(&SPIC);
+	PORTC.OUT |= (1 << 4);
+
+	//return (uint32_t) *(uint32_t*)spi_rx_buf;
+	return (uint16_t) ((*(uint16_t*)(spi_rx_buf+2)) >> 4) ;
+}
+
+void ADC_Read_Block(void)
+{
+	TCC0.INTCTRLA = TC_OVFINTLVL_OFF_gc;
+	PORTC.OUT &= ~(1 << 0);
+	for(int i = 0; i < ADC_BUFSZ; i++)
+	{
+		adc_buf[i] = ADC_Read();
+	}
+	PORTC.OUT |= (1 << 0);
+	TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
+}
+
+ISR(TCC0_OVF_vect)
+{
+	doUSBTask = true;
+}
+
+/** Configures the board hardware and chip peripherals for the demo's functionality. */
+void SetupHardware(void)
+{
+	/* Start the PLL to multiply the 2MHz RC oscillator to 32MHz and switch the CPU core to run from it */
+	XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU);
+	XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL);
+
+	/* Start the 32MHz internal RC oscillator and start the DFLL to increase it to 48MHz using the USB SOF as a reference */
+	XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ);
+	XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB);
+
+	PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
+
+	/* Hardware Initialization */
+	USB_Init();
+	ADC_Init();
+
+	/* turn on main LED */
+	PORTC.DIR |= (1 << 0);
+	PORTC.OUT |= (1 << 0);
+
+	/* set up button as input */
+	BUTTONPORT.DIR &= ~(1 << BUTTONPINOFFSET);
+	PORTC_PIN3CTRL = (1 << 6) | PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;
+
+	/* set up 25ms USB interrupt */
+	TCC0.CTRLA = TC_CLKSEL_DIV256_gc;
+	TCC0.PER = 3125;
+	TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
+	TCC0.INTFLAGS = 0x01;
+	TCC0.CTRLB = TC_WGMODE_NORMAL_gc;
+}
+
+/** Event handler for the library USB Connection event. */
+void EVENT_USB_Device_Connect(void)
+{
+	//LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+}
+
+/** Event handler for the library USB Disconnection event. */
+void EVENT_USB_Device_Disconnect(void)
+{
+	//LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+}
+
+/** Event handler for the library USB Configuration Changed event. */
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+	bool ConfigSuccess = true;
+
+	ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
+
+	//LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
+}
+
+/** Event handler for the library USB Control Request reception event. */
+void EVENT_USB_Device_ControlRequest(void)
+{
+	CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
+}
+
+/** CDC class driver callback function the processing of changes to the virtual
+ *	control lines sent from the host..
+ *
+ *	\param[in] CDCInterfaceInfo	Pointer to the CDC class interface configuration structure being referenced
+ */
+void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo)
+{
+	/* You can get changes to the virtual CDC lines in this callback; a common
+		 use-case is to use the Data Terminal Ready (DTR) flag to enable and
+		 disable CDC communications in your application when set to avoid the
+		 application blocking while waiting for a host to become ready and read
+		 in the pending data from the USB endpoints.
+	*/
+	bool HostReady = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) != 0;
+}
diff --git a/firmware_v2/main.h b/firmware_v2/main.h
new file mode 100644
index 0000000..f8cae59
--- /dev/null
+++ b/firmware_v2/main.h
@@ -0,0 +1,66 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2017.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2017  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaims all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+/** \file
+ *
+ *  Header file for main.c.
+ */
+
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+	/* Includes: */
+		#include <avr/io.h>
+		#include <avr/wdt.h>
+		#include <avr/power.h>
+		#include <avr/interrupt.h>
+		#include <string.h>
+		#include <stdio.h>
+
+		#include "Descriptors.h"
+
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Platform/Platform.h>
+
+	/* Function Prototypes: */
+		uint8_t ReadSignatureByte(uint16_t);
+
+		void ADC_Init(void);
+		uint16_t ADC_Read(void);
+		void ADC_Read_Block(void);
+
+		void SetupHardware(void);
+
+		void EVENT_USB_Device_Connect(void);
+		void EVENT_USB_Device_Disconnect(void);
+		void EVENT_USB_Device_ConfigurationChanged(void);
+		void EVENT_USB_Device_ControlRequest(void);
+
+#endif
diff --git a/firmware_v2/makefile b/firmware_v2/makefile
new file mode 100644
index 0000000..b46a203
--- /dev/null
+++ b/firmware_v2/makefile
@@ -0,0 +1,54 @@
+#
+#             LUFA Library
+#     Copyright (C) Dean Camera, 2017.
+#
+#  dean [at] fourwalledcubicle [dot] com
+#           www.lufa-lib.org
+#
+# --------------------------------------
+#         LUFA Project Makefile.
+# --------------------------------------
+
+# Run "make help" for target help.
+
+MCU          = atxmega16a4u
+ARCH         = XMEGA
+BOARD        = USBKEY
+F_CPU        = 32000000
+F_USB        = 48000000
+OPTIMIZATION = s
+TARGET       = main
+SRC          = $(TARGET).c Descriptors.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
+LUFA_PATH    = /home/atomicinf/src/lufa-LUFA-170418/LUFA
+CC_FLAGS     = -DUSE_LUFA_CONFIG_HEADER -IConfig/
+LD_FLAGS     =
+
+# Default target
+all:
+
+# Include LUFA-specific DMBS extension modules
+DMBS_LUFA_PATH ?= $(LUFA_PATH)/Build/LUFA
+include $(DMBS_LUFA_PATH)/lufa-sources.mk
+include $(DMBS_LUFA_PATH)/lufa-gcc.mk
+
+# Include common DMBS build system modules
+DMBS_PATH      ?= $(LUFA_PATH)/Build/DMBS/DMBS
+include $(DMBS_PATH)/core.mk
+include $(DMBS_PATH)/cppcheck.mk
+include $(DMBS_PATH)/doxygen.mk
+include $(DMBS_PATH)/dfu.mk
+include $(DMBS_PATH)/gcc.mk
+include $(DMBS_PATH)/hid.mk
+include $(DMBS_PATH)/avrdude.mk
+include $(DMBS_PATH)/atprogram.mk
+
+program-dfu: $(TARGET).hex
+	sudo dfu-programmer atxmega16a4u erase
+	sudo dfu-programmer atxmega16a4u flash $(TARGET).hex
+	sudo dfu-programmer atxmega16a4u launch
+
+program-avrisp2: $(TARGET).hex
+	avrdude -p $(MCU) -c avrisp2 -U flash:w:$(TARGET).hex
+
+program-avrisp2-dfu-fuses:
+	avrdude -p $(MCU) -c avrisp2 -U fuse2:w:0xBF:m
diff --git a/plotter/main.py b/plotter/main.py
new file mode 100644
index 0000000..be91cce
--- /dev/null
+++ b/plotter/main.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+
+import matplotlib as mpl
+mpl.use('TKAgg')
+import serial
+import Tkinter as tk
+import numpy as np
+import matplotlib.backends.tkagg as tkagg
+from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
+import time
+
+s = serial.Serial(port="/dev/ttyACM0", baudrate=115200)
+
+# Create a canvas
+w, h = 600, 400
+window = tk.Tk()
+window.title("A figure in a canvas")
+
+# Create the figure we desire to add to an existing canvas
+fig = mpl.figure.Figure(figsize=(6, 4), dpi=192)
+ax = fig.add_axes([0, 0, 1, 1])
+
+canvas = FigureCanvasTkAgg(fig, master=window)
+canvas.show()
+canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
+canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
+
+# Add more elements to the canvas, potentially on top of the figure
+# canvas.create_line(200, 50, fig_x + fig_w / 2, fig_y + fig_h / 2)
+# canvas.create_text(200, 50, text="Zero-crossing", anchor="s")
+
+#buf = np.zeros(512)
+
+def idle(parent, canvas):
+    global ax, s
+
+    while True:
+        while s.read(1) != 'A':
+            pass
+        if s.read(1) != 'A':
+            continue
+
+        tmp = s.read(1024)
+
+        if s.read(2) != 'ZZ':
+            continue
+
+        buf = np.frombuffer(tmp, dtype=np.uint16, count=512)
+        break
+
+    ax.clear()
+    X = np.linspace(0, 511, 512)
+    Y = buf
+    ax.plot(X, Y)
+    ax.set_xlim(0, 511)
+    ax.set_ylim(0, 4095)
+
+    canvas.draw()
+    parent.after(33, idle, parent, canvas)
+
+# Let Tk take over
+window.after(100,idle,window,canvas)
+tk.mainloop()
-- 
GitLab