📄 kbdif.c
字号:
/*
* Start of Zoran Standard Header
* Copyright (c) 2005 Zoran Corporation
*
*
* All rights reserved. Proprietary and confidential.
*
* DESCRIPTION for kbdif.c
* low level keyboard handler for the Combo user interface board.
*
* NEW HISTORY COMMENT (description must be followed by a blank line)
* <Enter change description here>
* ===== HISTORY of changes in //depot/imgeng/sw/se_gw/ui/fs/comboui/kbdif.c
*
* 19/Aug/05 #2 dstrauss Use hwAccess routines to protect hardware accesses.
* 16/Aug/05 #1 dstrauss Created.
*
*
* End of Zoran Standard Header
*/
#include "sys.h"
#include "ts.h"
#include "kbdif.h"
#include "hwaccess.h"
/************************************************************
* DEFINTIONS
************************************************************/
/* keyboard default task stack size (can be overridden in sys.h) */
#ifndef KBDIF_STACK_SIZE
#define KBDIF_STACK_SIZE 1024
#endif
/* kybd default task priority (can be overridden in sys.h) */
#ifndef KBDIF_TASK_PRIORITY
#define KBDIF_TASK_PRIORITY FP_PRIORITY
#endif
/* default kybd update period, in milliseconds (can be overridden in sys.h) */
#ifndef KBDIF_UPDATE_PERIOD
#define KBDIF_UPDATE_PERIOD 50
#endif
/* default kybd # debounce samples (can be overridden in sys.h) */
#ifndef KBDIF_DEBOUNCE_SAMPLES
#define KBDIF_DEBOUNCE_SAMPLES 3
#endif
/* default number of key handlers (can be overridden in sys.h */
#ifndef KBDIF_NUM_HANDLERS
#define KBDIF_NUM_HANDLERS 32
#endif
/************************************************************
* MACROS
************************************************************/
/* compare the oldstate array with the newstate array */
#define KEYS_UNCHANGED(oldstate, newstate) \
( \
(oldstate[0] == newstate[0]) \
&& (oldstate[1] == newstate[1]) \
&& (oldstate[2] == newstate[2]) \
&& (oldstate[3] == newstate[3]) \
&& (oldstate[4] == newstate[4]) \
&& (oldstate[5] == newstate[5]) \
&& (oldstate[6] == newstate[6]) \
&& (oldstate[7] == newstate[7]) \
)
/* update the oldstate array with the contents of the newstate array */
#define COPY_KEYS(oldstate, newstate) \
do { \
oldstate[0] = newstate[0]; \
oldstate[1] = newstate[1]; \
oldstate[2] = newstate[2]; \
oldstate[3] = newstate[3]; \
oldstate[4] = newstate[4]; \
oldstate[5] = newstate[5]; \
oldstate[6] = newstate[6]; \
oldstate[7] = newstate[7]; \
} while (0)
/************************************************************
* Statics
************************************************************/
/* allocate space for the necessary OS objects */
static tsTaskID kbdtaskid = INVALIDTASK;
static Uint32 kbdifStack[KBDIF_STACK_SIZE/sizeof(Uint32)];
static tsSemaphore kbdSem; /* keyboard semaphore */
static Uint8 keys[8]; /* last stable state of the keys */
static Uint8 current_keys[8]; /* current key state (unstable) */
static Uint8 key_changes[8]; /* which keys changed */
static Uint8 debounce_count;
static KBDIFKeyHandler key_handlers[KBDIF_NUM_HANDLERS];
static int num_handlers;
/************************************************************
* Code
************************************************************/
static void scanKeys(Uint8 states[8])
{
int rowcount;
Uint8 mask;
for (rowcount = 0, mask = 1; rowcount < 8; rowcount++, mask <<= 1) {
hwAccessLock(FALSE); /* lock out other accesses */
*(volatile unsigned char *)0xec000080 = ~(mask);
hwAccessUnlock(FALSE); /* allow other accesses */
hwAccessLock(FALSE); /* lock out other accesses */
states[rowcount] = ~(*(volatile unsigned char *)0xec000080);
hwAccessUnlock(FALSE); /* allow other accesses */
}
}
static void kbdifReportKeyChange(Uint32 code)
{
int count;
int maxcount;
TASKSEMWAIT(kbdSem);
maxcount = num_handlers; /* grab the current number of handlers */
TASKSEMSIGNAL(kbdSem);
for (count = 0; count < maxcount; count++) {
ASSERT(key_handlers[count] != NULL);
key_handlers[count](code);
}
}
static void kbdifTaskLoop()
{
Uint8 keys_now[8];
while (1) {
scanKeys(keys_now);
if (KEYS_UNCHANGED(keys_now, current_keys)) {
if (debounce_count < KBDIF_DEBOUNCE_SAMPLES) {
debounce_count++;
if (debounce_count == KBDIF_DEBOUNCE_SAMPLES) {
int rowcount;
int colcount;
Uint8 mask;
/* new key state */
/* remember which keys changed */
for (rowcount = 0; rowcount < 8; rowcount++) {
key_changes[rowcount] = keys[rowcount] ^ current_keys[rowcount];
}
COPY_KEYS(keys, current_keys);
/* report key changes */
for (rowcount = 0; rowcount < 8; rowcount++) {
for (colcount = 0, mask = 1; colcount < 8;
colcount++, mask <<= 1) {
if (key_changes[rowcount] & mask) {
Uint32 code = (rowcount * 8) + colcount;
if (keys[rowcount] & mask) {
code |= KEY_IS_DOWN;
}
kbdifReportKeyChange(code);
}
}
}
}
}
} else {
COPY_KEYS(current_keys, keys_now);
debounce_count = 0;
}
TASKSLEEP_MILLISECONDS(KBDIF_UPDATE_PERIOD);
}
}
static Sint32 kbdifTask(void *argv)
{
kbdifTaskLoop(); /* never returns */
return (0);
}
/************************************************************
* KBDIFRegisterKeyHandler(KBDIFKeyHandler handler)
* Register a key handler routine with the keyboard interface.
* The key handler routine gets called with a keycode whenever
* a key changes state. The keycode consists of one of the
* KEY_* values defined in kbdif.h or'ed with KEY_IS_DOWN
* if appropriate. Note that the key handler routine gets
* called in the context of the keyboard i/f task.
*
* Returns: API_OK if the handler is registered successfully
* API_FAIL otherwise.
************************************************************/
API_RET KBDIFRegisterKeyHandler(KBDIFKeyHandler handler)
{
ASSERT(handler);
TASKSEMWAIT(kbdSem);
if (num_handlers >= KBDIF_NUM_HANDLERS) {
TASKSEMSIGNAL(kbdSem);
return (API_FAIL);
}
key_handlers[num_handlers] = handler;
num_handlers++;
TASKSEMSIGNAL(kbdSem);
return (API_OK);
}
void KBDIFinit(void)
{
debounce_count = 0;
num_handlers = 0;
kbdSem = TASKSEMCREATE(1);
kbdtaskid = TASKCREATE(kbdifTask,
KBDIF_STACK_SIZE,
kbdifStack,
NULLDATA,
KBDIF_TASK_PRIORITY,
NULLARG,
"kbdifTask");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -