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

📄 headset_buttons.c

📁 蓝牙耳机的源代码,结合csr的开发套件使用
💻 C
字号:
/****************************************************************************Copyright (C) Cambridge Silicon Radio Ltd. 2005-2006Part of BlueLab 3.5.2-releaseFILE NAME    headset_buttons.c        DESCRIPTION    This is the button interpreter for BC4-Headset    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 eventNOTES*/#include "headset_private.h"#include "headset_buttonmanager.h"#include "headset_buttons.h"#include <stddef.h>#include <csrtypes.h>#include <panic.h>#include <stdlib.h>#include <pio.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_DOUBLE_PRESS_TIME_MS 500#define B_REPEAT_TIME_MS 500typedef enum ButtonsIntMsgTag {    B_DOUBLE_TIMER ,     B_INTERNAL_TIMER ,     B_REPEAT_TIMER  }ButtonsIntMsg_t;#define BUTTON_PIO_DEBOUNCE_NUM_CHECKS  3#define BUTTON_PIO_DEBOUNCE_TIME_MS     5/* LOCAL FUNCTION PROTOTYPES *//****************************************************************************NAME  buttonManagerMessageHandlerDESCRIPTION Message handler that receives the button presses and creates the system eventsRETURNS void    */void ButtonsMessageHandler ( Task pTask, MessageId pId, Message pMessage )   ;static bool ButtonsWasButtonPressed ( uint16 pOldState , uint16 pNewState) ;static uint16 ButtonsWhichButtonChanged ( uint16 pOldState , uint16 pNewState ) ;static void ButtonsButtonDetected (  BTaskData * pBTask ,uint16 pButtonMask  , ButtonsTime_t pTime  ) ;static void ButtonsEdgeDetect ( const uint16 pState , BTaskData * pBTask ) ;        static void ButtonsLevelDetect ( const uint16 pState , BTaskData * pBTask )  ;/****************************************************************************VARIABLES  *//****************************************************************************  FUNCTIONS*//****************************************************************************NAME  buttonManagerInit    DESCRIPTION Initialises the Button Module parametersRETURNS void*/  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);        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;        B_DEBUG(("B : Get[%x]\n", PioGet() )) ;        }/****************************************************************************NAME  ButtonsRegisterButtonsDESCRIPTION Registers buttons contained in the mask so that they will be detected by    the button taskRETURNS void    */void ButtonsRegisterButtons ( BTaskData *pBTask, uint16 pButtonMask , ButtonTriggerType_t pTrigger ) {    switch ( pTrigger )    {        case ( ButtonLevelTrigger ):        {            pBTask->gButtonLevelMask |= pButtonMask ;            B_DEBUG(("B  :Reg Lvl[%x][%x]\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 ( PioGet() , pBTask ) ;            }        break;        case ( ButtonEdgeTrigger ):        {            pBTask->gButtonEdgeMask |= pButtonMask ;            B_DEBUG(("B  :Reg Edge[%x][%x]\n",pButtonMask , pBTask->gButtonEdgeMask)) ;                        ButtonsEdgeDetect ( PioGet() , pBTask) ;        }        break;        default:            B_DEBUG(("B: reg [%x]?\n",pTrigger)) ;        break;    }          /* Debounce required PIO lines */    PioDebounce(pBTask->gButtonEdgeMask | pBTask->gButtonLevelMask,                 BUTTON_PIO_DEBOUNCE_NUM_CHECKS,                 BUTTON_PIO_DEBOUNCE_TIME_MS);    }/*************************************************************NAME  ButtonsUnRegisterButtonsDESCRIPTION Removes Registered buttons contained in the masks so that they will be detected by    the button taskRETURNS void    */void ButtonsUnRegisterButtons ( BTaskData *pBTask, uint16 pButtonMask  ){    pBTask->gButtonLevelMask &= (0xFFFF - pButtonMask ) ;    B_DEBUG(("B  :UnReg Lvl[%x][%x]\n",pButtonMask , pBTask->gButtonLevelMask)) ;    pBTask->gButtonEdgeMask &= (0xFFFF - pButtonMask ) ;    B_DEBUG(("B  :UnReg Edge[%x][%x]\n",pButtonMask , pBTask->gButtonEdgeMask)) ;}void ButtonsConfigDurations ( BTaskData *pBTask,  uint16 pLong , uint16 pVeryLong , uint16 pDouble , uint16 pRepeat)      {    /* 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 ;}/****************************************************************************NAME  buttonManagerMessageHandlerDESCRIPTION the button event message handler - converts button events to the system eventsRETURNS void*/void ButtonsMessageHandler ( Task pTask, MessageId pId, Message pMessage ) {       BTaskData * lBTask = (BTaskData*)pTask ;        /*the message if there is one*/    const MessagePioChanged * lMessage = ( const MessagePioChanged * ) (pMessage ) ;    B_DEBUG(("B :BMess \n")) ;    switch ( pId )    {    case MESSAGE_PIO_CHANGED :         {            ButtonsLevelDetect ( (uint16) lMessage->state , lBTask ) ;                        ButtonsEdgeDetect  ( (uint16) lMessage->state , lBTask ) ;        }    break ;        case B_DOUBLE_TIMER:                /*if we have reached here, then a double timer has been received*/         B_DEBUG(("B : Double[%x][%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_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 */        ButtonsButtonDetected ( lBTask, lBTask->gBOldState , lBTask->gBTime );                          break ;    case B_REPEAT_TIMER:        /*if we have reached here, the repeat time has been reached so send a new message*/        B_DEBUG(("B : Repeat [%x][%x]\n", lBTask->gBOldState , B_REPEAT  )) ;                /*send another repeat message*/        MessageSendLater ( &lBTask->task , B_REPEAT_TIMER , 0 ,  lBTask->gBRepeatDuration_ms ) ;         ButtonsButtonDetected ( lBTask, lBTask->gBOldState , B_REPEAT );                 break;    default :           B_DEBUG(("B : ?[%x]\n",pId)) ;         break ;    }}/****************************************************************************NAME  ButtonsWasButtonPressed    DESCRIPTION helper method - returns true if a buton was pressedRETURNS bool*/  static bool ButtonsWasButtonPressed ( uint16 pOldState , uint16 pNewState){    bool lWasButtonPressed = FALSE ;     uint16 lButton = ButtonsWhichButtonChanged ( pOldState , pNewState ) ;        if ( ( lButton & pNewState ) != 0 )    {        lWasButtonPressed = TRUE ;    }        /*    B_DEBUG(("B : Was[%x]\n", lWasButtonPressed)) ;    */        return lWasButtonPressed ;}/****************************************************************************NAME  ButtonsWhichButtonChanged    DESCRIPTION helper method - returns mask ofwhich button changedRETURNS uint16*/ static uint16 ButtonsWhichButtonChanged ( uint16 pOldState , uint16 pNewState ){    uint16 lWhichButton = 0 ;            lWhichButton = (pNewState ^ pOldState ) ;        /*    B_DEBUG(("B : Whi[%x] \n", lWhichButton)) ;    */        return lWhichButton ;}/****************************************************************************NAME  ButtonsButtonDetected    DESCRIPTION function to handle a button press - informs button manager of a change    currently makes direct call - may want to use message handling (tasks)RETURNS uint16*/ static void ButtonsButtonDetected (  BTaskData * pBTask, uint16 pButtonMask  , ButtonsTime_t pTime ){        if( pButtonMask == 0 )    {/*        MessageCancelAll ( &pBTask->task , B_INTERNAL_TIMER ) ;*/        MessageCancelAll ( &pBTask->task , B_REPEAT_TIMER ) ;    }    else    {        BMButtonDetected ( pButtonMask , pTime ) ;    } }/****************************************************************************NAME  ButtonsLevelDetect    DESCRIPTION function to detect level changes of buttons / multiple buttons. RETURNS void*/ static void ButtonsLevelDetect ( const uint16 pState , BTaskData * pBTask ) {    uint16 lNewState = 0x0000;    /*we have an indication from the PIO subsytem that a PIO has changed value*/    lNewState = (int) (pState & (pBTask->gButtonLevelMask) ) ;        B_DEBUG(("B| : [%x][%x]\n", pState , (pBTask->gButtonLevelMask) )) ;    B_DEBUG(("B| : [%x][%x]\n", pBTask->gBOldState , lNewState )) ;        if ( ButtonsWasButtonPressed( pBTask->gBOldState , lNewState )  )    {                /*cancel all previously timed messages*/        MessageCancelAll ( &pBTask->task , B_INTERNAL_TIMER ) ;        MessageCancelAll ( &pBTask->task , B_REPEAT_TIMER ) ;        MessageCancelAll ( &pBTask->task , B_DOUBLE_TIMER ) ;                        /* send new timed messages*/        MessageSendLater ( &pBTask->task , B_INTERNAL_TIMER , 0 ,  pBTask->gBLongDuration_ms ) ;         MessageSendLater ( &pBTask->task , B_INTERNAL_TIMER , 0 ,  pBTask->gBVeryLongDuration_ms ) ;         MessageSendLater ( &pBTask->task , B_REPEAT_TIMER , 0 ,  pBTask->gBRepeatDuration_ms ) ;                     /*having restrted the timers, reset the time*/        pBTask->gBTime = B_SHORT ;          }    else /*button was released or was masked out*/    {         /*it was only a released if there was a button actually pressed last time around -               buttons we have masked out still end up here but no state changes are made  */        if ( pBTask->gBOldState != 0 )        {                 /*if we have had a double press in the required time                  and the button pressed was the same as this one*/             if (  (pBTask->gBDoubleTap == TRUE ) && (pBTask->gBOldState == pBTask->gBDoubleState ) )             {                 pBTask->gBTime = B_DOUBLE ;                    /*reset the double state*/                 pBTask->gBDoubleState = 0x0000 ;                 pBTask->gBDoubleTap = FALSE ;                 ButtonsButtonDetected ( pBTask , pBTask->gBOldState , B_DOUBLE  );              }                                                 /*only send a message if it was a short one - long / v long /double handled elsewhere*/             if ( (pBTask->gBTime == B_SHORT ) )             {                 ButtonsButtonDetected ( pBTask , pBTask->gBOldState , B_SHORT  );                                   /*store the double state*/                 pBTask->gBDoubleState = pBTask->gBOldState ;                 pBTask->gBDoubleTap = TRUE ;                            /*start the double timer - only applicable to a short press*/                 MessageSendLater ( &pBTask->task , B_DOUBLE_TIMER , 0 ,pBTask->gBDoubleDuration_ms ) ;             }               else if ( (pBTask->gBTime == B_LONG) )             {                 ButtonsButtonDetected ( pBTask , pBTask->gBOldState , B_LONG_RELEASE  );                               }             else if ( (pBTask->gBTime == B_VERY_LONG) )             {                 ButtonsButtonDetected ( pBTask , pBTask->gBOldState , B_VERY_LONG_RELEASE  );              }                          if (pBTask->gBTime != B_INVALID)             {                MessageCancelAll ( &pBTask->task , B_INTERNAL_TIMER) ;                MessageCancelAll ( &pBTask->task , B_REPEAT_TIMER ) ;              }                 			 /*removing this allows all releases to generate combination presses is this right?*/             if ( !lNewState )             {                 pBTask->gBTime = B_INVALID ;                   }          }         }    pBTask->gBOldState = lNewState ;}  /****************************************************************************NAME EdgeDetect    DESCRIPTION function to detect edge changes of buttons / multiple buttons.     RETURNS void*/ static void ButtonsEdgeDetect ( const uint16 pState , BTaskData * pBTask ) {    uint16 lNewState = 0x0000 ;        uint16 lButton = 0x0000 ;        /*what has changed */    lNewState = (int) ( pState & (pBTask->gButtonEdgeMask) ) ;        lButton = ButtonsWhichButtonChanged( pBTask->gBOldEdgeState , lNewState ) ;            B_DEBUG(("BA: [%x][%x][%x]\n", pBTask->gBOldEdgeState , lNewState , pBTask->gButtonEdgeMask  )) ;    B_DEBUG(("BB: [%x][%x][%x]\n", lNewState , lButton , (lNewState & lButton) )) ;            /*if a button has changed*/    if ( lButton )    {            /*determine which edge has been received and process accordingly*/        if ( lNewState & lButton )        {              ButtonsButtonDetected ( pBTask , lButton , B_LOW_TO_HIGH )   ;        }        else        {            ButtonsButtonDetected ( pBTask , lButton , B_HIGH_TO_LOW  )   ;        }    }        /*remember the last state*/    pBTask->gBOldEdgeState = lNewState;}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -