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 uDMA allways missing byte

Hey everyone!

I have one problem. In my part of code below, I enable UART timeout interrupt, then get first byte, depending from that byte value, enable different size uDMA. Its like everything okey, but then I check uDMA buffer, alllways first byte incorrect. Maybe you have some ideas why?

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_uart.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/udma.h"

#define UART_RXBUF_SIZE         8
static uint8_t g_pui8RxPing[UART_RXBUF_SIZE];

volatile uint8_t cThisChar = 0;
volatile uint8_t rx_start = 0;
volatile uint8_t rx_address = 0;

#pragma DATA_ALIGN(ucControlTable, 1024)
uint8_t ucControlTable[1024];

// Library error routine
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif

// UART interrupt handler. Called on completion of uDMA transfer
void
UART1IntHandler(void)
{
    uint32_t ui32Status;

    ui32Status = ROM_UARTIntStatus(UART0_BASE, 1);

    ROM_UARTIntClear(UART0_BASE, ui32Status);

    cThisChar = ROM_UARTCharGet(UART0_BASE);

    if(cThisChar == 0x55)
    {
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC,
                                   (void *)(UART0_BASE + UART_O_DR),
                                   g_pui8RxPing, sizeof(g_pui8RxPing));

        ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    }

}

void
InitUART0(void)
{
    // Enable UART1 and make sure it can run while the CPU sleeps
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);

    // Configure and enable the UART with DMA
    ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                            UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                            UART_CONFIG_PAR_NONE);

    ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

    ROM_UARTEnable(UART0_BASE);
    ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);

    ROM_IntEnable(INT_UART0);

    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                              UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                              UDMA_ARB_4);

    ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
}

int
main(void)
{
    ROM_FPULazyStackingEnable();

    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    ROM_SysCtlPeripheralClockGating(true);

    // GPIO setup for LEDs
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);

    // GPIO setup for UART
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    // Enable uDMA
    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    ROM_uDMAEnable();
    ROM_uDMAControlBaseSet(ucControlTable);

    InitUART0();

    while(1)
    {
    }
}

For example I write to launchpad TM4C123GXL: 0x55,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08

