LCOV - code coverage report
Current view: top level - src/MIDI_Interfaces/USBMIDI/LowLevel - BulkTX.hpp (source / functions) Hit Total Coverage
Test: 3aaab29ec58d6e71a20fde08a40531cf32318591 Lines: 3 3 100.0 %
Date: 2024-05-18 12:29:05 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstddef>
       4             : 
       5             : #include <MIDI_Interfaces/USBMIDI/util/Atomic.hpp>
       6             : #include <Settings/NamespaceSettings.hpp>
       7             : 
       8             : BEGIN_CS_NAMESPACE
       9             : 
      10             : /// Sends Bulk packets (IN for device mode, OUT for host mode)
      11             : template <class Derived, class MessageTypeT, uint16_t MaxPacketSizeV>
      12             : struct BulkTX {
      13             :   public:
      14             :     using MessageType = MessageTypeT;
      15             : 
      16             :     /// Send a MIDI USB message. May block.
      17             :     ///
      18             :     /// @param  msg
      19             :     ///         The 4-byte MIDI USB message to send.
      20             :     void write(MessageType msg);
      21             : 
      22             :     /// Send multiple MIDI USB messages. May block.
      23             :     ///
      24             :     /// @param  msgs
      25             :     ///         An array of 4-byte MIDI USB messages to send.
      26             :     /// @param  num_msgs
      27             :     ///         The number of messages in the array.
      28             :     void write(const MessageType *msgs, uint32_t num_msgs);
      29             : 
      30             :     /// Send multiple MIDI USB messages. May block.
      31             :     template <size_t N>
      32             :     void write(const MessageType (&msgs)[N]) {
      33             :         write(msgs, N);
      34             :     }
      35             : 
      36             :     /// Send multiple MIDI USB messages without blocking.
      37             :     ///
      38             :     /// @param  msgs
      39             :     ///         An array of 4-byte MIDI USB messages to send.
      40             :     /// @param  num_msgs
      41             :     ///         The number of messages in the array.
      42             :     /// @return The number of messages that were actually sent.
      43             :     uint32_t write_nonblock(const MessageType *msgs, uint32_t num_msgs);
      44             : 
      45             :     /// Try sending the buffered data now.
      46             :     /// Start transmitting the latest packet if possible, even if it isn't full
      47             :     /// yet. If the latest packet is empty, this function has no effect.
      48             :     void send_now();
      49             : 
      50             :     /// Check if all transfers have completed.
      51             :     bool is_done() const;
      52             : 
      53             :   protected:
      54             :     void reset(uint16_t packet_size = MaxPacketSize);
      55             : 
      56             :   private:
      57             :     static constexpr uint16_t MaxPacketSize = MaxPacketSizeV;
      58             :     static constexpr uint16_t SizeReserved = MaxPacketSize + 1;
      59             : 
      60             :   protected:
      61             :     // Derived should implement the following methods:
      62             : 
      63             :     /// Start a timeout (e.g. using a timer interrupt) that later calls
      64             :     /// @ref timeout_callback().
      65             :     void start_timeout() = delete;
      66             :     /// Cancel the timeout started by @ref timeout_callback().
      67             :     void cancel_timeout() = delete;
      68             :     /// Start a USB transfer (from the main program).
      69             :     void tx_start(const void *data, uint32_t size) = delete;
      70             :     /// Start a USB transfer (from the timeout callback).
      71             :     void tx_start_timeout(const void *data, uint32_t size) = delete;
      72             :     /// Start a USB transfer (from the USB interrupt handler).
      73             :     void tx_start_isr(const void *data, uint32_t size) = delete;
      74             : 
      75             :   private:
      76             :     constexpr static std::memory_order mo_seq = std::memory_order_seq_cst;
      77             :     constexpr static std::memory_order mo_rel = std::memory_order_release;
      78             :     constexpr static std::memory_order mo_acq = std::memory_order_acquire;
      79             :     constexpr static std::memory_order mo_rlx = std::memory_order_relaxed;
      80             :     constexpr static std::memory_order mo_acq_rel = std::memory_order_acq_rel;
      81             : 
      82             :     /// State for writing outgoing USB-MIDI data.
      83             :     struct Writing {
      84             :         struct Buffer {
      85             :             uint16_t size {0};
      86             :             alignas(MessageType) uint8_t buffer[MaxPacketSize];
      87             :         } buffers[2];
      88             :         interrupt_atomic<Buffer *> active_writebuffer {&buffers[0]};
      89             :         interrupt_atomic<Buffer *> sending {nullptr};
      90             :         interrupt_atomic<Buffer *> send_later {nullptr};
      91             :         interrupt_atomic<Buffer *> send_now {nullptr};
      92             :         uint16_t packet_size = MaxPacketSize;
      93             :     } writing;
      94             :     using wbuffer_t = typename Writing::Buffer;
      95             : 
      96       94936 :     uint32_t index_of(wbuffer_t *p) const { return p - writing.buffers; }
      97       94936 :     wbuffer_t *other_buf(wbuffer_t *p) {
      98       94936 :         return &writing.buffers[!index_of(p)];
      99             :     }
     100             :     uint32_t write_impl(const MessageType *msgs, uint32_t num_msgs);
     101             : 
     102             :   protected:
     103             :     void timeout_callback();
     104             :     void tx_callback();
     105             : };
     106             : 
     107             : END_CS_NAMESPACE
     108             : 
     109             : #include "BulkTX.ipp"

Generated by: LCOV version 1.15