Goyoyo_v2/01_Code/FES_Common_Library/KeyHdl/keyhdl.c
2025-04-15 14:38:00 +05:30

356 lines
14 KiB
C

/*****************************************************************************/
/* 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 <stdint.h>
#include <stdio.h>
#include <string.h>
#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<key_single_port_map_size;keyCntr++)
{
if(KEYHDL_HW_READ_PIN(key_single_port_map[keyCntr].port,key_single_port_map[keyCntr].pin)==0)
{
KEY_SET_BIT_IN_ARRAY(key_array,key_single_port_map[keyCntr].key_name);
}
else
{
KEY_CLEAR_BIT_IN_ARRAY(key_array,key_single_port_map[keyCntr].key_name);
}
}
}
#endif
/*****************************************************************************/
/* See header file of description */
/*****************************************************************************/
#if (KEYHDL_SUPPORT_MULTI_KEY)
void KeyHdl_ReadMultiKeyStatus(void)
{
uint8_t multiKeyCntr=0;
uint8_t keyCntr=0;
uint8_t keymulti_pressed=0;
uint8_t keyIdx=0;
for(multiKeyCntr=0;multiKeyCntr<key_multi_list_map_size;multiKeyCntr++)
{
keymulti_pressed=0;
for(keyCntr=0;keyCntr<key_multi_list_map[multiKeyCntr].no_of_keys;keyCntr++)
{
keyIdx=key_multi_list_map[multiKeyCntr].multi_key_list[keyCntr];
/* read from global key array */
if(KEY_READ_BIT_IN_ARRAY(key_array,keyIdx))
{
keymulti_pressed++;
}
}
/* set the bit in global key array */
if(keymulti_pressed == key_multi_list_map[multiKeyCntr].no_of_keys)
{
KEY_SET_BIT_IN_ARRAY(key_array,key_multi_list_map[multiKeyCntr].key_name);
/* clear the single key array when there is multikey event */
for(keyCntr=0;keyCntr<key_multi_list_map[multiKeyCntr].no_of_keys;keyCntr++)
{
keyIdx=key_multi_list_map[multiKeyCntr].multi_key_list[keyCntr];
/* clear from global key array */
KEY_CLEAR_BIT_IN_ARRAY(key_array,keyIdx);
}
}
else
{
KEY_CLEAR_BIT_IN_ARRAY(key_array,key_multi_list_map[multiKeyCntr].key_name);
}
}
}
#endif
/*****************************************************************************/
/* See header file of description */
/*****************************************************************************/
#if (KEYHDL_SUPPORT_MATRIX_KEY)
void KeyHdl_ReadMatrixKeyStatus(void)
{
static uint8_t col_indx = 0;
uint8_t row_cntr=0;
uint8_t key_name=0;
/* Key Matrix Scan */
for(; row_cntr <KEYHDL_MATRIX_NO_OF_ROWS;row_cntr++)
{
key_name= key_matrix_map[row_cntr][col_indx];
if(KEYHDL_HW_READ_PIN(key_matrix_port_row[row_cntr].port,key_matrix_port_row[row_cntr].pin) == 0 )
{
KEY_SET_BIT_IN_ARRAY(key_array,key_name);
}
else
{
KEY_CLEAR_BIT_IN_ARRAY(key_array,key_name);
}
}
KEYHDL_HW_WRITE_PIN(key_matrix_port_col[col_indx].port,key_matrix_port_col[col_indx].pin,1);
col_indx++;
if(col_indx >= 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<MAX_KEYS;keyCntr++)
{
if(KEY_READ_BIT_IN_ARRAY(key_array,keyCntr))
{
key_param[keyCntr].bounce_time += call_rate;
if((key_param[keyCntr].bounce_time >= 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 */
/* */
/*****************************************************************************/