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.

LAUNCHXL-F280049C: TI GUI Connecting with USB-UART

Part Number: LAUNCHXL-F280049C

Tool/software:

Short Description: Trying to communicate with microcontroller from laptop through a USB TO UART bridge. GUI Composer automatically picks COM port with debug probe, but we want to use the USB TO UART bridge COM port which appears in the menu as Microsoft and won't let us connect to. It will let us select it but when running GUI composer, it automatically switches back to the debug probe.

Detailed: We are trying to communicate with the F280049C board using a USB to UART Bridge from the TI GUI Composer. We can run Tera Term and communicate effectively while running the board's code on CCS but when trying to configure the TI GUI to recognize a USB-UART communication path rather than the typical debug probe, we aren't able to connect to the com port and are either stuck with the debug com port or we get the error message that it can't connect to the board. After some research, we've been seeing that we need to create a JavaScript language conversion method? Here is the code below without any language conversion changes but it accomplishes the tasks that we want it to using tera term. Essentially the program will use a random number generator to simulate readings from a sensor and then in the terminal you are able to type: "position_cmd: (Any number here)" and it will update the variable being outputted to the terminal to the number that you just typed. On the TI Gui, I was wanting a textbox in which I could type the number that I want position_cmd to be and then I will see that output on a line graph in the TI GUI Composer as well. Is it possible to communicate with the TI GUI or do we have to make our own custom interface?


#include "driverlib.h"
#include "device.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define INPUT_BUF_LEN 32
#define POSITION_MIN 0
#define POSITION_MAX 100
#define PRINT_PERIOD_MS 500    // Print every 500 ms
#define RANDOM_PERIOD_MS 2000  // New random every 2000 ms
#define HOLD_PERIOD_MS 2000    // Hold manual value for 2000 ms

volatile uint16_t position = 0;
volatile uint16_t print_flag = 0;
volatile uint16_t random_flag = 0;
volatile uint16_t manual_hold_active = 0;
volatile uint16_t hold_elapsed_ms = 0;

void initTimers(void);
__interrupt void printTimerISR(void);
__interrupt void randomTimerISR(void);
uint16_t pseudo_random(uint16_t seed);

