Skip to content

Commit e3c9d94

Browse files
committed
fix stream read count computation
1 parent 8323e4b commit e3c9d94

File tree

3 files changed

+101
-79
lines changed

3 files changed

+101
-79
lines changed

src/class/cdc/cdc_host.c

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -43,67 +43,6 @@
4343
// MACRO CONSTANT TYPEDEF
4444
//--------------------------------------------------------------------+
4545

46-
bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes)
47-
{
48-
uint16_t const bulk_packet_size = (s->ep_speed == TUSB_SPEED_HIGH) ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
49-
50-
// ZLP condition: no pending data, last transferred bytes is multiple of packet size
51-
TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (bulk_packet_size-1))) );
52-
53-
if ( usbh_edpt_claim(s->daddr, s->ep_addr) )
54-
{
55-
TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, NULL, 0) );
56-
}
57-
58-
return true;
59-
}
60-
61-
uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s)
62-
{
63-
// skip if no data
64-
TU_VERIFY( tu_fifo_count(&s->ff), 0 );
65-
66-
// Claim the endpoint
67-
// uint8_t const rhport = 0;
68-
// TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 );
69-
TU_VERIFY( usbh_edpt_claim(s->daddr, s->ep_addr) );
70-
71-
// Pull data from FIFO -> EP buf
72-
uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
73-
74-
if ( count )
75-
{
76-
//TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 );
77-
TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 );
78-
return count;
79-
}else
80-
{
81-
// Release endpoint since we don't make any transfer
82-
// Note: data is dropped if terminal is not connected
83-
//usbd_edpt_release(rhport, p_cdc->ep_in);
84-
85-
usbh_edpt_release(s->daddr, s->ep_addr);
86-
return 0;
87-
}
88-
}
89-
90-
uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize)
91-
{
92-
TU_VERIFY(bufsize); // TODO support ZLP
93-
94-
uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
95-
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) )
100-
{
101-
tu_edpt_stream_write_xfer(s);
102-
}
103-
104-
return ret;
105-
}
106-
10746
typedef struct {
10847
uint8_t daddr;
10948
uint8_t bInterfaceNumber;
@@ -379,6 +318,8 @@ void cdch_close(uint8_t daddr)
379318
//tu_memclr(p_cdc, sizeof(cdch_interface_t));
380319
p_cdc->daddr = 0;
381320
p_cdc->bInterfaceNumber = 0;
321+
tu_edpt_stream_close(&p_cdc->stream.tx);
322+
tu_edpt_stream_close(&p_cdc->stream.rx);
382323
}
383324
}
384325
}

src/common/tusb_private.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex);
8787
// Endpoint Stream
8888
//--------------------------------------------------------------------+
8989

90-
// Init an stream, should only called once
90+
// Init an stream, should only be called once
9191
bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
9292
void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize);
9393

@@ -102,30 +102,43 @@ void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t
102102
s->ep_packetsize = tu_edpt_packet_size(desc_ep);
103103
}
104104

105+
TU_ATTR_ALWAYS_INLINE static inline
106+
void tu_edpt_stream_close(tu_edpt_stream_t* s)
107+
{
108+
s->hwid = 0;
109+
s->ep_addr = 0;
110+
}
111+
105112
// Clear fifo
106113
TU_ATTR_ALWAYS_INLINE static inline
107114
bool tu_edpt_stream_clear(tu_edpt_stream_t* s)
108115
{
109116
return tu_fifo_clear(&s->ff);
110117
}
111118

112-
//------------- Write -------------//
119+
//--------------------------------------------------------------------+
120+
// Stream Write
121+
//--------------------------------------------------------------------+
113122

114123
// Write to stream
115124
uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize);
116125

117126
// Start an usb transfer if endpoint is not busy
118127
uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s);
119128

129+
// Start an zero-length packet if needed
130+
bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes);
131+
120132
// Get the number of bytes available for writing
121133
TU_ATTR_ALWAYS_INLINE static inline
122134
uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s)
123135
{
124136
return (uint32_t) tu_fifo_remaining(&s->ff);
125137
}
126138

