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

📄 headset_leds.c

📁 bc5_stereo:bluetooth stereo Headset CODE 支持A2DP HSP 和 HSP 。可作为车载免提。BlueLab 2007环境下编译
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004-2007

FILE NAME
    headset_leds.c
    
DESCRIPTION
    Module responsible for managing the LED outputs and the pios 
    configured as led outputs.
    
*/


#include "headset_LEDmanager.h"
#include "headset_leds.h"
#include "headset_pio.h"
#include "headset_private.h"
#include "headset_statemanager.h"

#include <charger.h>
#include <panic.h>
#include <stddef.h>


#ifdef DEBUG_LEDS
#define LED_DEBUG(x) DEBUG(x)
#else
#define LED_DEBUG(x) 
#endif



#define LED_ON  TRUE    
#define LED_OFF FALSE

#define LEDS_STATE_START_DELAY_MS 300


/****************************************************************************
    LOCAL FUNCTION PROTOTYPES
*/

 /*internal message handler for the LED callback messages*/
static void LedsMessageHandler( Task task, MessageId id, Message message ) ;

 /*helper functions for the message handler*/
static uint16 LedsApplyFilterToTime     ( LedTaskData * pLEDTask , uint16 pTime )  ;
static LEDColour_t LedsGetPatternColour ( LedTaskData * pLEDTask , const LEDPattern_t * pPattern ) ;

 /*helper functions to change the state of LED pairs depending on the pattern being played*/
static void LedsTurnOffLEDPair ( LedTaskData * pLEDTask , LEDPattern_t * pPattern, bool pUseOveride  ) ;
static void LedsTurnOnLEDPair  ( LedTaskData * pLEDTask , LEDPattern_t * pPattern , LEDActivity_t * pLED );

    /*method to complete an event*/
static void LedsEventComplete ( LedTaskData * pLEDTask, LEDActivity_t * pPrimaryLed , LEDActivity_t * pSecondaryLed ) ;
    /*method to indicate that an event has been completed*/
static void LedsSendEventComplete ( headsetEvents_t pEvent , bool pPatternCompleted ) ;

    /*filter enable - check methods*/
static bool LedsIsFilterEnabled ( LedTaskData * pLEDTask , uint16 pFilter ) ;
static void LedsEnableFilter ( LedTaskData * pLEDTask ,  uint16 pFilter , bool pEnable) ;

static void LedsHandleOverideLED ( LedTaskData * pLEDTask , bool pOnOrOff ) ;

	/*Follower LED helper functions*/
static bool LedsCheckFiltersForLEDFollower( LedTaskData * pLEDTask ) ;

static uint16 LedsGetLedFollowerRepeatTimeLeft( LedTaskData * pLEDTask , LEDPattern_t* pPattern) ;

static uint16 LedsGetFollowerPin( LedTaskData * pLEDTask ) ;

static uint16 LedsGetLedFollowerStartDelay( LedTaskData * pLEDTask ) ;

static void LedsSetEnablePin ( LedTaskData * pLEDTask , bool pOnOrOff ) ;


/****************************************************************************
  FUNCTIONS
*/

/*****************************************************************************/
void LedsInit ( LedTaskData * pTask ) 
{
        /*Set the callback handler for the task*/
    pTask->task.handler = LedsMessageHandler ;
    
    pTask->gCurrentlyIndicatingEvent = FALSE ;
    	/*set the tricolour leds to known values*/
    pTask->gTriColLeds.TriCol_a = 0 ;
    pTask->gTriColLeds.TriCol_b = 0 ;
    pTask->gTriColLeds.TriCol_c = 0 ;
    
    pTask->gFollowing = FALSE ; 
    
    /*Disable the built-in charger indications*/
	ChargerSupressLed0(TRUE);
}


