1 /*
2 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
3 * Copyright (C) 2016 CC-Link Partner Association -http://am.cc-link.org/
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 #ifdef _WIN32
37 #include <stdint.h>
38 #include <stdlib.h>
39 #elif __linux__
40 #endif
41 #include <time.h>
42 #include <string.h>
43 #include "TIMER.h"
45 /*[ Structure for the timer ]*/
46 typedef struct
47 {
48 int iId; /* Timer id */
49 uint32_t ulTime; /* Period of time [ms] */
50 uint32_t ulStart; /* Start of time [ms] */
51 TIMER_CALLBACK pCallbackFunc; /* Callback function */
52 void *pCallbackArg; /* Callback argument */
53 } TIMER;
55 static TIMER Timer[TIMER_MAX];
56 static int iTimerId = 0;
58 /************************************************************************************/
59 /* This is an user defined function for initialize the timer. */
60 /************************************************************************************/
61 void timer_initialize( void )
62 {
63 /* Initialize the timer environment */
64 memset( &Timer, 0, sizeof( Timer ) );
66 return;
67 }
69 /************************************************************************************/
70 /* This is an user defined function for terminate the timer. */
71 /************************************************************************************/
72 void timer_terminate( void )
73 {
74 /* Terminate the timer environment */
75 /* if needed */
77 return;
78 }
80 /************************************************************************************/
81 /* This is an user defined function for main the timer. */
82 /************************************************************************************/
83 void timer_main( void )
84 {
85 int i, iStopId;
86 uint32_t ulCurrent;
88 /* main loop for the timer */
89 for( i = 0; i < TIMER_MAX; i++ )
90 {
91 if ( Timer[i].iId != 0 )
92 {
93 /* Get the difference time */
94 ulCurrent = timer_get_time();
95 /* Timeout the timer */
96 if ( Timer[i].ulTime <= ( ulCurrent - Timer[i].ulStart ))
97 {
98 iStopId = Timer[i].iId;
99 if ( Timer[i].pCallbackFunc != NULL )
100 {
101 /* Execute of the callback function */
102 Timer[i].pCallbackFunc( Timer[i].iId, Timer[i].pCallbackArg );
103 }
104 /* Initialize of the timer */
105 if ( iStopId == Timer[i].iId )
106 {
107 Timer[i].iId = 0;
108 }
109 }
110 }
111 }
113 return;
114 }
116 /************************************************************************************/
117 /* This is an user defined function for starting the timer.[ms] */
118 /************************************************************************************/
119 int timer_start( uint32_t ulTime, int *piId, TIMER_CALLBACK pCallbackFunc, void *pCallbackArg )
120 {
121 int i;
123 /* Check the unusing timer */
124 for( i = 0; i < TIMER_MAX; i++ )
125 {
126 if ( Timer[i].iId == 0 )
127 {
128 break;
129 }
130 }
131 if ( i == TIMER_MAX )
132 {
133 /* No free timer */
134 return TIMER_RESOURCE_NONE;
135 }
137 iTimerId ++;
138 if ( iTimerId == 0 )
139 {
140 iTimerId = 1;
141 }
142 Timer[i].iId = iTimerId;
144 Timer[i].ulTime = ulTime;
145 Timer[i].ulStart = timer_get_time();
146 Timer[i].pCallbackFunc = pCallbackFunc;
147 Timer[i].pCallbackArg = pCallbackArg;
149 if ( piId != NULL )
150 {
151 *piId = Timer[i].iId;
152 }
154 return TIMER_OK;
155 }
157 /************************************************************************************/
158 /* This is an user defined function for stoping the timer. */
159 /************************************************************************************/
160 void timer_stop( int iId )
161 {
162 int i;
164 /* Check the using timer */
165 for( i = 0; i < TIMER_MAX; i++ )
166 {
167 if ( Timer[i].iId == iId )
168 {
169 /* Initialize of the timer */
170 Timer[i].iId = 0;
171 break;
172 }
173 }
175 return;
176 }
178 /************************************************************************************/
179 /* This is an user defined function for getting the elapsed time from the start */
180 /* of the program.[ms] Please rewrite for user environment. */
181 /************************************************************************************/
182 uint32_t timer_get_time( void )
183 {
184 uint32_t ulTime;
186 ulTime = (uint32_t)(((int64_t)clock() * 1000 ) / CLOCKS_PER_SEC );
188 return ulTime;
189 }
191 /************************************************************************************/
192 /* This is an user defined function for calculate the broad cast wait time.[ms] */
193 /************************************************************************************/
194 uint32_t timer_broadcast_send_wait_time ( uint32_t ulMaxWaitTime )
195 {
196 uint32_t ulWaitTime;
198 /* Change of random number sequence */
199 srand( (unsigned)time( NULL ) );
201 /* Gets a wait time */
202 ulWaitTime = rand() % ulMaxWaitTime;
204 return ulWaitTime;
205 }
207 /************************************************************************************/
208 /* This is an user defined function for analyze the Time Data (Time of UNIX). */
209 /************************************************************************************/
210 void timer_analyze_time_data( int64_t llTime, TIMER_TIME_DATA *pTimeData )
211 {
212 /* Number of days table of each month (for the year-round, for a leap year) */
213 static const uint8_t aucDaysTable[2][13] = {
214 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
215 { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
216 };
217 uint32_t ulElapsedDays;
218 uint32_t ulTotalDays;
219 uint32_t ulThisYear;
220 uint32_t ulLastYearDays;
221 uint32_t ulThisYearDays;
222 uint32_t ulTempDays;
223 uint16_t usThisMonth;
224 uint32_t ulThisMinute;
225 uint16_t usIndex;
227 /* Calculate the number of days elapsed */
228 ulElapsedDays = (uint32_t)((( llTime / 1000) / 86400 ) + 719162);
230 /* It calculates the total number of days, including the day to the number of days elapsed */
231 ulTotalDays = ulElapsedDays + 1;
233 /* Initialized with the previous year */
234 ulThisYear = ulTotalDays / 365;
235 /* Calculate the year */
236 while ( 1 )
237 {
238 /* Calculate the previous year the number of days */
239 ulLastYearDays = ( ulThisYear * 365 ) + ( ulThisYear / 4 ) - ( ulThisYear / 100 ) + ( ulThisYear / 400 );
240 if ( ulLastYearDays >= ulTotalDays )
241 {
242 ulThisYear --;
243 }
244 else
245 {
246 ulThisYear ++;
247 break;
248 }
249 }
251 /* Calculate the number of days from January 1 */
252 ulThisYearDays = ulTotalDays - ulLastYearDays;
254 /* Calculating the index for the number of days table of each month or the full year or a leap year */
255 if (( ulThisYear % 4 == 0 ) && ( ulThisYear % 100 != 0 ) || ( ulThisYear % 400 == 0 ))
256 {
257 usIndex = 1;
258 }
259 else
260 {
261 usIndex = 0;
262 }
264 /* Calculate the month */
265 ulTempDays = 0;
266 for ( usThisMonth = 0; ( ulTempDays < ulThisYearDays ) && ( usThisMonth < 12 ); usThisMonth++ )
267 {
268 ulTempDays += aucDaysTable[ usIndex ][ usThisMonth + 1 ];
269 }
271 /* Results to the argument */
272 pTimeData->usYear = (uint16_t)ulThisYear;
273 pTimeData->usMonth = usThisMonth;
274 pTimeData->usDay = (uint16_t)( ulThisYearDays - ( ulTempDays - aucDaysTable[ usIndex ][ usThisMonth ]));
275 ulThisMinute = (uint32_t)(( llTime / 1000) % 86400 );
276 pTimeData->usHour = (uint16_t)( ulThisMinute / 3600 );
277 pTimeData->usMinute = (uint16_t)(( ulThisMinute % 3600 ) / 60 );
278 pTimeData->usSecond = (uint16_t)(( ulThisMinute % 3600 ) % 60 );
279 pTimeData->usMilliseconds = (uint16_t)( llTime % 1000 );
281 return;
282 }