2 Replies Latest reply on Dec 8, 2014 4:00 AM by zhao.enny

    when more than one  CyU3PDmaChannelSetXfer ,how do they work?

    zhao.enny

      In FX3APIGuide.pdf, the explanation of CyU3PDmaChannelSetXfer is: Set a transfer on the DMA channel.The function starts a transaction the selected DMA channel. It should be invoked only when the channel is in CY_U3P_DMA_CONFIGURED state.

         

      From the explanation CyU3PDmaChannelSetXfer starts data transaction,when  use the function  more then one time ,how do they work,For exzample:

         
          void   
         
          CyFxSlFifoApplnStart (   
         
                  void)   
         
          {   
         
              uint16_t size = 0;   
         
              CyU3PEpConfig_t epCfg;   
         
              CyU3PDmaChannelConfig_t dmaCfg;   
         
              CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;   
         
              CyU3PUSBSpeed_t usbSpeed = CyU3PUsbGetSpeed();   
         
              
         
              /* First identify the usb speed. Once that is identified,   
         
               * create a DMA channel and start the transfer on this. */   
         
              
         
              /* Based on the Bus Speed configure the endpoint packet size */   
         
              switch (usbSpeed)   
         
              {   
         
                  case CY_U3P_FULL_SPEED:   
         
                      size = 64;   
         
                      break;   
         
              
         
                  case CY_U3P_HIGH_SPEED:   
         
                      size = 512;   
         
                      break;   
         
              
         
                  case  CY_U3P_SUPER_SPEED:   
         
                      size = 1024;   
         
                      break;   
         
              
         
                  default:   
         
                      CyFxAppErrorHandler (CY_U3P_ERROR_FAILURE);   
         
                      break;   
         
              }   
         
              
         
              CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));   
         
              epCfg.enable = CyTrue;   
         
              epCfg.epType = CY_U3P_USB_EP_BULK;   
         
              epCfg.burstLen = (usbSpeed == CY_U3P_SUPER_SPEED) ? (CY_FX_EP_BURST_LENGTH) : 1;   
         
              epCfg.streams = 0;   
         
              epCfg.pcktSize = size;   
         
              
         
              /* Producer endpoint configuration */   
         
              apiRetStatus = CyU3PSetEpConfig(CY_FX_EP_PRODUCER, &epCfg);   
         
              if (apiRetStatus != CY_U3P_SUCCESS)   
         
              {   
         
                  CyFxAppErrorHandler (apiRetStatus);   
         
              }   
         
              
         
              /* Consumer endpoint configuration */   
         
              apiRetStatus = CyU3PSetEpConfig(CY_FX_EP_CONSUMER, &epCfg);   
         
              if (apiRetStatus != CY_U3P_SUCCESS)   
         
              {   
         
                  CyFxAppErrorHandler (apiRetStatus);   
         
              }   
         
              
         
              /* Create a DMA MANUAL channel for U2P transfer.   
         
               * DMA size is set based on the USB speed. */   
         
              dmaCfg.size  = (usbSpeed == CY_U3P_SUPER_SPEED) ? (CY_FX_EP_BURST_LENGTH*size) : size;   
         
              dmaCfg.count = CY_FX_SLFIFO_DMA_BUF_COUNT;   
         
              dmaCfg.prodSckId = CY_FX_PRODUCER_USB_SOCKET;   
         
              dmaCfg.consSckId = CY_FX_CONSUMER_PPORT_SOCKET;   
         
              dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;   
         
              /* Enabling the callback for produce event. */   
         
              dmaCfg.notification = 0;   
         
              dmaCfg.cb = NULL;   
         
              dmaCfg.prodHeader = 0;   
         
              dmaCfg.prodFooter = 0;   
         
              dmaCfg.consHeader = 0;   
         
              dmaCfg.prodAvailCount = 0;   
         
              
         
              apiRetStatus = CyU3PDmaChannelCreate (&glChHandleSlFifoUtoP,   
         
                  CY_U3P_DMA_TYPE_AUTO, &dmaCfg);   
         
              if (apiRetStatus != CY_U3P_SUCCESS)   
         
              {   
         
                  CyFxAppErrorHandler(apiRetStatus);   
         
              }   
         
              
         
              /* Create a DMA MANUAL channel for P2U transfer. */   
         
              dmaCfg.prodSckId = CY_FX_PRODUCER_PPORT_SOCKET;   
         
              dmaCfg.consSckId = CY_FX_CONSUMER_USB_SOCKET;   
         
              dmaCfg.cb = NULL;   
         
              apiRetStatus = CyU3PDmaChannelCreate (&glChHandleSlFifoPtoU,   
         
                  CY_U3P_DMA_TYPE_AUTO, &dmaCfg);   
         
              if (apiRetStatus != CY_U3P_SUCCESS)   
         
              {   
         
                  CyFxAppErrorHandler(apiRetStatus);   
         
              }   
         
              
         
              /* Flush the Endpoint memory */   
         
              CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);   
         
              CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);   
         
              
         
              /* Set DMA channel transfer size. */   
         
              apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleSlFifoUtoP, CY_FX_SLFIFO_DMA_TX_SIZE);   
         
              if (apiRetStatus != CY_U3P_SUCCESS)   
         
              {   
         
                  CyFxAppErrorHandler(apiRetStatus);   
         
              }   
         
                  apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleSlFifoPtoU, CY_FX_SLFIFO_DMA_TX_SIZE);     // line a   
         
              if (apiRetStatus != CY_U3P_SUCCESS)   
         
              {   
         
                  CyFxAppErrorHandler(apiRetStatus);   
         
              }   
         
              
         
              /* Update the status flag. */   
         
              glIsApplnActive = CyTrue;   
         
          }   
         
              
         
              
         
          
           CyFxSlFifoApplnUSBSetupCB (    
          
                   uint32_t setupdat0,    
          
                   uint32_t setupdat1    
          
               )    
          
           {    
          
               uint8_t  bRequest, bType;    
          
               uint16_t readCount = 0;    
          
               CyU3PReturnStatus_t status = CY_U3P_SUCCESS;    
          
                
          
               /* Decode the fields from the setup request. */    
          
               bType    = (setupdat0 & CY_U3P_USB_TYPE_MASK);    
          
               bRequest = ((setupdat0 & CY_U3P_USB_REQUEST_MASK) >> CY_U3P_USB_REQUEST_POS);    
          
                
          
               if (bType != CY_U3P_USB_CLASS_RQT)    
          
               {    
          
                   return CyFalse;    
          
               }    
          
                
          
               /* UART Specific Requests */    
          
               if (bRequest == CY_FX_USB_UART_GET_CUR_REQ)    
          
               {    
          
                   /* Host requests data. Send it over EP0. */    
          
                   if (glUartRxp == 0)    
          
                   {    
          
                        glUartRxBuffer[0]=0;    
          
                        glUartRxp=1;    
          
                   }    
          
                   status = CyU3PUsbSendEP0Data(glUartRxp, glUartRxBuffer);    
          
                   glUartRxp = 0;    
          
               }    
          
               else if (bRequest == CY_FX_USB_UART_SET_CUR_REQ)    
          
               {    
          
                   /* Get the UART data from EP0 */    
          
                   status = CyU3PUsbGetEP0Data (CY_FX_UART_MAX_BUFFER_SIZE, glUartTxBuffer, &readCount);    
          
                   if (status == CY_U3P_SUCCESS)    
          
                   {    
          
                        if(glUartTxBuffer[0]==1)    
          
                        {    
          
                          CyU3PDmaChannelReset(&glChHandleSlFifoPtoU);    
          
                        CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);    
          
                        }    
          
                       if(glUartTxBuffer[0]==0)    
          
                    CyU3PDmaChannelSetXfer (&glChHandleSlFifoPtoU, CY_FX_SLFIFO_DMA_TX_SIZE);      //line b    
          
                       /* Check status and actual count transferred */    
          
                       if (status != CY_U3P_SUCCESS)    
          
                       {    
          
                           /* Error handling */    
          
                           //CyFxAppErrorHandler(apiRetStatus);    
          
                       }    
          
                   }    
          
               }    
          
               else    
          
               {    
          
                   /* Mark with some error. */    
          
                   status = CY_U3P_ERROR_FAILURE;    
          
               }    
          
                
          
               if (status != CY_U3P_SUCCESS)    
          
               {    
          
                   return CyFalse;    
          
               }    
          
                
          
               return CyTrue;    
          
           }    
         
         
              
         
          For my understand,line a Set DMA channel transfer size and start data transaction, i donot konwn how line b works,from data test,line b works ,how to understand this,thanks for your help.   
        • 1. Re: when more than one  CyU3PDmaChannelSetXfer ,how do they work?
          shashank.rebbapragada

           Hello,

             

           

             

          You cannot call the CyU3PDmaChannelSetXfer() twice unless the channel has been reset in between.

             

          I think what is happening in this code is that the channel is first getting reset (check the CyU3PDmaChannelReset() call).

             

          And then it is being started again using the SetXfer() call.

             

          Where did you get this piece of code from? Can you share the whole project?

             

           

             

          Regards

             

          Shashank

          • 2. Re: when more than one  CyU3PDmaChannelSetXfer ,how do they work?
            zhao.enny
                 Shashank   
               
                    Thanks for your answer very much,I'm so sorry for reply you so late.the attachment is the all project.According to your reply,the project may crush in some time.If the value of glUartTxBuffer[0] donot be set '1',the CyU3PDmaChannelReset(&glChHandleSlFifoPtoU) and CyU3PUsbFlushEp(CY_FX_EP_PRODUCER) will not be called.Now,if glUartTxBuffer[0] get value '0', the CyU3PDmaChannelSetXfer called twice,then the system will crush,is it right? Sorry for reply you late again.    
               
                    Regards   
               
                        Enny