may be I can try to help you with more detailed code snippet informations about initializing the dma and the endpoints. The uart initialization would be also interesting.
Hi Lumpi and thanks for offering your help.
Please see the code below: In short, 1 bulk EP out, 1 bulk EP in. (It's really the bulk loopback auto demo rigged to a physical loopback on UART)
AUTO DMA is set between EP 1 out and UART tx. This one works fine.
AUTO DMA is set between UART Rx and EP1 in. No transfer unless the DMA buffer is full.
[testing of return code removed for clarity]CyU3PMemSet((uint8_t *)&lUARTCfg, 0, sizeof(lUARTCfg));lUARTCfg.baudRate = CY_U3P_UART_BAUDRATE_115200;lUARTCfg.stopBit = CY_U3P_UART_ONE_STOP_BIT;lUARTCfg.parity = CY_U3P_UART_NO_PARITY;lUARTCfg.txEnable = CyTrue;lUARTCfg.rxEnable = CyTrue;lUARTCfg.flowCtrl = CyFalse;lUARTCfg.isDma = CyTrue;lRetStatus = CyU3PUartInit();lRetStatus = CyU3PUartSetConfig(&lUARTCfg, (CyU3PUartIntrCb_t)0);lRetStatus = CyU3PUartTxSetBlockXfer(0xFFFFFFFFU);lRetStatus = CyU3PUartRxSetBlockXfer(0xFFFFFFFFU);...lSize = 512;CyU3PMemSet((uint8_t *)&lEPCfg, 0, sizeof(lEPCfg));lEPCfg.enable = CyTrue;lEPCfg.epType = CY_U3P_USB_EP_BULK;lEPCfg.burstLen = 1;lEPCfg.streams = 0;lEPCfg.pcktSize = lSize;
/* Endpoints configuration. */lRetStatus = CyU3PSetEpConfig(CY_FX_EP_PRODUCER, &lEPCfg);lRetStatus = CyU3PSetEpConfig(CY_FX_EP_CONSUMER, &lEPCfg);/* Create a DMA Auto Channel between two sockets of the U port.* DMA size is set based on the USB speed.*/lDMACfg.size = lSize;lDMACfg.count = PT_FX3_U3V_DMA_BUF_CNT;lDMACfg.prodSckId = CY_FX_EP_PRODUCER_SOCKET;lDMACfg.consSckId = CY_U3P_LPP_SOCKET_UART_CONS;lDMACfg.dmaMode = CY_U3P_DMA_MODE_BYTE;lDMACfg.notification = 0;lDMACfg.cb = (CyU3PDmaCallback_t)0;lDMACfg.prodHeader = 0;lDMACfg.prodFooter = 0;lDMACfg.consHeader = 0;lDMACfg.prodAvailCount = 0;
lRetStatus = CyU3PDmaChannelCreate(&sDMAChHandle,CY_U3P_DMA_TYPE_AUTO,&lDMACfg);/* Create a DMA Auto Channel between two sockets of the U port.* DMA size is set based on the USB speed.*/lDMACfg.size = 16; //lSize;lDMACfg.count = PT_FX3_U3V_DMA_BUF_CNT;lDMACfg.prodSckId = CY_U3P_LPP_SOCKET_UART_PROD;lDMACfg.consSckId = CY_FX_EP_CONSUMER_SOCKET;lRetStatus = CyU3PDmaChannelCreate(&sDMAChHandle,CY_U3P_DMA_TYPE_AUTO,&lDMACfg);/* Flush the Endpoint memory. */CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);
/* Set DMA Channel transfer size. */lRetStatus = CyU3PDmaChannelSetXfer(&sDMAChHandle, 0);lRetStatus = CyU3PDmaChannelSetXfer(&sDMAChHandle, 0);So everything looks fine when sending small packets on the endpoint. I see as few chars on the terminal as was sent from the control center.On the opposite direction, I need to send lDMACfg.size bytes for them to be able to get anything on the IN endpoint (Otherwise I get error: BULK IN transfer failed with Error Code:997)Please let me know if you require further details.Martin
I am not sure but I think I have heard about DMA receive data has to be a multiple of 4 bytes till DMA events occur. May be you try using a manual DMA buffer and then check these events. The dma buffer size of an USB endpoint should be 64 bytes for full speed, 512 bytes for high speed and 1024 bytes for super speed. You are using 16 bytes in the receive case. Have you changed this?
An other solution would be using UART in byte by byte mode instead of DMA mode. And then setup your USB endpoints as manual channels with....
CY_U3P_CPU_SOCKET_CONS = 0x3F00, /* Socket through which the FX3 CPU receives data. */
CY_U3P_CPU_SOCKET_PROD /* Socket through which the FX3 CPU produces data. */
that can work, but first try the UartReveice function if it returns after receiving expected byte count. If that also not works, it is possible that there is a restriction in the FX3 that UartReceive won't work if it reveices lesser than e. g. 4 or 16 bytes. That can be may be post a question with respect to the UartReceive and restrictions.
in the FX3 SDK release notes is a chapter with known issues and solutions with a descritpion to your issue...
7. Any UART/I2C/SPI read transfers in DMA mode that do not fill up the entire DMA buffer will
not trigger a DMA callback or a transfer complete event. The application needs to check for
transfer completion based on the UART/I2C/SPI events and then invoke the
CyU3PDmaChannelSetWrapUp() API on the DMA channel.