forked from ARMmbed/mbed-os
-
Notifications
You must be signed in to change notification settings - Fork 0
/
USBMIDI.h
226 lines (188 loc) · 5.96 KB
/
USBMIDI.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*
* Copyright (c) 2018-2019, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBMIDI_H
#define USBMIDI_H
/* These headers are included for child class. */
#include "USBDescriptor.h"
#include "USBDevice_Types.h"
#include "USBDevice.h"
#include "MIDIMessage.h"
#include "EventFlags.h"
#include "Mutex.h"
#include "Callback.h"
#define DEFAULT_CONFIGURATION (1)
/**
* \defgroup drivers_USBMIDI USBMIDI class
* \ingroup drivers-public-api-usb
* @{
*/
/**
* USBMIDI example
*
* @code
* #include "mbed.h"
* #include "USBMIDI.h"
*
* USBMIDI midi;
*
* int main() {
* while (1) {
* for(int i=48; i<83; i++) { // send some messages!
* midi.write(MIDIMessage::NoteOn(i));
* ThisThread::sleep_for(250);
* midi.write(MIDIMessage::NoteOff(i));
* ThisThread::sleep_for(500);
* }
* }
* }
* @endcode
*/
class USBMIDI: public USBDevice {
public:
/**
* Basic constructor
*
* Construct this object optionally connecting and blocking until it is ready.
*
* @note Do not use this constructor in derived classes.
*
* @param connect_blocking true to perform a blocking connect, false to start in a disconnected state
* @param vendor_id Your vendor_id
* @param product_id Your product_id
* @param product_release Your product_release
*/
USBMIDI(bool connect_blocking = true, uint16_t vendor_id = 0x0700, uint16_t product_id = 0x0101, uint16_t product_release = 0x0001);
/**
* Fully featured constructor
*
* Construct this object with the supplied USBPhy and parameters. The user
* this object is responsible for calling connect() or init().
*
* @note Derived classes must use this constructor and call init() or
* connect() themselves. Derived classes should also call deinit() in
* their destructor. This ensures that no interrupts can occur when the
* object is partially constructed or destroyed.
*
* @param phy USB phy to use
* @param vendor_id Your vendor_id
* @param product_id Your product_id
* @param product_release Your product_release
*/
USBMIDI(USBPhy *phy, uint16_t vendor_id, uint16_t product_id, uint16_t product_release);
/**
* Destroy this object
*
* Any classes which inherit from this class must call deinit
* before this destructor runs.
*/
virtual ~USBMIDI();
/**
* Check if this class is ready
*
* @return true if configured, false otherwise
*/
bool ready();
/**
* Block until this device is configured
*/
void wait_ready();
/**
* Send a MIDIMessage
*
* Comfort write for write(MIDIMessage::NoteOn(4)) type messages (ONLY)
*
* @param m The MIDIMessage to send
* @return true if the message was sent, false otherwise
*/
bool write(MIDIMessage m);
/**
* Send a MIDIMessage
*
* @param m The MIDIMessage to send
* @return true if the message was sent, false otherwise
*/
bool write(MIDIMessage * m);
/**
* Send a MIDIMessage
*
* (Actual implementation)
*
* @param data MIDI data to send
* @param length Length of MIDI data
* @param cable_num Legacy cable number
* @return true if the message was sent, false otherwise
*/
bool write(uint8_t * &data, uint16_t length, uint8_t cable_num = CABLE_NUM);
/**
* Check if a message can be read
*
* @return true if a packet can be read false otherwise
* @note USBMIDI::attach must be called to enable the receiver
*/
bool readable();
/**
* Read a message
*
* @param m The MIDIMessage to fill
* @return true if a message was read, false otherwise
*/
bool read(MIDIMessage &m);
/**
* Read a message (into buffer)
*
* @param data Buffer to write MIDI data into
* @param length Length of read MIDI data
* @param maxlength Maximal length of MIDI data that can be read into buffer (buffered surplus data will be discarded)
* @return true if a message was read, false otherwise
*/
bool read(uint8_t * &data, uint16_t &length, uint16_t maxlength = MAX_MIDI_MESSAGE_SIZE);
/**
* Attach a callback for when a MIDIEvent is received
*
* @param callback code to call when a packet is received
*/
void attach(mbed::Callback<void()> callback);
protected:
virtual void callback_state_change(DeviceState new_state);
virtual void callback_request(const setup_packet_t *setup);
virtual void callback_request_xfer_done(const setup_packet_t *setup, bool aborted);
virtual void callback_set_configuration(uint8_t configuration);
virtual void callback_set_interface(uint16_t interface, uint8_t alternate);
virtual const uint8_t *string_iproduct_desc();
virtual const uint8_t *string_iinterface_desc();
virtual const uint8_t *configuration_desc(uint8_t index);
private:
static const uint32_t MaxSize = 64;
uint8_t _bulk_buf[MaxSize];
uint32_t _bulk_buf_pos;
uint32_t _bulk_buf_size;
bool _data_ready;
uint8_t _data[MAX_MIDI_MESSAGE_SIZE + 1];
uint32_t _cur_data;
rtos::EventFlags _flags;
rtos::Mutex _write_mutex;
usb_ep_t _bulk_in;
usb_ep_t _bulk_out;
uint8_t _config_descriptor[0x65];
mbed::Callback<void()> _callback;
void _init();
void _in_callback();
void _out_callback();
bool _next_message();
};
/** @}*/
#endif