/*****************************************************************************/
void LedsIndicateEvent ( LedTaskData * pLEDTask , headsetEvents_t pEvent ) 
{ 
    uint16 lPrimaryLED = 0;
    uint16 lSecondaryLED = 0;
    
    uint16 lEventIndex = pEvent - EVENTS_EVENT_BASE ; 

        /*get the event and start the display*/
    lPrimaryLED     = pLEDTask->gEventPatterns[lEventIndex]->LED_A;
    lSecondaryLED   = pLEDTask->gEventPatterns[lEventIndex]->LED_B;
    
    LED_DEBUG(("LM : Ev LED [%x]i[%x] ", pEvent , lEventIndex )) ;
    #ifdef DEBUG_LM
    	LMPrintPattern ( pLEDTask->gEventPatterns [lEventIndex] ) ;
    #endif    
            /*if the PIO we want to use is currently indicating an event then do interrupt the event*/
    MessageCancelAll ( &pLEDTask->task, lPrimaryLED ) ;
    MessageCancelAll ( &pLEDTask->task, lSecondaryLED ) ;
   
        /*cancel all led state indications*/
    LedsIndicateNoState (  pLEDTask ) ; 
    
        /* - need to set the LEDS to a known state before starting the pattern*/
    LedsTurnOffLEDPair ( pLEDTask , pLEDTask->gEventPatterns[lEventIndex] , TRUE) ;

            /*now set up and start the event indication*/
    LedsSetLedActivity ( &pLEDTask->gActiveLEDS[lPrimaryLED] , IT_EventIndication , lEventIndex  , pLEDTask->gEventPatterns[lEventIndex]->DimTime ) ;
        /*Set the Alternative LED up with the same info*/
    LedsSetLedActivity ( &pLEDTask->gActiveLEDS[lSecondaryLED] , IT_EventIndication , lEventIndex , pLEDTask->gEventPatterns[lEventIndex]->DimTime ) ;

        
        /*if we just want to set a pin as an output (numFlashes == 0) - then dont send a message*/
    LED_DEBUG(("LM : NF[%x]\n" , pLEDTask->gEventPatterns [ lEventIndex ]->NumFlashes )) ;
    if ( pLEDTask->gEventPatterns [ lEventIndex ]->NumFlashes == 0 )
    {
            /*set the pins on or off as required*/
        if ( pLEDTask->gEventPatterns [ lEventIndex ]->OnTime > 0 )
        {
            LED_DEBUG(("LM : PIO_ON\n")) ;
            LedsTurnOnLEDPair ( pLEDTask , pLEDTask->gEventPatterns [ lEventIndex ] , &pLEDTask->gActiveLEDS[lPrimaryLED]  ) ;
        }
        else if ( pLEDTask->gEventPatterns [ lEventIndex ]->OffTime > 0 )
        {
            LED_DEBUG(("LM : PIO_OFF\n")) ;
            LedsTurnOffLEDPair ( pLEDTask , pLEDTask->gEventPatterns [ lEventIndex ] ,TRUE) ;
          
              /*If we are turning a pin off the revert to state indication*/
            LedsEventComplete ( pLEDTask, &pLEDTask->gActiveLEDS[lPrimaryLED] , &pLEDTask->gActiveLEDS[lSecondaryLED] ) ;
        }   
    }
    else
    {   /*start the pattern indication*/  /*All messages are handled via the primary LED*/
	    MessageSend (&pLEDTask->task , lPrimaryLED , 0 ) ;        
        pLEDTask->gCurrentlyIndicatingEvent = TRUE ;
    }
}

   
/*****************************************************************************/
void LedsIndicateState ( LedTaskData * pLEDTask , headsetHfpState pState , headsetA2dpState pA2dpState ) 
{ 
    uint16 led_state = pState + (HEADSET_NUM_HFP_STATES * pA2dpState);
    LEDPattern_t * lPattern = pLEDTask->gStatePatterns[led_state] ;

    #ifdef DEBUG_LM
    	LMPrintPattern( lPattern ) ;
    #endif
        
    
    LED_DEBUG(("LED: st[%x][%x]", pLEDTask->gActiveLEDS[lPattern->LED_A].Type , pLEDTask->gActiveLEDS[lPattern->LED_B].Type)) ;

        /*only indicate state if both leds we want to use are not currently indicating an event*/
    if (    ( pLEDTask->gActiveLEDS[lPattern->LED_A].Type   != IT_EventIndication  )
         && ( pLEDTask->gActiveLEDS[lPattern->LED_B].Type != IT_EventIndication  ) )
    {
        LED_DEBUG(("LED: IS : OK\n")) ;
            /*Find the LEDS that are set to indicate states and Cancel the messages,
              -do not want to indicate more than one state at a time*/
        LedsIndicateNoState (  pLEDTask ) ;
        
           /*Set up the Active LED with the State we want to indicate*/
        LedsSetLedActivity ( &pLEDTask->gActiveLEDS[lPattern->LED_A] , IT_StateIndication , led_state , lPattern->DimTime ) ;
            /*Set the Alternative LED up with the same info*/
        LedsSetLedActivity ( &pLEDTask->gActiveLEDS[lPattern->LED_B] , IT_StateIndication , led_state ,lPattern->DimTime) ;

            /* - need to set the LEDS to a known state before starting the pattern*/
        LedsTurnOffLEDPair ( pLEDTask , lPattern , TRUE ) ;

        LED_DEBUG(("LED: st2[%x][%x]", pLEDTask->gActiveLEDS[lPattern->LED_A].Type , pLEDTask->gActiveLEDS[lPattern->LED_B].Type)) ;


            /*Handle permanent output leds*/
        if ( lPattern->NumFlashes == 0 )
        {
            /*set the pins on or off as required*/
            if ( lPattern->OnTime > 0 )
            {
                LED_DEBUG(("LM :ST PIO_ON\n")) ;
                LedsTurnOnLEDPair ( pLEDTask ,lPattern , &pLEDTask->gActiveLEDS[lPattern->LED_A]  ) ;
            }
            else if ( lPattern->OffTime > 0 )
            {
                LED_DEBUG(("LM :ST PIO_OFF\n")) ;
                LedsTurnOffLEDPair ( pLEDTask , lPattern ,TRUE) ;
            }   
        }
        else
            /*send the first message for this state LED indication*/ 
        MessageSendLater (&pLEDTask->task , lPattern->LED_A , 0 , LEDS_STATE_START_DELAY_MS ) ;
    }
}


