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/WM/WM_TimerExternal.c

263 lines
7.2 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 : WM_TimerExternal.c
Purpose : Implementetion of WM_CreateTimer, WM_DeleteTimer
for systems with external one shot timers.
(--> Philips, 2003)
This module requires 2 macros in order to work and
generate code:
GUI_X_CREATE_TIMER(Period, void (*cb)(int))
GUI_X_DELETE_TIMER(ID)
Note that the delete macro is optional, since
one-shot-timers are expected to delete themselves.
----------------------------------------------------------------------
*/
#include <stddef.h> /* needed for definition of NULL */
#include "WM_Intern.h"
/* Typical configuration: */
#if 0
int MyApp_CreateTimer(int Period, void (*cb)(int)) {
int r = 0;
/* Alloc a one-shot timer from the kernel & start it etc ... */
return r;
}
#define GUI_X_CREATE_TIMER(Period, cb) MyApp_CreateTimer(Period, cb)
#define GUI_X_DELETE_TIMER(ID)
#endif
#if GUI_WINSUPPORT && defined(GUI_X_CREATE_TIMER) /* If 0, WM will not generate any code */
/*********************************************************************
*
* Required data structures
*
**********************************************************************
*/
typedef struct TIMER_LINK {
int UserId;
int TimerId;
WM_HWIN hWin;
GUI_HMEM hNext;
} TIMER_LINK;
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
static GUI_HMEM _hFirst;
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _DeleteLinkItem
*
* Purpose:
* Returns:
*
*/
static void _DeleteLinkItem(GUI_HMEM hLinkToDelete) {
GUI_HMEM hLink;
TIMER_LINK* pLink;
TIMER_LINK* pLinkToDelete;
if (hLinkToDelete) {
pLinkToDelete = (TIMER_LINK*)GUI_ALLOC_h2p(hLinkToDelete);
if (_hFirst == hLinkToDelete) {
_hFirst = pLinkToDelete->hNext;
GUI_ALLOC_Free(hLinkToDelete);
} else {
for (hLink = _hFirst; hLink; hLink = pLink->hNext) {
pLink = (TIMER_LINK*)GUI_ALLOC_h2p(hLink);
if (pLink->hNext == hLinkToDelete) {
pLink->hNext = pLinkToDelete->hNext;
GUI_ALLOC_Free(hLinkToDelete);
break; /* We found it ! */
}
}
}
}
}
/*********************************************************************
*
* _FindTimerByTimerId
*
* Purpose:
* Find the link item for this timer.
* Returns: pointer to the link if the TimerId is valid, else NULL
*
*/
static GUI_HMEM _FindTimerByTimerId(int TimerId) {
GUI_HMEM hLink;
TIMER_LINK* pLink;
for (hLink = _hFirst; hLink; hLink = pLink->hNext) {
pLink = (TIMER_LINK*)GUI_ALLOC_h2p(hLink);
if (pLink->TimerId == TimerId) {
break; /* We found it ! */
}
}
return hLink;
}
/*********************************************************************
*
* _FindTimerByUserId
*
* Purpose:
* Find the link item for this timer.
* Returns: pointer to the link if the Window handle & UserId are valid, else NULL
*
*/
static GUI_HMEM _FindTimerByUserId(WM_HWIN hWin, int UserId) {
GUI_HMEM hLink;
TIMER_LINK* pLink;
for (hLink = _hFirst; hLink; hLink = pLink->hNext) {
pLink = (TIMER_LINK*)GUI_ALLOC_h2p(hLink);
if ((pLink->hWin == hWin) && (pLink->UserId == UserId)) {
break; /* We found it ! */
}
}
return hLink;
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* _OnTimer
*
* This routine is called when a timer is expired. Its function is to
* find out which window needs to receive a WM_TIMER message.
*/
static void _OnTimer(int TimerId) {
TIMER_LINK* pLink;
GUI_HMEM hLink;
WM_LOCK();
hLink = _FindTimerByTimerId(TimerId);
if (hLink) {
WM_MESSAGE Msg;
/* Send Message */
pLink = GUI_ALLOC_h2p(hLink);
Msg.MsgId = WM_TIMER;
Msg.Data.v = pLink->UserId;
Msg.hWinSrc = 0;
WM_SendMessage(pLink->hWin, &Msg);
/* Since these timers are one shot, we need to delete the link item. */
_DeleteLinkItem(hLink);
}
WM_UNLOCK();
}
/*********************************************************************
*
* WM_DeleteTimer
*
* Purpose:
* API function (optional).
* Allows the application to delete a timer.
*/
void WM_DeleteTimer (WM_HWIN hWin, int UserId) {
GUI_HMEM hLink;
WM_LOCK();
hLink = _FindTimerByUserId(hWin, UserId);
if (hLink) {
TIMER_LINK* pLink;
pLink = GUI_ALLOC_h2p(hLink);
GUI_X_DELETE_TIMER(pLink->TimerId);
_DeleteLinkItem(hLink);
}
WM_UNLOCK();
}
/*********************************************************************
*
* WM_CreateTimer
*
* Returns: 0 if failed, else != 0
* Parameters:
* hWin Window handle of the window to receive the WM_TIMER message
* UserId User defined Id. If not needed, use 0.
* Period Number of time units (ticks)
* Mode 0: one-shot
*
*/
int WM_CreateTimer (WM_HWIN hWin, int UserId, int Period, int Mode) {
int r = 0;
int TimerId;
GUI_HMEM hTimerLink;
TIMER_LINK* pLink;
WM_LOCK();
TimerId = GUI_X_CREATE_TIMER(Period, _OnTimer);
if (TimerId) {
hTimerLink = GUI_ALLOC_AllocZero(sizeof(TIMER_LINK));
if (hTimerLink) {
pLink = (TIMER_LINK*) GUI_ALLOC_h2p(hTimerLink);
/* Put new timer at beginning of the linked list */
pLink->hNext = _hFirst;
if (_hFirst) {
TIMER_LINK* pNext;
pNext = (TIMER_LINK*) GUI_ALLOC_h2p(_hFirst);
}
_hFirst = hTimerLink;
/* Fill in link data */
pLink->hWin = hWin;
pLink->TimerId = TimerId;
pLink->UserId = UserId;
r = 1; /* All right, we have successfully created a new timer */
}
}
/* Cleanup in case of problem */
if (r == 0) {
if (TimerId) {
GUI_X_DELETE_TIMER(TimerId);
}
}
WM_UNLOCK();
return r;
}
#else
void WM_TimerExternal_c(void);
void WM_TimerExternal_c(void) {} /* avoid empty object files */
#endif /* GUI_WINSUPPORT */
/*************************** End of file ****************************/