From e875d7cf9f31fe9ac586718850a433f2851b5e19 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 25 Apr 2012 18:28:56 +0000 Subject: [PATCH] Changed MIDI event structure MIDI_EventPacket_t to use a single field for the combined virtual cable index and command ID, to prevent bitfield packing issues on some architectures (thanks to Darren Gibbs). --- Demos/Device/ClassDriver/MIDI/MIDI.c | 5 ++--- Demos/Device/LowLevel/MIDI/MIDI.c | 5 ++--- Demos/Host/ClassDriver/MIDIHost/MIDIHost.c | 7 +++---- Demos/Host/LowLevel/MIDIHost/MIDIHost.c | 7 +++---- LUFA/DoxygenPages/ChangeLog.txt | 2 ++ LUFA/DoxygenPages/MigrationInformation.txt | 6 ++++++ LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h | 15 +++++++++++++-- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Demos/Device/ClassDriver/MIDI/MIDI.c b/Demos/Device/ClassDriver/MIDI/MIDI.c index a55c6a70ed..6a117ab4b2 100644 --- a/Demos/Device/ClassDriver/MIDI/MIDI.c +++ b/Demos/Device/ClassDriver/MIDI/MIDI.c @@ -78,7 +78,7 @@ int main(void) MIDI_EventPacket_t ReceivedMIDIEvent; while (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent)) { - if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && (ReceivedMIDIEvent.Data3 > 0)) + if ((ReceivedMIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)) && (ReceivedMIDIEvent.Data3 > 0)) LEDs_SetAllLEDs(ReceivedMIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2); else LEDs_SetAllLEDs(LEDS_NO_LEDS); @@ -155,8 +155,7 @@ void CheckJoystickMovement(void) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { - .CableNumber = 0, - .Command = (MIDICommand >> 4), + .Event = MIDI_EVENT(0, MIDICommand), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, diff --git a/Demos/Device/LowLevel/MIDI/MIDI.c b/Demos/Device/LowLevel/MIDI/MIDI.c index f8bc4e9179..335c7143e3 100644 --- a/Demos/Device/LowLevel/MIDI/MIDI.c +++ b/Demos/Device/LowLevel/MIDI/MIDI.c @@ -160,8 +160,7 @@ void MIDI_Task(void) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { - .CableNumber = 0, - .Command = (MIDICommand >> 4), + .Event = MIDI_EVENT(0, MIDICommand), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, @@ -191,7 +190,7 @@ void MIDI_Task(void) Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); /* Check to see if the sent command is a note on message with a non-zero velocity */ - if ((MIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && (MIDIEvent.Data3 > 0)) + if ((MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)) && (MIDIEvent.Data3 > 0)) { /* Change LEDs depending on the pitch of the sent note */ LEDs_SetAllLEDs(MIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2); diff --git a/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c b/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c index 129bd3d628..472d19aee7 100644 --- a/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c +++ b/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c @@ -111,8 +111,8 @@ void JoystickHost_Task(void) MIDI_EventPacket_t MIDIEvent; while (MIDI_Host_ReceiveEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent)) { - bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4)); - bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4)); + bool NoteOnEvent = (MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)); + bool NoteOffEvent = (MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_OFF)); /* Display note events from the host */ if (NoteOnEvent || NoteOffEvent) @@ -173,8 +173,7 @@ void CheckJoystickMovement(void) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { - .CableNumber = 0, - .Command = (MIDICommand >> 4), + .Event = MIDI_EVENT(0, MIDICommand), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, diff --git a/Demos/Host/LowLevel/MIDIHost/MIDIHost.c b/Demos/Host/LowLevel/MIDIHost/MIDIHost.c index 060761f587..f4a52accd4 100644 --- a/Demos/Host/LowLevel/MIDIHost/MIDIHost.c +++ b/Demos/Host/LowLevel/MIDIHost/MIDIHost.c @@ -177,8 +177,8 @@ void MIDIHost_Task(void) if (!(Pipe_BytesInPipe())) Pipe_ClearIN(); - bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4)); - bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4)); + bool NoteOnEvent = (MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)); + bool NoteOffEvent = (MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_OFF)); if (NoteOnEvent || NoteOffEvent) { @@ -237,8 +237,7 @@ void MIDIHost_Task(void) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { - .CableNumber = 0, - .Command = (MIDICommand >> 4), + .Event = MIDI_EVENT(0, MIDICommand), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt index 150d5de399..df504763c7 100644 --- a/LUFA/DoxygenPages/ChangeLog.txt +++ b/LUFA/DoxygenPages/ChangeLog.txt @@ -33,6 +33,8 @@ * - The Pipe_ConfigurePipe() function no longer takes a number of banks as a special mask; the number of banks is now specified as an integer parameter * - Pipes are now configured via instances of a new struct USB_Pipe_Table_t in all host mode class drivers, rather than a list of pipe parameters * - Added support for various assert and debugging macros for the UC3 devices + * - Changed MIDI event structure MIDI_EventPacket_t to use a single field for the combined virtual cable index and command ID, to prevent bitfield packing issues + * on some architectures (thanks to Darren Gibbs). * - Library Applications: * - Raised the guard bits in the AVRISP-MKII clone project when in PDI and TPI to 32, to prevent communication errors on low quality connections to a target * - Added additional bootloader API data to expose the bootloader start address and class to the DFU and CDC class bootloaders diff --git a/LUFA/DoxygenPages/MigrationInformation.txt b/LUFA/DoxygenPages/MigrationInformation.txt index fe04732843..f0fd9b2109 100644 --- a/LUFA/DoxygenPages/MigrationInformation.txt +++ b/LUFA/DoxygenPages/MigrationInformation.txt @@ -27,6 +27,9 @@ * to update their class driver struct instantiation to match the new scheme (see \ref USB_Endpoint_Table_t). * - The \c ENDPOINT_BANKS_SUPPORTED() and \c ENDPOINT_MAX_ENDPOINT_SIZE() macros have been removed, as these do not function correctly with the new addressing * scheme for the endpoint APIs. Please refer to the target device's datasheet for the maximum bank size of each endpoint. + * - The MIDI class driver \ref MIDI_EventPacket_t event packet no longer contains seperate \c CableIndex and \c Command entries; these have been combined + * into a single \c Event element which can be contructed using the new macro \ref MIDI_EVENT(). Existing applications should use the new macro and structure + * element name. * * Host Mode * - The Android Accessory Host class driver property strings are now a array of \c char* rather than a struct of named pointers. Existing applications @@ -38,6 +41,9 @@ * calls to use full pipe addresses when required within the device. * - All host mode class drivers have been updated to use a new unified pipe description structure for all pipes; existing applications will need to update * their class driver struct instantiation to match the new scheme (see \ref USB_Pipe_Table_t). + * - The MIDI class driver \ref MIDI_EventPacket_t event packet no longer contains seperate \c CableIndex and \c Command entries; these have been combined + * into a single \c Event element which can be contructed using the new macro \ref MIDI_EVENT(). Existing applications should use the new macro and structure + * element name. * * \section Sec_Migration120219 Migrating from 111009 to 120219 * USB Core diff --git a/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h b/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h index 60b0908f3e..25b80b7d40 100644 --- a/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h +++ b/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h @@ -84,8 +84,20 @@ * addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address. * * \param[in] channel MIDI channel number to address. + * + * \return Constructed MIDI channel ID. */ #define MIDI_CHANNEL(channel) ((channel) - 1) + + /** Constructs a MIDI event ID from a given MIDI command and a virtual MIDI cable index. This can then be + * used to create and decode \ref MIDI_EventPacket_t MIDI event packets. + * + * \param[in] virtualcable Index of the virtual MIDI cable the event relates to + * \param[in] command MIDI command to send through the virtual MIDI cable + * + * \return Constructed MIDI event ID. + */ + #define MIDI_EVENT(virtualcable, command) ((virtualcable << 4) | (command >> 4)) /* Enums: */ /** Enum for the possible MIDI jack types in a MIDI device jack descriptor. */ @@ -290,8 +302,7 @@ */ typedef struct { - unsigned Command : 4; /**< Upper nibble of the MIDI command being sent or received in the event packet. */ - unsigned CableNumber : 4; /**< Virtual cable number of the event being sent or received in the given MIDI interface. */ + uint8_t Event; /**< MIDI event type, constructed with the \ref MIDI_EVENT() macro. */ uint8_t Data1; /**< First byte of data in the MIDI event. */ uint8_t Data2; /**< Second byte of data in the MIDI event. */