1#if 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)
21 PluggableUSBD().plug(
this);
43 std::memory_order_relaxed);
47 USBDevice::RequestResult *result,
50 *result = USBDevice::PassThrough;
64 PluggableUSBD().endpoint_add(
67 PluggableUSBD().endpoint_add(
101 const uint32_t *end = msgs + num_msgs;
108 uint32_t total_sent = 0, sent = 1;
109 while (total_sent < num_msgs && sent != 0) {
110 sent =
write_impl(msgs + total_sent, num_msgs - total_sent,
true);
118 uint32_t active_idx, size;
176std::tuple<uint32_t, PluggableUSBMIDI::wbuffer_t *, uint32_t>
178 this->assert_locked();
181 uint32_t size = writebuffer->
size;
183 return std::make_tuple(active_idx, writebuffer, size);
203 return this->unlock(), 0;
206 auto old_idx = active_idx;
223 size = (size / 4) * 4;
224 free_size = (free_size / 4) * 4;
225 memcpy(&writebuf->buffer[size], msgs, free_size);
226 uint32_t newsize = size + free_size;
227 writebuf->size = newsize;
236 else if (size == 0) {
241 std::atomic_signal_fence(std::memory_order_release);
248 return free_size / 4u;
263 bool old_ready = std::exchange(writebuffer->ready_to_send,
true);
266 return this->unlock(),
true;
275 return this->unlock(),
false;
288 uint32_t size = std::exchange(writebuffer->size,
SizeReserved);
297 if (old_timeout !=
nullptr)
308 uint32_t size = std::exchange(sendbuffer->size,
SizeReserved);
318 std::atomic_signal_fence(std::memory_order_acquire);
323 if (sendbuffer ==
nullptr)
324 return this->unlock();
327 bool old_ready = std::exchange(sendbuffer->ready_to_send,
true);
330 return this->unlock();
337 return this->unlock();
347 return this->unlock();
353 std::atomic_signal_fence(std::memory_order_release);
359 std::atomic_signal_fence(std::memory_order_acquire);
369 uint32_t next_idx = !sent_idx;
386 sent->ready_to_send =
false;
387 uint32_t oldsize = std::exchange(sent->size, 0);
398 sent->ready_to_send =
false;
399 uint32_t oldsize = std::exchange(sent->size, 0);
411 return this->unlock(), 0;
419 memcpy(&data, &readbuffer.buffer[readbuffer.index], 4);
421 readbuffer.index += 4;
423 if (readbuffer.index == readbuffer.size) {
437 return this->unlock(), data;
444 uint32_t num_bytes_read = read_finish(
bulk_out_ep);
449 if (num_bytes_read == 0) {
456 writebuffer.
index = 0;
457 writebuffer.size = num_bytes_read;
#define BEGIN_CS_NAMESPACE
#define CS_MIDI_USB_ASSERT(a)
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.