Introduction

SysConfig is a tool that helps simplify the configuration of your application on a SimpleLink device.

The basic idea of SysConfig is to allow intuitive and natural configuration of key components in an application. The SysCofnig tool will generate source code to configure these components (e.g. TI Drivers, networking stacks) based on the settings in the SysConfig configuration file (i.e. .syscfg). This generated code is then included in the application. For example, SysConfig will create and fill in all the 'C' structures needed by the TI Driver modules.

This lab is an introduction to SysConfig and will focus on its integration with TI Drivers modules (e.g. UART, I2C, etc.). Additional labs will be available for other key components (e.g. Networking stacks, BLE stack, etc.) but this lab is considered the starting point to understand and learn the power of SysConfig.

SysConfig is not dependent on an RTOS, compiler toolchain, or IDE. Additionally SysConfig is available

  • with CCS Desktop (which this lab will focus on).
  • with CCS Cloud
  • as a stand-alone desktop tool
  • as a cmdline tool

The tasks in this lab session are targeted to be completed within an hour time frame.

What SysConfig is not

Currently SysConfig is generally focused on generating configuration code. For example, the tool generates the configuration code for TI Drivers, but it does not generate code for the Driver init or open calls. For example, the application writer can use SysConfig to configure an I2C peripheral, but the writer must supply the calls to I2C_init, I2C_open, and I2C_transfer. Please refer to the documentation for each component in SysConfig for more information.

Here's what we'll learn

  • Introduction to SysConfig
  • Learn how to use SysConfig to configure TI Drivers in your application

Preview Disclaimer

Currently the SysConfig tool is available in CCS 8.2 (and higher). The SimpleLink SDKs are shipping TI Drivers examples (and a few others) in the examples/syscfg_preview directory that use SysConfig to setup the TI Drivers. These examples are not currently available via Resource Explorer. Therefore to play with SysConfig, the easiest way is to import an examples/syscfg_preview example directly into CCS as described below in this lab. Note: this currently requires that you have CCS and the SimpleLink SDK installed on your computer.

The documentation for SysConfig is still being developed. For now we have the following site that offers more details: SysConfig Preview.

Please note, not all boards are currently supported. Over the following quarters, the SimpleLink SDK will expand the use of SysConfig to include all boards, things like stack configuration, RTOS configuration, etc. Additional SimpleLink Academy labs will be rolled out as the new functionality becomes available.

Prerequisites

Software for development

Hardware requirements

You can use this workshop with any cc13xx, CC26xx, MSP432, or CC32xx LaunchPad Development Kit.

TI Driver Configuration

TI Drivers rely on the application to supply the driver configuration. The majority of this configuration is supplied in 'C' structures and arrays. For example, the below code sets up a I2C peripheral to be used in a TI Drivers example for the CC26X2R1_LAUNCHXL board.

This approach minimizes runtime allocation and overall footprint of the application.

The following two sections show the two ways this configuration is supplied

  • Current/Legacy: application supplies the source code
  • SysConfig: source code is generated based on configuration in SysConfig

Runtime usage of the TI Drivers

To use a TI Driver instance, you still must open it (e.g. UART_open must be called by the application) regardless of the method used to supply the TI Driver configuration.

Current/Legacy Approach

Projects must supply the needed TI Driver configuration in the Board source files. For example, here is the empty project for the CC26X2R1_LAUNCHXL. The Board source files that contain the TI Drivers configuration are circled.

Generally, the Board source file are the same for all TI Driver examples for a given board.

SysConfig Approach

With SysConfig, the configuration of the TI Drivers is the same, but instead of having the application writer supply the 'C' structures/arrays, the SysConfig tool generates the 'C' code for you instead.

The .syscfg file in a project holds all the configuration for the TI Drivers that will be used by the application. As part of the build, SysConfig will parse the .syscfg file and generate the needed 'C' structures/arrays for the TI Drivers.

Editing the .syscfg file

TI recommends that the .syscfg file only be modified via the SysConfig tool.

