Cypress Perform

Home > Design Support > Cypress Developer CommunityTM > Cypress Forums > USB Controllers > Need buffer full to DMA to USB EP IN?

Bookmark and Share
Cypress Developer CommunityTM
Forums | Videos | Blogs | Training | Rewards Program | Community Components



Need buffer full to DMA to USB EP IN?
Moderator:
RSKV

Post Reply
Follow this topic



Need buffer full to DMA to USB EP IN?

mgaron posted on 14 Nov 2012 1:34 PM PST
Member
3 Forum Posts

 Hi,

I am trying hard to understand the difference in the behavior between the bulk auto demo and one app where I set an auto dma between the uart rx and USB EP IN.

In the bulk auto demo, the bytes will be looped back onto the EP IN, no mather how few of them. No need to fill the DMA buffer before hitting the transfer data-IN button. There will be as many as sent, no padding (looked with some analyzer).

In the example I build, there is no way to get any bytes out of the EP before the DMA buffer is full. This seems to be the normal behavior when reading the doc, but I can not explain why the bulk loopback demo "seems" to be different.

My application is a simple DMA AUTO channel between UART (producer) and EP1 (consumer), 16-byte twin buffers (the smallest), infinite transfer, etc.

Any rational explanation for this behavior?

Thx for any help,

Martin




Re: Need buffer full to DMA to USB EP IN?

Lumpi6 posted on 15 Nov 2012 11:09 PM PST
Top Contributor
183 Forum Posts

Hi mgaron,

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.

regards,

lumpi



Re: Need buffer full to DMA to USB EP IN?

mgaron posted on 15 Nov 2012 10:53 AM PST
Member
3 Forum Posts

 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[0],
    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[1],
    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], 0);
  lRetStatus = CyU3PDmaChannelSetXfer(&sDMAChHandle[1], 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
 

 

 

 



Re: Need buffer full to DMA to USB EP IN?

Lumpi6 posted on 16 Nov 2012 11:47 PM PST
Top Contributor
183 Forum Posts

Hi,

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.

regards

lumpi



Re: Need buffer full to DMA to USB EP IN?

Lumpi6 posted on 21 Nov 2012 01:10 AM PST
Top Contributor
183 Forum Posts

Hi,

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.

regards

lumpi






ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.