UART2 Dynamic Pin Switching

The UART2 TX and RX pins can be reassigned during runtime. This can enable the CC23xx to interface with multiple UART streams connected to different TX/RX pins during runtime.

UART2 TX/RX Pin Switching Functionality

The run-time UART2 pin reconfiguration can be implemented using the UART2switchPins() function displayed below:

static void UART2switchPins(uint8_t oldTxPin, uint8_t oldRxPin, uint8_t newTxPin, uint8_t newRxPin, uint8_t newTxMux, uint8_t newRxMux)
{
   //Settings old UART pins to internal MUX
   GPIO_setMux(oldTxPin, GPIO_MUX_GPIO_INTERNAL);
   GPIO_setMux(oldRxPin, GPIO_MUX_GPIO_INTERNAL);

   // Configuring new UART pins for UART
   GPIO_setConfig(newTxPin, GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_HIGH);
   GPIO_setConfig(newRxPin, GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_DOWN_INTERNAL);

   // Configuring new UART pins with new MUX
   GPIO_setMux(newTxPin, newTxMux);
   GPIO_setMux(newRxPin, newRxMux);

   return;
}

The UART2switchPins() function takes in the currently used UART pins, the new UART pins along with the new MUX, and reconfigures them such that the new pins are now used for UART transmissions.

Before the function is called, the UART RX/TX buffers should be cleared, this can be done by closing and re-opening the UART2 handle.

UART2 Dynamic Pin Switching Example

The UART2 Dynamic Pin Switching functionality has been added to the uart2echo example and the application code can be found in this section. In this example, the UART pins change whenever either of the LaunchPad buttons are pressed.

#include <stdint.h>
#include <stddef.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART2.h>
#include "ti_drivers_config.h"


UART2_Handle uart;
uint8_t xdsUARTStatus = 0;
uint8_t altUARTStatus = 0;



static void UART2switchPins(uint8_t oldTxPin, uint8_t oldRxPin, uint8_t newTxPin, uint8_t newRxPin, uint8_t newTxMux, uint8_t newRxMux)
{
   //Settings old UART pins to internal MUX
   GPIO_setMux(oldTxPin, GPIO_MUX_GPIO_INTERNAL);
   GPIO_setMux(oldRxPin, GPIO_MUX_GPIO_INTERNAL);

   // Configuring new UART pins for UART
   GPIO_setConfig(newTxPin, GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_HIGH);
   GPIO_setConfig(newRxPin, GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_DOWN_INTERNAL);

   // Configuring new UART pins with new MUX
   GPIO_setMux(newTxPin, newTxMux);
   GPIO_setMux(newRxPin, newRxMux);

   return;
}


/*
*  ======== mainThread ========
*/
void *mainThread(void *arg0)
{
   const char   switchingAltMsg[] = "\r\nSwitching UART to DIO13 & DIO12:\r\n";
   const char   switchingXDSMsg[] = "\r\nSwitching UART to DIO20 & DIO22:\r\n";
   const char   echoPrompt[] = "Echoing characters:\r\n";
   char         input;
   UART2_Params uartParams;
   size_t       bytesRead;
   size_t       bytesWritten = 0;
   uint32_t     status = UART2_STATUS_SUCCESS;


   /* Call driver init functions */
   GPIO_init();
   /* Configure the LED and button pins */
   GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
   GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

   /* Turn on user LED */
   GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

   /* Create a UART where the default read and write mode is BLOCKING */
   UART2_Params_init(&uartParams);
   uartParams.baudRate = 115200;
   uartParams.readMode = UART2_Mode_NONBLOCKING;

   uart = UART2_open(CONFIG_UART2_0, &uartParams);

   if (uart == NULL) {
      /* UART2_open() failed */
      while (1);
   }

   // XDS UART pins are being used
   xdsUARTStatus = 1;

   /* Turn on user LED to indicate successful initialization */
   GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);
   UART2_write(uart, echoPrompt, sizeof(echoPrompt), &bytesWritten);

   /* Loop forever echoing */
   while (1) {
      bytesRead = 0;
      while (bytesRead == 0  && GPIO_read(CONFIG_GPIO_BUTTON_0) != 0 && GPIO_read(CONFIG_GPIO_BUTTON_1) != 0) {
            status = UART2_read(uart, &input, 1, &bytesRead);

            if (status != UART2_STATUS_SUCCESS && status !=UART2_STATUS_EAGAIN) {
               /* UART2_read() failed */
               while (1);
            }
      }

      bytesWritten = 0;
      while (bytesWritten == 0 && GPIO_read(CONFIG_GPIO_BUTTON_0) != 0 && GPIO_read(CONFIG_GPIO_BUTTON_1) != 0) {
            status = UART2_write(uart, &input, 1, &bytesWritten);

            if (status != UART2_STATUS_SUCCESS) {
               /* UART2_write() failed */
               while (1);
            }
      }

      // Reconfigure UART to use XDS uart (DIO20 and DIO22)
      if(GPIO_read(CONFIG_GPIO_BUTTON_0) == 0)
      {
            // Clear other UART
            altUARTStatus = 0;

            // If we are not in this UART config
            if(xdsUARTStatus != 1)
            {
               // Close and restart UART to clear buffers
               UART2_close(uart);
               UART2_open(CONFIG_UART2_0, &uartParams);

               // Perform the switch
               UART2switchPins(13, 12, 20, 22, 2, 2);  // Old TX/RX ((13,12) New TX/RX (20,22) New MUX TX/RX (2,2)

               // Set the current UART
               xdsUARTStatus = 1;

               // Print switch message
               UART2_write(uart, &switchingXDSMsg, sizeof(switchingXDSMsg), &bytesWritten);
               UART2_flushRx(uart);
            }
      }

      // Reconfigure UART to use alternative UART (DIO13 and DIO12)
      if(GPIO_read(CONFIG_GPIO_BUTTON_1) == 0)
      {
            // Clear other UART
            xdsUARTStatus = 0;

            // If we are not in this UART config
            if(altUARTStatus != 1)
            {
               // Close and restart UART to clear buffers
               UART2_close(uart);
               UART2_open(CONFIG_UART2_0, &uartParams);

               // Perform the switch
               UART2switchPins(20, 22, 13, 12, 3, 3);  // Old TX/RX (20,22) New TX/RX (13,12) New MUX TX/RX (3,3)

               // Set the current UART
               altUARTStatus = 1;

               // Print switch message
               UART2_write(uart, &switchingAltMsg, sizeof(switchingAltMsg), &bytesWritten);
               UART2_flushRx(uart);
            }
      }
      // Reset input buffer
      input = 0;
   }

   return NULL;
}