Then if you peek into Board.c for this example, we only see the configuration that is needed for the application (e.g. no I2C configuration since the empty example does not use I2C).

   /*
    *  ======== Board.c ========
    *  Configured TI-Drivers module definitions
    *
    *  DO NOT EDIT - This file is generated for the CC26X2R1_LAUNCHXL
    *  by the SysConfig tool.
    */

   #include <stddef.h>

   #ifndef DeviceFamily_CC26X2
   #define DeviceFamily_CC26X2
   #endif

   #include <ti/devices/DeviceFamily.h>

   #include "Board.h"

   /*
    *  =============================== GPIO ===============================
    */

   #include <ti/drivers/GPIO.h>
   #include <ti/drivers/gpio/GPIOCC26XX.h>

   /*
    *  ======== gpioPinConfigs ========
    *  Array of Pin configurations
    */
   GPIO_PinConfig gpioPinConfigs[] = {
       /* Board_GPIO_LED0 : LaunchPad LED Red */
       GPIOCC26XX_DIO_06 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_LOW,
   };

   /*
    *  ======== GPIOCC26XX_config ========
    */
   const GPIOCC26XX_Config GPIOCC26XX_config = {
       .pinConfigs = (GPIO_PinConfig *)gpioPinConfigs,
       .callbacks = NULL,
       .numberOfPinConfigs = 1,
       .numberOfCallbacks = 0,
       .intPriority = (~0)
   };


   /*
    *  =============================== PIN ===============================
    */

   #include <ti/drivers/PIN.h>
   #include <ti/drivers/pin/PINCC26XX.h>

   const PIN_Config BoardGpioInitTable[] = {
       /* LaunchPad LED Red, Parent Signal: Board_GPIO_LED0 GPIO Pin, (DIO6) */
       Board_PIN0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MED,

       PIN_TERMINATE
   };

   const PINCC26XX_HWAttrs PINCC26XX_hwAttrs = {
       .intPriority = (~0),
       .swiPriority = 0
   };




   /*
    *  =============================== Power ===============================
    */
   #include <ti/drivers/Power.h>
   #include <ti/drivers/power/PowerCC26X2.h>
   #include "Board.h"

   extern void PowerCC26XX_standbyPolicy(void);
   extern bool PowerCC26XX_calibrate(unsigned int);

   const PowerCC26X2_Config PowerCC26X2_config = {
       .enablePolicy             = true,
       .policyInitFxn            = NULL,
       .policyFxn                = PowerCC26XX_standbyPolicy,
       .calibrateFxn             = PowerCC26XX_calibrate,
       .calibrateRCOSC_LF        = true,
       .calibrateRCOSC_HF        = true
   };


   /*
    *  ======== Board_initHook ========
    *  Perform any board-specific initialization needed at startup.  This
    *  function is declared weak to allow applications to override it if needed.
    */
   #if defined(__IAR_SYSTEMS_ICC__)
   __weak void Board_initHook(void)
   #elif defined(__GNUC__) && !defined(__ti__)
   void __attribute__((weak)) Board_initHook(void)
   #else
   #pragma WEAK (Board_initHook)
   void Board_initHook(void)
   #endif
   {
   }

   /*
    *  ======== Board_init ========
    *  Perform any initialization needed before using any board APIs
    */
   void Board_init(void)
   {
       /* ==== /ti/drivers/Power initialization ==== */
       Power_init();

       /* ==== /ti/drivers/PIN initialization ==== */
       if (PIN_init(BoardGpioInitTable) != PIN_SUCCESS) {
           /* Error with PIN_init */
           while (1);
       }

       Board_initHook();
   }

Board.c

The SysConfig approach has the following advantages over having the application writer supply source code:

  • Adding a driver instance is easier.
  • Reduces the number of mistakes since the 'C' code is generated instead of hand-written (or copied/pasted).
  • The Board source files are specifically tailored to your application with SysConfig. With the legacy approach, TI Drivers examples have worst-case coverage (e.g. I2C configuration is present even if not using it).
  • SysConfig reduces the number of Board source files from 3 to 2 for TI Driver's configuration.
  • Changes between versions are handled more seamlessly. Note: this is not a common occurrance, but annoying when it happens!

