Saturday, April 13, 2019

Designing and testing the FPGA logic for the 1130 control panel

Writing VHDL for the FPGA

During my holiday away in the Bahamas and Florida, I wrote all the VHDL code for the FPGA. It consists of eight autonomous sections - four each for reading the state of 1130 logic signals and for driving the four chains of LEDs on the panel.

Coding in the Bahamas
The logic signals are read using PCA9505 chips that have 40 input pins connected to up to 40 of the 1130 logic signals. These are read over an I2C chain, which I implemented using some open source I2C master code and layering on the protocol to address and read from a chip.

As I read the signals, I use the state I just read to adjust the lamp level index. This is an integer running from 0 (fully off lamp) to 31 (fully on). I sample the signals 60 times a second and increment the index when the signal is one, otherwise decrement it. Of course, I never get the value get below 0 or above 31.

The LEDs employ APA106 controller chips inside which implement a single wire serial chain. The protocol is pretty simple - a reset burst of 60 us of logic low level readies the chips, then I send out the stream in GRB order starting from the first and ending with the last LED on the chain.

Each APA106 latches in the 24 bits intended for that LED, 8 bits of brightness each for the Green, Red and Blue color. It strips off the 24 bits and passes along the remaining signal stream to the subsequent chips. Thus, a string of 480 bits will provide the brightness and color to drive 40 LEDs in the chain

By varying the duration of the on and off times of the serial wire, I am modulating either a 1 or a 0 bit value for each of the 480 bit cells above. I can control the timing very precisely to ensure fault-free operation.

I built up logic to generate a sequence of the reset interval then up to 40 LEDs worth of color/brightness, repeating infinitely. As I begin each LED, which represents one of the 1130 logic signals, I use the lamp index produced by the sensing circuit above to select the proper GRB value for the index level.

Thus, if I have calculated a lamp is off, I get all-zeroes, while any lit level gives me the GRB that simulates an incandescent bulb at that brightness.This also simulates the color shift towards red as the lamp is dimmer.

The final two parts of the code are the startup reset controller and the lamp test logic. I hold all the finite state machines in reset for 63 clock cycles, also generating a reset signal that runs out to the four PCA9505 chips that sense the logic state. When the Lamp Test signal is on, I override the selection of color/brightness data to produce a full on white value in all LEDs.

Testing using simulation

Since my FPGA is a Xilinx Spartan 7, I used the Vivado design suite as the tool chain to write and synthesize the VHDL into the bitstream for the FPGA. This suite provides simulation capability, which I used to debug the logic that drives the LED chains. I worked with a single copy of the LED driver logic until it was producing the correct output under the simulator.

Simulating in Florida
Once it passed muster, I replicated the logic for the other three LED chains. I designed the LED chains to match the four PCA9505 chips sensing logic states. I could have chained all the sense chips together on one I2C link and chained all the LEDs together on a single serial line, but chose to break it up into four independent sections because, with an FPGA, hardware is essentially free and this further reduces the chance that anything will operate too slow and cause erratic behavior.

I did take some time off to watch the SpaceX Falcon Heavy launch, ensconced at the nearest viewing site in Kennedy Space Center, just outside the Apollo/Saturn center and across the creek from launch pads 39A and 39B. It was an awesome experience, although I can't throw any shade at the rest of the trip.

No comments:

Post a Comment