/*****************************************************************************/
void LedsIndicateNoState ( LedTaskData * pLEDTask  )  
{
     /*Find the LEDS that are set to indicate states and Cancel the messages,
    -do not want to indicate more than one state at a time*/
    uint16 lLoop = 0;
    
    for ( lLoop = 0 ; lLoop < HEADSET_NUM_LEDS ; lLoop ++ )
    {
        if (pLEDTask->gActiveLEDS[lLoop].Type == IT_StateIndication)
        {
            MessageCancelAll ( &pLEDTask->task, lLoop ) ; 
            pLEDTask->gActiveLEDS[lLoop].Type =  IT_Undefined ;
            
            LED_DEBUG(("LED: CancelStateInd[%x]\n" , lLoop)) ;
            LedsTurnOffLEDPair ( pLEDTask , pLEDTask->gStatePatterns[pLEDTask->gActiveLEDS[lLoop].Index] ,TRUE) ;
        }
    }
}


/*****************************************************************************/
bool LedsStateCanOverideDisable ( LedTaskData * pLEDTask , headsetHfpState pState , headsetA2dpState pA2dpState ) 
{
    uint16 led_state = pState + (HEADSET_NUM_HFP_STATES * pA2dpState);
    LEDPattern_t * lPattern = pLEDTask->gStatePatterns[led_state] ;
    if (lPattern != NULL)
        return lPattern->OverideDisable;
    else
        return FALSE;
}


