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

📄 headset_buttonmanager.c

📁 bc5_stereo:bluetooth stereo Headset CODE 支持A2DP HSP 和 HSP 。可作为车载免提。BlueLab 2007环境下编译
💻 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 + -