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.

UART Transmission with DMA on MSP432

Hi!

I want to send data over UART with using the DMA Controller. Directly sending data over "UART_transmitData(EUSCI_A0_MODULE,sendData)" is working. Now I configured the DMA, but it doesn't work. I hope you can help me.

My global variables in a struct globalVar

uint8_t sendBufferUart[8];
uint8_t controlTable[1024];

Here is the code for configuration the dma:

    //DMA configuration
    DMA_enableModule();

    DMA_setControlBase(ptrGlobalVar->controlTable);

    DMA_assignChannel(DMA_CH0_EUSCIA0TX);

    DMA_disableChannelAttribute(DMA_CH0_EUSCIA0TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);

    DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);

    DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_EUSCIA0TX, UDMA_MODE_BASIC, ptrGlobalVar->sendBufferUart ,(void*) UART_getTransmitBufferAddressForDMA(EUSCI_A0_MODULE), 8);

DMA_assignInterrupt(DMA_INT0,0);

Here is the code for Change buffer and sending code:

	uint16_t time4MsStamp = globalVar.FourMsCounter + globalVar.OneSecCounter*250;


	//dma controller for sending data with less cpu using
	uint8_t *ptrBufferBeginning;
	ptrBufferBeginning = globalVar.sendBufferUart;

	ptrBufferBeginning[0] = 0xF0;	//first start byte
	ptrBufferBeginning[1] = 0x0F;   //second start byte
	ptrBufferBeginning[2] = time4MsStamp;
	ptrBufferBeginning[3] = time4MsStamp >> 8;
	ptrBufferBeginning[4] = globalVar.curADCresult;
	ptrBufferBeginning[5] = globalVar.curADCresult >>8;
	ptrBufferBeginning[6] = 0x00;
	ptrBufferBeginning[7] = 0xFF;

	DMA_enableChannel(DMA_CHANNEL_0);
	DMA_requestChannel(DMA_CHANNEL_0);

Best regards,

Emru

  • Hi Emru,

    DMA_INT0 is the logical OR of all completion events whereas DMA_INT1/2/3 can be mapped to the DMA completion event of any of the eight channels, therefore please use one of these instead. I do not see the line Interrupt_enableInterrupt(INT_DMA_INT1); or Interrupt_enableMaster(); which are required as well for using the DMA interrupt.  You shouldn't have to request the channel either, this should happen automatically given the start of a UART transfer. Some MSP432 DMA UART examples can be found in the following threads:


    e2e.ti.com/.../453931
    e2e.ti.com/.../425881

    Regards,
    Ryan

  • Hello Ryan,

    Thank you for your answer. The Interrupts are enabled in another part of the code. Interrupts like Timer and ADC are working. How can I give the Start of an UART Transfer?

    Regards,
    Emru
  • Hello Emru,

    Try manually setting the EUSCIA0 UART transmit interrupt flag. You still need to use DMA_INT1 and follow the example code provided.

    Regards,
    Ryan
  • I tried UART without interrupt.

    (1) without DMA

    void UART_send_text( char ascii[], int n )
    {
    int i;
    for( i=0 ; i<n ; i++ )
    {
    if( ascii[i] == 0 ) return;
    while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
    UCA0TXBUF = ascii[i];
    }
    }

    (2) with DMA
    void UART_send_text_dma( char ascii[], int n )
    {
    /* Assign DMA channel 0 to EUSCI_A0_TX0 */
    MAP_DMA_assignChannel(DMA_CH0_EUSCIA0TX);

    /* Setup the TX transfer characteristics & buffers */
    MAP_DMA_setChannelControl(DMA_CH0_EUSCIA0TX | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIA0TX | UDMA_PRI_SELECT,
    UDMA_MODE_BASIC, ascii,
    (void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_A0_BASE),
    n);

    MAP_DMA_enableChannel(0);
    }

    (3) main
    /* initialize */

    char ascii_data[] = "abcdefghijklmnop"; // ascii buffer
    UART_send_text( &ascii_data[0], 14 );
    UART_send_text_dma( &ascii_data[0], 14 );
    Both worked all right!

**Attention** This is a public forum