/*****************************************************************************/
bool LedsEventCanOverideDisable ( LedTaskData * pLEDTask , MessageId pEvent ) 
{
    LEDPattern_t * lPattern = pLEDTask->gEventPatterns[pEvent - EVENTS_EVENT_BASE] ;
    if (lPattern != NULL)
    {
        return lPattern->OverideDisable;
    }
    else
        return FALSE;
}


/*****************************************************************************/
bool LedActiveFiltersCanOverideDisable( LedTaskData *pLEDTask )
{
    uint16 lFilterIndex ;
    
    for (lFilterIndex = 0 ; lFilterIndex< LM_NUM_FILTER_EVENTS ; lFilterIndex++ )
    {
        if ( LedsIsFilterEnabled(pLEDTask , lFilterIndex) )
        {
            /* check if this filter overides LED disable flag */
            if ( pLEDTask->gEventFilters[lFilterIndex].OverideDisable)
                return TRUE;
        }
    }
    return FALSE;
}


/*****************************************************************************/       
void LedsCheckForFilter ( LedTaskData * pLEDTask , headsetEvents_t pEvent ) 
{
    uint16 lFilterIndex = 0 ;
    
    for (lFilterIndex = 0 ; lFilterIndex < pLEDTask->gLMNumFiltersUsed ; lFilterIndex ++ )
    { 
        if ( pLEDTask->gEventFilters[ lFilterIndex ].Event == pEvent )
        {
            if (pLEDTask->gEventFilters[ lFilterIndex ].IsFilterActive)
            {
                /* Check filter isn't already enabled */
                if (!LedsIsFilterEnabled(pLEDTask , lFilterIndex))
                {
                    /* Enable filter */
                    LedsEnableFilter (pLEDTask , lFilterIndex , TRUE) ;

                    /* If it is an overide fLED filter and the currently playing pattern is OFF then turn on the overide led immediately*/
                    if ( pLEDTask->gEventFilters [ lFilterIndex].OverideLEDActive )
                    {
                        uint16 lOverideLEDIndex = pLEDTask->gEventFilters[ lFilterIndex].OverideLED ;                    
                        /* this should only happen if the led in question is currently off*/
                        if ( pLEDTask->gActiveLEDS[lOverideLEDIndex].OnOrOff == LED_OFF)
                        {
                             PioSetLedPin ( pLEDTask , lOverideLEDIndex , LED_ON) ;
                        }
                    }
                }
            }
            else
            {
                 uint16 lFilterToCancel = pLEDTask->gEventFilters[ lFilterIndex ].FilterToCancel ;
                /*disable the according filter*/
                 if ( lFilterToCancel != 0 )
                 {
                     uint16 lFilterToCancelIndex = lFilterToCancel - 1 ;
                     uint16 lOverideLEDIndex = pLEDTask->gEventFilters[ lFilterToCancelIndex ].OverideLED ;
                    
                     LED_DEBUG(("LED: FilCancel[%d][%d] [%d]\n",lFilterIndex + 1 , lFilterToCancel , lFilterToCancelIndex )) ;
                     
                        /*lFilter To cancel = 1-n, LedsEbnable filter requires 0-n */
                     LedsEnableFilter (pLEDTask , lFilterToCancelIndex , FALSE ) ;
                     
                     if ( pLEDTask->gActiveLEDS[lOverideLEDIndex].OnOrOff == LED_OFF)
                     {   /*  LedsHandleOverideLED ( pLEDTask , LED_OFF) ;*/
                         if ( pLEDTask->gEventFilters [ lFilterToCancelIndex].OverideLEDActive )
                         {
	          	             PioSetLedPin ( pLEDTask , pLEDTask->gEventFilters[lFilterToCancelIndex].OverideLED , LED_OFF) ;                
                         }    
                     }                           

⌨️ 快捷键说明

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