/*****************************************************************************/ /* FILENAME : KeyHdl.c */ /* */ /* DESCRIPTION : Handling Key Events for Application. */ /* */ /* NOTES : Copyright Sathish Kumar P. All rights reserved. */ /* */ /* AUTHOR : Sathish Kumar */ /* sathishembeddedgeek@gmail.com */ /* */ /* START DATE : 9th Feb 2020 */ /* */ /* VERSION DATE WHO DETAIL */ /* 00.00.01 09FEB20 Sathish Kumar initial version */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* I N C L U D E S */ /* */ /*****************************************************************************/ #include #include #include #include "keyhdl_api.h" #include "keyhdl.h" #if (KEYHDL_USE_OS==1) #include "FreeRTOS.h" #include "task.h" #endif /*****************************************************************************/ /* */ /* D E F I N I T I O N S */ /* */ /*****************************************************************************/ #define NO_OF_BYTES_FOR_KEY ((MAX_KEYS/8)+1) #define KEY_SET_BIT_IN_ARRAY(array,indx) array[(uint8_t)indx>>3] |= \ ((uint8_t)1<<(indx&0x7)) #define KEY_CLEAR_BIT_IN_ARRAY(array,indx) array[(uint8_t)indx>>3] &= \ (~((uint8_t)1<<(indx&0x7))) #define KEY_READ_BIT_IN_ARRAY(array,indx) array[(uint8_t)indx>>3] & \ ((uint8_t)1<<(indx&0x7)) #define ARRAY_SIZE(x) ((sizeof (x))/(sizeof (x [0]))) /*****************************************************************************/ /* */ /* C O N S T A N T S & V A R I A B L E S */ /* */ /*****************************************************************************/ #if (KEYHDL_SUPPORT_SINGLE_KEY) static const KeyPortMap_t key_single_port_map[]= KEYHDL_SINGLE_KEY_MAP; static const uint8_t key_single_port_map_size = ARRAY_SIZE(key_single_port_map); #endif #if (KEYHDL_SUPPORT_MATRIX_KEY) static const KeyEnumList key_matrix_map[KEYHDL_MATRIX_NO_OF_ROWS][KEYHDL_MATRIX_NO_OF_COLS] = KEYHDL_MATRIX_KEY_MAP; static const KeyGPIO_t key_matrix_port_row[KEYHDL_MATRIX_NO_OF_ROWS]= KEYHDL_MATRIX_ROW_MAP; static const KeyGPIO_t key_matrix_port_col[KEYHDL_MATRIX_NO_OF_COLS]= KEYHDL_MATRIX_COL_MAP; #endif #if (KEYHDL_SUPPORT_MULTI_KEY) static const KeyMultiMap_t key_multi_list_map[]= KEYHDL_MULTI_KEY_MAP; static const uint8_t key_multi_list_map_size = ARRAY_SIZE(key_multi_list_map); #endif static uint8_t key_array[NO_OF_BYTES_FOR_KEY]; static KeyParams_t key_param[MAX_KEYS]; static keyCallBackFnPtr usr_callback_fnc; /*****************************************************************************/ /* */ /* F U N C T I O N P R O T O T Y P E S */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ #if (KEYHDL_SUPPORT_SINGLE_KEY) void KeyHdl_ReadSingleKeyStatus(void); #endif /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ #if (KEYHDL_SUPPORT_MATRIX_KEY) void KeyHdl_ReadMatrixKeyStatus(void); #endif /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ #if (KEYHDL_SUPPORT_MULTI_KEY) void KeyHdl_ReadMultiKeyStatus(void); #endif /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ void KeyHdl_DeboucingCheck(uint16_t call_rate); /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ void KeyHdl_NotifyKeyEvent(void); /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ #if (KEYHDL_USE_OS==1) static void KeyHdl_FreeRtosTask(void *pvParameters); #endif /*****************************************************************************/ /* */ /* F U N C T I O N S */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ int8_t KeyHdl_Init(keyCallBackFnPtr fnptr) { int8_t ret = 0; KEYHDL_HW_INIT(); usr_callback_fnc = fnptr; /* definition and creation of freertos task */ #if (KEYHDL_USE_OS==1) /* Create OS Tasks */ if(xTaskCreate(KeyHdl_FreeRtosTask, (const char *) "KeyHdlTask", 2*configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 1UL), (xTaskHandle *) NULL)!= pdPASS) { ret = -1; } #endif return ret; } /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ void KeyHdl_HWScanISR(uint32_t call_rate) { /* Key Single scan */ #if (KEYHDL_SUPPORT_SINGLE_KEY) KeyHdl_ReadSingleKeyStatus(); #endif /* Key Matrix scan */ #if (KEYHDL_SUPPORT_MATRIX_KEY) KeyHdl_ReadMatrixKeyStatus(); #endif } #if (KEYHDL_USE_OS==1) /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ static void KeyHdl_FreeRtosTask(void *pvParameters) { while (1) { KeyHdl_Task(KEYHDL_TASK_TIME_IN_MS); /* About a delay here */ vTaskDelay(KEYHDL_TASK_TIME_IN_MS); } } #endif /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ void KeyHdl_Task(uint32_t call_rate) { static uint32_t call_rate_cntr=0; call_rate_cntr += call_rate; if(call_rate_cntr >= KEYHDL_TASK_TIME_IN_MS) { call_rate_cntr -= KEYHDL_TASK_TIME_IN_MS; /* This is placed here because it does not have time restriction. */ #if (KEYHDL_SUPPORT_MULTI_KEY) /* Key multi press */ KeyHdl_ReadMultiKeyStatus(); #endif /* check for key bounce */ KeyHdl_DeboucingCheck(KEYHDL_TASK_TIME_IN_MS); } } /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ #if (KEYHDL_SUPPORT_SINGLE_KEY) void KeyHdl_ReadSingleKeyStatus(void) { uint8_t keyCntr=0; for(keyCntr=0;keyCntr= KEYHDL_MATRIX_NO_OF_COLS) { col_indx = 0; } KEYHDL_HW_WRITE_PIN(key_matrix_port_col[col_indx].port,key_matrix_port_col[col_indx].pin,0); } #endif /*****************************************************************************/ /* See header file of description */ /*****************************************************************************/ void KeyHdl_DeboucingCheck(uint16_t call_rate) { uint8_t keyCntr=0; for(;keyCntr= KEYHDL_KEY_DEBOUNCE_TIME) && (key_param[keyCntr].event_type != KEY_EVENT_PRESSED)) { /* key press event */ key_param[keyCntr].event_type = KEY_EVENT_PRESSED; if(usr_callback_fnc) { usr_callback_fnc(keyCntr,KEYHDL_KEY_PRESSED,key_param[keyCntr].bounce_time); } } } else { /* key released */ key_param[keyCntr].event_type = KEY_EVENT_RELEASED; if(key_param[keyCntr].bounce_time >= KEYHDL_KEY_DEBOUNCE_TIME) { if(usr_callback_fnc) { usr_callback_fnc(keyCntr,KEYHDL_KEY_RELEASED,key_param[keyCntr].bounce_time); } } /* clear timers */ key_param[keyCntr].bounce_time = 0; } } } /*****************************************************************************/ /* */ /* E N D O F F I L E */ /* */ /*****************************************************************************/