# Sensor Controller Studio

## SCIF Driver - How to Use

Introduction

This guide describes how to use the Sensor Controller Interface driver (SCIF) generated from the following Sensor Controller project:

- Project name: ADC Data Streamer for LaunchPad
- Project file: `C:/Users/a0132649/Documents/Texas Instruments/Sensor Controller Studio/examples/adc_data_streamer_launchpad/adc_data_streamer_launchpad.scp`
- Operating system: TI-RTOS
- Target chip: CC2652P1F, package QFN48 7x7 RGZ, revision E (2.1)

The guide is tailored for this project, and contains code snippets that you can copy and paste directly into your application.

Preparation

Sensor Controller task code cannot be debugged from the application IDE (IAR EWARM or CCS).

Use Task Testing, Task Debugging and/or Run-Time Logging in Sensor Controller Studio to make sure that your Sensor Controller task(s) work as expected, before you start integrating the SCIF driver into the application.

Getting Started

Follow these steps to start integrating the SCIF driver into your application:

- Add the generated SCIF driver to the application project
- Include the SCIF driver header file
- Add callback functions
- Initialize the SCIF driver
- Start Sensor Controller tasks (simplified)
- Access Sensor Controller data structures from the application
- Handle Sensor Controller ALERT interrupts

Further Integration

These sections cover additional SCIF driver features and other information that can be helpful when integrating the SCIF driver:

- Task control

- Wait for the previous task control operation to finish
- Start or restart Sensor Controller tasks
- Stop Sensor Controller tasks
- Run Sensor Controller tasks once
- Trigger the execution code block manually

- Share I/O pins between the Sensor Controller and the application
- Use project specific definitions in the application
- Uninitialize the SCIF driver
- Run the Sensor Controller Studio code generator in the application pre-build step
- Generate Doxygen documentation for the SCIF driver

Getting Started

This section describes how to add and start integrating the SCIF driver into an existing System CPU application.

It is assumed that all the code snippets below go into one C source file, in the same directory as the SCIF driver. Otherwise you may have to change `#include` paths, and add function prototypes.

If you do not have an existing application, please take a look at some of the examples in Sensor Controller Studio.

Add the Generated SCIF Driver to the Application Project

You must add these files to your application project:

- `scif.c`
- `scif_framework.c`

You can optionally add these files to the application project:

- `scif.h`
- `scif_framework.h`
- `scif_osal_tirtos.c` (this source file is mostly for internal use, and is included by `scif_framework.c`)
- `scif_osal_tirtos.h`

IAR EWARM

- Right-click in the project tree
- Click Add -> Add Files ...
- Select the files to be added

CCS

- Right-click on the project in the project tree
- Click Add Files ...
- Select the files to be added
- Select the Link to files option (this allows Sensor Controller Studio to update the SCIF driver files)

Include the SCIF Driver Header File

Add the following code to include the SCIF driver main header file:

    #include "scif.h"

Add SCIF Driver Callback Functions

Add these SCIF driver callback functions to the application:

    // SCIF driver callback: Task control interface ready (non-blocking task control operation completed)
    void scCtrlReadyCallback(void) {

    }

    // SCIF driver callback: Sensor Controller task code has generated an alert interrupt
    void scTaskAlertCallback(void) {

    }

Initialize the SCIF Driver

Add the following code to initialize the SCIF driver. You can do this:

- In your application's `main()` function, immediately before the operating system (RTOS) task scheduler is started
- At the start an RTOS task, which has a main loop that handles the Sensor Controller

    // Initialize the SCIF operating system abstraction layer
    scifOsalInit();
    scifOsalRegisterCtrlReadyCallback(scCtrlReadyCallback);
    scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);

    // Initialize the SCIF driver
    scifInit(&scifDriverSetup);

I/O Pin Configuration

The `scifInit()` call initializes all I/O pins used by the Sensor Controller. Do not configure these I/O pins in the application.

Start Sensor Controller Tasks (Simplified)

The SCIF driver uses the task control interface to start and stop Sensor Controller tasks, and perform other task control operations. The Task Control section describes how to use the task control functions correctly, but for now we will only perform one operation that starts the Sensor Controller task.

To start the "ADC Data Streamer" task:

    // Start the "ADC Data Streamer" Sensor Controller task
    scifStartTasksNbl(1 << SCIF_ADC_DATA_STREAMER_TASK_ID);

Access Sensor Controller Data Structures from the Application

The application can directly access the Sensor Controller's `cfg`, `input`, `output` and `state` data structures, which are located in the AUX RAM. This is the one and only mechanism for exchanging data between the Sensor Controller and the application.

Resource-specified data structure members should not be accessed directly, but rather through the resource provided API.

ADC Data Streamer

The application will typically write to the `cfg` data structure before the task is started:

    scifTaskData.adcDataStreamer.cfg.alertThr = ...;

