StellarisWare: Direct Register Access vs Software Driver Model
When writing code for the Stellaris Launchpad you have two main choices in how you write the code. You can either manipulate control & data registers bit by bit with the Direct Register Access Model. Or you can use a defined set of API’s with a set of predefined options to abstract away the hardware level and let you focus on the software by using the Software Driver Model (a.k.a the Stellaris API)
Direct Register Access provides absolute control and is the quickest execution, but what you gain in speed and surgical precision you must balance against a steeper learning curve and considerably more tedious / less legible code. All header files used for DRA can be found in the Stellarisware/inc/* directory. At its core the DRA is really just a series of English Language aliases for the hex register locations that make it slightly easier to read and write values to them. If you want to do DRA get really familiar with the LM4F120H5QR chip datasheet as a reference. It is absolutely necessary.
The DRA differentiates between Register, mask and shift defines with name endings.
- *_R is used for Registers; read / write to these will affect the register directly
- *_M is used for Masks; logical and / or with these to get specific data fields within a register
- *_S is used to shift; shift << / >> by these values to move a value into place to be written to a register
The Software Driver Model on the other hand is considerably more user friendly and is the recommended starting point for beginners. The SDM provides a tremendous abstraction, the cost of which is slightly less control, though if you ever need the precise control of the DRA you can always suppliment the SDM with it. All the example code is written in the SDM with the rare exception of blinky and one off instructions done in DRA. The SDM consists of everything found in Stellarisware/driverlib/* directory where each peripheral (GPIO, I2C, SSI, etc…) has its own .c and .h file with relevant function information and definitions for that device.
An Example: Set SSI Clock Speed
DRA:
SSI0_CR0_R = ((5 << SSI_CR0_SCR_S) | SSI_CR0_SPH | SSI_CR0_SPO | SSI_CR0_FRF_MOTO | SSI_CR0_DSS_8);
…or equivalently…
SSI0_CR0_R = 0x000005c7;
SDM:
SSIConfigSetExpClk(SSI0_BASE, 50000000, SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 1000000,8);
As you can see the DRA is simply shifting different values into place and then writing them to the register. If you look at the Datasheet for the chip you would undoubtedly see all the correct values set. The SDM on the other hand has a clearly named function, it configures the SSI Clock, and gives a defined set of variables. If in doubt as to what variables to use always look at the relevant .h file in driverlib. All the variables and function definitions along with really good comments are there. (that or Google it, odds are someone somewhere has done something similar to what you are trying to do)
That, in a nutshell, is the difference between the Software Driver Model and Direct Register Access. I would suggest usig the SDM and ocassionally peppering in the DRA when needed, it makes for a more pleasant experience all around.