DAT290 / kod / Central_unit / keypad.c
keypad.c
Raw
#include 	<keypad.h>

/*
 * Initialization for keypad on a GPIO-port (low bits) specified in the parameter of the function.
 * The GPIO_TypeDef definitions can be found inside stm32f4xx.h.
 */
 
void initKeypad(GPIO_TypeDef* GPIOx){
	
	
	// Initialixzation of the pre-defined struct "GPIO_InitTypeDef".
	// Definition can be found in stm32f4xx_gpio.h.
	
	GPIO_InitTypeDef GPIOx_Init;
	
	// The first 4 pins are configured as inputs, these are the column pins you read the data from.
 	GPIOx_Init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIOx_Init.GPIO_Mode = GPIO_Mode_IN;
	GPIOx_Init.GPIO_OType = GPIO_OType_OD;
	GPIOx_Init.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_Init(GPIOx, &GPIOx_Init);	
	
	// Pins 4,5,6 and 7 are configured as outputs as each row needs to be activated for data to be read from the columns.
	GPIOx_Init.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6 | GPIO_Pin_7;
	GPIOx_Init.GPIO_Mode = GPIO_Mode_OUT;
	GPIOx_Init.GPIO_OType = GPIO_OType_PP;
	GPIOx_Init.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOx, &GPIOx_Init);	
}

// A function used to activate any row, or reset all of the rows.
void activateKeypadRow(unsigned short row, GPIO_TypeDef* GPIOx){
	switch(row){
		case 1: GPIOx->ODR = 0x10; break;
		case 2: GPIOx->ODR = 0x20; break;
		case 3: GPIOx->ODR = 0x40; break;
		case 4: GPIOx->ODR = 0x80; break;
		default: GPIOx->ODR = 0;   break;
	}
}

/* A function used to read every column of a row.
 * 
 * Example:
 * 	If a row is activated and the first and last buttons on the keypad are pressed on that row.
 * 	Then the function returns 9 (1001 in binary).
 * 
 * 	If the second and third buttons are pressed on a activated row.
 * 	Then the function returns 6 (0110 in binary).
 */
 
short readKeypadColumn(GPIO_TypeDef* GPIOx){
	unsigned short input, rv;
	
	// Read current input from the columns of the activated row.
	input = GPIOx->IDR & 0b1111;
	
	// rv = return value.
	rv = 0;
	
	// Now check which columns are turned on and add them to the return value variable.
	
	// if input == 1000.
	if(input & 8){
		rv |= 8;
	}
	
	// if input == 0100.
	if(input & 4){
		rv |= 4;
	}
	
	// if input == 0010.
	if(input & 2){
		rv |= 2;
	}
	
	// if input == 0001.
	if(input & 1){
		rv |= 1;
	}
	
	return rv;
}

/*
 * A function used to update the public KEYPAD_STATUS variable. 
 */

void readKeypad(GPIO_TypeDef* GPIOx){
	short row, col = 0;
	
	// rc = row counter.
	short rc = 0;
	
	// KEYPAD_STATUS is a public variable defined in keyad.h.
	KEYPAD_STATUS = 0;
	
	
	// Loop through every row activating it.
	// Use the readKeypadColumn function to find out which columns are pressed on the row.
	// Add the value returned from the readKeypadColumn function to the KEYPAD_STATUS variable.
	// Every column read is bit-shiftet 4 steps to the right because there are 4 columns read.
	// See keypad.h for how to use the KEYPAD_STATUS variable.
	
	for(row = 4; row > 0; row--){
		activateKeypadRow(row, GPIOx);
		if(col = readKeypadColumn(GPIOx)){
			KEYPAD_STATUS |= (col << 4*rc);
		}
		rc++;
	}
	
	// At last, no row should be activated when the read is done.
	activateKeypadRow(0, GPIOx);
}


unsigned short getKeypadStatus(void){
	return KEYPAD_STATUS;
}