Add MIDI class driver, update MIDI device demo to use the new USB class driver. All device demos/projects have now been converted to the new library class drivers, although documentation is yet to be completed.
This commit is contained in:
		
							parent
							
								
									d1e5266036
								
							
						
					
					
						commit
						74b7c07e96
					
				
					 13 changed files with 622 additions and 794 deletions
				
			
		| 
						 | 
				
			
			@ -38,129 +38,21 @@
 | 
			
		|||
 | 
			
		||||
	/* Includes: */
 | 
			
		||||
		#include <LUFA/Drivers/USB/USB.h>
 | 
			
		||||
		#include <LUFA/Drivers/USB/Class/Device/MIDI.h>
 | 
			
		||||
 | 
			
		||||
		#include <avr/pgmspace.h>
 | 
			
		||||
 | 
			
		||||
	/* Macros: */
 | 
			
		||||
		/** Descriptor header constant to indicate a Audio class interface descriptor. */
 | 
			
		||||
		#define DTYPE_AudioInterface        0x24
 | 
			
		||||
 | 
			
		||||
		/** Descriptor header constant to indicate a Audio class endpoint descriptor. */
 | 
			
		||||
		#define DTYPE_AudioEndpoint         0x25
 | 
			
		||||
 | 
			
		||||
		/** Audio class descriptor subtype value for a Audio class specific header descriptor. */
 | 
			
		||||
		#define DSUBTYPE_Header             0x01
 | 
			
		||||
 | 
			
		||||
		/** Audio class descriptor subtype value for a Audio class specific MIDI input jack descriptor. */
 | 
			
		||||
		#define DSUBTYPE_InputJack          0x02
 | 
			
		||||
 | 
			
		||||
		/** Audio class descriptor subtype value for a Audio class specific MIDI output jack descriptor. */
 | 
			
		||||
		#define DSUBTYPE_OutputJack         0x03
 | 
			
		||||
 | 
			
		||||
		/** Audio class descriptor subtype value for a general Audio class specific descriptor. */
 | 
			
		||||
		#define DSUBTYPE_General            0x01
 | 
			
		||||
 | 
			
		||||
		/** Audio class descriptor jack type value for an embedded (logical) MIDI input or output jack. */
 | 
			
		||||
		#define JACKTYPE_EMBEDDED           0x01
 | 
			
		||||
 | 
			
		||||
		/** Audio class descriptor jack type value for an external (physical) MIDI input or output jack. */
 | 
			
		||||
		#define JACKTYPE_EXTERNAL           0x02
 | 
			
		||||
		
 | 
			
		||||
		/** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
 | 
			
		||||
		#define MIDI_STREAM_OUT_EPNUM       1
 | 
			
		||||
 | 
			
		||||
		/** Endpoint number of the MIDI streaming data IN endpoint, for device-to-host data transfers. */
 | 
			
		||||
		#define MIDI_STREAM_IN_EPNUM        2
 | 
			
		||||
 | 
			
		||||
		/** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
 | 
			
		||||
		#define MIDI_STREAM_OUT_EPNUM       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 an Audio class specific interface descriptor. This follows a regular interface descriptor to
 | 
			
		||||
		 *  supply extra information about the audio device's layout to the host. See the USB Audio specification for more
 | 
			
		||||
		 *  details.
 | 
			
		||||
		 */
 | 
			
		||||
		typedef struct
 | 
			
		||||
		{
 | 
			
		||||
			USB_Descriptor_Header_t   Header; /**< Regular descriptor header containing the descriptor's type and length */
 | 
			
		||||
			uint8_t                   Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
 | 
			
		||||
 | 
			
		||||
			uint16_t                  ACSpecification; /** Binary coded decimal value, indicating the supported Audio Class specification version */
 | 
			
		||||
			uint16_t                  TotalLength; /** Total length of the Audio class specific control descriptors, including this descriptor */
 | 
			
		||||
			
 | 
			
		||||
			uint8_t                   InCollection; /** Total number of audio class interfaces within this device */
 | 
			
		||||
			uint8_t                   InterfaceNumbers[1]; /** Interface numbers of each audio interface */
 | 
			
		||||
		} USB_AudioInterface_AC_t;
 | 
			
		||||
		
 | 
			
		||||
		/** Type define for an Audio class specific MIDI streaming interface descriptor. This indicates to the host
 | 
			
		||||
		 *  how MIDI the specification compliance of the device and the total length of the Audio class specific descriptors.
 | 
			
		||||
		 *  See the USB Audio specification for more details.
 | 
			
		||||
		 */
 | 
			
		||||
		typedef struct
 | 
			
		||||
		{
 | 
			
		||||
			USB_Descriptor_Header_t   Header; /**< Regular descriptor header containing the descriptor's type and length */
 | 
			
		||||
			uint8_t                   Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
 | 
			
		||||
			
 | 
			
		||||
			uint16_t                  AudioSpecification; /**< Binary coded decimal value, indicating the supported Audio Class specification version */
 | 
			
		||||
			uint16_t                  TotalLength; /**< Total length of the Audio class specific descriptors, including this descriptor */
 | 
			
		||||
		} USB_AudioInterface_MIDI_AS_t;
 | 
			
		||||
		
 | 
			
		||||
		/** Type define for an Audio class specific endpoint descriptor. This contains a regular endpoint 
 | 
			
		||||
		 *  descriptor with a few Audio-class specific extensions. See the USB Audio specification for more details.
 | 
			
		||||
		 */
 | 
			
		||||
		typedef struct
 | 
			
		||||
		{
 | 
			
		||||
			USB_Descriptor_Endpoint_t Endpoint; /**< Standard endpoint descriptor describing the audio endpoint */
 | 
			
		||||
 | 
			
		||||
			uint8_t                   Refresh; /**< Always set to zero */
 | 
			
		||||
			uint8_t                   SyncEndpointNumber; /**< Endpoint address to send synchronisation information to, if needed (zero otherwise) */
 | 
			
		||||
		} USB_AudioStreamEndpoint_Std_t;
 | 
			
		||||
 | 
			
		||||
		/** Type define for an Audio class specific MIDI IN jack. This gives information to the host on a MIDI input, either
 | 
			
		||||
		 *  a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint).
 | 
			
		||||
		 */
 | 
			
		||||
		typedef struct
 | 
			
		||||
		{
 | 
			
		||||
			USB_Descriptor_Header_t   Header; /**< Regular descriptor header containing the descriptor's type and length */
 | 
			
		||||
			uint8_t                   Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
 | 
			
		||||
 | 
			
		||||
			uint8_t                   JackType; /**< Type of jack, one of the JACKTYPE_* mask values */
 | 
			
		||||
			uint8_t                   JackID; /**< ID value of this jack - must be a unique value within the device */
 | 
			
		||||
			
 | 
			
		||||
			uint8_t                   JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
 | 
			
		||||
		} USB_MIDI_In_Jack_t;
 | 
			
		||||
 | 
			
		||||
		/** Type define for an Audio class specific MIDI OUT jack. This gives information to the host on a MIDI output, either
 | 
			
		||||
		 *  a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint).
 | 
			
		||||
		 */
 | 
			
		||||
		typedef struct
 | 
			
		||||
		{
 | 
			
		||||
			USB_Descriptor_Header_t   Header; /**< Regular descriptor header containing the descriptor's type and length */
 | 
			
		||||
			uint8_t                   Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
 | 
			
		||||
 | 
			
		||||
			uint8_t                   JackType; /**< Type of jack, one of the JACKTYPE_* mask values */
 | 
			
		||||
			uint8_t                   JackID; /**< ID value of this jack - must be a unique value within the device */
 | 
			
		||||
			
 | 
			
		||||
			uint8_t                   NumberOfPins; /**< Number of output channels within the jack, either physical or logical */
 | 
			
		||||
			uint8_t                   SourceJackID[1]; /**< ID of each output pin's source data jack */
 | 
			
		||||
			uint8_t                   SourcePinID[1]; /**< Pin number in the input jack of each output pin's source data */
 | 
			
		||||
			
 | 
			
		||||
			uint8_t                   JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device */
 | 
			
		||||
		} USB_MIDI_Out_Jack_t;
 | 
			
		||||
		
 | 
			
		||||
		/** Type define for an Audio class specific extended MIDI jack endpoint descriptor. This contains extra information
 | 
			
		||||
		 *  on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio
 | 
			
		||||
		 *  class specific extended MIDI endpoint descriptor. See the USB Audio specification for more details.
 | 
			
		||||
		 */
 | 
			
		||||
		typedef struct
 | 
			
		||||
		{
 | 
			
		||||
			USB_Descriptor_Header_t   Header; /**< Regular descriptor header containing the descriptor's type and length */
 | 
			
		||||
			uint8_t                   Subtype; /**< Sub type value used to distinguish between audio class specific descriptors */
 | 
			
		||||
 | 
			
		||||
			uint8_t                   TotalEmbeddedJacks; /**< Total number of jacks inside this endpoint */
 | 
			
		||||
			uint8_t                   AssociatedJackID[1]; /**< IDs of each jack inside the endpoint */
 | 
			
		||||
		} USB_MIDI_Jack_Endpoint_t;
 | 
			
		||||
 | 
			
		||||
		/** 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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,25 +28,34 @@
 | 
			
		|||
  this software.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/** \file
 | 
			
		||||
 *
 | 
			
		||||
 *  Main source file for the MIDI input demo. This file contains the main tasks of the demo and
 | 
			
		||||
 *  is responsible for the initial application hardware configuration.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "MIDI.h"
 | 
			
		||||
 | 
			
		||||
/* Scheduler Task List */
 | 
			
		||||
TASK_LIST
 | 
			
		||||
{
 | 
			
		||||
	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
 | 
			
		||||
	{ .Task = USB_MIDI_Task        , .TaskStatus = TASK_STOP },
 | 
			
		||||
};
 | 
			
		||||
USB_ClassInfo_MIDI_t Keyboard_MIDI_Interface =
 | 
			
		||||
	{
 | 
			
		||||
		.InterfaceNumber       = 0,
 | 
			
		||||
 | 
			
		||||
/** Main program entry point. This routine configures the hardware required by the application, then
 | 
			
		||||
 *  starts the scheduler to run the application tasks.
 | 
			
		||||
 */
 | 
			
		||||
		.DataINEndpointNumber  = MIDI_STREAM_IN_EPNUM,
 | 
			
		||||
		.DataINEndpointSize    = MIDI_STREAM_EPSIZE,
 | 
			
		||||
 | 
			
		||||
		.DataOUTEndpointNumber = MIDI_STREAM_OUT_EPNUM,
 | 
			
		||||
		.DataOUTEndpointSize   = MIDI_STREAM_EPSIZE,
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
	SetupHardware();
 | 
			
		||||
 | 
			
		||||
	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 | 
			
		||||
	
 | 
			
		||||
	for (;;)
 | 
			
		||||
	{
 | 
			
		||||
		CheckJoystickMovement();
 | 
			
		||||
	
 | 
			
		||||
		USB_USBTask();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetupHardware(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Disable watchdog if enabled by bootloader/fuses */
 | 
			
		||||
	MCUSR &= ~(1 << WDRF);
 | 
			
		||||
| 
						 | 
				
			
			@ -59,161 +68,85 @@ int main(void)
 | 
			
		|||
	Joystick_Init();
 | 
			
		||||
	LEDs_Init();
 | 
			
		||||
	Buttons_Init();
 | 
			
		||||
 | 
			
		||||
	/* Indicate USB not ready */
 | 
			
		||||
	UpdateStatus(Status_USBNotReady);
 | 
			
		||||
	
 | 
			
		||||
	/* Initialize Scheduler so that it can be used */
 | 
			
		||||
	Scheduler_Init();
 | 
			
		||||
 | 
			
		||||
	/* Initialize USB Subsystem */
 | 
			
		||||
	USB_Init();
 | 
			
		||||
 | 
			
		||||
	/* Scheduling - routine never returns, so put this last in the main function */
 | 
			
		||||
	Scheduler_Start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
 | 
			
		||||
void EVENT_USB_Connect(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Start USB management task */
 | 
			
		||||
	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
 | 
			
		||||
 | 
			
		||||
	/* Indicate USB enumerating */
 | 
			
		||||
	UpdateStatus(Status_USBEnumerating);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
 | 
			
		||||
 *  the status LEDs, disables the sample update and PWM output timers and stops the USB and MIDI management tasks.
 | 
			
		||||
 */
 | 
			
		||||
void EVENT_USB_Disconnect(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Stop running audio and USB management tasks */
 | 
			
		||||
	Scheduler_SetTaskMode(USB_MIDI_Task, TASK_STOP);
 | 
			
		||||
	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
 | 
			
		||||
 | 
			
		||||
	/* Indicate USB not ready */
 | 
			
		||||
	UpdateStatus(Status_USBNotReady);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
 | 
			
		||||
 *  of the USB device after enumeration - the device endpoints are configured and the MIDI management task started.
 | 
			
		||||
 */
 | 
			
		||||
void EVENT_USB_ConfigurationChanged(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Setup MIDI stream endpoints */
 | 
			
		||||
	Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPNUM, EP_TYPE_BULK,
 | 
			
		||||
		                       ENDPOINT_DIR_OUT, MIDI_STREAM_EPSIZE,
 | 
			
		||||
	                           ENDPOINT_BANK_SINGLE);
 | 
			
		||||
 | 
			
		||||
	Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPNUM, EP_TYPE_BULK,
 | 
			
		||||
		                       ENDPOINT_DIR_IN, MIDI_STREAM_EPSIZE,
 | 
			
		||||
	                           ENDPOINT_BANK_SINGLE);
 | 
			
		||||
 | 
			
		||||
	/* Indicate USB connected and ready */
 | 
			
		||||
	UpdateStatus(Status_USBReady);
 | 
			
		||||
 | 
			
		||||
	/* Start MIDI task */
 | 
			
		||||
	Scheduler_SetTaskMode(USB_MIDI_Task, TASK_RUN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Task to handle the generation of MIDI note change events in response to presses of the board joystick, and send them
 | 
			
		||||
 *  to the host.
 | 
			
		||||
 */
 | 
			
		||||
TASK(USB_MIDI_Task)
 | 
			
		||||
void CheckJoystickMovement(void)
 | 
			
		||||
{
 | 
			
		||||
	static uint8_t PrevJoystickStatus;
 | 
			
		||||
 | 
			
		||||
	/* Select the MIDI IN stream */
 | 
			
		||||
	Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
 | 
			
		||||
 | 
			
		||||
	/* Check if endpoint is ready to be written to */
 | 
			
		||||
	if (Endpoint_IsINReady())
 | 
			
		||||
	{
 | 
			
		||||
		/* Get current joystick mask, XOR with previous to detect joystick changes */
 | 
			
		||||
		uint8_t JoystickStatus  = Joystick_GetStatus();
 | 
			
		||||
		uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
 | 
			
		||||
	uint8_t MIDICommand = 0;
 | 
			
		||||
	uint8_t MIDIPitch;
 | 
			
		||||
	
 | 
			
		||||
	/* Get current joystick mask, XOR with previous to detect joystick changes */
 | 
			
		||||
	uint8_t JoystickStatus  = Joystick_GetStatus();
 | 
			
		||||
	uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
 | 
			
		||||
		
 | 
			
		||||
		/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
 | 
			
		||||
		uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
 | 
			
		||||
	/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
 | 
			
		||||
	uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
 | 
			
		||||
 | 
			
		||||
		if (JoystickChanges & JOY_LEFT)
 | 
			
		||||
		  SendMIDINoteChange(0x3C, (JoystickStatus & JOY_LEFT), 0, Channel);
 | 
			
		||||
 | 
			
		||||
		if (JoystickChanges & JOY_UP)
 | 
			
		||||
		  SendMIDINoteChange(0x3D, (JoystickStatus & JOY_UP), 0, Channel);
 | 
			
		||||
 | 
			
		||||
		if (JoystickChanges & JOY_RIGHT)
 | 
			
		||||
		  SendMIDINoteChange(0x3E, (JoystickStatus & JOY_RIGHT), 0, Channel);
 | 
			
		||||
 | 
			
		||||
		if (JoystickChanges & JOY_DOWN)
 | 
			
		||||
		  SendMIDINoteChange(0x3F, (JoystickStatus & JOY_DOWN), 0, Channel);
 | 
			
		||||
 | 
			
		||||
		if (JoystickChanges & JOY_PRESS)
 | 
			
		||||
		  SendMIDINoteChange(0x3B, (JoystickStatus & JOY_PRESS), 0, Channel);
 | 
			
		||||
 | 
			
		||||
		/* Save previous joystick value for next joystick change detection */
 | 
			
		||||
		PrevJoystickStatus = JoystickStatus;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Select the MIDI OUT stream */
 | 
			
		||||
	Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPNUM);
 | 
			
		||||
 | 
			
		||||
	/* Check if endpoint is ready to be read from, if so discard its (unused) data */
 | 
			
		||||
	if (Endpoint_IsOUTReceived())
 | 
			
		||||
	  Endpoint_ClearOUT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
 | 
			
		||||
 *  log to a serial port, or anything else that is suitable for status updates.
 | 
			
		||||
 *
 | 
			
		||||
 *  \param CurrentStatus  Current status of the system, from the MIDI_StatusCodes_t enum
 | 
			
		||||
 */
 | 
			
		||||
void UpdateStatus(uint8_t CurrentStatus)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t LEDMask = LEDS_NO_LEDS;
 | 
			
		||||
	
 | 
			
		||||
	/* Set the LED mask to the appropriate LED mask based on the given status code */
 | 
			
		||||
	switch (CurrentStatus)
 | 
			
		||||
	if (JoystickChanges & JOY_LEFT)
 | 
			
		||||
	{
 | 
			
		||||
		case Status_USBNotReady:
 | 
			
		||||
			LEDMask = (LEDS_LED1);
 | 
			
		||||
			break;
 | 
			
		||||
		case Status_USBEnumerating:
 | 
			
		||||
			LEDMask = (LEDS_LED1 | LEDS_LED2);
 | 
			
		||||
			break;
 | 
			
		||||
		case Status_USBReady:
 | 
			
		||||
			LEDMask = (LEDS_LED2 | LEDS_LED4);
 | 
			
		||||
			break;
 | 
			
		||||
		MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 | 
			
		||||
		MIDIPitch   = 0x3C;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (JoystickChanges & JOY_UP)
 | 
			
		||||
	{
 | 
			
		||||
		MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 | 
			
		||||
		MIDIPitch   = 0x3D;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (JoystickChanges & JOY_RIGHT)
 | 
			
		||||
	{
 | 
			
		||||
		MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 | 
			
		||||
		MIDIPitch   = 0x3E;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Set the board LEDs to the new LED mask */
 | 
			
		||||
	LEDs_SetAllLEDs(LEDMask);
 | 
			
		||||
}
 | 
			
		||||
	if (JoystickChanges & JOY_DOWN)
 | 
			
		||||
	{
 | 
			
		||||
		MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 | 
			
		||||
		MIDIPitch   = 0x3F;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/** Sends a MIDI note change event (note on or off) to the MIDI output jack, on the given virtual cable ID and channel.
 | 
			
		||||
 *
 | 
			
		||||
 *  \param Pitch    Pitch of the note to turn on or off
 | 
			
		||||
 *  \param OnOff    Set to true if the note is on (being held down), or false otherwise
 | 
			
		||||
 *  \param CableID  ID of the virtual cable to send the note change to
 | 
			
		||||
 *  \param Channel  MIDI channel number to send the note change event to
 | 
			
		||||
 */
 | 
			
		||||
void SendMIDINoteChange(const uint8_t Pitch, const bool OnOff, const uint8_t CableID, const uint8_t Channel)
 | 
			
		||||
{
 | 
			
		||||
	/* Wait until endpoint ready for more data */
 | 
			
		||||
	while (!(Endpoint_IsReadWriteAllowed()));
 | 
			
		||||
 | 
			
		||||
	/* Check if the message should be a Note On or Note Off command */
 | 
			
		||||
	uint8_t Command = ((OnOff)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 | 
			
		||||
 | 
			
		||||
	/* Write the Packet Header to the endpoint */
 | 
			
		||||
	Endpoint_Write_Byte((CableID << 4) | (Command >> 4));
 | 
			
		||||
 | 
			
		||||
	/* Write the Note On/Off command with the specified channel, pitch and velocity */
 | 
			
		||||
	Endpoint_Write_Byte(Command | Channel);
 | 
			
		||||
	Endpoint_Write_Byte(Pitch);
 | 
			
		||||
	Endpoint_Write_Byte(MIDI_STANDARD_VELOCITY);
 | 
			
		||||
	if (JoystickChanges & JOY_PRESS)
 | 
			
		||||
	{
 | 
			
		||||
		MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 | 
			
		||||
		MIDIPitch   = 0x3B;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Send the data in the endpoint to the host */
 | 
			
		||||
	Endpoint_ClearIN();
 | 
			
		||||
	if (MIDICommand)
 | 
			
		||||
	{
 | 
			
		||||
		USB_MIDI_EventPacket_t MIDIEvent = (USB_MIDI_EventPacket_t)
 | 
			
		||||
			{
 | 
			
		||||
				.CableNumber = 0,
 | 
			
		||||
				.Command     = MIDICommand,
 | 
			
		||||
				
 | 
			
		||||
				.Data1       = (MIDICommand << 4) | Channel,
 | 
			
		||||
				.Data2       = MIDIPitch,
 | 
			
		||||
				.Data3       = MIDI_STANDARD_VELOCITY,			
 | 
			
		||||
			};
 | 
			
		||||
			
 | 
			
		||||
		USB_MIDI_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	PrevJoystickStatus = JoystickStatus;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EVENT_USB_Connect(void)
 | 
			
		||||
{
 | 
			
		||||
	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EVENT_USB_Disconnect(void)
 | 
			
		||||
{
 | 
			
		||||
	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EVENT_USB_ConfigurationChanged(void)
 | 
			
		||||
{
 | 
			
		||||
	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 | 
			
		||||
	
 | 
			
		||||
	if (!(USB_MIDI_ConfigureEndpoints(&Keyboard_MIDI_Interface)))
 | 
			
		||||
	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,49 +44,27 @@
 | 
			
		|||
 | 
			
		||||
		#include "Descriptors.h"
 | 
			
		||||
				
 | 
			
		||||
		#include <LUFA/Version.h>                            // Library Version Information
 | 
			
		||||
		#include <LUFA/Drivers/USB/USB.h>                    // USB Functionality
 | 
			
		||||
		#include <LUFA/Drivers/Board/Joystick.h>             // Joystick driver
 | 
			
		||||
		#include <LUFA/Drivers/Board/LEDs.h>                 // LEDs driver
 | 
			
		||||
		#include <LUFA/Drivers/Board/Buttons.h>              // Board Buttons driver
 | 
			
		||||
		#include <LUFA/Scheduler/Scheduler.h>                // Simple scheduler for task management
 | 
			
		||||
		#include <LUFA/Version.h>
 | 
			
		||||
		#include <LUFA/Drivers/Board/LEDs.h>
 | 
			
		||||
		#include <LUFA/Drivers/Board/Joystick.h>
 | 
			
		||||
		#include <LUFA/Drivers/Board/Buttons.h>
 | 
			
		||||
		#include <LUFA/Drivers/Peripheral/ADC.h>
 | 
			
		||||
		#include <LUFA/Drivers/USB/USB.h>
 | 
			
		||||
		#include <LUFA/Drivers/USB/Class/Device/MIDI.h>
 | 
			
		||||
 | 
			
		||||
   /* Macros: */
 | 
			
		||||
		/** MIDI command for a note on (activation) event */
 | 
			
		||||
		#define MIDI_COMMAND_NOTE_ON         0x90
 | 
			
		||||
 | 
			
		||||
		/** MIDI command for a note off (deactivation) event */
 | 
			
		||||
		#define MIDI_COMMAND_NOTE_OFF        0x80
 | 
			
		||||
 | 
			
		||||
		/** Standard key press velocity value used for all note events, as no pressure sensor is mounted */
 | 
			
		||||
		#define MIDI_STANDARD_VELOCITY       64
 | 
			
		||||
	/* Macros: */
 | 
			
		||||
		#define LEDMASK_USB_NOTREADY      LEDS_LED1
 | 
			
		||||
		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
 | 
			
		||||
		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
 | 
			
		||||
		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 | 
			
		||||
		
 | 
			
		||||
	/* Function Prototypes: */
 | 
			
		||||
		void SetupHardware(void);
 | 
			
		||||
		void CheckJoystickMovement(void);
 | 
			
		||||
		
 | 
			
		||||
		/** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel
 | 
			
		||||
		 *  addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address.
 | 
			
		||||
		 *
 | 
			
		||||
		 *  \param channel  MIDI channel number to address
 | 
			
		||||
		 */
 | 
			
		||||
		#define MIDI_CHANNEL(channel)        (channel - 1)
 | 
			
		||||
 | 
			
		||||
	/* Enums: */
 | 
			
		||||
		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
 | 
			
		||||
		enum MIDI_StatusCodes_t
 | 
			
		||||
		{
 | 
			
		||||
			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
 | 
			
		||||
			Status_USBEnumerating = 1, /**< USB interface is enumerating */
 | 
			
		||||
			Status_USBReady       = 2, /**< USB interface is connected and ready */
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
	/* Task Definitions: */
 | 
			
		||||
		TASK(USB_MIDI_Task);
 | 
			
		||||
 | 
			
		||||
   /* Function Prototypes: */
 | 
			
		||||
		void EVENT_USB_Connect(void);
 | 
			
		||||
		void EVENT_USB_Disconnect(void);
 | 
			
		||||
		void EVENT_USB_ConfigurationChanged(void);
 | 
			
		||||
 | 
			
		||||
		void SendMIDINoteChange(const uint8_t Pitch, const bool OnOff,
 | 
			
		||||
		                        const uint8_t CableID, const uint8_t Channel);		
 | 
			
		||||
		void UpdateStatus(uint8_t CurrentStatus);
 | 
			
		||||
		void EVENT_USB_UnhandledControlPacket(void);
 | 
			
		||||
		
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 | 
			
		|||
# List C source files here. (C dependencies are automatically generated.)
 | 
			
		||||
SRC = $(TARGET).c                                                 \
 | 
			
		||||
	  Descriptors.c                                               \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 | 
			
		|||
	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
 | 
			
		||||
	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/MIDI.c           \
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# List C++ source files here. (C dependencies are automatically generated.)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue