@@ -171,40 +171,64 @@ int8_t usbd_cdc_control(usbd_cdc_state_t *cdc_in, uint8_t cmd, uint8_t *pbuf, ui
171
171
return USBD_OK ;
172
172
}
173
173
174
+ static uint16_t inline usbd_cdc_tx_buffer_mask (uint16_t val ) {
175
+ return val & (USBD_CDC_TX_DATA_SIZE - 1 );
176
+ }
177
+
178
+ static uint16_t inline usbd_cdc_tx_buffer_size (usbd_cdc_itf_t * cdc ) {
179
+ return cdc -> tx_buf_ptr_in - cdc -> tx_buf_ptr_out ;
180
+ }
181
+
182
+ static bool inline usbd_cdc_tx_buffer_empty (usbd_cdc_itf_t * cdc ) {
183
+ return cdc -> tx_buf_ptr_out == cdc -> tx_buf_ptr_in ;
184
+ }
185
+
186
+ static bool inline usbd_cdc_tx_buffer_will_be_empty (usbd_cdc_itf_t * cdc ) {
187
+ return cdc -> tx_buf_ptr_out_next == cdc -> tx_buf_ptr_in ;
188
+ }
189
+
190
+ static bool inline usbd_cdc_tx_buffer_full (usbd_cdc_itf_t * cdc ) {
191
+ return usbd_cdc_tx_buffer_size (cdc ) == USBD_CDC_TX_DATA_SIZE ;
192
+ }
193
+
194
+ static uint16_t usbd_cdc_tx_send_length (usbd_cdc_itf_t * cdc ) {
195
+ uint16_t to_end = USBD_CDC_TX_DATA_SIZE - usbd_cdc_tx_buffer_mask (cdc -> tx_buf_ptr_out );
196
+ return MIN (usbd_cdc_tx_buffer_size (cdc ), to_end );
197
+ }
198
+
199
+ static void usbd_cdc_tx_buffer_put (usbd_cdc_itf_t * cdc , uint8_t data ) {
200
+ cdc -> tx_buf [usbd_cdc_tx_buffer_mask (cdc -> tx_buf_ptr_in )] = data ;
201
+ cdc -> tx_buf_ptr_in ++ ;
202
+ }
203
+
204
+ static uint8_t * usbd_cdc_tx_buffer_getp (usbd_cdc_itf_t * cdc , uint16_t len ) {
205
+ cdc -> tx_buf_ptr_out_next += len ;
206
+ return & cdc -> tx_buf [usbd_cdc_tx_buffer_mask (cdc -> tx_buf_ptr_out )];
207
+ }
208
+
174
209
// Called when the USB IN endpoint is ready to receive more data
175
210
// (cdc.base.tx_in_progress must be 0)
176
211
void usbd_cdc_tx_ready (usbd_cdc_state_t * cdc_in ) {
177
212
178
213
usbd_cdc_itf_t * cdc = (usbd_cdc_itf_t * )cdc_in ;
179
- cdc -> tx_buf_ptr_out = cdc -> tx_buf_ptr_out_shadow ;
214
+ cdc -> tx_buf_ptr_out = cdc -> tx_buf_ptr_out_next ;
180
215
181
- if (cdc -> tx_buf_ptr_out == cdc -> tx_buf_ptr_in && !cdc -> tx_need_empty_packet ) {
216
+ if (usbd_cdc_tx_buffer_empty ( cdc ) && !cdc -> tx_need_empty_packet ) {
182
217
// No outstanding data to send
183
218
return ;
184
219
}
185
-
186
- uint32_t len ;
187
- if (cdc -> tx_buf_ptr_out > cdc -> tx_buf_ptr_in ) { // rollback
188
- len = USBD_CDC_TX_DATA_SIZE - cdc -> tx_buf_ptr_out ;
189
- } else {
190
- len = cdc -> tx_buf_ptr_in - cdc -> tx_buf_ptr_out ;
191
- }
192
-
220
+ uint16_t len = usbd_cdc_tx_send_length (cdc );
193
221
// Should always succeed because cdc.base.tx_in_progress==0
194
- USBD_CDC_TransmitPacket (& cdc -> base , len , & cdc -> tx_buf [ cdc -> tx_buf_ptr_out ] );
222
+ USBD_CDC_TransmitPacket (& cdc -> base , len , usbd_cdc_tx_buffer_getp ( cdc , len ) );
195
223
196
- cdc -> tx_buf_ptr_out_shadow += len ;
197
- if (cdc -> tx_buf_ptr_out_shadow == USBD_CDC_TX_DATA_SIZE ) {
198
- cdc -> tx_buf_ptr_out_shadow = 0 ;
199
- }
200
224
201
225
// According to the USB specification, a packet size of 64 bytes (CDC_DATA_FS_MAX_PACKET_SIZE)
202
226
// gets held at the USB host until the next packet is sent. This is because a
203
227
// packet of maximum size is considered to be part of a longer chunk of data, and
204
228
// the host waits for all data to arrive (ie, waits for a packet < max packet size).
205
229
// To flush a packet of exactly max packet size, we need to send a zero-size packet.
206
230
// See eg http://www.cypress.com/?id=4&rID=92719
207
- cdc -> tx_need_empty_packet = (len > 0 && len % usbd_cdc_max_packet (cdc -> base .usbd -> pdev ) == 0 && cdc -> tx_buf_ptr_out_shadow == cdc -> tx_buf_ptr_in );
231
+ cdc -> tx_need_empty_packet = (len > 0 && len % usbd_cdc_max_packet (cdc -> base .usbd -> pdev ) == 0 && usbd_cdc_tx_buffer_will_be_empty ( cdc ) );
208
232
}
209
233
210
234
// Attempt to queue data on the USB IN endpoint
@@ -291,10 +315,7 @@ int8_t usbd_cdc_receive(usbd_cdc_state_t *cdc_in, size_t len) {
291
315
}
292
316
293
317
int usbd_cdc_tx_half_empty (usbd_cdc_itf_t * cdc ) {
294
- int32_t tx_waiting = (int32_t )cdc -> tx_buf_ptr_in - (int32_t )cdc -> tx_buf_ptr_out ;
295
- if (tx_waiting < 0 ) {
296
- tx_waiting += USBD_CDC_TX_DATA_SIZE ;
297
- }
318
+ int32_t tx_waiting = usbd_cdc_tx_buffer_size (cdc );
298
319
return tx_waiting <= USBD_CDC_TX_DATA_SIZE / 2 ;
299
320
}
300
321
@@ -317,8 +338,7 @@ int usbd_cdc_tx(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len, uint32_t
317
338
for (uint32_t i = 0 ; i < len ; i ++ ) {
318
339
// Wait until the device is connected and the buffer has space, with a given timeout
319
340
uint32_t start = HAL_GetTick ();
320
- while (cdc -> connect_state == USBD_CDC_CONNECT_STATE_DISCONNECTED
321
- || ((cdc -> tx_buf_ptr_in + 1 ) & (USBD_CDC_TX_DATA_SIZE - 1 )) == cdc -> tx_buf_ptr_out ) {
341
+ while (cdc -> connect_state == USBD_CDC_CONNECT_STATE_DISCONNECTED || usbd_cdc_tx_buffer_full (cdc )) {
322
342
usbd_cdc_try_tx (cdc );
323
343
// Wraparound of tick is taken care of by 2's complement arithmetic.
324
344
if (HAL_GetTick () - start >= timeout ) {
@@ -333,8 +353,7 @@ int usbd_cdc_tx(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len, uint32_t
333
353
}
334
354
335
355
// Write data to device buffer
336
- cdc -> tx_buf [cdc -> tx_buf_ptr_in ] = buf [i ];
337
- cdc -> tx_buf_ptr_in = (cdc -> tx_buf_ptr_in + 1 ) & (USBD_CDC_TX_DATA_SIZE - 1 );
356
+ usbd_cdc_tx_buffer_put (cdc , buf [i ]);
338
357
}
339
358
340
359
usbd_cdc_try_tx (cdc );
@@ -357,7 +376,7 @@ void usbd_cdc_tx_always(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len) {
357
376
// If the buffer is full, wait until it gets drained, with a timeout of 500ms
358
377
// (wraparound of tick is taken care of by 2's complement arithmetic).
359
378
uint32_t start = HAL_GetTick ();
360
- while ((( cdc -> tx_buf_ptr_in + 1 ) & ( USBD_CDC_TX_DATA_SIZE - 1 )) == cdc -> tx_buf_ptr_out && HAL_GetTick () - start <= 500 ) {
379
+ while (usbd_cdc_tx_buffer_full ( cdc ) && HAL_GetTick () - start <= 500 ) {
361
380
usbd_cdc_try_tx (cdc );
362
381
if (query_irq () == IRQ_STATE_DISABLED ) {
363
382
// IRQs disabled so buffer will never be drained; exit loop
@@ -367,8 +386,7 @@ void usbd_cdc_tx_always(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len) {
367
386
}
368
387
}
369
388
370
- cdc -> tx_buf [cdc -> tx_buf_ptr_in ] = buf [i ];
371
- cdc -> tx_buf_ptr_in = (cdc -> tx_buf_ptr_in + 1 ) & (USBD_CDC_TX_DATA_SIZE - 1 );
389
+ usbd_cdc_tx_buffer_put (cdc , buf [i ]);
372
390
}
373
391
usbd_cdc_try_tx (cdc );
374
392
}
0 commit comments