📄 am_timer_container.cc
字号:
/* (c) Copyright Motorola 1996-2005, All rights reserved. Motorola Confidential Proprietary Contains confidential proprietary information of Motorola, Inc. Reverse engineering is prohibited. The copyright notice does not imply publication. DESCRIPTION: This function contains the AM Application Layer main driver routines. These functions build up information for the hardware layer, and then all at once, pass it to the hardware layer. *************** REVISION HISTORY ********************************************* Date Author Reference ======== ======== ========================== 2005-03-09 w16355 CR - LIBff73889 BT_AUDIO_LOOPBACK Failure in GNPO. 2004-12-06 w16355 CR - LIBff38607 AUDIO_LOW_POWER is randomly set in suspend mode. 1999-11-10 bchoi CR - CSGce39480 Modify Audio Manager timer functionality to use SUAPI compliant timers.******************************************************************************/#include <audio/AM_Timer_Container.H>#include <audio/AM_HW_Primitive_Builder.H>#include <ENGINE_AUDIO/am_c_utilities.h>/************** GLOBAL CONSTANTS *********************************************/extern BOOL am_suspend;//===============================================================================// Global Declaration for the AM // No time to encapsulate, hate to do this, but necessary for time//===============================================================================AM_Timer_Container am_timer_handler; //===============================================================================// Function:Constructor //// Initialize all the pointers, SUAPI will panic if any of the suapi calls// fails, thats why I don't check the outcome// I would use a cyclical timer, but I can't find a good definition,,, CHANGE THIS TO A CYCLical timer.//===============================================================================AM_Timer_Container::AM_Timer_Container(){ SU_RET_STATUS err = 0; HeadPtr = NULL;}//===============================================================================// Function:Initialize//// Can't figure out why they don't like allocating memory, so the constructor// can not get teh SUAPI resources. the OS is not ready when the static thunks// are created. So run them in the task.//===============================================================================void AM_Timer_Container::Initialize(){ SU_RET_STATUS err = 0; TaskHandle = suGetSelfHandle(); TimerHandle = suCreateTimer(&err); TimerEventNumber = suAllocEvent(&err); ImmediateTimerEventNumber = suAllocEvent(&err); TimerEventMask = suEvnumToEvmask(TimerEventNumber); ImmediateTimerEventMask = suEvnumToEvmask(ImmediateTimerEventNumber);}//===============================================================================// Function Destructor://// This should never get called , but you never know. Return the timer// and the 2 events back to suapi.//===============================================================================AM_Timer_Container::~AM_Timer_Container(){ SU_RET_STATUS err = 0; suDeleteTimer(TimerHandle, &err); suFreeEvent(TimerEventNumber); suFreeEvent(ImmediateTimerEventNumber); }//===============================================================================// Function TickTock:// Loop thru everyone in our list and try to expire their timers.// If they return TRUE for the expiration, remove them from our list// Kick of the timer when we are done. Again. A cyclical timer would be nice...//===============================================================================#if (AUDIO_RAINBOW == TRUE)void AM_Timer_Container::TickTock(SU_PAL_TICKS time)#elsevoid AM_Timer_Container::TickTock(SU_TICKS time)#endif{ AM_Timer_Base *tmp = HeadPtr; AM_Timer_Base *current = NULL; while(tmp) { current = tmp; tmp = tmp->Next; Stop(current); // remove it from our list for the execution. If we want it back we will insert it again. if(current->Expired(time) == 0) { ReInsert(current); } } StartTimer(TICKS_PER_EVENT);}int AM_Timer_Container::ReInsert(AM_Timer_Base *timer){ if(HeadPtr != NULL) { HeadPtr->Prev = timer; timer->Next = HeadPtr; timer->Prev = NULL; HeadPtr = timer; } else { HeadPtr = timer; } return 0;}//===============================================================================// Function Start// Start this timer object// First determine if someone is trying to start a tiemr that is already active// if they are then just restart the sequence because they are already in our list.// NOTE: If StartSequence returns anything other than 0,// that means that we want to trigger an instantaneous timer or ZERO time//===============================================================================int AM_Timer_Container::Start(AM_Timer_Base *timer){ if(!timer->IsActive()) { if(HeadPtr != NULL) { HeadPtr->Prev = timer; timer->Next = HeadPtr; timer->Prev = NULL; HeadPtr = timer; if(timer->StartSequence()) { StartTimer(0); } } else { HeadPtr = timer; if(timer->StartSequence()) { StartTimer(0); } else { StartTimer(TICKS_PER_EVENT); } } } else { if(timer->StartSequence()) { StartTimer(0); } } return 0;}//===============================================================================// Function Stop// Stop this timer object, // First make sure its in our list and the remove it////===============================================================================int AM_Timer_Container::Stop(AM_Timer_Base *timer){ timer->SetActive(FALSE); if(HeadPtr == NULL) { return 1; /// abort..... something strange, someone requested to remove the link and nothing is there. } if(timer == HeadPtr) { HeadPtr = HeadPtr->Next; if(HeadPtr != NULL) { HeadPtr->Prev = NULL; } timer->Prev = NULL; timer->Next = NULL; return 0; } if(timer->Prev == NULL) { return 1; // another strange thing, your not in the list } timer->Prev->Next = timer->Next; // have the timers previous point to the next one in line. if(timer->Next != NULL) { timer->Next->Prev = timer->Prev; } timer->Prev = NULL; timer->Next = NULL; return 0;}//===============================================================================//Function: GetEventMask// return the mask for all events that the container is looking for.//===============================================================================SU_EVMASK AM_Timer_Container::GetEventMask(){ return TimerEventMask | ImmediateTimerEventMask;}//===============================================================================// Function HandleEvents// Entry point from the tasks perspective// This may have to change depending on how the task is structured// but basically The application task should get the events that it is waiting// on and pass them into the Handle Events. // Should we clear the mask after evaluation?// Implementation if the Timer event occurs, the clear both, theres no// reason to do it twice.//===============================================================================void AM_Timer_Container::HandleEvents(SU_EVMASK events){ // Ignore all timer expirations while we are suspended. // If Audio Manager runs it can interfere with audio // setup issued by the Test Command task. if ( am_suspend == FALSE ) { if(events & TimerEventMask) { TickTock(TICKS_PER_EVENT); } else if (events & ImmediateTimerEventMask) { TickTock(0); } else if ( events & am_event_mask ) { AM_HW_Primitive_Builder::aud_keypress_timer_expiry(); } }}//===============================================================================// Function StartTimer// Start a timer, if the ticks sent in is 0, then set our event immediately//===============================================================================#if (AUDIO_RAINBOW == TRUE)int AM_Timer_Container::StartTimer(SU_PAL_TICKS ticks)#elseint AM_Timer_Container::StartTimer(SU_TICKS ticks)#endif{ SU_RET_STATUS err = 0; if(HeadPtr != NULL) { if(ticks == 0) { suSetEventMask(TaskHandle, ImmediateTimerEventMask,&err); } else { suStartEventTimer(TimerHandle, TICKS_PER_EVENT, TaskHandle, TimerEventMask, &err); } } return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -