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.

CC2640R2F: Can you have multiple Uart ports?

Part Number: CC2640R2F


I have to switch between two uart ports. The base address used in the uart setup is UART0_BASE. How can I add another uart port?

  • Hello Krishna,

    There is only 1 UART module for the main application processor (CM3), but you can also use the sensor controller UART emulator in parallel on separate pins.

    If you want to simply switch between different pins for the main UART module I believe you can extend the uartCC26XXHWAttrs in CC2640R2_LAUNCHXL.c and CC2640R2_LAUNCHXL.h in similar fashion as is done for SPI, except duplicate everything except pins and make sure never to open both Board_UART0 and Board_UART1 at the same time. I have not tested this myself, so let me know how it works.

    in Board.h

    #define Board_UART0             CC2640R2_LAUNCHXL_UART0

    #define Board_UART1             CC2640R2_LAUNCHXL_UART0

  • Hello Eirik,

    I have tried to do something like that (code below). When I want to switch, should I close UART0 and open UART1? Is that how you are suggesting to switch?

    UARTCC26XX_Object uartCC26XXObjects[UARTCOUNT];

    uint8_t uartCC26XXRingBuffer[UARTCOUNT][255];

    const UARTCC26XX_HWAttrsV2 uartCC26XXHWAttrs[UARTCOUNT] = {
    {
    .baseAddr = UART0_BASE,
    .powerMngrId = PowerCC26XX_PERIPH_UART0,
    .intNum = INT_UART0_COMB,
    .intPriority = ~0,
    .swiPriority = 0,
    .txPin = M_BLE_U_TX,
    .rxPin = M_BLE_U_RX,
    .ctsPin = PIN_UNASSIGNED,
    .rtsPin = PIN_UNASSIGNED,
    .ringBufPtr = uartCC26XXRingBuffer[UART0],
    .ringBufSize = sizeof(uartCC26XXRingBuffer[UART0]),
    .txIntFifoThr = UARTCC26XX_FIFO_THRESHOLD_1_8,
    .rxIntFifoThr = UARTCC26XX_FIFO_THRESHOLD_4_8,
    .errorFxn = NULL
    },
    {
    .baseAddr = UART0_BASE,
    .powerMngrId = PowerCC26XX_PERIPH_UART0,
    .intNum = INT_UART0_COMB,
    .intPriority = ~0,
    .swiPriority = 0,
    .txPin = S_U1_TX,
    .rxPin = S_U1_RX,
    .ctsPin = PIN_UNASSIGNED,
    .rtsPin = PIN_UNASSIGNED,
    .ringBufPtr = uartCC26XXRingBuffer[UART1],
    .ringBufSize = sizeof(uartCC26XXRingBuffer[UART1]),
    .txIntFifoThr = UARTCC26XX_FIFO_THRESHOLD_1_8,
    .rxIntFifoThr = UARTCC26XX_FIFO_THRESHOLD_4_8,
    .errorFxn = NULL
    }
    };

  • You can also use simulated UART in sensor controller.

  • Correct. That was the idea, but I have not had time to test it. Let me know how it works out.

  • The process halts when I try to close Uart0 and open Uart1. Any other peripheral that can be ported as UART?

  • How can I go about doing this?

  • You can install sensor controller Studio and find Uart emulator example in it.

  • Show me how you open, close and open again in code.

    Did you also increase the count?

    typedef enum CC2640R2_LAUNCHXL_UARTName {
        CC2640R2_LAUNCHXL_UART0 = 0,
        CC2640R2_LAUNCHXL_UART1 
    
        CC2640R2_LAUNCHXL_UARTCOUNT
    } CC2640R2_LAUNCHXL_UARTName;

    And added UAR config?

    const UART_Config UART_config[CC2640R2_LAUNCHXL_UARTCOUNT] = {
        {
            .fxnTablePtr = &UARTCC26XX_fxnTable,
            .object      = &uartCC26XXObjects[CC2640R2_LAUNCHXL_UART0],
            .hwAttrs     = &uartCC26XXHWAttrs[CC2640R2_LAUNCHXL_UART0]
        },
        {
            .fxnTablePtr = &UARTCC26XX_fxnTable,
            .object      = &uartCC26XXObjects[CC2640R2_LAUNCHXL_UART1],
            .hwAttrs     = &uartCC26XXHWAttrs[CC2640R2_LAUNCHXL_UART1]
        },
    };
  • Yes I did both the steps as mentioned by you. Depending on the message, I have two sequence to switch between the two uart ports.

    if(dataIn[0] == 's')
    {
    newMsg->len = len-2;
    memcpy(newMsg->buffer,(char *)&dataIn[SIZE_OF_MSG_PREFIX], len);
    List_put(&uartWriteList, (List_Elem *) newMsg);
    // If no write is currently active, start a new one
    if (uartWriteActive == 0)
    {
    uartWriteActive = 1;
    mainActive = false;
    uartCurrentMsg = (uartMsg_t *) List_get(&uartWriteList);

     UART_close(UART0); 

    uartHandleSafety = UART_open(UART1, &uartParams);

    UART_write(uartHandleSafety, uartCurrentMsg->buffer, uartCurrentMsg->len);

    }
    }
    else
    {
    newMsg->len = len;
    memcpy(newMsg->buffer, dataIn, len);
    List_put(&uartWriteList, (List_Elem *) newMsg);
    // If no write is currently active, start a new one
    if (uartWriteActive == 0)
    {
    uartWriteActive = 1;
    mainActive = true;
    uartCurrentMsg = (uartMsg_t *) List_get(&uartWriteList);

    UART_close(UART1); 

    uartHandleMain = UART_open(UART0, &uartParams); 

    UART_write(uartHandleMain, uartCurrentMsg->buffer, uartCurrentMsg->len);
    }

  • UART_close use the handle as an argument:

    UART_close(uartHandleSafety ); 

    http://dev.ti.com/tirex/explore/node?node=ADfS7ixpgUmHy56H6NON4Q__krol.2c__LATEST

  • Thank you I was able to switch between two Uarts. If I need to have both Uarts open, I will have to setup a emulator for the second one right? There is not other way, I guess.

  • Yes, you have to use sensor controller to emulate second UART if you need two UART opened at the same time.

  • Hello Yikai Chen,

    Can you please explain if the board can support only one Uart instance how does the uart emulator work?Assuming I am able to send and receive on both uarts at the same time.

  • CC2640R2F only supports one UART so if you need two UARTs. The alternative is to use sensor controller, which is another MCU in CC2640R2, to simulate another UART. Then, you can have two UARTs.