Beispiel #1
0
/****************************************************************************
DESCRIPTION
 	Called after the configuration has been read and will trigger buttons events
    if a pio has been pressed or held whilst the configuration was still being loaded
    , i.e. the power on button press    
*/
void ButtonsCheckForChangeAfterInit(void)
{        
    uint32 pio_state;

    ButtonsTaskData * lButtonsTask = theHeadset.theButtonsTask ;
      
    lButtonsTask->gBTime = B_INVALID ; 
    
    {
        /* get 32 bit pio state for BC5 onwards chips */
        pio_state = (((PIOGET() & 0xffff) | CHARGER_VREG_VALUE | CHARGER_CONNECT_VALUE)) ;
        
        /* perform a level detect looking for transistion of recently added button definition, mask pio's 
           against level configured pios to prevent false butotn press indications */
        ButtonsLevelDetect ( (pio_state & lButtonsTask->gPerformLevelCheck) , lButtonsTask ) ;
    
        /* perform an edge detect looking for transistion of recently added button definition, mask pio's 
           against edge configured pios to prevent false button press indications */
        ButtonsEdgeDetect ( (pio_state & lButtonsTask->gPerformEdgeCheck) , lButtonsTask) ;
    }
    
    /* store current set pio state in order to be able to detect the transition of a PIO in the button handler */
    lButtonsTask->gOldPioState = pio_state;
            
    /* Debounce required PIO lines */
    pio_state = PioDebounce32((0xFFFF & lButtonsTask->gButtonLevelMask),  /* mask off upper 16 bits */
                              lButtonsTask->button_config->debounce_number, 
                              lButtonsTask->button_config->debounce_period_ms );    
    
    /* check whether it has been possible to select the use of PIOs specified, if it was not possible
       to use all the PIOs specified due to a PIO being assigned a different function by PSKEY then none 
       of the PIOs will now work so mask out the unavailable PIO and assign the PIOs that are available
       for receiving change notifications */
    if(pio_state)
    {
        /* mask out the unavailable PIOs and register those PIOs that are available for receiving change events */
        PioDebounce32((0xFFFF & lButtonsTask->gButtonLevelMask & ~pio_state),  /* mask off upper 16 bits */
                              lButtonsTask->button_config->debounce_number, 
                              lButtonsTask->button_config->debounce_period_ms );           

        B_DEBUG(("B: **** ERROR **** PIO NOT AVAILABLE = 0x%lx\n",pio_state)) ;

#ifdef DEBUG_BUTTONS
        Panic();
#endif
    }

#ifdef BHC612_
	ChargerDebounce( (CHARGER_VREG_EVENT|CHARGER_CONNECT_EVENT), 4, 250 );
#else
    ChargerDebounce( (CHARGER_VREG_EVENT|CHARGER_CONNECT_EVENT), lButtonsTask->button_config->debounce_number, lButtonsTask->button_config->debounce_period_ms );
#endif    
} 
Beispiel #2
0
/****************************************************************************
DESCRIPTION
    Called after the configuration has been read and will trigger buttons events
    if a pio has been pressed or held whilst the configuration was still being loaded
    , i.e. the power on button press    
*/
void ButtonsCheckForChangeAfterInit(void)
{        
    uint32 input_state; /* contains translated pio and capsense bits, format is inputs */

    ButtonsTaskData * lButtonsTask = theSink.theButtonsTask ;
      
    lButtonsTask->gBTime = B_INVALID ;   

    /* translate the pio and capsense bits into 'input' bits mask */
#ifdef ENABLE_CAPSENSE
    input_state = ButtonsTranslate(lButtonsTask->gOldCapState, (((PIOGET()^theSink.conf1->PIOIO.pio_invert) | CHARGER_VREG_VALUE | CHARGER_CONNECT_VALUE)));
#else    
    input_state = ButtonsTranslate(0, (((PIOGET()^theSink.conf1->PIOIO.pio_invert) | CHARGER_VREG_VALUE | CHARGER_CONNECT_VALUE)));
#endif
    /* perform a level detect looking for transistion of recently added button definition, mask inputs 
       against level configured inputs to prevent false button press indications */
    ButtonsLevelDetect ( (input_state & lButtonsTask->gPerformInputLevelCheck) , lButtonsTask ) ;
    
    /* perform an edge detect looking for transistion of recently added button definition, mask inputs 
       against edge configured inputs to prevent false button press indications */
    ButtonsEdgeDetect ( (input_state & lButtonsTask->gPerformInputEdgeCheck) , lButtonsTask) ;
    
    /* store current input states in order to be able to detect the transition of an input (pio or capsense)
       in the button handler */
    lButtonsTask->gBOldInputState = input_state;

    /* Debounce required PIO lines */
    if(!PioCommonDebounce((lButtonsTask->gButtonPIOLevelMask & ~(VREG_PIN_MASK|CHG_PIN_MASK)),  
                           lButtonsTask->button_config->debounce_number, 
                           lButtonsTask->button_config->debounce_period_ms ))
    {
        B_DEBUG(("B: **** ERROR **** PIO NOT AVAILABLE = 0x%lx\n",input_state)) ;
#ifdef DEBUG_BUTTONS
        Panic();
#endif

    }
    
    ChargerDebounce( (CHARGER_VREG_EVENT|CHARGER_CONNECT_EVENT), lButtonsTask->button_config->debounce_number, lButtonsTask->button_config->debounce_period_ms );
    B_DEBUG(("B: initial buttoncheck\n")) ;
    
} 
Beispiel #3
0
/****************************************************************************

DESCRIPTION
    function to detect edge changes of buttons / multiple buttons. 

*/ 
static void ButtonsCheckDetection(uint16 CapSenseState, uint32 PioState)
{   
    ButtonsTaskData * lBTask = theSink.theButtonsTask ;
    
    /* take the current capacitive touch state and pio state and translate into a uint32
       input state used for checking button presses */
    uint32 lInputState = ButtonsTranslate(CapSenseState, PioState);

    B_DEBUG(("But CheckDet: Inputs: Cap[%x] PIO[%lx] Inputs[%lx] OldState[%lx]\n", CapSenseState , PioState , lInputState, lBTask->gBOldInputState)) ;
    B_DEBUG(("But CheckDet: Masks:  Edge [%lx] Lev [%lx]\n",lBTask->gPerformInputEdgeCheck, lBTask->gPerformInputLevelCheck));

    /* when an input is configured for an edge detect only there is significant performance gain to be had
       by only doing an edge detect call and not a level detect. To do this use a previously set edge
       detect mask and check this against the current pio being reported. Also need to check if a previously
       set PIO has now been removed and check for the edge transition once again. */
    if((lBTask->gPerformInputEdgeCheck & lInputState) ||
       (lBTask->gPerformInputEdgeCheck & lBTask->gBOldInputState))
    {
        /* check for a valid edge transition against current pio states masked with edge configured pios
           and perform appropriate action */                
        ButtonsEdgeDetect  ( lInputState, lBTask ) ;
    }          
            
    /* only do a level detect call which is vm/messaging intensive when a pio has been configured as 
       short or long or very long or very very long, i.e. not rising or falling */
    if((lBTask->gPerformInputLevelCheck & lInputState ) ||
       (lBTask->gPerformInputLevelCheck & lBTask->gBOldInputState))
    {
        /* perform a level detection, this call uses a number of messages and is quite slow to process */
        ButtonsLevelDetect ( lInputState, lBTask) ;            
    }         

#ifdef ENABLE_GAIA
    gaiaReportPioChange(PioState);
#endif

    /* update last button state for next time around */
    lBTask->gBOldInputState = lInputState;
    lBTask->gOldPIOState = PioState;
}
Beispiel #4
0
static void ButtonsMessageHandler ( Task pTask, MessageId pId, Message pMessage ) 
{   
    ButtonsTaskData * lBTask = (ButtonsTaskData*)pTask ;

    B_DEBUG(("B:Message\n")) ;
    switch ( pId )
    {
	    case MESSAGE_PIO_CHANGED : 
        {
            const MessagePioChanged * lMessage = ( const MessagePioChanged * ) (pMessage ) ;
            uint32 lNewPioState = (uint32)( lMessage->state | CHARGER_VREG_VALUE | CHARGER_CONNECT_VALUE) ;
            
            B_DEBUG(("B:BMH - PIO_CHANGE: %x %x\n",lMessage->state16to31, lMessage->state)) ;
            
        
            /* when a pio is configured for an edge detect only there is significant performance gain to be had
               by only doing an edge detect call and not a level detect. To do this use a previously set edge
               detect mask and check this against the current pio being reported. Also need to check if a previously
               set PIO has now been removed and check for the edge transition once again. */
            if((lBTask->gPerformEdgeCheck & lNewPioState) ||
               (lBTask->gPerformEdgeCheck & lBTask->gOldPioState))
            {
                /* check for a valid edge transition against current pio states masked with edge configured pios
                   and perform appropriate action */                
                ButtonsEdgeDetect  ( (uint32)( lNewPioState & lBTask->gPerformEdgeCheck), lBTask ) ;
            }          
            
            /* only do a level detect call which is vm/messaging intensive when a pio has been configured as 
               short or long or very long or very very long, i.e. not rising or falling */
            if((lBTask->gPerformLevelCheck & lNewPioState ) ||
               (lBTask->gPerformLevelCheck & lBTask->gOldPioState))
            {
                /* perform a level detection, this call uses a number of messages and is quite slow to process */
                ButtonsLevelDetect ( ((uint32)lNewPioState & lBTask->gPerformLevelCheck) , lBTask) ;            
            }         
            
            /* store current set pio state in order to be able to detect the transition of a PIO configured as edge 
               detect only */
            lBTask->gOldPioState = lNewPioState ;
        
        }
    	break ;
        
        case MESSAGE_CHARGER_CHANGED:
	    {
		    const MessageChargerChanged *m = (const MessageChargerChanged *) (pMessage ) ;			
         
            /* when a charger or vreg change event is detectecd perform both an edge and level detection
               passing in only those approriately masked pios for edge or level configured buttons */
            ButtonsLevelDetect ( (((uint32)m->vreg_en_high << VREG_PIN) | ((uint32)m->charger_connected << CHG_PIN) | PIOGET()) & lBTask->gPerformLevelCheck , lBTask) ;           
            ButtonsEdgeDetect  ( (((uint32)m->vreg_en_high << VREG_PIN) | ((uint32)m->charger_connected << CHG_PIN) | PIOGET()) & lBTask->gPerformEdgeCheck , 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")) ;
            
            /* an internal timer has triggered which was initiated from the level detect function call */
        	if ( lBTask->gBTime == B_VERY_LONG )
        	{
                /* update timer state flag */
                lBTask->gBTime = B_VERY_VERY_LONG ;                
        	}
			/* a long press timer event has triggered */
            else if ( lBTask->gBTime == B_LONG )
        	{
                /* don't send very very long timer message until needed, i.e. very_long timer expired */
                MessageSendLater ( &lBTask->task , B_INTERNAL_TIMER , 0 ,  (lBTask->button_config->very_very_long_press_time - lBTask->button_config->very_long_press_time ) ) ;                   
                /* update tiemr state flag */
            	lBTask->gBTime = B_VERY_LONG ;
               	/*notify the app that the timer has expired*/
            	MessageSend( &theHeadset.task , EventVLongTimer , 0 ) ;    
        	}
			/* the first timer event triggered from the level detect call */
            else
        	{
                /* only send very long message when long timer expired to save messaging.                 */
                MessageSendLater ( &lBTask->task , B_INTERNAL_TIMER , 0 , (lBTask->button_config->very_long_press_time - lBTask->button_config->long_press_time)) ;
               	/*notify the app that the timer has expired*/
            	MessageSend( &theHeadset.task , 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[%lx][%x]\n", lBTask->gBOldState , B_REPEAT  )) ;
        
        	/*send another repeat message*/
        	MessageSendLater ( &lBTask->task , B_REPEAT_TIMER , 0 ,  lBTask->button_config->repeat_time ) ; 

        	ButtonsButtonDetected ( lBTask, lBTask->gBOldState , B_REPEAT ); 
		}
        break;
    	default :
           B_DEBUG(("B:?[%x]\n",pId)) ; 
        break ;
    }
}