SSIB - Custom I/O Devices for Other MicrocontrollersSubmitted to Parallax by Al Williams
This SX project is an abbreviated excerpt from Al Williams' Beginning Assembly Language for the SX Microcontroller book. The book is not yet available in print, so you may download the individual chapter at this link. For the complete book, click here.
One of the things the SX excels at is producing custom I/O devices for other microcontrollers. The SX is fast and inexpensive – it is well suited to the task of making dedicated peripheral devices. This peripheral device can help other microcontrollers (like BASIC Stamp modules, for example) receive serial data from a PC or other device.
Parallax’s BASIC Stamp modules have a microcontroller that you program using BASIC. These BASIC Stamp modules are perfect for quick and simple projects. Although BASIC Stamp modules excel at many jobs, they are inherently single-tasking. This single-tasking philosophy makes programming simpler, but it makes serial input tricky. The BASIC Stamp has a perfectly capable command for reading serial data (the SERIN command). The problem is that the BASIC Stamp can't issue a SERIN command and do something else at the same time. If a BASIC Stamp module performing a task when serial data arrives, the data is lost. To ameliorate this limitation, BASIC Stamp modules can employ a handshaking signal. This output line signals the transmitting device when the BASIC Stamp is ready to accept serial data. This works well if the sending device can stop transmission. Unfortunately, this isn't always possible or desirable.
The best answer would be to insert a buffer between the sending device and the BASIC Stamp module. The buffer would hold any incoming data until the BASIC Stamp program reads it. This is a perfect application for an SX. The high speed of the SX allows you to service many serial channels simultaneously with no chance of data loss. This particular design uses an SX28 – the project doesn’t even use all the pins available, and just ignore the extra pins.
On the BASIC Stamp side the SSIB uses 3 pins. One pin receives data from the SSIB. The other two pins act as handshake lines. If the BASIC Stamp asserts CHANA, the SSIB sends data from channel A to the BASIC Stamp. CHANB selects data from the B channel. If neither line is active the SSIB sends no data to the BASIC Stamp. In its default configuration, the SSIB uses 9600 baud communications on each channel. However, you can change a few configuration parameters to alter this for each port individually.
Inside the SSIB
Click on the image to the right for a close up view of the schematic. The SSIB code (see the Listings at the end of this unit) takes advantage of the SX's high clock speed. Although the SX in use can clock up to 50 MHz, this is overkill for this application. Even at 10 MHz, there is plenty of time to do all the tasks required. Running more slowly allows the SX to draw less power. Remember, many processors divide their external clock, but the SX does not when in turbo mode. So an SX running at 10 MHz is comparable to some other processors running at 40 MHz! A processor that divides by 4 would have to run at 200 MHz to match a 50 MHz SX. Almost all of the code executes in response to a high-speed periodic interrupt that occurs every 13 µs.
The first thing the interrupt service routine (ISR) does is transmits any pending serial bits. Next, the serial receivers execute (first channel A, then channel B). Notice that the receivers are essentially copies of each other, but each receiver has private variables.
After servicing all 3 serial channels, the ISR turns its attention to managing the circular buffers for each channel. If a transmission is already in progress, the ISR simply exits. Otherwise, the ISR examines each channel's handshaking line. If the line is active, the code examines the corresponding circular buffer. If any characters are waiting, the ISR moves a waiting character into the transmit register so that on the next interrupt the character will be sent to the BASIC Stamp.
Once the chip is running, the main loop (at mainloop) simply waits for an incoming character, and moves it to the correct queue. The enqueue and get_byte routines (along with enqueue1 and get_byte1) handle the mechanics of reading each byte and placing it in the circular buffer. Previous examples did the buffering in the ISR. However, with two channels, I decided to move the buffering to the main program (which has practically nothing to do anyway).
The queuing logic implements a 16-byte circular buffer that is more sophisticated than early versions you’ve examined. The tricky part of the code computes how much of the buffer is free. If this number is less than or equal to the BUFFERLIM constant, the SSIB turns off the inbound handshaking line for that channel. If the device in question can respond to handshake requests quickly, you could set BUFFERLIM to 1. However, many devices can still send a character or two before they respond to a handshake. In that case, you can set BUFFERLIM to a higher value.
Using the SSIB
The device connected to the SSIB’s RES1 and RES2 terminals is a 10 MHz ceramic resonator with capacitors. This three-terminal device has a ground lead in the center. The other two terminals are interchangeable. If you are simply testing the circuit you can use the SX-Key or SX-Blitz to generate the 10 MHz clock automatically (it senses the FREQ directive in the program). You could also use a 10 MHz crystal with some extra capacitors, but a ceramic resonator is less expensive and just as good in this application. The SX data sheets show how to use a crystal if you want to try one.
The listing at the end of this unit shows the code that reads data from the SSIB. Instead of actually performing other processing, the program does simulated work in the form of a SLEEP statement. Notice that the BASIC Stamp reads data from the same pin regardless of which channel it wants to read. However, the BASIC Stamp program’s SERIN command uses a different handshaking line to select the channel it wants. In this case, using pin 12 selects channel A and pin 13 selects channel B. Regardless, the BASIC Stamp reads the data from pin 14.
The simulator BASIC Stamp at IC2 (see the listings) just writes bytes out of each serial port periodically. Of course, the two BASIC Stamp modules won't be synchronized, so only the buffer allows this arrangement to work. If you set the first BASIC Stamp module to read more often than the simulator writes, the buffer should never overflow. If you send bytes more often than you read, the SSIB buffers will fill. In this case, the SSIB will use the outbound handshaking lines to hold off the simulator.
Standard and Inverted Mode
The BASIC Stamp and the SSIB can perform serial I/O in standard mode, or in inverted mode. The mode selection affects the polarity of the signal line, of course, but it also changes the polarity of the handshaking lines. In standard mode, the handshake lines must go low to enable data transmission and this is recommended for most applications.. This works well, because the SSIB has internal pull up resistors to hold the lines high in the absence of other input. If you use inverted mode, be aware that the handshake lines will be enabled until the BASIC Stamp program or other device wakes up and explicitly inhibits transmission. If you want to modify the timing used to generate the baud rates, you’ll need to understand how the code handles different speeds. To ensure accuracy, the interrupt rate needs to be quite a bit faster than the period of a single bit.
Why design chips like the SSIB? Creating functional modules allows designers that don't have your tools and skills to still create powerful systems. With the low-cost of the SX chip there is no reason you can't add more than one to most designs. Even when designing with the SX, chips like the SSIB can let you distribute the workload among several processors for even more power.
Download a zip with some source code here.