The application will typically read from the `output` data structure while the task is running:

    for (int n = 0; n < SCIF_ADC_DATA_STREAMER_BUFFER_SIZE; n++) {
        ... = scifTaskData.adcDataStreamer.output.pSamples[n];
    }

The `state` data structure is normally for internal use by the Sensor Controller, but can also be used for data exchange during operation or for observation:

    ... = scifTaskData.adcDataStreamer.state.alertEnabled;
    ... = scifTaskData.adcDataStreamer.state.exit;
    ... = scifTaskData.adcDataStreamer.state.head;
    ... = scifTaskData.adcDataStreamer.state.tail;

    scifTaskData.adcDataStreamer.state.alertEnabled = ...;
    scifTaskData.adcDataStreamer.state.exit = ...;
    scifTaskData.adcDataStreamer.state.head = ...;
    scifTaskData.adcDataStreamer.state.tail = ...;

Handle Sensor Controller ALERT interrupts

You can handle Sensor Controller ALERT events at any desired priority level, for example:

- In interrupt context, that is, in `scTaskAlertCallback()`
- In RTOS task context, using `scTaskAlertCallback()` to unblock the task by posting a semaphore or similar

    // Clear the ALERT interrupt source
    scifClearAlertIntSource();

    ... Access Sensor Controller task data structures here ...

    // Acknowledge the ALERT event
    scifAckAlertEvents();

Further Integration

This section describes task control in more detail, additional SCIF driver features, and other useful information.

Task Control

Task control operations are used to start and stop Sensor Controller tasks, and to trigger manual execution of task code blocks.

The task control interface can perform one operation at a time, and it is busy until the Sensor Controller has completed the operation. The task control functions are, however, non-blocking (hence the `Nbl` suffix), and return immediately. This means that you must wait for each task control operation to finish before performing another operation.

You can wait either before or after each task control operation. Normally it makes sense to wait before each operation since this reduces the waiting time. If your application performs task control from multiple threads of execution, you must ensure that this is done atomically:

1. Enter critical section
2. Wait for the previous task control operation to finish
3. Perform task control operation, for example start Sensor Controller tasks
4. Leave critical section

Wait for the Previous Task Control Operation to Finish

This code waits until the previous task control operation has finished, with a timeout in microseconds. The timeout is application specific. The function returns immediately if task control interface already is ready.

    // Wait with 20 millisecond timeout
    if (scifWaitOnNbl(20000) != SCIF_SUCCESS) {
        ... Handle timeout or usage error (see the function documentation) ...
    } else {
        ... Perform the next task control operation, for example start Sensor Controller tasks ...
    }

Start or Restart Sensor Controller Tasks

Starting a Sensor Controller task triggers the Initialization code. The task is then active.

After a Sensor Controller task has been stopped (see below), you must reset the task's data structures before it can be restarted. The `scifResetTaskStructs()` function will always reset the `state` data structure. You can optionally also reset the `cfg`, `input` and `output` data structures.

Do the following to (re)start a Sensor Controller task:

- To start or restart the "ADC Data Streamer" task:

    // Reset all data structures except configuration
    scifResetTaskStructs(1 << SCIF_ADC_DATA_STREAMER_TASK_ID, (1 << SCIF_STRUCT_INPUT) | (1 << SCIF_STRUCT_OUTPUT));

    // (Re)start the "ADC Data Streamer" Sensor Controller task
    if (scifWaitOnNbl(20000) != SCIF_SUCCESS) {
        ... Handle timeout or usage error ...
    } else if (scifStartTasksNbl(1 << SCIF_ADC_DATA_STREAMER_TASK_ID) != SCIF_SUCCESS) {
        ... Handle usage error ...
    }

Stop Sensor Controller Tasks

Stopping a Sensor Controller task triggers the Termination code. The task is then inactive.

Do the following to stop a Sensor Controller task:

- To stop the "ADC Data Streamer" task:

    // Stop the "ADC Data Streamer" Sensor Controller task
    if (scifWaitOnNbl(20000) != SCIF_SUCCESS) {
        ... Handle timeout or usage error ...
    } else if (scifStopTasksNbl(1 << SCIF_ADC_DATA_STREAMER_TASK_ID) != SCIF_SUCCESS) {
        ... Handle usage error ...
    }

Run Sensor Controller Tasks Once

Running a Sensor Controller task once triggers the Initialization Code, the Execution Code (one time), and the Termination Code.

Do the following to run a Sensor Controller task once:

- To run the "ADC Data Streamer" task:

    // Run the "ADC Data Streamer" Sensor Controller task
    if (scifWaitOnNbl(20000) != SCIF_SUCCESS) {
        ... Handle timeout or usage error ...
    } else if (scifExecuteTasksOnceNbl(1 << SCIF_ADC_DATA_STREAMER_TASK_ID) != SCIF_SUCCESS) {
        ... Handle usage error ...
    }

Trigger the Execution Code Block Manually

For an active task, it is possible to trigger the Execution Code manually.

Do the following to trigger a single iteration of the Execution Code:

- To run the "ADC Data Streamer" task's Execution Code:

    // Run the "ADC Data Streamer" Execution Code
    if (scifWaitOnNbl(20000) != SCIF_SUCCESS) {
        ... Handle timeout or usage error ...
    } else if (scifSwTriggerExecutionCodeNbl(1 << SCIF_ADC_DATA_STREAMER_TASK_ID) != SCIF_SUCCESS) {
        ... Handle usage error ...
    }

Share I/O Pins Between the Sensor Controller and the Application

In some applications you may want to transfer ownership of I/O pins between the Sensor Controller and MCU domain peripherals, for example when:

- The Sensor Controller and the application need to access different I2C devices over the same SCL and SDA lines
- The Sensor Controller and the application need to access different SPI devices over the same SCLK, MOSI and MISO lines, but with different chip select pins

To transfer I/O pins from Sensor Controller task(s) to the application:

- Stop the Sensor Controller task(s) that are currently using the I/O pins
- You can now open the TI driver(s) that require the I/O pins

To transfer I/O pins from the application back to Sensor Controller tasks:

- Close the TI driver(s) that are currently using the I/O pins
- Move I/O pin ownership back to the Sensor Controller task(s):

- For the ADC Data Streamer task, call:

    scifReinitTaskIo(1 << SCIF_ADC_DATA_STREAMER_TASK_ID);

- You can now restart the Sensor Controller task(s)

Use Project Specific Definitions in the Application

The SCIF Driver provides these definitions for use in the application:

- Target chip identification

- `SCIF_TARGET_CHIP_NAME_CC2652P1F` (no value)
- `SCIF_TARGET_CHIP_PACKAGE_QFN48_7X7_RGZ` (no value)

- Number of tasks

- `SCIF_TASK_COUNT`

- Task IDs

- `SCIF_ADC_DATA_STREAMER_TASK_ID`

- User-specified constants

- `SCIF_ADC_DATA_STREAMER_BUFFER_SIZE`

- I/O mapping

- `SCIF_ADC_DATA_STREAMER_DIO_A_SENSOR_OUTPUT`
- `SCIF_ADC_DATA_STREAMER_DIO_O_GLED`

Uninitialize the SCIF Driver

It is possible to include multiple SCIF driver setups (that is, outputs from multiple Sensor Controller projects) in one application.

To switch driver setup, first stop using and uninitialize this SCIF driver:

    // Stop all Sensor Controller tasks
    if (scifWaitOnNbl(20000) != SCIF_SUCCESS) {
        ... Handle error...
    } else if (scifStopTasksNbl((1 << SCIF_ADC_DATA_STREAMER_TASK_ID)) != SCIF_SUCCESS) {
        ... Handle error...
    } else if (scifWaitOnNbl(20000) != SCIF_SUCCESS) {
        ... Handle error...

    } else {
        // All tasks have been stopped successfully

        // Uninitialize the SCIF driver (includes I/O configuration)
        scifUninit();
    }

Then initialize the other SCIF driver, as described in its "How to Use" guide.

I/O Pin Configuration

The `scifUninit()` call uninitializes all Sensor Controller I/O pins. The I/O pins will be reverted to regular GPIO inputs, with pull as configured in the Sensor Controller Studio task panel(s).

Run Sensor Controller Studio Code Generator During Application Pre-Build Step

Use the Sensor Controller Studio command line interface (CLI) to ensure that the generated SCIF driver is up-to-date.

The `-s` parameter prevents file output when existing files already are up-to-date.

IAR EWARM

- Right-click on the project in the project tree
- Click Options...
- Select Build Actions
- Add the following to the pre-build step (you may need to create a batch file if you have multiple pre-build steps):

    "C:\Program Files (x86)\Texas Instruments\Sensor Controller Studio\bin\sensor_controller_studio_cli.exe" -g "C:/Users/a0132649/Documents/Texas Instruments/Sensor Controller Studio/examples/adc_data_streamer_launchpad/adc_data_streamer_launchpad.scp" -s -q

CCS

- Right-click on the project in the project tree
- Click Options...
- Select Build
- Add the following to the pre-build steps:

    "C:/Program Files (x86)/Texas Instruments/Sensor Controller Studio/bin/sensor_controller_studio_cli.exe" -g "C:/Users/a0132649/Documents/Texas Instruments/Sensor Controller Studio/examples/adc_data_streamer_launchpad/adc_data_streamer_launchpad.scp" -s -q

Generate Doxygen HTML Documentation for the SCIF Driver

Doxygen generates HTML documentation based on specially formatted comments in source code. Download Doxygen from http://www.doxygen.org/.

Set the path to `doxygen.exe` in the Preferences panel if needed. The current path is `C:/Program Files/doxygen/bin/doxygen.exe`.

To create or update the HTML documentation, run `scif_run_doxygen.bat`. The generated documentation can then be found here: scif_dox/index.html