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.

CC2642R: UART2 Rx Buffer Fragmented

Part Number: CC2642R
Other Parts Discussed in Thread: SYSCONFIG, SYSBIOS

Hi folks,

I have a CC2642R1 (SimpleLink SDK 5.10) chatting with an external UART Device via the UART2 driver.

  • TXs are less than 32 bytes and write flawlessly.
  • RXs are about 70 bytes long and I can only verify reconstruction of the first 6 values.

I believe that one of my settings is wrong or I my method for UART_READ is incorrect. There appears to be a bug in the UART2 driver which I am waiting for a TI Driver Expert to try to identify and resolve but that should not prevent me from fixing whatever is wrong with the buffer. 

Thank you,

Ken

SysConfig:

Global Variables:

// Read Buffers
const  size_t   RX_Size = 128;
static uint8_t  RX_COM1 [RX_Size];

Interface Initialization and Task:

// Initialize the UART driver.
UART2_Params_init(&COM_Params);
COM_Params.readMode     = UART2_Mode_CALLBACK;
COM_Params.readCallback = callbackFxn_read;
COM_Params.dataLength   = UART2_DataLen_8;
COM_Params.stopBits     = UART2_StopBits_1;
COM_Params.parityType   = UART2_Parity_NONE;
COM_Params.baudRate     = 115200;

COM_1 = UART2_open(UART2_Device1, &COM_Params);

if (COM_1 == NULL) {
    Display_printf(dispHost, 0, 0, "COM Task: Failure to Initialize\n");
    while(1);
} else {
    Display_printf(dispHost, 0, 0, "COM Task: Initialized Successfully\n");
}

while(1) {
    memset(RX_COM1, 0x00, sizeof(RX_COM1));
    size_t numBytesRead = 0;

    status = UART2_read(COM_1, &RX_COM1, RX_COM1, numBytesRead);

    if (status != UART2_STATUS_SUCCESS) {
        /* UART2_read() failed */
        Display_printf(dispHost, 0, 0, "COM: Failed to Read\n");
    }

    // Wake up the OS task
    Semaphore_pend(Semaphore_handle(&comTaskSemaphore), BIOS_WAIT_FOREVER);
    RX_Handler(RX_COM1,numBytesRead);
    WaitingForRX = false;

    // Flush the 32 byte Rx buffer internal to the UART2 Driver.
    UART2_flushRx(COM_1);
}

Functions:

/*
 *  ======== callbackFxn ========
 */
    void callbackFxn_read(UART2_Handle handle, void *buffer, size_t count, void *userArg, int_fast16_t status)
    {
        if (status != UART2_STATUS_SUCCESS) {
            /* RX error occured in UART2_read() */
            Display_printf(dispHost, 0, 0, "COM: Failed to Read\n");
        }

        // Wake up the OS task
        Semaphore_post(Semaphore_handle(&comTaskSemaphore));

    }

/*
 *  ===========================================================================
 *  Serial Port Interface
 *  ===========================================================================
 */

    void RX_Handler(uint8_t* RX_Buffer, size_t numBytes){
        // Debug Code
        Display_printf(dispHost, 0, 0, "COM: UART Received %u bytes!", numBytes);
        uint16_t loop;
        for (loop = 0; loop <= 255; loop++){
            if (RX_Buffer[loop] != 0x00){numBytes++;}
        }
        Display_printf(dispHost, 0, 0, "COM: Read Received %u bytes!\n\n",numBytes);
    }

Console Output:

[Cortex_M4_0] 
Host Display Initialized!
Tasks Initializing: 

COM Task: Initialized Successfully

COM: Requesting Data
Packed Message size: 6
COM: Sent 6 bytes
COM: UART Received 0 bytes!
COM: Read Received 54 bytes!


COM: Requesting Data
Packed Message size: 6
COM: Sent 6 bytes
COM: UART Received 0 bytes!
COM: Read Received 54 bytes!

Buffer Comparison:

I wrote down the values I observed on my oscilloscope and the values from the Buffer as seen in CCS 10.3.0

This corresponds with the above console output. The 54 Bytes read are likely the result of reading PAST the buffer (size 128 vs loop size 256).

  • GREEN values indicate confirmed Read Success
  • YELLOW values indicate unconfirmed Read
  • RED values indicate confirmed Read Failure
