📄 headset_leds.c
字号:
/****************************************************************************Copyright (C) Cambridge Silicon Radio Ltd. 2004-2006Part of BlueLab 3.5.2-releaseFILE NAME headset_LEDs.c DESCRIPTION Module responsible for managing the LED outputs and the pios configured as led outputs */#include "headset_leds.h"#include "headset_private.h"#include "headset_LEDmanager.h"#include "headset_statemanager.h"#include "headset_pio.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 /*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 bool LedsGetLEDStateFromPattern ( LedTaskData * pLEDTask , const LEDPattern_t * pPattern , const LEDActivity_t * pLED ) ;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 ) ;static void LedsCancelStateIndications ( LedTaskData * pLedTask ) ;static void LedsCancelEventIndications ( LedTaskData * pLEDTask ) ;/***********************************************************************/static bool gFollowing = FALSE ;static bool LedsCheckFiltersForLEDFollower( LedTaskData * pLEDTask ) ;static uint16 LedsGetLedFollowerRepeatTimeLeft( LedTaskData * pLEDTask , LEDPattern_t* pPattern) ;static uint16 LedsGetFollowerPin( LedTaskData * pLEDTask ) ;static uint16 LedsGetLedFollowerStartDelay( LedTaskData * pLEDTask ) ;/***********************************************************************/void LedsInit ( LedTaskData * pTask ) { /*Set the callback handler for the task*/ pTask->task.handler = LedsMessageHandler ; pTask->gCurrentlyIndicatingEvent = FALSE ;}/****************************************************************************NAME LedsIndicateEventDESCRIPTION THis function starts an event notification. It overides any prior ent notification acting on the same PIO It also overides any state notification on the same PIO. If a state indication is happening on a different pio, this will be allowed to continue.RETURNS void */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 )) ; LMPrintPattern ( pLEDTask->gEventPatterns [lEventIndex] ) ; /*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*/ LedsCancelStateIndications ( 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 ) ; /*Set the Alternative LED up with the same info*/ LedsSetLedActivity ( &pLEDTask->gActiveLEDS[lSecondaryLED] , IT_EventIndication , lEventIndex ) ; /*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 ; }} /****************************************************************************NAME LedsCheckForFilterDESCRIPTION This function checksif a filter has been configured for the given event, if it has then activates / deactivates the filter Regardless of whether a filter has been activated or not, the event is signalled as completed as we have now deaklt with it (only checked for a filter if a pattern was not associated.RETURNS void */ 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 ) { 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) ; } } } else { LED_DEBUG(("LED: Fil !\n")) ; } } LED_DEBUG(("LM : Filter Found[%d]A[%x] [%d]\n", lFilterIndex , pEvent , pLEDTask->gEventFilters[ lFilterIndex ].IsFilterActive )) ; } } /*there was no pattern event configured indicate that we have dealt with the event and there was no pattern associated *//* LedsSendEventComplete ( pEvent , FALSE) ;*/}/****************************************************************************NAME LEDManagerIndicateStateDESCRIPTION This function kicks off a state indication. It cancels any previous state indication but does not overide an event indication. RETURNS void */void LedsIndicateState ( LedTaskData * pLEDTask , headsetState pState ) { uint16 lPrimaryLED = 0; uint16 lSecondaryLED = 0 ; LEDPattern_t * lPattern = pLEDTask->gStatePatterns[pState] ; LMPrintPattern( lPattern ) ; lPrimaryLED = lPattern->LED_A; lSecondaryLED = lPattern->LED_B; LED_DEBUG(("LED: st[%x][%x]", pLEDTask->gActiveLEDS[lPrimaryLED].Type , pLEDTask->gActiveLEDS[lSecondaryLED].Type)) ; /*only indicate state if both leds we want to use are not currently indicating an event*/ if ( ( pLEDTask->gActiveLEDS[lPrimaryLED].Type != IT_EventIndication ) && ( pLEDTask->gActiveLEDS[lSecondaryLED].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*/ LedsCancelStateIndications ( pLEDTask ) ; /*Set up the Active LED with the State we want to indicate*/ LedsSetLedActivity ( &pLEDTask->gActiveLEDS[lPrimaryLED] , IT_StateIndication , pState ) ; /*Set the Alternative LED up with the same info*/ LedsSetLedActivity ( &pLEDTask->gActiveLEDS[lSecondaryLED] , IT_StateIndication , pState ) ; /* - 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[lPrimaryLED].Type , pLEDTask->gActiveLEDS[lSecondaryLED].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[lPrimaryLED] ) ; } 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 , lPrimaryLED , 0 , LEDS_STATE_START_DELAY_MS ) ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -