54 lines
1.2 KiB
C++
54 lines
1.2 KiB
C++
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
|
|
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<size_t Size>
|
|
struct RingBuffer {
|
|
size_t head = 0;
|
|
size_t tail = 0;
|
|
uint8_t data[Size];
|
|
};
|
|
|
|
static volatile RingBuffer<detail::VCP_RECEIVE_BUFFER_SIZE> 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
|
|
}
|
|
}
|
|
};
|