How is .syscfg different from .cfg (for TI-RTOS users)

The TI-RTOS configuration file (.cfg) is used to configure the kernel. Similar to the .syscfg file, the .cfg file is parsed and source files are generated. Currently the SysConfig tool does not configure TI-RTOS, so the .cfg file is still needed for TI-RTOS based applications.

Quiz

Does SysConfig change the runtime usage of TI Drivers?

Lab: Getting started

For this lab, we are going to import the Empty example from the examples\syscfg_preview directory. We'll do the following things in the below tasks

  • Investigate the .syscfg file
  • Configure the Display module in SysConfig
  • Configure the Watchdog module in SysConfig
  • Add a button via SysConfig that will stop the tickling/feeding of the Watchdog timer.

The below steps will use simplelink_cc26x2_sdk_2_40 along with the CC26X2R1_LAUNCHXL LaunchPad board. So some of the pictures/directory names/line numbers/sizes/etc. might be slightly different if you are using a different board or version.

Task 1 - Importing an Example

Start your Desktop CCS and import the TI-RTOS empty project from your SimpleLink SDK. Since SysConfig is still preview, it has not been incorporated into Resource Explorer, so we'll import via the CCS Project tab. Please make sure to select the syscfg_preview directory!

  1. Select ProjectImport CCS Project... in CCS and navigate to <SL_SDK>\examples\syscfg_preview\rtos\CC26X2R1_LAUNCHXL\drivers\empty\tirtos\ccs
  2. Select the project and hit Finish

After importing, you should see two projects in Project Explorer...empty (the application project) and kernel project. Also note the Debug directory is empty. The generated TI Drivers Board files will go into the Debug\syscfg as part of the build.

Task 2 - Verifying the Example Works

To test that the software and hardware pre-requisites are fulfilled, we are going to build and run the project before going forward. This will generate the Board.c and Board.h files also.

  1. Our first mission is to build the imported project. Select the project in Project Explorer and choose ProjectBuild Project from the menu. Notice the beginning of the application project build log that SysConfig generates the Board files (which are now in the Debug/syscfg directory). Note: as more SDK components start to be integrated with SysConfig, more files will be generated.

  2. When the project is built, we are going to make sure that the hardware and debugger work.

    • Make sure the target is connected to the computer via the appropiate USB cable (please refer to the Board.html file in the empty project to locate the USB connector used for emulation).
    • To start debugging, select RunDebug, or press F11.
  3. When the download is finished, press F8 or the green play icon to run.
  4. You should see an LED toggle every second. Here is the code for the toggling in empty.c. Remember the constant Board_GPIO_LED0! We'll see where it comes from in the next step...
      while (1) {
          sleep(time);
          GPIO_toggle(Board_GPIO_LED0);
      }
    

Quiz

Board.c and Board.h are the only files ever generated by SysConfig?

Task 3 - Exploring SysConfig (Software)

Now that we've confirmed the setup is working, now let's actually look at the SysConfig GUI Tool in CCS. We'll see where the Board_GPIO_LED0 constant was defined and how the GPIO configuration was done also.

  1. Double-click the empty.syscfg file in the Project Explorer. After a couple seconds you should see this window.

  2. Let's look at a preview of the TI Driver configuration code that is going to be generated by the empty.syscfg file. Select the <> icon on the top right of the SysConfig GUI. Note: all SysConfig generated files can be previewed here. For example ti_ndk_Config.c file for MSP432E4 Networking configuration.

  3. Click the Board.c file. This opens the preview of the generated Board.c. In later tasks in this lab, you'll see this file updated as we change the TI Driver configuration. As you look at the Board.c, you'll notice it is rather empty (as expected...the project is called Empty after all). Let's look at a couple key items in this file

    • Generation Disclaimer: At the top, you'll see the disclaimer to not modify this file since it is generated. Any changes made to this file will be wiped out when it is re-generated. We'll show how to modify these generated files later on in this lab (spoiler...add the files to the project and exclude the .syscfg file).
    • Configuration of the LED: The configuration for the LED that this example uses.

      Device/Board Specific

      Since the low level driver configuration is device/board specific, if you are using a different device or board, your generated Board.c will have different names for the constants and data structures.

  4. Select the GPIO module in the Software view. Here is the configuration for there the LED that the example uses.

    Where did the LaunchPad LED Red in the Use Hardware field in the above picture come from?

    Next section:)

