This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3200 UART DMA implementation

Other Parts Discussed in Thread: CC3200

Hi,

I am trying to configure the UART DMA for receiving data.

I referred the uart_dma code from sdk, but that code is only for DMATX and DMARX interrupts. So in that code, only DMA is going to trigger the handler. Hence, it doesn't check the DMA transfer complete flags on the handler.

But i want to get the DMA for receive while the Tx interrupt to transmit data.

I have configured the DMA receive as well as the Tx interrupt.

But my problem is, how to detect which interrupt has triggered my handler.

I tried to check the status of UART_INT_DMARX on the handler, but that didn't helped.

How should i detect the whether my DMA receive is completed or not??

Thank you in advance.

Regards,

Abhishek.

  • Hi Abhishek,


    We will look into this and get back to you.


    Regards,
    Aashish
  • Hi Aashish,
    Thank you very much.
    Awaiting your feedback.

    Regards,
    Abhishek.
  • Hi Abhishek,


    For DMARX you need to enable UART_INT_DMARX and for UART TX you need to enable UART_INT_TX. Also refer udma code DMA Rx. To get uart interrupt status use UARTIntStatus() API.



    Regards,
    Aashish
  • Hi Aashish,
    Thank you very much for replying.
    Actually the DMARX is defined as:-
    #define UART_INT_DMARX 0x10000 // DMA Rx Done interrupt Mask

    Can you please share some code for initializing DMARX and UART_TX interrupts and detecting them on the Interrupt_Handler ??

    Thanks and regards,
    Abhishek.

  • Hi Aashish,
    Any suggestions on this one ??

    Regards,
    Abhishek.
  • Hello,
    The uDMA causes a UART interrupt when a transfer has been complete, by using
    MAP_UARTIntEnable(PERIPHERAL_BASE_VALUE, UART_INT_DMARX);
    In order to understand better you want the uDMA controller to trigger an interrupt in other cases as well? Such as Receive interrupt (UART_INT_RX), or receive timeout interrupt (UART_INT_RT) ?
    This is what you want? I'm also in a similar situation and i'm a bit confused as i've been blown with information on CC3200 lately. Did you resolve your issues, if yes could you share? Because it could help.

    Regards,
    Nick.
  • Hi Nick91,
    That's exactly what i wanted to achieve, but i couldn't.
    In my case, i was continuously transmitting a large string of data, so using DMATX was not a problem.
    However, i was receiving very less data (about 4-5 bytes). So using DMARX was not a feasible option.
    So i wanted to configure Receive interrupt (UART_INT_RX) as well.

    But i was not able to do so.
  • Why not? Can't you just OR the interrupt flags? Like so UART_INT_RX | UART_INT_DMARX ? What is the issue?
  • Hi Nick,


    We are unable to understand exact issue you are facing. Please explain it in detail.


    Regards,
    Aashish
  • Hi,

    Let me explain you the problem that i faced.

    I was advised to refer the uart_dma example from the sdk.

    In this example, the code initializes the DMA and waits for the bRxDone flag to be true (polling!!).

    This bRxDone flag is set to true on the UARTIntHandler().

    Here, the DMA receive complete flag is not checked, rather the checking is based in the bRxDone flag.

    Now, i had designed a system which continuously sends and receives data. I wanted to set both receive and transmit operations on DMA, which i was unable to do. My problem is, i am not able to differentiate between the DMA_TX, DMA_RX and Receive TImeout interrupt once any of these interrupts occur.

  • So, to get my system going, i implemented the Tx and Rx interrupts and sent/received data byte-by-byte as:-

      gul32_TxInt_Type = MAP_UARTTxIntModeGet(CONSOLE);
      gul32_Int_Type = MAP_UARTIntStatus(CONSOLE, true);

      if((gul32_Int_Type & UART_INT_RX) && MAP_UARTCharsAvail(CONSOLE))
      {
        MAP_UARTIntClear(CONSOLE, UART_INT_RX);

        //Received data here in temporary buffer

        Temp_Received_Data[rpointer++] = (unsigned char)MAP_UARTCharGetNonBlocking(CONSOLE);

       }

      if(gul32_TxInt_Type & UART_TXINT_MODE_EOT)
      {
        MAP_UARTCharPut/*NonBlocking*/(CONSOLE,  Data_From_Temp_Buffer[wpointer++]);

      }

  • I tried a lot to understand the whole DMA working and implement it for both Tx and Rx, but couldn't get the DMA working.
    The above work-around is working as of now, but it would be really appreciated if i get it on DMA.
  • Hi Abhishek,

    I did a few modifications to "uart_dma" example and I could see the UART_INT_DMARX & UART_INT_DMATX status is getting reflected properly

    Code Snippet

    static void UARTIntHandler()
    {
        unsigned long ulIntStatus;
        
        /* Interrupt status */
        ulIntStatus = MAP_UARTIntStatus(UARTA0_BASE,false);
        
        /* Check if RX DMA is complete */
        if(ulIntStatus & UART_INT_DMARX )
        {
            /* Print message */
            Message("Rx DMA Done\r\n");
              
    	/* Disable UART RX DMA */
            MAP_UARTDMADisable(UARTA0_BASE,UART_DMA_RX);
    
        }
        
        /* Check if TX DMA is complete */
        if(ulIntStatus & UART_INT_DMATX )
        {
            /* Print message */
            Message("Tx DMA Done\r\n");
       
    	/* Disable UART TX DMA */
            MAP_UARTDMADisable(UARTA0_BASE,UART_DMA_TX);
        }
        
        /* Clear the UART Interrupt */
        MAP_UARTIntClear(UARTA0_BASE,ulIntStatus);
    
    }


    And a few modifications in main...

     Message("Type in 8 characters\r\n");
    
        //
        // Configure the UART Tx and Rx FIFO level to 1/8 i.e 2 characters
        //
        UARTFIFOLevelSet(UARTA0_BASE,UART_FIFO_TX1_8,UART_FIFO_RX1_8);
    
        //
        // Setup DMA transfer for UART A0
        //
        UDMASetupTransfer(UDMA_CH8_UARTA0_RX,
                          UDMA_MODE_BASIC,
                          8,
                          UDMA_SIZE_8,
                          UDMA_ARB_2,
                          (void *)(UARTA0_BASE+UART_O_DR),
                          UDMA_SRC_INC_NONE,
                          (void *)ucTextBuff,
                          UDMA_DST_INC_8);
    
        //
        // Setup DMA transfer for UART A0
        //
        UDMASetupTransfer(UDMA_CH9_UARTA0_TX,
                          UDMA_MODE_BASIC,
                          sizeof(ucTextBuff_tx),
                          UDMA_SIZE_8,
                          UDMA_ARB_2,
                          (void *)ucTextBuff_tx,
                          UDMA_SRC_INC_8,
                          (void *)(UARTA0_BASE+UART_O_DR),
                          UDMA_DST_INC_NONE);
    
        
        //
        // Enable Rx DMA request from UART
        //
        MAP_UARTDMAEnable(UARTA0_BASE,UART_DMA_RX|UART_DMA_TX);
    

    Thanks and Regards,

    Praveen

  • hi , why do you disable the DMARX interrupt after receiving the burst of data ?
    I want the DMA to send data to the buffer continuously not only 8 bytes , I tried not to disable the DMARX in the interrupt but only clearing it's flag , but this have leaded me to hang in the ISR.
    can you help me out solving this issue ?