Skip to content

Commit 8f2d3ed

Browse files
committed
1 parent c92b7fd commit 8f2d3ed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+4156
-3811
lines changed

src/class/audio/audio_device.c

Lines changed: 767 additions & 944 deletions
Large diffs are not rendered by default.

src/class/audio/audio_device.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@
203203
#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1
204204
#endif
205205

206+
// Audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74)
207+
#define CFG_TUD_AUDIO_INTERRUPT_EP_SZ 6
208+
206209
// Use software encoding/decoding
207210

208211
// The software coding feature of the driver is not mandatory. It is useful if, for instance, you have two I2S streams which need to be interleaved

src/class/bth/bth_device.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@
4343
//--------------------------------------------------------------------+
4444
// MACRO CONSTANT TYPEDEF
4545
//--------------------------------------------------------------------+
46-
typedef struct
47-
{
46+
typedef struct {
4847
uint8_t itf_num;
4948
uint8_t ep_ev;
5049
uint8_t ep_acl_in;
@@ -55,17 +54,18 @@ typedef struct
5554

5655
// Previous amount of bytes sent when issuing ZLP
5756
uint32_t prev_xferred_bytes;
58-
59-
// Endpoint Transfer buffer
60-
CFG_TUSB_MEM_ALIGN bt_hci_cmd_t hci_cmd;
61-
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_BTH_DATA_EPSIZE];
62-
6357
} btd_interface_t;
6458

59+
typedef struct {
60+
TUD_EPBUF_DEF(epout_buf, CFG_TUD_BTH_DATA_EPSIZE);
61+
TUD_EPBUF_TYPE_DEF(bt_hci_cmd_t, hci_cmd);
62+
} btd_epbuf_t;
63+
6564
//--------------------------------------------------------------------+
6665
// INTERNAL OBJECT & FUNCTION DECLARATION
6766
//--------------------------------------------------------------------+
68-
CFG_TUD_MEM_SECTION btd_interface_t _btd_itf;
67+
static btd_interface_t _btd_itf;
68+
CFG_TUD_MEM_SECTION static btd_epbuf_t _btd_epbuf;
6969

7070
static bool bt_tx_data(uint8_t ep, void *data, uint16_t len)
7171
{
@@ -158,7 +158,7 @@ uint16_t btd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_
158158
itf_desc = (tusb_desc_interface_t const *)tu_desc_next(tu_desc_next(desc_ep));
159159

160160
// Prepare for incoming data from host
161-
TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_itf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE), 0);
161+
TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE), 0);
162162

163163
drv_len = hci_itf_size;
164164

@@ -249,14 +249,16 @@ bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c
249249
}
250250
else return false;
251251

252-
return tud_control_xfer(rhport, request, &_btd_itf.hci_cmd, sizeof(_btd_itf.hci_cmd));
252+
return tud_control_xfer(rhport, request, &_btd_epbuf.hci_cmd, sizeof(bt_hci_cmd_t));
253253
}
254254
else if ( stage == CONTROL_STAGE_DATA )
255255
{
256256
// Handle class request only
257257
TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
258258

259-
if (tud_bt_hci_cmd_cb) tud_bt_hci_cmd_cb(&_btd_itf.hci_cmd, tu_min16(request->wLength, sizeof(_btd_itf.hci_cmd)));
259+
if (tud_bt_hci_cmd_cb) {
260+
tud_bt_hci_cmd_cb(&_btd_epbuf.hci_cmd, tu_min16(request->wLength, sizeof(bt_hci_cmd_t)));
261+
}
260262
}
261263

