An engineer fresh out of school learns not to believe everything he’s told while designing a character display.
It was my first job out of college–a small contract manufacturing company in the North Bay Area–and they had a small engineering department. I liked the smallness because it meant I got to cut my teeth on the front lines of project design, both hardware and software.
After a few months of small projects, they landed me on a seemingly simple one. The task was to design a 2×20 character display that was compatible with the standard Hitachi LCD interface (HD44780). This also had to be a retrofittable product that would work with our controllers as well as with competing controller products. I was in charge of the interface, character generation, and display painting/scanning. One of the main goals was to take cost out of the design, so I decided to use the then new Cypress PSoC. This chip allowed us to pull the high voltage power supply, the display output interface, and the data input all into the microcontroller. It was a single chip design. The previous design, occupying the same physical size, was completely covered in surface mount parts.
After getting data to be displayed, the next task was getting user data into the chip for display and control. The first generation displays used a simple shift register to take the data input in serial form, and output it in parallel. Because of this, a big flaw was covered up by the previous designers, who of course were long gone before I was hired. The data should have been simple SPI mode 0. But, I was told, the clock goes high when the serial interface is multiplexed. Being new and naive and fresh out of school, I just took it as fact and created special cases to handle the clock line going high, based on timing.
This is where my first challenge started, the data on the display was gibberish. This shouldn't have been that difficult, I had routines that could display arrays of data just fine, now I just needed to get data from an SPI register and populate the array. Even if I had gotten the order wrong, they would at least be ASCII characters, but this was gibberish.
Upon closer inspection, the clock and data rise times were on the order of 100µs. This seemed fast to me, but a call to the field applications engineer (FAE) at Cypress set this young student straight—these were horribly slow rise times. As the clock line went through the transition region, noise on it caused multiple clock transitions to be asserted. I took this back to my supervisor, who informed me that this was probably from the RC filters that were placed on the clock and data lines. He told me that without them, the SPI didn't work with the original display. “Hmmm, that's odd,” I thought. We bypassed the RC and confirmed that with fast clock transitions, the design worked. But this was to be sold as a retrofit, and we couldn't ask customers to remove surface mount parts from their controllers.
This is where the PSoC started to pay off. With the help of the FAE, we routed the clock input into a slow analog comparator inside the chip to eliminate the multiple transitions. Then we used more internal routing to get the signal back to the SPI module. All this signal conditioning, and no CPU resources were being used–it worked like a champ.
We were home free until I plugged my masterpiece into one of our competitors’ boards and it didn't work. How could this be? I looked at the input signals and they were SPI mode 0 conforming. Our controller was not!
Some more digging and reading up on SPI led to the realization that the long-gone engineer had put our main controller board into SPI mode 2. This puts the data sampling on the falling edge, but then he skewed the clock phase with an RC delay, to get the data just barely into the correct position for the positive transition of the clock signal. This essentially made our controller output mode 3 SPI data. He also covered this up with the fact that 8 bits worth of zeros were placed in front of and following the actual data byte. Management insisted that the display had to work both ways automatically, because the old one did.
I needed a way to make a serial interface work in both mode 0 and a barely compliant mode 3. We got samples of all our competitors’ controller boards and I started looking at the start up sequences and SPI modes. Our board was the only one that had an errant SPI mode, all the others were fully mode 0 compliant. Our board was also the most conservative on start up. It had a long 500ms delay after power up, before it sent data to the display. The other boards all sent data to the display in under 100ms. This was my saving grace. I could start a timer on power up and stop the timer when the first clock edge was detected, if it was longer than 300ms, it was our board, so set mode 3, otherwise do normal mode 0. Again, it worked like a champ. After showing management, they said, "It needs to be hot pluggable. What happens when you hot plug it?" It worked fine on our competitors’ controller boards, but not on ours. Argh!
This last hurdle was surmounted in quite an elegant way. I called it auto bit alignment. In the Hitachi protocol, there is an 'E' bit in every data byte that is sent. This bit is always a 1 for any valid data. Previously, I had just ignored the bit since it was always 1. I changed this so that when receiving a byte, if 'E' wasn't 1, the byte got discarded. After a small time delay where the SPI interface was deactivated, I turned it back on and waited for the register to fill. This process would repeat until 'E' was a 1.
This method was so simple and robust that the demonstration was to use a wire and short the clock line high or low, or the data line high or low, and watch the recovery process. It typically recovered after one character, but sometimes it took three corrupt characters on the display before things were aligned. The wire was used because during hot plugging, recovery was almost always imperceptible. I again had to detect which type of controller the display was plugged into, but comparing all the controllers allowed me to once again use a timing pattern to differentiate and work accordingly. Finally, the project was done! The display was a success, and we sold about 10k units a year.
I learned a lot that first year. Mainly to not always believe what I was told, and to exercise due diligence when investigating.
Aaron Lager works in high level programming, covering what the software community now calls full stack development.