1#if defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_MBED_RP2040)
3#include "PluggableUSBMIDI.hpp"
11#define CS_MIDI_USB_ASSERT(a) MBED_ASSERT((a))
13#define CS_MIDI_USB_ASSERT(a) (void)(a)
16constexpr static auto mo_rel = std::memory_order_release;
17constexpr static auto mo_acq = std::memory_order_acquire;
18constexpr static auto mo_rlx = std::memory_order_relaxed;
19constexpr static auto mo_acq_rel = std::memory_order_acq_rel;
26 PluggableUSBD().plug(
this);
49 USBDevice::RequestResult *result,
52 *result = USBDevice::PassThrough;
66 PluggableUSBD().endpoint_add(
69 PluggableUSBD().endpoint_add(
103 const uint32_t *end = msgs + num_msgs;
110 uint32_t total_sent = 0, sent = 1;
111 while (total_sent < num_msgs && sent != 0) {
112 sent =
write_impl(msgs + total_sent, num_msgs - total_sent,
true);
119 uint32_t active_idx, size;
177std::tuple<uint32_t, PluggableUSBMIDI::wbuffer_t *, uint32_t>
190 uint32_t old_idx = active_idx;
192 if (old_idx != active_idx) {
198 return std::make_tuple(active_idx, writebuffer, size);
218 auto old_idx = active_idx;
232 memcpy(&writebuf->buffer[size], msgs, free_size);
233 uint32_t newsize = size + free_size;
236 while (!writebuf->size.compare_exchange_weak(size, newsize,
mo_rel)) {
247 memcpy(&writebuf->buffer[size], msgs, free_size);
248 newsize = size + free_size;
257 else if (size == 0) {
260 std::atomic_signal_fence(
mo_rel);
267 return free_size / 4u;
273 if (old_timeout !=
nullptr)
323 std::atomic_signal_fence(
mo_acq);
357 std::atomic_signal_fence(
mo_rel);
363 std::atomic_signal_fence(
mo_acq);
373 uint32_t next_idx = !sent_idx;
390 sent->ready_to_send.store(
false,
mo_rlx);
391 uint32_t oldsize = sent->size.exchange(0,
mo_rel);
402 sent->ready_to_send.store(
false,
mo_rlx);
403 uint32_t oldsize = sent->size.exchange(0,
mo_rel);
422 memcpy(&data, &readbuffer.buffer[readbuffer.index], 4);
424 readbuffer.index += 4;
426 if (readbuffer.index == readbuffer.size) {
447 uint32_t num_bytes_read = read_finish(
bulk_out_ep);
452 if (num_bytes_read == 0) {
459 writebuffer.
index = 0;
460 writebuffer.size = num_bytes_read;
#define BEGIN_CS_NAMESPACE
static constexpr auto mo_rel
#define CS_MIDI_USB_ASSERT(a)
static constexpr auto mo_rlx
static constexpr auto mo_acq_rel
static constexpr auto mo_acq
static constexpr uint32_t NumRxPackets
static constexpr uint32_t PacketSize
USB packet size.
Reading::Buffer rbuffer_t
uint32_t active_writebuffer
The index of the buffer that is currently being written to.
bool ready_to_send
Indicates that this buffer can be sent as soon as the previous one has been sent.
void send_in_callback(uint32_t activebuf_idx)
static constexpr uint32_t SizeReserved
struct PluggableUSBMIDI::Reading reading
struct PluggableUSBMIDI::Writing writing
uint32_t write_nonblock(const uint32_t *msgs, uint32_t num_msgs)
Send multiple MIDI USB messages without blocking.
Writing::Buffer wbuffer_t
uint32_t read()
Try reading a 4-byte MIDI USB message.
void callback_state_change(DeviceState new_state) override
void send_now()
Try sending the buffered data now.
void write_start_sync(uint8_t *buffer, uint32_t size)
uint8_t buffer[PacketSize]
Buffer * send_timeout
Buffer to be sent in the timeout callback.
microseconds timeout_duration
void callback_set_interface(uint16_t interface, uint8_t alternate) override
uint32_t write_impl(const uint32_t *msgs, uint32_t num_msgs, bool nonblocking)
Buffer * sending
Buffer that is being sent.
bool callback_set_configuration(uint8_t configuration) override
bool connected() const
Check if this class is connected and ready.
void init(EndpointResolver &resolver) override
struct PluggableUSBMIDI::Reading::Buffer buffers[NumRxPackets]
std::tuple< uint32_t, wbuffer_t *, uint32_t > read_writebuf_size()
std::atomic< bool > usb_connected
uint32_t size
How many bytes are in the buffer.
bool send_now_impl_nonblock(uint32_t activebuf_idx)
uint32_t callback_request(const setup_packet_t *setup, USBDevice::RequestResult *result, uint8_t **data) override
bool callback_request_xfer_done(const setup_packet_t *setup, bool aborted) override
struct PluggableUSBMIDI::Writing::Buffer buffers[2]
void write(uint32_t msg)
Send a MIDI USB message.
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Return the smaller of two numbers/objects.