2017-11-10 08:37 PM
I'm doing research on USB lib v2.4.2 and HAL (checked 1.6.0 and 1.8.0), trying to understand how it's internals are working. Target chip is STM32F746, target mode is FS (because of internal PHY).
I'm stuck at this function from stm32f7xx_ll_usb.c:
HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
{ uint32_t count32b= 0 , i= 0; if (dma == 0) { count32b = (len + 3) / 4; for (i = 0; i < count32b; i++, src += 4) { USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src); } } return HAL_OK;}what this function will do if parameter 'dma' is not equals to 0? I mean, if DMA is meant to be used, how and when data will be written to FIFO? How data is extracted from FIFO if reading function using same approach (Note: commented documentation says about parameter 'dma' but obviously its not even mentioned in function proto; same with ch_ep_num - this function reas from DFIFO0 only!):
/**
* @brief USB_ReadPacket : read a packet from the Tx FIFO associated * with the EP/channel * @param USBx : Selected device * @param src : source pointer * @param ch_ep_num : endpoint or host channel number * @param len : Number of bytes to read * @param dma: USB dma enabled or disabled * This parameter can be one of these values: * 0 : DMA feature not used * 1 : DMA feature used * @retval pointer to destination buffer */void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len){ uint32_t i=0; uint32_t count32b = (len + 3) / 4; for ( i = 0; i < count32b; i++, dest += 4 ) { *(__packed uint32_t *)dest = USBx_DFIFO(0); } return ((void *)dest);}Could someone clarify exactly how DMA USB is working? Does it work at all? RM says that registers
DIEPDMA
x andDOEPDMA
x are 'only to USB OTG HS
'. Can FS work with DMA or only by crude copiing, or what?My wild guess is: to transfer data between DFIFO and application I should use DMA mem-to-mem function, am I right?2017-12-07 10:25 AM
ok, here I am to give an answer to myself:
1) USB FS in STM32F746 can't use DMA. DMA is available only for HS core there.
2) Amounts of data to be moved are not so large, maximum 64 bytes for FS, so there is a tradeoff between CPU involvement and DMA initialization overhead: is design can guarantee that this particular channel/stream will be used ONLY for THIS transfers, it can be initialized only once and then you need only to 'ignite' transfers from time to time. So mem-2-mem transfers could possible increase efficiency, but only a little, and only with careful design.
Currently i'm using simplest approach: CPU transfers in basic loops. Its just works.