3 Replies Latest reply on Aug 16, 2016 12:51 AM by user_488319578

    DMA Channels Dynamic Reconnection

    user_488319578

      Dear Cypress,

         

      could you explain how to correctly perform dma channels reconnection on Cypress FX3?

      I want to switch between to producers on event (external GPIO interrupt). For this I have one Consumer (USB BULK IN) and two Producers (CPU with CY_U3P_DMA_TYPE_MANUAL_OUT,and PIB with CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE) which should be switched. For this I have the following code:

         

      //Customising CPU->USB EP_IN DMA Management
      CyU3PMemSet ((uint8_t *)&dma5, 0, sizeof (dma5));
      dma5.size =size;
      dma5.count = 1;
      dma5.dmaMode = CY_U3P_DMA_MODE_BYTE;
      dma5.notification =CY_U3P_DMA_CB_CONS_EVENT;
      dma5.cb = NULL;
      dma5.prodHeader = 0;
      dma5.prodFooter = 0;
      dma5.consHeader = 0;
      dma5.prodAvailCount = 0;
      dma5.prodSckId = CY_U3P_CPU_SOCKET_PROD;
      dma5.consSckId = CY_FX_EP_CONSUMER_SOCKET;

         

      //Customising PIB->USB EP_IN DMA Management
      CyU3PMemSet ((uint8_t *)&dma1, 0, sizeof (dma1));
      dma1.size = (usbSpeed == CY_U3P_SUPER_SPEED) ?
      (size * CY_FX_EP_BURST_LENGTH ) : (size);
      dma1.size = (size * CY_FX_EP_BURST_LENGTH );
      dma1.count = CY_FX_BULKSRCSINK_DMA_BUF_COUNT;
      dma1.validSckCount = 2;
      dma1.dmaMode = CY_U3P_DMA_MODE_BYTE;
      dma1.notification = 0;
      dma1.cb = 0;
      dma1.prodHeader = 0;
      dma1.prodFooter = 0;
      dma1.consHeader = 0;
      dma1.prodAvailCount = 0;
      dma1.prodSckId[0] = CY_U3P_PIB_SOCKET_0;
      dma1.prodSckId[1] = CY_U3P_PIB_SOCKET_1;
      dma1.consSckId[0] = CY_FX_EP_CONSUMER_SOCKET;

         

      For dma initialization I do next:

         

      //To enable DMA5?
      apiRetStatus = CyU3PDmaChannelCreate(&glChHandleCPUtoUsb2, CY_U3P_DMA_TYPE_MANUAL_OUT, &dma5);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
      CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
      CyFxAppErrorHandler(apiRetStatus);
      }

         

      // Set DMA Channel transfer size
      apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleCPUtoUsb2, 0);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
      CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
      CyFxAppErrorHandler(apiRetStatus);
      }

         

      //To enable DMA1?
      apiRetStatus = CyU3PDmaMultiChannelCreate(&glChHandleBulkSrc, CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE, &dma1);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
      CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
      CyFxAppErrorHandler(apiRetStatus);
      }

         


      apiRetStatus = CyU3PDmaMultiChannelSetXfer (&glChHandleBulkSrc, CY_FX_BULKSRCSINK_DMA_TX_SIZE,0);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
      CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer failed, Error code = %d\n", apiRetStatus);
      CyFxAppErrorHandler(apiRetStatus);
      }

         

       

         

      Separately it works. How to dynamically reconnect channels for example to switch off glChHandleBulkSrc and switch on glChHandleCPUtoUsb2? Should I use CyU3PDmaMultiChannelDestroy or any other function?

         

       

         

      Thank you!