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.

EK-TM4C123GXL: TM4C123GH6PM some UART DMA problems

Part Number: EK-TM4C123GXL
Other Parts Discussed in Thread: ENERGIA

Hi everyone

I'm using Energia IDE (version 0101E0017) and my tivaware revision is 2.0.1.11577. I know they are pretty old versions, but they worked fine for the past. Yet, recently I use the UART DMA and found it doesn't work functionally. Hope you guys could help me with these:

1. I can't use UART7 DMA to transmit data to another tm4c123gxl launchpad, no byte was received, but when using UART0 DMA, the correct amount of data could be transferred to my laptop. Here is my code. The first part is UART0 DMA which works fine, the second part is UART7 DMA which does not work, and the third part is the reception part which uploaded to another launchpad.

// using uart0 dma in basic mode, data can be transmitted.

#include <stdint.h>
#include <stdbool.h>
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/udma.h"
#include "inc/hw_uart.h"

#define TX_BUFFER_SIZE  256
byte txBuffer[TX_BUFFER_SIZE];

// uDMA control table aligned to 1024-byte boundary
#pragma DATA_ALIGN(controlTable, 1024);
uint8_t controlTable[1024];

void setup()
{
  SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);  // 80MHz
  
  for(uint32_t ui32Idx = 0; ui32Idx < TX_BUFFER_SIZE; ui32Idx++)
  {    
    txBuffer[ui32Idx] = 65;  // 'A'
  }
    
  UARTConfiguration();
  UDMAConfiguration();
}

void UARTConfiguration()
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  //SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);
  
  GPIOPinConfigure(GPIO_PA0_U0RX);
  GPIOPinConfigure(GPIO_PA1_U0TX);

  GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

  UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);

  UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
  
  UARTIntEnable(UART0_BASE, UART_INT_TX | UART_INT_RX);  
  
  UARTEnable(UART0_BASE);  
  
  UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
}

void UDMAConfiguration()
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
  //SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
  
  uDMAEnable();
  uDMAControlBaseSet(&controlTable[0]);
  
  uDMAChannelAssign(UDMA_CH9_UART0TX);

  uDMAChannelAttributeDisable(UDMA_CH9_UART0TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);

  uDMAChannelAttributeEnable(UDMA_CH9_UART0TX, UDMA_ATTR_USEBURST);

  uDMAChannelControlSet(UDMA_CH9_UART0TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);

  uDMAChannelTransferSet(UDMA_CH9_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, txBuffer, (void *)(UART0_BASE + UART_O_DR), sizeof(txBuffer));
  
  uDMAChannelEnable(UDMA_CH9_UART0TX);
}

void loop(){}




// using uart7 dma in basic mode, no data be transmitted.

#include <stdint.h>
#include <stdbool.h>
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/udma.h"
#include "inc/hw_uart.h"

#define TX_BUFFER_SIZE  256
byte txBuffer[TX_BUFFER_SIZE];

// uDMA control table aligned to 1024-byte boundary
#pragma DATA_ALIGN(controlTable, 1024);
uint8_t controlTable[1024];

void setup()
{
  SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);  // 80MHz
  
  for(uint32_t ui32Idx = 0; ui32Idx < TX_BUFFER_SIZE; ui32Idx++)
  {    
    txBuffer[ui32Idx] = 65;  // 'A'
  }
    
  UARTConfiguration();
  UDMAConfiguration();
}

void UARTConfiguration()
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UART7);
  //SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART7);
  
  GPIOPinConfigure(GPIO_PE0_U7RX);
  GPIOPinConfigure(GPIO_PE1_U7TX);

  GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1);

  UARTConfigSetExpClk(UART7_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);

  UARTFIFOLevelSet(UART7_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
  
  UARTIntEnable(UART7_BASE, UART_INT_TX | UART_INT_RX);  
  
  UARTEnable(UART7_BASE);  
  
  UARTDMAEnable(UART7_BASE, UART_DMA_RX | UART_DMA_TX);
}

