Skip to content

Commit 9d872d5

Browse files
authored
Merge pull request #2593 from HiFiPhile/dcd_notif
cdc: add uart status notification support.
2 parents 963971c + 89da5a7 commit 9d872d5

File tree

13 files changed

+214
-104
lines changed

13 files changed

+214
-104
lines changed

examples/device/cdc_dual_ports/src/main.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,27 +98,33 @@ void tud_umount_cb(void) {
9898
blink_interval_ms = BLINK_NOT_MOUNTED;
9999
}
100100

101-
102101
//--------------------------------------------------------------------+
103102
// USB CDC
104103
//--------------------------------------------------------------------+
105104
static void cdc_task(void) {
106-
uint8_t itf;
107-
108-
for (itf = 0; itf < CFG_TUD_CDC; itf++) {
105+
for (uint8_t itf = 0; itf < CFG_TUD_CDC; itf++) {
109106
// connected() check for DTR bit
110107
// Most but not all terminal client set this when making connection
111108
// if ( tud_cdc_n_connected(itf) )
112109
{
113110
if (tud_cdc_n_available(itf)) {
114111
uint8_t buf[64];
115-
116112
uint32_t count = tud_cdc_n_read(itf, buf, sizeof(buf));
117113

118114
// echo back to both serial ports
119115
echo_serial_port(0, buf, count);
120116
echo_serial_port(1, buf, count);
121117
}
118+
119+
// Press on-board button to send Uart status notification
120+
static uint32_t btn_prev = 0;
121+
static cdc_notify_uart_state_t uart_state = { .value = 0 };
122+
const uint32_t btn = board_button_read();
123+
if (!btn_prev && btn) {
124+
uart_state.dsr ^= 1;
125+
tud_cdc_notify_uart_state(&uart_state);
126+
}
127+
btn_prev = btn;
122128
}
123129
}
124130
}

examples/device/cdc_dual_ports/src/tusb_config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
#define CFG_TUD_MIDI 0
9898
#define CFG_TUD_VENDOR 0
9999

100+
#define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint
101+
100102
// CDC FIFO size of TX and RX
101103
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
102104
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

examples/device/cdc_dual_ports/src/usb_descriptors.c

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@
4242
//--------------------------------------------------------------------+
4343
// Device Descriptors
4444
//--------------------------------------------------------------------+
45-
tusb_desc_device_t const desc_device =
46-
{
45+
tusb_desc_device_t const desc_device = {
4746
.bLength = sizeof(tusb_desc_device_t),
4847
.bDescriptorType = TUSB_DESC_DEVICE,
4948
.bcdUSB = USB_BCD,
@@ -68,16 +67,14 @@ tusb_desc_device_t const desc_device =
6867

6968
// Invoked when received GET DEVICE DESCRIPTOR
7069
// Application return pointer to descriptor
71-
uint8_t const * tud_descriptor_device_cb(void)
72-
{
70+
uint8_t const *tud_descriptor_device_cb(void) {
7371
return (uint8_t const *) &desc_device;
7472
}
7573

7674
//--------------------------------------------------------------------+
7775
// Configuration Descriptor
7876
//--------------------------------------------------------------------+
79-
enum
80-
{
77+
enum {
8178
ITF_NUM_CDC_0 = 0,
8279
ITF_NUM_CDC_0_DATA,
8380
ITF_NUM_CDC_1,
@@ -130,36 +127,32 @@ enum
130127
#define EPNUM_CDC_1_IN 0x84
131128
#endif
132129

133-
uint8_t const desc_fs_configuration[] =
134-
{
130+
uint8_t const desc_fs_configuration[] = {
135131
// Config number, interface count, string index, total length, attribute, power in mA
136132
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
137133

138134
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
139-
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
135+
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 16, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
140136

141137
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
142-
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
138+
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 16, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
143139
};
144140

145141
#if TUD_OPT_HIGH_SPEED
146142
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
147-
148-
uint8_t const desc_hs_configuration[] =
149-
{
143+
uint8_t const desc_hs_configuration[] = {
150144
// Config number, interface count, string index, total length, attribute, power in mA
151145
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
152146

153147
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
154-
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 512),
148+
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 16, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 512),
155149

156150
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
157-
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 512),
151+
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 16, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 512),
158152
};
159153

160154
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
161-
tusb_desc_device_qualifier_t const desc_device_qualifier =
162-
{
155+
tusb_desc_device_qualifier_t const desc_device_qualifier = {
163156
.bLength = sizeof(tusb_desc_device_t),
164157
.bDescriptorType = TUSB_DESC_DEVICE,
165158
.bcdUSB = USB_BCD,
@@ -177,34 +170,31 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
177170
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
178171
// device_qualifier descriptor describes information about a high-speed capable device that would
179172
// change if the device were operating at the other speed. If not highspeed capable stall this request.
180-
uint8_t const* tud_descriptor_device_qualifier_cb(void)
181-
{
182-
return (uint8_t const*) &desc_device_qualifier;
173+
uint8_t const *tud_descriptor_device_qualifier_cb(void) {
174+
return (uint8_t const *) &desc_device_qualifier;
183175
}
184176

185177
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
186178
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
187179
// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
188-
uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
189-
{
190-
(void) index; // for multiple configurations
180+
uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {
181+
(void) index;// for multiple configurations
191182

192183
// if link speed is high return fullspeed config, and vice versa
193-
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration;
184+
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration;
194185
}
195186

196-
#endif // highspeed
187+
#endif// highspeed
197188

198189
// Invoked when received GET CONFIGURATION DESCRIPTOR
199190
// Application return pointer to descriptor
200191
// Descriptor contents must exist long enough for transfer to complete
201-
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
202-
{
192+
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
203193
(void) index; // for multiple configurations
204194

205195
#if TUD_OPT_HIGH_SPEED
206196
// Although we are highspeed, host may be fullspeed.
207-
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
197+
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
208198
#else
209199
return desc_fs_configuration;
210200
#endif
@@ -223,8 +213,7 @@ enum {
223213
};
224214

225215
// array of pointer to string descriptors
226-
char const *string_desc_arr[] =
227-
{
216+
char const *string_desc_arr[] = {
228217
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
229218
"TinyUSB", // 1: Manufacturer
230219
"TinyUSB Device", // 2: Product
@@ -254,14 +243,14 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
254243
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
255244
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
256245

257-
if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
246+
if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; }
258247

259248
const char *str = string_desc_arr[index];
260249

261250
// Cap at max char
262251
chr_count = strlen(str);
263252
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
264-
if ( chr_count > max_count ) chr_count = max_count;
253+
if ( chr_count > max_count ) { chr_count = max_count; }
265254

266255
// Convert ASCII string into UTF-16
267256
for ( size_t i = 0; i < chr_count; i++ ) {
@@ -272,6 +261,5 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
272261

273262
// first byte is length (including header), second byte is string type
274263
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
275-
276264
return _desc_str;
277265
}

examples/device/cdc_msc/src/main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ void cdc_task(void) {
119119
tud_cdc_write(buf, count);
120120
tud_cdc_write_flush();
121121
}
122+
123+
// Press on-board button to send Uart status notification
124+
static uint32_t btn_prev = 0;
125+
static cdc_notify_uart_state_t uart_state = { .value = 0 };
126+
const uint32_t btn = board_button_read();
127+
if (!btn_prev && btn) {
128+
uart_state.dsr ^= 1;
129+
tud_cdc_notify_uart_state(&uart_state);
130+
}
131+
btn_prev = btn;
122132
}
123133
}
124134

examples/device/cdc_msc/src/tusb_config.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
//--------------------------------------------------------------------
8888

8989
#ifndef CFG_TUD_ENDPOINT0_SIZE
90-
#define CFG_TUD_ENDPOINT0_SIZE 64
90+
#define CFG_TUD_ENDPOINT0_SIZE 64
9191
#endif
9292

9393
//------------- CLASS -------------//
@@ -97,6 +97,8 @@
9797
#define CFG_TUD_MIDI 0
9898
#define CFG_TUD_VENDOR 0
9999

100+
#define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint
101+
100102
// CDC FIFO size of TX and RX
101103
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
102104
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

examples/device/cdc_msc/src/usb_descriptors.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ tusb_desc_device_t const desc_device = {
5252
.bDeviceClass = TUSB_CLASS_MISC,
5353
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
5454
.bDeviceProtocol = MISC_PROTOCOL_IAD,
55-
5655
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
5756

5857
.idVendor = USB_VID,
@@ -131,7 +130,7 @@ uint8_t const desc_fs_configuration[] = {
131130
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
132131

133132
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
134-
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
133+
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
135134

136135
// Interface number, string index, EP Out & EP In address, EP size
137136
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
@@ -146,7 +145,7 @@ uint8_t const desc_hs_configuration[] = {
146145
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
147146

148147
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
149-
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
148+
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
150149

151150
// Interface number, string index, EP Out & EP In address, EP size
152151
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
@@ -197,7 +196,6 @@ uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {
197196

198197
#endif // highspeed
199198

200-
201199
// Invoked when received GET CONFIGURATION DESCRIPTOR
202200
// Application return pointer to descriptor
203201
// Descriptor contents must exist long enough for transfer to complete
@@ -256,14 +254,14 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
256254
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
257255
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
258256

259-
if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
257+
if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; }
260258

261259
const char *str = string_desc_arr[index];
262260

263261
// Cap at max char
264262
chr_count = strlen(str);
265263
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
266-
if ( chr_count > max_count ) chr_count = max_count;
264+
if ( chr_count > max_count ) { chr_count = max_count; }
267265

268266
// Convert ASCII string into UTF-16
269267
for ( size_t i = 0; i < chr_count; i++ ) {
@@ -274,6 +272,5 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
274272

275273
// first byte is length (including header), second byte is string type
276274
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
277-
278275
return _desc_str;
279276
}

examples/device/cdc_msc_freertos/src/main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@ void cdc_task(void *params) {
189189
}
190190

191191
tud_cdc_write_flush();
192+
193+
// Press on-board button to send Uart status notification
194+
static uint32_t btn_prev = 0;
195+
static cdc_notify_uart_state_t uart_state = { .value = 0 };
196+
const uint32_t btn = board_button_read();
197+
if (!btn_prev && btn) {
198+
uart_state.dsr ^= 1;
199+
tud_cdc_notify_uart_state(&uart_state);
200+
}
201+
btn_prev = btn;
192202
}
193203

194204
// For ESP32-Sx this delay is essential to allow idle how to run and reset watchdog

examples/device/cdc_msc_freertos/src/tusb_config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@
104104
#define CFG_TUD_MIDI 0
105105
#define CFG_TUD_VENDOR 0
106106

107+
#define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint
108+
107109
// CDC FIFO size of TX and RX
108110
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
109111
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

0 commit comments

Comments
 (0)