262264
return true;
@@ -267,10 +269,10 @@ bool btd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
267269
// received new data from host
268270
if (ep_addr == _btd_itf.ep_acl_out)
269271
{
270-
if (tud_bt_acl_data_received_cb) tud_bt_acl_data_received_cb(_btd_itf.epout_buf, xferred_bytes);
272+
if (tud_bt_acl_data_received_cb) tud_bt_acl_data_received_cb(_btd_epbuf.epout_buf, xferred_bytes);
271273

272274
// prepare for next data
273-
TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_itf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE));
275+
TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE));
274276
}
275277
else if (ep_addr == _btd_itf.ep_ev)
276278
{

src/class/cdc/cdc_device.c

Lines changed: 75 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,27 @@ typedef struct {
7272

7373
OSAL_MUTEX_DEF(rx_ff_mutex);
7474
OSAL_MUTEX_DEF(tx_ff_mutex);
75-
76-
// Endpoint Transfer buffer
77-
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
78-
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE];
7975
} cdcd_interface_t;
8076

8177
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)
8278

79+
typedef struct {
80+
TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE);
81+
TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE);
82+
} cdcd_epbuf_t;
83+
8384
//--------------------------------------------------------------------+
8485
// INTERNAL OBJECT & FUNCTION DECLARATION
8586
//--------------------------------------------------------------------+
86-
CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
87+
static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
88+
CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC];
89+
8790
static tud_cdc_configure_fifo_t _cdcd_fifo_cfg;
8891

89-
static bool _prep_out_transaction (cdcd_interface_t* p_cdc) {
90-
uint8_t const rhport = 0;
92+
static bool _prep_out_transaction(uint8_t itf) {
93+
const uint8_t rhport = 0;
94+
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
95+
cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf];
9196

9297
// Skip if usb is not ready yet
9398
TU_VERIFY(tud_ready() && p_cdc->ep_out);
@@ -98,17 +103,17 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) {
98103
// TODO Actually we can still carry out the transfer, keeping count of received bytes
99104
// and slowly move it to the FIFO when read().
100105
// This pre-check reduces endpoint claiming
101-
TU_VERIFY(available >= sizeof(p_cdc->epout_buf));
106+
TU_VERIFY(available >= CFG_TUD_CDC_EP_BUFSIZE);
102107

103108
// claim endpoint
104109
TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_out));
105110

106111
// fifo can be changed before endpoint is claimed
107112
available = tu_fifo_remaining(&p_cdc->rx_ff);
108113

109-
if ( available >= sizeof(p_cdc->epout_buf) ) {
110-
return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf));
111-
}else {
114+
if (available >= CFG_TUD_CDC_EP_BUFSIZE) {
115+
return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE);
116+
} else {
112117
// Release endpoint since we don't make any transfer
113118
usbd_edpt_release(rhport, p_cdc->ep_out);
114119
return false;
@@ -119,7 +124,7 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) {
119124
// APPLICATION API
120125
//--------------------------------------------------------------------+
121126

122-
bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) {
127+
bool tud_cdc_configure_fifo(const tud_cdc_configure_fifo_t* cfg) {
123128
TU_VERIFY(cfg);
124129
_cdcd_fifo_cfg = (*cfg);
125130
return true;
@@ -156,7 +161,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) {
156161
uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) {
157162
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
158163
uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX));
159-
_prep_out_transaction(p_cdc);
164+
_prep_out_transaction(itf);
160165
return num_read;
161166
}
162167

@@ -167,13 +172,13 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) {
167172
void tud_cdc_n_read_flush(uint8_t itf) {
168173
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
169174
tu_fifo_clear(&p_cdc->rx_ff);
170-
_prep_out_transaction(p_cdc);
175+
_prep_out_transaction(itf);
171176
}
172177

173178
//--------------------------------------------------------------------+
174179
// WRITE API
175180
//--------------------------------------------------------------------+
176-
uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) {
181+
uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) {
177182
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
178183
uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX));
179184

@@ -191,23 +196,26 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) {
191196

192197
uint32_t tud_cdc_n_write_flush(uint8_t itf) {
193198
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
199+
cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf];
194200

195201
// Skip if usb is not ready yet
196202
TU_VERIFY(tud_ready(), 0);
197203

198204
// No data to send
199-
if (!tu_fifo_count(&p_cdc->tx_ff)) return 0;
205+
if (!tu_fifo_count(&p_cdc->tx_ff)) {
206+
return 0;
207+
}
200208

201-
uint8_t const rhport = 0;
209+
const uint8_t rhport = 0;
202210

203211
// Claim the endpoint
204212
TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_in), 0);
205213

