@@ -288,23 +288,29 @@ static int dwc2_tx_fifo_write(const struct device *dev,
288288 unsigned int key ;
289289 uint32_t len ;
290290
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+ }
306311
307- len = MIN (buf -> len , spcavail );
312+ len = MIN (buf -> len , spcavail );
313+ }
308314
309315 if (len != 0U ) {
310316 max_pktcnt = dwc2_get_iept_pktctn (dev , ep_idx );
@@ -332,8 +338,8 @@ static int dwc2_tx_fifo_write(const struct device *dev,
332338 pktcnt = 1U ;
333339 }
334340
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 );
337343 priv -> tx_len [ep_idx ] = len ;
338344
339345 /* Lock and write to endpoint FIFO */
@@ -363,22 +369,31 @@ static int dwc2_tx_fifo_write(const struct device *dev,
363369 sys_write32 (USB_DWC2_DIEPINT_INEPNAKEFF , diepint_reg );
364370
365371 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 ));
379392 }
380393
381- sys_write32 (val , UDC_DWC2_EP_FIFO (base , ep_idx ));
394+ pktcnt -- ;
395+ src += pktlen ;
396+ len -= pktlen ;
382397 }
383398 }
384399
0 commit comments