@@ -288,23 +288,29 @@ static int dwc2_tx_fifo_write(const struct device *dev,
288
288
unsigned int key ;
289
289
uint32_t len ;
290
290
291
- spcavail = dwc2_ftx_avail (dev , ep_idx );
292
- /* Round down to multiple of endpoint MPS */
293
- spcavail -= spcavail % cfg -> mps ;
294
- /*
295
- * Here, the available space should be equal to the FIFO space
296
- * assigned/configured for that endpoint because we do not schedule another
297
- * transfer until the previous one has not finished. For simplicity,
298
- * we only check that the available space is not less than the endpoint
299
- * MPS.
300
- */
301
- if (spcavail < cfg -> mps ) {
302
- LOG_ERR ("ep 0x%02x FIFO space is too low, %u (%u)" ,
303
- cfg -> addr , spcavail , dwc2_ftx_avail (dev , ep_idx ));
304
- return - EAGAIN ;
305
- }
291
+ if (priv -> bufferdma ) {
292
+ /* DMA automatically handles packet split */
293
+ len = buf -> len ;
294
+ } else {
295
+ uint32_t spcavail = dwc2_ftx_avail (dev , ep_idx );
296
+
297
+ /* Round down to multiple of endpoint MPS */
298
+ spcavail -= spcavail % cfg -> mps ;
299
+
300
+ /* Here, the available space should be equal to the FIFO space
301
+ * assigned/configured for that endpoint because we do not
302
+ * schedule another transfer until the previous one has not
303
+ * finished. For simplicity, we only check that the available
304
+ * space is not less than the endpoint MPS.
305
+ */
306
+ if (spcavail < cfg -> mps ) {
307
+ LOG_ERR ("ep 0x%02x FIFO space is too low, %u (%u)" ,
308
+ cfg -> addr , spcavail , dwc2_ftx_avail (dev , ep_idx ));
309
+ return - EAGAIN ;
310
+ }
306
311
307
- len = MIN (buf -> len , spcavail );
312
+ len = MIN (buf -> len , spcavail );
313
+ }
308
314
309
315
if (len != 0U ) {
310
316
max_pktcnt = dwc2_get_iept_pktctn (dev , ep_idx );
@@ -332,8 +338,8 @@ static int dwc2_tx_fifo_write(const struct device *dev,
332
338
pktcnt = 1U ;
333
339
}
334
340
335
- LOG_DBG ("Prepare ep 0x%02x xfer len %u pktcnt %u spcavail %u " ,
336
- cfg -> addr , len , pktcnt , spcavail );
341
+ LOG_DBG ("Prepare ep 0x%02x xfer len %u pktcnt %u" ,
342
+ cfg -> addr , len , pktcnt );
337
343
priv -> tx_len [ep_idx ] = len ;
338
344
339
345
/* Lock and write to endpoint FIFO */
@@ -363,22 +369,31 @@ static int dwc2_tx_fifo_write(const struct device *dev,
363
369
sys_write32 (USB_DWC2_DIEPINT_INEPNAKEFF , diepint_reg );
364
370
365
371
if (!priv -> bufferdma ) {
366
- /* FIFO access is always in 32-bit words */
367
-
368
- for (uint32_t i = 0UL ; i < len ; i += d ) {
369
- uint32_t val = buf -> data [i ];
370
-
371
- if (i + 1 < len ) {
372
- val |= ((uint32_t )buf -> data [i + 1UL ]) << 8 ;
373
- }
374
- if (i + 2 < len ) {
375
- val |= ((uint32_t )buf -> data [i + 2UL ]) << 16 ;
376
- }
377
- if (i + 3 < len ) {
378
- val |= ((uint32_t )buf -> data [i + 3UL ]) << 24 ;
372
+ const uint8_t * src = buf -> data ;
373
+ uint32_t pktlen ;
374
+
375
+ while (pktcnt > 0 ) {
376
+ uint32_t pktlen = MIN (len , cfg -> mps );
377
+
378
+ for (uint32_t i = 0UL ; i < pktlen ; i += d ) {
379
+ uint32_t val = src [i ];
380
+
381
+ if (i + 1 < pktlen ) {
382
+ val |= ((uint32_t )src [i + 1UL ]) << 8 ;
383
+ }
384
+ if (i + 2 < pktlen ) {
385
+ val |= ((uint32_t )src [i + 2UL ]) << 16 ;
386
+ }
387
+ if (i + 3 < pktlen ) {
388
+ val |= ((uint32_t )src [i + 3UL ]) << 24 ;
389
+ }
390
+
391
+ sys_write32 (val , UDC_DWC2_EP_FIFO (base , ep_idx ));
379
392
}
380
393
381
- sys_write32 (val , UDC_DWC2_EP_FIFO (base , ep_idx ));
394
+ pktcnt -- ;
395
+ src += pktlen ;
396
+ len -= pktlen ;
382
397
}
383
398
}
384
399
0 commit comments