206214
// Pull data from FIFO
207-
uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf));
215+
const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE);
208216

209217
if (count) {
210-
TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0);
218+
TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, p_epbuf->epin, count), 0);
211219
return count;
212220
} else {
213221
// Release endpoint since we don't make any transfer
@@ -291,32 +299,37 @@ void cdcd_reset(uint8_t rhport) {
291299
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
292300

293301
tu_memclr(p_cdc, ITF_MEM_RESET_SIZE);
294-
if (!_cdcd_fifo_cfg.rx_persistent) tu_fifo_clear(&p_cdc->rx_ff);
295-
if (!_cdcd_fifo_cfg.tx_persistent) tu_fifo_clear(&p_cdc->tx_ff);
302+
if (!_cdcd_fifo_cfg.rx_persistent) {
303+
tu_fifo_clear(&p_cdc->rx_ff);
304+
}
305+
if (!_cdcd_fifo_cfg.tx_persistent) {
306+
tu_fifo_clear(&p_cdc->tx_ff);
307+
}
296308
tu_fifo_set_overwritable(&p_cdc->tx_ff, true);
297309
}
298310
}
299311

300-
uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) {
312+
uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len) {
301313
// Only support ACM subclass
302314
TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass &&
303315
CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0);
304316

305317
// Find available interface
306-
cdcd_interface_t* p_cdc = NULL;
307-
for (uint8_t cdc_id = 0; cdc_id < CFG_TUD_CDC; cdc_id++) {
308-
if (_cdcd_itf[cdc_id].ep_in == 0) {
309-
p_cdc = &_cdcd_itf[cdc_id];
318+
cdcd_interface_t* p_cdc;
319+
uint8_t cdc_id;
320+
for (cdc_id = 0; cdc_id < CFG_TUD_CDC; cdc_id++) {
321+
p_cdc = &_cdcd_itf[cdc_id];
322+
if (p_cdc->ep_in == 0) {
310323
break;
311324
}
312325
}
313-
TU_ASSERT(p_cdc, 0);
326+
TU_ASSERT(cdc_id < CFG_TUD_CDC, 0);
314327

315328
//------------- Control Interface -------------//
316329
p_cdc->itf_num = itf_desc->bInterfaceNumber;
317330

318331
uint16_t drv_len = sizeof(tusb_desc_interface_t);
319-
uint8_t const* p_desc = tu_desc_next(itf_desc);
332+
const uint8_t* p_desc = tu_desc_next(itf_desc);
320333

321334
// Communication Functional Descriptors
322335
while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) {
@@ -326,7 +339,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1
326339

327340
if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
328341
// notification endpoint
329-
tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc;
342+
const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc;
330343

331344
TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0);
332345
p_cdc->ep_notif = desc_ep->bEndpointAddress;
@@ -337,7 +350,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1
337350

338351
//------------- Data Interface (if any) -------------//
339352
if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) &&
340-
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const*) p_desc)->bInterfaceClass)) {
353+
(TUSB_CLASS_CDC_DATA == ((const tusb_desc_interface_t*) p_desc)->bInterfaceClass)) {
341354
// next to endpoint descriptor
342355
drv_len += tu_desc_len(p_desc);
343356
p_desc = tu_desc_next(p_desc);
@@ -349,35 +362,39 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1
349362
}
350363

351364
// Prepare for incoming data
352-
_prep_out_transaction(p_cdc);
365+
_prep_out_transaction(cdc_id);
353366

354367
return drv_len;
355368
}
356369

