drivers/timers_win32/timers_win32.c
author greg
Fri, 17 Jul 2009 20:30:38 +0200
changeset 571 6eddab0b7ca8
parent 556 8296acd119a9
child 575 18db803e593f
permissions -rw-r--r--
fix method to exit properly the Timer Loop
fix time unit
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     1
/*
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     2
This file is part of CanFestival, a library implementing CanOpen Stack.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     3
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     4
Copyright (C): Edouard TISSERANT and Francis DUPIN
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     5
Copyright (C) Win32 Port Leonid Tochinski
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     6
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     7
See COPYING file for copyrights details.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     8
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     9
This library is free software; you can redistribute it and/or
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    10
modify it under the terms of the GNU Lesser General Public
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    11
License as published by the Free Software Foundation; either
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    12
version 2.1 of the License, or (at your option) any later version.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    13
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    14
This library is distributed in the hope that it will be useful,
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    15
but WITHOUT ANY WARRANTY; without even the implied warranty of
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    17
Lesser General Public License for more details.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    18
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    19
You should have received a copy of the GNU Lesser General Public
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    20
License along with this library; if not, write to the Free Software
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    21
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    22
*/
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    23
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    24
#include <windows.h>
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    25
#include <stdlib.h>
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    26
#include <sys/timeb.h>
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    27
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    28
#include "applicfg.h"
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    29
#include "can_driver.h"
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    30
#include "timer.h"
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    31
#include "timers_driver.h"
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    32
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    33
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    34
struct _timeb timebuffer;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    35
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    36
/* Synchronization Object Implementation */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    37
CRITICAL_SECTION CanFestival_mutex;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    38
HANDLE timer_thread = NULL;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    39
HANDLE timer = NULL;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    40
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    41
stop_timer=0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    42
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    43
static TimerCallback_t init_callback;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    44
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    45
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    46
void EnterMutex(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    47
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    48
	EnterCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    49
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    50
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    51
void LeaveMutex(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    52
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    53
	LeaveCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    54
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    55
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    56
// --------------- CAN Receive Thread Implementation ---------------
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    57
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    58
void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    59
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    60
	unsigned long thread_id = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    61
	*Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    62
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    63
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    64
void WaitReceiveTaskEnd(TASK_HANDLE *Thread)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    65
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    66
	WaitForSingleObject(*Thread, INFINITE);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    67
	CloseHandle(*Thread);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    68
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    69
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    70
int TimerThreadLoop(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    71
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    72
	EnterMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    73
	// At first, TimeDispatch will call init_callback.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    74
	SetAlarm(NULL, 0, init_callback, 0, 0);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    75
	LeaveMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    76
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    77
	while(!stop_timer)
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    78
	{
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    79
		WaitForSingleObject(timer, INFINITE);
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    80
		if(stop_timer)
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    81
			break;
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    82
		_ftime(&timebuffer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    83
		EnterMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    84
		TimeDispatch();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    85
		LeaveMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    86
	}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    87
	return 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    88
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    89
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    90
void TimerInit(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    91
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    92
	LARGE_INTEGER liDueTime;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    93
	liDueTime.QuadPart = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    94
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    95
	InitializeCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    96
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    97
	timer = CreateWaitableTimer(NULL, FALSE, NULL);
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    98
	if(NULL == timer)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    99
    {
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   100
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   101
    }
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   102
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   103
	// Take first absolute time ref in milliseconds.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   104
	_ftime(&timebuffer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   105
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   106
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   107
void TimerCleanup(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   108
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   109
	DeleteCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   110
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   111
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   112
void StopTimerLoop(TimerCallback_t exitfunction)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   113
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   114
	EnterMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   115
	exitfunction(NULL,0);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   116
	LeaveMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   117
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   118
	stop_timer = 1;
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   119
	setTimer(0);
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   120
	WaitForSingleObject(timer_thread, INFINITE);
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   121
	CloseHandle(timer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   122
	CloseHandle(timer_thread);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   123
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   124
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   125
void StartTimerLoop(TimerCallback_t _init_callback)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   126
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   127
	unsigned long timer_thread_id;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   128
	stop_timer = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   129
	init_callback = _init_callback;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   130
	timer_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TimerThreadLoop, NULL, 0, &timer_thread_id);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   131
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   132
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   133
/* Set the next alarm */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   134
void setTimer(TIMEVAL value)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   135
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   136
	if(value == TIMEVAL_MAX)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   137
		CancelWaitableTimer(timer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   138
	else
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   139
	{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   140
		LARGE_INTEGER liDueTime;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   141
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   142
		/* arg 2 of SetWaitableTimer take 100 ns interval */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   143
		liDueTime.QuadPart = -value;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   144
		//printf("SetTimer(%llu)\n", value);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   145
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   146
		if (!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, FALSE))
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   147
		{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   148
			printf("SetWaitableTimer failed (%d)\n", GetLastError());
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   149
		}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   150
	}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   151
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   152
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   153
/* Get the elapsed time since the last occured alarm */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   154
TIMEVAL getElapsedTime(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   155
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   156
	struct _timeb timetmp;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   157
	_ftime(&timetmp);
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   158
	return (timetmp.time - timebuffer.time) * 10000000 + (timetmp.millitm - timebuffer.millitm) * 10000;
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   159
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   160