Editor's Note: Embedded Systems Architecture, 2nd Edition, is a practical and technical guide to understanding the components that make up an embedded system’s architecture. Offering detailed explanations and numerous code examples, the book provides a comprehensive get-up-and-running reference for those new to the field and those updating their skills. This excerpt offers a introduction and review of device drivers' role in interfacing with and controlling the underlying embedded hardware.
Adapted from “Embedded Systems Architecture, 2nd Edition” by Tammy Noergaard (Newnes)
8.3 Example 3: On-Board Bus Device Drivers
As discussed in Chapter 7, associated with every bus is/are (1) some type of protocol that defines how devices gain access to the bus (arbitration), (2) the rules attached devices must follow to communicate over the bus (handshaking), and (3) the signals associated with the various bus lines. Bus protocol is supported by the bus device drivers, which commonly include all or some combination of all of the 10 functions from the list of device driver functionality introduced at the start of this chapter, including:
- Bus Startup: initialization of the bus upon PowerON or reset.
- Bus Shutdown: configuring bus into its PowerOFF state.
- Bus Disable: allowing other software to disable bus on-the-fly.
- Bus Enable: allowing other software to enable bus on-the-fly.
- Bus Acquire: allowing other software to gain singular (locking) access to bus.
- Bus Release: allowing other software to free (unlock) bus.
- Bus Read: allowing other software to read data from bus.
- Bus Write: allowing other software to write data to bus.
- Bus Install: allowing other software to install new bus device on-the-fly for expandable buses.
- Bus Uninstall: allowing other software to remove installed bus device on-the-fly for expandable buses.
Which of the routines are implemented and how they are implemented depends on the actual bus. The pseudocode below is an example of an I2C bus initialization routine provided as an example of a bus startup (initialization) device driver on the MPC860.
8.3.1 On-Board Bus Device Driver Pseudocode Examples
The following pseudocode gives an example of implementing a bus initialization routine on the MPC860, specifically the startup function in reference to the architecture. These examples demonstrate how bus management can be implemented on a more complex architecture, and this can be used as a guide to understand how to write bus management drivers on other processors of equal or lesser complexity than the MPC860 architecture. Other driver routines have not been pseudocoded, because the same concepts apply here as in Sections 8.1 and 8.2—essentially, looking in the architecture and bus documentation for the mechanisms that enable a bus, disable a bus, acquire a bus, etc.
I2C Bus Startup (Initialization) on the MPC860
The I2C (inter-IC) protocol is a serial bus with one serial data line (SDA) and one serial clock line (SCL). With the I2C protocol, all devices attached to the bus have a unique address (identifier), and this identifier is part of the data stream transmitted over the SDL line.
The components on the master processor that support the I2C protocol are what need initialization. In the case of the MPC860, there is an integrated I2C controller on the master processor (see Figure 8-29). The I2C controller is made up transmitter registers, receiver registers, a baud rate generator, and a control unit. The baud rate generator generates the clock signals when the I2C controller acts as the I2C bus master—if in slave mode, the controller uses the clock signal received from the master. In reception mode, data is transmitted from the SDA line into the control unit, through the shift register, which in turn transmits the data to the receive data register. The data that will be transmitted over the I2C bus from the PPC is initially stored in the transmit data register and transferred out through the shift register to the control unit and over the SDA line. Initializing the I2C bus on the MPC860 means initializing the I2C SDA and SCL pins, many of the I2C registers, some of the parameter RAM, and the associated buffer descriptors.
Figure 8-29. I2C Controller on MPC860. © Freescale Semiconductor, Inc. Used by permission.
The MPC860 I2C SDA and SCL pins are configured via the Port B general purpose I/O port (see Figures 8-30a and b). Because the I/O pins can support multiple functions, the specific function a pin will support needs to be configured via port B’s registers (shown in Figure 8-30c). Port B has four read/write (16-bit) control registers: the Port B Data Register (PBDAT), the Port B Open Drain Register (PBODR), the Port B Direction Register (PBDIR), and the Port B Pin Assignment Register (PBPAR). In general, the PBDAT register contains the data on the pin, the PBODR configures the pin for open drain or active output, the PBDIR configures the pin as either an input or output pin, and the PBPAR assigns the pin its function (I2C, general purpose I/O, etc.).
Figure 8-30a. SDA and SCL pins on MPC860. © Freescale Semiconductor, Inc. Used by permission.
Figure 8-30b. MPC860 Port B Pins. © Freescale Semiconductor, Inc. Used by permission.
Figure 8-30c. MPC860 Port B Register. © Freescale Semiconductor, Inc. Used by permission.
To read more, go to: “Initializing the SDA and SCL pins .”