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.

TM4C1294NCPDT: TI RTOS UART on RS485 interrupt end of trame

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: SYSBIOS

Hi,

I use the UART for an RS485 serial where I drive an output signal to read or write on the network. I want to have an interruption at the end of the frame when sending TX.
It works fine without TI RTOS using the EOT bit but I want to do the same with TI RTOS.
There are several posts on this subject but I did not find an explicit one that allowed me to find a solution.

Thanks in advance

Christophe G
  • Hello Christophe,

    Sorry for the lack of response here on this query, it got lost in the shuffle on our end.

    Do you still need some guidance on this and if so have you taken any further steps on trying to implement this?

    What TI-RTOS example have you started from?

  • Hello Ralph,

    A lot of post about this topic without a real answer.

    For begining I modified the mutex example.

     *  ======== mutex.c ========
     */
    
    #include <stdbool.h>
    
    /* XDC module Headers */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS module Headers */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Semaphore.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/uart/UARTtiva.c>
    
    #include "inc/hw_uart.h"
    #include "driverlib/uart.h"
    #include "utils/ringbuf.h"
    #include "utils/uartstdio.h"
    
    #include "inc/hw_uart.h"
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/interrupt.h"
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #define TASKSTACKSIZE   512
    
    Void task1Fxn(UArg arg0, UArg arg1);
    Void task2Fxn(UArg arg0, UArg arg1);
    
    Int resource = 0;
    Int finishCount = 0;
    UInt32 sleepTickCount;
    
    Task_Struct task1Struct, task2Struct;
    Char task1Stack[TASKSTACKSIZE], task2Stack[TASKSTACKSIZE];
    Semaphore_Struct semStruct;
    Semaphore_Handle semHandle;
    
    char input = 0x9;
    UART_Handle uart;
    
    void UART00_IRQHandlerWrite(UART_Handle handle, void *buffer, size_t num);
    /*
     *  ======== main ========
     */
    Int main()
    {
        /* Construct BIOS objects */
        Task_Params taskParams;
        Semaphore_Params semParams;
    
    
        UART_Params uartParams;
     //   const char echoPrompt[] = "\fEchoing characters:\r\n";
    
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initUART();
    
    
    
        /* Construct writer/reader Task threads */
        Task_Params_init(&taskParams);
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = &task1Stack;
        taskParams.priority = 1;
        Task_construct(&task1Struct, (Task_FuncPtr)task1Fxn, &taskParams, NULL);
    
        taskParams.stack = &task2Stack;
        taskParams.priority = 2;
        Task_construct(&task2Struct, (Task_FuncPtr)task2Fxn, &taskParams, NULL);
    
        /* Construct a Semaphore object to be use as a resource lock, inital count 1 */
        Semaphore_Params_init(&semParams);
        Semaphore_construct(&semStruct, 1, &semParams);
    
        /* Obtain instance handle */
        semHandle = Semaphore_handle(&semStruct);
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.baudRate = 115200;
        uartParams.dataLength = UART_LEN_8;
        uartParams.stopBits = UART_STOP_ONE;
        uartParams.parityType = UART_PAR_NONE;
    //    uartParams.writeTimeout = UART_WAIT_FOREVER;
        uartParams.writeMode = UART_MODE_CALLBACK;//UART_MODE_BLOCKING;//UART_MODE_CALLBACK; // the uart uses a read interrupt
        uartParams.writeCallback = &UART00_IRQHandlerWrite; // function called when the uart interrupt fires
        HWREG(UART0_BASE + UART_O_CTL) |= UART_TXINT_MODE_EOT;
    
        //uart = UART_open(Board_UART0, &uartParams);
    
         UARTTiva_open(uart, &uartParams);
    
    
        if (uart == NULL) {
            System_abort("Error opening the UART");
        }
    
       // UART_write(uart, echoPrompt, sizeof(echoPrompt));
    
        /* We want to sleep for 10000 microseconds */
        sleepTickCount = 10000 / Clock_tickPeriod;
    
        BIOS_start();    /* Does not return */
        return(0);
    }
    
    /*
     *  ======== task1Fxn ========
     */
    Void task1Fxn(UArg arg0, UArg arg1)
    {
        UInt32 time;
    
       while(1) {
            System_printf("Running task1 function\n");
    
            if (Semaphore_getCount(semHandle) == 0) {
                System_printf("Sem blocked in task1\n");
            }
    
            GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 1);
            UART_write(uart, &input, 1);
    
    
            /* Get access to resource */
            Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
            //while((UARTBusy(Board_UART0)));
            //GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0,0);
    
    
            /* Do work by waiting for 2 system ticks to pass */
            time = Clock_getTicks();
            while (Clock_getTicks() <= (time + 1)) {
                ;
            }
    
            /* Do work on locked resource */
            resource += 1;
            /* Unlock resource */
    
            Semaphore_post(semHandle);
    
            Task_sleep(sleepTickCount);
        }
    }
    
    /*
     *  ======== task2Fxn ========
     */
    Void task2Fxn(UArg arg0, UArg arg1)
    {
        while(1) {
            System_printf("Running task2 function\n");
    
            if (Semaphore_getCount(semHandle) == 0) {
                System_printf("Sem blocked in task2\n");
            }
    
    //        GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0);
    
            /* Get access to resource */
            Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
    
            /* Do work on locked resource */
            resource += 1;
            /* Unlock resource */
    
            Semaphore_post(semHandle);
    
            Task_sleep(sleepTickCount);
    
            finishCount++;
            if (finishCount == 5) {
                System_printf("Calling BIOS_exit from task2\n");
                BIOS_exit(0);
            }
        }
    }
    
    void UART00_IRQHandlerWrite(UART_Handle handle, void *buffer, size_t num)
    {
    
       // GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0);
    
    
    
        {
         //  ++ucEndOfFrame;
         //
         //  Write the next character into the transmit FIFO.
         //
         //  UART_write(uart, &input, 1);
         //  UARTCharPut(MODBUS_UART_BASE, RingBufReadOne(&g_sTxBuf));
    
        }
    
       //while(UARTBusy(Board_UART0))
    
    
        //while(  (UARTIntStatus(UART0_BASE,UART_RIS_TXRIS)) == 1)
        {
           //      GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0,0);
            //while((UARTBusy(Board_UART0)));
            //GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0,0);
    
            Semaphore_post(semHandle);
        }
    }
    

    I used the EOT bit without success

    Could I use HWI or UART_OPEN()?

    Thanks in advance

    Christophe G

  • Hello Christophe,

    It does not look like the UART driver for TI-RTOS supports UART_TXINT_MODE_EOT at all. So therefore, you would need to define your own HWI to handle this because likely when you try and do it as you have outlined, the TI-RTOS driver is overwriting it. Another option could be to use HWI to capture interrupts in the context of the RTOS but then use more traditional techniques in parallel with the RTOS - so you would not use the the TI-RTOS UART driver, but TivaWare instead. The key to making that approach work however is that the HWI needs to be registered through SysBios or else it won't work.