📄 headset_buttonmanager.c
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2005-2007
FILE NAME
headset_buttonmanager.c
DESCRIPTION
This is the button manager for stereo application.
This file provides a configurable wrapper for the button messages and
converts them into the standard system messages which are passed to the
main message handler - main.c.
NOTES
*/
#include "headset_buttonmanager.h"
#include "headset_buttons.h"
#include "headset_debug.h"
#include "headset_events.h"
#include "headset_private.h"
#include "headset_statemanager.h"
#include <csrtypes.h>
#include <panic.h>
#include <stddef.h>
#include <stdlib.h>
#ifdef DEBUG_BUT_MAN
#define BM_DEBUG(x) DEBUG(x)
const char * const gDebugTimeStrings[13] = {"Inv" ,
"Short",
"Long" ,
"VLong" ,
"Double" ,
"Rpt" ,
"LToH" ,
"HToL" ,
"ShSingle",
"Long Release",
"VLong Release",
"V V Long" ,
"VV Long Release"} ;
#else
#define BM_DEBUG(x)
#endif
/* Instance pointer to the task that we are registered with. */
static BTaskData * gButtonsTask = NULL ;
#define BM_EVENTS_PER_BLOCK (20)
#define BM_NUM_BLOCKS (2)
#define BM_NUM_CONFIGURABLE_EVENTS (BM_EVENTS_PER_BLOCK * BM_NUM_BLOCKS)
/****************************************************************************
LOCAL FUNCTION PROTOTYPES
*/
static void BMCheckForButtonMatch ( uint32 pButtonMask , ButtonsTime_t pDuration ) ;
static ButtonEvents_t * BMGetButtonEvent ( void ) ;
static void BMCheckForButtonPatternMatch ( uint32 pButtonMask ) ;
/****************************************************************************
FUNCTIONS
*/
/*****************************************************************************/
void buttonManagerInit ( BTaskData *pBTask, Task pClient )
{
uint16 lIndex = 0 ;
uint16 lButtonIndex = 0;
/*a pointer to the buttons task*/
gButtonsTask = pBTask ;
gButtonsTask->client = pClient;
/*the button events*/
gButtonsTask->gButtonEvents [0] = NULL ;
gButtonsTask->gButtonEvents [1] = NULL ;
/*create the button patterns*/
/*get the memory for the button Match Patterns*/
gButtonsTask->gButtonPatterns[0] = PanicUnlessMalloc ( (sizeof(ButtonMatchPattern_t) * BM_NUM_BUTTON_MATCH_PATTERNS) ) ;
gButtonsTask->gButtonPatterns[1] = gButtonsTask->gButtonPatterns[0] + 1 ;
BM_DEBUG(("BM: Button MatchPats [%d] [%d]\n" , (int)gButtonsTask->gButtonPatterns[0] , (int)gButtonsTask->gButtonPatterns[1]));
for (lIndex = 0 ; lIndex < BM_NUM_BUTTON_MATCH_PATTERNS ; lIndex++ )
{
/*set the progress to the beginning*/
gButtonsTask->gButtonMatchProgress[lIndex] = 0 ;
/*set the button match patterns to known vals*/
gButtonsTask->gButtonPatterns[lIndex]->NumberOfMatches = 0 ;
gButtonsTask->gButtonPatterns[lIndex]->EventToSend = 0 ;
for (lButtonIndex = 0 ; lButtonIndex < BM_NUM_BUTTONS_PER_MATCH_PATTERN ; lButtonIndex++)
{
gButtonsTask->gButtonPatterns[lIndex]->ButtonToMatch[lButtonIndex] = B_INVALID ;
}
}
/* create the array of Button Events that we are going to populate */
gButtonsTask->gButtonEvents[0] = (ButtonEvents_t * ) ( PanicUnlessMalloc( sizeof( ButtonEvents_t ) * BM_EVENTS_PER_BLOCK ) ) ;
gButtonsTask->gButtonEvents[1]= (ButtonEvents_t * ) ( PanicUnlessMalloc( sizeof( ButtonEvents_t ) * BM_EVENTS_PER_BLOCK ) ) ;
/*init the PIO button routines with the Button manager Task data */
ButtonsInit( gButtonsTask ) ;
}
/*****************************************************************************/
bool buttonManagerAddMapping ( uint32 pButtonMask ,
headsetEvents_t pSystemEvent ,
uint16 pHfpStateMask ,
uint16 pA2dpStateMask ,
ButtonsTime_t pDuration,
const uint16 pio_debounce )
{
ButtonTriggerType_t lTrigger = ButtonLevelTrigger ;
ButtonEvents_t * lButtonEvent ;
bool lAddOk = FALSE;
BM_DEBUG(("BM : nB[%lx]E[%x]HF[%x]AV[%x] [%s]",pButtonMask, pSystemEvent, pHfpStateMask , pA2dpStateMask , gDebugTimeStrings[pDuration])) ;
lButtonEvent = BMGetButtonEvent() ;
/**if we were given a button event**/
if ( lButtonEvent )
{
lButtonEvent->ButtonMask = pButtonMask ;
lButtonEvent->Duration = pDuration ;
lButtonEvent->Event = pSystemEvent ;
lButtonEvent->HfpStateMask = pHfpStateMask ;
lButtonEvent->A2dpStateMask = pA2dpStateMask ;
/*inc the global index*/
gButtonsTask->gNumEventsConfigured++ ;
if ( (pDuration == B_LOW_TO_HIGH ) || (pDuration == B_HIGH_TO_LOW) )
{
lTrigger = ButtonEdgeTrigger ;
}
/*register the buttons we are interested in with the buttons task*/
ButtonsRegisterButtons (gButtonsTask , pButtonMask , lTrigger , pio_debounce) ;
lAddOk = TRUE ;
}
else
{
BM_DEBUG(("_![%x]\n", gButtonsTask->gNumEventsConfigured)) ;
}
return lAddOk ;
}
/*****************************************************************************/
void buttonManagerConfigDurations ( uint16 pLong , uint16 pVeryLong , uint16 pDouble , uint16 pRepeat , uint16 pVeryVeryLong )
{
BM_DEBUG(("BM : Dur L[%d] VL[%d] D[%d] R[%d] VVL[%d]\n" , pLong , pVeryLong , pDouble , pRepeat , pVeryVeryLong)) ;
ButtonsConfigDurations ( gButtonsTask , pLong , pVeryLong , pDouble , pRepeat , pVeryVeryLong) ;
}
/*****************************************************************************/
void BMButtonDetected ( uint32 pButtonMask , ButtonsTime_t pTime )
{
BM_DEBUG(("BM : But [%lx] [%s]\n" , pButtonMask , gDebugTimeStrings[pTime] )) ;
/*perform the search over both blocks*/
BMCheckForButtonMatch ( pButtonMask , pTime ) ;
/*only use regular button presses for the pattern matching to make life simpler*/
if ( ( pTime == B_SHORT ) || (pTime == B_LONG ) )
{
BMCheckForButtonPatternMatch ( pButtonMask ) ;
}
}
/*****************************************************************************/
bool BMAddPatternMapping ( uint16 pSystemEvent , uint32 * pButtonsToMatch )
{
uint16 lMapIndex = 0 ;
uint16 lButtonIndex = 0 ;
/*adds a button pattern map*/
for (lMapIndex = 0 ; lMapIndex < BM_NUM_BUTTON_MATCH_PATTERNS ; lMapIndex++)
{
if (gButtonsTask->gButtonPatterns[lMapIndex]->EventToSend == B_INVALID )
{
gButtonsTask->gButtonPatterns[lMapIndex]->EventToSend = pSystemEvent ;
for (lButtonIndex = 0 ; lButtonIndex < BM_NUM_BUTTONS_PER_MATCH_PATTERN ; lButtonIndex++)
{
gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[lButtonIndex] = pButtonsToMatch[lButtonIndex] ;
if (gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[lButtonIndex] != 0)
{
gButtonsTask->gButtonPatterns[lMapIndex]->NumberOfMatches = lButtonIndex + 1;
}
}
BM_DEBUG(("BM: But Pat Added[%d] [%x] ,[%ld][%ld][%ld][%ld][%ld][%ld] [%d]\n" , lMapIndex , gButtonsTask->gButtonPatterns[lMapIndex]->EventToSend
, gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[0]
, gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[1]
, gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[2]
, gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[3]
, gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[4]
, gButtonsTask->gButtonPatterns[lMapIndex]->ButtonToMatch[5]
, gButtonsTask->gButtonPatterns[lMapIndex]->NumberOfMatches
)) ;
return TRUE ;
}
}
return FALSE ;
}
/****************************************************************************
NAME
BMGetButtonEvent
DESCRIPTION
Method to get a ButtonEvent if there are any free ones available.
RETURNS
ButtonEvents_t * if there is one available - NULL otherwise.
*/
static ButtonEvents_t * BMGetButtonEvent ( void )
{
ButtonEvents_t * lButtonEvent = NULL ;
/*iterate through the button Eventts looking for an empty block*/
uint16 lBlockIndex = 0 ;
uint16 lEvIndex = 0 ;
/*each block*/
for (lBlockIndex = 0 ; lBlockIndex < BM_NUM_BLOCKS ; lBlockIndex++)
{ /*Each Entry*/
for (lEvIndex = 0 ; lEvIndex < BM_EVENTS_PER_BLOCK ; lEvIndex ++)
{
lButtonEvent = &gButtonsTask->gButtonEvents[lBlockIndex][lEvIndex];
/*if this event is empty*/
if ( lButtonEvent->Event == (EventInvalid - EVENTS_EVENT_BASE) )
{
BM_DEBUG(("BM: BuF[%d][%d]\n" , lBlockIndex , lEvIndex )) ;
/*if we find an empty one then do not continue looking*/
return lButtonEvent ;
}
}
}
/*if there were no events available return NULL*/
return NULL ;
}
/****************************************************************************
NAME
BMCheckForButtonMatch
DESCRIPTION
Function to check a button for a match in the button events map - sends a message
to a connected task with the corresponding event.
*/
static void BMCheckForButtonMatch ( uint32 pButtonMask , ButtonsTime_t pDuration )
{
uint16 lHfpStateBit = ( 1 << stateManagerGetHfpState () ) ;
uint16 lA2dpStateBit = ( 1 << stateManagerGetA2dpState () ) ;
uint16 lBlockIndex = 0 ;
uint16 lEvIndex = 0 ;
BM_DEBUG(("BM : BMCheckForButtonMatch [%x][%x][%lx][%x]\n" , lHfpStateBit , lA2dpStateBit , pButtonMask, pDuration)) ;
/*each block*/
for (lBlockIndex = 0 ; lBlockIndex < BM_NUM_BLOCKS ; lBlockIndex++)
{ /*Each Entry*/
for (lEvIndex = 0 ; lEvIndex < BM_EVENTS_PER_BLOCK ; lEvIndex ++)
{
ButtonEvents_t * lButtonEvent = &gButtonsTask->gButtonEvents [lBlockIndex] [ lEvIndex ] ;
/*if the event is valid*/
if ( lButtonEvent != NULL)
{
if (lButtonEvent->ButtonMask == pButtonMask )
{
/*we have a button match*/
if ( lButtonEvent->Duration == pDuration )
{
if ( ((lButtonEvent->HfpStateMask) & (lHfpStateBit)) && ((lButtonEvent->A2dpStateMask) & (lA2dpStateBit)) )
{
BM_DEBUG(("BM : Match [%lx][%x]\n" , pButtonMask , lButtonEvent->Event)) ;
/*we have fully matched an event....so tell the main task about it*/
MessageSend( gButtonsTask->client, lButtonEvent->Event , 0 ) ;
}
}
}
}
}
}
}
/****************************************************************************
NAME
BMCheckForButtonPatternMatch
DESCRIPTION
Check to see if a button pattern has been matched.
*/
static void BMCheckForButtonPatternMatch ( uint32 pButtonMask )
{
uint16 lIndex = 0 ;
BM_DEBUG(("BM: Pat[%lx]\n", pButtonMask )) ;
for (lIndex = 0; lIndex < BM_NUM_BUTTON_MATCH_PATTERNS ; lIndex++ )
{
if ( gButtonsTask->gButtonPatterns[lIndex]->ButtonToMatch[gButtonsTask->gButtonMatchProgress[lIndex]] == pButtonMask )
{
/*we have matched a button*/
gButtonsTask->gButtonMatchProgress[lIndex]++ ;
BM_DEBUG(("BM: Pat Prog[%d][%x]\n", lIndex , gButtonsTask->gButtonMatchProgress[lIndex] )) ;
if (gButtonsTask->gButtonMatchProgress[lIndex] >= gButtonsTask->gButtonPatterns[lIndex]->NumberOfMatches)
{
/*we have matched a pattern*/
BM_DEBUG(("BM: Pat Match[%d] Ev[%x]\n", lIndex ,gButtonsTask->gButtonPatterns[lIndex]->EventToSend)) ;
gButtonsTask->gButtonMatchProgress[lIndex] = 0 ;
MessageSend( gButtonsTask->client, gButtonsTask->gButtonPatterns[lIndex]->EventToSend , 0 ) ;
}
}
else
{
gButtonsTask->gButtonMatchProgress[lIndex] = 0 ;
/*special case = if the last button pressed was the same as the first button*/
if ( gButtonsTask->gButtonPatterns [ lIndex ]->ButtonToMatch[0]== pButtonMask)
{
gButtonsTask->gButtonMatchProgress[lIndex] = 1 ;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -