CC26xx Driver Library |

- Main Page
- Related Pages
- CC26xx APIs
- Register Descriptions
- Online Resources

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Programming Model

# Introduction

The peripheral driver library provides support for two programming models: The direct register access model and the software driver model. Each model can be used independently or combined, based on the needs of the application or the programming environment desired by the developer.

Each programming model has advantages and disadvantages. Use of the direct register access model generally results in smaller and more efficient code than using the software driver model. However, the direct register access model requires detailed knowledge of the operation of each register and bit field, as well as their interactions and any sequencing required for proper operation of the peripheral; the software driver model insulates the developer from these details, thus generally requiring less time to develop applications.

# Direct Register Access Model

In the direct register access model, the peripherals are programmed by the application by writing values directly into the registers in the peripheral. A set of defines, that simplify this process, is provided.

These defines are stored in the `inc/` directory and there is a single `hw_*.h` header file for each peripheral type. For example, the defines for SSI are stored in the `hw_ssi.h` header file.

The defines used by the direct register access model follow a naming convention that makes it easier to know how to use a particular macro. The rules are as follows:

- All register name macros start with the module name (for example, `SSI` for the SSI module) and are followed by the name of the register as it appears in the data sheet.
- The register defines are offset values relative to the base address of a peripheral instance. If an offset is used, this will be identified in the register name using `_O_` (for example, `CR0` register in the data sheet results in `SSI_O_CR0`). The base address of each peripheral is defined in the memory map header file stored in the `inc/` directory, under the name `hw_memmap.h`.
- All register defines for a given peripheral are listed in the first section of the corresponding header file (for example, in the first section of the `hw_ssi.h` file for the SSI registers).
- All register bit fields start with the module name, followed by the register name, and then followed by the bit field name as it appears in the data sheet. For example, the `SCR` bit field in the `CR0` register in the `SSI` module is identified by `SSI_CR0_SCR...`.
- Defines that end in `_M` represent the mask for a bit field in a register.
- Defines that end in `_S` represent the number of bits to shift a value in order to align it with a bit field. These values match the macro with the same base name but ending with `_M`.
- If a bit field has enumerated values the enumeration names are appended to the name of the bit field define. For example, the `SSI_CR0_DSS` bit field has a set of enumerations that specify the allowed values of this bit field pre-shifted to the correct bit positions. E.g. the enumeration "7_BIT" can be set using the define `SSI_CR0_DSS_7_BIT`. This improves readability and also helps the programmer select valid values for specific bit fields.

Given these defines, the `CR0` register, in the first instance of the SSI peripheral (SSI0), can be programmed as follows:

        HWREG(SSI0_BASE + SSI_O_CR0) = ((5 << SSI_CR0_SCR_S) | SSI_CR0_SPH | SSI_CR0_SPO);

Alternatively, the following has the same effect (although it is not as easy to understand):

        HWREG(SSI0_BASE + SSI_O_CR0) = 0x000005c0;

The value of the `SCR` field from the `CR0` register can be extracted as follows:

        ulValue = (HWREG(SSI0_BASE + SSI_O_CR0) & SSI_CR0_SCR_M) >> SSI_CR0_SCR_S;

# Software Driver Model

In the software driver model, the API provided by the peripheral driver library is used by applications to control the peripherals. Because these drivers provide complete control of the peripherals in their normal mode of operation, it is possible to write an entire application without direct access to the hardware. This method provides for rapid development of the application without requiring knowledge of how to program the peripheral registers.

Corresponding to the direct register access model example, the following call also programs the `CR0` register in the SSI module (though the register name is hidden by the API):

        SSIConfigSetExpClk(SSI0_BASE, 50000000, SSI_FRF_MOTO_MODE_3,
                           SSI_MODE_MASTER, 1000000, 8);

The resulting value in the `CR0` register might not be exactly the same because SSIConfigSetExpClk() may compute a different value for the `SCR` bit field than what was used in the direct register access model example.

All example applications use the software driver model.

# Combining the Models

The direct register access model and software driver model can be used together in a single application, thus applying the most appropriate model as needed to any particular situation within the application. For example, the software driver model can be used to configure the peripherals (because this is not performance critical) and the direct register access model can be used to operate the peripheral (which may be more performance critical). Or, the software driver model can be used for peripherals that are not performance critical (such as a UART used for data logging) and the direct register access model can be used for performance critical peripherals (such as the ADC module used to capture real-time analog data).