void MIDI_OUT(void) { if (complete == 1) { complete = 0; LEDs_TurnOnLEDs(LEDMASK_TX); uint8_t Channel = 0; MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { .CableNumber = 0, .Command = MIDI_FROM_ARDUINO.Data1 >> 4, .Data1 = MIDI_FROM_ARDUINO.Data1 | Channel, .Data2 = MIDI_FROM_ARDUINO.Data2, .Data3 = MIDI_FROM_ARDUINO.Data3, }; MIDI_Device_SendEventPacket(&MIDI_Interface, &MIDIEvent); MIDI_Device_Flush(&MIDI_Interface); } else {
void sendMidiNote(int button, bool on) { int command = (on) ? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF; MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { .Event = MIDI_EVENT(0, command), .Data1 = command | MIDI_CHANNEL(1), .Data2 = 60 + button, .Data3 = MIDI_STANDARD_VELOCITY, }; MIDI_Device_SendEventPacket(&tbase8_MIDI_Interface, &MIDIEvent); MIDI_Device_Flush(&tbase8_MIDI_Interface); } /** Configures the board hardware and chip peripherals for the demo's functionality. */ void SetupHardware(void) { /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); /* Disable clock division */ clock_prescale_set(clock_div_1); /* Set the port directions for port b and d */ DDRD = 0xFF; DDRB = 0xFF; PORTD = 0b01010101; PORTB = 0b01010101; /* Hardware Initialization */ USB_Init(); }
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) { if (USB_DeviceState != DEVICE_STATE_Configured) return; #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) MIDI_Device_Flush(MIDIInterfaceInfo); #endif }
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) { if (USB_DeviceState != DEVICE_STATE_Configured) return; #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address); if (Endpoint_IsINReady()) MIDI_Device_Flush(MIDIInterfaceInfo); #endif }
void usb_send_func(MidiDevice * device, uint8_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { MIDI_EventPacket_t event; event.CableNumber = 0; event.Data1 = byte0; event.Data2 = byte1; event.Data3 = byte2; //if the length is undefined we assume it is a SYSEX message if (midi_packet_length(byte0) == UNDEFINED) { switch(cnt) { case 3: if (byte2 == SYSEX_END) event.Command = SYSEX_ENDS_IN_3; else event.Command = SYSEX_START_OR_CONT; break; case 2: if (byte1 == SYSEX_END) event.Command = SYSEX_ENDS_IN_2; else event.Command = SYSEX_START_OR_CONT; break; case 1: if (byte0 == SYSEX_END) event.Command = SYSEX_ENDS_IN_1; else event.Command = SYSEX_START_OR_CONT; break; default: return; //invalid cnt } } else { //deal with 'system common' messages //TODO are there any more? switch(byte0 & 0xF0){ case MIDI_SONGPOSITION: event.Command = SYS_COMMON_3; break; case MIDI_SONGSELECT: case MIDI_TC_QUATERFRAME: event.Command = SYS_COMMON_2; break; default: event.Command = byte0 >> 4; break; } } MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event); MIDI_Device_Flush(&USB_MIDI_Interface); MIDI_Device_USBTask(&USB_MIDI_Interface); USB_USBTask(); }
/** Checks for changes in the position of the board joystick, sending MIDI events to the host upon each change. */ void CheckJoystickMovement(void) { static uint8_t 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 second virtual cable, otherwise use the first */ uint8_t VirtualCable = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? 1 : 0; if (JoystickChanges & JOY_LEFT) { 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; } if (JoystickChanges & JOY_DOWN) { MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3F; } if (JoystickChanges & JOY_PRESS) { MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3B; } if (MIDICommand) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { .Event = MIDI_EVENT(VirtualCable, MIDICommand), .Data1 = MIDICommand | MIDI_CHANNEL(1), .Data2 = MIDIPitch, .Data3 = MIDI_STANDARD_VELOCITY, }; MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent); MIDI_Device_Flush(&Keyboard_MIDI_Interface); } PrevJoystickStatus = JoystickStatus; } /** Event handler for the library USB Connection event. */ void EVENT_USB_Device_Connect(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); }
void midi_flush(void) { MIDI_Device_Flush(g_midi_interface_info); }
/** 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) { MIDI_EventPacket_t midiEvent; struct { uint8_t command; uint8_t channel; uint8_t data2; uint8_t data3; } midiMsg; int ind; int led1_ticks = 0; int led2_ticks = 0; SetupHardware(); RingBuffer_InitBuffer(&USBtoUSART_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); /* See if we have a message yet */ if (BufferCount >= 4) { /* Read in the message from the serial buffer */ for (ind=0; ind<4; ind++) { ((uint8_t *)&midiMsg)[ind] = RingBuffer_Remove(&USARTtoUSB_Buffer); } /* Build a midi event to send via USB */ midiEvent.CableNumber = 0; midiEvent.Command = midiMsg.command >> 4; midiEvent.Data1 = (midiMsg.command & 0xF0) | ((midiMsg.channel-1) & 0x0F); midiEvent.Data2 = midiMsg.data2; midiEvent.Data3 = midiMsg.data3; MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &midiEvent); MIDI_Device_Flush(&Keyboard_MIDI_Interface); /* Turn on the TX led and starts its timer */ LEDs_TurnOnLEDs(LEDS_LED1); led1_ticks = LED_ON_TICKS; } /* Turn off the Tx LED when the tick count reaches zero */ if (led1_ticks) { led1_ticks--; if (led1_ticks == 0) { LEDs_TurnOffLEDs(LEDS_LED1); } } if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &midiEvent)) { RingBuff_Count_t count = RingBuffer_GetCount(&USBtoUSART_Buffer); /* Room to send a message? */ if ((BUFFER_SIZE - count) >= sizeof(midiMsg)) { midiMsg.command = midiEvent.Command << 4; midiMsg.channel = (midiEvent.Data1 & 0x0F) + 1; midiMsg.data2 = midiEvent.Data2; midiMsg.data3 = midiEvent.Data3; for (ind=0; ind<sizeof(midiMsg); ind++) { RingBuffer_Insert(&USBtoUSART_Buffer, ((uint8_t *)&midiMsg)[ind]); } /* Turn on the RX led and start its timer */ LEDs_TurnOnLEDs(LEDS_LED2); led2_ticks = LED_ON_TICKS; } else { /* Turn on the RX led and leave it on to indicate the * buffer is full and the sketch is not reading it * fast enough. */ LEDs_TurnOnLEDs(LEDS_LED2); } /* if there's no room in the serial buffer the message gets dropped */ } /* Turn off the RX LED when the tick count reaches zero */ if (led2_ticks) { led2_ticks--; if (led2_ticks == 0) { LEDs_TurnOffLEDs(LEDS_LED2); } } /* any data to send to main processor? */ if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) { Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer)); } MIDI_Device_USBTask(&Keyboard_MIDI_Interface); USB_USBTask(); } }