/* * Scan keypad and write the keycode to LEDs. * The matrix keypad of Wytec EduBase board is connected to * PORTD and PORTA. * * The connections between the keypad and Tiva LaunchPad are * row 0 PTC10 * row 1 PTC11 * row 2 PTC12 * row 3 PTC13 * col 0 PTE20 * col 1 PTE21 * col 2 PTE22 * col 3 PTE23 * * This program scans keypad and writes the keycode to the LEDs * on PORTB. The keycode is labeled 1 to 16. Since there are * only 4 LEDs, the bottom right key returns a 16 will not turn * on any LED. * */ #include "MKL25Z4.h" void delayUs(int n); void keypad_init(void); char keypad_getkey(void); int main(void) { char key; volatile unsigned char readback; /* initialize ports connected to keypad */ keypad_init(); /* enable PTC 6-3 as output for LEDs */ SIM->SCGC5 |= 0x800; /* enable clock to Port C */ PORTC->PCR[3] = 0x100; /* make PTC3 pin as GPIO */ PORTC->PCR[4] = 0x100; /* make PTC4 pin as GPIO */ PORTC->PCR[5] = 0x100; /* make PTC5 pin as GPIO */ PORTC->PCR[6] = 0x100; /* make PTC6 pin as GPIO */ PTC->PDDR |= 0x78; /* make PTC6-3 as output pin */ while(1) { key = keypad_getkey(); /* read the keypad */ PTC->PDOR = key << 3; /* and write it to the LEDs */ } } /* * This function intialize the ports connected to the keypad. * PORTA is used as input port and PORTD is used as output port. */ void keypad_init(void) { SIM->SCGC5 |= 0x0800; /* enable clock to Port C */ SIM->SCGC5 |= 0x2000; /* enable clock to Port E */ PORTC->PCR[10] = 0x100; /* make PTC10 pin as GPIO */ PORTC->PCR[11] = 0x100; /* make PTC11 pin as GPIO */ PORTC->PCR[12] = 0x100; /* make PTC12 pin as GPIO */ PORTC->PCR[13] = 0x100; /* make PTC13 pin as GPIO */ PORTE->PCR[20] = 0x100; /* make PTE20 pin as GPIO */ PORTE->PCR[21] = 0x100; /* make PTE21 pin as GPIO */ PORTE->PCR[22] = 0x100; /* make PTE22 pin as GPIO */ PORTE->PCR[23] = 0x100; /* make PTE23 pin as GPIO */ PTC->PDDR &= ~(0xF << 10); /* make PTC13-10 input */ PTE->PDDR &= ~(0xF << 20); /* make PTE23-20 input */ } /* * This is a non-blocking function to read the keypad. * If a key is pressed, it returns a keycode. Otherwise, a zero * is returned. * PTC (ROW) is used as input port. There are pull-down resistors for * all pins used for keypad on the EduBase board. When these pins * are not active, they are low. * PTE (COL) is used as output port that drives the keypad columns. * First all columns are driven high and the input pins are read. If no * key is pressed, it will read a zero. Otherwise, some key is pressed. * If any key is pressed, the program drives one column high at a time and * leave the rest of the columns inactive (float) then read the input pins. * Knowing which row is active and which column is active, the program * can decide which key is pressed. */ char keypad_getkey(void) { int row, col; const char col_select[] = {0x01, 0x02, 0x04, 0x08}; /* one of the row is active */ /* check to see any key pressed first */ PTE->PDDR |= 0xF << 20; /* enable all columns */ PTE->PSOR = 0xF << 20; /* set column data pins all high */ delayUs(2); /* wait for signal to settle */ row = (PTC->PDIR >> 10) & 0xF; /* read all rows */ PTE->PCOR = 0xF << 20; /* set column data pins all low */ PTE->PDDR &= ~(0xF << 20); /* disable all columns */ if (row == 0) return 0; /* no key pressed, return a zero */ /* If a key is pressed, it gets here to find out which key. * It activates one row at a time and read the input to see * which column is active. */ for (col = 0; col < 4; col++) { PTE->PDDR &= ~(0xF << 20); /* disable all cols */ PTE->PDDR |= col_select[col] << 20; /* enable one col */ PTE->PSOR = 0x0F << 20; /* turn the active col high */ delayUs(2); /* wait for signal to settle */ row = (PTC->PDIR >> 10) & 0xF; /* read all rows */ PTE->PCOR = 0xF << 20; /* set column data pins all low */ if (row != 0) break; /* if one of the input is low, some key is pressed. */ } PTE->PDDR &= ~(0xF << 20); /* disable all cols */ if (col == 4) return 0; /* if we get here, no key is pressed */ /* gets here when one of the rows has key pressed */ if (row == 0x01) return col + 0 * 4 + 1; /* key in column 0 */ if (row == 0x02) return col + 1 * 4 + 1; /* key in column 1 */ if (row == 0x04) return col + 2 * 4 + 1; /* key in column 2 */ if (row == 0x08) return col + 3 * 4 + 1; /* key in column 3 */ return 0; /* just to be safe */ } /* delay n microseconds (41.94MHz CPU clock) */ void delayUs(int n) { int i, j; for(i = 0 ; i < n; i++) for(j = 0; j < 7; j++) {} /* do nothing */ }