diff options
| author | Donald Delmar Davis <don@suspectdevices.com> | 2013-09-23 19:14:52 -0700 |
|---|---|---|
| committer | Donald Delmar Davis <don@suspectdevices.com> | 2013-09-23 19:14:52 -0700 |
| commit | bd15d30ea0421dcf7074489db90ac64ba53a29e6 (patch) | |
| tree | 35ff190d369ce17fd87ab563fca29786f0453ced | |
Add the stuff for real...
| -rwxr-xr-x | Config/LUFAConfig.h | 126 | ||||
| -rwxr-xr-x | Descriptors.c | 329 | ||||
| -rwxr-xr-x | Descriptors.h | 98 | ||||
| -rwxr-xr-x | MIDI.c | 151 | ||||
| -rwxr-xr-x | MIDI.h | 79 | ||||
| -rw-r--r-- | MIDI.hex | 252 | ||||
| -rw-r--r-- | MidiSpecs.h | 151 | ||||
| -rw-r--r-- | MinSysex.c | 249 | ||||
| -rw-r--r-- | MinSysex.h | 38 | ||||
| -rw-r--r-- | README.md | 0 | ||||
| -rwxr-xr-x | makefile | 41 | ||||
| -rwxr-xr-x | reset.py | 171 | ||||
| -rw-r--r-- | sysextest.py | 164 |
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 + @@ -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); +} + @@ -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 |
