📄 kpd_scan_functions.c
字号:
/**
* @file kpd_scan_functions.c
*
* Implementation of hardware keypad interface functions.
* These functions implement the keypad interface with the windows.
*
* @author Laurent Sollier (l-sollier@ti.com)
* @version 0.1
*/
/*
* History:
*
* Date Author Modification
* ------------------------------------
* 10/10/2001 L Sollier Create
*
*
* (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved
*/
#include "board.cfg"
#include "nucleus.h" /* used for HISR */
#include "kpd/kpd_scan_functions.h"
#include "kpd/kpd_cfg.h"
#include "kpd/kpd_physical_key_def.h"
#include "kpd/kpd_messages_i.h"
#include "kpd/kpd_env.h"
#include "rvf/rvf_api.h"
#include "rvm/rvm_use_id_list.h"
#include "rvf/rvf_env.h"
#if ((CHIPSET == 12) || (CHIPSET == 15))
#include "inth/sys_inth.h"
#else
#include "armio/armio.h"
#include "inth/iq.h"
#endif
#include "memif/mem.h"
#include "../../../../../g23m/condat/ms/src/mfw/legend_debug.h"
//---------------------------------------------------------------------------------//
#include "sys_inth.h"
#define BIOS_TRACE_DEBUG(string)\
rvf_send_trace (string,(sizeof(string)-1),4294967295,3,0x10001 )
#define BIOS_TRACE_DEBUG_PARAM(string,param)\
rvf_send_trace (string,(sizeof(string)-1),param,3,0x10001 )
//---------------------------------------------------------------------------------//
#if ((CHIPSET == 12) || (CHIPSET == 15))
/**
* Register mapping
*/
#define KBR_CTRL_REG (MEM_KEYBOARD + 0x00) /* KBR control reg */
#define KBR_DEBOUNCING_TIME (MEM_KEYBOARD + 0x02) /* KBR debouncing time reg */
#define KBR_LONG_KEY_TIME (MEM_KEYBOARD + 0x04) /* KBR long key time reg */
#define KBR_TIME_OUT (MEM_KEYBOARD + 0x06) /* KBR Time out reg */
#define KBR_INTERRUPT_STATUS_REG (MEM_KEYBOARD + 0x08) /* KBR interrupt status reg */
#define KBR_CLR_INTERRUPT_STATUS_REG (MEM_KEYBOARD + 0x0A) /* KBR clear interrupt status reg */
#define KBR_INTERRUPT_ENALBE (MEM_KEYBOARD + 0x0C) /* KBR interrupt enalbe reg */
#define KBR_STATE_MACHINE_STATUS (MEM_KEYBOARD + 0x0E) /* KBR state machine status reg */
#define KBR_IN (MEM_KEYBOARD + 0x10) /* KBR inputs (rows) */
#define KBR_OUT (MEM_KEYBOARD + 0x12) /* KBR outputs (columns) */
#define KBR_FULL_CODE_15_0 (MEM_KEYBOARD + 0x14) /* KBR full code 15 - 0 */
#define KBR_FULL_CODE_31_16 (MEM_KEYBOARD + 0x16) /* KBR full code 31 - 16 */
#define KBR_FULL_CODE_47_32 (MEM_KEYBOARD + 0x18) /* KBR full code 47 - 32 */
#define KBR_FULL_CODE_63_48 (MEM_KEYBOARD + 0x1A) /* KBR full code 63 - 48 */
#define KBR_FORCE_KBC (MEM_KEYBOARD + 0x1EA) /* KBR Force KBC to Tristate when IP freeze */
/**
* Register values
*/
#define NORMAL_OPERATION 1
#define MAX_COL 8 /* Used for mapping key value on to layout */
#define NO_KEY 0
#endif
#if ((CHIPSET == 12) || (CHIPSET == 15))
#define KP_ROW_IN KBR_IN
#define KP_COL_OUT KBR_OUT
#else
#define KP_ROW_IN ARMIO_KBR_IN
#define KP_COL_OUT ARMIO_KBR_OUT
#endif
#if (BOARD == 7)
const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
{
/* Layout of B-Sample */
{KPD_PKEY_SOFT_LEFT, KPD_PKEY_UP, KPD_PKEY_DOWN, KPD_PKEY_SOFT_RIGHT},
{KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_GREEN},
{KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_NULL},
{KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_NULL},
{KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE,KPD_PKEY_NULL},
};
#elif ((BOARD == 8) || (BOARD == 9))
const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
{
/* Layout of C-Sample */
{KPD_PKEY_UP, KPD_PKEY_GREEN,KPD_PKEY_SOFT_RIGHT,KPD_PKEY_DOWN},
{KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_SOFT_LEFT},
{KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_NULL},
{KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_NULL},
{KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_NULL},
};
#elif ((BOARD == 40) || (BOARD == 41) || (BOARD == 42) || (BOARD == 43))
const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
{
/* Layout of D-Sample and E-Sample */
{KPD_PKEY_GREEN, KPD_PKEY_VOL_DOWN, KPD_PKEY_VOL_UP,KPD_PKEY_SOFT_LEFT, KPD_PKEY_LEFT},
{KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_REC, KPD_PKEY_RIGHT},
{KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_SOFT_RIGHT, KPD_PKEY_UP},
{KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_NULL, KPD_PKEY_DOWN},
{KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_NULL, KPD_PKEY_NAV_CENTER},
};
#elif ((BOARD==70)||(BOARD==71))
const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
{
/* Layout of I-Sample */
/*
{KPD_PKEY_HOME, KPD_PKEY_BACK, KPD_PKEY_SOFT_LEFT, KPD_PKEY_SOFT_RIGHT, KPD_PKEY_UP},
{KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_GREEN, KPD_PKEY_RIGHT},
{KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_RED, KPD_PKEY_LEFT},
{KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_VOL_DOWN, KPD_PKEY_DOWN},
{KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_VOL_UP, KPD_PKEY_NAV_CENTER},
*/
#if (0)
{KPD_PKEY_GREEN, KPD_PKEY_SOFT_LEFT, KPD_PKEY_SOFT_RIGHT, KPD_PKEY_DOWN, KPD_PKEY_1},
{KPD_PKEY_5, KPD_PKEY_4, KPD_PKEY_3, KPD_PKEY_UP, KPD_PKEY_REC},
{KPD_PKEY_7, KPD_PKEY_NAV_CENTER, KPD_PKEY_6, KPD_PKEY_LEFT, KPD_PKEY_VOL_UP},
{KPD_PKEY_DIESE, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_RIGHT, KPD_PKEY_VOL_DOWN},
{KPD_PKEY_NULL, KPD_PKEY_0, KPD_PKEY_STAR, KPD_PKEY_2, KPD_PKEY_NULL},
#else
{KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_SOFT_LEFT, KPD_PKEY_UP},
{KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_SOFT_RIGHT, KPD_PKEY_RIGHT},
{KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_GREEN, KPD_PKEY_DOWN},
{KPD_PKEY_DIESE, KPD_PKEY_0, KPD_PKEY_STAR, KPD_PKEY_NAV_CENTER, KPD_PKEY_LEFT},
{KPD_PKEY_NULL, KPD_PKEY_NULL, KPD_PKEY_NULL, KPD_PKEY_NULL, KPD_PKEY_NULL}
#endif
};
#endif
#define KP_ACTIVATE(i) (~(1<<i))
#define KP_IS_ACTIVE(rows,i) ((rows & (1<<i)) == 0)
#define KP_ALL_OFF 0x1F
#define KP_ALL_ON 0
extern T_KPD_ENV_CTRL_BLK* kpd_env_ctrl_blk;
typedef struct { NU_HISR hisr;
#ifndef HISR_STACK_SHARING
#if (LOCOSTO_LITE)
//char hisr_stack[288];
char hisr_stack[1024]; //QiangZeng060830
#else
//char hisr_stack[512];
char hisr_stack[1024]; //QiangZeng060830
#endif
#endif
} T_HISR_INFOS;
static T_HISR_INFOS hisr_infos = {0};
/**
* @name Functions implementation
*
*/
/*@{*/
#if ((CHIPSET == 12) || (CHIPSET == 15))
/** kpd_init_ctrl_reg : Initialize the Control register
*/
void kpd_init_ctrl_reg(const UINT8 software_nreset,
const UINT8 nsoftware_mode,
const T_KPD_PTV ptv,
const T_KPD_EnableDetection long_key_process_en,
const T_KPD_EnableDetection time_out_empty_en,
const T_KPD_EnableDetection time_out_long_key_en,
const T_KPD_EnableDetection repeat_mode_en)
{
volatile UINT16 status_reg;
status_reg = *(volatile UINT16*) KBR_STATE_MACHINE_STATUS;
if ( (status_reg != KPD_TEST_TIMER_DEBOUNCING) && (status_reg != KPD_TEST_TIMER_LONG_KEY) &&
(status_reg != KPD_TEST_TIMER_TIME_OUT) && (status_reg != KPD_TEST_TIMER_REPEAT_KEY) )
{
/* The PTV can be programmed since the timer is not running */
*(volatile UINT16*) KBR_CTRL_REG = (software_nreset |
nsoftware_mode << 1 |
ptv << 2 |
long_key_process_en << 5 |
time_out_empty_en << 6 |
time_out_long_key_en << 7 |
repeat_mode_en << 8);
}
else
{
/* The PTV must not be programmed when the timer is running */
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 0, 1, software_nreset);
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 1, 1, nsoftware_mode);
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 5, 1, long_key_process_en);
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 6, 1, time_out_empty_en);
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 7, 1, time_out_long_key_en);
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 8, 1, repeat_mode_en);
}
}
/** kpd_ctrl_repeat_int : set or reset repeat interrupt
*/
void kpd_ctrl_repeat_int(const UINT8 state)
{
if (state == KPD_ENABLE_REPEAT)
{
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 8, 1, KPD_DETECTION_ENABLED);
}
else
{
SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 8, 1, KPD_DETECTION_DISABLED);
}
}
/** kpd_software_reset : reset software
*/
void kpd_software_reset(void)
{
volatile UINT16 mem_reg;
mem_reg = (*(volatile UINT16*) KBR_CTRL_REG) & 0xFFFE;
*(volatile UINT16*) KBR_CTRL_REG = mem_reg;
}
/** kpd_set_debouncing_time : Set the desired value of debouncing time
*/
void kpd_set_debouncing_time(const UINT8 debouncing_time)
{
*(volatile UINT16*) KBR_DEBOUNCING_TIME = debouncing_time;
}
/** kpd_set_timeout_time : Set the desired value of the timeout time
*/
void kpd_set_timeout_time(const UINT16 timeout_time)
{
*(volatile UINT16*) KBR_TIME_OUT = ((timeout_time * KPD_CLOCK_FREQ) / (1<<KPD_CLOCK_DIVIDER+1))-1;
}
#endif /* (CHIPSET == 12) */
#if 1
/**
* function: hisr_entry
*/
static void hisr_entry(void)
{
if(RVF_OK != rvf_send_event(kpd_env_ctrl_blk->addr_id, (UINT16) (EVENT_MASK(RVF_APPL_EVT_7))) )
{
KPD_SEND_TRACE("KPD: can not send event to kpd task!!!!!", RV_TRACE_LEVEL_ERROR);
}
}
#else
/**
* function: hisr_entry
*/
static void hisr_entry(void)
{
T_RVF_MB_STATUS mb_status;
T_KPD_KEY_PRESSED_MSG* msg_key_pressed;
//T_KPD_PHYSICAL_KEY_ID key;
#if ((CHIPSET != 12) && (CHIPSET != 15)) || (((CHIPSET == 12) || (CHIPSET == 15)) && (KPD_DECODING_MODE == SOFTWARE_MODE_ENABLE))
/* Reserve memory for message */
mb_status = rvf_get_buf (kpd_env_ctrl_blk->prim_id, sizeof(T_KPD_KEY_PRESSED_MSG), (void **) &msg_key_pressed);
if (mb_status != RVF_RED) /* Memory allocation success */
{
/* Fill the message */
msg_key_pressed->hdr.msg_id = KPD_KEY_PRESSED_MSG;
/* Virtual key id is not yet known */
msg_key_pressed->value = KPD_PKEY_NULL;
if (mb_status == RVF_GREEN)
msg_key_pressed->key_to_process = TRUE;
else
msg_key_pressed->key_to_process = FALSE;
/* Send message to the keypad task */
rvf_send_msg(kpd_env_ctrl_blk->addr_id, msg_key_pressed);
}
else
{
KPD_SEND_TRACE("KPD: Not enough memory to send new key pressed", RV_TRACE_LEVEL_ERROR);
kpd_acknowledge_key_pressed();
}
#else
UINT8 int_status_reg;
T_KPD_GENERIC_INTERRUPT_MSG* msg_interrupt;
T_KPD_KEY_EVENT_INTERRUPT_MSG* msg_key_interrupt;
static BOOLEAN repeat_active = FALSE;
/* Retrieve interrupt status from register */
int_status_reg = *(volatile UINT16*) KBR_INTERRUPT_STATUS_REG;
if ((int_status_reg & 0x0001) || (int_status_reg & 0x0002)) /* Key changed / Long press */
{
mb_status = rvf_get_buf (kpd_env_ctrl_blk->prim_id, sizeof(T_KPD_KEY_EVENT_INTERRUPT_MSG), (void **) &msg_key_interrupt);
if (mb_status != RVF_RED) /* Memory allocation success */
{
if (int_status_reg & 0x0001)
{
msg_key_interrupt->hdr.msg_id = KPD_KEY_EVENT_INTERRUPT_MSG;
//begin: added by caisheng 200060821 for kpd queue full problem
if (kpd_env_ctrl_blk->long_time == 0)
kpd_env_ctrl_blk->long_time = KPD_DEFAULT_LONG_TIME;
//end by caisheng
/* Key pressed change -> Reset Long timer */
*(volatile UINT16*) KBR_LONG_KEY_TIME = kpd_env_ctrl_blk->long_time;
}
else
{
msg_key_interrupt->hdr.msg_id = KPD_LONG_KEY_INTERRUPT_MSG;
if(repeat_active == FALSE)
{
repeat_active = TRUE;
//begin: added by caisheng 200060821 for kpd queue full problem
if (kpd_env_ctrl_blk->repeat_time == 0)
kpd_env_ctrl_blk->repeat_time = KPD_DEFAULT_REPEAT_TIME;
//end by caisheng
*(volatile UINT16*) KBR_LONG_KEY_TIME = kpd_env_ctrl_blk->repeat_time;
}
}
msg_key_interrupt->full_code_15_0 = *(volatile UINT16*) KBR_FULL_CODE_15_0;
msg_key_interrupt->full_code_31_16 = *(volatile UINT16*) KBR_FULL_CODE_31_16;
msg_key_interrupt->full_code_47_32 = *(volatile UINT16*) KBR_FULL_CODE_47_32;
msg_key_interrupt->full_code_63_48 = *(volatile UINT16*) KBR_FULL_CODE_63_48;
/* Set long timer register to Long time */
if ((msg_key_interrupt->full_code_15_0 == NO_KEY) &&
(msg_key_interrupt->full_code_31_16 == NO_KEY) &&
(msg_key_interrupt->full_code_47_32 == NO_KEY) &&
(msg_key_interrupt->full_code_63_48 == NO_KEY))
{
repeat_active = FALSE;
*(volatile UINT16*) KBR_LONG_KEY_TIME = kpd_env_ctrl_blk->long_time;
}
/* Send message to the keypad task */
rvf_send_msg(kpd_env_ctrl_blk->addr_id, msg_key_interrupt);
}
else
{
KPD_SEND_TRACE("KPD: Not enough memory to send interrupt message", RV_TRACE_LEVEL_ERROR);
}
}
else /* interrupt e.g. miss event, time out */
{
mb_status = rvf_get_buf (kpd_env_ctrl_blk->prim_id, sizeof(T_KPD_GENERIC_INTERRUPT_MSG), (void **) &msg_interrupt);
if (mb_status != RVF_RED) /* Memory allocation success */
{
if (int_status_reg & 0x0008) /* Miss event */
{
msg_interrupt->hdr.msg_id = KPD_MISS_EVENT_INTERRUPT_MSG;
}
else if(int_status_reg & 0x0004) /* Time out */
{
msg_interrupt->hdr.msg_id = KPD_TIMEOUT_INTERRUPT_MSG;
}
/* Send message to the keypad task */
rvf_send_msg(kpd_env_ctrl_blk->addr_id, msg_interrupt);
}
else
{
KPD_SEND_TRACE("KPD: Not enough memory to send interrupt message", RV_TRACE_LEVEL_ERROR);
}
}
/* Clear interrupt */
*(volatile UINT16*) KBR_CLR_INTERRUPT_STATUS_REG |= int_status_reg;
kpd_acknowledge_key_pressed();
#endif /* ((CHIPSET != 12) && (CHIPSET != 15)) || (((CHIPSET == 12) || (CHIPSET == 15)) && (KPD_DECODING_MODE == SOFTWARE_MODE_ENABLE)) */
}
#endif
/**
* function: kpd_initialize_keypad_hardware
*/
void kpd_initialize_keypad_hardware(void)
{
/**
* Common initialisation
*/
/* HISR creation */
NU_Create_HISR(&hisr_infos.hisr,
"KPD_HISR",
hisr_entry,
2,
#ifndef HISR_STACK_SHARING
hisr_infos.hisr_stack,
sizeof(hisr_infos.hisr_stack));
#else
HISR_STACK_PRIO2,
HISR_STACK_PRIO2_SIZE);
#endif
/**
* Chip / Board specific initialisation
*/
#if ((CHIPSET == 12) || (CHIPSET == 15))
/** Hardware decoding
*/
#if (KPD_DECODING_MODE == HARDWARE_DECODING)
/* Init control register ; hardware decoding */
kpd_init_ctrl_reg(NORMAL_OPERATION, /* Reset / Normal op */
HARDWARE_DECODING, /* Hardware / Software decoding */
KPD_CLOCK_DIVIDER, /* Clk divisor */
KPD_DETECTION_ENABLED, /* Long key enable */
KPD_DETECTION_ENABLED, /* timeout no key */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -