1 Reply Latest reply on Oct 15, 2012 5:30 AM by rama.sai.krishna.vakkantula

    FX3 UART DMA mode.

    gary.altenberg

      Hello,

         

      I have been trying to get the UART to work in DMA mode. What I would like to do is receive a USB packet with some data that I that is to be sent out using the UART and also send any data received by the UART back to the computer over USB. I am able to do this using the byte by byte mode but it requires the use of a thread to continuosly look for received data and put it in a buffer to be sent back to the computer over USB. I seems like this would be a perfect use for the UART DMA mode. I can not find any examples that show how to do this besides the one that shows how to do a loopback. For that there is only one DMA channel created but I think I need to channels one for sending and one for receiveing. Is this correct?

         

       

         

      Here is some code that I wrote to initialize the UART and create the a send and receive DMA channel. Does this look correct.

         

       

         

      CyU3PReturnStatus_t SerialInit(void)
      {
          CyU3PUartConfig_t uartConfig;
          CyU3PReturnStatus_t apiRetStatus;
          CyU3PDmaChannelConfig_t dmaConfig;
         

          // Initialize the UART.
          apiRetStatus = CyU3PUartInit();
          if (apiRetStatus != CY_U3P_SUCCESS && apiRetStatus != CY_U3P_ERROR_ALREADY_STARTED)
              return apiRetStatus;

          // Set UART configuration
          CyU3PMemSet ((uint8_t *)&uartConfig, 0, sizeof (uartConfig));
          uartConfig.baudRate = CY_U3P_UART_BAUDRATE_9600;
          uartConfig.stopBit = CY_U3P_UART_ONE_STOP_BIT;
          uartConfig.parity = CY_U3P_UART_NO_PARITY;   
          uartConfig.txEnable = CyTrue;
          uartConfig.rxEnable = CyTrue;
          uartConfig.flowCtrl = CyFalse;
          uartConfig.isDma = CyTrue;

          apiRetStatus = CyU3PUartSetConfig (&uartConfig, NULL);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;
        
          // Initialize the dmaConfig.
          CyU3PMemSet ((uint8_t *)&dmaConfig, 0, sizeof(dmaConfig));
          dmaConfig.size = CY_FX_UART_DMA_BUF_SIZE;
          dmaConfig.count = 1;
          dmaConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
          dmaConfig.prodHeader = 0;
          dmaConfig.prodFooter = 0;
          dmaConfig.consHeader = 0;
          dmaConfig.prodAvailCount = 0;

          // Create a channel to write to the UART.
          dmaConfig.prodSckId = CY_U3P_CPU_SOCKET_PROD;
          dmaConfig.consSckId = CY_U3P_LPP_SOCKET_UART_CONS;
          dmaConfig.notification = 0;
          dmaConfig.cb = NULL;
          apiRetStatus = CyU3PDmaChannelCreate (&glUartTxChHandle, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaConfig);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;

          // Create a channel to read from the UART.
          dmaConfig.prodSckId = CY_U3P_LPP_SOCKET_UART_PROD;
          dmaConfig.consSckId = CY_U3P_CPU_SOCKET_CONS;
          dmaConfig.notification = CY_U3P_DMA_CB_PROD_EVENT;
          dmaConfig.cb = CyFxUartDmaCallback;
          apiRetStatus = CyU3PDmaChannelCreate (&glUartRxChHandle, CY_U3P_DMA_TYPE_MANUAL_IN, &dmaConfig);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;

          // Set UART Tx transfer Size to infinite
          apiRetStatus = CyU3PUartTxSetBlockXfer(0xffffffff);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;

          // Set UART Rx transfer Size to 1
          apiRetStatus = CyU3PUartRxSetBlockXfer(0xFFFFFFFF);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;

          // Set DMA Channel transfer size
          apiRetStatus = CyU3PDmaChannelSetXfer (&glUartTxChHandle, CY_FX_UART_DMA_TX_SIZE);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;

          return apiRetStatus;
      }
       

         

      Here is some code that send data to the UART to be transmitted. When I do this no data goes out the UART. What am I doing wrong?

         

      CyU3PReturnStatus_t SendUART(uint8_t *buffer, int Length)
      {
          CyU3PReturnStatus_t apiRetStatus;
          CyU3PDmaBuffer_t dmaFw2UARTBuffer;
         
          // Get an out buffer.
          apiRetStatus = CyU3PDmaChannelGetBuffer(&glUartTxChHandle, &dmaFw2UARTBuffer, CYU3P_WAIT_FOREVER);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;

          CyU3PMemCopy(dmaFw2UARTBuffer.buffer, buffer, Length);

          apiRetStatus = CyU3PDmaChannelCommitBuffer (&glUartTxChHandle, Length, 0);
          if (apiRetStatus != CY_U3P_SUCCESS)
              return apiRetStatus;
             
          return apiRetStatus;
      }
       

         

      Thank you,

         

      Garyio