Skip to content

Commit 8323e4b

Browse files
committed
moving edpt_stream API into common tusb.c
1 parent 9e8ea44 commit 8323e4b

File tree

5 files changed

+239
-146
lines changed

5 files changed

+239
-146
lines changed

src/class/cdc/cdc_host.c

Lines changed: 40 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -42,166 +42,68 @@
4242
//--------------------------------------------------------------------+
4343
// MACRO CONSTANT TYPEDEF
4444
//--------------------------------------------------------------------+
45-
typedef struct {
46-
tu_fifo_t ff;
47-
48-
// mutex: read if ep rx, write if e tx
49-
OSAL_MUTEX_DEF(ff_mutex);
50-
51-
// TODO xfer_fifo can skip this buffer
52-
uint8_t* ep_buf;
53-
uint16_t ep_bufsize;
54-
uint8_t ep_addr;
55-
}tu_edpt_stream_t;
56-
57-
bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool use_wr_mutex, bool overwritable,
58-
void* ff_buf, uint16_t ff_bufsize,
59-
uint8_t* ep_buf, uint16_t ep_bufsize)
60-
{
61-
osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex);
62-
(void) new_mutex;
63-
(void) use_wr_mutex;
64-
65-
tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable);
66-
tu_fifo_config_mutex(&s->ff, use_wr_mutex ? new_mutex : NULL, use_wr_mutex ? NULL : new_mutex);
67-
68-
s->ep_buf = ep_buf;
69-
s->ep_bufsize = ep_bufsize;
70-
71-
return true;
72-
}
73-
74-
bool tu_edpt_stream_clear(tu_edpt_stream_t* s)
75-
{
76-
return tu_fifo_clear(&s->ff);
77-
}
7845

79-
bool tu_edpt_stream_write_zlp_if_needed(uint8_t daddr, tu_edpt_stream_t* s, uint32_t last_xferred_bytes)
46+
bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes)
8047
{
81-
uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
48+
uint16_t const bulk_packet_size = (s->ep_speed == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
8249

8350
// ZLP condition: no pending data, last transferred bytes is multiple of packet size
8451
TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (bulk_packet_size-1))) );
8552

86-
if ( usbh_edpt_claim(daddr, s->ep_addr) )
53+
if ( usbh_edpt_claim(s->daddr, s->ep_addr) )
8754
{
88-
TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, NULL, 0) );
55+
TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, NULL, 0) );
8956
}
9057

9158
return true;
9259
}
9360

94-
uint32_t tu_edpt_stream_write_xfer(uint8_t daddr, tu_edpt_stream_t* s)
61+
uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s)
9562
{
9663
// skip if no data
9764
TU_VERIFY( tu_fifo_count(&s->ff), 0 );
9865

9966
// Claim the endpoint
10067
// uint8_t const rhport = 0;
10168
// TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 );
102-
TU_VERIFY( usbh_edpt_claim(daddr, s->ep_addr) );
69+
TU_VERIFY( usbh_edpt_claim(s->daddr, s->ep_addr) );
10370

10471
// Pull data from FIFO -> EP buf
10572
uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
10673

10774
if ( count )
10875
{
10976
//TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 );
110-
TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, s->ep_buf, count), 0 );
77+
TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 );
11178
return count;
11279
}else
11380
{
11481
// Release endpoint since we don't make any transfer
11582
// Note: data is dropped if terminal is not connected
11683
//usbd_edpt_release(rhport, p_cdc->ep_in);
11784

118-
usbh_edpt_release(daddr, s->ep_addr);
85+
usbh_edpt_release(s->daddr, s->ep_addr);
11986
return 0;
12087
}
12188
}
12289

123-
uint32_t tu_edpt_stream_write(uint8_t daddr, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize)
124-
{
125-
uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
126-
127-
// flush if queue more than packet size
128-
uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
129-
if ( (tu_fifo_count(&s->ff) >= bulk_packet_size)
130-
/* || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) */ )
131-
{
132-
tu_edpt_stream_write_xfer(daddr, s);
133-
}
134-
135-
return ret;
136-
}
137-
138-
void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes)
139-
{
140-
tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes);
141-
}
142-
143-
uint32_t tu_edpt_stream_read_xfer(uint8_t daddr, tu_edpt_stream_t* s)
90+
uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize)
14491
{
145-
uint16_t available = tu_fifo_remaining(&s->ff);
92+
TU_VERIFY(bufsize); // TODO support ZLP
14693

147-
// Prepare for incoming data but only allow what we can store in the ring buffer.
148-
// TODO Actually we can still carry out the transfer, keeping count of received bytes
149-
// and slowly move it to the FIFO when read().
150-
// This pre-check reduces endpoint claiming
151-
uint16_t const bulk_packet_size = (tuh_speed_get(daddr) == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
152-
TU_VERIFY(available >= bulk_packet_size);
153-
154-
// claim endpoint
155-
TU_VERIFY(usbh_edpt_claim(daddr, s->ep_addr), 0);
156-
157-
// fifo can be changed before endpoint is claimed
158-
available = tu_fifo_remaining(&s->ff);
159-
160-
if ( available >= bulk_packet_size )
161-
{
162-
// multiple of packet size limit by ep bufsize
163-
uint16_t count = (uint16_t) (available & (bulk_packet_size -1));
164-
count = tu_min16(count, s->ep_bufsize);
94+
uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
16595

166-
TU_ASSERT( usbh_edpt_xfer(daddr, s->ep_addr, s->ep_buf, count), 0 );
167-
return count;
168-
}else
96+
// flush if fifo has more than packet size or
97+
// in rare case: fifo depth is configured too small (which never reach packet size)
98+
uint16_t const bulk_packet_size = (s->ep_speed == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
99+
if ( (tu_fifo_count(&s->ff) >= bulk_packet_size) || ( tu_fifo_depth(&s->ff) < bulk_packet_size) )
169100
{
170-
// Release endpoint since we don't make any transfer
171-
usbh_edpt_release(daddr, s->ep_addr);
172-
return 0;
101+
tu_edpt_stream_write_xfer(s);
173102
}
174-
}
175-
176-
uint32_t tu_edpt_stream_read(uint8_t daddr, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize)
177-
{
178-
uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize);
179-
tu_edpt_stream_read_xfer(daddr, s);
180-
return num_read;
181-
}
182-
183-
uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s)
184-
{
185-
return (uint32_t) tu_fifo_count(&s->ff);
186-
}
187-
188-
uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s)
189-
{
190-
return (uint32_t) tu_fifo_remaining(&s->ff);
191-
}
192103

193-
bool tu_edpt_stream_read_clear(uint8_t daddr, tu_edpt_stream_t* s)
194-
{
195-
bool ret = tu_fifo_clear(&s->ff);
196-
tu_edpt_stream_read_xfer(daddr, s);
197104
return ret;
198105
}
199106

200-
bool tu_edpt_stream_write_clear(tu_edpt_stream_t* s)
201-
{
202-
return tu_fifo_clear(&s->ff);
203-
}
204-
205107
typedef struct {
206108
uint8_t daddr;
207109
uint8_t bInterfaceNumber;
@@ -326,23 +228,23 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize)
326228
cdch_interface_t* p_cdc = get_itf(idx);
327229
TU_VERIFY(p_cdc);
328230

329-
return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize);
231+
return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize);
330232
}
331233

332234
uint32_t tuh_cdc_write_flush(uint8_t idx)
333235
{
334236
cdch_interface_t* p_cdc = get_itf(idx);
335237
TU_VERIFY(p_cdc);
336238

337-
return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx);
239+
return tu_edpt_stream_write_xfer(&p_cdc->stream.tx);
338240
}
339241

340242
bool tuh_cdc_write_clear(uint8_t idx)
341243
{
342244
cdch_interface_t* p_cdc = get_itf(idx);
343245
TU_VERIFY(p_cdc);
344246

345-
return tu_edpt_stream_write_clear(&p_cdc->stream.tx);
247+
return tu_edpt_stream_clear(&p_cdc->stream.tx);
346248
}
347249

348250
uint32_t tuh_cdc_write_available(uint8_t idx)
@@ -358,7 +260,7 @@ uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize)
358260
cdch_interface_t* p_cdc = get_itf(idx);
359261
TU_VERIFY(p_cdc);
360262

361-
return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize);
263+
return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize);
362264
}
363265

364266
uint32_t tuh_cdc_read_available(uint8_t idx)
@@ -374,7 +276,9 @@ bool tuh_cdc_read_clear (uint8_t idx)
374276
cdch_interface_t* p_cdc = get_itf(idx);
375277
TU_VERIFY(p_cdc);
376278

377-
return tu_edpt_stream_read_clear(p_cdc->daddr, &p_cdc->stream.rx);
279+
bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx);
280+
tu_edpt_stream_read_xfer(&p_cdc->stream.rx);
281+
return ret;
378282
}
379283

380284
//--------------------------------------------------------------------+
@@ -452,13 +356,13 @@ void cdch_init(void)
452356
{
453357
cdch_interface_t* p_cdc = &cdch_data[i];
454358

455-
tu_edpt_stream_init(&p_cdc->stream.tx, true, false,
456-
p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE,
457-
p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE);
359+
tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false,
360+
p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE,
361+
p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE);
458362

459-
tu_edpt_stream_init(&p_cdc->stream.rx, false, false,
460-
p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE,
461-
p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE);
363+
tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false,
364+
p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE,
365+
p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE);
462366
}
463367
}
464368

@@ -475,8 +379,6 @@ void cdch_close(uint8_t daddr)
475379
//tu_memclr(p_cdc, sizeof(cdch_interface_t));
476380
p_cdc->daddr = 0;
477381
p_cdc->bInterfaceNumber = 0;
478-
tu_edpt_stream_clear(&p_cdc->stream.tx);
479-
tu_edpt_stream_clear(&p_cdc->stream.rx);
480382
}
481383
}
482384
}
@@ -495,23 +397,22 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t
495397
// invoke tx complete callback to possibly refill tx fifo
496398
if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx);
497399

498-
if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) )
400+
if ( 0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx) )
499401
{
500402
// If there is no data left, a ZLP should be sent if needed
501403
// xferred_bytes is multiple of EP Packet size and not zero
502-
tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes);
404+
tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes);
503405
}
504406
}
505407
else if ( ep_addr == p_cdc->stream.rx.ep_addr )
506408
{
507-
// skip if ZLP
508-
if (xferred_bytes) tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes);
409+
tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes);
509410

510411
// invoke receive callback
511412
if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx);
512413

513414
// prepare for next transfer if needed
514-
tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx);
415+
tu_edpt_stream_read_xfer(&p_cdc->stream.rx);
515416
}else if ( ep_addr == p_cdc->ep_notif )
516417
{
517418
// TODO handle notification endpoint
@@ -527,7 +428,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t
527428
// Enumeration
528429
//--------------------------------------------------------------------+
529430

530-
bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len)
431+
bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len)
531432
{
532433
(void) rhport;
533434

@@ -542,7 +443,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
542443
cdch_interface_t * p_cdc = find_new_itf();
543444
TU_VERIFY(p_cdc);
544445

545-
p_cdc->daddr = dev_addr;
446+
p_cdc->daddr = daddr;
546447
p_cdc->bInterfaceNumber = itf_desc->bInterfaceNumber;
547448
p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass;
548449
p_cdc->bInterfaceProtocol = itf_desc->bInterfaceProtocol;
@@ -569,7 +470,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
569470
TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc));
570471
tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc;
571472

572-
TU_ASSERT( tuh_edpt_open(dev_addr, desc_ep) );
473+
TU_ASSERT( tuh_edpt_open(daddr, desc_ep) );
573474
p_cdc->ep_notif = desc_ep->bEndpointAddress;
574475

575476
p_desc = tu_desc_next(p_desc);
@@ -589,14 +490,14 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
589490
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType &&
590491
TUSB_XFER_BULK == desc_ep->bmAttributes.xfer);
591492

592-
TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep));
493+
TU_ASSERT(tuh_edpt_open(daddr, desc_ep));
593494

594495
if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN )
595496
{
596-
p_cdc->stream.rx.ep_addr = desc_ep->bEndpointAddress;
497+
tu_edpt_stream_open(&p_cdc->stream.rx, daddr, desc_ep);
597498
}else
598499
{
599-
p_cdc->stream.tx.ep_addr = desc_ep->bEndpointAddress;
500+
tu_edpt_stream_open(&p_cdc->stream.tx, daddr, desc_ep);
600501
}
601502

602503
p_desc = tu_desc_next(p_desc);
@@ -616,7 +517,7 @@ static void config_cdc_complete(uint8_t daddr, uint8_t itf_num)
616517

617518
// Prepare for incoming data
618519
cdch_interface_t* p_cdc = get_itf(idx);
619-
tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx);
520+
tu_edpt_stream_read_xfer(&p_cdc->stream.rx);
620521
}
621522

622523
// notify usbh that driver enumeration is complete

0 commit comments

Comments
 (0)