357370
// Invoked when a control transfer occurred on an interface of this class
358371
// Driver response accordingly to the request and the transfer stage (setup/data/ack)
359372
// return false to stall control endpoint (e.g unsupported request)
360-
bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) {
373+
bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) {
361374
// Handle class request only
362375
TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
363376

364-
uint8_t itf = 0;
365-
cdcd_interface_t* p_cdc = _cdcd_itf;
377+
uint8_t itf;
378+
cdcd_interface_t* p_cdc;
366379

367380
// Identify which interface to use
368-
for (;; itf++, p_cdc++) {
369-
if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false;
370-
371-
if (p_cdc->itf_num == request->wIndex) break;
381+
for (itf = 0; itf < CFG_TUD_CDC; itf++) {
382+
p_cdc = &_cdcd_itf[itf];
383+
if (p_cdc->itf_num == request->wIndex) {
384+
break;
385+
}
372386
}
387+
TU_VERIFY(itf < CFG_TUD_CDC);
373388

374389
switch (request->bRequest) {
375390
case CDC_REQUEST_SET_LINE_CODING:
376391
if (stage == CONTROL_STAGE_SETUP) {
377392
TU_LOG_DRV(" Set Line Coding\r\n");
378393
tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t));
379394
} else if (stage == CONTROL_STAGE_ACK) {
380-
if (tud_cdc_line_coding_cb) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding);
395+
if (tud_cdc_line_coding_cb) {
396+
tud_cdc_line_coding_cb(itf, &p_cdc->line_coding);
397+
}
381398
}
382399
break;
383400

@@ -408,7 +425,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
408425
TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts);
409426

410427
// Invoke callback
411-
if (tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, dtr, rts);
428+
if (tud_cdc_line_state_cb) {
429+
tud_cdc_line_state_cb(itf, dtr, rts);
430+
}
412431
}
413432
break;
414433

@@ -417,7 +436,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
417436
tud_control_status(rhport, request);
418437
} else if (stage == CONTROL_STAGE_ACK) {
419438
TU_LOG_DRV(" Send Break\r\n");
420-
if (tud_cdc_send_break_cb) tud_cdc_send_break_cb(itf, request->wValue);
439+
if (tud_cdc_send_break_cb) {
440+
tud_cdc_send_break_cb(itf, request->wValue);
441+
}
421442
}
422443
break;
423444

@@ -437,36 +458,43 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
437458
// Identify which interface to use
438459
for (itf = 0; itf < CFG_TUD_CDC; itf++) {
439460
p_cdc = &_cdcd_itf[itf];
440-
if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) break;
461+
if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) {
462+
break;
463+
}
441464
}
442465
TU_ASSERT(itf < CFG_TUD_CDC);
466+
cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf];
443467

444468
// Received new data
445469
if (ep_addr == p_cdc->ep_out) {
446-
tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes);
470+
tu_fifo_write_n(&p_cdc->rx_ff, p_epbuf->epout, (uint16_t) xferred_bytes);
447471

448472
// Check for wanted char and invoke callback if needed
449473
if (tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1)) {
450474
for (uint32_t i = 0; i < xferred_bytes; i++) {
451-
if ((p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) {
475+
if ((p_cdc->wanted_char == p_epbuf->epout[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) {
452476
tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char);
453477
}
454478
}
455479
}
456480

457481
// invoke receive callback (if there is still data)
458-
if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf);
482+
if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) {
483+
tud_cdc_rx_cb(itf);
484+
}
459485

460486
// prepare for OUT transaction
461-
_prep_out_transaction(p_cdc);
487+
_prep_out_transaction(itf);
462488
}
463489

464490
// Data sent to host, we continue to fetch from tx fifo to send.
465491
// Note: This will cause incorrect baudrate set in line coding.
466492
// Though maybe the baudrate is not really important !!!
467493
if (ep_addr == p_cdc->ep_in) {
468494
// invoke transmit callback to possibly refill tx fifo
469-
if (tud_cdc_tx_complete_cb) tud_cdc_tx_complete_cb(itf);
495+
if (tud_cdc_tx_complete_cb) {
496+
tud_cdc_tx_complete_cb(itf);
497+
}
470498

471499
if (0 == tud_cdc_n_write_flush(itf)) {
472500
// If there is no data left, a ZLP should be sent if

0 commit comments

Comments
 (0)