aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Delmar Davis <don@suspectdevices.com>2013-09-23 19:14:52 -0700
committerDonald Delmar Davis <don@suspectdevices.com>2013-09-23 19:14:52 -0700
commitbd15d30ea0421dcf7074489db90ac64ba53a29e6 (patch)
tree35ff190d369ce17fd87ab563fca29786f0453ced
Add the stuff for real...
-rwxr-xr-xConfig/LUFAConfig.h126
-rwxr-xr-xDescriptors.c329
-rwxr-xr-xDescriptors.h98
-rwxr-xr-xMIDI.c151
-rwxr-xr-xMIDI.h79
-rw-r--r--MIDI.hex252
-rw-r--r--MidiSpecs.h151
-rw-r--r--MinSysex.c249
-rw-r--r--MinSysex.h38
-rw-r--r--README.md0
-rwxr-xr-xmakefile41
-rwxr-xr-xreset.py171
-rw-r--r--sysextest.py164
13 files changed, 1849 insertions, 0 deletions
diff --git a/Config/LUFAConfig.h b/Config/LUFAConfig.h
new file mode 100755
index 0000000..a4ca343
--- /dev/null
+++ b/Config/LUFAConfig.h
@@ -0,0 +1,126 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2013.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2013 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 2
+// #define NO_DEVICE_REMOTE_WAKEUP
+// #define NO_DEVICE_SELF_POWER
+
+ #else
+
+ #error Unsupported architecture for this LUFA configuration file.
+
+ #endif
+#endif
diff --git a/Descriptors.c b/Descriptors.c
new file mode 100755
index 0000000..01bd8d4
--- /dev/null
+++ b/Descriptors.c
@@ -0,0 +1,329 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2013.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2013 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(01.10),
+ .Class = USB_CSCP_NoDeviceClass,
+ .SubClass = USB_CSCP_NoDeviceSubclass,
+ .Protocol = USB_CSCP_NoDeviceProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x2341, //0x03EB,
+ .ProductID = 0x0037, //0x2048,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = STRING_ID_Manufacturer,
+ .ProductStrIndex = STRING_ID_Product,
+ .SerialNumStrIndex = NO_DESCRIPTOR,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
+{
+ .Config =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+ .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+ .TotalInterfaces = 2,
+
+ .ConfigurationNumber = 1,
+ .ConfigurationStrIndex = NO_DESCRIPTOR,
+
+ .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .Audio_ControlInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 0,
+
+ .Class = AUDIO_CSCP_AudioClass,
+ .SubClass = AUDIO_CSCP_ControlSubclass,
+ .Protocol = AUDIO_CSCP_ControlProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Audio_ControlInterface_SPC =
+ {
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
+
+ .ACSpecification = VERSION_BCD(01.00),
+ .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
+
+ .InCollection = 1,
+ .InterfaceNumber = 1,
+ },
+
+ .Audio_StreamInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = AUDIO_CSCP_AudioClass,
+ .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
+ .Protocol = AUDIO_CSCP_StreamingProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .Audio_StreamInterface_SPC =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
+
+ .AudioSpecification = VERSION_BCD(01.00),
+
+ .TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
+ offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
+ },
+
+ .MIDI_In_Jack_Emb =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
+
+ .JackType = MIDI_JACKTYPE_Embedded,
+ .JackID = 0x01,
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_In_Jack_Ext =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
+
+ .JackType = MIDI_JACKTYPE_External,
+ .JackID = 0x02,
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_Out_Jack_Emb =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
+
+ .JackType = MIDI_JACKTYPE_Embedded,
+ .JackID = 0x03,
+
+ .NumberOfPins = 1,
+ .SourceJackID = {0x02},
+ .SourcePinID = {0x01},
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_Out_Jack_Ext =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
+ .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
+
+ .JackType = MIDI_JACKTYPE_External,
+ .JackID = 0x04,
+
+ .NumberOfPins = 1,
+ .SourceJackID = {0x01},
+ .SourcePinID = {0x01},
+
+ .JackStrIndex = NO_DESCRIPTOR
+ },
+
+ .MIDI_In_Jack_Endpoint =
+ {
+ .Endpoint =
+ {
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = MIDI_STREAM_OUT_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = MIDI_STREAM_EPSIZE,
+ .PollingIntervalMS = 0x05
+ },
+
+ .Refresh = 0,
+ .SyncEndpointNumber = 0
+ },
+
+ .MIDI_In_Jack_Endpoint_SPC =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
+ .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
+
+ .TotalEmbeddedJacks = 0x01,
+ .AssociatedJackID = {0x01}
+ },
+
+ .MIDI_Out_Jack_Endpoint =
+ {
+ .Endpoint =
+ {
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = MIDI_STREAM_IN_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = MIDI_STREAM_EPSIZE,
+ .PollingIntervalMS = 0x05
+ },
+
+ .Refresh = 0,
+ .SyncEndpointNumber = 0
+ },
+
+ .MIDI_Out_Jack_Endpoint_SPC =
+ {
+ .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
+ .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
+
+ .TotalEmbeddedJacks = 0x01,
+ .AssociatedJackID = {0x03}
+ }
+};
+
+/** 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 =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {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 =
+{
+ .Header = {.Size = USB_STRING_LEN(15), .Type = DTYPE_String},
+
+ .UnicodeString = L"Suspect Devices"
+};
+
+/** 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 =
+{
+ .Header = {.Size = USB_STRING_LEN(24), .Type = DTYPE_String},
+
+ .UnicodeString = L"Let's Get Leonard Loaded"
+};
+
+/** 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 uint8_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/Descriptors.h b/Descriptors.h
new file mode 100755
index 0000000..92c6c38
--- /dev/null
+++ b/Descriptors.h
@@ -0,0 +1,98 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2013.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2013 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 <LUFA/Drivers/USB/USB.h>
+
+ #include <avr/pgmspace.h>
+
+ /* Macros: */
+ /** Endpoint address of the MIDI streaming data IN endpoint, for device-to-host data transfers. */
+ #define MIDI_STREAM_IN_EPADDR (ENDPOINT_DIR_IN | 2)
+
+ /** Endpoint address of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
+ #define MIDI_STREAM_OUT_EPADDR (ENDPOINT_DIR_OUT | 1)
+
+ /** Endpoint size in bytes of the Audio isochronous streaming data IN and OUT endpoints. */
+ #define MIDI_STREAM_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;
+
+ // MIDI Audio Control Interface
+ USB_Descriptor_Interface_t Audio_ControlInterface;
+ USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC;
+
+ // MIDI Audio Streaming Interface
+ USB_Descriptor_Interface_t Audio_StreamInterface;
+ USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC;
+ USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Emb;
+ USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Ext;
+ USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Emb;
+ USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Ext;
+ USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
+ USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
+ USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
+ USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC;
+ } USB_Descriptor_Configuration_t;
+
+ /** 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 uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/MIDI.c b/MIDI.c
new file mode 100755
index 0000000..e5cf63b
--- /dev/null
+++ b/MIDI.c
@@ -0,0 +1,151 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2013.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2013 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 MIDI demo. This file contains the main tasks of
+ * the demo and is responsible for the initial application hardware configuration.
+ */
+
+#include "MIDI.h"
+
+/** LUFA MIDI Class driver interface configuration and state information. This structure is
+ * passed to all MIDI Class driver functions, so that multiple instances of the same class
+ * within a device can be differentiated from one another.
+ */
+USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
+ {
+ .Config =
+ {
+ .StreamingInterfaceNumber = 1,
+ .DataINEndpoint =
+ {
+ .Address = MIDI_STREAM_IN_EPADDR,
+ .Size = MIDI_STREAM_EPSIZE,
+ .Banks = 1,
+ },
+ .DataOUTEndpoint =
+ {
+ .Address = MIDI_STREAM_OUT_EPADDR,
+ .Size = MIDI_STREAM_EPSIZE,
+ .Banks = 1,
+ },
+ },
+ };
+
+volatile uint8_t myMidiChannel=DEFAULT_MIDI_CHANNEL;
+volatile uint8_t myMidiDevice=DEFAULT_MIDI_DEVICE;
+volatile uint8_t myMidiCable=DEFAULT_MIDI_CABLE;
+volatile uint8_t myMidiID[]={ARDUINO_MMA_VENDOR_1 ,ARDUINO_MMA_VENDOR_2,ARDUINO_MMA_VENDOR_3};
+
+/** 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();
+ MIDI_EVENT_PACKET_t e;
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+ GlobalInterruptEnable();
+
+ for (;;)
+ {
+
+ while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, (MIDI_EventPacket_t *)(&e)))
+ {
+ minSysexHandler(e);
+
+ }
+
+ MIDI_Device_USBTask(&USB_MIDI_Interface);
+ 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);
+#elif (ARCH == ARCH_XMEGA)
+ /* 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;
+#endif
+
+ /* Hardware Initialization */
+// Joystick_Init();
+ LEDs_Init();
+// Buttons_Init();
+ USB_Init();
+}
+
+
+/** Event handler for the library USB Connection event. */
+void EVENT_USB_Device_Connect(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+}
+
+/** Event handler for the library USB Disconnection event. */
+void EVENT_USB_Device_Disconnect(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+}
+
+/** Event handler for the library USB Configuration Changed event. */
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+ bool ConfigSuccess = true;
+
+ ConfigSuccess &= MIDI_Device_ConfigureEndpoints(&USB_MIDI_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)
+{
+ MIDI_Device_ProcessControlRequest(&USB_MIDI_Interface);
+}
+
diff --git a/MIDI.h b/MIDI.h
new file mode 100755
index 0000000..ba257ea
--- /dev/null
+++ b/MIDI.h
@@ -0,0 +1,79 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2013.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2013 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 MIDI.c.
+ */
+
+#ifndef _AUDIO_OUTPUT_H_
+#define _AUDIO_OUTPUT_H_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/wdt.h>
+ #include <avr/power.h>
+ #include <avr/interrupt.h>
+ #include <stdbool.h>
+ #include <string.h>
+
+ #include "Descriptors.h"
+ #include "MidiSpecs.h"
+ #include "MinSysex.h"
+
+
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Platform/Platform.h>
+
+ /* Macros: */
+ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+
+ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+
+ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+
+ /** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
+
+ /* Function Prototypes: */
+ void SetupHardware(void);
+ void CheckJoystickMovement(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/MIDI.hex b/MIDI.hex
new file mode 100644
index 0000000..6b896d5
--- /dev/null
+++ b/MIDI.hex
@@ -0,0 +1,252 @@
+:10000000BEC00000D7C00000D5C00000D3C00000B3
+:10001000D1C00000CFC00000CDC00000CBC00000A8
+:10002000C9C00000C7C00000E1C40000C3C0000098
+:10003000C1C00000BFC00000BDC00000BBC00000C8
+:10004000B9C00000B7C00000B5C00000B3C00000D8
+:10005000B1C00000AFC00000ADC00000ABC00000E8
+:10006000A9C00000A7C00000A5C00000A3C00000F8
+:10007000A1C000009FC000009DC000009BC0000008
+:1000800099C0000097C0000095C0000093C0000018
+:1000900091C000008FC000008DC000008BC0000028
+:1000A00089C0000087C0000085C000001201100157
+:1000B000000000084123370001000102000109028D
+:1000C0006500020100C032090400000001010000C7
+:1000D00009240100010900010109040100020103D2
+:1000E000000007240100014100062402010100066E
+:1000F0002402020200092403010301020100092471
+:10010000030204010101000905010240000500008D
+:1001100005250101010905820240000500000525B1
+:1001200001010304030904200353007500730070E8
+:1001300000650063007400200044006500760069DB
+:1001400000630065007300000032034C006500741A
+:100150000027007300200047006500740020004C59
+:100160000065006F006E0061007200640020004CAA
+:10017000006F00610064006500640000000011244D
+:100180001FBECFEFDAE0DEBFCDBF11E0A0E0B1E0EF
+:10019000EEE7FFE002C005900D92AA32B107D9F751
+:1001A00012E0AAE2B1E001C01D92AA33B107E1F763
+:1001B00043D0E3C625CF289A5D98479A089528989A
+:1001C0005D9A47980895089580E091E0C0D680FD3B
+:1001D00002C021E801C020E295B1822F8170809594
+:1001E0009160892385B99BB1822F8072809590623E
+:1001F00089238BB988B120788F77282B28B9089567
+:1002000084B7877F84BF88E10FB6F894809360003D
+:10021000109260000FBE80E090E020E80FB6F894E6
+:1002200020936100809361000FBE209A289A559A0E
+:100230005D9A3F9A4798BDC30F931F93DF93CF9367
+:1002400000D000D0CDB7DEB7DBDF28985D9A4798A5
+:1002500078948E010F5F1F4F05C069817A818B8171
+:100260009C8181D080E091E0B80104D68823A9F771
+:1002700080E091E03DD6E9D5F5CFDA01923049F042
+:10028000933061F09130F9F4ECEAF0E022E130E0F3
+:100290001EC0EEEBF0E025E630E019C0813049F0F9
+:1002A000813018F0823079F408C0E3E2F1E0849103
+:1002B00007C0E7E2F1E0849103C0E9E4F1E0849152
+:1002C000282F30E004C0E0E0F0E020E030E0ED93E3
+:1002D000FC93C901089511D3F89488E893E120E9CB
+:1002E00031E0F9013197F1F70197D9F787E797E7FF
+:1002F00090930108809300082CE088E190E00FB60D
+:10030000F894A895809360000FBE20936000FFCF03
+:10031000CF93DF9313B880E289B916B880912F018B
+:100320008D37C9F08E37E1F4809132018630C1F407
+:10033000809133018130A1F4C1E1D1E080E091E00E
+:10034000BE01E6D5249681E0C932D807B9F780E02E
+:1003500091E0B0D505C0809134018E3109F4BBDF46
+:10036000DF91CF9108959B01AC01862F8F70682F8C
+:1003700070E0CB01877F892B09F485C062FF83C0C1
+:1003800080912C01823051F480912A0190912B01AF
+:10039000813491051CF083E080932C016430710559
+:1003A00049F0643071050CF46EC0683071050CF0D2
+:1003B0006AC04AC080912C01813029F1813020F03F
+:1003C000823009F060C02BC010922B0110922A01DC
+:1003D000303F09F058C0842F8E57823040F480910E
+:1003E0000C015817A1F05F3709F04DC010C0809183
+:1003F0000E01481709F047C080910F01851709F0D9
+:1004000042C081E005C080911001831721F482E091
+:1004100080932C0104C083E080932C010895809187
+:100420002A0190912B01FC01EE0FFF1FEE0FFF1F21
+:10043000E35DFE4F20833183428353830196909383
+:100440002B0180932A01089580912A0190912B011C
+:10045000FC01EE0FFF1FEE0FFF1FE35DFE4F208339
+:10046000318342835383019690932B0180932A0119
+:1004700080912C01823029F44BDF13B880E289B9D6
+:1004800016B810922C0108959C01409138025091A9
+:1004900039024617570718F4F90190E045C0611575
+:1004A000710511F0AB01F8CF8091E8008E77809351
+:1004B000E80040E050E0F0CF80913102882309F459
+:1004C00045C0853009F444C08091E80083FF02C034
+:1004D00081E008958091E80082FD32C08091E800BB
+:1004E00080FF22C08091F3009091F200782F60E0AD
+:1004F000292F30E0262B372B07C081918093F10004
+:10050000415050402F5F3F4F4115510519F02830A1
+:10051000310598F390E02830310509F491E080919D
+:10052000E8008E778093E8004115510529F699235C
+:1005300019F606C080913102882341F0853041F0E0
+:100540008091E80082FFF6CF80E0089582E0089570
+:1005500083E008959C01409138025091390246177A
+:10056000570718F4F90190E046C06115710511F0C4
+:10057000AB01F8CF8091E8008E778093E80040E0EF
+:1005800050E0F0CF80913102882309F447C08530D4
+:1005900009F446C08091E80083FF02C081E008951D
+:1005A0008091E80082FD34C08091E80080FF23C084
+:1005B0008091F3009091F200782F60E0292F30E0D5
+:1005C000262B372B08C084918093F100319641503F
+:1005D00050402F5F3F4F4115510519F0283031052C
+:1005E00090F390E02830310509F491E08091E80023
+:1005F0008E778093E8004115510521F6992309F083
+:10060000C1CF06C080913102882341F0853041F08E
+:100610008091E80082FFF6CF80E0089582E008959F
+:1006200083E00895BF92CF92DF92EF92FF920F93F3
+:100630001F93CF93DF93182F092F7B016A012BD1D2
+:10064000B82E8823B1F5812F902F9C01E901C114A8
+:10065000D10439F0F60180819181E81AF90AC80FB6
+:10066000D91F00E010E022C08091E80085FD16C08F
+:100670008091E8008B778093E800E7D3C114D10420
+:1006800049F0F60180819181800F911F91838083D1
+:1006900085E010C000D1882349F00CC08091F100A2
+:1006A00089930894E108F1080F5F1F4FE114F104EA
+:1006B000D9F68B2DDF91CF911F910F91FF90EF9085
+:1006C000DF90CF90BF900895BF92CF92DF92EF92CC
+:1006D000FF920F931F93CF93DF93182F092F7B0166
+:1006E0006A01D9D0B82E8823B1F5812F902F9C01B3
+:1006F000E901C114D10439F0F60180819181E81A31
+:10070000F90AC80FD91F00E010E022C08091E8006C
+:1007100085FD16C08091E8008E778093E80095D320
+:10072000C114D10449F0F60180819181800F911F9D
+:100730009183808385E010C0AED0882349F00CC03F
+:1007400089918093F1000894E108F1080F5F1F4F31
+:10075000E114F104D9F68B2DDF91CF911F910F9108
+:10076000FF90EF90DF90CF90BF900895382F282F03
+:100770002EC0822F8F708093E900231721F4762FEB
+:10078000942F50E006C07091EC009091ED005091D4
+:10079000F00091FF1BC08091EB008E7F8093EB00F7
+:1007A0008091ED008D7F8093ED008091EB00816062
+:1007B0008093EB007093EC009093ED005093F00069
+:1007C0008091EE0087FD02C080E008952F5F273002
+:1007D00080F23F703093E90081E008950F931F93FA
+:1007E000CF93DF93062FEC0110E02AC09881992364
+:1007F00029F16B81E981FA812C81892F8F708730F3
+:1008000018F5223010F452E001C056E040E028E034
+:1008100030E003C04F5F220F331F2E173F07D0F386
+:100820006295660F660F607C991F9927991F692B47
+:100830004295407F452B9ADF882331F01F5F259634
+:100840001017A0F281E001C080E0DF91CF911F91ED
+:100850000F9108958091320288239CF404C0809106
+:1008600031028823B9F08091E80082FFF8CF8091AF
+:10087000E8008B778093E800089580913102882307
+:1008800049F08091E80080FFF8CF8091E8008E77F2
+:100890008093E80008954091E4005091E50024E63B
+:1008A0008091EC0080FF24C08091E80080FD1EC094
+:1008B00080913102882311F482E00895853011F48B
+:1008C00083E008958091EB0085FF02C081E00895E8
+:1008D0008091E4009091E5008417950709F32223A5
+:1008E00011F484E008952150AC01DACF80E008953E
+:1008F0008091E80082FFDCCFF9CF6BD072D0E0EEC0
+:10090000F0E0808181608083A8EDB0E08C918F77EA
+:100910008C9319BCE7EDF0E080818E7F80838C9111
+:100920008F7E8C93109230020895EF92FF920F9376
+:100930001F934FD056D008ED10E0F80180818F77DB
+:10094000808380818068808380818F7D808319BCD3
+:100950001092310210922D0210922F0210922E024C
+:1009600080EEE82EF12CF70180818B7F8083F801E7
+:1009700080818160808380E060E042E0F7DEE1EE2C
+:10098000F0E080818E7F8083E2EEF0E08081816004
+:100990008083808188608083F70180818E7F80835F
+:1009A000F8018081806180831F910F91FF90EF900B
+:1009B0000895E8EDF0E080818F7E8083E7EDF0E040
+:1009C00080818160808384E082BF81E080933002F7
+:1009D000ACCFE8EDF0E080818E7F80831092E20062
+:1009E00008951092DA001092E10008951F920F927C
+:1009F0000FB60F9211242F933F934F935F936F93F2
+:100A00007F938F939F93AF93BF93EF93FF938091C7
+:100A1000E10082FF0AC08091E20082FF06C080915F
+:100A2000E1008B7F8093E1000FD28091DA0080FF9C
+:100A30001DC08091D80080FF19C08091DA008E7FA0
+:100A40008093DA008091D90080FF0CC080E189BDDD
+:100A500082E189BD09B400FEFDCF81E080933102BF
+:100A6000AADB04C019BC10923102A9DB8091E1001D
+:100A700080FF18C08091E20080FF14C08091E200E6
+:100A80008E7F8093E2008091E20080618093E2009B
+:100A90008091D80080628093D80019BC85E0809353
+:100AA0003102D2D18091E10084FF2FC08091E20019
+:100AB00084FF2BC080E189BD82E189BD09B400FEBD
+:100AC000FDCF8091D8008F7D8093D8008091E10088
+:100AD0008F7E8093E1008091E2008F7E8093E20020
+:100AE0008091E20081608093E20080912D02882352
+:100AF00011F084E007C08091E30087FD02C081E02F
+:100B000001C083E0809331029FD18091E10083FF97
+:100B100022C08091E20083FF1EC08091E100877FA8
+:100B20008093E10082E08093310210922D02809147
+:100B3000E1008E7F8093E1008091E2008E7F8093C0
+:100B4000E2008091E20080618093E20080E060E05A
+:100B500042E00CDE79D1FF91EF91BF91AF919F916F
+:100B60008F917F916F915F914F913F912F910F9056
+:100B70000FBE0F901F9018951F93DF93CF93CDB7A3
+:100B8000DEB7AC970FB6F894DEBF0FBECDBFE2E381
+:100B9000F2E08091F100819322E0EA33F207C9F795
+:100BA00012DB8091E80083FF37C1809132023091DF
+:100BB0003302353009F487C0363040F43130C9F1A2
+:100BC000313070F0333009F027C133C0383009F4C8
+:100BD000F5C0393009F404C1363009F01DC196C0A2
+:100BE000803821F0823809F017C108C090912E0298
+:100BF00080912F02882399F0926011C08091360273
+:100C00008F708093E9008091EB0090E025E096954D
+:100C100087952A95E1F7982F91701092E9008091BD
+:100C2000E800877F8093E8009093F1001092F10034
+:100C3000D0C0882319F0823009F0EEC090E08F71A7
+:100C40009070009721F0029709F0E6C00CC08091E7
+:100C50003402813009F0E0C010922F02333069F580
+:100C600080932F022AC080913402882331F520918D
+:100C700036022F7009F4D0C02093E9008091EB0078
+:100C800080FF1BC0333021F48091EB00806213C0E1
+:100C90008091EB0080618093EB0081E090E002C0E6
+:100CA000880F991F2A95E2F78093EA001092EA00D4
+:100CB0008091EB0088608093EB001092E9008091B6
+:100CC000E800877F89C0882309F0A6C0109134020C
+:100CD0001F778091E3008078812B8093E3008091DF
+:100CE000E800877F8093E800B5DD8091E80080FF11
+:100CF000FCCF8091E30080688093E300112311F41E
+:100D000082E001C083E08093310286C08058823047
+:100D100008F082C0809134029091350223E08C3D2E
+:100D2000920709F033C083E08C838AE28B837FB71C
+:100D3000F894DE0115966EE040E050E011E2E62FF7
+:100D4000F0E010935700849140FF03C082958F70AC
+:100D50006F5F8F70282F30E08A3018F0C901C79676
+:100D600002C0C901C0968D939D934F5F5F4F443180
+:100D7000510529F77FBF8091E800877F8093E800C5
+:100D8000CE0103966AE270E07FDB12C0609136020A
+:100D9000AE014F5F5F4F71DABC01009709F43CC0B0
+:100DA0008091E800877F8093E80089819A81D2DB77
+:100DB0008091E8008B778093E8002EC0803861F541
+:100DC0008091E800877F8093E80080912D028093D6
+:100DD000F1008091E8008E778093E8003BDD1CC035
+:100DE0008823D1F4909134029230B0F48091E800DD
+:100DF000877F8093E80090932D022CDD80912D0257
+:100E0000882331F48091E30087FD02C081E001C0B6
+:100E100084E080933102D8D98091E80083FF0AC032
+:100E20008091E800877F8093E8008091EB008062EA
+:100E30008093EB00AC960FB6F894DEBF0FBECDBF2B
+:100E4000CF91DF911F91089508951F9380913102F2
+:100E5000882371F01091E9008091EC001092E90074
+:100E60008091E80083FF01C087DE1F701093E900C6
+:100E70001F910895FC01809131028430C9F486816C
+:100E80008F708093E9008091E80085FF11C0CB014D
+:100E900064E070E040E050E0C5DB8091E80085FD53
+:100EA00005C08091E8008B778093E80081E0089589
+:100EB00080E00895FC0180913102843011F082E0DD
+:100EC000089581818F708093E9004091F300209113
+:100ED000F200942F80E030E0822B932B892B11F4C9
+:100EE00080E008958091E8008E778093E800D3CC6D
+:100EF000FC0180913102843051F481818F708093A4
+:100F0000E9008091E80080FF02C0CF01D3CF0895AF
+:100F1000FC0180913102843011F092E016C0818191
+:100F20008F708093E900CB0164E070E040E050E016
+:100F3000CBDB982F882349F48091E80085FD05C01C
+:100F40008091E8008E778093E800892F0895CF93F1
+:100F5000DF93EC011B8682E08C838987CE010196AA
+:100F600061E03CDC882331F0CE01069661E036DC9E
+:0E0F7000811181E0DF91CF910895F894FFCFB9
+:100F7E000182400000010140000001000A0A7D23A9
+:100F8E004104F07E7F0406027D0423410104020128
+:0A0F9E0002040000010621F7000024
+:00000001FF
diff --git a/MidiSpecs.h b/MidiSpecs.h
new file mode 100644
index 0000000..931d2d4
--- /dev/null
+++ b/MidiSpecs.h
@@ -0,0 +1,151 @@
+/*--------------------------------------------------------------------------MidiSpecs.h
+ *
+ * These defines are based on specs created by the USB and MMA standards organizations.
+ * There are not a lot of other ways to code them so liscensing this is rather ludicrous.
+ * However, in order to be able to embed this in client projects, and avoid the stupidity
+ * of enforced open everything I will declare the following about this file.
+ *
+ * Copyright (c) 2011-13 Donald Delmar Davis, Suspect Devices
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * USB midi commands from
+ * MIDI10.pdf "Universal Serial Bus Device Class Definition for MIDI Devices"
+ * REV 1. (1999)
+ * http://www.usb.org/developers/devclass_docs/midi10.pdf
+ *
+ */
+
+#ifndef __LETS_MIDI_SPECS_H__
+#define __LETS_MIDI_SPECS_H__
+#include <stdint.h>
+#include <stdbool.h>
+// rework this for the different architectures....
+#if defined(__GNUC__)
+typedef struct
+{
+ unsigned cin : 4; // this is the low nibble.
+ unsigned cable : 4;
+// uint8_t cin;
+ uint8_t midi0;
+ uint8_t midi1;
+ uint8_t midi2;
+} __attribute__ ((__packed__)) MIDI_EVENT_PACKET_t ;
+#else
+typedef struct // may need to be adjusted for other compilers and bitfield order...
+{
+ unsigned cable : 4;
+ unsigned cin : 4;
+ uint8_t midi0;
+ uint8_t midi1;
+ uint8_t midi2;
+} MIDI_EVENT_PACKET_t ;
+#endif
+
+
+#define CIN_MISC_FUNCTION 0x00 /* Reserved for future extension. */
+#define CIN_CABLE_EVENT 0x01 /* Reserved for future extension. */
+#define CIN_2BYTE_SYS_COMMON 0x02 /* 2Bytes -- MTC, SongSelect, etc. */
+#define CIN_3BYTE_SYS_COMMON 0x03 /* 3Bytes -- SPP, etc. */
+#define CIN_SYSEX 0x04 /* 3Bytes */
+#define CIN_SYSEX_ENDS_IN_1 0x05 /* 1Bytes */
+#define CIN_SYSEX_ENDS_IN_2 0x06 /* 2Bytes */
+#define CIN_SYSEX_ENDS_IN_3 0x07 /* 3Bytes */
+#define CIN_NOTE_OFF 0x08 /* 3Bytes */
+#define CIN_NOTE_ON 0x09 /* 3Bytes */
+#define CIN_AFTER_TOUCH 0x0A /* 3Bytes */
+#define CIN_CONTROL_CHANGE 0x0B /* 3Bytes */
+#define CIN_PROGRAM_CHANGE 0x0C /* 2Bytes */
+#define CIN_CHANNEL_PRESSURE 0x0D /* 2Bytes */
+#define CIN_PITCH_WHEEL 0x0E /* 3Bytes */
+#define CIN_1BYTE 0x0F /* 1Bytes */
+//#define CIN_IS_SYSEX(cin) ((cin == CIN_SYSEX)||(cin == CIN_SYSEX_ENDS_IN_1)||(cin == CIN_SYSEX_ENDS_IN_2)||(cin == CIN_SYSEX_ENDS_IN_3))
+#define CIN_IS_SYSEX(cin) ( ((cin) & ~(0x08)) && ((cin) &0x04) )
+
+/*
+ * MIDI V1 message definitions these are from the MMA document
+ * http://www.midi.org/techspecs/midimessages.php
+ */
+#define MIDIv1_BAUD_RATE 31250
+
+/*
+ * parse midi (v1) message macros
+ */
+#define MIDIv1_IS_STATUS(b) ((b) & 0x80)
+#define MIDIv1_IS_VOICE(b) ((b) <= 0xEF)
+#define MIDIv1_VOICE_COMMAND(b) ((b) & 0xF0)
+#define MIDIv1_VOICE_CHANNEL(b) ((b) & 0x0F)
+#define MIDIv1_IS_SYSCOMMON(b) (((b) >= 0xF0) & ((b) < 0xF8))
+#define MIDIv1_IS_REALTIME(b) ((b) >= 0xF8)
+
+/*
+ * Voice category messages
+ */
+#define MIDIv1_NOTE_OFF 0x80 /* 2 bytes data -- CIN_NOTE_OFF */
+#define MIDIv1_NOTE_ON 0x90 /* 2 bytes data -- CIN_NOTE_ON */
+#define MIDIv1_AFTER_TOUCH 0xA0 /* 2 bytes data -- CIN_AFTER_TOUCH */
+#define MIDIv1_CONTROL_CHANGE 0xB0 /* 2 bytes data -- CIN_CONTROL_CHANGE */
+#define MIDIv1_PROGRAM_CHANGE 0xC0 /* 1 byte data -- CIN_PROGRAM_CHANGE */
+#define MIDIv1_CHANNEL_PRESSURE 0xD0 /* 1 byte data -- CIN_CHANNEL_PRESSURE */
+#define MIDIv1_PITCH_WHEEL 0xE0 /* 2 bytes data -- CIN_PITCH_WHEEL */
+
+/*
+ * System common category messages
+ */
+#define MIDIv1_SYSEX_START 0xF0
+#define MIDIv1_SYSEX_END 0xF7
+#define MIDIv1_MTC_QUARTER_FRAME 0xF1 /* 1 byte data -- CIN_2BYTE_SYS_COMMON */
+#define MIDIv1_SONG_POSITION_PTR 0xF2 /* 2 bytes data -- CIN_3BYTE_SYS_COMMON */
+#define MIDIv1_SONG_SELECT 0xF3 /* 1 byte data -- CIN_2BYTE_SYS_COMMON */
+#define MIDIv1_TUNE_REQUEST 0xF6 /* no data -- CIN_1BYTE */
+
+/*
+ * Realtime category messages, can be sent anytime
+ */
+#define MIDIv1_CLOCK 0xF8 /* no data -- CIN_1BYTE */
+#define MIDIv1_TICK 0xF9 /* no data -- CIN_1BYTE */
+#define MIDIv1_START 0xFA /* no data -- CIN_1BYTE */
+#define MIDIv1_CONTINUE 0xFB /* no data -- CIN_1BYTE */
+#define MIDIv1_STOP 0xFC /* no data -- CIN_1BYTE */
+#define MIDIv1_ACTIVE_SENSE 0xFE /* no data -- CIN_1BYTE */
+#define MIDIv1_RESET 0xFF /* no data -- CIN_1BYTE */
+
+/*
+ * sysex universal id's
+ */
+#define MIDIv1_UNIVERSAL_REALTIME_ID 0x7F
+#define MIDIv1_UNIVERSAL_NON_REALTIME_ID 0x7E
+#define MIDIv1_UNIVERSAL_ALL_CHANNELS 0x7F
+/*
+ * Susbset of universal sysex (general info request)
+ * As described http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/midispec.htm
+ */
+#define USYSEX_NON_REAL_TIME 0x7E
+#define USYSEX_REAL_TIME 0x7F
+#define USYSEX_ALL_CHANNELS 0x7F
+#define USYSEX_GENERAL_INFO 0x06
+#define USYSEX_GI_ID_REQUEST 0x01
+#define USYSEX_GI_ID_RESPONSE 0x02
+
+
+#endif
+
+
diff --git a/MinSysex.c b/MinSysex.c
new file mode 100644
index 0000000..6efb53c
--- /dev/null
+++ b/MinSysex.c
@@ -0,0 +1,249 @@
+//
+// MinSysex.c
+// LibMaple4Midi
+//
+// Created by Donald D Davis on 4/11/13.
+// Copyright (c) 2013 Suspect Devices. All rights reserved.
+// Modified BSD Liscense
+/*
+ 0xF0 SysEx
+ 0x7E Non-Realtime
+ 0x7F The SysEx channel. Could be from 0x00 to 0x7F.
+ Here we set it to "disregard channel".
+ 0x06 Sub-ID -- General Information
+ 0x01 Sub-ID2 -- Identity Request
+ 0xF7 End of SysEx
+---- response
+ 0xF0 SysEx
+ 0x7E Non-Realtime
+ 0x7F The SysEx channel. Could be from 0x00 to 0x7F.
+ Here we set it to "disregard channel".
+ 0x06 Sub-ID -- General Information
+ 0x02 Sub-ID2 -- Identity Reply
+ 0xID Manufacturer's ID
+ 0xf1 The f1 and f2 bytes make up the family code. Each
+ 0xf2 manufacturer assigns different family codes to his products.
+ 0xp1 The p1 and p2 bytes make up the model number. Each
+ 0xp2 manufacturer assigns different model numbers to his products.
+ 0xv1 The v1, v2, v3 and v4 bytes make up the version number.
+ 0xv2
+ 0xv3
+ 0xv4
+ 0xF7 End of SysEx
+*/
+#define STANDARD_ID_RESPONSE_LENGTH 6
+
+//#include <libmaple/usb_midi_device.h>
+//#include <libmaple/nvic.h>
+//#include <libmaple/delay.h>
+#include <MinSysex.h>
+//#include <wirish/wirish.h>
+#include <avr/wdt.h>
+#include <util/delay.h>
+
+#define MAX_SYSEX_SIZE ((256+1)/4)
+
+/********************************* ACHTUNG! ignores usbmidi cable ********************************/
+const MIDI_EVENT_PACKET_t standardIDResponse[]={
+ { CIN_SYSEX,
+ DEFAULT_MIDI_CABLE,
+ MIDIv1_SYSEX_START,
+ USYSEX_NON_REAL_TIME,
+ USYSEX_ALL_CHANNELS},
+ { CIN_SYSEX,
+ DEFAULT_MIDI_CABLE,
+ USYSEX_GENERAL_INFO,
+ USYSEX_GI_ID_RESPONSE,
+ ARDUINO_MMA_VENDOR_1},
+ { CIN_SYSEX,
+ DEFAULT_MIDI_CABLE,
+ ARDUINO_MMA_VENDOR_2, // extended ID
+ ARDUINO_MMA_VENDOR_3, // extended ID
+ 1}, // family #1
+ { CIN_SYSEX,
+ DEFAULT_MIDI_CABLE,
+ 2, // family #2
+ 1, // part #1
+ 2}, // part #2
+ { CIN_SYSEX,
+ DEFAULT_MIDI_CABLE,
+ 0, // version 1
+ 0, // version 2
+ 1}, // version 3
+ { CIN_SYSEX_ENDS_IN_2,
+ DEFAULT_MIDI_CABLE,
+ '!', // lgl compatible
+ MIDIv1_SYSEX_END,
+ 0}
+};
+/*
+const MIDI_EventPacket_t standardIDResponse[]={
+ { CIN_SYSEX,
+ MIDIv1_SYSEX_START,
+ USYSEX_NON_REAL_TIME,
+ USYSEX_ALL_CHANNELS},
+ { CIN_SYSEX,
+ USYSEX_GENERAL_INFO,
+ USYSEX_GI_ID_RESPONSE,
+ ARDUINO_MMA_VENDOR_1 },
+ { CIN_SYSEX ,
+ ARDUINO_MMA_VENDOR_2, // extended ID
+ ARDUINO_MMA_VENDOR_3 , // extended ID
+ 1 }, // family #1
+ { CIN_SYSEX,
+ 2, // family #2
+ 1, // part #1
+ 2 }, // part #2
+ { CIN_SYSEX,
+ 0, // version 1
+ 0, // version 2
+ 1 }, // version 3
+ { CIN_SYSEX_ENDS_IN_2,
+ '!', // lgl compatible
+ MIDIv1_SYSEX_END,
+ 0 } // padd
+};*/
+//#define STANDARD_ID_RESPONSE_LENGTH (sizeof(standardIDResponse))
+
+typedef enum {NOT_IN_SYSEX=0,COULD_BE_MY_SYSEX,YUP_ITS_MY_SYSEX,ITS_NOT_MY_SYSEX} sysexStates;
+volatile MIDI_EVENT_PACKET_t sysexBuffer[MAX_SYSEX_SIZE];
+volatile sysexStates sysexState;
+volatile int sysexFinger=0;
+
+/*
+ 0xF0 SysEx
+ 0x?? ARDUINO_MMA_VENDOR_1
+ 0x?? ARDUINO_MMA_VENDOR_2
+
+ 0x?? ARDUINO_MMA_VENDOR_3
+ 0x10 LGL_DEVICE_NUMBER
+ 0xLE CMD: REBOOT
+
+ 0xf7 EOSysEx
+*/
+#define STACK_TOP 0x20000800
+#define EXC_RETURN 0xFFFFFFF9
+#define DEFAULT_CPSR 0x61000000
+#define RESET_DELAY 100000
+
+void dealWithItQuickly(void);
+/* -----------------------------------------------------------------------------dealWithItQuickly()
+ * Note: at this point we have established that the sysex belongs to us.
+ * So we need to respond to any generic requests like information requests.
+ * We also need to handle requests which are meant for us. At the moment this is just the
+ * reset request.
+ *
+ */
+void dealWithItQuickly(){
+ LEDs_ToggleLEDs(LEDS_LED2);
+ switch (sysexBuffer[0].midi1) {
+
+ case USYSEX_NON_REAL_TIME:
+ switch (sysexBuffer[1].midi0) {
+ case USYSEX_GENERAL_INFO:
+ if (sysexBuffer[1].midi1==USYSEX_GI_ID_REQUEST) {
+ for (uint8_t i=0;i<STANDARD_ID_RESPONSE_LENGTH;i++)
+ MIDI_Device_SendEventPacket(&USB_MIDI_Interface, (MIDI_EventPacket_t *)standardIDResponse+i);
+ MIDI_Device_Flush(&USB_MIDI_Interface);
+ }
+
+ break;
+ }
+ case USYSEX_REAL_TIME:
+ break;
+ case ARDUINO_MMA_VENDOR_1:
+ if (sysexBuffer[1].midi2==LGL_RESET_CMD) {
+
+ Jump_To_Bootloader();
+ /* Can't happen. */
+ //ASSERT_FAULT(0);
+
+ }
+
+ default:
+ break;
+ }
+ ;//turn the led on?
+}
+
+/* -----------------------------------------------------------------------------LglSysexHandler()
+ * The idea here is to identify which Sysex's belong to us and deal with them.
+ */
+void minSysexHandler(MIDI_EVENT_PACKET_t e) {
+
+ if (!CIN_IS_SYSEX(e.cin)) {
+ return;
+ }
+
+ if ((sysexState==YUP_ITS_MY_SYSEX) && (sysexFinger>MAX_SYSEX_SIZE)){
+ sysexState=ITS_NOT_MY_SYSEX; //eisenhower policy. Even if its mine I cant deal with it.
+ }
+
+ switch (e.cin) {
+ case CIN_SYSEX: // sysex starts or continues.
+ switch (sysexState) {
+ case NOT_IN_SYSEX : // new sysex.
+ sysexFinger=0;
+ if (e.midi0 == MIDIv1_SYSEX_START) {
+
+
+ if (e.midi1==USYSEX_REAL_TIME
+ ||e.midi1==USYSEX_NON_REAL_TIME) {
+ if ((e.midi2==myMidiChannel)
+ ||(e.midi2==USYSEX_ALL_CHANNELS)
+ ) {
+ sysexState=YUP_ITS_MY_SYSEX;
+ sysexBuffer[sysexFinger++]=e;
+ }
+ } else if ((e.midi1==myMidiID[0])
+ && (e.midi2==myMidiID[1])
+ ){
+
+ sysexState=COULD_BE_MY_SYSEX;
+ sysexBuffer[sysexFinger++]=e;
+ }
+ }
+ break;
+ case COULD_BE_MY_SYSEX:
+ if (e.midi0==myMidiID[2]) {
+ sysexState=YUP_ITS_MY_SYSEX;
+ sysexBuffer[sysexFinger++]=e;
+ } else {
+ sysexState=ITS_NOT_MY_SYSEX;
+ }
+ break;
+ case YUP_ITS_MY_SYSEX:
+ sysexBuffer[sysexFinger++]=e;
+ break;
+ default:
+ break;
+ }
+ break;
+ case CIN_SYSEX_ENDS_IN_1:
+ case CIN_SYSEX_ENDS_IN_2:
+ case CIN_SYSEX_ENDS_IN_3:
+ sysexBuffer[sysexFinger++]=e;
+ if (sysexState==YUP_ITS_MY_SYSEX) {
+ dealWithItQuickly(); // its our sysex and we will cry if we want to
+ LEDs_ToggleLEDs(LEDS_LED2);
+ }
+ //sysexFinger=0;
+ sysexState=NOT_IN_SYSEX;
+ break;
+ default:
+ return;
+ }
+ return;
+}
+
+void Jump_To_Bootloader(void)
+{
+ // If USB is used, detach from the bus and reset it
+ USB_Disable(); // Disable all interrupts
+ cli();
+ // Wait for the USB detachment to register on the host
+ Delay_MS(500);
+ *(uint16_t *)0x0800 = 0x7777;
+ wdt_enable(WDTO_250MS);
+ for (;;);
+} \ No newline at end of file
diff --git a/MinSysex.h b/MinSysex.h
new file mode 100644
index 0000000..8a16b98
--- /dev/null
+++ b/MinSysex.h
@@ -0,0 +1,38 @@
+//
+// lgl_min_sysex.h
+// LibMaple4Midi
+//
+// Created by Donald D Davis on 4/11/13.
+// Copyright (c) 2013 Suspect Devices. All rights reserved.
+//
+#ifndef __LGL_MIN_SYSEX_H__
+#define __LGL_MIN_SYSEX_H__ 1
+
+
+#include "MidiSpecs.h"
+#include "MIDI.h"
+//#include "LGL.h"
+
+#define ARDUINO_MMA_VENDOR_1 0x7D
+#define ARDUINO_MMA_VENDOR_2 0x23
+#define ARDUINO_MMA_VENDOR_3 0x41
+
+// move to LGL.h
+#define LGL_RESET_CMD 0x1e
+#define LGL_BOOTLOADER_CMD 0x1f
+
+#define DEFAULT_MIDI_CHANNEL 0x0A
+#define DEFAULT_MIDI_DEVICE 0x0A
+#define DEFAULT_MIDI_CABLE 0x00
+
+// eventually all of this should be in a place for settings which can be written to flash.
+extern volatile uint8_t myMidiChannel;
+extern volatile uint8_t myMidiDevice;
+extern volatile uint8_t myMidiCable;
+extern volatile uint8_t myMidiID[];
+extern USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface;
+
+void LglSysexHandler(uint32_t *midiBufferRx,uint32_t *rx_offset,uint32_t *n_unread_bytes);
+void minSysexHandler(MIDI_EVENT_PACKET_t e);
+void Jump_To_Bootloader(void);
+#endif \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/README.md
diff --git a/makefile b/makefile
new file mode 100755
index 0000000..5c2fd21
--- /dev/null
+++ b/makefile
@@ -0,0 +1,41 @@
+#
+# LUFA Library
+# Copyright (C) Dean Camera, 2013.
+#
+# dean [at] fourwalledcubicle [dot] com
+# www.lufa-lib.org
+#
+# --------------------------------------
+# LUFA Project Makefile.
+# --------------------------------------
+
+# Run "make help" for target help.
+
+MCU = atmega32u4
+ARCH = AVR8
+BOARD = LEONARDO
+F_CPU = 16000000
+F_USB = $(F_CPU)
+OPTIMIZATION = s
+TARGET = MIDI
+SRC = $(TARGET).c Descriptors.c MinSysex.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
+LUFA_PATH = ../../../../LUFA
+CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
+LD_FLAGS =
+AVRDUDE_PROGRAMMER = avr109 # Add this
+AVRDUDE_PORT = /dev/tty.usbmodem1a21
+AVRDUDE_FLAGS = -b57600
+
+# 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
diff --git a/reset.py b/reset.py
new file mode 100755
index 0000000..d4c78f6
--- /dev/null
+++ b/reset.py
@@ -0,0 +1,171 @@
+'''------------------------------------------------------------------------ reset.py
+
+ This is a quick reboot mechanism for loading code onto a stock arduino leonardo
+ It sends and recieves the Univeral midi sysex id request when it finds the a
+ device it sends the device a sysex to reset it.
+
+
+ Copyright (c) 2013 Donald Delmar Davis, Suspect Devices
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ software and associated documentation files (the "Software"), to deal in the Software
+ without restriction, including without limitation the rights to use, copy, modify,
+ merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies
+ or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+'''
+import rtmidi_python as rtmidi
+import time
+import sys
+import serial
+
+# this stuff should probably go in a constants file.
+SYSEX_BEGIN =0xf0
+SYSEX_NON_REAL_TIME =0x7e
+SYSEX_NON_REAL =0x7f
+SYSEX_ALL_CHANNELS =0x7f
+SYSEX_GENERAL_INFO =0x06
+SYSEX_IDENTITY_REQUEST =0x01
+SYSEX_IDENTITY_REPLY =0x02
+SYSEX_END_SYSEX =0xF7
+
+
+ARDUINO_MMA_VENDOR_1 =0x7D
+ARDUINO_MMA_VENDOR_2 =0x23
+ARDUINO_MMA_VENDOR_3 =0x41
+LGL_RESET_CMD =0x1e
+LGL_BOOTLOADER_CMD =0x1f
+
+
+global we_are_done
+we_are_done=False
+
+askfortheids=[SYSEX_BEGIN,SYSEX_NON_REAL_TIME,SYSEX_ALL_CHANNELS,
+ SYSEX_GENERAL_INFO,SYSEX_IDENTITY_REQUEST,SYSEX_END_SYSEX]
+
+resetthedevice=[SYSEX_BEGIN,
+ ARDUINO_MMA_VENDOR_1,
+ ARDUINO_MMA_VENDOR_2,
+ ARDUINO_MMA_VENDOR_3,
+ 0x0a, #device/channel is currently ignored...
+ LGL_RESET_CMD,
+ SYSEX_END_SYSEX]
+
+'''
+ this is our callback routine for midi messages.
+ It handles sysexes sent to it and the universal sysex id response.
+'''
+def handleOurSysexes(message, time_stamp):
+ global we_are_done
+ #print "?"+str(message)+"?"
+ if (len(message)>4 and message[0]==SYSEX_BEGIN): #if its a sysex message
+ if (message[1]==125 and message[2]==51 and message[3]==51):
+ print "DBG:",decodePayload(message)
+ elif (message[1]==SYSEX_NON_REAL_TIME and message[3]==SYSEX_GENERAL_INFO
+ #and message[4]==SYSEX_IDENTITY_REPLY
+ ):
+ print 'MANUFACTURER ID: 0x%02X 0x%02X 0x%02X' % (
+ message[5],message[6],message[7])
+ print "FAMILY ID : 0x%02X%02x" % (
+ message[8], message[9])
+ print "PRODUCT ID : 0x%02X%02x" % (
+ message[10], message[11])
+ print "VERSION : 0x%02X%02x%02X%02x" % (
+ message[12],message[13],message[14],message[15])
+ if (message[15] == ord('!')) :
+ print "YAY LETS GET LOADED!!!"
+ midi_out.send_message(resetthedevice)
+ we_are_done=True
+
+
+#012345678
+#bxxxyyyzz
+#b=sosysex, xxx= my mma id, yyy = client mma id , zz other info
+
+def decodePayload(payload):
+#
+ return "".join(map(chr, payload[4:-1]))
+
+# main code begins here.
+'''
+ Monophonic....
+ This should poll all avaliable midi devices until we find one that has one of our devices on it.
+ eventually this should be expanded to handle multiple devices and understand multiple clients
+'''
+
+try:
+ midi_in = rtmidi.MidiIn()
+ midi_out = rtmidi.MidiOut()
+ if len(midi_in.ports):
+ print midi_in.ports
+ midi_in.callback = handleOurSysexes
+ midi_in.ignore_types(False,False,False)
+ midi_in.open_port(0)
+ midi_out.open_port(0)
+ time.sleep(3)
+ midi_out.send_message(askfortheids)
+ else:
+ print "Bailing: No Midi Devices attached!"
+ exit()
+
+
+
+except Exception as e:
+ print str(e)
+ exit()
+
+
+
+while 1:
+ time.sleep(1)
+
+ if we_are_done:
+ midi_in.close_port()
+ midi_out.close_port()
+ time.sleep(2)
+ exit()
+
+ time.sleep(1)
+ print "requesting id"
+
+ midi_out.send_message(askfortheids)
+
+
+"""
+ http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/midispec.htm
+
+ 0xF0 SysEx
+ 0x7E Non-Realtime
+ 0x7F The SysEx channel. Could be from 0x00 to 0x7F. Here we set it to "disregard channel".
+ 0x06 Sub-ID -- General Information
+ 0x01 Sub-ID2 -- Identity Request
+ 0xF7 End of SysEx
+ Here is the Identity Reply message:
+ 0xF0 SysEx
+ 0x7E Non-Realtime
+ 0x7F The SysEx channel. Could be from 0x00 to 0x7F.
+ Here we set it to "disregard channel".
+ 0x06 Sub-ID -- General Information
+ 0x02 Sub-ID2 -- Identity Reply
+ 0xID Manufacturer's ID
+ 0xf1 The f1 and f2 bytes make up the family code. Each
+ 0xf2 manufacturer assigns different family codes to his products.
+ 0xp1 The p1 and p2 bytes make up the model number. Each
+ 0xp2 manufacturer assigns different model numbers to his products.
+ 0xv1 The v1, v2, v3 and v4 bytes make up the version number.
+ 0xv2
+ 0xv3
+ 0xv4
+ 0xF7 End of SysEx
+""" \ No newline at end of file
diff --git a/sysextest.py b/sysextest.py
new file mode 100644
index 0000000..d6bc26e
--- /dev/null
+++ b/sysextest.py
@@ -0,0 +1,164 @@
+'''---------------------------------------------------------------- sysextest.py
+This is a quick and dirty debugging console for a midi device.
+
+It recieves sysex messages sent the the dev id 0x7d 0x33 0x33 and decodes and
+prints them.
+
+In addition it also sends and recieves the Univeral midi sysex id request.
+
+
+ Copyright (c) 2013 Donald Delmar Davis, Suspect Devices
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ software and associated documentation files (the "Software"), to deal in the Software
+ without restriction, including without limitation the rights to use, copy, modify,
+ merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies
+ or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+'''
+import rtmidi_python as rtmidi
+import time
+import sys
+import serial
+
+# this stuff should probably go in a constants file.
+SYSEX_BEGIN =0xf0
+SYSEX_NON_REAL_TIME =0x7e
+SYSEX_NON_REAL =0x7f
+SYSEX_ALL_CHANNELS =0x7f
+SYSEX_GENERAL_INFO =0x06
+SYSEX_IDENTITY_REQUEST =0x01
+SYSEX_IDENTITY_REPLY =0x02
+SYSEX_END_SYSEX =0xF7
+
+
+ARDUINO_MMA_VENDOR_1 =0x7D
+ARDUINO_MMA_VENDOR_2 =0x23
+ARDUINO_MMA_VENDOR_3 =0x41
+LGL_RESET_CMD =0x1e
+LGL_BOOTLOADER_CMD =0x1f
+
+
+askfortheids=[SYSEX_BEGIN,SYSEX_NON_REAL_TIME,SYSEX_ALL_CHANNELS,
+ SYSEX_GENERAL_INFO,SYSEX_IDENTITY_REQUEST,SYSEX_END_SYSEX]
+
+resetthedevice=[SYSEX_BEGIN,
+ ARDUINO_MMA_VENDOR_1,
+ ARDUINO_MMA_VENDOR_2,
+ ARDUINO_MMA_VENDOR_3,
+ 0x0a, #device/channel is currently ignored...
+ LGL_RESET_CMD,
+ SYSEX_END_SYSEX]
+
+'''
+ this is our callback routine for midi messages.
+ It handles sysexes sent to it and the universal sysex id response.
+'''
+def handleOurSysexes(message, time_stamp):
+ #print "?"+str(message)+"?"
+ if (len(message)>4 and message[0]==SYSEX_BEGIN): #if its a sysex message
+ if (message[1]==125 and message[2]==51 and message[3]==51):
+ print "DBG:",decodePayload(message)
+ elif (message[1]==SYSEX_NON_REAL_TIME and message[3]==SYSEX_GENERAL_INFO
+ and message[4]==SYSEX_IDENTITY_REPLY ):
+ print 'MANUFACTURER ID: 0x%02X 0x%02X 0x%02X' % (
+ message[5],message[6],message[7])
+ print "FAMILY ID : 0x%02X%02x" % (
+ message[8], message[9])
+ print "PRODUCT ID : 0x%02X%02x" % (
+ message[10], message[11])
+ print "VERSION : 0x%02X%02x%02X%02x" % (
+ message[12],message[13],message[14],message[15])
+ if (message[15] == ord('!')) :
+ print "YAY LETS GET LOADED!!!"
+ midi_out.send_message(resetthedevice)
+ ser = serial.Serial()
+ time.sleep(2.5)
+ ser.port='/dev/tty.usbmodem1a21'
+ ser.baudrate=1200
+ ser.open()
+ ser.close()
+ time.sleep(1)
+ ser.open()
+ ser.close()
+
+
+#012345678
+#bxxxyyyzz
+#b=sosysex, xxx= my mma id, yyy = client mma id , zz other info
+
+def decodePayload(payload):
+#
+ return "".join(map(chr, payload[4:-1]))
+
+# main code begins here.
+'''
+ Monophonic....
+ This should poll all avaliable midi devices until we find one that has one of our devices on it.
+ eventually this should be expanded to handle multiple devices and understand multiple clients
+'''
+
+try:
+ midi_in = rtmidi.MidiIn()
+ midi_out = rtmidi.MidiOut()
+ if len(midi_in.ports):
+ print midi_in.ports
+ midi_in.callback = handleOurSysexes
+ midi_in.ignore_types(False,False,False)
+ midi_in.open_port(0)
+ midi_out.open_port(0)
+ time.sleep(2)
+ midi_out.send_message(askfortheids)
+ else:
+ print "Bailing: No Midi Devices attached!"
+ exit()
+except Exception as e:
+ print str(e)
+ exit()
+
+
+
+while 1:
+ time.sleep(5)
+ print "requesting id"
+ midi_out.send_message(askfortheids)
+
+
+"""
+ http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/midispec.htm
+
+ 0xF0 SysEx
+ 0x7E Non-Realtime
+ 0x7F The SysEx channel. Could be from 0x00 to 0x7F. Here we set it to "disregard channel".
+ 0x06 Sub-ID -- General Information
+ 0x01 Sub-ID2 -- Identity Request
+ 0xF7 End of SysEx
+ Here is the Identity Reply message:
+ 0xF0 SysEx
+ 0x7E Non-Realtime
+ 0x7F The SysEx channel. Could be from 0x00 to 0x7F.
+ Here we set it to "disregard channel".
+ 0x06 Sub-ID -- General Information
+ 0x02 Sub-ID2 -- Identity Reply
+ 0xID Manufacturer's ID
+ 0xf1 The f1 and f2 bytes make up the family code. Each
+ 0xf2 manufacturer assigns different family codes to his products.
+ 0xp1 The p1 and p2 bytes make up the model number. Each
+ 0xp2 manufacturer assigns different model numbers to his products.
+ 0xv1 The v1, v2, v3 and v4 bytes make up the version number.
+ 0xv2
+ 0xv3
+ 0xv4
+ 0xF7 End of SysEx
+""" \ No newline at end of file