In uDMA buffer I get: 0x04,0x02,0x03,0x04,0x05,0x06,0x07. So first bayte incorrect (always different lenght), and last one is out of buffer lenght..

  • Hello Gytis,

    1. Please add a SysCtlPeripheralReset before every SysCtlPeripheralEnable

    2. Did you try not using the UART FIFO by using UARTFIFODisable API call and check if the same result is ssen?

    3. When not doing a UDMA but using the CPU does it work fine?

    Regards

    Amit

  • Thank you for your suggestions Amit!


    1. As you can seen in my code, I already have add SysCtlPeripheralReset before SysCtlPeripheralEnable. maybe you want to say every uDMAChannelEnable? I try both ways, still missing byte..

    2. Yeach, try and UARTFIFODisable, still the same result...

    3. Yes, if I try just uart rx rt, its work great, and if I try just udma, it also work great, no problems..

    Maybe some other suggestions?

  • Hello Gytis

    Can you move the following function in the original code to the Interrupt handler after you enable the DMA Channel in UDMA?

        ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);

    If that does not help then I would need to get my LaunchPads to check the same as I do not have a UART Transmitter in standalone.

    Regards,

    Amit

  • void
    UART0IntHandler(void)
    {
        uint32_t ui32Status;
        
        ui32Status = ROM_UARTIntStatus(UART0_BASE, 1);

        ROM_UARTIntClear(UART0_BASE, ui32Status);

        ROM_UARTDMADisable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
        cThisChar = ROM_UARTCharGet(UART0_BASE);

        if(cThisChar == 0x55)
        {
            ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);


            ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC,
                                       (void *)(UART0_BASE + UART_O_DR),
                                       g_pui8RxPing, sizeof(g_pui8RxPing));

            ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
        }

    }

    Its working for me only in this way.. In ISR, first I disable DMA, after that, enable, as you can see.. It should be fine, but it goes to one big another problem.. It make timer's dont work.. And that intresting. If I remove that DMADisable in ISR, timers work GREAT for me..?!

    Maybe you could look for any other solutions?

  • Hello Gytis,

    Timer has got nothing to do with UART or DMA (unles Timer DMA is being used). Can you see with the debugger where the program execution goes, when timers do not work?

    Regards

    Amit

  • #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_uart.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/uart.h"
    #include "driverlib/udma.h"
    #include "driverlib/timer.h"
    #include "utils/cpu_usage.h"
    #include "utils/uartstdio.h"
    #include "utils/ustdlib.h"
    #include <string.h>
    
    #if defined(ewarm)
    #pragma data_alignment=1024
    uint8_t ui8ControlTable[1024];
    #elif defined(ccs)
    #pragma DATA_ALIGN(ui8ControlTable, 1024)
    uint8_t ui8ControlTable[1024];
    #else
    uint8_t ui8ControlTable[1024] __attribute__ ((aligned(1024)));
    #endif
    
    void Read_Function(void);
    void Write_Function(void);
    void ReadState(void);
    void uDMA_Send(char *TxData, short size);
    
    #define RXBUF_SIZE_3         3 // Read state
    #define RXBUF_SIZE_4         4 // Write state
    //
    static uint8_t RxRead_one[RXBUF_SIZE_3];
    static uint8_t RxWrite_one[RXBUF_SIZE_4];
    
    // Transfer counters
    volatile short DMA_Done = 0;
    volatile short DMA_EndWait = 0;
    volatile short cThisChar = 0;
    volatile short rx_start = 0;
    volatile short rx_address = 0;
    volatile short Ch_Data, Channel_detect;
    
    // uDMA control table aligned to 1024-byte boundary
    #pragma DATA_ALIGN(ucControlTable, 64)
    uint8_t ucControlTable[64];
    
    // UART interrupt handler. Called on completion of uDMA transfer
    void
    UART0IntHandler(void)
    {
    	    uint32_t ui32Status;
    	    uint32_t ui32Mode;
    
    	    ui32Status = ROM_UARTIntStatus(UART0_BASE, 1);
    	    ROM_UARTIntClear(UART0_BASE, ui32Status);
    
    	    if(DMA_EndWait == 1)
    	    {
    	        ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT);
    	        if(ui32Mode == UDMA_MODE_STOP)
    	        {
    	        	DMA_Done = 1;
    	        	DMA_EndWait = 0;
    	        }
    	    }
    	    else if(DMA_EndWait == 0)
    	    {
    			ROM_UARTDMADisable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);// If I remove uartdisable, timers work good, but not dma!! Other case vica versa!
    
    			cThisChar = ROM_UARTCharGet(UART0_BASE);
    
    			switch(cThisChar) // By uart rx, I get first 3 bytes, last one, desice, how big buffer will be.
    			{
    			case 0x55:
    				rx_start = 1;
    				rx_address = 0;
    				break;
    
    			case 0x01:
    				if(rx_start == 1 && rx_address != 1)
    				{
    					rx_address = 1;
    				}
    				else if(rx_start && rx_address == 1)
    				{
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
    
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxWrite_one, sizeof(RxWrite_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    
    			case 0x00:
    				if(rx_start && rx_address == 1)
    				{
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
    
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxRead_one, sizeof(RxRead_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    	    }
    	    }
    }
    
    void Read_Function(void)
    {
    		if(RxRead_one[0] == 0x01)
    		{
    			 if(RxRead_one[1] == 0x01) // Channel
    			 {
    				   if(ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_1) == 0x02)
    				   {
    			        Ch_Data = 0x01;
    				   }
    				   else
    				   {
    				    Ch_Data = 0x00;
    				   }
    				   Channel_detect = 0x01;
    				   ReadState();
    			 }
    		}
    }
    
    void Write_Function(void)
    {
    		if(RxWrite_one[0] == 0x02)
    		{
    			 if(RxWrite_one[1] == 0x05)
    			 {
    				  ROM_TimerEnable(TIMER0_BASE, TIMER_A); // I need turn on Pin for 50ms, so enable Timer and turn on Pin, then in ISR, Pin turn off!
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x02); //Turn on Pin!
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x05;
    				  ReadState();
    			 }
    
    
    			 else if(RxWrite_one[1] == 0x06) //IMPORTANTE!! If you use in UART ISR disableDma, please chance RxWrite_one[1] to RxWrite_one[0]!! and RxWrite_one[2] to RxWrite_one[1]!!
    			 {                               // Other wise leave as there writed, to see how work Timer!!
    				  ROM_TimerEnable(TIMER1_BASE, TIMER_A);
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x04); //Turn on Pin!
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x06;
    				  ReadState();
    			 }
    		}
    }
    
    
    
    void ReadState(void)
    {
    	char TxRead_one[7] = {0x55, 0x01, 0x01, 0x01, Channel_detect, Ch_Data, 0xAA};
    
    	uDMA_Send(TxRead_one, 7);
    }
    
    void uDMA_Send(char *TxData, short size)
    {
    	char TxSend[15];
    
    	memcpy(TxSend, TxData, size);
    
        ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
    
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC, TxSend,
                               (void *)(UART0_BASE + UART_O_DR),
                               size);
    
        ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
    }
    
    void
    InitUART0Enable(void)
    {
        // Enable uDMA
        ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_UDMA);
        ROM_uDMAEnable();
        ROM_uDMAControlBaseSet(ucControlTable);
    
        // Enable UART1 and make sure it can run while the CPU sleeps
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
        ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
        // Configure and enable the UART with DMA
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                                UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                UART_CONFIG_PAR_NONE);
    
        ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
    
        ROM_UARTEnable(UART0_BASE);
    
        //ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX); //Disable!!
    
        ROM_IntEnable(INT_UART0);
    
        // Receive channel setup
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                                  UDMA_ARB_4);
        ////TX////
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0TX, UDMA_ATTR_USEBURST);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
                                  UDMA_ARB_4);
    
        ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    }
    
    void
    Timer0IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER0_BASE, TIMER_A);
    }
    
    void
    Timer1IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER1_BASE, TIMER_A);
    }
    
    void
    ConfigureTimers(void)
    {
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    
    	//One shot timer's
    	ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_ONE_SHOT);
    	ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_ONE_SHOT);
    
    	//Period now 200ms
    	ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet()/5);
    	ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet()/5);
    
    	// Interrupt stuff
    	ROM_IntEnable(INT_TIMER0A);
    	ROM_IntEnable(INT_TIMER1A);
    	ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_IntMasterEnable();
    }
    // main code
    int
    main(void)
    {
    	ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_INT);
    
        ROM_SysCtlPeripheralClockGating(true);
    	ConfigureTimers();
    
        // GPIO setup for LEDs
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
    	ROM_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
        //Initialize the uDMA/UART
        InitUART0Enable();
    
        //Blink the LED while the transfers occur
        while(1)
        {
    		if(DMA_Done == 1)
    		{
    			if(cThisChar == 0x00)
    			{
    				Read_Function();
    			}
    			else if(cThisChar == 0x01)
    			{
    				Write_Function();
    			}
    			DMA_Done = 0;
    		}
        }
    }
    
    

    // External declaration for the interrupt handler used by the application.
    //
    //*****************************************************************************
    extern void UART0IntHandler(void);
    extern void Timer1IntHandler(void);
    extern void Timer0IntHandler(void);

    //

    0x55, 0x01, 0x01, 0x02, 0x06, 0x01, 0xAA  combination to turn on Timer1

    0x55, 0x01, 0x01, 0x02, 0x05, 0x01, 0xAA  combination to turn on Timer0...


    Maybe you could quick look? Because for me its hard to see there program goes...

    From my understanding, I have look to debugger and its goes to timer ISR, but in Timer ISR, doesn't turn off Pin... That do great, then I remove uartdmadisable in uart ISR..

  • Hello Gytis,

    I have attached the updated code. I think it is a sequencing issue.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_uart.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/uart.h"
    #include "driverlib/udma.h"
    #include "driverlib/timer.h"
    #include "utils/cpu_usage.h"
    #include "utils/uartstdio.h"
    #include "utils/ustdlib.h"
    #include <string.h>
    
    #if defined(ewarm)
    #pragma data_alignment=1024
    uint8_t ui8ControlTable[1024];
    #elif defined(ccs)
    #pragma DATA_ALIGN(ui8ControlTable, 1024)
    uint8_t ui8ControlTable[1024];
    #else
    uint8_t ui8ControlTable[1024] __attribute__ ((aligned(1024)));
    #endif
    
    void Read_Function(void);
    void Write_Function(void);
    void ReadState(void);
    void uDMA_Send(char *TxData, short size);
    
    #define RXBUF_SIZE_3         3 // Read state
    #define RXBUF_SIZE_4         4 // Write state
    //
    static uint8_t RxRead_one[RXBUF_SIZE_3];
    static uint8_t RxWrite_one[RXBUF_SIZE_4];
    
    // Transfer counters
    volatile short DMA_Done = 0;
    volatile short DMA_EndWait = 0;
    volatile short cThisChar = 0;
    volatile short rx_start = 0;
    volatile short rx_address = 0;
    volatile short Ch_Data, Channel_detect;
    
    // uDMA control table aligned to 1024-byte boundary
    #pragma DATA_ALIGN(ucControlTable, 64)
    uint8_t ucControlTable[64];
    
    // UART interrupt handler. Called on completion of uDMA transfer
    void
    UART0IntHandler(void)
    {
    	    uint32_t ui32Status;
    	    uint32_t ui32Mode;
    
    	    ui32Status = ROM_UARTIntStatus(UART0_BASE, 1);
    	    ROM_UARTIntClear(UART0_BASE, ui32Status);
    
    	    if(DMA_EndWait == 1)
    	    {
    	        ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT);
    	        if(ui32Mode == UDMA_MODE_STOP)
    	        {
    				ROM_UARTDMADisable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);// If I remove uartdisable, timers work good, but not dma!! Other case vica versa!
    
    	        	DMA_Done = 1;
    	        	DMA_EndWait = 0;
    	        }
    	    }
    	    else if(DMA_EndWait == 0)
    	    {
    			cThisChar = ROM_UARTCharGet(UART0_BASE);
    
    			switch(cThisChar) // By uart rx, I get first 3 bytes, last one, desice, how big buffer will be.
    			{
    			case 0x55:
    				rx_start = 1;
    				rx_address = 0;
    				break;
    
    			case 0x01:
    				if(rx_start == 1 && rx_address != 1)
    				{
    					rx_address = 1;
    				}
    				else if(rx_start && rx_address == 1)
    				{
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxWrite_one, sizeof(RxWrite_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    
    			case 0x00:
    				if(rx_start && rx_address == 1)
    				{
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxRead_one, sizeof(RxRead_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    	    }
    	    }
    }
    
    void Read_Function(void)
    {
    		if(RxRead_one[0] == 0x01)
    		{
    			 if(RxRead_one[1] == 0x01) // Channel
    			 {
    				   if(ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_1) == 0x02)
    				   {
    			        Ch_Data = 0x01;
    				   }
    				   else
    				   {
    				    Ch_Data = 0x00;
    				   }
    				   Channel_detect = 0x01;
    				   ReadState();
    			 }
    		}
    }
    
    void Write_Function(void)
    {
    		if(RxWrite_one[0] == 0x02)
    		{
    			 if(RxWrite_one[1] == 0x05)
    			 {
    				  ROM_TimerEnable(TIMER0_BASE, TIMER_A); // I need turn on Pin for 50ms, so enable Timer and turn on Pin, then in ISR, Pin turn off!
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x02); //Turn on Pin!
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x05;
    				  ReadState();
    			 }
    
    
    			 else if(RxWrite_one[1] == 0x06) //IMPORTANTE!! If you use in UART ISR disableDma, please chance RxWrite_one[1] to RxWrite_one[0]!! and RxWrite_one[2] to RxWrite_one[1]!!
    			 {                               // Other wise leave as there writed, to see how work Timer!!
    				  ROM_TimerEnable(TIMER1_BASE, TIMER_A);
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x04); //Turn on Pin!
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x06;
    				  ReadState();
    			 }
    		}
    }
    
    
    
    void ReadState(void)
    {
    	char TxRead_one[7] = {0x55, 0x01, 0x01, 0x01, Channel_detect, Ch_Data, 0xAA};
    
    	uDMA_Send(TxRead_one, 7);
    }
    
    void uDMA_Send(char *TxData, short size)
    {
    	char TxSend[15];
    
    	memcpy(TxSend, TxData, size);
    
        ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX);
    
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC, TxSend,
                               (void *)(UART0_BASE + UART_O_DR),
                               size);
    
        ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
    }
    
    void
    InitUART0Enable(void)
    {
        // Enable uDMA
        ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_UDMA);
        ROM_uDMAEnable();
        ROM_uDMAControlBaseSet(ucControlTable);
    
        // Enable UART1 and make sure it can run while the CPU sleeps
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
        ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
        // Configure and enable the UART with DMA
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                                UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                UART_CONFIG_PAR_NONE);
    
        ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
    
        ROM_UARTEnable(UART0_BASE);
    
        //ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX | UART_DMA_TX); //Disable!!
    
        ROM_IntEnable(INT_UART0);
    
        // Receive channel setup
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                                  UDMA_ARB_4);
        ////TX////
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0TX, UDMA_ATTR_USEBURST);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
                                  UDMA_ARB_4);
    
        ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    }
    
    void
    Timer0IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER0_BASE, TIMER_A);
    }
    
    void
    Timer1IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER1_BASE, TIMER_A);
    }
    
    void
    ConfigureTimers(void)
    {
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    
    	//One shot timer's
    	ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_ONE_SHOT);
    	ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_ONE_SHOT);
    
    	//Period now 200ms
    	ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet()/5);
    	ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet()/5);
    
    	// Interrupt stuff
    	ROM_IntEnable(INT_TIMER0A);
    	ROM_IntEnable(INT_TIMER1A);
    	ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_IntMasterEnable();
    }
    // main code
    int
    main(void)
    {
    	ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_INT);
    
        ROM_SysCtlPeripheralClockGating(true);
    	ConfigureTimers();
    
        // GPIO setup for LEDs
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
    	ROM_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
        //Initialize the uDMA/UART
        InitUART0Enable();
    
        //Blink the LED while the transfers occur
        while(1)
        {
    		if(DMA_Done == 1)
    		{
    			if(cThisChar == 0x00)
    			{
    				Read_Function();
    			}
    			else if(cThisChar == 0x01)
    			{
    				Write_Function();
    			}
    			DMA_Done = 0;
    		}
        }
    }
    
    

    It the above sequence of 7 characters is what is needed to turn on the timers, then I may be able to do the same on my board to see (do not have access to my board for the next couple of days, so please excuse)

    Regards

    Amit

  • Thank you very much Amit!

    interesting after I make a lot different experiments, I found that if in UART ISR i left udma disable, the problem why timer doesn't work, is because of uDMA TX fols.. If after timer enable I turn on uDMA TX (uDMA TX working good), timer stuck.. other vise timer works!

    I rewrite and well comment code, please look, maybe have some suggestions?

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_uart.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/uart.h"
    #include "driverlib/udma.h"
    #include "driverlib/timer.h"
    #include "utils/cpu_usage.h"
    #include "utils/uartstdio.h"
    #include "utils/ustdlib.h"
    #include <string.h>
    
    #if defined(ewarm)
    #pragma data_alignment=1024
    uint8_t ui8ControlTable[1024];
    #elif defined(ccs)
    #pragma DATA_ALIGN(ui8ControlTable, 1024)
    uint8_t ui8ControlTable[1024];
    #else
    uint8_t ui8ControlTable[1024] __attribute__ ((aligned(1024)));
    #endif
    
    void Read_Function(void);
    void Write_Function(void);
    void ReadState(void);
    void uDMA_Send(char *TxData, short size);
    
    #define RXBUF_SIZE_3         3 // Read state
    #define RXBUF_SIZE_4         4 // Write state
    //
    static uint8_t RxRead_one[RXBUF_SIZE_3];
    static uint8_t RxWrite_one[RXBUF_SIZE_4];
    
    // Transfer counters
    volatile short DMA_Done = 0;
    volatile short DMA_EndWait = 0;
    volatile short cThisChar = 0;
    volatile short rx_start = 0;
    volatile short rx_address = 0;
    volatile short Ch_Data, Channel_detect;
    
    // uDMA control table aligned to 1024-byte boundary
    #pragma DATA_ALIGN(ucControlTable, 64)
    uint8_t ucControlTable[64];
    
    // UART interrupt handler. Called on completion of uDMA transfer
    void
    UART0IntHandler(void)
    {
    	    uint32_t ui32Status;
    	    uint32_t ui32Mode;
    
    	    ui32Status = ROM_UARTIntStatus(UART0_BASE, 1);
    	    ROM_UARTIntClear(UART0_BASE, ui32Status);
    
    	    if(DMA_EndWait == 1)
    	    {
    	        ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT);
    	        if(ui32Mode == UDMA_MODE_STOP)
    	        {
    	        	DMA_Done = 1;
    	        	DMA_EndWait = 0;
    	        }
    	    }
    	    else if(DMA_EndWait == 0)
    	    {
    	    	ROM_UARTDMADisable(UART0_BASE, UART_DMA_RX); // uDMA only work GOOD with first uDMADisable!
    
    			cThisChar = ROM_UARTCharGet(UART0_BASE);
    
    			switch(cThisChar) // By uart rx, I get first 3 bytes, last one, decide, how big buffer will be.
    			{
    			case 0x55:
    				rx_start = 1;
    				rx_address = 0;
    				break;
    
    			case 0x01:
    				if(rx_start == 1 && rx_address != 1)
    				{
    					rx_address = 1;
    				}
    				else if(rx_start && rx_address == 1)
    				{
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxWrite_one, sizeof(RxWrite_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    
    			case 0x00:
    				if(rx_start && rx_address == 1)
    				{
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxRead_one, sizeof(RxRead_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    	    }
    	    }
    }
    
    void Read_Function(void)
    {
    		if(RxRead_one[0] == 0x01)
    		{
    			 if(RxRead_one[1] == 0x01) // Channel
    			 {
    				   if(ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_1) == 0x02)
    				   {
    			        Ch_Data = 0x01;
    				   }
    				   else
    				   {
    				    Ch_Data = 0x00;
    				   }
    				   Channel_detect = 0x01;
    				   ReadState(); // This case, uDMA work!!
    			 }
    		}
    }
    
    void Write_Function(void)
    {
    		if(RxWrite_one[0] == 0x02)
    		{
    			 if(RxWrite_one[1] == 0x05)
    			 {
    				  ROM_TimerEnable(TIMER0_BASE, TIMER_A);
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x02); //Turn on Pin!
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x05;
    				  ReadState(); // With uDMA TX, Timer stuck's!! But uDMA TX working good...!
    			 }
    
    
    			 else if(RxWrite_one[1] == 0x06)
    			 {
    				  ROM_TimerEnable(TIMER1_BASE, TIMER_A);
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x04);
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x06;
    				  //ReadState();    // IF I TURN OFF uDMA TX, Timer work!! With uDMA TX stuck's!!
    			 }
    		}
    }
    
    
    
    void ReadState(void)
    {
    	char TxRead_one[7] = {0x55, 0x01, 0x01, 0x01, 0x02, 0x03, 0xAA};
    
        ROM_UARTDMAEnable(UART0_BASE, UART_DMA_TX);
    
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC, TxRead_one,
                               (void *)(UART0_BASE + UART_O_DR),
                               sizeof(TxRead_one));
    
        ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
    }
    
    void
    InitUART0Enable(void)
    {
        // Enable uDMA
        ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_UDMA);
        ROM_uDMAEnable();
        ROM_uDMAControlBaseSet(ucControlTable);
    
        // Enable UART1 and make sure it can run while the CPU sleeps
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
        ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    
        // Configure and enable the UART with DMA
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                                UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                UART_CONFIG_PAR_NONE);
    
        ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
        //ROM_UARTFIFODisable(UART0_BASE);
    
        ROM_UARTEnable(UART0_BASE);
    
        ROM_IntEnable(INT_UART0);
    
        // Receive channel setup
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                                  UDMA_ARB_4);
        ////TX////
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0TX, UDMA_ATTR_USEBURST);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
                                  UDMA_ARB_4);
    
        ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    }
    
    void
    Timer0IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER0_BASE, TIMER_A);
    }
    
    void
    Timer1IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER1_BASE, TIMER_A);
    }
    
    void
    ConfigureTimers(void)
    {
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    
    	//One shot timer's
    	ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_ONE_SHOT);
    	ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_ONE_SHOT);
    
    	//Period now 50ms
    	ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet()/20);
    	ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet()/20);
    
    	// Interrupt stuff
    	ROM_IntEnable(INT_TIMER0A);
    	ROM_IntEnable(INT_TIMER1A);
    	ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_IntMasterEnable();
    }
    // main code
    int
    main(void)
    {
    	ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_INT);
    
        ROM_SysCtlPeripheralClockGating(true);
    	ConfigureTimers();
    
        // GPIO setup for LEDs
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
    	ROM_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
        //Initialize the uDMA/UART
        InitUART0Enable();
    
        //Blink the LED while the transfers occur
        while(1)
        {
    		if(DMA_Done == 1)
    		{
    			if(cThisChar == 0x00)
    			{
    				Read_Function();
    			}
    			else if(cThisChar == 0x01)
    			{
    				Write_Function();
    			}
    			DMA_Done = 0;
    		}
        }
    }
    

  • Hello Gytis,

    I think I found the issue. I debugged the code today and it seems that the timer is working but the CPU is stuck in the UART Interrupt. On closer inspection it turns out that when the UART TX DMA is enabled, it gives a done interrupt and the CPU goes in the UART Interrupt handler

            else if(DMA_EndWait == 0)
            {
                UARTDMADisable(UART0_BASE, UART_DMA_RX); // uDMA only work GOOD with first uDMADisable!

                cThisChar = UARTCharGet(UART0_BASE);

    and gets stuck in the UARTCharGet as it is a blocking function.

    I think when you enable the UART TX DMA, what needs to be done is a flag set so that it does skips the else if conditions.

    Hope that helps!!1

    Regards

    Amit

  • Yes, you really found issue!! Thank you!!


    Yeach, I think to what to do with uDMA Tx interrupt.. I dont need that interrupt. try UARTIntDisable(UART0_BASE, UART_INT_TX), but probably udma tx set flag to uart_int_rx interrupt. But I think its bad idea disable uart rx for a while..

    That you have in mind to set flag?

  • Hello Gytis,

    When DMA is being used the completion of either RX or TX will trigger an Interrupt. So the Interrupt Handler has to know that the TXDMA is happening and the next interrupt would be when TXDMA is done.

    You can use the DMA Control Structure to determine if TX DMA is done and exit the Interrupt Handler.

    Regards

    Amit

  • Sorry Amit, but its really hard to find out how it realize in program.. Maybe you have more detail hints?

  • Hello Gytis,

    Search for the gui32TxOperation in the attached file

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_uart.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/uart.h"
    #include "driverlib/udma.h"
    #include "driverlib/timer.h"
    #include "utils/cpu_usage.h"
    #include "utils/uartstdio.h"
    #include "utils/ustdlib.h"
    #include <string.h>
    
    #if defined(ewarm)
    #pragma data_alignment=1024
    uint8_t ui8ControlTable[1024];
    #elif defined(ccs)
    #pragma DATA_ALIGN(ui8ControlTable, 1024)
    uint8_t ui8ControlTable[1024];
    #else
    uint8_t ui8ControlTable[1024] __attribute__ ((aligned(1024)));
    #endif
    
    void Read_Function(void);
    void Write_Function(void);
    void ReadState(void);
    void uDMA_Send(char *TxData, short size);
    
    #define RXBUF_SIZE_3         3 // Read state
    #define RXBUF_SIZE_4         4 // Write state
    //
    static uint8_t RxRead_one[RXBUF_SIZE_3];
    static uint8_t RxWrite_one[RXBUF_SIZE_4];
    
    // Transfer counters
    volatile short DMA_Done = 0;
    volatile short DMA_EndWait = 0;
    volatile short cThisChar = 0;
    volatile short rx_start = 0;
    volatile short rx_address = 0;
    volatile short Ch_Data, Channel_detect;
    volatile uint32_t gui32TxOperation = 0;
    
    // uDMA control table aligned to 1024-byte boundary
    #pragma DATA_ALIGN(ucControlTable, 64)
    uint8_t ucControlTable[64];
    
    // UART interrupt handler. Called on completion of uDMA transfer
    void
    UART0IntHandler(void)
    {
    	    uint32_t ui32Status;
    	    uint32_t ui32Mode;
    
    	    ui32Status = ROM_UARTIntStatus(UART0_BASE, 1);
    	    ROM_UARTIntClear(UART0_BASE, ui32Status);
    
    		if(gui32TxOperation == 1)
    		{
    			gui32TxOperation = 0;
    		}
    		else if(gui32TxOperation == 0 && DMA_EndWait == 1)
    	    {
    	        ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT);
    	        if(ui32Mode == UDMA_MODE_STOP)
    	        {
    	        	DMA_Done = 1;
    	        	DMA_EndWait = 0;
    	        }
    	    }
    	    else if(gui32TxOperation == 0 && DMA_EndWait == 0)
    	    {
    	    	ROM_UARTDMADisable(UART0_BASE, UART_DMA_RX); // uDMA only work GOOD with first uDMADisable!
    
    			cThisChar = ROM_UARTCharGet(UART0_BASE);
    
    			switch(cThisChar) // By uart rx, I get first 3 bytes, last one, decide, how big buffer will be.
    			{
    			case 0x55:
    				rx_start = 1;
    				rx_address = 0;
    				break;
    
    			case 0x01:
    				if(rx_start == 1 && rx_address != 1)
    				{
    					rx_address = 1;
    				}
    				else if(rx_start && rx_address == 1)
    				{
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxWrite_one, sizeof(RxWrite_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    
    			case 0x00:
    				if(rx_start && rx_address == 1)
    				{
    					ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
    										   UDMA_MODE_BASIC,
    										   (void *)(UART0_BASE + UART_O_DR),
    										   RxRead_one, sizeof(RxRead_one));
    
    					ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    
    					ROM_UARTDMAEnable(UART0_BASE, UART_DMA_RX);
    
    					DMA_EndWait = 1;
    
    					rx_address = 0;
    					rx_start = 0;
    				}
    				break;
    	    }
    	    }
    }
    
    void Read_Function(void)
    {
    		if(RxRead_one[0] == 0x01)
    		{
    			 if(RxRead_one[1] == 0x01) // Channel
    			 {
    				   if(ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_1) == 0x02)
    				   {
    			        Ch_Data = 0x01;
    				   }
    				   else
    				   {
    				    Ch_Data = 0x00;
    				   }
    				   Channel_detect = 0x01;
    				   ReadState(); // This case, uDMA work!!
    			 }
    		}
    }
    
    void Write_Function(void)
    {
    		if(RxWrite_one[0] == 0x02)
    		{
    			 if(RxWrite_one[1] == 0x05)
    			 {
    				  ROM_TimerEnable(TIMER0_BASE, TIMER_A);
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x02); //Turn on Pin!
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x05;
    				  ReadState(); // With uDMA TX, Timer stuck's!! But uDMA TX working good...!
    			 }
    
    
    			 else if(RxWrite_one[1] == 0x06)
    			 {
    				  ROM_TimerEnable(TIMER1_BASE, TIMER_A);
    				  //
    				  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x04);
    
    				  Ch_Data = 0x01;
    				  Channel_detect = 0x06;
    				  //ReadState();    // IF I TURN OFF uDMA TX, Timer work!! With uDMA TX stuck's!!
    			 }
    		}
    }
    
    
    
    void ReadState(void)
    {
    	char TxRead_one[7] = {0x55, 0x01, 0x01, 0x01, 0x02, 0x03, 0xAA};
    
        ROM_UARTDMAEnable(UART0_BASE, UART_DMA_TX);
    
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC, TxRead_one,
                               (void *)(UART0_BASE + UART_O_DR),
                               sizeof(TxRead_one));
    
        ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
    	
    	gui32TxOperation = 1;
    }
    
    void
    InitUART0Enable(void)
    {
        // Enable uDMA
        ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_UDMA);
        ROM_uDMAEnable();
        ROM_uDMAControlBaseSet(ucControlTable);
    
        // Enable UART1 and make sure it can run while the CPU sleeps
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
        ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    
        // Configure and enable the UART with DMA
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                                UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                UART_CONFIG_PAR_NONE);
    
        ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
        //ROM_UARTFIFODisable(UART0_BASE);
    
        ROM_UARTEnable(UART0_BASE);
    
        ROM_IntEnable(INT_UART0);
    
        // Receive channel setup
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                                  UDMA_ARB_4);
        ////TX////
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
        ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0TX, UDMA_ATTR_USEBURST);
    
        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
                                  UDMA_ARB_4);
    
        ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    }
    
    void
    Timer0IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER0_BASE, TIMER_A);
    }
    
    void
    Timer1IntHandler(void)
    {
    	ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00); // Turn off Pin
        //
    	ROM_TimerDisable(TIMER1_BASE, TIMER_A);
    }
    
    void
    ConfigureTimers(void)
    {
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    
    	//One shot timer's
    	ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_ONE_SHOT);
    	ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_ONE_SHOT);
    
    	//Period now 50ms
    	ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet()/20);
    	ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet()/20);
    
    	// Interrupt stuff
    	ROM_IntEnable(INT_TIMER0A);
    	ROM_IntEnable(INT_TIMER1A);
    	ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_IntMasterEnable();
    }
    // main code
    int
    main(void)
    {
    	ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_INT);
    
        ROM_SysCtlPeripheralClockGating(true);
    	ConfigureTimers();
    
        // GPIO setup for LEDs
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
    	ROM_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
        //Initialize the uDMA/UART
        InitUART0Enable();
    
        //Blink the LED while the transfers occur
        while(1)
        {
    		if(DMA_Done == 1)
    		{
    			if(cThisChar == 0x00)
    			{
    				Read_Function();
    			}
    			else if(cThisChar == 0x01)
    			{
    				Write_Function();
    			}
    			DMA_Done = 0;
    		}
        }
    }
    

    regards

    Amit

  • Thank, I have make it by the same idea.

    Have one more question. So in TM4C123GXL microcontroller it's impossible to turn off UART TX interrupt by hardware?

  • Hello Gytis,

    UART TX Interrupt can be masked in the UARTIM.TXIM register bit. However when UDMA is being used the TX done interrupt is coming from the uDMA and not the UART controller.

    Regards

    Amit

  • So, its "DMA Channel Interrupt Status (DMACHIS)"  CHIS register?

    Datasheet, is writing like that:

    "When a μDMA channel generates a completion interrupt, the CHIS bit corresponding to the peripheral
    channel is set in the DMA Channel Interrupt Status (DMACHIS) register"

    But in udma API, I only can disable ISR uDMAIntUnregister(uint32_t ui32IntChannel), wich available only with UDMA_INT_SW or  UDMA_INT_ERR (software and error interrupts)..

    So i'm confuse...

  • Hello Gytis,

    In the udma.c file there is the uDMAIntStatus which would return the UDMACHIS and this can be used to find out which Channel (TX or RX) caused the interrupt. The uDMAIntStatus has to be called in the Peripheral Interrupt Handler and then the code has to check if TX or RX Done caused the interrupt.

    Regards

    Amit

  • Thank you Amit, it works for me!!