What you can do with the PiXi - No. 2
Keypad Scanner for the Raspberry Pi
Adding switches, push-buttons or a keypad to the Raspberry Pi can quickly eat up valuable GPIO, even with an add-on board that gives you extra I/O you can quickly lose GPIO to a large number of buttons. But if you have an FPGA at your disposal with a small amount of I/O available then you could create a matrix keypad scanner that dramatically reduces the amount of I/O needed to connect a button panel or keypad to the Raspberry Pi.
Matrix keypads work differently to basic push-buttons. If you had a 12-button keypad then the basic way of connecting these to some GPIO on the Pi would be to have each button driving a single GPIO pin.
A matrix-keypad reduces the number of connections required by using each button to join a row signal wire (input) to a column signal wire (output). With four row signal wires and three column signal wires, you can create a 12-key button panel with just seven wires. Unfortunately this needs a more complex interface to drive a signal into the row connections, read the output from the column signals and turn the signals detected into a code that indicates which button was pressed.
The FPGA on the PiXi-2.0 has a custom keypad reader built into it. Up to 16 of the 24 general-purpose 3.3V I/O can be configured to implement a matrix keypad scanner that can work with up to 64 keys. Smaller keypads can be connected too which reduce the amount of I/O required.
Both of these keypads use the matrix keypad interface designed into the PiXi FPGA. The one on the left which is a Raspberry Pi powered custom replacement keypad for a computer-controlled telescope usea a 6x4 keypad that requires just 10 GPIO signals. The one on the right uses a 12-key telephone handset style keypad that requires just 7 GPIO signals.
The scanner is completely built into the FPGA It’s written in VHDL (the code is open-source and freely available on GitHub) and compiled into the standard configuration for the FPGA. Essentially, it works like this:
1) Energise the row(1) signal;
2) Read inputs from all column signals;
3) If any button is pressed on row(1), translate the column signals into an ASCII code for the button pressed and write this to a character buffer;
4) Energise the row(2) signal;
5) Read inputs from all column signals;
6) If any button is pressed on row(2), translate the column signals into an ASCII code for the button pressed and write this to a character buffer;
7) Energise the row(3) signal;
8) Read inputs from all column signals;
9) If any button is pressed on row(3), translate the column signals into an ASCII code for the button pressed and write this to a character buffer;
10) Energise the row(4) signal;
11) Read inputs from all column signals;
12) If any button is pressed on row(4), translate the column signals into an ASCII code for the button pressed and write this to a character buffer;
Return to (1) to continue scanning;
Larger keypad designs would continue to scan up to a further four rows depending on how many rows are required.
The character buffer is a 16-character deep “first-in-first-out” (FIFO) memory. The keypad scanner writes characters to the buffer as the buttons are pressed and the buffer can be read from the Raspberry Pi to identify which button has been pressed.
The scanner can also generate key-down & key-up messages so that we can accurately detect if a key is pressed or released.
The scanner includes a look-up-table that translates the column data from the scanner into an 8-bit code that’s unique for each key. This could be anything between 0 & 255. We’ve used ASCII character codes for the numeric keypad shown above so that as the Raspberry Pi reads the data back, it gets the standard & widely recognised ASCII codes for the numbers on the keys as they are pressed.
So if you need more buttons for your project, take a look at the benefits that an FPGA add-on board could provide. This is just one example of what you can do with an FPGA connected to the Raspberry Pi. With over 200,000 logic gates, registers, memory DSP functions, advanced clocking resources and complex I/O functions, not to mention the 100s of 1000s of interconnects that can be used to join everything together to deliver a custom design, there’s a lot you can do with an FPGA and the Raspberry Pi!
Thanks for reading :o) More examples soon!