Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
PluggableUSBMIDI.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <cstdint>
6#include <utility>
7
8#include <USB/PluggableUSBDevice.h>
9#include <drivers/Timeout.h>
10#include <platform/Callback.h>
11
14#include <Settings/NamespaceSettings.hpp>
15
17
18class PluggableUSBMIDI : protected arduino::internal::PluggableUSBModule,
19 protected BulkRX<PluggableUSBMIDI, uint32_t, 64>,
20 protected BulkTX<PluggableUSBMIDI, uint32_t, 64> {
21 public:
24
25 public:
26 using setup_packet_t = USBDevice::setup_packet_t;
27 using DeviceState = USBDevice::DeviceState;
28 using microseconds = std::chrono::microseconds;
29
30 private:
31 // BulkTX/RX API
32 friend class BulkTX<PluggableUSBMIDI, uint32_t, 64>;
33 friend class BulkRX<PluggableUSBMIDI, uint32_t, 64>;
34 static constexpr uint32_t get_packet_size() { return 64; }
35
37 auto cb = mbed::callback(this, &PluggableUSBMIDI::timeout_callback);
38 timeout.attach(std::move(cb), timeout_duration);
39 }
40 void cancel_timeout() { timeout.detach(); }
41 void tx_start(const void *data, uint32_t size) {
42 auto data_u8 = reinterpret_cast<uint8_t *>(const_cast<void *>(data));
43 write_start(bulk_in_ep, data_u8, size);
44 }
45 void tx_start_timeout(const void *data, uint32_t size) {
46 tx_start(data, size);
47 }
48 void tx_start_isr(const void *data, uint32_t size) { tx_start(data, size); }
49 void rx_start(void *data, uint32_t size) {
50 read_start(bulk_out_ep, reinterpret_cast<uint8_t *>(data), size);
51 }
52 void rx_start_isr(void *data, uint32_t size) { rx_start(data, size); }
53
54 public:
56 bool connected() const;
57 bool connectedForWrite() const { return connected(); }
58
62 uint32_t read() {
63 uint32_t data = 0;
64 read(data);
65 return data;
66 }
67
68 using BulkRX<PluggableUSBMIDI, uint32_t, 64>::read;
69 using BulkTX<PluggableUSBMIDI, uint32_t, 64>::write;
70 using BulkTX<PluggableUSBMIDI, uint32_t, 64>::write_nonblock;
71 using BulkTX<PluggableUSBMIDI, uint32_t, 64>::send_now;
72 using BulkTX<PluggableUSBMIDI, uint32_t, 64>::getWriteError;
73 using BulkTX<PluggableUSBMIDI, uint32_t, 64>::clearWriteError;
74
83
84 protected:
85 void init(EndpointResolver &resolver) override;
86 void callback_state_change(DeviceState new_state) override;
87 uint32_t callback_request(const setup_packet_t *setup,
88 USBDevice::RequestResult *result,
89 uint8_t **data) override;
91 bool aborted) override;
92 bool callback_set_configuration(uint8_t configuration) override;
93 void callback_set_interface(uint16_t interface, uint8_t alternate) override;
94
95 const uint8_t *string_iinterface_desc() override;
96 const uint8_t *configuration_desc(uint8_t index) override;
97 uint8_t getProductVersion() override { return 16; }
98
99 protected:
103 mbed::Timeout timeout;
104
105 usb_ep_t bulk_in_ep;
106 usb_ep_t bulk_out_ep;
107 uint8_t config_descriptor[0x65];
108
109 // Interrupt handlers
113 void in_callback() {
114 assert_locked();
115 write_finish(bulk_in_ep);
117 }
119 assert_locked();
120 uint32_t num_bytes_read = read_finish(bulk_out_ep);
121 BulkRX::rx_callback(num_bytes_read);
122 }
123};
124
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
void setErrorTimeout(microseconds timeout)
USBDevice::setup_packet_t setup_packet_t
uint8_t getProductVersion() override
microseconds error_timeout_duration
void rx_start(void *data, uint32_t size)
void rx_start_isr(void *data, uint32_t size)
USBDevice::DeviceState DeviceState
uint32_t read()
Try reading a 4-byte MIDI USB message.
void callback_state_change(DeviceState new_state) override
const uint8_t * configuration_desc(uint8_t index) override
microseconds timeout_duration
void callback_set_interface(uint16_t interface, uint8_t alternate) override
interrupt_atomic< bool > usb_connected
void setTimeout(microseconds timeout)
Set the timeout, the number of microseconds to buffer the outgoing MIDI messages.
bool callback_set_configuration(uint8_t configuration) override
bool connected() const
Check if this class is connected and ready.
void init(EndpointResolver &resolver) override
bool connectedForWrite() const
uint32_t callback_request(const setup_packet_t *setup, USBDevice::RequestResult *result, uint8_t **data) override
void tx_start_isr(const void *data, uint32_t size)
bool callback_request_xfer_done(const setup_packet_t *setup, bool aborted) override
void tx_start_timeout(const void *data, uint32_t size)
uint8_t config_descriptor[0x65]
const uint8_t * string_iinterface_desc() override
std::chrono::microseconds microseconds
static constexpr uint32_t get_packet_size()
void tx_start(const void *data, uint32_t size)
Wrapper that provides atomic access to variables shared between the main program and interrupt handle...
Definition Atomic.hpp:81
Receives Bulk packets (OUT for device mode, IN for host mode)
Definition BulkRX.hpp:12
void rx_callback(uint32_t num_bytes_read)
Sends Bulk packets (IN for device mode, OUT for host mode)
Definition BulkTX.hpp:12
void tx_callback()
uint32_t write_nonblock(const MessageType *msgs, uint32_t num_msgs)
Send multiple MIDI USB messages without blocking.
void timeout_callback()
void send_now()
Try sending the buffered data now.
uint32_t getWriteError() const
Get the number messages that failed to send.
Definition BulkTX.hpp:54
void write(MessageType msg)
Send a MIDI USB message.
uint32_t clearWriteError()
Get and clear the number messages that failed to send.
Definition BulkTX.hpp:56