summaryrefslogtreecommitdiff
path: root/source/LCM/Timer.cpp
blob: 8dd19e4410b00dd71c8db0c9194070a94f35e05d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/***********************************************************************
 * Copyright (C) ST-Ericsson SA 2011
 * License terms: 3-clause BSD license
 **********************************************************************/

/*************************************************************************
* Includes
*************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "Timer.h"
#include "LCDriverMethods.h"


/***********************************************************************
 * Declaration of file local functions
 **********************************************************************/
/* Constructor */
Timer::Timer(void):
    systemTime_(0),
    logger_(0)
{
    timers_.Timers_p = NULL;
    timers_.ActiveTimers = 0;
    timers_.MaxTimers = 0;
}

/* Destructor */
Timer::~Timer(void)
{
    delete[] timers_.Timers_p;
}
/***********************************************************************
 * Definition of external functions
 **********************************************************************/

/*
 * Initialization of the Timers handler.
 *
 * @param [in] Timers   Numbers of defined timers.
 *
 * @retval   E_SUCCESS After successful execution.
 * @retval   E_INVALID_INPUT_PARAMETERS If no timer s for initialization.
 */
ErrorCode_e Timer::Init(uint32 Timers)
{
    /* Check input parameters. */
    if (0 == Timers) {
        /* Invalid input parameters! */
        return E_INVALID_INPUT_PARAMETERS;
    }

    /* Allocate memory space for timers */
    timers_.Timers_p = new Timer_t[Timers];

    if (timers_.Timers_p == NULL) {
        /* Error allocation Timers buffer! */
        return E_ALLOCATE_FAILED;
    }

    /* Clear Timers buffer */
    memset(timers_.Timers_p, 0x00, Timers * sizeof(Timer_t));

    /* Inicialize numbers of defined and activated timers */
    timers_.MaxTimers = Timers;
    timers_.ActiveTimers = 0;

    return E_SUCCESS;
}

/*
 * Reserve new timer.
 *
 * @param [in] Timer_p   pointer to the timer data.
 *
 * @return   Index of reserved timer.
 * @return   Index 0 if no free timers.
 */
uint32 Timer::Get(Timer_t *Timer_p)
{
    uint32 TimerKey = 0;

    /* Check input parameters */
    if (0 == Timer_p->Time || NULL == Timer_p->HandleFunction_p) {
        goto ErrorExit;
    }

    /* Find free timer */
    TimerKey = FindFreeTimer();

    if (0 == TimerKey) {
        goto ErrorExit; // no free timers
    }

    timers_.ActiveTimers++;

    timers_.Timers_p[TimerKey - 1] = *Timer_p;

#ifdef _TIMERDEBUG
    logger_->log("Timer: Get - Timer 0x%p", &timers_.Timers_p[TimerKey - 1]);
#endif

ErrorExit:
    return TimerKey;
}

/*
 * Release reserved timer.
 *
 * @param [in] TimerKey   Index of reserved timer.
 *
 * @retval   E_SUCCESS  After successful execution.
 * @retval   E_INVALID_INPUT_PARAMETERS If one of the input.
 * @retval   E_NONEXIST_TIMER non exist timer.
 */
ErrorCode_e Timer::Release(uint32 TimerKey)
{
    ErrorCode_e ReturnValue = E_INVALID_INPUT_PARAMETERS;
    Timer_t *TimerData_p = NULL;

    /* check input parameters */
    if ((0 == TimerKey) || (timers_.MaxTimers < TimerKey)) {
        goto ErrorExit;
    }

    TimerData_p = &timers_.Timers_p[TimerKey - 1];

    if (NULL != TimerData_p->HandleFunction_p) {
        /* clear timer data */
        TimerData_p->Time = 0;
        TimerData_p->HandleFunction_p = NULL;

        /* first check number of active timers */
        if (0 < timers_.ActiveTimers) {
            /* remove timer from active timer counter */
            timers_.ActiveTimers--;
        }

        ReturnValue = E_SUCCESS;

#ifdef _TIMERDEBUG
        logger_->log("Timer: Release - Timer 0x%p", (void *)TimerData_p);
#endif
    } else {
        ReturnValue = E_NONEXIST_TIMER;
    }

ErrorExit:
    return ReturnValue;
}

/*
 * Read the current time of timer.
 *
 * @param [in] TimerKey   Index of reserved timer.
 *
 * @return   Current time of the timer.
 */
uint32 Timer::ReadTime(uint32 TimerKey)
{
    uint32 Time = 0;

    if (TimerKey == 0 || TimerKey > timers_.MaxTimers) {
        return Time;
    }

    Timer_t *TimerData_p = &timers_.Timers_p[TimerKey - 1];

    if (NULL != TimerData_p->HandleFunction_p) {
        /* get timer data */
        Time = TimerData_p->Time;
    }

    return Time;
}

/*
 * Get current system time.
 *
 * @return   System Time.
 */
uint32 Timer::GetSystemTime()
{
    return static_cast<uint32>(systemTime_);
}


/*
 * The timer handler method which is polled in the main execution thread.
 * Checks if there is a timer which time has elapsed and calls its callback,
 * handle the timers time decrementation.
 *
 * @param [in] IsTimerOn   Determinates if the timers are active to be handled.
 *
 * @return   Function doesn't return value.
 */
void Timer::DoTimerHandler(bool IsTimerOn)
{
    uint32 SearchTimerKey = 0;
    uint32 TimeIncrement = GetIncrement();

    while (timers_.ActiveTimers > 0 && SearchTimerKey < timers_.MaxTimers) {
        /* get Timer(SearchTimerKey) data */
        Timer_t *TimerData_p = &timers_.Timers_p[SearchTimerKey];

        if (NULL != TimerData_p->HandleFunction_p) {
            /* decrement Time */
            if (IsTimerOn) {
                TimerData_p->Time -= min(TimerData_p->Time, TimeIncrement);
            }

            /* check for elapsed time */
            if (TimerData_p->Time == 0) {
#ifdef _TIMERDEBUG
                logger_->log("Timer: DoTimerHandler - callback handle function Timer 0x%p", TimerData_p);
#endif
                TimerData_p->HandleFunction_p(TimerData_p->Param_p, TimerData_p, TimerData_p->Data_p);

                /* Check for periodicals of timer */
                if (TimerData_p->PeriodicalTime != 0) {
                    /* Set again Timer with periodical time */
                    TimerData_p->Time = TimerData_p->PeriodicalTime;
                } else {
                    /* release current timer */
                    Release(SearchTimerKey + 1);
                }
            }
        }

        /* next timer for check */
        SearchTimerKey++;
    }
}

/*
 * Get the difference in time from the last call.
 *
 * @return increment   the duration of time which should be
 *                     substracted from the timers.
 */
uint32 Timer::GetIncrement()
{
    time_t now = OS::GetSystemTimeInMs();
    time_t increment = now - systemTime_;
    systemTime_ = now;
    return static_cast<uint32>(increment);
}

/*
 * Find free timer.
 *
 * @retval   Timer index if free timer exist.
 * @retval   0 if no free timer.
 */
uint32 Timer::FindFreeTimer()
{
    uint32 TimerKey = 0;

    for (size_t i = 0; i != timers_.MaxTimers; ++i) {
        if (timers_.Timers_p[i].HandleFunction_p == NULL) {
            TimerKey = i + 1;
            break;
        }
    }

    return TimerKey;
}