Using TI’s TM4C MCU
There are many benefits to integrating a small display into your embedded system. In this project article, Stuart takes a 3.5″ LCD video monitor and builds a circuit that provides a text-based terminal that can plug into the display. This basically emulates an old-style alphanumeric computer terminal, but using modern low-power LCD technology.
I picked up a $15 LCD video monitor from Amazon. It has two standard, composite video inputs. The screen is only 3.5″, so you would never use it to replace a 12″ or 14″ monitor. It is intended for use as a display for backup cameras in vehicles.
All that said, a display like this has some other uses. For example, it could be a status display for an embedded system. Of course, you could always carry around a tablet, or even display things on your phone. But what if you want the display self-contained? Or you don’t want to add Wi-Fi to your design? What if it’s a piece of equipment that is located where phones and computers aren’t allowed?
I thought it would be interesting to build a circuit to provide a text-based terminal that can plug into the display. The effect would be similar to the old alphanumeric computer terminals used in the 1970s and 1980s, but with a much smaller, lighter, and less power-hungry screen. To make this work, I had to generate an output that would drive the composite video input of the monitor.
WHAT IS COMPOSITE VIDEO?
The composite video waveform dates back to the days of monochrome televisions, when they were built with vacuum tubes. Because the signal was sent over the air, everything needed to display a complete picture had to be embedded in the transmitted waveform. The picture on the screen was painted as a series of lines from left to right and from top to bottom. There was no digital communication. It was all done with voltages and resistor-capacitor timing.
To paint the image on the screen, the waveform has to include:
• A signal to start painting on the picture tube at the top left corner of the screen
• When to start each new line
• The brightness (white level) of each dot on each line
The composite waveform is shown in Figure 1. Since the video terminal circuit that I built is only for painting characters—not a television picture—all the video information is either white or black. In contrast, on a television broadcast the video portion would vary between white and black to reproduce the grayscale image of the transmitted picture. The composite waveform, when sent over a cable, is normally a 1V P-P (peak-to-peak) signal. When broadcast over the air, the amplitude varies with signal strength. Circuits in a television receiver normalize it, so the signal can be used.
Each line starts with a horizontal sync pulse that is about 0.1V, with 4.7µs duration. This tells the receiver to restart the scan at the next line. There is a black region on either side of the horizontal sync pulse to give the circuits in the receiver time to process the sync input. These are called “blanking,” and they are referred to as the “front porch” (the blanking interval just before the sync) and the “back porch” (the blanking interval just after the sync). Between the back porch of one sync pulse and the front porch of the next is the live scan video information. This is where one scan line of the picture is painted.
Once the last horizontal line has been painted, the scanning beam must be moved back to the top left corner to start the next image. This is done with vertical synchronization pulses, which are the same voltage as the horizontal sync pulses, but have a longer time period. Circuits in the television recognize the difference in the pulse width between horizontal and vertical sync, and move the scan back to the top left corner. The vertical sync on an old television took some time to retrace the scanning beam, so three vertical sync pulses were followed by a long blanking interval. That gave the circuits time to make the vertical recovery.
The vertical blanking interval is broken up or serrated by horizontal sync pulses, so the horizontal synchronization isn’t lost during the vertical retrace time. The vertical scan rate is 60Hz in the US NTSC system. This is not an accident. By making the vertical scan rate the same as the 60Hz power frequency, some visible artifacts resulting from using vacuum tubes, unregulated power supplies, tube filaments operating at 60Hz, etc., can be minimized. The horizontal sync rate is 15,750Hz, or a 63.5µs period. The 60Hz vertical rate combined with a 15,750Hz horizontal line frequency gives 262.5 horizontal scan lines per picture.
TOTAL VIDEO TIMES
Because the sync, front porch and back porch together need about 11µs, the total live video time on each scan line is about 52µs. So, the horizontal synchronization process steals about 20% of the total line time. Similarly, the vertical retrace takes some time, so a portion of the 262 horizontal scan lines are blanked and used for vertical retrace.
In displaying text on a monitor using composite video, each character needs multiple lines on the display. In the 1970s and 1980s, typical characters were either 5×7 or 7×9—that’s 5 dots wide by 7 dots high, or 7 dots wide by 9 dots high. To display a complete character, 7 or 9 scan rows would be needed, with at least one blank row of dots between each character row to separate the characters. The monitor would therefore display around 20 or 24 character rows.
Similarly, with each character being 5 or 7 dots wide, clocking the dots at a reasonable rate to make the characters wide enough to read, results in a row of typically 70 to 80 characters. Filters in a television to remove the audio subcarrier mean a television can’t display that many dots on the screen, but a monitor with composite video input can.
If the first line of the display contains the characters ABC, then the first three locations in the RAM will contain the ASCII codes for those characters. As the scan moves across the screen, the first scan line will address the top line of character A, then B, then C, and then the rest of the line will be blank. The second scan line will address the second line of character A, then B, then C, and so on. Each character row is displayed, one scan line at a time, all the way to the bottom of the screen.
Later versions of the composite waveform inserted information into the vertical blanking interval for things like channel information and closed captioning. Although composite video has been superseded by higher resolution VGA, DVI and HDMI in computers, the ability to run a full video signal down a single coaxial cable still has advantages in some situations. And, now, of course, the television broadcast itself is a digital HDTV transmission.
EARLY VIDEO TERMINALS
The composite video standard defines a standard way of getting a video image to the monitor, but a signal containing intelligible information still has to be generated. Early video terminals were constructed with TTL (transistor-transistor logic). The logic had to walk through the display memory, retrieving stored ASCII characters in sequence.
The output of the display memory would go to a ROM (read-only memory) that contained the codes for converting the ASCII from the RAM into dot patterns for each scan line of the character. A shift register produced white/black outputs that produced dots on the screen. Additional logic was needed to generate the horizontal and vertical signals when needed, and still more logic was needed to handle incoming serial data, and write it into memory. The Lear-Siegler ADM-3A was one such terminal. You can find a maintenance manual for it with schematics on the Internet. That terminal had over 100 ICs.
Video cards installed in early computers often used video timing ICs, such as the Motorola 6845. These devices had programmable internal counters to address external RAM and to generate the vertical and horizontal timing pulses. But they still required external RAM, an external character generator ROM and additional hardware to put the ASCII characters into the RAM.
The new circuit implements similar functionality using a modern microcontroller (MCU). I used a Texas Instruments (TI) TM4C1233H6PM Arm-based MCU, mainly because I had a few on hand. The entire circuit consists of the MCU, an RS232 interface chip, a single-gate, open-collector buffer and a voltage regulator. A transistor drives the video output to the monitor.
The TM4C has enough internal memory to store the video information and to support the program. Memory was expensive in the days of the original terminals, but there is plenty of memory to store scan rows instead of characters in the TM4C RAM. So, instead of storing ASCII characters that are converted to dots by an external ROM, the TM4C program converts the incoming ASCII codes to dots in a lookup table, and stores the dots in the RAM.
Using internal RAM has an additional advantage—no complicated RAM synchronization is needed. Early video cards needed a mechanism to ensure that the computer microprocessor did not write new characters into memory during the live scan time. If they did, the display would be covered with “snow”—white dots that randomly appear on the screen. If the writing occurs during the live scan time, it interferes with reading the memory to display the characters. One way this was fixed is by writing only during the horizontal or vertical blanking periods, when the screen is blanked anyway.
In the TM4C design, this isn’t necessary, because the reading is performed using the internal DMA controller. DMA access to the RAM is synchronized with the MCU CPU. As a result, there is never a problem with interference between the two.
Early terminal designs used a shift register to shift out the dots. The TM4C design uses one of the synchronous serial ports to output the dots. Internal timers generate the synchronization signals, and the entire process is driven by the horizontal sync signal. The TM4C provides a nearly self-contained video terminal with few external parts needed (not counting, of course, the electronics in the LCD video terminal, itself).
Due to the tiny size of the monitor, a DIP switch selects either a 75-character x 20-row output, or a 35-character × 10-row output. The 75×20 output is for display on larger terminals. You can use it on the tiny display, but it’s impractical.
Figure 2 is a block diagram showing how a terminal might be implemented in the 1980s, compared to the new design. The address counters in the old design (top of Figure 2) might be discrete counters or part of a video timing chip, but you can see that there is a lot of logic required either way, to generate the video information. This diagram doesn’t even include the logic that gets new characters into memory. The lower diagram in Figure 2 is the new approach, where nearly everything is contained in the MCU. Although the MCU, itself, is far more complex than the old design, it still replaces dozens of ICs with just one.
The schematic of the circuit is shown in Figure 3 and Figure 4. U1, the TM4C1233H6, is one of many parts in the TI TM4C family. Internal timer T0 generates the 15,750Hz horizontal and vertical sync pulses, and the output of T0 is fed back to input PB6 as an interrupt.
Synchronous serial interface number 3 is used to generate video dots and blanking. The output of SSI3, on PD3, is pulled to ground, because it needs to be at blanking level when not active, and the TM4C normally floats the output when inactive. SSI3 is configured to transmit 7-bit words, since the character matrix is 7 dots × 9 dots. The SSI shift register is clocked at 10MHz in 75-character-per-line mode, and at 5MHz in 35-character-per-line mode. This is the dot rate, and allows the 52.5µs live scan time to display 525 dots. Using a 7×9 character format, that’s 75 characters per line. With a 5MHz clock, it’s 37 characters per line. I set it to 35 in the firmware.
U3 buffers the output of PD3 so it can drive the output transistor. Serial port 0, on PA0 and PA1, is used for programming the device. A jumper, W1, is grounded to put the TM4C into programming mode. J2 connects an external RS232 converter to connect to the host serial port, as described in my article “Debugging Embedded Systems with Minimal Resources” (Circuit Cellar 312, July 2016). Figure 5 is a schematic of the programming adapter.
U5 is a 3.3V to RS232 converter that connects serial port 1 (UART1), on PB0/PB1, to the host system. UART1 is fixed at 9600 baud in the firmware, though that can obviously be changed. Header J3 is a 10-pin header that connects to a D-series connector with a short cable. Transistor Q1 mixes the dot and sync signals to produce the composite video output. To keep the dots crisp, Q1 is biased so that it never goes fully into saturation or cutoff.
There are some special considerations in the TM4C firmware to make working video. The “character generator ROM,” which is actually an array in flash memory, is configured for 7×9 dots. But the actual display memory is sized for 10 dots per character, to make a blank scan line under each character row for vertical separation. This extra scan line isn’t included in the character matrix. It’s just an extra line that is initialized to all zeros (blank). So, the start of the first character row is at location 0 in the display memory array, and the next one is at location 750 (75 characters per row × 10 scan lines per character). To blink the cursor, the blank line under the character where the cursor is located is switched once per second between white and black.
Although the horizontal characters per line can be changed simply by changing the dot clock and forcing the DMA to send only 262 dots (35 characters) per scan line, the vertical spacing isn’t so easy. In 35-character-per-line mode, if the same number of character rows were used as in the 75-character-per-row mode, the characters would be vertically “squashed,” and only the upper half of the display would be used. So, in 35-character-per-line mode, each line of dots is sent twice to expand the vertical height of each row. The full frame is still 262 scan lines, but each character row now takes 20 scan lines instead of 10.
Timer T0 is configured as a 16-bit PWM generator. The duty cycle is 4.7µs for the horizontal sync, and 58µs for vertical sync. The interrupt service routine (ISR) has to change the PWM duty cycle (but not the frequency) to generate the wider vertical sync pulse. The value can’t be changed inside the ISR, because it will produce a short pulse at the output. Instead, the ISR sets a flag, and the main loop changes the duty cycle, when the time count is lower than the new duty cycle value. This causes the new duty cycle and pulse width to occur on the next timer period.
The software scrolls the screen when a new character needs to be inserted and the screen is at the end. This is accomplished by moving an index that indicates where the top row starts. At initialization, location 0 in the display RAM area is the start of the first line. When the bottom of the screen is reached, the screen is scrolled up by making location 750 (the start of the second character row) the top of the screen, and the row starting at location 0—now the last row on the screen—is blanked. The circuit board and the monitor, displaying a few lines of test text, are shown in Figure 6. See the sidebar “ Composite Video Display Calculations” below as a guide if you wish to try out alternate clock frequencies or different character generator dimensions.
When color television was introduced, the monochrome video waveform was modified to accommodate the addition of color. The waveform had to be compatible with existing monochrome televisions, so the changes had to be invisible to existing monochrome receivers. Color was added by sending a color sync burst during the horizontal synchronization back porch, which synchronized the chrominance phase with that of the transmitter. The color information is phase-encoded with a 3.58MHz signal on the video. Circuits inside the television extract the 3.58MHz color signal to display the color information with the luminance (white/gray/black) information. The video circuit here does not include color. That would take additional hardware and a significantly faster processor.
As currently implemented, the terminal is fairly simple. Characters are received via the serial port and written to the display at the current cursor position. When the end of the display is reached, the screen scrolls up one line, and new characters are inserted at the bottom. The addition of direct cursor addressing would allow the host to send characters that tell the terminal to place the cursor at a specific line and column position.
Another improvement would be to add underline or inverse video for the characters. The high bit of the incoming byte can be used to indicate when a character is to be displayed in this enhanced mode. The original ASCII character set needed only 7 bits, so the highest bit can be used for special features. Some word processors of that era used these features. when available.
Although this entire project was based on displaying ASCII characters, there is no reason you can’t display graphics information on the screen. The resolution isn’t very high, and, as mentioned, adding color would require different hardware. But unlike the character-based terminals of the 1980s, you aren’t locked into displaying characters only.
Since there is no hardware character generator between the RAM and the dot output, you can display low-resolution graphics just by filling the memory with the graphics image. In fact, the first test I did on the system when I connected it to the LCD was to display a line in the middle of every other character position in each character row. The result was a display that had just a series of horizontal dashed lines. I did this because it was easy to do and didn’t require any of the character processing routines to be functional. If you look at the source code, you will see that the simple code to do this is still there, just commented out. The source code for this project can be downloaded from Circuit Cellar’s article code and files webpage.
This project started out to re-create something resembling the terminals that we used on in the 1980s. Unless you are interested in that sort of project, the original intent for this circuit wouldn’t be of use. But the simplicity of the circuit provides an easy way to build a text-based or even graphics-based monochrome display that will drive any monitor with a composite video input. It provides an inexpensive way to produce a display for diagnostics, monitoring and general visual displays, especially given the low cost of the monitor used for the prototype.
The calculations for the composite video display are given here, should you wish to tinker with alternate clock frequencies or different character generator dimensions:
Horizontal blanking plus sync time = 10.9µs
Horizontal scan rate = 15,750Hz = 63.5µs period
Live scan time = 63.5µs – 10.9µs = 52.6µs
Dots per line = live scan time × dot clock frequency = 52.6µs x 10MHz = 525 for 10MHz, 262 for 5MHz
Characters per line = dots per line/horiz. dots per char = 525/7 = 75 for 10MHz, 37 for 5MHz (limited to 35 in FW)
See article code archive for code for this article.
“Debugging Embedded Systems with Minimal Resources” (Circuit Cellar 312, July 2016).
Texas Instruments | www.ti.com
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • MARCH 2020 #356 – Get a PDF of the issue