void main(void)
{
    uint16_t receivedChar;
    unsigned char inputBuffer[INPUT_BUF_LEN];
    uint16_t idx;
    char msg[64];
    uint16_t seed = 1234; // Arbitrary seed

    Device_init();
    Device_initGPIO();

    // SCI GPIO configuration (SCIB RX: GPIO13, TX: GPIO40)
    GPIO_setControllerCore(13, GPIO_CORE_CPU1);
    GPIO_setPinConfig(GPIO_13_SCIB_RX);
    GPIO_setDirectionMode(13, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(13, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(13, GPIO_QUAL_ASYNC);

    GPIO_setControllerCore(40, GPIO_CORE_CPU1);
    GPIO_setPinConfig(GPIO_40_SCIB_TX);
    GPIO_setDirectionMode(40, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(40, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(40, GPIO_QUAL_ASYNC);

    Interrupt_initModule();
    Interrupt_initVectorTable();

    // Register ISRs
    Interrupt_register(INT_TIMER0, &printTimerISR);
    Interrupt_register(INT_TIMER1, &randomTimerISR);

    // Initialize timers
    initTimers();

    SCI_performSoftwareReset(SCIB_BASE);
    SCI_setConfig(SCIB_BASE, DEVICE_LSPCLK_FREQ, 9600, (SCI_CONFIG_WLEN_8 |
                                                        SCI_CONFIG_STOP_ONE |
                                                        SCI_CONFIG_PAR_NONE));
    SCI_resetChannels(SCIB_BASE);
    SCI_resetRxFIFO(SCIB_BASE);
    SCI_resetTxFIFO(SCIB_BASE);
    SCI_clearInterruptStatus(SCIB_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
    SCI_enableFIFO(SCIB_BASE);
    SCI_enableModule(SCIB_BASE);
    SCI_performSoftwareReset(SCIB_BASE);

    // Enable timer interrupts
    Interrupt_enable(INT_TIMER0);
    Interrupt_enable(INT_TIMER1);
    CPUTimer_enableInterrupt(CPUTIMER0_BASE);
    CPUTimer_enableInterrupt(CPUTIMER1_BASE);

    EINT;
    ERTM;

    // Initial random position
    position = pseudo_random(seed) % (POSITION_MAX - POSITION_MIN + 1) + POSITION_MIN;

    for (;;)
    {
        // Print position every 500 ms
        if (print_flag)
        {
            snprintf(msg, sizeof(msg), "\r\nThe position is %u radians\n", position);
            SCI_writeCharArray(SCIB_BASE, (uint16_t*)msg, strlen(msg));
            print_flag = 0;
        }

        // Update position randomly every 2000 ms (if not in manual hold)
        if (random_flag)
        {
            if (!manual_hold_active)
            {
                static uint16_t rand_seed = 0;
                rand_seed++;
                position = pseudo_random(rand_seed) % (POSITION_MAX - POSITION_MIN + 1) + POSITION_MIN;
            }
            random_flag = 0;
        }

        // Check for incoming data (non-blocking)
        if (SCI_getRxFIFOStatus(SCIB_BASE) != SCI_FIFO_RX0)
        {
            idx = 0;
            while (1)
            {
                receivedChar = SCI_readCharBlockingFIFO(SCIB_BASE);
                SCI_writeCharBlockingFIFO(SCIB_BASE, receivedChar); // Echo

                if (receivedChar == '\r' || receivedChar == '\n')
                {
                    inputBuffer[idx] = '\0';
                    break;
                }
                if (idx < INPUT_BUF_LEN - 1)
                {
                    inputBuffer[idx++] = (unsigned char)receivedChar;
                }
            }

            // Parse command
            if (strncmp((char*)inputBuffer, "position_cmd:", 13) == 0)
            {
                int new_pos = atoi((char*)inputBuffer + 13);
                if (new_pos >= POSITION_MIN && new_pos <= POSITION_MAX)
                {
                    position = (uint16_t)new_pos;
                    manual_hold_active = 1;
                    hold_elapsed_ms = 0;
                    snprintf(msg, sizeof(msg), "\r\nThe position is %u radians\n", position);
                    SCI_writeCharArray(SCIB_BASE, (uint16_t*)msg, strlen(msg));
                }
            }
        }
    }
}

// Simple pseudo-random number generator (linear congruential)
uint16_t pseudo_random(uint16_t seed)
{
    static uint16_t lfsr = 0;
    if (seed != 0) lfsr = seed;
    lfsr = (lfsr * 1103515245 + 12345) & 0x7FFF;
    return lfsr;
}

// Initialize two timers: one for printing, one for random update
void initTimers(void)
{
    // Timer0: Print every 500 ms
    uint32_t print_cycles = (DEVICE_SYSCLK_FREQ / 1000) * PRINT_PERIOD_MS - 1;
    CPUTimer_setPeriod(CPUTIMER0_BASE, print_cycles);
    CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
    CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    CPUTimer_startTimer(CPUTIMER0_BASE);

    // Timer1: Random update every 2000 ms
    uint32_t random_cycles = (DEVICE_SYSCLK_FREQ / 1000) * RANDOM_PERIOD_MS - 1;
    CPUTimer_setPeriod(CPUTIMER1_BASE, random_cycles);
    CPUTimer_setPreScaler(CPUTIMER1_BASE, 0);
    CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);
    CPUTimer_startTimer(CPUTIMER1_BASE);
}

// Timer0 ISR: set print flag every 500 ms, manage manual hold timer
__interrupt void printTimerISR(void)
{
    print_flag = 1;
    if (manual_hold_active)
    {
        hold_elapsed_ms += PRINT_PERIOD_MS;
        if (hold_elapsed_ms >= HOLD_PERIOD_MS)
        {
            manual_hold_active = 0;
            hold_elapsed_ms = 0;
        }
    }
    CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

// Timer1 ISR: set random flag every 2000 ms
__interrupt void randomTimerISR(void)
{
    random_flag = 1;
    CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}