Quiz

We've still not really answered where Board_GPIO_LED0 is defined. We see it in the GPIO configuration in the GUI, but where is the actual source code for it!

Task 4 - Exploring SysConfig (Hardware)

  1. Select the Hardware view. The hardware components on this LaunchPad are defined under this section. You can see that the LaunchPad LED Red is being currently used (green check-mark) and shows the software configuration of it.

Custom Hardware

SysConfig supports all the SimpleLink LaunchPads and many BoosterPacks. Documentation (and a SimpleLink Academy Lab) will be provided in the future to show how to integrate in your custom board(s).

Task 5 - Output via the Display Module

Let's start using SysConfig to configure new things! First let's add a Display_printf to see output via the UART. All SimpleLink LaunchPads have a back-channel UART via the emulation USB cable.

  1. Have the Board.c preview open in SysConfig. We can see the Display source code configuration get added when you do the next step!

  2. In SysConfig, click the + icon next to the Display module and then select XDS110 UART in the Use Hardware drop-down and save the file. When you hit the + icon, you'll see the Board.c file change in the preview.

  3. Now let's add the usage of the Display module into the empty.c file.

    • Add Display.h header

      #include <ti/display/Display.h>
      

      empty.c Add in with other #includes

    • Add initialization of the Display instance. Also add a count variable that will be used in the Display_printf.

      Display_init();
      Display_Handle hSerial = Display_open(Display_Type_UART, NULL);
      uint32_t count = 0;
      

      empty.c :: mainThread() in the function before the while loop.

    • Add the Display_print call into the while loop.

      while (1) {
         sleep(time);
         GPIO_toggle(Board_GPIO_LED0);
         Display_printf(hSerial, 1, 0, "LED Toggle %d", count++);
      }
      

      empty.c :: mainThread() the new while loop

  4. Rebuild/load/run the application.

  5. Open your favorite terminal application (e.g. PuTTY, CCS Terminal). You'll probably need to use Device Manager (if using Windows) to determine the correct COM port.

    with the following settings (note your COM port will most likely be different!).

    You should see the output in the terminal session

The TI Drivers and Display module are covered in the <SimpleLink_SDK_Install_Dir>/docs/tidrivers/tidriversAPIs.html file. You can get to a specific module via SysConfig. In the module view, click the ?

Here is the description text and link for the Display module.

Task 6 - Add Watchdog

