The Hexkeypad can be plugged into either the JP1 or JP2 40-pin expansion headers. Once plugged in it is automatically connected to the lower 8 bits of that header and ignores the rest. The lower 8 bits are connected directly the 4 row pins and 4 column pins (so 8 pins in total) as shown further below.
| Device | Hexkeypad | |||||||||||||||
| Input/Output | either | |||||||||||||||
| Address Base | JP1=0xFF200060, JP2=0xFF200070 | |||||||||||||||
| Address Map |
| |||||||||||||||
| Initialization | Set direction register bits so that either rows are inputs and columns are output, or vice versa. | |||||||||||||||
| Interrupts |
| |||||||||||||||
| Hardware Setup | Connect the 40-pin ribbon from the hexkeypad to either port JP1/2 on the DE1-SoC | |||||||||||||||
| Reference | Hexkeypad Tutorial |

The hexkeypad is arranged as a 4x4 matrix of wires, and note that they are ONLY wires, no circuitry or logic other than pull-up exist. When you press a button the two wires touch, so to figure out when a key is pressed you need to configure, for example, the rows as outputs and the columns as inputs. You can then drive the rows low and see if any column pin turns low (since the hexkeypad is active-low as explained below). For example, if you press number 5 on the hexkeypad, that connects pin R1 to C1 so if you set R1 as a low output you would see it low on C1 if it was an input, and if you set C1 as a low output you would see low on R1 if it was an input. See the referenced Documentation above.
Active-low - The pins of the hexkeypad are set to be "pulled-up" to logical 1 (or high) by default, so if nothing is being pressed you should read 1's. You should hence drive the output pins low and observe which input pin is low.
Acknowledging interrupts - Interrupts are triggered when any bit in the Edge Capture Register is high. For the hexkeypad this usually means an interrupt gets generated when you first press a button. Make sure you clear the edge capture register before you enable interrupts and before you exit your interrupt handler.
The image below shows how the pins connect to the 4 row and 4 column pins of the hexkeypad.
| Port Bit | Hexpad Pin |
| 0 | R0 |
| 1 | R1 |
| 2 | R2 |
| 3 | R3 |
| 4 | C0 |
| 5 | C1 |
| 6 | C2 |
| 7 | C3 |
.equ ADDR_JP1PORT, 0xFF200060 movia r2,ADDR_JP1PORT movia r3,0xf0 stwio r3,4(r2) # Set directions - rows to input, columns to output stwio r0,(r2) # Drive all output pins low ldwio r3,0(r2) # Read port data andi r3,r3,0xf # Mask out all but last 4 bits
.equ ADDR_LEDR, 0xFF200000
.equ ADDR_JP2PORT, 0xFF200070
.equ ADDR_JP2PORT_DIR, 0xFF200074
.global _start
_start:
movia r2,ADDR_LEDR
mov r5,zero # Start display at 00000000
stwio r5,0(r2) # Write to LED displays
movia r2,ADDR_JP2PORT_DIR
movia r3,0x000000f0
stwio r3,0(r2) # Set rows to input, columns to output
movia r2,ADDR_JP2PORT
stwio r0,(r2) # Drive all output pins low
LOOP:
movia r2,ADDR_JP2PORT
ldwio r3,0(r2) # Read port data
movi r4,0xf
and r3,r3,r4 # Mask out all but last 4 bits
beq r4,r3,LOOP
movia r2,ADDR_LEDR
xori r3,r3,0x0f # Invert bits to drive LEDs
stwio r3,0(r2) # Write to LED displays
# Debounce loop
movia r9,10000000
DELAY:
subi r9,r9,1
bne r9,r0, DELAY
br _start
/*****
* Gets a NON-DEBOUNCED key from the keypad. Note that this also shows the
* use of procedures and functions in C.
*
* This program detects a key pressed on the hexkeypad and displays it on the
* red LEDs by lighting the corresponding LED
*****/
#define ADDR_JP1PORT ((volatile long *) 0xFF200060)
#define HEXPAD_DIR ((volatile long *) 0xFF200064)
#define ADDR_LEDR ((volatile long *) 0xFF200000)
unsigned char colstims[]={0xe0,0xd0,0xb0,0x70}; //to run the hexpad
// start the hex keypad
// note that since this uses the GPIO interface you must set the
// directions of the individual bits. See the section on GPIO for
// more information.
void HexkeypadInit()
{
*HEXPAD_DIR = 0xf0; // set directions . rows in, cols out
*ADDR_JP1PORT = 0x0f; //set all rows to high
}
// return key found pressed, -1 if no key pressed
// note: if multiple keys pressed, returns the first key
// does not debounce key!
char HexkeypadIn()
{
// Wait until a key is pressed
int rowRead = (*ADDR_JP1PORT) & 0x0f;
while (rowRead == 0x0f) {
rowRead = (*ADDR_JP1PORT) & 0x0f;
}
// Key has been pressed! Debounce!
int d = 0;
while (d < 100) {
d++;
}
// Switch to read columns
*HEXPAD_DIR = 0x0f; // rows out, cols in
*ADDR_JP1PORT = 0xf0; // set all cols to high
// Process rows
//rowRead = (*ADDR_JP1PORT) & 0x0f;
rowRead = rowRead ^ 0x0f; // invert the number
// Set it to first confirmed row
if (rowRead & 0x01) {
rowRead = 0;
} else if (rowRead & 0x02) {
rowRead = 1;
} else if (rowRead & 0x04) {
rowRead = 2;
} else if (rowRead & 0x08) {
rowRead = 3;
} else {
rowRead = -1;
}
// Read column
int colRead = (*ADDR_JP1PORT) & 0xf0;
// Process column
colRead = colRead ^ 0xf0; // invert the number
// Set it to first confirmed column
if (colRead & 0x10) {
colRead = 0;
} else if (colRead & 0x20) {
colRead = 1;
} else if (colRead & 0x40) {
colRead = 2;
} else if (colRead & 0x80) {
colRead = 3;
} else {
colRead = -1;
}
// Reset rows and columns
*HEXPAD_DIR = 0xf0; // rows in, cols out
*ADDR_JP1PORT = 0x0f; // set all cols to high
// Determine from rows and columns which key was pressed
char numRead = -1;
if ((rowRead != -1) && (colRead != -1)) {
numRead = (char) (4*rowRead) + colRead;
}
return(numRead);
}
int main()
{
char inputkey;
HexkeypadInit(); //this is a procedure to start the keypad
while (1)
{
inputkey = HexkeypadIn(); //function, returns key pressed
if (inputkey != -1) {
int i;
int val = 1;
for (i = 0; i < inputkey; i++)
{
val = val << 1;
}
*ADDR_LEDR = val;
}
}
}