void UDMAConfiguration()
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
  //SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
  
  uDMAEnable();
  uDMAControlBaseSet(&controlTable[0]);
  
  uDMAChannelAssign(UDMA_CH21_UART7TX);

  uDMAChannelAttributeDisable(UDMA_CH21_UART7TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);

  uDMAChannelAttributeEnable(UDMA_CH21_UART7TX, UDMA_ATTR_USEBURST);

  uDMAChannelControlSet(UDMA_CH21_UART7TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);

  uDMAChannelTransferSet(UDMA_CH21_UART7TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, txBuffer, (void *)(UART7_BASE + UART_O_DR), sizeof(txBuffer));
  
  uDMAChannelEnable(UDMA_CH21_UART7TX);
}

void loop(){}


// this part is for another launchpad to receive data from uart7, then send the data to laptop through uart0
void setup() { Serial.begin(115200); Serial7.begin(115200); Serial7.setBufferSize(8192, 8192); } void loop() { if (Serial7.available() > 0) { char ch = Serial7.read(); Serial.write(ch); } }

2. As mentioned in problem 1, even the correct amount of data could be transferred to laptop, but sometime the data bytes are garbled (shown in the picture).

The garbled data pattern is always 12 bytes and the bytes would not change their value or position. So I did some tests with basic mode and ping-pong mode, below shows the ping-pong mode code.

// ping pong mode for uart data sending

#include <stdint.h> #include <stdbool.h> #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "inc/hw_uart.h" #define PINGPONG_BUFFER_SIZE 128 byte pingBuffer[PINGPONG_BUFFER_SIZE]; byte pongBuffer[PINGPONG_BUFFER_SIZE]; // uDMA control table aligned to 1024-byte boundary #pragma DATA_ALIGN(controlTable, 1024); uint8_t controlTable[1024]; void setup() { SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // 80MHz for(uint16_t i = 0; i < PINGPONG_BUFFER_SIZE; i++) { pingBuffer[i] = 65; // 'A' pongBuffer[i] = 66; // 'B' } UARTConfiguration(); UDMAConfiguration(); } void UARTConfiguration() { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); //SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8); UARTIntRegister(UART0_BASE, UART0IntHandler); UARTIntEnable(UART0_BASE, UART_INT_TX | UART_INT_RX); UARTEnable(UART0_BASE); UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX); } void UDMAConfiguration() { SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); //SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA); uDMAEnable(); uDMAControlBaseSet(&controlTable[0]); uDMAChannelAssign(UDMA_CH9_UART0TX); uDMAChannelAttributeDisable(UDMA_CH9_UART0TX, UDMA_ATTR_ALL); uDMAChannelControlSet(UDMA_CH9_UART0TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); uDMAChannelControlSet(UDMA_CH9_UART0TX | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); uDMAChannelTransferSet(UDMA_CH9_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, pingBuffer, (void *)(UART0_BASE + UART_O_DR), sizeof(pingBuffer)); uDMAChannelTransferSet(UDMA_CH9_UART0TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, pongBuffer, (void *)(UART0_BASE + UART_O_DR), sizeof(pongBuffer)); uDMAChannelEnable(UDMA_CH9_UART0TX); } void UART0IntHandler() { uint32_t DMAMode; UARTIntClear(UART0_BASE, UART_INT_TX | UART_INT_RX); DMAMode = uDMAChannelModeGet(UDMA_CH9_UART0TX | UDMA_PRI_SELECT); if(DMAMode == UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CH9_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, pingBuffer, (void *)(UART0_BASE + UART_O_DR), sizeof(pingBuffer)); } DMAMode = uDMAChannelModeGet(UDMA_CH9_UART0TX | UDMA_ALT_SELECT); if(DMAMode == UDMA_MODE_STOP) { uDMAChannelTransferSet(UDMA_CH9_UART0TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, pongBuffer, (void *)(UART0_BASE + UART_O_DR), sizeof(pongBuffer)); } } void loop(){}

In two modes by changing the value of PINGPONG_BUFFER_SIZE and TX_BUFFER_SIZE respectively, results are shown below.

buffer size basic mode (txBuffer) position ping pong mode (ping buffer) position ping pong mode (pong buffer) position
128 X (all 0x65) X X (all 0x65) X X (all 0x66) X
256 O 0x88~0x93 X (all 0x65) X O 0x87~0x92
512 O 0x88~0x93 X (all 0x65) X X (all 0x66) X
1024 X (all 0x65) X X (all 0x65) X X (all 0x66) X

In basic mode, I found that garbled data seems to appear at same position, so I reduce txBuffer size to 128 bytes, since 128 is smaller than 136 (0x88), garbled data should not appear. As expected, those data did not show up, nor they did not appear when txBuffer size is set to 1024. So strange!

Similar situation happened in ping pong mode...

Thank you for your time of reading this, I sincerely hope anyone of you could help to explain about the strange bytes, how could it happen, how to fix this, and why UART7 DMA does not work.

  • Hello,

    There are two problems presented here, so let's first tackle the no byte transfer issue as if we get it working, it may help provide further clues as to what is going on with Problem 2.

    user5286691 said:
    1. I can't use UART7 DMA to transmit data to another tm4c123gxl launchpad, no byte was received, but when using UART0 DMA, the correct amount of data could be transferred to my laptop. Here is my code. The first part is UART0 DMA which works fine, the second part is UART7 DMA which does not work, and the third part is the reception part which uploaded to another launchpad.

    Have you been able to transfer UART0 DMA data between LaunchPad's? This is the first thing I would try.

    Right now we know:

    UART0 -> Laptop (OK)

    UART7 -> LaunchPad (FAIL)

    If we can confirm that UART0 -> LaunchPad is okay too, then we know the issue is with UART7 setup.

    However if you cannot get data to transfer between the LaunchPads with the known working UART0 configuration, then we have isolated the problem so your receiving LaunchPad.

    Another thing to check if you can would be the UART lines via scope or logic state analyzer in order to ascertain if there are bytes even being output.

  • Hi, Ralph Jacobi

    Thank for your rapid reply.

    I want to apologize for wasting your time on my first issue which is caused by wiring error.

    I connected PE0 (rx) to PE0, and PE1 (tx) to PE1, ha ha that's embarrassing!

    The first issue is solved, but the second remains.

    As usual, I did some tests. Results are shown below.

    BASIC MODE

    uart7 uart0
    128 X X
    256 X O
    512 O O
    1024 X X

    PING PONG MODE (uart7 tx)

    uart7 ping uart7 pong uart0 ping uart0 pong
    128 X X O (previous record shows no abnormality, probably I didn't notice that.) X
    256 O X X O
    512 X X X X
    1024 X X X X

    The amount of the garbled bytes is still 12 bytes.

    I still don't have any clue about this, hope someone could provide some information.

    Thank again for your help!

  • Hi,

    No worries about the wiring mishap, happens to all of us :)

    Regarding the 12 garbage bytes issue, I don't have an immediate suggestion based on what you've shown so far. As you are using LaunchPad's, could you provide me the CCS project for the UART transmit to UART0 so I can test it on my end? I presume that if using a UART terminal software, I will be able to see the garbage bytes on the PC terminal without needing the 2nd LaunchPad that uses Energia, correct?

    If I can re-create it on my end, then it will be easier for me to quickly debug and offer a solution.
  • Hello,

    Is this still an open issue for you? Are you able to share a CCS project so I can test the corrupt byte behavior on my end?
  • uart_dma.7zHi,

    Because I use Energia for both of lauchpads, maybe I can't provide you any CCS project at this time.

    I'm trying to execute those code on CCS, but not yet succeed (I didn't use CCS to create any project before).

    If it is okay, I would provide the Energia project first despite it might be useless.

    Please let me know is there any other information I could provide.

    Thank you, I'll reply as soon as I can.

  • Hello,

    I see, I am not sure how Energia interfaces with TivaWare, I had thought you were using TivaWare for one and Energia for the other.

    You may want to ask on the Energia forums if anyone has had issues like what you are observing: forum.43oh.com/.../

    If you get a CCS project with TivaWare working and still observe the same issue, please let me know.

    By the way for CCS Project creation, we always recommend starting from an existing TivaWare example as that will have the right basic project settings and initial links to TivaWare resources which you can then expand on for your application.
  • Hello,

    I don't see any discussion related to DMA on that forum, that's why I post the issue here.

    The CCS project with same configuration has been created today.

    Everything is fine, whatever in basic mode or in ping pong mode.

    This issue seems might not happen when choosing the CCS IDE to program.

    Thank for your suggestion.