Most production applications include some type of Watchdog timer to help in unexpected behavior. We are going to add a Watchdog timer into the application. We'll keep it simple and not have it restart the application. It will only set a flag to denote that it had expired.

  1. In SysConfig, click the + icon next to the Watchdog module and then change the Period to 1500.

  2. Now let's add the usage of the Watchdog module into the empty.c file.

    • Add header and some global variables

      #include <ti/drivers/Watchdog.h>
      volatile uint8_t serviceFlag = 1;
      volatile uint8_t watchdogExpired = 0;
      Watchdog_Handle watchdogHandle;
      

      empty.c Add in with other #includes

    • Open the Watchdog peripheral

      Watchdog_init();
      
      Watchdog_Params params;
      Watchdog_Params_init(&params);
      params.callbackFxn = (Watchdog_Callback)watchdogCallback;
      params.resetMode = Watchdog_RESET_OFF;
      
      watchdogHandle = Watchdog_open(Board_WATCHDOG0, &params);
      if (watchdogHandle == NULL) {
        /* Error opening Watchdog */
        while (1);
      }
      

      empty.c :: mainThread() in the function before the while loop.

    • Add the Watchdog callback. Note this function is specified in the Watchdog parameters above.

      void watchdogCallback(uintptr_t unused)
      {
        /* Clear watchdog interrupt flag */
        Watchdog_clear(watchdogHandle);
        watchdogExpired = 1;
        serviceFlag = 1;
      }
      

      empty.c above the mainThread function

    • Add the tickling/feeding of the Watchdog timer and debug output to show that the Watchdog timer expired in the while loop.

      while (1) {
         sleep(time);
         GPIO_toggle(Board_GPIO_LED0);
         Display_printf(hSerial, 1, 0, "LED Toggle %d", count++);
      
         if (watchdogExpired) {
           Display_printf(hSerial, 1, 0, "Watchdog expired!");
           watchdogExpired = 0;
         }
      
         if (serviceFlag) {
           Watchdog_clear(watchdogHandle);
           Display_printf(hSerial, 1, 0, "Cleared WD");
         }
      }
      

      empty.c modified while loop

  3. Rebuild/load/run the application.

Quiz

Why does the Watchdog never expire?

Watchdog configuration vary per device

Please consult Watchdog API reference and TRM for more details on the Watchdog for your device.

Task 7 - Add a button

Let's add a button to the application. When pressed, it will disable the tickling/feeding of the Watchdog in the while loop.

  1. Have the Board.h preview open in SysConfig. We can see the name of the button get modified as we change it!

  2. In SysConfig, let's add a button via the Hardware view instead of Software.

    • Select Hardware and click the + icon next to LaunchPad Button BTN-1 (left).
    • Change the name of the constant to Board_WDBUTTON. Note: you'll see the name change in the Board.h preview window.
    • Select Pull Up for the Pull field and Failing Edge for the Interrupt Trigger. Note: your board might have different requirements.
    • Finally, set the button callback to stopTicklingWatchdog

  3. Now let's add the usage of the button into the empty.c file.

    • Add the enabling of the callback. Note the name of the constant is from the SysConfig Name setting.

      GPIO_enableInt(Board_WDBUTTON);
      

      empty.c after the GPIO_setConfig

    • Add the callback (note the name must match the SysConfig Callback Function setting).

      void stopTicklingWatchdog(uint_least8_t index)
      {
       serviceFlag = 0;
      }
      

      empty.c above the mainThread function

  4. Rebuild/load/run the application.

  5. Hit BTN-1 (or whatever button you specify) refer to Board.html for details. Your output should denote that the Watchdog did expire.

Quiz

Click on the "Show Board". What is this for?

Task 8 - How to “disable” SysConfig

Great! You have your configuration setup, but you'd like to add some comments in the Board.c or Board.h files or simply "freeze" them. How do you do this?

  1. Copy the source files from Debug/syscfg into your project.

  2. Right-click on empty.syscfg and "Exclude from Build". Note: the empty.syscfg file will be greyed out when excluded.

  3. Rebuild/load/run the application. It will behave the same except the files will not be generated.

Task 9 - Moving to a new SDK Version

You have everything configured via SysConfig with a specific version of the SDK and the application is working well...great! What happens when you move to a newer version of the SDK? Here are the high-level steps that you need to do:

  1. Install the new SDK and have CCS discover it.

  2. Move the working application to the new SDK (refer to the SimpleLink User Guide for details on how to do this).

  3. Rebuild the application. This will regenerate the files based on the new content in the new SDK. Please note that SysConfig really has two pieces

    • The SysConfig GUI/cmdline tool (available in CCS or as a stand-alone tool).
    • The meta-data in the SimpleLink SDKs that the SysConfig tool reads to build up the views (e.g. the Display module in the SDK specifies that it supports, UART, Console and LCD).
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.