Oscilloscope RX UART RX Buffer
00 0x02 0x02
01 0x41 0x41
02 0x04 0x04
03 0x01 0x01
04 0x33 0x33
05 0xFD 0xFD
06 0x55 0x55
07 0x00 0x00
08 0x00 0x00
09 0x00 0x00
10 0x00 0x00
11 0x00 0x00
12 0x00 0x00
13 0x00 0x00
14 0x00 0x00
15 0x00 0x00
16 0x00 0x00
17 0x00 0x00
18 0x00 0x00
19 0x00 0x00
20 0x00 0x00
21 0x00 0x00
22 0x00 0x00
23 0x00 0x00
24 0x00 0x00
25 0x00 0x00
26 0x00 0x00
27 0x00 0x00
28 0x00 0x00
29 0x00 0x00
30 0x79 0x79
31 0x00 0x00
32 0x00 0x00
33 0x00 0x00
34 0x00 0x00
35 0x00 0x00
36 0x00 0x00
37 0x00 0x00
38 0x00 0x00
39 0x00 0x00
40 0x00 0x00
41 0x00 0x00
42 0x00 0x00
43 0x00 0x00
44 0x00 0x00
45 0x00 0x00
46 0x00 0x00
47 0x00 0x00
48 0x00 0x00
49 0x00 0x00
50 0x02 0x00
51 0x00 0x00
52 0x00 0x00
53 0x00 0x00
54 0x04 0x00
55 0x00 0x00
56 0x12 0x00
57 0x21 0x00
58 0xB9 0x00
59 0x40 0x00
60 0x00 0x00
61 0x00 0x00
62 0x00 0x00
63 0x00 0x00
64 0x00 0x00
65 0x00 0x00
66 0x00 0x00
67 0x56 0x00
68 0xC5 0x00
69 0x03 0x00
  • Thanks for the detailed analysis Ken, I will have a team member further investigate and reply by the end of this week.

    Regards,
    Ryan

  • Hey Ken,

    I used a LAUNHCXL-CC26X2R1with an RX/TX Ring Buffer Size of 128 and the following uart2callback.c which did not generate any unexpected results.

    #include <stdint.h>
    #include <stddef.h>
    
    /* POSIX Header files */
    #include <semaphore.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART2.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    static sem_t sem;
    static volatile size_t numBytesRead;
    
    const  size_t   RX_Size = 128;
    static uint8_t  RX_COM1 [128];
    static uint8_t  RX_Buffer [128];
    
    /*
     *  ======== callbackFxn ========
     */
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count,
            void *userArg, int_fast16_t status)
    {
        if (status != UART2_STATUS_SUCCESS) {
            /* RX error occured in UART2_read() */
            while (1);
        }
    
        numBytesRead = count;
        sem_post(&sem);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        const char        echoPrompt[] = "Echoing characters:\r\n";
        UART2_Handle      uart;
        UART2_Params      uartParams;
        int32_t           semStatus;
        uint32_t          status = UART2_STATUS_SUCCESS;
    
        /* Call driver init functions */
        GPIO_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Create semaphore */
        semStatus = sem_init(&sem, 0, 0);
    
        if (semStatus != 0) {
            /* Error creating semaphore */
            while (1);
        }
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
        uartParams.readMode = UART2_Mode_CALLBACK;
        uartParams.readCallback = callbackFxn;
        uartParams.baudRate = 115200;
    
        uart = UART2_open(CONFIG_UART2_0, &uartParams);
    
        if (uart == NULL) {
            /* UART2_open() failed */
            while (1);
        }
    
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        /* Pass NULL for bytesWritten since it's not used in this example */
        UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
    
        /* Loop forever echoing */
        while (1) {
            numBytesRead = 0;
    
            /* Pass NULL for bytesRead since it's not used in this example */
            status = UART2_read(uart, &RX_COM1, RX_Size, NULL);
    
            if (status != UART2_STATUS_SUCCESS) {
                /* UART2_read() failed */
                while (1);
            }
    
            /* Do not write until read callback executes */
            sem_wait(&sem);
    
            if (numBytesRead > 0) {
                status = UART2_write(uart, &RX_COM1, numBytesRead, NULL);
    
                uint16_t loop;
                for (loop = 0; loop <= numBytesRead; loop++){
                     RX_Buffer[loop] = RX_COM1[loop];}
    
                UART2_flushRx(uart);
    
                if (status != UART2_STATUS_SUCCESS) {
                    /* UART2_write() failed */
                    while (1);
    
                }
            }
        }
    }

    Can you please review and let me know what changes should be made to create the unexpected behavior?

    Regards,
    Ryan

  • Hi Ryan,

    Thanks for getting back to me. I have successfully validated the setup you provided and made modifications to my project directly based on your code. I am still unable to get the entire buffer sometimes, but now that I have a working example demonstrating the buffer can be returned correctly I feel more positive about putting a few more hours into getting to the bottom of this mystery. I think I have isolated the problem as I will detail at the end of this post and have provided updated example code for your review.


    uart2callback_CC26X2R1_LAUNCHXL_tirtos_ccs 

    Procedure:

    (1) I imported uart2callback_CC26X2R1_LAUNCHXL_tirtos_ccs from SDK 5.10 into my CCS 10.3.0 Workspace. I replaced all code within uart2callback.c with your code. The UART2 port for this example project is by default opened on the XDS110 port, so I opened a command shell console configured for the XD110 UART Serial Port. I have attached a photo of the Console which confirms that the setup is correct.

    (2) I proceeded to change the UART2 configuration in SysConfig by updating the TX/RX pins and assigning the RX/TX Ring Buffers to 128:

    (3) I modified the code in two locations to issue a prescribed command once:

    void *mainThread(void *arg0)
    {
        const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
        ...
        uart = UART2_open(CONFIG_UART2_0, &uartParams);
        UART2_flushRx(uart);
        ...
        
        /* Loop forever echoing */
        while (1) {
            ...
            if (numBytesRead > 0) {
                //status = UART2_write(uart, &RX_COM1, numBytesRead, NULL);
                ...
            }
        }
    }

    (4) I verified the communication (TX) with my scope:

    (5) I verified the communication (RX) with my scope at the beginning and end:

    (6) I validated the communication (RX) buffer by comparing the expected response against the RX_COM1 and RX_Buffer:

    Results:

    The posted example code is working correctly. After debugging it several times, however, the buffer starts exhibiting the fragmentation if I stop and restart the debugging process several times after minor code modifications. Clean builds do not affect this, only powering down the LaunchpadXL.


    Target Project

    Applied Critical Modifications to Project:

    1. SysConfig Ring Buffer should be set to an appropriate size (eg: 128).
    2. UART2 read callback function updates the number of bytes read rather than the size_t address argument of UART2_Read.

    Results with Critical Modifications to Project:

    • UART2 Callback function now reports 36 bytes have been received - but not the same 70 with the example code.
    • Buffer is still incomplete.

    Isolated Problem:

    What I have noticed is when I use a clock used to trigger the UART2_write of the command, the number of read bytes and buffer are incomplete. When I do not use a clock and only call the UART2_write statically, the number of read bytes and buffer are complete. 


    Updated Example Project

    I attempted to add a continuous clock from "util.h" to recreate the buffer corruption but found myself facing a number of compiler issues. I reviewed SYS/BIOS (TI-RTOS Kernel) User's Guide (Rev. V), chapter 5 "Timing Services" and observed a very different system for initializing clocks - though the core functionality appears identical. This leads me to believe that I am probably abusing "util.h" as a clock mechanism throughout my code. 

    uart2callback_CC26X2R1_LAUNCHXL_tirtos_ccs 

    #include <stdint.h>
    #include <stddef.h>
    
    /* POSIX Header files */
    #include <semaphore.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART2.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    static sem_t sem;
    static volatile size_t numBytesRead;
    static bool    WaitingForRX = false;
    
    const  size_t   RX_Size = 128;
    static uint8_t  RX_COM1   [RX_Size];
    static uint8_t  RX_Buffer [RX_Size];
    
    
    /*
     *  ======== TX Clock =========
     */
    #define REQUEST_DATA_T   20
        static Clock_Struct clock_Request;
            static void clockhandler_requestData(UArg arg) {
                if (!WaitingForRX){
                    const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
                    UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
                    WaitingForRX = true;
                }
            }
    
    /*
     *  ======== callbackFxn ========
     */
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count,
            void *userArg, int_fast16_t status)
    {
        if (status != UART2_STATUS_SUCCESS) {
            /* RX error occured in UART2_read() */
            while (1);
        }
    
        numBytesRead = count;
        sem_post(&sem);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
        UART2_Handle      uart;
        UART2_Params      uartParams;
        int32_t           semStatus;
        uint32_t          status = UART2_STATUS_SUCCESS;
    
        /* Call driver init functions */
        GPIO_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Create semaphore */
        semStatus = sem_init(&sem, 0, 0);
    
        if (semStatus != 0) {
            /* Error creating semaphore */
            while (1);
        }
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
        uartParams.readMode = UART2_Mode_CALLBACK;
        uartParams.readCallback = callbackFxn;
        uartParams.baudRate = 115200;
    
        uart = UART2_open(CONFIG_UART2_0, &uartParams);
        UART2_flushRx(uart);
    
        if (uart == NULL) {
            /* UART2_open() failed */
            while (1);
        }
    
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        /* Pass NULL for bytesWritten since it's not used in this example */
        //const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
        //UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
        Util_constructClock(&clock_Request,         clockhandler_requestData,     REQUEST_DATA_T, REQUEST_DATA_T, true,  NULL);
    
    
        /* Loop forever echoing */
        while (1) {
            numBytesRead = 0;
    
            /* Pass NULL for bytesRead since it's not used in this example */
            status = UART2_read(uart, &RX_COM1, RX_Size, NULL);
    
            if (status != UART2_STATUS_SUCCESS) {
                /* UART2_read() failed */
                while (1);
            }
    
            /* Do not write until read callback executes */
            sem_wait(&sem);
    
            if (numBytesRead > 0) {
    
                uint16_t loop;
                for (loop = 0; loop <= numBytesRead; loop++){
                     RX_Buffer[loop] = RX_COM1[loop];}
    
                UART2_flushRx(uart);
                WaitingForRX = false;
    
                if (status != UART2_STATUS_SUCCESS) {
                    /* UART2_write() failed */
                    while (1);
    
                }
            }
        }
    }

    Compiler Errors:

    **** Build of configuration Debug for project uart2callback_CC26X2R1_LAUNCHXL_tirtos_ccs ****
    
    "C:\\ti\\ccs1030\\ccs\\utils\\bin\\gmake" -k -j 8 all -O 
     
    Building file: "../uart2callback.c"
    Invoking: Arm Compiler
    "C:/ti/ccs1030/ccs/tools/compiler/ti-cgt-arm_20.2.4.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="C:/ESC_New/uart2callback_CC26X2R1_LAUNCHXL_tirtos_ccs" --include_path="C:/ESC_New/uart2callback_CC26X2R1_LAUNCHXL_tirtos_ccs/Debug" --include_path="C:/ti/simplelink_cc13x2_26x2_sdk_5_10_00_48/source" --include_path="C:/ti/simplelink_cc13x2_26x2_sdk_5_10_00_48/source/ti/posix/ccs" --include_path="C:/ti/ccs1030/ccs/tools/compiler/ti-cgt-arm_20.2.4.LTS/include" --define=DeviceFamily_CC26X2 -g --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on --preproc_with_compile --preproc_dependency="uart2callback.d_raw" --include_path="C:/ESC_New/uart2callback_CC26X2R1_LAUNCHXL_tirtos_ccs/Debug/syscfg" --cmd_file="C:/ESC_New/tirtos_builds_cc13x2_cc26x2_release_ccs/Debug/configPkg/compiler.opt"  "../uart2callback.c"
     
    >> Compilation failure
    subdir_rules.mk:9: recipe for target 'uart2callback.obj' failed
    "../uart2callback.c", line 19: warning #2170-D: use of a const variable in a constant expression is nonstandard in C
    "../uart2callback.c", line 20: warning #2170-D: use of a const variable in a constant expression is nonstandard in C
    "../uart2callback.c", line 27: error #20: identifier "Clock_Struct" is undefined
    "../uart2callback.c", line 28: error #20: identifier "UArg" is undefined
    "../uart2callback.c", line 31: error #20: identifier "uart" is undefined
    "../uart2callback.c", line 98: warning #225-D: function "Util_constructClock" declared implicitly
    "../uart2callback.c", line 58: warning #179-D: variable "echoPrompt" was declared but never referenced
    "../uart2callback.c", line 20: warning #552-D: variable "RX_Buffer" was set but never used
    3 errors detected in the compilation of "../uart2callback.c".
    gmake: *** [uart2callback.obj] Error 1
    gmake: Target 'all' not remade because of errors.
    
    **** Build Finished ****
    

    Using Clock Module:

     Clock_Params clockParams;
     Clock_Handle myClock;
     Error_Block eb;
    
     Error_init(&eb);
     Clock_Params_init(&clockParams);
     clockParams.period = 20;
     clockParams.startFlag = TRUE;
     clockParams.arg = (UArg)0x5555;
     myClock = Clock_create(clockhandler_requestData, 5, &clockParams, &eb);
     if (myClock == NULL) {
         Display_printf(dispHost, 0, 0, "COM1: Test Clock Failed!");
     }
     
     ...
     
        // Request Status Clock (in ms)
        static void clockhandler_requestData(UArg arg) {
            if (!WaitingForRX){
                Display_printf(dispHost, 0, 0, "COM1: Requesting Data");
                const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
                UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
                WaitingForRX = true;
            }
        }


    Mixed Sucess

    I think the problems can be attributed to an abuse of the util.h clock. The interrupt it generates is so strong that it affects the performance of the UART2 driver. That said, sometimes it returns a buffer length 70 and sometimes a buffer length of 36. The start delay and period of the clock do not influence the output.

  • If you want to use the BLE5 util.h/c resource, then you will have to add these files to your project's main directory and include several ble5stack search paths.  The code below does not produce any errors but was not functionally tested.

    /*
     * Copyright (c) 2020, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== uart2callback.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    
    /* POSIX Header files */
    #include <semaphore.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART2.h>
    #include <ti/sysbios/knl/Clock.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    #include "util.h"
    
    static sem_t sem;
    static volatile size_t numBytesRead;
    static bool    WaitingForRX = false;
    
    const  size_t   RX_Size = 128;
    static uint8_t  RX_COM1   [RX_Size];
    static uint8_t  RX_Buffer [RX_Size];
    
    /*
     *  ======== TX Clock =========
     */
    #define REQUEST_DATA_T   20
    static Clock_Struct clock_Request;
    static void clockhandler_requestData(UArg arg);
    UART2_Handle      uart;
    
    /*
     *  ======== callbackFxn ========
     */
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count,
            void *userArg, int_fast16_t status)
    {
        if (status != UART2_STATUS_SUCCESS) {
            /* RX error occured in UART2_read() */
            while (1);
        }
    
        numBytesRead = count;
        sem_post(&sem);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
        UART2_Params      uartParams;
        int32_t           semStatus;
        uint32_t          status = UART2_STATUS_SUCCESS;
    
        /* Call driver init functions */
        GPIO_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Create semaphore */
        semStatus = sem_init(&sem, 0, 0);
    
        if (semStatus != 0) {
            /* Error creating semaphore */
            while (1);
        }
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
        uartParams.readMode = UART2_Mode_CALLBACK;
        uartParams.readCallback = callbackFxn;
        uartParams.baudRate = 115200;
    
        uart = UART2_open(CONFIG_UART2_0, &uartParams);
        UART2_flushRx(uart);
    
        if (uart == NULL) {
            /* UART2_open() failed */
            while (1);
        }
    
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        /* Pass NULL for bytesWritten since it's not used in this example */
        //const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
        //UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
        Util_constructClock(&clock_Request,         clockhandler_requestData,     REQUEST_DATA_T, REQUEST_DATA_T, true,  NULL);
    
    
        /* Loop forever echoing */
        while (1) {
            numBytesRead = 0;
    
            /* Pass NULL for bytesRead since it's not used in this example */
            status = UART2_read(uart, &RX_COM1, RX_Size, NULL);
    
            if (status != UART2_STATUS_SUCCESS) {
                /* UART2_read() failed */
                while (1);
            }
    
            /* Do not write until read callback executes */
            sem_wait(&sem);
    
            if (numBytesRead > 0) {
    
                uint16_t loop;
                for (loop = 0; loop <= numBytesRead; loop++){
                     RX_Buffer[loop] = RX_COM1[loop];}
    
                UART2_flushRx(uart);
                WaitingForRX = false;
    
                if (status != UART2_STATUS_SUCCESS) {
                    /* UART2_write() failed */
                    while (1);
    
                }
            }
        }
    }
    
    static void clockhandler_requestData(UArg arg) {
        if (!WaitingForRX){
            const char        echoPrompt[] = {0x02,0x01,0x04,0x40,0x84,0x03};
            UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
            WaitingForRX = true;
        }
    }

    Otherwise you should be using the ti.sysbios.knl.Clock TI-RTOS Kernel Runtime API or Timer.h TI Drivers Runtime API for your Clock utility or timer needs.

    Regards,
    Ryan

  • Thank you Ryan,

    Your example works on both Launchpad and custom PCB. I can't quite explain why the code didn't originally work in my target project, but at this point I think it is better to just start fresh with the modified example. I want to really thank you for all of your help - I could not have solved this without your insights.

    Best,

    Ken