#pragma once #include #include #include extern "C" void vcpReceiveCallback(uint8_t*, uint32_t); namespace detail { constexpr auto VCP_RECEIVE_BUFFER_SIZE = 64; } // namespace detail class VcpReceiver { public: static inline bool rxByte(uint8_t& data) { if(m_receiveBuffer.head == m_receiveBuffer.tail) return false; const uint8_t newTail = (m_receiveBuffer.tail + 1) % detail::VCP_RECEIVE_BUFFER_SIZE; data = m_receiveBuffer.data[newTail]; m_receiveBuffer.tail = newTail; return true; } private: friend void vcpReceiveCallback(uint8_t*, uint32_t); template struct RingBuffer { size_t head = 0; size_t tail = 0; uint8_t data[Size]; }; static volatile RingBuffer m_receiveBuffer; static inline void rxHandler(const uint8_t& data) { const uint8_t newHead = (m_receiveBuffer.head + 1) % detail::VCP_RECEIVE_BUFFER_SIZE; if(newHead != m_receiveBuffer.tail) { m_receiveBuffer.head = newHead; m_receiveBuffer.data[newHead] = data; } else { // TODO: Handle overflow } } };