📄 lh7a400_evb_keyboard_driver.c
字号:
/**********************************************************************
* $Workfile: LH7A400_evb_keyboard_driver.c $
* $Revision: 1.2 $
* $Author: SuryanG $
* $Date: Jan 17 2002 18:30:42 $
*
* Project: LH7A400 EVB
*
* Description:
* This is a driver for the Fujitsu N860-1406-0001 keyboard and the
* LH7A400 EVB CPU board. Keys must be pressed and released; auto-
* repeat is not supported.
*
* The following public functions are provided
* LH7A400_evb_kb_init()--initialize the driver
* LH7A400_evb_kb_hit()--return true if there is a key in the buffer
* LH7A400_evb_kb_get_char()--returns the key in the buffer
* LH7A400_evb_kb_set_caps_lock()--turn caps lock on or off
* LH7A400_evb_kb_caps_lock_is_on()--return true if caps lock is on
* LH7A400_evb_kb_set_num_lock()--turn num lock on or off
* LH7A400_evb_kb_num_lock_is_on()--return true if num lock is on.
*
* State Machine:
* The static functions below make up the following state machine
*
* Initial State:
* Caps lock off
* Num Lock off
* clear previous key state
* Set all column drivers high.
* Go to Polling state.
*
* Polling state:
* Wait 10 ms.
* If any row reads back high
* Go to Debounce state
* Else stay in Polling state:
*
* Debounce state:
* Wait 10 ms
* if any row reads back high
* Set column driver 0 high; all others Hi-Z
* clear current key state
* Go to Control Button Scan state
* else
* Go to Polling state
*
* Control Button Scan state
* Wait 10 us
* read current column from column scan register
* read back row
* if in column 0
* Record state of Alt, Ctrl, and/or Fn keys
* Set column driver 1 high, all others Hi-Z
* Go to Control Button Scan State
* else if in column 1
* Record state of left shift and/or right shift keys
* Set column driver 0 high, all others Hi-Z
* Go to Scan state
*
* Scan state:
* Wait 10 us
* read current column from column scan register
* read back row
* based on current column, mask off any control keys from row
* if no keys are pressed in the row
* increment column number
* if column number is 7 (1 greater than maximum column)
* if any control keys were recorded as pressed
* if key state is different from previous state
* post recorded control key states in queue
* Set all column drivers high
* previous key state = current key state
* Go to Polling State
* else
* Go to Scan state
* else
* record one key as pressed
* modify key value by control keys (including caps
* lock and num lock)
* if current key state does not equal previous key state
* post recorded key state with control state to queue
* previous key state
* Set all column drivers high
* Go to Polling state
*
*
* References:
* Fujitsu Limited N860-1406-0001 CIRCUIT SPECIFICATION
*
* Notes:
* This driver consumes a timer and an interrupt priority for the
* timer.
* You can override the timer number and its priority by defining
* KEYBOARD_TIMER and KEYBOARD_PRIOIRTY at compile time.
* See LH7A400_evb_keyboard_driver.h for the default values.
*
* If you wish to use an OS queue instead of the queue provided here,
* #define LH7A400_EVB_KB_USE_OS_Q and re-implement
* LH7A400_evb_kb_reset_queue(), LH7A400_evb_kb_hit() and
* KEYVAL LH7A400_evb_kb_get_char()
*
* $Log: P:/PVCS6_6/archives/LH7A400 (Aruba)/keyboard/LH7A400_evb_keyboard_driver.c-arc $
*
* Rev 1.2 Jan 17 2002 18:30:42 SuryanG
* Corrected some typos in file header.
* Removed #include "priority_driver.h".
*
* Rev 1.1 Jan 11 2002 09:46:42 KovitzP
* Added KB_ prefix to #defined constants
*
* Rev 1.0 Jan 10 2002 16:29:40 KovitzP
* Initial revision.
*
*
* COPYRIGHT (C) 2002 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
**********************************************************************/
#include "LH7A400_evb_keyboard_driver.h"
#include "LH7A400_EVB_CPLD_driver.h"
#include "LH7A400_gpio_driver.h"
#include "LH7A400_timer_driver.h"
#include "LH7A400_int_driver.h"
#define KEY_BUFFER_SIZE 128
#if !defined LH7A400_EVB_KB_USE_OS_Q
static KEYVAL key_queue[KEY_BUFFER_SIZE];
static INT_32 front = 0, back = 0;
#endif
static KEYVAL scanned_key, previous_key;
static INT_32 caps_lock = 0;
static INT_32 num_lock = 0;
static void poll_state_handler(void);
static void control_button_scan_state_handler(void);
static void scan_state_handler(void);
static void debounce_state_handler(void);
static void goto_control_button_scan_state(void);
static void goto_debounce_state(void);
static void goto_poll_state(void);
#if !defined LH7A400_EVB_KB_USE_OS_Q
void LH7A400_evb_kb_reset_queue(void)
{
front = back;
}
INT_32 LH7A400_evb_kb_hit(void)
{
return front != back;
}
KEYVAL LH7A400_evb_kb_get_char(void)
{
KEYVAL key;
key = key_queue[back++];
if (back >= KEY_BUFFER_SIZE)
back = 0;
return key;
}
static void LH7A400_enqueue_key(KEYVAL key)
{
key_queue[front++] = key;
if (front >= KEY_BUFFER_SIZE)
front = 0;
}
#endif
/**********************************************************************
*
* Function: poll_state_handler
*
* Purpose:
* Implement Polling state after wait interval
*
* Processing:
* See Polling State description.
*
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
static void poll_state_handler(void)
{
timer_int_clear(KB_KEYBOARD_TIMER);
if (pld_read_row_sense() )
{
/* then a key has been pressed; debounce */
timer_irq_setup(KB_KEYBOARD_TIMER,
KB_KEYBOARD_PRIORITY,
debounce_state_handler);
}
}
/**********************************************************************
*
* Function: debounce_state_handler
*
* Purpose:
* Implement Polling state after wait interval
*
* Processing:
* See Polling State description.
*
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
static void debounce_state_handler(void)
{
if (pld_read_row_sense() )
{
timer_stop(KB_KEYBOARD_TIMER);
goto_control_button_scan_state();
}
else
goto_poll_state();
timer_int_clear(KB_KEYBOARD_TIMER);
}
/**********************************************************************
*
* Function: goto_control_button_scan_state
*
* Purpose:
* Set up keyboard driver for Control Button Scan state
*
* Processing:
* Clear current scanned key
* start scan at column 0
* setup the polling interval; setup timer interrupt to be
* handled by control button scan handler, and start the timer.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
* Enter this state with timer stopped and set for periodic mode
*
**********************************************************************/
static void goto_control_button_scan_state(void)
{
/* start scanning with the column 0 */
gpio_keyscan_set(GPIO_KSCAN_COL_ENABLE);
scanned_key.raw = 0;
/* reset timer to force Control button scan state */
timer_irq_setup(KB_KEYBOARD_TIMER,
KB_KEYBOARD_PRIORITY,
control_button_scan_state_handler);
timer_set_delay(KB_KEYBOARD_TIMER, KB_SCAN_INTERVAL);
timer_start(KB_KEYBOARD_TIMER);
}
/**********************************************************************
*
* Function: control_button_scan_state_handler
*
* Purpose:
* Implement Control Button Scan state after wait interval
*
* Processing:
* See Polling State description.
*
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
static void control_button_scan_state_handler(void)
{
UNS_8 current_column;
UNS_16 row;
timer_stop(KB_KEYBOARD_TIMER);
timer_int_clear(KB_KEYBOARD_TIMER);
current_column = gpio_keyscan_get() - GPIO_KSCAN_COL_ENABLE;
row = pld_read_row_sense();
switch(current_column)
{
case 0:
if (row & KB_CTRL_KEY)
scanned_key.decoded.ctrl = 1;
if (row & KB_FN_KEY)
scanned_key.decoded.fn = 1;
if (row & KB_ALT_KEY)
scanned_key.decoded.alt = 1;
gpio_keyscan_set(GPIO_KSCAN_COL_ENABLE + current_column + 1);
break;
case 1:
if (row & KB_LEFT_SHIFT_KEY)
scanned_key.decoded.left_shift = 1;
if (row & KB_RIGHT_SHIFT_KEY)
scanned_key.decoded.right_shift = 1;
/* all control keys read. restart scan */
gpio_keyscan_set(GPIO_KSCAN_COL_ENABLE);
timer_irq_setup(KB_KEYBOARD_TIMER,
KB_KEYBOARD_PRIORITY,
scan_state_handler);
break;
default:
/* should never get here */
for (;;)
;
break;
}
timer_start(KB_KEYBOARD_TIMER);
}
/**********************************************************************
*
* Function: scan_state_handler
*
* Purpose:
* Implement Control Button Scan state after wait interval
*
* Processing:
* See Polling State description.
*
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
static void scan_state_handler(void)
{
UNS_8 current_column;
UNS_16 row;
timer_stop(KB_KEYBOARD_TIMER);
timer_int_clear(KB_KEYBOARD_TIMER);
current_column = gpio_keyscan_get() - GPIO_KSCAN_COL_ENABLE;
row = pld_read_row_sense();
/* mask off any control keys */
if (current_column <= KB_MAX_CONTROL_COL)
{
switch (current_column)
{
case 0:
row &= ~(KB_ALT_KEY | KB_CTRL_KEY | KB_FN_KEY);
break;
case 1:
row &= ~(KB_LEFT_SHIFT_KEY | KB_RIGHT_SHIFT_KEY);
break;
}
}
if (row == 0)
{
/* no key detected in this column */
if (current_column == KB_MAX_COL)
{
/*
scan complete; no characters detected;
see if any shift, control, alt or fn keys pressed
*/
if (scanned_key.raw != previous_key.raw)
{
previous_key.raw = scanned_key.raw;
if (scanned_key.decoded.fn || scanned_key.decoded.ctrl ||
scanned_key.decoded.alt ||
scanned_key.decoded.left_shift ||
scanned_key.decoded.right_shift)
{
LH7A400_enqueue_key(previous_key);
/* start scanning again */
goto_control_button_scan_state();
}
else
{
/* no key is pressed; restart polling */
goto_poll_state();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -