This repository has been archived on 2025-02-28. You can view files and clone it, but cannot push or open issues or pull requests.
controller-hd/User/lib/lcd/gui/Core/GUITimer.c

274 lines
7.1 KiB
C

/*
*********************************************************************************************************
* uC/GUI
* Universal graphic software for embedded applications
*
* (c) Copyright 2002, Micrium Inc., Weston, FL
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
* µC/GUI is protected by international copyright laws. Knowledge of the
* source code may not be used to write a similar product. This file may
* only be used in accordance with a license and should not be redistributed
* in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File : GUITimer.c
Purpose : Supplies timers
----------------------------------------------------------------------
---------------------------END-OF-HEADER------------------------------
*/
#include <stddef.h> /* needed for definition of NULL */
#include "GUI_Protected.h"
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define GUI_TIMER_H2P(h) (GUI_TIMER_Obj*)GUI_ALLOC_h2p(h)
/*********************************************************************
*
* Types
*
**********************************************************************
*/
typedef struct {
GUI_TIMER_CALLBACK* cb;
GUI_TIMER_HANDLE hNext;
int Flags;
U32 Context;
GUI_TIMER_TIME t0;
GUI_TIMER_TIME Period;
} GUI_TIMER_Obj;
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
GUI_TIMER_HANDLE hFirstTimer;
GUI_TIMER_HANDLE _hActiveTimer;
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _Unlink
*/
static void _Unlink(GUI_TIMER_HANDLE hTimer) {
GUI_TIMER_Obj* pTimer = GUI_TIMER_H2P(hTimer);
GUI_TIMER_HANDLE hi;
GUI_TIMER_Obj* pi;
/* Check if it is the first element */
if (hFirstTimer == hTimer) {
hFirstTimer = pTimer->hNext;
return;
}
hi = hFirstTimer;
/* Try to find it in the list ... */
while(hi) {
/* GUI_ASSERT(hi<1000,0); */
pi = GUI_TIMER_H2P(hi);
if (pi->hNext == hTimer) {
pi->hNext = pTimer->hNext;
break;
}
hi = pi->hNext;
}
}
/*********************************************************************
*
* _Link
*
* Purpose:
* This routine inserts the new timer (referenced by its handle) into
* the linked list. The linked list is sorted according to timestamps.
* The first element is the timer which expires first.
*/
static void _Link(GUI_TIMER_HANDLE hNew) {
GUI_TIMER_Obj* pNew = GUI_TIMER_H2P(hNew);
GUI_TIMER_Obj* pTimer;
GUI_TIMER_Obj* pNext;
GUI_TIMER_HANDLE hNext;
if (hFirstTimer ==0) { /* List is empty, make it the only element */
hFirstTimer = hNew;
pNew->hNext = 0;
} else {
GUI_TIMER_Obj* pFirstTimer = GUI_TIMER_H2P(hFirstTimer);
/* Check if we have to make it the first element */
if ((pNew->t0 - pFirstTimer->t0) <=0) {
pNew->hNext = hFirstTimer;
hFirstTimer = hNew;
return;
} else {
GUI_TIMER_HANDLE hTimer = hFirstTimer;
/* Put it into the list */
do {
pTimer = GUI_TIMER_H2P(hTimer);
hNext = pTimer->hNext;
if (hNext ==0)
goto Append;
pNext = GUI_TIMER_H2P(hNext);
if ((pNew->t0 - pNext->t0) <=0) {
pNew->hNext = hNext;
pTimer->hNext= hNew;
return;
}
} while(1);
/* Put it at the end of the list */
Append:
pNew->hNext = hNext;
pTimer->hNext= hNew;
return;
}
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_TIMER_Exec
*/
int GUI_TIMER_Exec(void) {
int r = 0;
GUI_TIMER_TIME t = GUI_GetTime();
GUI_LOCK(); {
while (hFirstTimer) {
GUI_TIMER_Obj* pTimer = GUI_TIMER_H2P(hFirstTimer);
if ((pTimer->t0-t) <=0) {
GUI_TIMER_MESSAGE tm;
tm.Time = t;
tm.Context = pTimer->Context;
_hActiveTimer = hFirstTimer;
hFirstTimer = pTimer->hNext;
pTimer->cb(&tm);
r = 1;
} else
break;
}
/*
GUI_TIMER_Obj* pObj = GUI_TIMER_H2P(hObj);
pObj->t0 = Time;
*/
} GUI_UNLOCK();
return r;
}
/*********************************************************************
*
* GUI_TIMER_Create
*/
GUI_TIMER_HANDLE GUI_TIMER_Create(GUI_TIMER_CALLBACK* cb, int Time, U32 Context, int Flags) {
GUI_TIMER_HANDLE hObj;
GUI_TIMER_Obj* pObj;
GUI_LOCK();
GUI_USE_PARA(Flags);
GUI_USE_PARA(Time);
GUI_pfTimerExec = GUI_TIMER_Exec;
{
/* Alloc memory for obj */
hObj = GUI_ALLOC_AllocZero(sizeof(GUI_TIMER_Obj));
pObj = GUI_TIMER_H2P(hObj);
/* init member variables */
pObj->cb = cb;
pObj->Context = Context;
pObj->t0 = Time; //houhh 20061018...
/* Link it */
_Link(hObj);
} GUI_UNLOCK();
return hObj;
}
/*********************************************************************
*
* GUI_TIMER_Delete
*/
void GUI_TIMER_Delete(GUI_TIMER_HANDLE hObj) {
/* Unlink Timer */
GUI_LOCK();
_Unlink(hObj);
GUI_ALLOC_Free(hObj);
GUI_UNLOCK();
}
/*********************************************************************
*
* GUI_TIMER_SetPeriod
*/
void GUI_TIMER_SetPeriod(GUI_TIMER_HANDLE hObj, GUI_TIMER_TIME Period) {
GUI_LOCK(); {
GUI_TIMER_Obj* pObj = GUI_TIMER_H2P(hObj);
pObj->Period = Period;
} GUI_UNLOCK();
}
/*********************************************************************
*
* GUI_TIMER_SetTime
*/
void GUI_TIMER_SetTime(GUI_TIMER_HANDLE hObj, GUI_TIMER_TIME Time) {
GUI_LOCK(); {
GUI_TIMER_Obj* pObj = GUI_TIMER_H2P(hObj);
pObj->t0 = Time;
} GUI_UNLOCK();
}
//////
void GUI_TIMER_Context(GUI_TIMER_HANDLE hObj, U32 Context) {
GUI_LOCK(); {
GUI_TIMER_Obj* pObj = GUI_TIMER_H2P(hObj);
pObj->Context = Context;
} GUI_UNLOCK();
}
//////
/*********************************************************************
*
* GUI_TIMER_SetDelay
*/
void GUI_TIMER_SetDelay(GUI_TIMER_HANDLE hObj, GUI_TIMER_TIME Delay) {
GUI_LOCK(); {
GUI_TIMER_Obj* pObj = GUI_TIMER_H2P(hObj);
pObj->t0 = Delay;
_Unlink(hObj);
_Link(hObj);
} GUI_UNLOCK();
}
/*********************************************************************
*
* GUI_TIMER_Restart
*/
void GUI_TIMER_Restart(GUI_TIMER_HANDLE hObj) {
GUI_TIMER_Obj* pObj;
GUI_LOCK();
{
if (hObj == 0) {
hObj = _hActiveTimer;
}
pObj = GUI_TIMER_H2P(hObj);
pObj->t0 = GUI_GetTime() +pObj->Period;
_Unlink(hObj);
_Link(hObj);
} GUI_UNLOCK();
}
/*************************** End of file ****************************/