The C Programmer’s Guide to the QVGA Controller
Table of Contents
PART 1 GETTING STARTED
Introduction. How to Use This Manual
Chapter 1: Getting to Know Your QVGA
PART 2 PROGRAMMING THE QVGA CONTROLLER
Chapter 3: The IDE: Writing, Compiling, Downloading and Debugging Programs
Chapter 4: Making Effective Use of Memory
Chapter 5: Programming the Graphical User Interface
Chapter 6: Real Time Programming
Chapter 7: Failure and Run-Time Error Recovery
PART 3 COMMUNICATIONS, MEASUREMENT, AND CONTROL
Chapter 8: Digital and Timer-Controlled I/O
Chapter 9: Data Acquisition Using the QVGA Controller
Chapter 10: Outputting Voltages with Digital to Analog Conversion
Chapter 11: Serial Communications RS-232 and RS-485 Communications Serial Connectors and Configuration Options Multi-Drop Communications Using RS-232 Multi-Drop Communications Using RS-485 Synchronous Serial Peripheral Interface (SPI) Chapter 12: The Battery-Backed Real Time Clock PART 4: PUTTING IT ALL TOGETHER Chapter 13: A Turnkeyed Application PART 5: REFERENCE DATA Appendix A: QVGA Electrical Specifications Appendix C: Physical Dimensions
Chapter 11: Serial Communications
RS-232 and RS-485 Communications
Serial Connectors and Configuration Options
Multi-Drop Communications Using RS-232
Multi-Drop Communications Using RS-485
Synchronous Serial Peripheral Interface (SPI)
Chapter 12: The Battery-Backed Real Time Clock
PART 4: PUTTING IT ALL TOGETHER
Chapter 13: A Turnkeyed Application
PART 5: REFERENCE DATA
Appendix A: QVGA Electrical Specifications
Appendix C: Physical Dimensions
Chapter 11: Serial Communications
RS-232 and RS-485 Communications
The QVGA Controller has two serial communications ports: a primary serial port called Serial 1 that supports both RS232 and RS485 protocols, and a secondary serial port called Serial 2 that supports RS232. The Serial 1 port is implemented with the 68HC11's on-chip hardware UART (Universal Asynchronous Receiver/Transmitter). Serial 2 is implemented by a software UART in the controller’s QED-Forth Kernel that uses two of the processor’s PortA I/O pins to generate a serial communications channel.
Table 11‑1 Serial Communications Channels
The primary channel’s UART translates the bit-by-bit data on the serial cable into bytes of data that can be interpreted by the QED-Forth Kernel or by your application program. It controls the serial-to-parallel and parallel-to-serial conversion and performs all of the timing functions necessary for asynchronous serial communications. The communications is asynchronous because no synchronizing clock signal is transmitted along with the data. Rather, the UART deduces the correct time to sample the incoming signal based on the start and stop bits in the signal itself. (The QVGA Controller also supports fast synchronous serial communications via the Serial Peripheral Interface described later in this Chapter.)
The secondary channel is very useful for debugging application programs that communicate with other computers or I/O via the primary channel. Since both channels can operate simultaneously and independently, debugging can be performed while the application program is communicating via its primary channel. The dual communications channels also provide an easy way to link systems that communicate using different serial protocols.
There are several protocols that govern the format of exchanged data, with the RS232 protocol used primarily by personal computers, and the RS485 protocol used in industrial control systems. The Serial 1 port can be configured for either RS232 or RS485 communications at up to 19200 baud. The Serial 2 port is dedicated to RS232 communications at up to 4800 baud.
RS232 is by far the most common protocol. It is supported by virtually all personal computers, and is the default protocol for both of the QVGA Controller’s serial ports. Its simplest implementation requires only three wires: one to transmit serial data, a second to receive serial data, and a third to provide a common ground reference. RS232 allows both communicating parties to transmit and receive data at the same time; this is referred to as full duplex communications. RS232’s greatest benefit is its universality; practically all personal computers can use this protocol to send and receive serial data.
RS232 uses inverse logic; that is, a positive bit at the 68HC11 UART is inverted by the onboard RS232 driver chip and appears as a negative signal on the serial cable. The terminal’s serial receiver chip re-inverts the signal to its positive sense. The data bits are also transmitted in reverse order, with the least significant bit transmitted first, after a start bit. The specified signal levels of approximately +/- 9 Volts are derived from the QVGA Controller’s +5 Volt supply by a dual RS232 driver chip that has a built-in charge pump voltage multiplier.
The QVGA Controller offers a unique addition to full duplex RS232: it can place its RS232 transmitter into a high impedance silent mode under software control. This allows you to configure full duplex multi-drop networks in which a single master can sequentially address one of many slaves and start a full-duplex exchange of data.
RS485 is another protocol supported by the primary serial port on the QVGA Controller. It is a half duplex protocol, meaning that only one party at a time may transmit data. Unlike the standard RS232 protocol, RS485 allows many communicating parties to share the same 3-wire communications cable. Thus RS485 is the standard protocol of choice when multi-drop communications are required.
Like RS232, the data bits are transmitted in reverse order, with the least significant bit transmitted first. The RS485 protocol uses differential data signals for improved noise immunity; thus RS485 can communicate over greater distances than RS232. An RS485 transceiver is present on the QVGA Controller, and its data direction is controlled by pin 4 of port PPC of the peripheral interface adapter (PIA).
Serial Connectors and Configuration Options
The primary and secondary serial communications ports are accessible through the QVGA Controller's 10 pin, dual row Communications Connector (H14) and through the individual Serial 1 and Serial 2 connectors. These standard 9-pin serial connectors are located on the top edge of the QVGA Controller. A serial communications cable is supplied with QVGA Starter Kits.
The pinout of the Communications Connector (H14) is shown in Table 11‑2, and the following diagrams show how these signals map to the two serial communications connectors. Although the RS232 protocol specifies functions for as many as 25 pins, each communications channel requires only three for simple serial interfaces: TxD1 (transmit data), RxD1 (receive data), and DGND (digital ground). The RS232 protocol specifies the use of two separate grounds, a signal ground and a protective (or “chassis”) ground. The QVGA Controller does not differentiate between these. To provide a convenient means of attaching two grounds to the serial cable, there are several pins (labeled DGND) on the communications connector that are connected to the controller’s ground plane.
Table 11‑2 Serial Communications Connector, H14
Table 11‑3 Serial 1 Connector Table 11‑4 Serial 2 Connector
Given the availability of ready-made communications cables, it is not necessary to study or understand the following descriptions of cable connections. These detailed signal descriptions and cable diagrams are presented to provide complete information for those who have special communications requirements and for those who wish to make their own application-specific communications cables. Most computers conform to IBM PC AT-compatible RS232 interfaces which use 9-pin D-Type connectors, consequently the QVGA Controller brings out its serial ports to two female 9-pin D-Type connectors. Table 11‑5 shows the connection diagram for a standard 9-pin serial cable.
Table 11‑5 Serial Cable Connections.
We can gain insight into the operation of the RS232 protocol by examining the signal connections used for the primary serial port in Table 11‑5. The transmit and receive data signals carry the messages being communicated between the QVGA Controller and the PC or terminal. The QVGA Controller’s transmit data signal TxD1 (pin 2 on the 9-pin serial connector) is connected to the terminal’s receive data signal RxD (pin 2 on its 9-pin connector). Likewise, the terminal’s transmit signal TxD is connected to the QVGA Controller’s receive signal RxD1. Chassis and signal grounds are connected together to the digital ground (DGND) signal.
From the QVGA Controller’s point of view, these three signals (TxD, RxD, and ground) are the only connections required to perform serial communications. While these signals provide a data path, they do not provide hardware handshaking that allows the two communicating parties to let each other know when they are ready to send or receive data.
The RS232 protocol provides for four handshaking signals called ready to send (RTS), clear to send (CTS), data set ready (DSR), and data terminal ready (DTR) to coordinate the transfer of information. The QVGA Controller, however, does not implement hardware handshaking. Rather, it relies on software handshaking via transmission of XON/XOFF characters to coordinate data transfer and ensure that information is not lost when one of the communicating parties is busy.
Many terminals and PCs, however, do rely on hardware handshaking to determine when the other party (in this case the QVGA Controller) is ready to accept data. By connecting pairs of these handshaking signals together, the terminal or PC can be made to think that the QVGA Controller is always ready to send and receive data. Thus in Table 11‑5 , RTS1 is connected to CTS1, and DSR1 is connected to DTR1 onboard the QVGA Controller using zero ohm shorting resistors. These signals may alternatively be redirected to the digital inputs and outputs used by the second serial port if hardware handshaking is required.
The secondary serial port is connected similarly except that the onboard connection of RTS to CTS, and DSR to DTR are permanent.
Enabling the Secondary Serial Port
To enable the secondary serial port, turn dip switch 5 (labeled “2COM”) on the QED Board ON. Otherwise, dip switch 5 should be OFF so that it frees bit 3 of PORTA for use as general-purpose I/O.
Enabling RS485 Communications
If your application requires RS485, use the primary serial port (serial1) for RS485 communications, and use the secondary serial port (Serial 2) to program and debug your application code using the RS232 protocol. The default serial routines used by the onboard kernel assume that full duplex communications are available, so you cannot use the RS485 protocol to program the controller. You can use it to communicate with other devices.
A three-post jumper located between the third socket and H6 configures the primary serial port for either RS232 or RS485 operation.
For RS232 operation: Install the jumper shunt across the two pins closest to the crystal (the default configuration). In this case, cable connections may be made to Serial 1 on either the 10-pin Serial Communications Header or the Serial 1 Connector.
For RS485 operation: Install the jumper shunt across the two pins closest to the J3 silk screen. In this case, cable connections must be made to Serial 1 at pins 5 and 6 of the 10-pin Serial Communications Header. The RS485 connections are not brought out to the Serial 1 Connector.
Using the Serial Ports
Using the primary serial port is easy. In fact, you have been using it all along as you worked through the examples in this document. The standard C serial I/O routines such as printf(), scanf(), putchar(), and getchar() give you high level access to the serial ports. All high level routines call the following low level revectorable serial primitives to access the currently active serial port:
int AskKey(void) // returns a flag that is true if an input char is waiting
char Key(void) // waits for and returns the next input char
void Emit(char) // outputs the specified char to the serial port
Because all of the serial I/O routines on the QVGA Controller are revectorable, it is very easy to change the serial port in use without modifying any high level code.
Let’s do a quick experiment to see how easy it is. We’ll use code from the GETSTART.C program. If you have already downloaded the program, you are ready to go. If your board is presently running a multitasking application, type
to stop the program now.
If you have not yet compiled the GETSTART program and you want to do the exercises here, open GETSTART.C in your TextPad editor, click on the Make Tool (the Make icon), and after the compilation is done, enter the Terminal Program by clicking on the terminal icon and use the “Send Text File” menu item to send GETSTART.DLF to the QVGA Controller.
Switching the Default Serial Port
Before running the program, let’s switch to the secondary serial port. The secondary serial port is implemented by a software UART that controls two pins on PortA. Pin 3 of PortA is the Serial2 input, and pin 4 of PortA is the Serial2 output. To switch to the secondary serial port running at 1200 baud, simply flip DIP switch #5 to the ON position to enable the secondary serial port hardware, and type from the terminal the following QED-Forth commands:
You can operate the port at any baud rate up to 4800 baud; just specify the rate you want before the BAUD2 command. Now select the “Communications” item in the “Settings” menu of the Terminal program, and click on 1200 baud (or whatever baud rate you selected in the command above). Move the serial cable from the “Serial Port 1” connector to the “Serial Port 2” connector at the QVGA Controller. Typing a carriage return at the terminal should now produce the familiar “ok” response via the Serial2 port.
and you’ll see the familiar starting message of the GETSTART.C program:
The radius is 0; the circular area is 0.
In fact, the program works the same as it did before, but now it is using the secondary serial port instead of the primary port -- and you didn’t even have to recompile the code!
For those of you interested in the details, here’s how it works: The low-level serial driver routines named Key(), AskKey() and Emit() are revectorable routines that can be redirected to use either of the serial ports. By interactively executing the QED-Forth function
before calling main, we revectored these serial primitives to use the Serial2 port.
You can invoke the C version of this routine by calling
anywhere within your C program’s source code file. Function prototypes for this function and other versatile serial I/O routines are defined in the COMM.H header file, and are described in detail in the Control-C Glossary.
To return to using the primary serial port, simply type from the active terminal the QED-Forth command:
which transfers control back to serial port 1 running at the prior established baud rate (typically 9600 baud). A hardware reset (toggling DIP switch #7) has the same effect. If you do this now, remember to move the QVGA Controller’s serial connector back to Serial Port 1, and to change the terminal’s baud rate back to 9600 baud using the “Communications” item under the terminal’s “Settings” menu.
If you always want the QVGA Controller to start up using the secondary serial port as the default serial communications link, you can type at your terminal:
where 1200 is the baud rate that you choose; you can specify any standard baud rate up to 4800 baud. The complementary routine is:
which makes the primary serial port the default startup serial link. We recommend that you keep the faster Serial1 port as the default serial link as you work through the exercises in this book.
All of these functions that we are calling interactively via the operating system can also be called from C in your program source code; their C function prototypes are as follows:
void UseSerial1( void );
void UseSerial2( void );
void Baud2( int baud );
void Serial1AtStartup( void );
void Serial2AtStartup( int baud );
In summary, the code provided for implementing the second serial port is very flexible and can be used to support dual concurrent communications ports. Data translation between different machines can be performed with ease, and applications that communicate via the primary serial port can be debugged using the secondary channel.
Timing Considerations and Multitasking
In multitasking systems using both serial ports Serial1 and Serial2, the application code should include one of the commands
SERIAL_ACCESS = RELEASE_ALWAYS;
SERIAL_ACCESS = RELEASE_NEVER;
before building the tasks. This prevents contention that can occur if the default RELEASE_AFTER_LINE option is installed in the SERIAL_ACCESS user variable.
The primary serial port, Serial1, is supported by the 68HC11's on-chip hardware UART, and does not require interrupts to work properly. On the other hand, the secondary serial port (Serial2) is implemented using hardware pins PA3 (input) and PA4 (output), and is controlled by the associated interrupts IC4/OC5 and OC4, respectively. The QVGA Controller’s kernel software contains a complete set of high level driver routines for the Serial2 port, and these functions are summarized in the Control-C Glossary.
The maximum Serial2 communications rate is 4800 baud. Because the software UART is interrupt based, competing interrupts that prevent timely servicing of the Serial2 interrupts can cause communications errors on the secondary serial channel. For example, at 4800 baud (bits per second), each bit lasts about 200 microseconds (µs), and if communications are full duplex (e.g., if the QVGA Controller echoes each incoming character), then there is a serial interrupt every 100 µs or so. In the middle of a character, each interrupt service routine takes about 35 µs. At the end of a received character, the service routine takes about 45 µs. At the start of a transmitted character, the service routine takes about 65 µs. Thus, as a rough approximation, operating at 4800 baud full duplex requires about 40 to 50% of the 6811's CPU time (that is, an average of approximately 40 to 50 µs service time every 100 µs).
If you are running Serial2 at 4800 baud, the rest of your application must be able to function properly using the remaining portion of the CPU time. Moreover, if Serial2 is running full duplex at 4800 baud, any other interrupt service routine that takes longer than 100 µs is likely to cause a problem. If an interrupt service routine takes longer than 200 µs, then an entire serial bit will be missed, causing a communications error. Also, several non-serial interrupts can stack up; if they have higher priority than the serial interrupts, they will be serviced before the Serial2 interrupt routine, and again a serial input or output bit may be lost.
Routines that temporarily disable interrupts for significant periods of time can also interfere with the Serial2 port. The Control-C Glossary contains a list of functions that temporarily disable interrupts, and the glossary entries give further information regarding how long interrupts are disabled. In most cases the times are less than 25 µs which does not pose a problem. However, note that the ReadWatch() and SetWatch() functions disable interrupts for about one millisecond (msec.), and the functions that write to EEPROM disable interrupts for 20 msec. per programmed byte. Be sure to account for these effects when designing your application.
We have built sophisticated instruments using the QVGA Controller that operate very reliably using multiple interrupts in addition to the software UART. If your application requires use of the secondary serial port as well as other interrupt routines, the key is to keep the interrupt service routines short and fast. You might also consider operating the secondary serial port at a lower baud rate to relax the timing constraints.
Setting Baud Rates
The rate of data transmission is expressed in bits per second, or baud. The primary serial channel can operate at standard speeds up to 19200 baud and can be configured for either RS232 (the default) or RS485 operation. The Serial2 channel is always configured for RS232 communications, and can sustain baud rates up to 4800 baud.
void Serial1AtStartup( void );
void Serial2AtStartup( int baud );
make it easy to establish a standard baud rate at which the board will communicate each time it starts up. Although the maximum standard baud rate of the primary serial port is 19200 baud, nonstandard baud rates of over 80 Kbaud can be attained by the 68HC11's on-chip UART and the onboard RS232 driver. The maximum sustainable baud rate on the secondary serial port is 4800 baud.
While the default baud rate of the primary serial port is 9600 baud, you can speed your communications and download times appreciably by switching to a faster baud rate. It's very simple. Just type at your terminal:
The new baud rate takes effect upon the next reset or restart. Thus you can type the command
or reset the board using DIP switch number 7, or turn the system off and on again. In each case, your QVGA Controller will be communicating at 19200 baud, and this baud rate will remain in effect until another BAUD1.AT.STARTUP command is executed, or until you invoke the Special Cleanup Mode as described earlier.
To reconfigure the Mosaic Terminal to communicate at 19200 baud, select the "Comm" item under the "Settings" menu and click on 19200 in the "Baud Rate" selection box.
Multi-Drop Communications Using RS-232
The RS-232 driver (Maxim Part No. MAX242) can be tri-stated under software control. This allows standard point-to-point full duplex communications, as well as a multi-drop configuration with one master (a single QVGA Controller or a desktop computer) and multiple QVGA Controller slaves. To implement this multi-drop scheme, each slave keeps its RS-232 transmitter silent until it is addressed by the master and is given permission to transmit. The advantage of such a multi-drop RS-232 network is that the communications are full duplex, with each communicating party capable of simultaneous transmission and reception of data. The software routines
control the dual RS232 transmitters on the board.
Connecting a standard full duplex link RS232 between two computers is the same as with a standard RS232 link, with the TxD (transmitter output) of each computer connected to the RxD (receiver input) of the other computer. A serial cable accomplishs this connection.
In a multi-drop configuration, the TxD of the master is connected to the RxD of each slave, and the RxD of the master is connected to the TxD of each slave. Figure 11‑1 shows a typical multi-drop communications network. The QVGA Controller makes it easy to configure a multi-drop network of QVGA Controllers controlled by a single master desktop computer.
To properly operate the network each slave computer executes RS232Silent at startup; thus all of the slave transmitters remain silent individually addressed by the master. When a slave is addressed, it executes RS232Transmit() at which point full duplex (two-way) communications commences between the master and the selected slave. When the communication is complete the slave silences its transmitter so that the master can talk to a different slave on the network.
Figure 11‑1 Typical RS-232 multi-drop communications network.
Multi-Drop Communications Using RS-485
Connecting computers together in multi-drop networks is common in factories and laboratories. In these distributed processing networks, a variety of machines and instruments work locally, but communicate and share data or resources with one another globally using a single serial link. You can use the QED Board’s RS485 link to create such a multi-drop serial network.
In the most common multi-drop RS-485 protocol, one computer is designated as a “master” and the rest of the computers or devices on the serial bus are designated as “slaves”. At any given time, only the master and a single “active” slave communicate. The remaining “inactive” slaves may actively receive, or listen to, data on the communications line, but only one slave at a time can transmit a message. If more than one slave tried to drive the transmit line simultaneously, their serial drivers would fight with each other for control of the bus. To ensure that no two devices drive the network at the same time, it is necessary that each slave device be able to disable it’s own RS-485 data transmitter.
to send an acknowledgment to the master (which should now be listening to the serial bus to accept the acknowledgment). The master and slave can then exchange data.
Synchronous Serial Peripheral Interface (SPI)
The Serial Peripheral Interface, SPI, is a fast synchronous serial interface. It provides a convenient means of connecting the QVGA Controller to a variety of peripheral devices, including analog to digital and digital to analog converters, real time clocks, and other computers which use high speed communication. The QVGA Controller’s on-board 12 bit A/D and 8 bit D/A converters communicate with the processor via the SPI.
The SPI can transfer data much more rapidly than an asynchronous serial link – its maximum rate is 2 Megabits/second.
After configuring the SPI system to communicate on a properly connected network of devices, sending and receiving data is as simple as writing and reading a register. The QED-Forth kernel includes pre-coded drivers that configure the SPI for maximum speed data transfer using a format that is compatible with the on-board D/A and 12 bit A/D. This chapter describes those drivers, and presents code that makes it easy to configure the SPI for different data transfer rates and formats.
SPI Bus Pins
Hardware is interfaced to the SPI via four PORTD pins named /SS, SCK, MOSI, and MISO brought out to pins 11 through 14 on the Digital I/O connector (see Appendix A). The SCK (serial clock) pin is a configurable synchronous data clock output. This signal synchronizes the exchange of bytes between the 68HC11 processor and the peripherals. The byte-sized messages are transmitted and received via the MOSI (master out/slave in) and MISO (master in/slave out) pins. The /SS (active-low slave select) signal enables data transfers by slave devices when it is active low. A ground connection is also necessary to ensure that the communicating devices have a common voltage reference.
When the 68HC11 controls the network, it is referred to as a “master”; otherwise, it is a “slave”. The distinction between master and slave is an important one. The device that initiates a data transfer is the master, and all other devices on the network are slaves. Only one active master may control the network at a time; however, the device that assumes the role of master may change according to an appropriate protocol.
The /SS pin can be configured as either an input or an output. Initializing the 68HC11 as a slave (by clearing the MSTR bit in the SPCR control register as explained below) automatically configures the /SS pin as an input. If the /SS input to a slave is inactive (high), the slave ignores the SCK input, does not transmit or receive data, and keeps its MISO output in a high-impedance state so that it does not interfere with the SPI bus. If the /SS input to a slave is active (low), the slave transfers data in response to the SCK clock input that is initiated by the master.
If the 68HC11 is initialized as a master (by setting the MSTR bit in the SPCR control register as explained below) then bit 5 of the Port D data direction register (DDRD) determines whether /SS is an input or an output. If bit 5 of DDRD is 1, then /SS is a general purpose output that operates independently of the SPI. This allows the processor that is master to control the input /SS pins of other CPU’s, for example. If bit 5 of DDRD is 0, then /SS is an input. In this situation, if the /SS input is pulled low while the 68HC11 is the master, the processor detects a “mode fault” (by setting a bit in the SPI status register) meaning that there is more than one master device on the SPI bus.
There are many possible configurations of master/slave networks. Regardless of the network, however, there are only four signals used: SCK provides a synchronized clock, MOSI and MISO signals are used for data transmission and reception, and /SS configures the 68HC11 as a master or slave device. In this chapter we will consider the most general and simple configurations.
SPI Network Connections
Configured as a master device, the 68HC11 transmits bytes via the “master out/slave in” pin, MOSI. It receives bytes sent by a slave device via the “master in/slave out” pin, MISO. Transmissions are always initiated by the master device, and consist of an exchange of bytes. As the master transmits a byte to an active slave (that is, a slave with its /SS input active low), the master receives a byte from the slave. It may be that only the byte sent from the master to the slave is meaningful; nevertheless, each device simultaneously transmits and receives one byte. The only difference between the master and slave devices is that the master initiates the transmission.
Slave devices use the master in/slave out pin, MISO, for transmitting, and the master out/slave in pin, MOSI, for receiving data. The following wiring diagram illustrates how the MOSI, and MISO pins of a master 68HC11 and a slave 68HC11 would be connected to exchange data:
The status of a device as master or slave determines how the various pins must be configured. The arrows in the diagram point to pins configured as inputs, and originate from output pins. Thus, the master 68HC11 has only one input, MISO, which is the slave QVGA Controller’s only output. Note that the master device outputs the clock synchronization signal SCK to the slave’s SCK which is configured as an input. Also, in the diagram, the master QVGA Controller’s /SS (slave select) is configured as an output. By setting this output LOW, the slave’s input /SS is pulled LOW. The GROUND line serves as a common voltage reference for the master and slave.
There are a variety of ways the MOSI, MISO, SCK and /SS pins on your QVGA Controller can be connected. The one you choose depends on the specific device, or devices you will be connecting to. In some circumstances a one-way data flow may suffice. For example, a QVGA Controller connected to a serial A/D converter might have these connections:
In this example, the QVGA Controller selects the serial A/D by outputting a LOW signal on /SS. Even though the MOSI pin is not connected to anything, the master initiates a transmission using a “dummy” byte. The SCK pin clocks the serial A/D’s CLK input which causes the A/D’s conversion result to be transferred to the master via the MISO line.
The 68HC11 allows the details of the synchronous communications protocol to be customized for compatibility with a variety of peripherals. The next section describes the registers that configure and control the QVGA Controller’s SPI.
Configuring the SPI
The SPI is configured and accessed via four registers:
Given a properly wired network and a properly configured SPCR control register, a master device may transmit a message by simply storing the byte to the SPDR data register. This automatically activates the SCK clock which synchronously transmits the data. As the master transmits its data, 8 bits of data are simultaneously received. The received data byte is accessed by reading SPDR data register. This ability to exchange messages means that the SPI is capable of full duplex communication. Once the data has been exchanged, a flag bit in the SPSR status register is set to indicate that the transfer is complete. If the programmer has enabled the local interrupt mask for the SPI, an interrupt is recognized at this point. Any required SPI output signals must be configured as outputs by setting the appropriate bits in the Port D data direction register which is named PORTD.DIRECTION in the QED-Forth kernel.
Initializing the SPI Control Register
The SPI control register, SPCR, contains 8 bits which must be initialized for proper control of the QVGA Controller’s SPI (M68HC11 Reference Manual, p.8-7). These bits are:
The DWOM bit (port D wired-or mode) should always be set to 0. Setting DWOM to 1 takes away the processor’s ability to pull the Port D signals high unless there is a pull-up resistor on each bit of the port. Setting this bit to 1 without installing pull-up resisters corrupts the operation of the serial communications interface which uses bits 0 and 1 of Port D.
Setting SPE (SPI enable) to 1 turns on the SPI system. This bit should be set only after all other SPI configuration is complete.
SPIE is a local interrupt mask that allows an interrupt to be recognized when an SPI data transfer has completed, or if a write collision or mode fault is detected.
Setting the MSTR bit initializes the 68HC11 as a master, and clearing the MSTR bit initializes it as a slave. Clearing the MSTR bit in the SPCR control register automatically configures the /SS (slave select) pin as an input. The /SS input in turn determines whether the slave responds to the SCK input, as described in a previous section. If the 68HC11 is initialized as a master by setting the MSTR bit, then bit 5 of the Port D data direction register (PORTD.DIRECTION) determines whether /SS is an input or an output. If the /SS pin of the master is an output, it can be controlled independently of the SPI system. If the /SS pin of the master is an input and if a low input level is detected, the processor sets the MODF bit in the SPI status register a “mode fault” condition. This detects the presence of more than one master on the SPI bus.
The CPOL, CPHA, SR1 and SPR0 configure the SCK pin’s clock polarity, clock phase, and clock rate. These signals are described in detail below.
SPI Clock Signal Configuration
The SCK pin’s synchronous clock signal has configurable phase, polarity and baud rate so that it can interface to a variety of synchronous serial devices. In general, all devices on a network should use the same phase, polarity, and baud rate clock signal. In some cases, however, a sophisticated network may have device groups on a network that use different clock configurations. Although the devices would share the same network, communications would only be understandable by members of the same group.
The clock’s polarity is controlled by a bit named CPOL (clock polarity) and its phase is controlled by CPHA (clock phase). CPOL determines whether the clock idles in the low state (CPOL = 0) or the high state (CPOL = 1). If the clock idles in the low state, the leading edge of the clock is a rising edge. If the clock idles in the high state, the leading edge of the clock is a falling edge. The CPHA bit determines whether data is valid on the leading or trailing edge of the clock. Note that the data is changed by the transmitting device one half clock cycle before it is valid.
The following table summarizes the combinations of CPHA and CPOL settings:
Many serial devices require a clock that idles in the low state (CPOL = 0), and expect valid data to be present on rising clock edges. Thus in this common configuration the transmitting device outputs the data when the clock goes low, and the receiving device samples the valid data when the clock goes high (CPHA = 0). In other words, data is valid on the “rising leading edge” of the clock.
To interface devices that support synchronized serial interfaces, but are not configurable like the 68HC11, determine the device’s requirements for clock phase and polarity and configure the 68HC11’s CPHA and CPOL accordingly. It is important to note that when the CPHA bit is 0, the /SS line must be de-asserted and re-asserted between each successive data byte exchange (M68HC11 Reference Manual, p.8-3). If the CPHA bit is 1, the /SS line may be tied low between successive transfers.
SPI Baud Rate
The two lowest order bits in the SPCR control register, named SPR1 and SPR0, determine the data exchange frequency expressed in bits per second; this frequency is also known as the baud rate. This setting is only relevant for the master device, as it is the master’s clock which drives the transfer. SPR1 and SPR0 determine the baud rate according to the following table:
Summary of the SPCR Control Register
The SPIE bit in the SPCR (SPI control register) enables SPI interrupt handling. The SPE bit turns on the SPI system. The DWOM bit determines whether Port D needs pull-up resistors; it should be set to 0. The MSTR bit determines whether the device is a master or slave. The CPOL and CPHA bits configure the synchronous clock polarity and phase and specify when valid data is present on the MISO and MOSI data lines. Finally, for master devices, the SPR1 and SPR0 bits determine the baud rate at which data is exchanged.
SPI Status Register Flags
There are three flag bits implemented in the SPSR (SPI status register). They are:
Any of these conditions may generate an interrupt if the SPIE (SPI interrupt enable) bit in the SPCR control register is set.
The SPIF is set when a data transfer is complete, and is cleared by a read of the SPSR status register, followed by a read or write to the SPDR data register. Thus, resetting the SPIF flag is very simple. After a data transfer is initiated by writing to the SPDR data register, the processor may poll the SPSR status register until the SPIF flag is set. Then reading the data that was received (by reading the SPDR) or initiating a new data transfer (by writing to the SPDR) automatically clears the SPIF flag. Alternatively, the if the SPI interrupts are enabled, the SPI interrupt handler determines what caused the interrupt by reading the SPSR register to see which of the three status bits is set. If SPIF is set, reading the received data or initiating a new data transfer automatically clears the SPIF bit.
A write collision occurs when a byte is written to the SPI data register, SPDR, while data is being exchanged. The WCOL flag is set when a write collision occurs. The data transfer that is in process when the write collision occurs is completed. WCOL is cleared by a read to the SPSR followed by a read or write to the SPDR.
A mode fault occurs when the SPI senses that a multimaster conflict (MC68HC11F1 Technical Data Manual, p.10-5) exists on the network as explained above in connection with the /SS input. When a mode fault is detected, the processor:
1. disables the SPI outputs by clearing the bits in the Port D data direction register (DDRD),
2. clears the MSTR bit in the SPCR to configure the SPI as a slave,
3. clears the SPE bit to disable the SPI, and
4. generates an interrupt if the SPIE bit in the SPCR is enabled
These steps greatly reduce the chance that the communicating devices might be damaged by contention on the SPI bus. The MODF bit is cleared by a read of the SPSR followed by a write to the SPCR.
SPI Data Transfers
A data transfer is initiated by a master device when it stores a message byte into its SPDR register. If a slave device has already stored a byte into its SPDR register, that byte will be exchanged with the master’s byte. Once the bytes have been exchanged, the master may write a new byte to initiate another byte exchange. Although data byte transfers are easily executed once the network has been wired and configured properly, a carefully executed software protocol may be required to ensure data integrity.
The flexibility and power of the 68HC11’s serial peripheral interface supports high speed communication between the 68HC11 and other synchronous serial devices. The interface can be used to support analog to digital and digital to analog converters, networks of many computers controlled by a single master, or networks of devices controlled by several coordinated masters. Pre-coded device drivers configure the SPI for a standard data format, and routines defined in this chapter make it easy to customize a data format and baud rate for your application. With careful design, many peripherals can communicate via the SPI, and powerful multi-processor systems can be linked using this high speed bus.
Home|Site Map|Products|Manuals|Resources|Order|About Us
Copyright (c) 2006 Mosaic Industries, Inc.
Your source for single board computers, embedded controllers, and operator interfaces for instruments and automation