📄 hal_key.c
字号:
/**************************************************************************************************
Filename: hal_key.c
Revised: $Date: 2007-11-07 11:54:17 -0800 (Wed, 07 Nov 2007) $
Revision: $Revision: 15885 $
Description: This file contains the interface to the HAL KEY Service.
Copyright 2006-2007 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED 揂S IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/*********************************************************************
NOTE: If polling is used, the hal_driver task schedules the KeyRead()
to occur every 100ms. This should be long enough to naturally
debounce the keys. The KeyRead() function remembers the key
state of the previous poll and will only return a non-zero
value if the key state changes.
NOTE: If interrupts are used, the KeyRead() function is scheduled
25ms after the interrupt occurs by the ISR. This delay is used
for key debouncing. The ISR disables any further Key interrupt
until KeyRead() is executed. KeyRead() will re-enable Key
interrupts after executing. Unlike polling, when interrupts
are enabled, the previous key state is not remembered. This
means that KeyRead() will return the current state of the keys
(not a change in state of the keys).
NOTE: If interrupts are used, the KeyRead() fucntion is scheduled by
the ISR. Therefore, the joystick movements will only be detected
during a pushbutton interrupt caused by S1 or the center joystick
pushbutton.
NOTE: When a switch like S1 is pushed, the S1 signal goes from a normally
high state to a low state. This transition is typically clean. The
duration of the low state is around 200ms. When the signal returns
to the high state, there is a high likelihood of signal bounce, which
causes a unwanted interrupts. Normally, we would set the interrupt
edge to falling edge to generate an interrupt when S1 is pushed, but
because of the signal bounce, it is better to set the edge to rising
edge to generate an interrupt when S1 is released. The debounce logic
can then filter out the signal bounce. The result is that we typically
get only 1 interrupt per button push. This mechanism is not totally
foolproof because occasionally, signal bound occurs during the falling
edge as well. A similar mechanism is used to handle the joystick
pushbutton on the DB. For the EB, we do not have independent control
of the interrupt edge for the S1 and center joystick pushbutton. As
a result, only one or the other pushbuttons work reasonably well with
interrupts. The default is the make the S1 switch on the EB work more
reliably.
*********************************************************************/
/**************************************************************************************************
* INCLUDES
**************************************************************************************************/
#include "hal_mcu.h"
#include "hal_defs.h"
#include "hal_types.h"
#include "hal_drivers.h"
#include "hal_adc.h"
#include "hal_key.h"
#include "osal.h"
/**************************************************************************************************
* MACROS
**************************************************************************************************/
/**************************************************************************************************
* CONSTANTS
**************************************************************************************************/
#define HAL_KEY_BIT0 0x01
#define HAL_KEY_BIT1 0x02
#define HAL_KEY_BIT2 0x04
#define HAL_KEY_BIT3 0x08
#define HAL_KEY_BIT4 0x10
#define HAL_KEY_BIT5 0x20
#define HAL_KEY_BIT6 0x40
#define HAL_KEY_BIT7 0x80
#define HAL_KEY_RISING_EDGE 0
#define HAL_KEY_FALLING_EDGE 1
#define HAL_KEY_PDUP2 0x80
#define HAL_KEY_PDUP1 0x40
#define HAL_KEY_PDUP0 0x20
#define HAL_KEY_DEBOUNCE_VALUE 25
#define HAL_KEY_POLLING_VALUE 100
#if defined (HAL_BOARD_CC2430DB)
#define HAL_KEY_SW_6_ENABLE
#define HAL_KEY_SW_6_PORT P0 /* Port location of SW1 */
#define HAL_KEY_SW_6_BIT HAL_KEY_BIT1 /* Bit location of SW1 */
#define HAL_KEY_SW_6_SEL P0SEL /* Port Select Register for SW1 */
#define HAL_KEY_SW_6_DIR P0DIR /* Port Direction Register for SW1 */
#define HAL_KEY_SW_6_IEN IEN1 /* Interrupt Enable Register for SW1 */
#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT5 /* Interrupt Enable bit for SW1 */
#define HAL_KEY_SW_6_EDGE HAL_KEY_RISING_EDGE /* Type of interrupt for SW1 */
#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT0 /* EdgeType enable bit SW1 */
#define HAL_KEY_SW_6_ICTL PICTL /* Port Interrupt Control for SW1 */
#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT3 /* Interrupt enable bit for SW1 */
#define HAL_KEY_SW_6_PXIFG P0IFG /* Port Interrupt Flag for SW1 */
#define HAL_KEY_JOYSTICK_ENABLE
#define HAL_KEY_JOY_CHN HAL_ADC_CHANNEL_6
#define HAL_KEY_SW_5_ENABLE /* 2430DB - SW5 is enabled based on key interrupt enable or not - see config */
#define HAL_KEY_SW_5_PORT P2 /* Port location of SW5 */
#define HAL_KEY_SW_5_BIT HAL_KEY_BIT0 /* Bit location of SW5 */
#define HAL_KEY_SW_5_SEL P2SEL /* Port Select Register for SW5 */
#define HAL_KEY_SW_5_DIR P2DIR /* Port Direction Register for SW5 */
#define HAL_KEY_SW_5_INP P2INP /* Port Input Mode Register for SW5 */
#define HAL_KEY_SW_5_IEN IEN2 /* Interrupt Enable Register for SW5 */
#define HAL_KEY_SW_5_IENBIT HAL_KEY_BIT1 /* Interrupt Enable bit for SW5 */
#define HAL_KEY_SW_5_EDGE HAL_KEY_FALLING_EDGE /* Type of interrupt for SW5 */
#define HAL_KEY_SW_5_EDGEBIT HAL_KEY_BIT2 /* EdgeType enable bit SW5 */
#define HAL_KEY_SW_5_ICTL PICTL /* Port Interrupt Control for SW5 */
#define HAL_KEY_SW_5_ICTLBIT HAL_KEY_BIT5 /* Interrupt enable bit for SW5 */
#define HAL_KEY_SW_5_PXIFG P2IFG /* Port Interrupt Flag for SW5 */
#define HAL_KEY_P0INT_LOW_USED HAL_KEY_SW_6_BIT /* P0 can only be enabled/disabled as group of high or low nibble */
#define HAL_KEY_POINT_HIGH_USED 0 /* P0 can only be enabled/disabled as group of high or low nibble */
#endif
#if defined (HAL_BOARD_CC2430EB) || defined (HAL_BOARD_CC2430BB)
#define HAL_KEY_SW_6_ENABLE
#define HAL_KEY_SW_6_PORT P0 /* Port location of SW1 */
#define HAL_KEY_SW_6_BIT HAL_KEY_BIT1 /* Bit location of SW1 */
#define HAL_KEY_SW_6_SEL P0SEL /* Port Select Register for SW1 */
#define HAL_KEY_SW_6_DIR P0DIR /* Port Direction Register for SW1 */
#define HAL_KEY_SW_6_IEN IEN1 /* Interrupt Enable Register for SW1 */
#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT5 /* Interrupt Enable bit for SW1 */
#define HAL_KEY_SW_6_EDGE HAL_KEY_RISING_EDGE /* Type of interrupt for SW1 */
#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT0 /* EdgeType enable bit SW1 */
#define HAL_KEY_SW_6_ICTL PICTL /* Port Interrupt Control for SW1 */
#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT3 /* Interrupt enable bit for SW1 */
#define HAL_KEY_SW_6_PXIFG P0IFG /* Port Interrupt Flag for SW1 */
#define HAL_KEY_P0INT_LOW_USED HAL_KEY_SW_6_BIT /* P0 can only be enabled/disabled as group of high or low nibble */
#endif
#if defined (HAL_BOARD_CC2430BB)
#define HAL_KEY_POINT_HIGH_USED 0
#endif
#if defined (HAL_BOARD_CC2430EB)
#define HAL_KEY_JOYSTICK_ENABLE
#define HAL_KEY_JOY_CHN HAL_ADC_CHANNEL_6
#define HAL_KEY_SW_5_ENABLE
#define HAL_KEY_SW_5_PORT P0 /* Port location of SW5 */
#define HAL_KEY_SW_5_BIT HAL_KEY_BIT5 /* Bit location of SW5 */
#define HAL_KEY_SW_5_SEL P0SEL /* Port Select Register for SW5 */
#define HAL_KEY_SW_5_DIR P0DIR /* Port Direction Register for SW5 */
#define HAL_KEY_SW_5_INP P0INP /* Port Input Mode Register for SW5 */
#define HAL_KEY_SW_5_IEN IEN1 /* Interrupt Enable Register for SW5 */
#define HAL_KEY_SW_5_IENBIT HAL_KEY_BIT5 /* Interrupt Enable bit for SW5 */
#define HAL_KEY_SW_5_EDGE HAL_KEY_RISING_EDGE /* Type of interrupt for SW5 */
#define HAL_KEY_SW_5_EDGEBIT HAL_KEY_BIT2 /* EdgeType enable bit SW5 */
#define HAL_KEY_SW_5_ICTL PICTL /* Port Interrupt Control for SW5 */
#define HAL_KEY_SW_5_ICTLBIT HAL_KEY_BIT4 /* Interrupt enable bit for SW5 */
#define HAL_KEY_SW_5_PXIFG P0IFG /* Port Interrupt Flag for SW5 */
#define HAL_KEY_POINT_HIGH_USED HAL_KEY_SW_5_BIT /* P0 can only be enabled/disabled as group of high or low nibble */
#endif
/**************************************************************************************************
* TYPEDEFS
**************************************************************************************************/
/**************************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************************/
static uint8 halKeySavedKeys; /* used to store previous key state in polling mode */
static halKeyCBack_t pHalKeyProcessFunction;
bool Hal_KeyIntEnable; /* interrupt enable/disable flag */
uint8 halSaveIntKey; /* used by ISR to save state of interrupt-driven keys */
static uint8 HalKeyConfigured;
/**************************************************************************************************
* FUNCTIONS - Local
**************************************************************************************************/
void halProcessKeyInterrupt (void);
/**************************************************************************************************
* FUNCTIONS - API
**************************************************************************************************/
/**************************************************************************************************
* @fn HalKeyInit
*
* @brief Initilize Key Service
*
* @param none
*
* @return None
**************************************************************************************************/
void HalKeyInit( void )
{
#if (HAL_KEY == TRUE)
/* Initialize previous key to 0 */
halKeySavedKeys = 0;
#if defined (HAL_KEY_SW_6_ENABLE)
HAL_KEY_SW_6_SEL &= ~(HAL_KEY_SW_6_BIT); /* Set pin function to GPIO */
HAL_KEY_SW_6_DIR &= ~(HAL_KEY_SW_6_BIT); /* Set pin direction to Input */
#endif
#if defined (HAL_KEY_SW_5_ENABLE)
HAL_KEY_SW_5_SEL &= ~(HAL_KEY_SW_5_BIT); /* Set pin function to GPIO */
HAL_KEY_SW_5_DIR &= ~(HAL_KEY_SW_5_BIT); /* Set pin direction to Input */
HAL_KEY_SW_5_INP |= HAL_KEY_SW_5_BIT; /* Set pin input mode to tri-state */
#endif
/* Initialize callback function */
pHalKeyProcessFunction = NULL;
/* Start with key is not configured */
HalKeyConfigured = FALSE;
#endif /* HAL_KEY */
}
/**************************************************************************************************
* @fn HalKeyConfig
*
* @brief Configure the Key serivce
*
* @param interruptEnable - TRUE/FALSE, enable/disable interrupt
* cback - pointer to the CallBack function
*
* @return None
**************************************************************************************************/
void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)
{
#if (HAL_KEY == TRUE)
/* Enable/Disable Interrupt or */
Hal_KeyIntEnable = interruptEnable;
/* Register the callback fucntion */
pHalKeyProcessFunction = cback;
/* Determine if interrupt is enable or not */
if (Hal_KeyIntEnable)
{
/*
Work around for CC2430DB when interrupt is enabled and SW5 (center joystick)
is used. This SW5 uses P2 which also has debug lines connected to it. This
causes contant interruption on P2INT_VECTOR. Disable the usage of P2 interrupt
will stop this problem.
*/
#if defined (HAL_BOARD_CC2430DB)
#undef HAL_KEY_SW_5_ENABLE /* Dis-allow SW5 when key interrupt is enable */
#endif
#if defined (HAL_KEY_SW_5_ENABLE)
PICTL &= ~(HAL_KEY_SW_5_EDGEBIT); /* Set rising or falling edge */
#if (HAL_KEY_SW_5_EDGE == HAL_KEY_FALLING_EDGE)
PICTL |= HAL_KEY_SW_5_EDGEBIT;
#endif
HAL_KEY_SW_5_ICTL |= HAL_KEY_SW_5_ICTLBIT; /* Set interrupt enable bit */
HAL_KEY_SW_5_IEN |= HAL_KEY_SW_5_IENBIT;
HAL_KEY_SW_5_PXIFG = ~(HAL_KEY_SW_5_BIT); /* Clear any pending interrupts */
#endif
#if defined (HAL_KEY_SW_6_ENABLE)
PICTL &= ~(HAL_KEY_SW_6_EDGEBIT); /* Set rising or falling edge */
#if (HAL_KEY_SW_6_EDGE == HAL_KEY_FALLING_EDGE)
PICTL |= HAL_KEY_SW_6_EDGEBIT;
#endif
HAL_KEY_SW_6_ICTL |= HAL_KEY_SW_6_ICTLBIT; /* Set interrupt enable bit */
HAL_KEY_SW_6_IEN |= HAL_KEY_SW_6_IENBIT;
HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear any pending interrupts */
#endif
/* Do this only after the hal_key is configured - to work with sleep stuff */
if (HalKeyConfigured == TRUE)
{
osal_stop_timerEx( Hal_TaskID, HAL_KEY_EVENT); /* Cancel polling if active */
}
}
else /* Interrupts NOT enabled */
{
/*
Work around for CC2430DB when interrupt is enabled and SW5 (center joystick)
is used. This SW5 uses P2 which also has debug lines connected to it. This
causes contant interruption on P2INT_VECTOR. Disable the usage of P2 interrupt
will stop this problem.
*/
#if defined (HAL_BOARD_CC2430DB)
#define HAL_KEY_SW_5_ENABLE /* Allow SW5 only when key interrupt is disable */
#endif
#if defined (HAL_KEY_SW_6_ENABLE)
HAL_KEY_SW_6_ICTL &= ~(HAL_KEY_SW_6_ICTLBIT); /* Clear interrupt enable bit */
HAL_KEY_SW_6_IEN &= ~(HAL_KEY_SW_6_IENBIT);
#endif
#if defined (HAL_KEY_SW_5_ENABLE)
HAL_KEY_SW_5_ICTL &= ~(HAL_KEY_SW_5_ICTLBIT); /* Clear interrupt enable bit */
HAL_KEY_SW_5_IEN &= ~(HAL_KEY_SW_5_IENBIT);
#endif
osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE); /* Kick off polling */
}
/* Key now is configured */
HalKeyConfigured = TRUE;
#endif /* HAL_KEY */
}
/**************************************************************************************************
* @fn HalKeyRead
*
* @brief Read the current value of a key
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -