42
42
//--------------------------------------------------------------------+
43
43
// MACRO CONSTANT TYPEDEF
44
44
//--------------------------------------------------------------------+
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
- }
78
45
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 )
80
47
{
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 ;
82
49
83
50
// ZLP condition: no pending data, last transferred bytes is multiple of packet size
84
51
TU_VERIFY ( !tu_fifo_count (& s -> ff ) && last_xferred_bytes && (0 == (last_xferred_bytes & (bulk_packet_size - 1 ))) );
85
52
86
- if ( usbh_edpt_claim (daddr , s -> ep_addr ) )
53
+ if ( usbh_edpt_claim (s -> daddr , s -> ep_addr ) )
87
54
{
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 ) );
89
56
}
90
57
91
58
return true;
92
59
}
93
60
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 )
95
62
{
96
63
// skip if no data
97
64
TU_VERIFY ( tu_fifo_count (& s -> ff ), 0 );
98
65
99
66
// Claim the endpoint
100
67
// uint8_t const rhport = 0;
101
68
// 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 ) );
103
70
104
71
// Pull data from FIFO -> EP buf
105
72
uint16_t const count = tu_fifo_read_n (& s -> ff , s -> ep_buf , s -> ep_bufsize );
106
73
107
74
if ( count )
108
75
{
109
76
//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 );
111
78
return count ;
112
79
}else
113
80
{
114
81
// Release endpoint since we don't make any transfer
115
82
// Note: data is dropped if terminal is not connected
116
83
//usbd_edpt_release(rhport, p_cdc->ep_in);
117
84
118
- usbh_edpt_release (daddr , s -> ep_addr );
85
+ usbh_edpt_release (s -> daddr , s -> ep_addr );
119
86
return 0 ;
120
87
}
121
88
}
122
89
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 )
144
91
{
145
- uint16_t available = tu_fifo_remaining ( & s -> ff );
92
+ TU_VERIFY ( bufsize ); // TODO support ZLP
146
93
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 );
165
95
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 ) )
169
100
{
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 );
173
102
}
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
- }
192
103
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 );
197
104
return ret ;
198
105
}
199
106
200
- bool tu_edpt_stream_write_clear (tu_edpt_stream_t * s )
201
- {
202
- return tu_fifo_clear (& s -> ff );
203
- }
204
-
205
107
typedef struct {
206
108
uint8_t daddr ;
207
109
uint8_t bInterfaceNumber ;
@@ -326,23 +228,23 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize)
326
228
cdch_interface_t * p_cdc = get_itf (idx );
327
229
TU_VERIFY (p_cdc );
328
230
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 );
330
232
}
331
233
332
234
uint32_t tuh_cdc_write_flush (uint8_t idx )
333
235
{
334
236
cdch_interface_t * p_cdc = get_itf (idx );
335
237
TU_VERIFY (p_cdc );
336
238
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 );
338
240
}
339
241
340
242
bool tuh_cdc_write_clear (uint8_t idx )
341
243
{
342
244
cdch_interface_t * p_cdc = get_itf (idx );
343
245
TU_VERIFY (p_cdc );
344
246
345
- return tu_edpt_stream_write_clear (& p_cdc -> stream .tx );
247
+ return tu_edpt_stream_clear (& p_cdc -> stream .tx );
346
248
}
347
249
348
250
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)
358
260
cdch_interface_t * p_cdc = get_itf (idx );
359
261
TU_VERIFY (p_cdc );
360
262
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 );
362
264
}
363
265
364
266
uint32_t tuh_cdc_read_available (uint8_t idx )
@@ -374,7 +276,9 @@ bool tuh_cdc_read_clear (uint8_t idx)
374
276
cdch_interface_t * p_cdc = get_itf (idx );
375
277
TU_VERIFY (p_cdc );
376
278
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 ;
378
282
}
379
283
380
284
//--------------------------------------------------------------------+
@@ -452,13 +356,13 @@ void cdch_init(void)
452
356
{
453
357
cdch_interface_t * p_cdc = & cdch_data [i ];
454
358
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 );
458
362
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 );
462
366
}
463
367
}
464
368
@@ -475,8 +379,6 @@ void cdch_close(uint8_t daddr)
475
379
//tu_memclr(p_cdc, sizeof(cdch_interface_t));
476
380
p_cdc -> daddr = 0 ;
477
381
p_cdc -> bInterfaceNumber = 0 ;
478
- tu_edpt_stream_clear (& p_cdc -> stream .tx );
479
- tu_edpt_stream_clear (& p_cdc -> stream .rx );
480
382
}
481
383
}
482
384
}
@@ -495,23 +397,22 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t
495
397
// invoke tx complete callback to possibly refill tx fifo
496
398
if (tuh_cdc_tx_complete_cb ) tuh_cdc_tx_complete_cb (idx );
497
399
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 ) )
499
401
{
500
402
// If there is no data left, a ZLP should be sent if needed
501
403
// 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 );
503
405
}
504
406
}
505
407
else if ( ep_addr == p_cdc -> stream .rx .ep_addr )
506
408
{
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 );
509
410
510
411
// invoke receive callback
511
412
if (tuh_cdc_rx_cb ) tuh_cdc_rx_cb (idx );
512
413
513
414
// 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 );
515
416
}else if ( ep_addr == p_cdc -> ep_notif )
516
417
{
517
418
// 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
527
428
// Enumeration
528
429
//--------------------------------------------------------------------+
529
430
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 )
531
432
{
532
433
(void ) rhport ;
533
434
@@ -542,7 +443,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
542
443
cdch_interface_t * p_cdc = find_new_itf ();
543
444
TU_VERIFY (p_cdc );
544
445
545
- p_cdc -> daddr = dev_addr ;
446
+ p_cdc -> daddr = daddr ;
546
447
p_cdc -> bInterfaceNumber = itf_desc -> bInterfaceNumber ;
547
448
p_cdc -> bInterfaceSubClass = itf_desc -> bInterfaceSubClass ;
548
449
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
569
470
TU_ASSERT (TUSB_DESC_ENDPOINT == tu_desc_type (p_desc ));
570
471
tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const * ) p_desc ;
571
472
572
- TU_ASSERT ( tuh_edpt_open (dev_addr , desc_ep ) );
473
+ TU_ASSERT ( tuh_edpt_open (daddr , desc_ep ) );
573
474
p_cdc -> ep_notif = desc_ep -> bEndpointAddress ;
574
475
575
476
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
589
490
TU_ASSERT (TUSB_DESC_ENDPOINT == desc_ep -> bDescriptorType &&
590
491
TUSB_XFER_BULK == desc_ep -> bmAttributes .xfer );
591
492
592
- TU_ASSERT (tuh_edpt_open (dev_addr , desc_ep ));
493
+ TU_ASSERT (tuh_edpt_open (daddr , desc_ep ));
593
494
594
495
if ( tu_edpt_dir (desc_ep -> bEndpointAddress ) == TUSB_DIR_IN )
595
496
{
596
- p_cdc -> stream .rx . ep_addr = desc_ep -> bEndpointAddress ;
497
+ tu_edpt_stream_open ( & p_cdc -> stream .rx , daddr , desc_ep ) ;
597
498
}else
598
499
{
599
- p_cdc -> stream .tx . ep_addr = desc_ep -> bEndpointAddress ;
500
+ tu_edpt_stream_open ( & p_cdc -> stream .tx , daddr , desc_ep ) ;
600
501
}
601
502
602
503
p_desc = tu_desc_next (p_desc );
@@ -616,7 +517,7 @@ static void config_cdc_complete(uint8_t daddr, uint8_t itf_num)
616
517
617
518
// Prepare for incoming data
618
519
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 );
620
521
}
621
522
622
523
// notify usbh that driver enumeration is complete
0 commit comments