📄 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_scan_functions.h"
#include "kpd_cfg.h"
#include "kpd_physical_key_def.h"
#include "kpd_messages_i.h"
#include "kpd_env.h"
#include "rvf_api.h"
#include "rvm_use_id_list.h"
#include "rvf_env.h"
#include "mem.h"
#include "armio.h"
#include "iq.h"
//glowing,2004-06-16,import from M188
INT8 g_norejectkeyflag = 0;
#if (CHIPSET == 12)
#define KBR_CTRL_REG (MEM_KEYBOARD + 0x00) /* KBR control reg */
#define KBR_DEBOUNCING_TIME (MEM_KEYBOARD + 0x02) /* KBR debouncing time 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) */
#endif
#if (CHIPSET == 12)
#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)
#define KP_ROWS 5
#define KP_COLS 4
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))
#define KP_ROWS 5
#define KP_COLS 4
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))
#define KP_ROWS 5
#define KP_COLS 5
const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
{
/* Layout of D-Sample; KPD_PKEY_RED is power key ,specially deal with */
//{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_NAV_CENTER, KPD_PKEY_NULL},
// {KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_DOWN, KPD_PKEY_NULL },
//this handset keypad define
//glowing,2004-06-28, modify the keypad layout
#if 0 //the following is the keypad layout for M188
{KPD_PKEY_GREEN, KPD_PKEY_SOFT_LEFT,KPD_PKEY_SOFT_RIGHT, KPD_PKEY_DOWN, KPD_PKEY_REC },
{KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_UP , KPD_PKEY_VOL_UP },
{KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6,KPD_PKEY_LEFT , KPD_PKEY_VOL_DOWN},
{KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_RIGHT, KPD_PKEY_NULL},
{KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_NAV_CENTER, KPD_PKEY_NULL },
#else //the following is the keypad layout for M288
{KPD_PKEY_GREEN, KPD_PKEY_SOFT_LEFT,KPD_PKEY_SOFT_RIGHT, KPD_PKEY_DOWN, KPD_PKEY_VOL_UP },
{KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_UP , KPD_PKEY_VOL_DOWN },
{KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6,KPD_PKEY_LEFT , KPD_PKEY_NULL},
{KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_RIGHT, KPD_PKEY_REC},
{KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_NAV_CENTER, KPD_PKEY_NULL },
#endif
//glowing,2004-06-28, end of modify
};
#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;
char hisr_stack[512];
} T_HISR_INFOS;
static T_HISR_INFOS hisr_infos = {0};
/**
* @name Functions implementation
*
*/
/*@{*/
#if (CHIPSET == 12)
/** kpd_init_ctrl_reg : Initialize the Control register
*/
void kpd_init_ctrl_reg(const UINT8 software_nreset,
const T_KPD_Nsoftware_mode 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_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;
}
#endif /* #if (CHIPSET == 12) */
/**
* 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;
/* 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();
}
}
/**
* function: kpd_initialize_keypad_hardware
*/
void kpd_initialize_keypad_hardware(void)
{
/* HISR creation */
NU_Create_HISR(&hisr_infos.hisr,
"KPD_HISR",
hisr_entry,
2,
hisr_infos.hisr_stack,
sizeof(hisr_infos.hisr_stack));
#if (CHIPSET == 12)
/* Init control register ; hardware decoding */
kpd_init_ctrl_reg(1, HARDWARE_DECODING, KPD_CLK_DIV32,
KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED,
KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED);
/* Debouncing time = 64ms */
kpd_set_debouncing_time(0x3F);
#endif
/* Activate all outputs */
*(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;
/* Unmask keypad interrupt */
#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
AI_UnmaskIT (ARMIO_MASKIT_KBD);
#elif (CHIPSET == 12)
IQ_Unmask (IQ_KEYBOARD);
#else
IQ_Unmask (IQ_ARMIO);
#endif
}
/**
* function: kpd_key_handler
*/
void kpd_key_handler(void)
{
/* If keypad is not started, return immediately */
if ( (kpd_env_ctrl_blk == 0) || (kpd_env_ctrl_blk->swe_is_initialized == FALSE) )
{
kpd_acknowledge_key_pressed();
}
else
{
/* Mask keypad interrupt until key is released */
#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
AI_MaskIT (ARMIO_MASKIT_KBD);
#elif (CHIPSET == 12)
IQ_Mask(IQ_KEYBOARD);
#else
IQ_Mask(IQ_ARMIO);
#endif
/* Activate HISR to process the key event */
NU_Activate_HISR(&hisr_infos.hisr);
}
}
/**
* function: kpd_acknowledge_key_pressed
*/
void kpd_acknowledge_key_pressed(void)
{
/* Unmask keypad interrupt */
#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
AI_UnmaskIT (ARMIO_MASKIT_KBD);
#elif (CHIPSET == 12)
IQ_Unmask (IQ_KEYBOARD);
#else
IQ_Unmask (IQ_ARMIO);
#endif
}
/*
* delay
*
* Wait a while to let bus settle
* Magic value found by trial and error
*
*/
static void delay(void)
{
volatile int i;
for (i=0;i<10;i++) ;
}
/**
* function: kpd_scan_keypad
*/
T_KPD_PHYSICAL_KEY_ID kpd_scan_keypad(void)
{
int row, col;
volatile UINT16 rows;
/* Activate all columns to find if any row is active */
*(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;
delay();
rows = (*(volatile UINT16*) KP_ROW_IN) & 0x1F;
if (rows == KP_ALL_OFF)
return KPD_PKEY_NULL;
/* Deactivate all columns */
*(volatile UINT16*) KP_COL_OUT = KP_ALL_OFF;
/* Activate 1 column at a time */
for (col = 0; col < KP_COLS; col++)
{
*(volatile UINT16*) KP_COL_OUT = (KP_ACTIVATE(col));
delay();
/* Find which row is active */
rows = (*(volatile UINT16*) KP_ROW_IN) & 0x1F;
if (rows != KP_ALL_OFF)
{
for (row = 0; row < KP_ROWS; row++)
{
/* first active row */
if ( KP_IS_ACTIVE(rows,row))
{
/* Reactivate all columns */
*(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;
/* DO NOT remove this comment. It allows to simply define the link physical layout
and physical key Id (for a new keypad) */
//KPD_SEND_TRACE_PARAM("KPD: Keypad layout check ", keypad_layout[row][col], RV_TRACE_LEVEL_DEBUG_HIGH);
return keypad_layout[row][col];
}
}
}
}
/* No row was active - Reactivate all columns and return */
*(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;
return KPD_PKEY_NULL;
}
//glowing,2004-06-12,
MmiTraceInt(int i){
//#ifdef _DEBUG_HARDWARE_
/*ljq modified it to control trace command 2003/1/9*/
// if (RivieraTraceFlag)
// KPD_SEND_TRACE_PARAM("zym:MmiTraceInt", i, RV_TRACE_LEVEL_DEBUG_HIGH);
//#endif
}
//glowing,2004-06-17,import from M188
void GetTaskInfo(void){
/* Define an array capable of holding 20 task pointers. */
NU_TASK Task,*Pointer_Array[40];
CHAR task_name[8];
DATA_ELEMENT task_status;
UNSIGNED scheduled_count;
OPTION priority;
OPTION preempt;
UNSIGNED time_slice;
VOID *stack_base;
UNSIGNED stack_size,number,i;
UNSIGNED minimum_stack;
STATUS status;
/* Obtain a list of currently active task pointers (Max of 20). */
number = NU_Task_Pointers(&Pointer_Array[0],40);
/* At this point, number contains the actual number of
pointers in the list. */
/* Obtain information about the task control block "Task".
Assume "Task" has previously been created with the Nucleus
PLUS NU_Create_Task service call. */
for(i = 0; i < number ; i++){
status = NU_Task_Information(Pointer_Array[i], task_name, &task_status,
&scheduled_count, &priority, &preempt,
&time_slice, &stack_base,
&stack_size, &minimum_stack);
/* If status is NU_SUCCESS, the other information is accurate. */
if(status == NU_SUCCESS){
if(task_status == 0){
MmiTrace("Runing Task");
MmiTrace(task_name);
}
if(task_status == 2){
MmiTrace("Ready Task");
MmiTrace(task_name);
}
//MmiTrace(task_name);
//MmiTraceInt(task_status);
//MmiTraceInt(priority);
}
else{
MmiTrace("Failed");
}
}
}
void GetTimerInfo(void){
/* Define an array capable of holding 20 timer pointers. */
NU_TIMER *Pointer_Array[20];
UNSIGNED number;
NU_TIMER Timer;
CHAR timer_name[8];
OPTION enable;
UNSIGNED expirations;
UNSIGNED id,i;
UNSIGNED initial_time;
UNSIGNED reschedule_time;
STATUS status;
/* Obtain a list of currently active timer pointers
(Maximum of 20). */
number = NU_Timer_Pointers(&Pointer_Array[0], 20);
/* At this point, number contains the actual number
of pointers in the list. */
for(i = 0; i < 20 ; i++){
/* Obtain information about the timer control block "Timer".
Assume "Timer" has previously been created with the
Nucleus PLUS NU_Create_Timer service call. */
status = NU_Timer_Information(Pointer_Array[i], timer_name, &enable, &expirations, &id, &initial_time,&reschedule_time);
/* If status is NU_SUCCESS, the other information is accurate. */
if(status == NU_SUCCESS){
MmiTrace("Success");
MmiTrace(timer_name);
}
else{
MmiTrace("Failed");
}
}
}
//glowing,2004-06-17,end of import
/*@}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -