2026-04-05 21:04:56 +09:00
|
|
|
#pragma once
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
#include <span>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include "tusb.h"
|
|
|
|
|
#include "ring_buffer.h"
|
|
|
|
|
|
|
|
|
|
struct usb_cdc {
|
2026-04-07 12:09:18 +09:00
|
|
|
ring_buffer<uint8_t, 8192> tx;
|
2026-04-05 21:04:56 +09:00
|
|
|
|
2026-04-11 09:48:25 +09:00
|
|
|
bool send(std::span<const uint8_t> data) {
|
|
|
|
|
if (!tx.push(data)) return false;
|
2026-04-05 21:04:56 +09:00
|
|
|
drain();
|
2026-04-11 09:48:25 +09:00
|
|
|
return true;
|
2026-04-05 21:04:56 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void send(const std::vector<uint8_t>& data) {
|
|
|
|
|
send(std::span<const uint8_t>{data});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drain() {
|
|
|
|
|
while (!tx.empty()) {
|
|
|
|
|
uint32_t avail = tud_cdc_write_available();
|
|
|
|
|
if (avail == 0) break;
|
|
|
|
|
auto chunk = tx.read_contiguous();
|
|
|
|
|
if (chunk.size() > avail) chunk = chunk.first(avail);
|
|
|
|
|
tud_cdc_write(chunk.data(), chunk.size());
|
|
|
|
|
tx.consume(chunk.size());
|
|
|
|
|
}
|
|
|
|
|
tud_cdc_write_flush();
|
|
|
|
|
}
|
|
|
|
|
};
|