Sound Byte Libs 29c5ff3
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
cdc.cpp
Go to the documentation of this file.
1/*
2 * cdc.cpp - USB CDC Serial implementation
3 *
4 * Wraps TinyUSB CDC functions with SBL API.
5 */
6
7#include "cdc.hpp"
8#include "tusb.h"
9#include <cstring>
10
11// Connection tracking for just_connected()
12// Fires on: (1) first USB enumeration (boot), (2) DTR rising edge (terminal open)
13static bool s_last_ready = false;
14static volatile bool s_dtr_rose = false;
15
16extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
17 (void)itf;
18 (void)rts;
19 if (dtr) {
20 s_dtr_rose = true;
21 }
22}
23
24namespace sbl::usb {
25
26size_t CdcSerial::write(const uint8_t* data, size_t len) {
27 if (!tud_ready()) {
28 return 0;
29 }
30
31 size_t written = 0;
32 while (written < len) {
33 size_t avail = tud_cdc_write_available();
34 if (avail == 0) {
35 // Buffer full, flush and retry
36 tud_cdc_write_flush();
37 tud_task(); // Process USB to make room
38 avail = tud_cdc_write_available();
39 if (avail == 0) {
40 break; // Still full, return what we wrote
41 }
42 }
43
44 size_t to_write = (len - written) < avail ? (len - written) : avail;
45 size_t n = tud_cdc_write(data + written, to_write);
46 written += n;
47
48 if (n == 0) {
49 break; // Write failed
50 }
51 }
52
53 tud_cdc_write_flush();
54 return written;
55}
56
57size_t CdcSerial::puts(const char* str) {
58 if (!str) return 0;
59 return write(reinterpret_cast<const uint8_t*>(str), strlen(str));
60}
61
62bool CdcSerial::write_byte(uint8_t byte) {
63 if (!tud_ready()) {
64 return false;
65 }
66
67 if (tud_cdc_write_available() == 0) {
68 tud_cdc_write_flush();
69 tud_task();
70 if (tud_cdc_write_available() == 0) {
71 return false;
72 }
73 }
74
75 return tud_cdc_write_char(byte) == 1;
76}
77
78size_t CdcSerial::read(uint8_t* data, size_t max_len) {
79 if (!tud_cdc_available()) {
80 return 0;
81 }
82 return tud_cdc_read(data, max_len);
83}
84
86 if (!tud_cdc_available()) {
87 return -1;
88 }
89 return tud_cdc_read_char();
90}
91
93 return tud_cdc_available();
94}
95
97 return tud_cdc_connected();
98}
99
101 bool ready = tud_ready();
102
103 // Boot: detect first USB enumeration
104 if (ready && !s_last_ready) {
105 s_last_ready = true;
106 return true;
107 }
109
110 // Reconnect: detect DTR rising edge (terminal open)
111 if (s_dtr_rose) {
112 s_dtr_rose = false;
113 return true;
114 }
115
116 return false;
117}
118
120 tud_cdc_write_flush();
121
122 // Wait for TX complete with timeout
123 for (int i = 0; i < 1000; i++) {
124 tud_task();
125 if (tud_cdc_write_available() == CFG_TUD_CDC_TX_BUFSIZE) {
126 break; // Buffer empty, all sent
127 }
128 // Small delay - could use Timer::delay_us() but keep it simple
129 for (volatile int j = 0; j < 1000; j++) {}
130 }
131}
132
133} // namespace sbl::usb
static bool s_last_ready
Definition cdc.cpp:13
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
Definition cdc.cpp:16
static volatile bool s_dtr_rose
Definition cdc.cpp:14
USB CDC (Virtual COM Port) interface.
static size_t write(const uint8_t *data, size_t len)
Write data to USB serial (non-blocking)
Definition cdc.cpp:26
static size_t puts(const char *str)
Write null-terminated string.
Definition cdc.cpp:57
static void flush()
Flush TX buffer.
Definition cdc.cpp:119
static size_t available()
Get number of bytes available to read.
Definition cdc.cpp:92
static size_t read(uint8_t *data, size_t max_len)
Read data from USB serial (non-blocking)
Definition cdc.cpp:78
static bool write_byte(uint8_t byte)
Write single byte.
Definition cdc.cpp:62
static bool connected()
Check if host has terminal connected (DTR set)
Definition cdc.cpp:96
static bool just_connected()
Check if a terminal just connected (DTR rising edge)
Definition cdc.cpp:100
static int read_byte()
Read single byte.
Definition cdc.cpp:85
USB device support.
Definition cdc.cpp:24
bool ready()
Check if USB is enumerated and ready.