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.
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:
SSI
for the SSI module) and are followed by the name of the register as it appears in the data sheet._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
.hw_ssi.h
file for the SSI registers).SCR
bit field in the CR0
register in the SSI
module is identified by SSI_CR0_SCR...
._M
represent the mask for a bit field in a register._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
.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;
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.
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).