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

📄 headset_buttons.c

📁 bc5_stereo:bluetooth stereo Headset CODE 支持A2DP HSP 和 HSP 。可作为车载免提。BlueLab 2007环境下编译
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
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 + -