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.

Flag at the end of the message (UART) issue.



Hello again,

I have search o lot in forum about this question, I find Dave Wilson mind that:

"I suppose, add code to UARTStdioIntHandler to do something similar to what UARTPeek does and set some flag for your main loop whenever it detects the end of a line.."

http://e2e.ti.com/support/microcontrollers/stellaris_arm/f/471/p/46111/159192.aspx#159192


So, I need instead of UARTPeek spinning all the time in while loop looking for '\r' - end of line (like qs-rgb example), find a way to make flag high and jump to UARTStdioIntHandler interrupt..

I need write about six separated Hex elements in one line and press Enter..

this is possible at all?

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

static char g_cInput[APP_INPUT_BUF_SIZE];

extern void UARTStdioIntHandler(void)
{
    // Seriuosly, i dont know.. Something like clean flag..
    UARTgets(g_cInput,sizeof(g_cInput));
    // something...
}

int
main(void)
{
    SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|
                    SYSCTL_OSC_MAIN);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    IntMasterEnable();  // Need this one?
    
    UARTStdioConfig(0, 115200, 16000000);

    while(1)
    {
    }
}

  • Hello Gytis,

    You can use the Interrupt Handler to get the six codes and enter key to make the same decision instead of spinning in the main code.

    Basically on receiving the first character you can put it into an array and check if the entry is a "Enter" key or not. If not then keep on appending the recived codes. If enter then use the array to make the decision

    Regards

    Amit

  • Yes, I maked code work that way, but the best choise for me would be use uDMA(I have task make it work with DMA).. I tryed change TM4C123G LaunchPad workbook lab 13 code in this way, that i could receive characters from putty, but something wrong about dma configuration..

    Maybe you could help whit this code?

    #define UART_TXBUF_SIZE         16
    #define UART_RXBUF_SIZE         16
    static uint8_t g_pui8TxBuf[UART_TXBUF_SIZE];
    static uint8_t g_pui8RxPing[UART_RXBUF_SIZE];
    static uint8_t g_pui8RxPong[UART_RXBUF_SIZE];

    // Error counter
    static uint32_t g_ui32DMAErrCount = 0;

    // Transfer counters
    static uint32_t g_ui32RxPingCount = 0;
    static uint32_t g_ui32RxPongCount = 0;

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

    void
    uDMAErrorHandler(void)
    {
        uint32_t ui32Status;

        ui32Status = ROM_uDMAErrorStatusGet();

        if(ui32Status)
        {
            ROM_uDMAErrorStatusClear();
            g_ui32DMAErrCount++;
        }
    }

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

        ui32Status = ROM_UARTIntStatus(UART1_BASE, 1);

        ROM_UARTIntClear(UART1_BASE, ui32Status);

        ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT);

        if(ui32Mode == UDMA_MODE_STOP)
        {
            g_ui32RxPingCount++;

            ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
                                       UDMA_MODE_PINGPONG,
                                       (void *)(UART1_BASE + UART_O_DR),
                                       g_pui8RxPing, sizeof(g_pui8RxPing));
        }

        ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT);

        if(ui32Mode == UDMA_MODE_STOP)
        {
            g_ui32RxPongCount++;

            ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
                                       UDMA_MODE_PINGPONG,
                                       (void *)(UART1_BASE + UART_O_DR),
                                       g_pui8RxPong, sizeof(g_pui8RxPong));
        }

        if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
        {

            ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC, g_pui8TxBuf,
                                       (void *)(UART1_BASE + UART_O_DR),
                                       sizeof(g_pui8TxBuf));

            ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
        }

    }

    // Initialize UART uDMA transfer
    void
    InitUART1Enable(void)
    {
        // Enable UART1 and make sure it can run while the CPU sleeps
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
        ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1);

        ROM_GPIOPinConfigure(GPIO_PB0_U1RX);
        ROM_GPIOPinConfigure(GPIO_PB1_U1TX);
        // Configure and enable the UART with DMA
        ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

        ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 115200,
                                UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                UART_CONFIG_PAR_NONE);

        ROM_UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

        ROM_UARTEnable(UART1_BASE);
        ROM_UARTDMAEnable(UART1_BASE, UART_DMA_RX);

        ROM_IntEnable(INT_UART1);

        // Receive channel setup for ping and pong
        ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1RX,
                                        UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);

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

        ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
                                  UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                                  UDMA_ARB_4);

        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
                                   UDMA_MODE_PINGPONG,
                                   (void *)(UART1_BASE + UART_O_DR),
                                   g_pui8RxPing, sizeof(g_pui8RxPing));

        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
                                   UDMA_MODE_PINGPONG,
                                   (void *)(UART1_BASE + UART_O_DR),
                                   g_pui8RxPong, sizeof(g_pui8RxPong));

        // Enable both channels
        ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1RX);
    }

    // main code
    int
    main(void)
    {
        volatile uint32_t ui32Loop;


        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

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

        // Initialize the uDMA/UART
        InitUART1Enable();

        // Blink the LED while the transfers occur
        while(1)
        {
            if((g_ui32RxPingCount || g_ui32RxPingCount) > 0)
            {
                GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

                SysCtlDelay(SysCtlClockGet() / 20 / 3);

                GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

                SysCtlDelay(SysCtlClockGet() / 20 / 3);
            }
        }
    }

  • Hello Gytis

    Can you please elaborate the issue, so that I can better analyze the code?

    Regards

    Amit

  • Hello Amit!

    Yes, of course!

    So I need microcontroller communicate with PuTTY program, like write 6 Hex (0x55 0x01 0x00 0x01 0x08 0xAA) and TM4C123G DMA buffer collect data to Rx buffer, then buffer fill, start interrupt..

  • Hello Gytis,

    I am still not sure what the exact issue you are facing. But based on the description I may want to hypothize.

    The UART FIFO Level is set for 1/2 by default. The FIFO is 16 locations deep and so a RX DMA Request will be made only when the number of bytes cross 8 (i.e. the 9th byte is written). Since with 6 bytes that threshold will not be crossed there is no DMA transfer occurring.


    Regards

    Amit Ashara

  • Yea, but even I write much more characters to uart, still dont get any data to Rx buffer, something wrong in configuration uDMA?

    So the main question would be, is this code writed good to capture all incoming data from UART? Maybe I something missed of writed wrong way..

  • Hello Gytis

    I ran the code on my LaunchPad and it didn't work the first time around. However after some tries (no code change to the last code post) it did work but then stopped. I believe it to be something on the uDMA side. Hope to have an answer by Monday

    Regards

    Amit

  • Hey!


    Thats very good news Amit!! I will waiting for your answer at monday and will try by my self!

  • Hello Gytis,

    I updated the sequence by reset of the UDMA before enabling the same. Now after every 16 bytes of transmission I get a UART Interrupt.

    Attached is the updated code.

    http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/908/1134.udma_5F00_demo.7z

    Regards

    Amit

  • Thank you very much!

    I have one question, I read in datasheet, then "μDMA transfer is complete, the μDMA controller generates a completion interrupt on the interrupt vector of the peripheral" That correct. And By datasheet, transfer complete in three cases:

    "μDMA can indicate transfer completion at the end of an entire transfer (this case 16 bytes) or when a FIFO or buffer reaches a certain level"

    If I have 3 lenght data, like:

    0x55,0x01,0x01,0x05,0xAA (5 characters),

    0x55,0x01,0x01,0x03,0x67,0x05,0xAA (7 characters) and

    0x55,0x01,0x01,0x05,0x03.0x05,0x12,0x45,0x56,0xAA (10 characters)

    always in the end with 0xAA.

    Could μDMA indicate transfer completion then detect Hex == 0xAA?

    It would be like buffer reaches 5 character and check it is Hex == 0xAA, if no going to 7 character and if its == 0xAA, indicate transfer completion, if no, go to 10 character and then indicate transfer completion.

  • Hello Gytis

    not the uDMA in tiva. It just understands that when a request is asserted then it has to transfer a defined amount if data from source to destination. It will not do any modification (like inversion) nor check of what the data pattern contains

    Regards

    Amit

  • Okey, I think last problem mine with this project.. This is part of code, at the end problem describtion..

    #define Lenght 35
    volatile int RxData[Lenght];

    void
    UARTIntHandler(void)
    {
        uint32_t ui32Status;
        char cThisChar;

        ui32Status = ROM_UARTIntStatus(UART0_BASE, true);
        ROM_UARTIntClear(UART0_BASE, ui32Status);

        while(ROM_UARTCharsAvail(UART0_BASE))
        {
         cThisChar = ROM_UARTCharGetNonBlocking(UART0_BASE);// Try use UARTCharGet function, result is the same..
        }

            RxData[counter] = cThisChar; // Checking or RxData is correct at Memory browser!!!
            counter++;

            if(cThisChar == 0xAA)
            {
             //MainFunction(RxData, counter);//Go to MainFunction
             counter = 0;
            }
    }

    void
    ConfigureUART(void)
    {
        //Enable the peripherals
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

        //Set GPIO
        ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
        ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

        //Configure the UART for 115200 8-N-1
        ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                                (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                 UART_CONFIG_PAR_NONE));
        
        //Enable the UART interrupt.
        ROM_IntEnable(INT_UART0);
        ROM_UARTIntEnable(UART0_BASE, UART_INT_RX|UART_INT_RT);
        ROM_IntMasterEnable();
    }

    int main(void)
    {
        // Main 16MHz clock
        ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_INT);

        // Enable and Initialize the UART & Timers.
        ConfigureTimers();
        ConfigureUART();

        // Enable DeepSleep Clock
        ROM_SysCtlDeepSleepClockSet(SYSCTL_DSLP_PIOSC_PD);
        ROM_SysCtlPeripheralClockGating(true);

        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

        ROM_GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED);
        //ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, Relay1_ON|Relay1_OFF|Relay2_ON|Relay2_OFF);

        // Configure to DeepSleep
        ROM_SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_UART0);
        ROM_SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_TIMER0);
        ROM_SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_TIMER1);

        while(1)
        {
         ROM_SysCtlDeepSleep();
        }
    }

    Sending Data: $55$01$01$02$05$01$AA equal to = 0x55,0x01,0x01,0x02,0x05,0x01,0xAA; via Terminal v1.9b

    Checking or RxData is correct at CCS Memory browser!!!


    Problem is that, about 5-10 times data send and its correct, then always one or two
    times to tiva C I get something like this: 0x01,0x01,0x01,0x02,0x05,0x01,0xAA (first Hex incorrect)
    or most cases 0x01,0x01,0x02,0x05,0x01,0xAA,0xAA (first seems like missed, at the end it becomes two 0xAA)

    for me its really big problem.. Maybe someone could try this program with launchpad? Maybe its my computer or launchpad fault..(TM4C123GH6PMI) Maybe something with code..
     I try different ways like Set fifo level:

        //ROM_UARTFIFOEnable(UART0_BASE);
        //ROM_UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX2_8, UART_FIFO_RX2_8); and without receive timeout (Nothing change..)

  • Dont worry, I solved this problem, just need few code lines changes to this:

        do
        {
            cThisChar = UARTCharGet(UART0_BASE);
            RxData[counter] = cThisChar;
            counter++;
        }
        while(cThisChar != 0xAA);

    Works well!