#ifndef MIDIUSB_h | |||||
#define MIDIUSB_h | |||||
// For compatibility with Arduino's MIDIUSB library | |||||
#ifdef __cplusplus | |||||
#if !defined(USB_MIDI) | |||||
#error "Please select MIDI in Tools > USB Type to use MIDIUSB.h" | |||||
#endif | |||||
#include "usb_api.h" | |||||
typedef struct { | |||||
struct { | |||||
uint8_t header; | |||||
uint8_t byte1; | |||||
uint8_t byte2; | |||||
uint8_t byte3; | |||||
}; | |||||
} midiEventPacket_t; | |||||
class MIDI_ | |||||
{ | |||||
public: | |||||
constexpr MIDI_(void) { } | |||||
uint32_t available(void) { | |||||
return usbMIDI.midiusb_available(); | |||||
} | |||||
midiEventPacket_t read(void) { | |||||
midiEventPacket_t event; | |||||
usbMIDI.midiusb_read((uint8_t *)&event); | |||||
return event; | |||||
} | |||||
void flush(void) { | |||||
usbMIDI.send_now(); | |||||
} | |||||
void sendMIDI(midiEventPacket_t event) { | |||||
usbMIDI.send_raw(event.header, event.byte1, event.byte2, event.byte3); | |||||
} | |||||
size_t write(const uint8_t *buffer, size_t size) { | |||||
// TODO - is this really needed? | |||||
return 0; | |||||
} | |||||
operator bool() { | |||||
// TODO - is this really needed? | |||||
return true; | |||||
} | |||||
}; | |||||
extern MIDI_ MidiUSB; | |||||
#endif // __cplusplus | |||||
#endif // MIDIUSB_h |
uint32_t usb_midi_class::midiusb_available() | |||||
{ | |||||
uint8_t c, intr_state; | |||||
intr_state = SREG; | |||||
cli(); | |||||
if (!usb_configuration) { | |||||
SREG = intr_state; | |||||
return 0; | |||||
} | |||||
UENUM = MIDI_RX_ENDPOINT; | |||||
retry: | |||||
c = UEINTX; | |||||
if (!(c & (1<<RWAL))) { | |||||
if (c & (1<<RXOUTI)) { | |||||
UEINTX = 0x6B; | |||||
goto retry; | |||||
} | |||||
SREG = intr_state; | |||||
return 0; | |||||
} | |||||
SREG = intr_state; | |||||
return 4; | |||||
} | |||||
void usb_midi_class::midiusb_read(uint8_t *buf) | |||||
{ | |||||
uint8_t c, intr_state; | |||||
intr_state = SREG; | |||||
cli(); | |||||
if (!usb_configuration) { | |||||
SREG = intr_state; | |||||
buf[0] = 0; | |||||
buf[1] = 0; | |||||
buf[2] = 0; | |||||
buf[3] = 0; | |||||
return; | |||||
} | |||||
UENUM = MIDI_RX_ENDPOINT; | |||||
retry: | |||||
c = UEINTX; | |||||
if (!(c & (1<<RWAL))) { | |||||
if (c & (1<<RXOUTI)) { | |||||
UEINTX = 0x6B; | |||||
goto retry; | |||||
} | |||||
SREG = intr_state; | |||||
buf[0] = 0; | |||||
buf[1] = 0; | |||||
buf[2] = 0; | |||||
buf[3] = 0; | |||||
return; | |||||
} | |||||
buf[0] = UEDATX; | |||||
buf[1] = UEDATX; | |||||
buf[2] = UEDATX; | |||||
buf[3] = UEDATX; | |||||
if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B; | |||||
SREG = intr_state; | |||||
} | |||||
bool usb_midi_class::read(uint8_t channel) | bool usb_midi_class::read(uint8_t channel) |
} | } | ||||
private: | private: | ||||
void send_raw(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3); | void send_raw(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3); | ||||
uint32_t midiusb_available(); | |||||
void midiusb_read(uint8_t *buf); | |||||
void sendSysEx_BufferHasTerm(uint16_t length, const uint8_t *data); | void sendSysEx_BufferHasTerm(uint16_t length, const uint8_t *data); | ||||
void sendSysEx_AddTermBytes(uint16_t length, const uint8_t *data); | void sendSysEx_AddTermBytes(uint16_t length, const uint8_t *data); | ||||
void read_sysex_byte(uint8_t b); | void read_sysex_byte(uint8_t b); | ||||
void (*handleActiveSensing)(void); | void (*handleActiveSensing)(void); | ||||
void (*handleSystemReset)(void); | void (*handleSystemReset)(void); | ||||
void (*handleRealTimeSystem)(uint8_t rtb); | void (*handleRealTimeSystem)(uint8_t rtb); | ||||
friend class MIDI_; | |||||
}; | }; | ||||
extern usb_midi_class usbMIDI; | extern usb_midi_class usbMIDI; |