⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lh7a400_evb_keyboard_driver.c

📁 sharp的arm920t 7A400的评估板附带光盘Sharp KEVLH7A400 v0.3b Welcome to the SHARP KEV7A400 Evaluation board
💻 C
📖 第 1 页 / 共 3 页
字号:
/**********************************************************************
 *	$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 + -