127-
128-
//------------- Read -------------//
139+
//--------------------------------------------------------------------+
140+
// Stream Read
141+
//--------------------------------------------------------------------+
129142

130143
// Read from stream
131144
uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize);

src/tusb.c

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,86 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove
224224
return true;
225225
}
226226

227-
//------------- Stream Write -------------//
227+
TU_ATTR_ALWAYS_INLINE static inline
228+
bool stream_claim(tu_edpt_stream_t* s)
229+
{
230+
if (s->is_host)
231+
{
232+
#if CFG_TUH_ENABLED
233+
return usbh_edpt_claim(s->daddr, s->ep_addr);
234+
#endif
235+
}else
236+
{
237+
#if CFG_TUD_ENABLED
238+
return usbd_edpt_claim(s->rhport, s->ep_addr);
239+
#endif
240+
}
241+
242+
return false;
243+
}
228244

229-
//------------- Stream Read -------------//
245+
246+
//--------------------------------------------------------------------+
247+
// Stream Write
248+
//--------------------------------------------------------------------+
249+
250+
bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes)
251+
{
252+
// ZLP condition: no pending data, last transferred bytes is multiple of packet size
253+
TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize-1))) );
254+
255+
TU_VERIFY( stream_claim(s) );
256+
TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, NULL, 0) );
257+
258+
return true;
259+
}
260+
261+
uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s)
262+
{
263+
// skip if no data
264+
TU_VERIFY( tu_fifo_count(&s->ff), 0 );
265+
266+
// Claim the endpoint
267+
TU_VERIFY( stream_claim(s), 0 );
268+
269+
// Pull data from FIFO -> EP buf
270+
uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
271+
272+
if ( count )
273+
{
274+
//TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 );
275+
TU_ASSERT( usbh_edpt_xfer(s->daddr, s->ep_addr, s->ep_buf, count), 0 );
276+
return count;
277+
}else
278+
{
279+
// Release endpoint since we don't make any transfer
280+
// Note: data is dropped if terminal is not connected
281+
//usbd_edpt_release(rhport, p_cdc->ep_in);
282+
283+
usbh_edpt_release(s->daddr, s->ep_addr);
284+
return 0;
285+
}
286+
}
287+
288+
uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize)
289+
{
290+
TU_VERIFY(bufsize); // TODO support ZLP
291+
292+
uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
293+
294+
// flush if fifo has more than packet size or
295+
// in rare case: fifo depth is configured too small (which never reach packet size)
296+
if ( (tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize) )
297+
{
298+
tu_edpt_stream_write_xfer(s);
299+
}
300+
301+
return ret;
302+
}
303+
304+
//--------------------------------------------------------------------+
305+
// Stream Read
306+
//--------------------------------------------------------------------+
230307

231308
uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s)
232309
{
@@ -239,25 +316,15 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s)
239316
TU_VERIFY(available >= s->ep_packetsize);
240317

241318
// claim endpoint
242-
if (s->is_host)
243-
{
244-
#if CFG_TUH_ENABLED
245-
TU_VERIFY(usbh_edpt_claim(s->daddr, s->ep_addr), 0);
246-
#endif
247-
}else
248-
{
249-
#if CFG_TUD_ENABLED
250-
TU_VERIFY(usbd_edpt_claim(s->rhport, s->ep_addr), 0);
251-
#endif
252-
}
319+
TU_VERIFY(stream_claim(s), 0);
253320

254321
// get available again since fifo can be changed before endpoint is claimed
255322
available = tu_fifo_remaining(&s->ff);
256323

257324
if ( available >= s->ep_packetsize )
258325
{
259326
// multiple of packet size limit by ep bufsize
260-
uint16_t count = (uint16_t) (available & (s->ep_packetsize -1));
327+
uint16_t count = (uint16_t) (available & ~(s->ep_packetsize -1));
261328
count = tu_min16(count, s->ep_bufsize);
262329

263330
if (s->is_host)
@@ -301,6 +368,7 @@ uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize
301368
//--------------------------------------------------------------------+
302369
// Debug
303370
//--------------------------------------------------------------------+
371+
304372
#if CFG_TUSB_DEBUG
305373
#include <ctype.h>
306374

0 commit comments

Comments
 (0)