?? headset_buttons.c
字號:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2005-2007
FILE NAME
headset_buttons.c
DESCRIPTION
This is the button interpreter for the stereo application.
This file extracts the button messages from the PIO subsystem and figures out
the button press type and time. It passes the information to the button manager
which is responsible for translating the button press generated into a system event.
*/
#include "headset_buttonmanager.h"
#include "headset_buttons.h"
#include "headset_debug.h"
#include "headset_private.h"
#include <charger.h>
#include <csrtypes.h>
#include <panic.h>
#include <pio.h>
#include <stddef.h>
#include <stdlib.h>
#ifdef DEBUG_BUTTONS
#define B_DEBUG(x) DEBUG(x)
#else
#define B_DEBUG(x)
#endif
/* The default button durations */
#define B_LONG_TIME_MS (1000)
#define B_VERY_LONG_TIME_MS (2000)
#define B_VERY_VERY_LONG_TIME_MS (4000)
#define B_DOUBLE_PRESS_TIME_MS (500)
#define B_REPEAT_TIME_MS (500)
typedef enum ButtonsIntMsgTag
{
B_DOUBLE_TIMER ,
B_INTERNAL_TIMER ,
B_REPEAT_TIMER
}ButtonsIntMsg_t;
#define BUTTON_PIO_DEBOUNCE_NUM_CHECKS (4)
#define BUTTON_PIO_DEBOUNCE_TIME_MS (15)
#define VREG_PIN (24)
#define CHG_PIN (25)
/****************************************************************************
LOCAL FUNCTION PROTOTYPES
*/
static void ButtonsMessageHandler ( Task pTask, MessageId pId, Message pMessage ) ;
static bool ButtonsWasButtonPressed ( uint32 pOldState , uint32 pNewState) ;
static uint32 ButtonsWhichButtonChanged ( uint32 pOldState , uint32 pNewState ) ;
static void ButtonsButtonDetected ( BTaskData * pBTask ,uint32 pButtonMask , ButtonsTime_t pTime ) ;
static void ButtonsEdgeDetect ( const uint32 pState , BTaskData * pBTask ) ;
static void ButtonsLevelDetect ( const uint32 pState , BTaskData * pBTask ) ;
static bool ButtonsIsChargerConnected ( void ) ;
/****************************************************************************
FUNCTIONS
*/
/*****************************************************************************/
void ButtonsInit ( BTaskData *pBTask )
{
pBTask->gBOldState = 0x0000 ;
pBTask->gBTime = B_SHORT ;
pBTask->gBDoubleTap = FALSE ;
pBTask->gBDoubleState = 0x0000 ;
pBTask->gButtonLevelMask = 0x0000 ;
pBTask->gButtonEdgeMask = 0x0000 ;
pBTask->gBOldEdgeState = 0x0000 ;
pBTask->task.handler = ButtonsMessageHandler;
/*connect the underlying PIO task to this task*/
MessagePioTask(&pBTask->task);
/*connect the underlying Charger task to this task*/
MessageChargerTask(&pBTask->task);
pBTask->gBLongDuration_ms = B_LONG_TIME_MS;
pBTask->gBVeryLongDuration_ms = B_VERY_LONG_TIME_MS;
pBTask->gBDoubleDuration_ms = B_DOUBLE_PRESS_TIME_MS;
pBTask->gBRepeatDuration_ms = B_REPEAT_TIME_MS;
pBTask->gBVeryVeryLongDuration_ms = B_VERY_VERY_LONG_TIME_MS;
B_DEBUG(("B : Get[%lx]\n", PioGet32() )) ;
}
/*****************************************************************************/
void ButtonsRegisterButtons ( BTaskData *pBTask, uint32 pButtonMask , ButtonTriggerType_t pTrigger , const uint16 pio_debounce )
{
uint16 charger_events = 0;
bool vreg_en = PioGetVregEn();
bool chg_en = ButtonsIsChargerConnected();
uint32 vreg_val = 0;
uint32 chg_val = 0;
if (vreg_en)
vreg_val = (uint32)1 << VREG_PIN;
if (chg_en)
chg_val = (uint32)1 << CHG_PIN;
switch ( pTrigger )
{
case ( ButtonLevelTrigger ):
{
pBTask->gButtonLevelMask |= pButtonMask ;
B_DEBUG(("B :Reg Lvl[%lx][%lx]\n",pButtonMask , pBTask->gButtonLevelMask)) ;
/*reset the state so that no messages are sent*/
pBTask->gBTime = B_INVALID ;
/*kick off the messages looking for a power On*/
ButtonsLevelDetect ( PioGet32() | vreg_val | chg_val , pBTask ) ;
}
break;
case ( ButtonEdgeTrigger ):
{
pBTask->gButtonEdgeMask |= pButtonMask ;
B_DEBUG(("B :Reg Edge[%lx][%lx]\n",pButtonMask , pBTask->gButtonEdgeMask)) ;
ButtonsEdgeDetect ( PioGet32() | vreg_val | chg_val , pBTask) ;
}
break;
default:
B_DEBUG(("B: reg [%x]?\n",pTrigger)) ;
break;
}
B_DEBUG(("B: Debounce no[%x] time[%x]?\n",( pio_debounce >> 8 ) & 0xff, pio_debounce & 0xff)) ;
/* Debounce required PIO lines - only first 24 bits */
PioDebounce( (pBTask->gButtonEdgeMask | pBTask->gButtonLevelMask) & 0xffffff, ( pio_debounce >> 8 ) & 0xff, pio_debounce & 0xff );
/* Debounce required charger events - special PIO values (24 = vreg, 25 = chg) */
if ((pBTask->gButtonEdgeMask | pBTask->gButtonLevelMask) & ((uint32)1 << VREG_PIN))
charger_events |= CHARGER_VREG_EVENT;
if ((pBTask->gButtonEdgeMask | pBTask->gButtonLevelMask) & ((uint32)1 << CHG_PIN))
charger_events |= CHARGER_CONNECT_EVENT;
B_DEBUG(("B :Reg chg[%x]\n", charger_events));
if (charger_events)
ChargerDebounce(charger_events, ( pio_debounce >> 8 ) & 0xff, pio_debounce & 0xff);
}
/*****************************************************************************/
void ButtonsConfigDurations ( BTaskData *pBTask, uint16 pLong , uint16 pVeryLong , uint16 pDouble , uint16 pRepeat , uint16 pVeryVeryLong)
{
/* Range checking performed by Configuration Manager */
B_DEBUG(("B : Dur [%d][%d][%d][%d]\n" , pLong , pVeryLong , pDouble, pRepeat )) ;
pBTask->gBLongDuration_ms = pLong;
pBTask->gBVeryLongDuration_ms = pVeryLong ;
pBTask->gBDoubleDuration_ms = pDouble ;
pBTask->gBRepeatDuration_ms = pRepeat ;
pBTask->gBVeryVeryLongDuration_ms = pVeryVeryLong ;
}
/****************************************************************************
NAME
ButtonsMessageHandler
DESCRIPTION
The button event message handler - converts button events to the system events.
*/
static void ButtonsMessageHandler ( Task pTask, MessageId pId, Message pMessage )
{
BTaskData * lBTask = (BTaskData*)pTask ;
B_DEBUG(("B :BMess \n")) ;
switch ( pId )
{
case MESSAGE_PIO_CHANGED :
{
const MessagePioChanged * lMessage = ( const MessagePioChanged * ) (pMessage ) ;
bool vreg_en = PioGetVregEn();
bool chg_en = ButtonsIsChargerConnected();
uint32 vreg_val = 0;
uint32 chg_val = 0;
if (vreg_en)
vreg_val = (uint32)1 << VREG_PIN;
if (chg_en)
chg_val = (uint32)1 << CHG_PIN;
ButtonsLevelDetect ( ((uint32)lMessage->state16to31 << 16) | lMessage->state | vreg_val | chg_val , lBTask ) ;
ButtonsEdgeDetect ( ((uint32)lMessage->state16to31 << 16) | lMessage->state | vreg_val | chg_val , lBTask ) ;
}
break ;
case MESSAGE_CHARGER_CHANGED:
{
const MessageChargerChanged *m = (const MessageChargerChanged *) (pMessage ) ;
ButtonsLevelDetect ( ((uint32)m->vreg_en_high << VREG_PIN) | ((uint32)m->charger_connected << CHG_PIN) | PioGet32() , lBTask ) ;
ButtonsEdgeDetect ( ((uint32)m->vreg_en_high << VREG_PIN) | ((uint32)m->charger_connected << CHG_PIN) | PioGet32() , lBTask ) ;
}
break;
case B_DOUBLE_TIMER:
{
/*if we have reached here, then a double timer has been received*/
B_DEBUG(("B : Double[%lx][%x]\n", lBTask->gBDoubleState , B_SHORT_SINGLE)) ;
lBTask->gBDoubleTap = FALSE ;
/*indicate that a short button was pressed and it did not become a double press */
ButtonsButtonDetected ( lBTask, lBTask->gBDoubleState , B_SHORT_SINGLE );
}
break ;
case B_INTERNAL_TIMER:
{
/*if we have reached here, then the buttons have been held longer than one of the timed messages*/
B_DEBUG(("B : Timer\n")) ;
if ( lBTask->gBTime == B_VERY_LONG )
{
lBTask->gBTime = B_VERY_VERY_LONG ;
}
else if ( lBTask->gBTime == B_LONG )
{
lBTask->gBTime = B_VERY_LONG ;
/*notify the app that the timer has expired*/
MessageSend( getAppTask() , EventVLongTimer , 0 ) ;
}
else
{
/*notify the app that the timer has expired*/
MessageSend( getAppTask() , EventLongTimer , 0 ) ;
lBTask->gBTime = B_LONG ;
}
/*indicate that we have received a message */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -