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

📄 dc550_keypad.c

📁 一款经典的数字电话设计资料
💻 C
字号:
/*****************************************************************************/
/*  CONFIDENTIAL                                                             */
/*  Sigpro Copyright 2003, All rights reserved                               */
/*****************************************************************************/
/*  CLIENT:  Telematrix                                                      */
/*  PROJECT: DC550 Digital Centrex Phone                                     */
/*  FILE:    dc550_keypad.c                                                  */
/*****************************************************************************/
/*  The keypad scanner will scan all fourty buttons, debounce them and send  */
/*  a message to the Software Controller whenever a key up or key down event */
/*  is detected.                                                             */
/*****************************************************************************/

#include "dc550_controller.h"
#include "dc550_keypad.h"

/******************************************************************************
 *  LOCAL CONSTANTS AND DATA TYPES
 *****************************************************************************/
typedef enum enum_KP_STATE {
    KP_IDLE=0, KP_DEBOUNCING_DOWN, KP_DOWN, KP_DEBOUNCING_UP, KP_BLOCKED
} KP_STATE;

struct str_kpBtnData {
  KP_STATE    state;
  signed char ctr;
};

struct str_kpTaskData {
  int                  row;
  int                  rowMask;
  struct str_kpBtnData *btnData;
  BOOL                 firsttime;
};

/******************************************************************************
 *  GLOBAL VARIABLES
 *****************************************************************************/

/******************************************************************************
 *  STATIC VARIABLES
 *****************************************************************************/
static struct str_kpTaskData kpTaskData;
static struct str_kpBtnData kpBtnData[KP_NUMBTNS];

/******************************************************************************
 *  STATIC FUNCTION: static void keypad_init(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is a helper function which is used to set
 *  each of the button data items to specified values.
 *****************************************************************************/
static void kp_initBtnData(KP_STATE state, BOOL clrCtr)
{
  int i;
  struct str_kpBtnData *ptr = &kpBtnData[0];

  for (i=0; i<KP_NUMBTNS; i++, ptr++) {
    ptr->state = state;
    if (clrCtr)
        ptr->ctr = 0;
  }
}

/******************************************************************************
 *  FUNCTION: void keypad_init(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called to initialize the keypad scanner task.
 *****************************************************************************/
void keypad_init(void)
{
  /* Initialize global/static variables */
  kpTaskData.row = 0;
  kpTaskData.rowMask = KP_FIRSTROW_MSK;
  kpTaskData.btnData = &kpBtnData[0];
  kpTaskData.firsttime = TRUE;

  /* Clear all button data to KP_IDLE and zero the debounce counter */
  kp_initBtnData(KP_IDLE, TRUE);
}


/******************************************************************************
 *  FUNCTION: void keypad_exec(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called to execute the keypad scanner task.
 *****************************************************************************/
void keypad_exec(void)
{
    int rowStatus, col, colMask;
    struct str_kpBtnData *btnData = kpTaskData.btnData;

    /*
     * If this is the first time ever to be called,
     *   simply activate the first row (to be read next time)
     */
    if (kpTaskData.firsttime) {
        kpTaskData.firsttime = FALSE;

        /* Activate the First Row and Return */
        KP_ROW_POUT |= KP_ALLROWS_MSK;
        KP_ROW_POUT &= ~(kpTaskData.rowMask);

        KP_ROW_PDIR &= ~(KP_ALLROWS_MSK);
        KP_ROW_PDIR |= (kpTaskData.rowMask);

        return;
    }

    /* Read the status of each button on the current row */
    rowStatus = KP_COL_PIN;

    /* Process each button in this row */
    col = 0;
    colMask = KP_FIRSTCOL_MSK;
    while (col < KP_NUMCOLS) {

        /* Ignore this button if state is KP_BLOCKED */
        if (btnData->state != KP_BLOCKED) {

            /* Button is Down */
            if ((rowStatus & colMask) == 0) {

                /* If was up last time, zero the counter and start over */
                if ( (btnData->state == KP_DEBOUNCING_UP) ||
                     (btnData->state == KP_IDLE) ) {
                    btnData->ctr = 0;
                    if (btnData->state == KP_DEBOUNCING_UP)
		      btnData->state = KP_DOWN;
		}

                /* Still debouncing... */
                if ( (btnData->state != KP_DOWN) &&
                     (btnData->ctr < KP_DOWN_MAXCNT) ) {

                    /* Increment debounce counter */
                    btnData->ctr++;

                    /* Set state to debouncing down */
                    btnData->state = KP_DEBOUNCING_DOWN;

                    /* Is the Button Solid Down Yet? */
                    if (btnData->ctr == KP_DOWN_MAXCNT) {
 
                        /* set all other button states to blocked */
                        kp_initBtnData(KP_BLOCKED, FALSE);

                        /* set this button's state to KP_DOWN */
                        btnData->state = KP_DOWN;

                        /* send BTN_DN message to s/w ctrlr */
                        controller_report_keypress(
                            kpTaskData.row*KP_NUMCOLS+col,
                            KEYSTATE_DOWN);
                    }
                }
            }

            /* Button is Up */
            else {

                /* If was down last time, zero the counter and start over */
                if ( (btnData->state == KP_DEBOUNCING_DOWN) ||
                     (btnData->state == KP_DOWN) ) {
                  btnData->ctr = 0;
                  if (btnData->state == KP_DEBOUNCING_DOWN)
                      btnData->state = KP_IDLE;
		}

                /* Still debouncing... */
                if ( (btnData->state != KP_IDLE) &&
                     (btnData->ctr < KP_UP_MAXCNT) ) {

                    /* Increment debounce counter */
                    btnData->ctr++;

                    /* Set state to debouncing up */
                    btnData->state = KP_DEBOUNCING_UP;

                    /* Is the Button Solid UP Yet? */
                    if (btnData->ctr == KP_UP_MAXCNT) {

                        /* set all button states to idle & clr counters */
                        kp_initBtnData(KP_IDLE, TRUE);

                        /* send BTN_UP message to s/w ctrlr */
                        controller_report_keypress(
                            kpTaskData.row*KP_NUMCOLS+col, KEYSTATE_UP);
                    }
                }
            }
        }

        /* Look at next button in this row */
        col++;
        colMask <<= 1;
        btnData++;

    } /* for each column */

    /* Point to Next Row */
    kpTaskData.row++;
    kpTaskData.rowMask <<= 1;
    kpTaskData.btnData = btnData;

    /* Wrap Around to First Row if Needed */
    if (kpTaskData.row >= KP_NUMROWS) {
        kpTaskData.row = 0;
        kpTaskData.rowMask = KP_FIRSTROW_MSK;
        kpTaskData.btnData = &kpBtnData[0];
    }

    /* Activate the New Row (to be read next time) */
    KP_ROW_POUT |= KP_ALLROWS_MSK;
    KP_ROW_POUT &= ~(kpTaskData.rowMask);

    KP_ROW_PDIR &= ~(KP_ALLROWS_MSK);
    KP_ROW_PDIR |= (kpTaskData.rowMask);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -