Add win32 target (--can=win32) to compile with msys and mingw32
authorgreg
Mon, 10 Sep 2007 08:04:32 +0200
changeset 267 96c688ebcde7
parent 266 8678a3cf7fe7
child 268 8a21eb5bdedc
Add win32 target (--can=win32) to compile with msys and mingw32
CanFestival-3.vc8.vcproj
configure
drivers/can_ixxat_win32/ixxat.cpp
drivers/can_peak_win32/can_peak_win32.c
drivers/can_uvccm_win32/can_uvccm_win32.cpp
drivers/timers_win32/Makefile
drivers/timers_win32/Makefile.in
drivers/timers_win32/timers_win32.cpp
drivers/unix/unix.c
drivers/win32/Makefile
drivers/win32/Makefile.in
drivers/win32/drivers_win32.cpp
drivers/win32/timers_win32.cpp
drivers/win32/win32.cpp
examples/Makefile.in
examples/TestMasterMicroMod/Makefile.in
examples/TestMasterSlave/Makefile.in
--- a/CanFestival-3.vc8.vcproj	Tue Sep 04 17:47:46 2007 +0200
+++ b/CanFestival-3.vc8.vcproj	Mon Sep 10 08:04:32 2007 +0200
@@ -222,7 +222,7 @@
 					>
 				</File>
 				<File
-					RelativePath=".\drivers\win32\timers_win32.cpp"
+					RelativePath=".\drivers\timers_win32\timers_win32.cpp"
 					>
 				</File>
 			</Filter>
--- a/configure	Tue Sep 04 17:47:46 2007 +0200
+++ b/configure	Mon Sep 10 08:04:32 2007 +0200
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 
 #
 # Copyright (C) 2004 Edouard TISSERRANT, Laurent BESSARD
@@ -26,11 +26,11 @@
 ###########################################################################
 
 # Number of can bus to use 
-MAX_CAN_BUS_ID=1 
+MAX_CAN_BUS_ID=1
 
 # max bytes to transmit by SDO Put 4 if you only support expedited transfert.
 # For a normal transfert, (usually for a string), put the maximum string size to transfer.
-SDO_MAX_LENGTH_TRANSFERT=32 
+SDO_MAX_LENGTH_TRANSFERT=32
 
 # Number of SDO from differents nodes that the node can manage concurrently.   
 # for a slave node, usually put 1.
@@ -39,7 +39,7 @@
 # Used for NMTable[bus][nodeId]	  
 # You can put less of 128 if on the netwo
 # are connected only smaller nodeId node.
-NMT_MAX_NODE_ID=128  
+NMT_MAX_NODE_ID=128
 
 #Timeout in milliseconds for SDO.
 #    Comment the #define if not used (infinite wait for SDO response message)
@@ -332,10 +332,15 @@
 	if [ "$SUB_OS_NAME" = "CYGWIN" ]; then
 		echo "Choosing unix (cygwin) target"
 		SUB_TARGET=unix
-	else
+	fi
+	if [ "$SUB_OS_NAME" = "Linux" ]; then
 		echo "Choosing unix target"
 		SUB_TARGET=unix
 	fi
+	if [ "$SUB_OS_NAME" = "MINGW32" ]; then
+		echo "Choosing windows target"
+		SUB_TARGET=win32
+	fi
 fi
 
 # Try to gess can
@@ -360,6 +365,12 @@
 	SUB_TIMERS_DRIVER=unix
 fi
 
+# If target is windows, default timers also
+if [ "$SUB_TARGET" = "win32" -a "$SUB_TIMERS_DRIVER" = "" ]; then
+	echo "Choosing windows timers driver."
+	SUB_TIMERS_DRIVER=win32
+fi
+
 # Warn for unstalled peak driver if choosen
 if [ "$SUB_CAN_DRIVER" = "peak" ]; then
 	if [ ! -e /usr/lib/libpcan.so ]; then 
@@ -662,6 +673,17 @@
 \	examples/TestMasterMicroMod/Makefile.in
 fi
 
+if [ "$SUB_TARGET" = "win32" ]; then
+	MAKEFILES=$MAKEFILES\
+\	examples/TestMasterSlave/Makefile.in
+fi
+
+if [ "$SUB_TARGET" = "win32" ]; then
+	MAKEFILES=$MAKEFILES\
+\	examples/TestMasterMicroMod/Makefile.in
+fi
+
+
 if [ "$SUB_TARGET" = "hcs12" ]; then
 	MAKEFILES=$MAKEFILES\
 \	examples/gene_SYNC_HCS12/Makefile.in
--- a/drivers/can_ixxat_win32/ixxat.cpp	Tue Sep 04 17:47:46 2007 +0200
+++ b/drivers/can_ixxat_win32/ixxat.cpp	Mon Sep 10 08:04:32 2007 +0200
@@ -124,13 +124,13 @@
 bool IXXAT::send(const Message *m)
    {
    if (m_BoardHdl == 0xFFFF)
-      return false;
+      return true; // true -> NOT OK
    long res = VCI_ERR;
    if (m->rtr == NOT_A_REQUEST)
       res = VCI_TransmitObj(m_BoardHdl, m_TxQueHdl, m->cob_id.w, m->len, const_cast<unsigned char*>(m->data));
    else
       res = VCI_RequestObj(m_BoardHdl, m_TxQueHdl, m->cob_id.w, m->len);
-   return (res == VCI_OK);   
+   return (res == false); // false -> OK 
    }
 
 
--- a/drivers/can_peak_win32/can_peak_win32.c	Tue Sep 04 17:47:46 2007 +0200
+++ b/drivers/can_peak_win32/can_peak_win32.c	Mon Sep 10 08:04:32 2007 +0200
@@ -31,7 +31,7 @@
 
 #include "cancfg.h"
 #include "can_driver.h"
-
+#include "def.h"
 #ifndef extra_PCAN_init_params
 	#define extra_PCAN_init_params /**/
 #else
@@ -66,18 +66,46 @@
 	return 0x0000;
 }
 
+#define MyCase(fc) case fc: printf(#fc);break;
+void print_message(Message *m)
+{
+	int i;
+	switch(m->cob_id.w >> 7)
+	{
+		MyCase(SYNC)
+		MyCase(TIME_STAMP)
+		MyCase(PDO1tx)
+		MyCase(PDO1rx)
+		MyCase(PDO2tx)
+		MyCase(PDO2rx)
+		MyCase(PDO3tx)
+		MyCase(PDO3rx)
+		MyCase(PDO4tx)
+		MyCase(PDO4rx)
+		MyCase(SDOtx)
+		MyCase(SDOrx)
+		MyCase(NODE_GUARD)
+		MyCase(NMT)
+	}
+	printf(" rtr:%d", m->rtr);
+	printf(" len:%d", m->len);
+	for (i = 0 ; i < m->len ; i++)
+		printf(" %02x", m->data[i]);
+	printf("\n");
+}
+
 void
 canInit (s_BOARD *board)
 {
 	int baudrate;
 	
-#ifdef PCAN2_HEADER_
+//#ifdef PCAN2_HEADER_
 	// if not the first handler
 	if(second_board == (s_BOARD *)board)
 		if(baudrate = TranslateBaudeRate(board->baudrate))
 			CAN2_Init (baudrate,
 			  CAN_INIT_TYPE_ST extra_PCAN_init_params);
-#endif
+//#endif
 	if(first_board == (s_BOARD *)board)
 		if(baudrate = TranslateBaudeRate(board->baudrate))
 			CAN_Init (baudrate,
@@ -90,9 +118,7 @@
 {
 	UNS8 data;
 	TPCANMsg peakMsg;
-
 	DWORD Res;
-
 	do{
 		// We read the queue looking for messages.
 		// 
@@ -107,7 +133,6 @@
 			Res = CAN_Read (&peakMsg);
 		else
 			Res = CAN_ERR_BUSOFF;
-	
 		// A message was received
 		// We process the message(s)
 		// 
@@ -129,6 +154,7 @@
 					MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN;
 			}
 			m->cob_id.w = peakMsg.ID;
+			
 			if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)	/* bits of MSGTYPE_ */
 				m->rtr = 0;
 			else
@@ -136,7 +162,7 @@
 			m->len = peakMsg.LEN;	/* count of data bytes (0..8) */
 			for (data = 0; data < peakMsg.LEN; data++)
 				m->data[data] = peakMsg.DATA[data];	/* data bytes, up to 8 */
-	
+		
 		}else{
 		//pthread_mutex_unlock (&PeakCan_mutex);
 		//if (Res != CAN_ERR_OK)
@@ -171,16 +197,21 @@
 	/* count of data bytes (0..8) */
 	for (data = 0; data < m->len; data++)
 		peakMsg.DATA[data] = m->data[data];	/* data bytes, up to 8 */
+	
 	do
 	{
 #ifdef PCAN2_HEADER_
 		// if not the first handler
 		if(second_board == (s_BOARD *)fd0)
+		{
 			errno = CAN2_Write (&peakMsg);
+		}
 		else 
 #endif
 		if(first_board == (s_BOARD *)fd0)
-			errno = CAN_Write (&peakMsg);
+			{
+				errno = CAN_Write (&peakMsg);
+			}
 		else 
 			goto fail;
 		if (errno)
@@ -204,29 +235,20 @@
 CAN_HANDLE
 canOpen_driver (s_BOARD * board)
 {
-#ifdef PCAN2_HEADER_
-	if(first_board != NULL && second_board != NULL)
-#else
-	if(first_board != NULL)
-#endif
-	{
-		fprintf (stderr, "Open failed.\n");
-		fprintf (stderr,
-				 "can_peak_win32.c: no more can port available with this pcan library\n");
-		fprintf (stderr,
-				 "can_peak_win32.c: please link another executable with another pcan lib\n");
-		return NULL;
-	}
-
-#ifdef PCAN2_HEADER_
-	if(first_board == NULL)
-		first_board = board;
-	else
-		second_board = board; 
-#else
-	first_board = board;
-#endif
-
+  char busname[64];
+  char* pEnd;
+
+  //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0));
+  if (strtol(board->busname, &pEnd,0) == 0)
+  {
+      first_board = board;
+      printf ("First Board selected\n");
+  }
+  if (strtol(board->busname, &pEnd,0) == 1)
+  {
+     second_board = board;
+     printf ("Second Board selected\n");
+  }
 	canInit(board);
 	
 	return (CAN_HANDLE)board;
--- a/drivers/can_uvccm_win32/can_uvccm_win32.cpp	Tue Sep 04 17:47:46 2007 +0200
+++ b/drivers/can_uvccm_win32/can_uvccm_win32.cpp	Mon Sep 10 08:04:32 2007 +0200
@@ -73,7 +73,7 @@
 bool can_uvccm_win32::send(const Message *m)
    {
    if (m_port == INVALID_HANDLE_VALUE)
-      return false;
+      return true;
 
    // build can_uvccm_win32 command string
    std::string can_cmd;
@@ -93,8 +93,8 @@
    ::GetOverlappedResult(m_port, &overlapped, &bytes_written, FALSE);
 
    bool result = (bytes_written == can_cmd.size());
-
-   return result;
+   
+   return false;
    }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/timers_win32/Makefile	Mon Sep 10 08:04:32 2007 +0200
@@ -0,0 +1,62 @@
+#! gmake
+
+#
+# Copyright (C) 2006 Laurent Bessard
+# 
+# This file is part of canfestival, a library implementing the canopen
+# stack
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# 
+
+CC = mingw32-g++
+OPT_CFLAGS = -O2
+CFLAGS = $(OPT_CFLAGS)
+PROG_CFLAGS = 
+OS_NAME = MINGW32
+ARCH_NAME = x86
+PREFIX = /usr/local
+TARGET = win32
+CAN_DRIVER = can_peak_win32
+TIMERS_DRIVER = timers_win32
+
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
+
+OBJS = $(TIMERS_DRIVER).o
+
+SRC_HFILES = ../../include/$(TIMERS_DRIVER)/timerscfg.h
+
+TARGET_HFILES = $(PREFIX)/include/canfestival/timerscfg.h
+
+all: driver
+
+driver: $(OBJS)
+
+%o: %cpp
+	$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+install:
+	mkdir -p $(PREFIX)/include/canfestival
+	cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+
+uninstall:
+	rm -f $(TARGET_HFILES)
+
+clean:
+	rm -f $(OBJS)
+
+mrproper: clean
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/timers_win32/Makefile.in	Mon Sep 10 08:04:32 2007 +0200
@@ -0,0 +1,62 @@
+#! gmake
+
+#
+# Copyright (C) 2006 Laurent Bessard
+# 
+# This file is part of canfestival, a library implementing the canopen
+# stack
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# 
+
+CC = mingw32-g++
+OPT_CFLAGS = -O2
+CFLAGS = SUB_OPT_CFLAGS
+PROG_CFLAGS = SUB_PROG_CFLAGS
+OS_NAME = SUB_OS_NAME
+ARCH_NAME = SUB_ARCH_NAME
+PREFIX = SUB_PREFIX
+TARGET = SUB_TARGET
+CAN_DRIVER = SUB_CAN_DRIVER
+TIMERS_DRIVER = SUB_TIMERS_DRIVER
+
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
+
+OBJS = $(TIMERS_DRIVER).o
+
+SRC_HFILES = ../../include/$(TIMERS_DRIVER)/timerscfg.h
+
+TARGET_HFILES = $(PREFIX)/include/canfestival/timerscfg.h
+
+all: driver
+
+driver: $(OBJS)
+
+%o: %cpp
+	$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+install:
+	mkdir -p $(PREFIX)/include/canfestival
+	cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+
+uninstall:
+	rm -f $(TARGET_HFILES)
+
+clean:
+	rm -f $(OBJS)
+
+mrproper: clean
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/timers_win32/timers_win32.cpp	Mon Sep 10 08:04:32 2007 +0200
@@ -0,0 +1,241 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+Copyright (C) Win32 Port Leonid Tochinski
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+
+
+#include <windows.h>
+#include <stdlib.h>
+
+extern "C"
+{
+#include "applicfg.h"
+#include "can_driver.h"
+#include "timer.h"
+#include "timers_driver.h"
+};
+
+// --------------- Synchronization Object Implementation ---------------
+class ccritical_section
+   {
+   public:
+      ccritical_section()
+         {
+         ::InitializeCriticalSection(&m_cs);
+         }
+      ~ccritical_section()
+         {
+         ::DeleteCriticalSection(&m_cs);
+         }
+      void enter()
+         {
+         ::EnterCriticalSection(&m_cs);
+         }
+      void leave()
+         {
+         ::LeaveCriticalSection(&m_cs);
+         }
+   private:
+      CRITICAL_SECTION m_cs;
+   };
+
+static ccritical_section g_cs;
+
+
+void EnterMutex(void)
+   {
+   g_cs.enter();
+   }
+
+void LeaveMutex(void)
+   {
+   g_cs.leave();
+   }
+// --------------- Synchronization Object Implementation ---------------
+
+
+// --------------- CAN Receive Thread Implementation ---------------
+
+void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
+   {
+   unsigned long thread_id = 0;
+   *Thread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id);
+   }
+
+void WaitReceiveTaskEnd(TASK_HANDLE Thread)
+   {
+   ::WaitForSingleObject(Thread, INFINITE);
+   ::CloseHandle(Thread);
+   //*Thread = NULL;
+   }
+// --------------- CAN Receive Thread Implementation ---------------
+
+
+// --------------- Timer Thread Implementation ---------------
+class class_timers
+   {
+   public:
+      class_timers();
+      ~class_timers();
+      void start_timer_thread();
+      void resume_timer_thread();
+      void stop_timer_thread();
+      void set_timer(TIMEVAL value);
+      TIMEVAL get_elapsed_time();
+   private:
+      TIMEVAL get_timer() const;   
+      static DWORD WINAPI timer_loop_thread_proc(void* arg);
+   private:
+      TIMEVAL m_last_occured_alarm_time;
+      volatile TIMEVAL m_last_alarm_set_time;
+      HANDLE m_timer_thread;
+      volatile bool m_continue_timer_loop;
+      bool m_use_hi_res_timer;
+      double m_counts_per_usec;
+   };
+
+class_timers::class_timers() : m_last_occured_alarm_time(TIMEVAL_MAX),
+      m_last_alarm_set_time(TIMEVAL_MAX),
+      m_timer_thread(0),
+      m_continue_timer_loop(false),
+      m_use_hi_res_timer(false),
+      m_counts_per_usec(0.)
+   {
+   // initialize hi resolution timer
+   LARGE_INTEGER counts_per_sec = {0, 0};
+   if (::QueryPerformanceFrequency(&counts_per_sec) && counts_per_sec.QuadPart > 0)
+      {
+      m_use_hi_res_timer = true;
+      m_counts_per_usec = counts_per_sec.QuadPart / 1000000.;
+      }
+   m_use_hi_res_timer = true;
+   }
+
+class_timers::~class_timers()
+   {
+   stop_timer_thread();
+   }
+
+// time is in micro seconds
+TIMEVAL class_timers::get_timer() const
+   {
+   if (m_use_hi_res_timer)
+      {
+      LARGE_INTEGER performance_count = {0, 0};
+      ::QueryPerformanceCounter(&performance_count);
+      return (TIMEVAL)(performance_count.QuadPart / m_counts_per_usec);
+      }
+   // hi-res timer is unavailable
+   return 1000 * ::GetTickCount();
+   }
+
+DWORD WINAPI class_timers::timer_loop_thread_proc(void* arg)
+   {
+   class_timers* This = reinterpret_cast<class_timers*>(arg);
+   while (This->m_continue_timer_loop)
+      {
+      TIMEVAL cur_time = This->get_timer();
+      if (cur_time >= This->m_last_alarm_set_time)
+         {
+         This->m_last_occured_alarm_time = cur_time;
+         This->m_last_alarm_set_time = TIMEVAL_MAX;         
+         EnterMutex();
+         TimeDispatch();
+         LeaveMutex();
+         }
+      else
+         {
+         ::Sleep(1);
+         }
+      }
+   return 0;
+   }
+
+void class_timers::start_timer_thread()
+   {
+   if (m_timer_thread == 0)
+      {
+      unsigned long thread_id = 0;
+      m_timer_thread = ::CreateThread(NULL, 0, &timer_loop_thread_proc, this, CREATE_SUSPENDED, &thread_id);
+      m_last_alarm_set_time = TIMEVAL_MAX;
+      m_last_occured_alarm_time = get_timer();
+      }
+   }
+
+void class_timers::resume_timer_thread()
+   {
+   if (m_timer_thread)
+      {
+      m_continue_timer_loop = true;
+      ::ResumeThread(m_timer_thread);
+      }
+   }
+
+void class_timers::stop_timer_thread()
+   {
+   if (m_timer_thread)
+      {
+      m_continue_timer_loop = false;
+      ::WaitForSingleObject(m_timer_thread, INFINITE);
+      ::CloseHandle(m_timer_thread);
+      m_timer_thread = 0;
+      }
+   }
+
+void class_timers::set_timer(TIMEVAL value)
+   {
+   m_last_alarm_set_time = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : get_timer() + value;
+   }
+
+// elapsed time since last occured alarm
+TIMEVAL class_timers::get_elapsed_time()
+   {
+   return get_timer() - m_last_occured_alarm_time;
+   }
+
+// ----------------------------------------------------------
+
+static class_timers s_timers;
+
+void StartTimerLoop(TimerCallback_t init_callback)
+   {
+   s_timers.start_timer_thread();
+   // At first, TimeDispatch will call init_callback.
+   if (init_callback != NULL)
+      SetAlarm(NULL, 0, init_callback, (TIMEVAL)0, (TIMEVAL)0);
+   s_timers.resume_timer_thread();
+   }
+
+void StopTimerLoop(void)
+   {
+   s_timers.stop_timer_thread();
+   }
+
+void setTimer(TIMEVAL value)
+   {
+   s_timers.set_timer(value);
+   }
+
+TIMEVAL getElapsedTime(void)
+   {
+   return s_timers.get_elapsed_time();
+   }
--- a/drivers/unix/unix.c	Tue Sep 04 17:47:46 2007 +0200
+++ b/drivers/unix/unix.c	Mon Sep 10 08:04:32 2007 +0200
@@ -124,9 +124,9 @@
 	        //LeaveMutex();
 		res = DLL_CALL(canSend)(((CANPort*)port)->fd, m);
 		//EnterMutex();
-		return res;
+		return res; // OK
 	}               
-	return -1;
+	return 1; // NOT OK
 }
 
 void canReceiveLoop(CAN_PORT port)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/win32/Makefile	Mon Sep 10 08:04:32 2007 +0200
@@ -0,0 +1,84 @@
+#! gmake
+
+#
+# Copyright (C) 2006 Laurent Bessard
+# 
+# This file is part of canfestival, a library implementing the canopen
+# stack
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# 
+
+CC = mingw32-g++
+OPT_CFLAGS = -O2
+CFLAGS = $(OPT_CFLAGS)
+PROG_CFLAGS = 
+OS_NAME = MINGW32
+ARCH_NAME = x86
+PREFIX = /usr/local
+TARGET = win32
+CAN_DRIVER = can_peak_win32
+TIMERS_DRIVER = timers_win32
+ENABLE_DLL_DRIVERS = 1
+
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(TIMERS_DRIVER)
+
+OBJS = $(TARGET).o
+
+# add timers driver if any
+ifneq ($(TIMERS_DRIVER),timers_)
+OBJS += ../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o
+endif
+
+SRC_HFILES = ../../include/$(TARGET)/applicfg.h ../../include/$(TARGET)/canfestival.h
+
+TARGET_HFILES = $(PREFIX)/include/$(TARGET)/applicfg.h $(PREFIX)/include/$(TARGET)/canfestival.h
+
+all: driver
+
+driver: $(OBJS)
+
+
+%o: %cpp
+	$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+#../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o:
+#	$(MAKE) -C ../$(TIMERS_DRIVER) driver
+
+#../$(CAN_DRIVER)/$(CAN_DRIVER).o:
+#	$(MAKE) -C ../$(CAN_DRIVER) driver
+
+libcanfestival_$(TARGET).a: $(OBJS)
+	@echo Building [libcanfestival_$(TARGET).a]
+	ar rc $@ $(OBJS)
+	ranlib $@
+
+install: libcanfestival_$(TARGET).a
+	mkdir -p $(PREFIX)/lib/
+	mkdir -p $(PREFIX)/include/canfestival
+	cp libcanfestival_$(TARGET).a $(PREFIX)/lib/
+	cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+
+uninstall:
+	rm -f $(PREFIX)/lib/libcanfestival_$(TARGET).a
+	rm -f $(TARGET_HFILES)
+
+clean:
+	rm -f $(OBJS)
+	rm -f libcanfestival_$(TARGET).a
+
+mrproper: clean
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/win32/Makefile.in	Mon Sep 10 08:04:32 2007 +0200
@@ -0,0 +1,84 @@
+#! gmake
+
+#
+# Copyright (C) 2006 Laurent Bessard
+# 
+# This file is part of canfestival, a library implementing the canopen
+# stack
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# 
+
+CC = mingw32-g++
+OPT_CFLAGS = -O2
+CFLAGS = SUB_OPT_CFLAGS
+PROG_CFLAGS = SUB_PROG_CFLAGS
+OS_NAME = SUB_OS_NAME
+ARCH_NAME = SUB_ARCH_NAME
+PREFIX = SUB_PREFIX
+TARGET = SUB_TARGET
+CAN_DRIVER = SUB_CAN_DRIVER
+TIMERS_DRIVER = SUB_TIMERS_DRIVER
+ENABLE_DLL_DRIVERS = SUB_ENABLE_DLL_DRIVERS
+
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(TIMERS_DRIVER)
+
+OBJS = $(TARGET).o
+
+# add timers driver if any
+ifneq ($(TIMERS_DRIVER),timers_)
+OBJS += ../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o
+endif
+
+SRC_HFILES = ../../include/$(TARGET)/applicfg.h ../../include/$(TARGET)/canfestival.h
+
+TARGET_HFILES = $(PREFIX)/include/$(TARGET)/applicfg.h $(PREFIX)/include/$(TARGET)/canfestival.h
+
+all: driver
+
+driver: $(OBJS)
+
+
+%o: %cpp
+	$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+#../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o:
+#	$(MAKE) -C ../$(TIMERS_DRIVER) driver
+
+#../$(CAN_DRIVER)/$(CAN_DRIVER).o:
+#	$(MAKE) -C ../$(CAN_DRIVER) driver
+
+libcanfestival_$(TARGET).a: $(OBJS)
+	@echo Building [libcanfestival_$(TARGET).a]
+	ar rc $@ $(OBJS)
+	ranlib $@
+
+install: libcanfestival_$(TARGET).a
+	mkdir -p $(PREFIX)/lib/
+	mkdir -p $(PREFIX)/include/canfestival
+	cp libcanfestival_$(TARGET).a $(PREFIX)/lib/
+	cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+
+uninstall:
+	rm -f $(PREFIX)/lib/libcanfestival_$(TARGET).a
+	rm -f $(TARGET_HFILES)
+
+clean:
+	rm -f $(OBJS)
+	rm -f libcanfestival_$(TARGET).a
+
+mrproper: clean
+
+
--- a/drivers/win32/drivers_win32.cpp	Tue Sep 04 17:47:46 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-/*
-This file is part of CanFestival, a library implementing CanOpen Stack.
-
-Copyright (C): Edouard TISSERANT and Francis DUPIN
-Copyright (C) Win32 Port Leonid Tochinski
-
-See COPYING file for copyrights details.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-/*
- CAN driver interface.
-*/
-
-#include <windows.h>
-
-extern "C"
-   {
-#define DLL_CALL(funcname) (*_##funcname)
-#define FCT_PTR_INIT =NULL
-#include "canfestival.h"
-#include "timer.h"
-
-#include "timers_driver.h"
-   };
-
-typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
-typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m);
-typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board);
-typedef int (*CANCLOSE_DRIVER_PROC)(void* inst);
-
-
-class driver_procs
-   {
-   public:
-      driver_procs();
-      ~driver_procs();
-
-      HMODULE load_canfestival_driver(LPCTSTR driver_name);
-      bool can_driver_valid() const;
-
-   public:
-      // can driver
-      CANRECEIVE_DRIVER_PROC m_canReceive;
-      CANSEND_DRIVER_PROC m_canSend;
-      CANOPEN_DRIVER_PROC m_canOpen;
-      CANCLOSE_DRIVER_PROC m_canClose;
-
-      // driver module habndle
-      HMODULE m_driver_handle;
-   };
-
-driver_procs::driver_procs() : m_canReceive(0),
-      m_canSend(0),
-      m_canOpen(0),
-      m_canClose(0),
-      m_driver_handle(0)
-   {}
-
-driver_procs::~driver_procs()
-   {
-   if (m_driver_handle)
-      ::FreeLibrary(m_driver_handle);
-   }
-
-bool driver_procs::can_driver_valid() const
-   {
-   return ((m_canReceive != NULL) &&
-           (m_canSend != NULL) &&
-           (m_canOpen != NULL) &&
-           (m_canClose != NULL));
-   }
-
-// GetProcAddress doesn't have an UNICODE version for NT
-#ifdef UNDER_CE
-  #define myTEXT(str) TEXT(str)
-#else
-  #define myTEXT(str) str
-#endif
-
-HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name)
-   {
-   if (can_driver_valid())
-      return m_driver_handle;
-   m_driver_handle = ::LoadLibrary(driver_name);
-   if (m_driver_handle == NULL)
-      return NULL;
-
-   m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver"));
-   m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver"));
-   m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver"));
-   m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver"));
-   return can_driver_valid()?m_driver_handle:NULL;
-   }
-
-struct driver_data
-   {
-   CO_Data * d;
-   HANDLE receive_thread;
-   void* inst;
-   volatile bool continue_receive_thread;
-   };
-
-driver_procs s_driver_procs;
-
-LIB_HANDLE LoadCanDriver(char* driver_name)
-   {
-		return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name);
-   }
-
-UNS8 canReceive(CAN_PORT fd0, Message *m)
-   {
-   if (fd0 != NULL && s_driver_procs.m_canReceive != NULL)
-	   {
-		  driver_data* data = (driver_data*)fd0;
-		  return (*s_driver_procs.m_canReceive)(data->inst, m);
-	   }
-   return 1;
-   }
-
-void* canReceiveLoop(CAN_PORT fd0)
-   {
-   driver_data* data = (driver_data*)fd0;
-   Message m;
-   while (data->continue_receive_thread)
-      {
-      if (!canReceive(fd0, &m))
-         {
-         EnterMutex();
-         canDispatch(data->d, &m);
-         LeaveMutex();
-         }
-      else
-         {
-		 break;
-         ::Sleep(1);
-         }
-      }
-   return 0;
-   }
-
-/***************************************************************************/
-UNS8 canSend(CAN_PORT fd0, Message *m)
-   {
-   if (fd0 != NULL && s_driver_procs.m_canSend != NULL)
-      {
-      UNS8 res;
-      driver_data* data = (driver_data*)fd0;
-      res = (*s_driver_procs.m_canSend)(data->inst, m);      
-      if (res)
-         return 0;
-      }
-   return 1;
-   }
-
-/***************************************************************************/
-CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
-   {
-   if (board != NULL && s_driver_procs.m_canOpen != NULL)
-      {
-      void* inst = (*s_driver_procs.m_canOpen)(board);
-      if (inst != NULL)
-         {
-         driver_data* data = new driver_data;
-         data->d = d;
-         data->inst = inst;
-         data->continue_receive_thread = true;
-         CreateReceiveTask(data, &data->receive_thread, &canReceiveLoop);
-	 EnterMutex();
-         d->canHandle = data;
-         LeaveMutex();
-         return data;
-         }
-      }
-   return NULL;
-   }
-
-/***************************************************************************/
-int canClose(CO_Data * d)
-   {
-   if (s_driver_procs.m_canClose != NULL)
-      {
-		  driver_data* data;
-		  EnterMutex();
-		  if(d->canHandle != NULL){
-			data = (driver_data*)d->canHandle;
-			d->canHandle = NULL;
-			data->continue_receive_thread = false;}
-		  LeaveMutex();
-		  WaitReceiveTaskEnd(&data->receive_thread);
-		  (*s_driver_procs.m_canClose)(data->inst);
-		  delete data;
-		  return 0;
-      }
-   return 0;
-   }
-
-
--- a/drivers/win32/timers_win32.cpp	Tue Sep 04 17:47:46 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
-This file is part of CanFestival, a library implementing CanOpen Stack.
-
-Copyright (C): Edouard TISSERANT and Francis DUPIN
-Copyright (C) Win32 Port Leonid Tochinski
-
-See COPYING file for copyrights details.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-
-
-#include <windows.h>
-#include <stdlib.h>
-
-extern "C"
-{
-#include "applicfg.h"
-#include "can_driver.h"
-#include "timer.h"
-#include "timers_driver.h"
-};
-
-// --------------- Synchronization Object Implementation ---------------
-class ccritical_section
-   {
-   public:
-      ccritical_section()
-         {
-         ::InitializeCriticalSection(&m_cs);
-         }
-      ~ccritical_section()
-         {
-         ::DeleteCriticalSection(&m_cs);
-         }
-      void enter()
-         {
-         ::EnterCriticalSection(&m_cs);
-         }
-      void leave()
-         {
-         ::LeaveCriticalSection(&m_cs);
-         }
-   private:
-      CRITICAL_SECTION m_cs;
-   };
-
-static ccritical_section g_cs;
-
-
-void EnterMutex(void)
-   {
-   g_cs.enter();
-   }
-
-void LeaveMutex(void)
-   {
-   g_cs.leave();
-   }
-// --------------- Synchronization Object Implementation ---------------
-
-
-// --------------- CAN Receive Thread Implementation ---------------
-
-void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
-   {
-   unsigned long thread_id = 0;
-   *Thread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id);
-   }
-
-void WaitReceiveTaskEnd(TASK_HANDLE Thread)
-   {
-   ::WaitForSingleObject(Thread, INFINITE);
-   ::CloseHandle(Thread);
-   //*Thread = NULL;
-   }
-// --------------- CAN Receive Thread Implementation ---------------
-
-
-// --------------- Timer Thread Implementation ---------------
-class class_timers
-   {
-   public:
-      class_timers();
-      ~class_timers();
-      void start_timer_thread();
-      void resume_timer_thread();
-      void stop_timer_thread();
-      void set_timer(TIMEVAL value);
-      TIMEVAL get_elapsed_time();
-   private:
-      TIMEVAL get_timer() const;   
-      static DWORD WINAPI timer_loop_thread_proc(void* arg);
-   private:
-      TIMEVAL m_last_occured_alarm_time;
-      volatile TIMEVAL m_last_alarm_set_time;
-      HANDLE m_timer_thread;
-      volatile bool m_continue_timer_loop;
-      bool m_use_hi_res_timer;
-      double m_counts_per_usec;
-   };
-
-class_timers::class_timers() : m_last_occured_alarm_time(TIMEVAL_MAX),
-      m_last_alarm_set_time(TIMEVAL_MAX),
-      m_timer_thread(0),
-      m_continue_timer_loop(false),
-      m_use_hi_res_timer(false),
-      m_counts_per_usec(0.)
-   {
-   // initialize hi resolution timer
-   LARGE_INTEGER counts_per_sec = {0, 0};
-   if (::QueryPerformanceFrequency(&counts_per_sec) && counts_per_sec.QuadPart > 0)
-      {
-      m_use_hi_res_timer = true;
-      m_counts_per_usec = counts_per_sec.QuadPart / 1000000.;
-      }
-   m_use_hi_res_timer = true;
-   }
-
-class_timers::~class_timers()
-   {
-   stop_timer_thread();
-   }
-
-// time is in micro seconds
-TIMEVAL class_timers::get_timer() const
-   {
-   if (m_use_hi_res_timer)
-      {
-      LARGE_INTEGER performance_count = {0, 0};
-      ::QueryPerformanceCounter(&performance_count);
-      return (TIMEVAL)(performance_count.QuadPart / m_counts_per_usec);
-      }
-   // hi-res timer is unavailable
-   return 1000 * ::GetTickCount();
-   }
-
-DWORD WINAPI class_timers::timer_loop_thread_proc(void* arg)
-   {
-   class_timers* This = reinterpret_cast<class_timers*>(arg);
-   while (This->m_continue_timer_loop)
-      {
-      TIMEVAL cur_time = This->get_timer();
-      if (cur_time >= This->m_last_alarm_set_time)
-         {
-         This->m_last_occured_alarm_time = cur_time;
-         This->m_last_alarm_set_time = TIMEVAL_MAX;         
-         EnterMutex();
-         TimeDispatch();
-         LeaveMutex();
-         }
-      else
-         {
-         ::Sleep(1);
-         }
-      }
-   return 0;
-   }
-
-void class_timers::start_timer_thread()
-   {
-   if (m_timer_thread == 0)
-      {
-      unsigned long thread_id = 0;
-      m_timer_thread = ::CreateThread(NULL, 0, &timer_loop_thread_proc, this, CREATE_SUSPENDED, &thread_id);
-      m_last_alarm_set_time = TIMEVAL_MAX;
-      m_last_occured_alarm_time = get_timer();
-      }
-   }
-
-void class_timers::resume_timer_thread()
-   {
-   if (m_timer_thread)
-      {
-      m_continue_timer_loop = true;
-      ::ResumeThread(m_timer_thread);
-      }
-   }
-
-void class_timers::stop_timer_thread()
-   {
-   if (m_timer_thread)
-      {
-      m_continue_timer_loop = false;
-      ::WaitForSingleObject(m_timer_thread, INFINITE);
-      ::CloseHandle(m_timer_thread);
-      m_timer_thread = 0;
-      }
-   }
-
-void class_timers::set_timer(TIMEVAL value)
-   {
-   m_last_alarm_set_time = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : get_timer() + value;
-   }
-
-// elapsed time since last occured alarm
-TIMEVAL class_timers::get_elapsed_time()
-   {
-   return get_timer() - m_last_occured_alarm_time;
-   }
-
-// ----------------------------------------------------------
-
-static class_timers s_timers;
-
-void StartTimerLoop(TimerCallback_t init_callback)
-   {
-   s_timers.start_timer_thread();
-   // At first, TimeDispatch will call init_callback.
-   if (init_callback != NULL)
-      SetAlarm(NULL, 0, init_callback, (TIMEVAL)0, (TIMEVAL)0);
-   s_timers.resume_timer_thread();
-   }
-
-void StopTimerLoop(void)
-   {
-   s_timers.stop_timer_thread();
-   }
-
-void setTimer(TIMEVAL value)
-   {
-   s_timers.set_timer(value);
-   }
-
-TIMEVAL getElapsedTime(void)
-   {
-   return s_timers.get_elapsed_time();
-   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/win32/win32.cpp	Mon Sep 10 08:04:32 2007 +0200
@@ -0,0 +1,218 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+Copyright (C) Win32 Port Leonid Tochinski
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ CAN driver interface.
+*/
+
+#include <windows.h>
+
+extern "C"
+   {
+#define DLL_CALL(funcname) (*_##funcname)
+#define FCT_PTR_INIT =NULL
+#include "canfestival.h"
+#include "timer.h"
+
+#include "timers_driver.h"
+   };
+
+typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
+typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m);
+typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board);
+typedef int (*CANCLOSE_DRIVER_PROC)(void* inst);
+
+
+class driver_procs
+   {
+   public:
+      driver_procs();
+      ~driver_procs();
+
+      HMODULE load_canfestival_driver(LPCTSTR driver_name);
+      bool can_driver_valid() const;
+
+   public:
+      // can driver
+      CANRECEIVE_DRIVER_PROC m_canReceive;
+      CANSEND_DRIVER_PROC m_canSend;
+      CANOPEN_DRIVER_PROC m_canOpen;
+      CANCLOSE_DRIVER_PROC m_canClose;
+
+      // driver module habndle
+      HMODULE m_driver_handle;
+   };
+
+driver_procs::driver_procs() : m_canReceive(0),
+      m_canSend(0),
+      m_canOpen(0),
+      m_canClose(0),
+      m_driver_handle(0)
+   {}
+
+driver_procs::~driver_procs()
+   {
+   if (m_driver_handle)
+      ::FreeLibrary(m_driver_handle);
+   }
+
+bool driver_procs::can_driver_valid() const
+   {
+   return ((m_canReceive != NULL) &&
+           (m_canSend != NULL) &&
+           (m_canOpen != NULL) &&
+           (m_canClose != NULL));
+   }
+
+// GetProcAddress doesn't have an UNICODE version for NT
+#ifdef UNDER_CE
+  #define myTEXT(str) TEXT(str)
+#else
+  #define myTEXT(str) str
+#endif
+
+HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name)
+   {
+  //LPCTSTR driver1 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll";
+  //LPCTSTR driver2 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll";
+  //printf("can_driver_valid=%d\n",can_driver_valid());
+   if (can_driver_valid())
+      return m_driver_handle;
+   printf("driver_name=%s\n",driver_name);
+   m_driver_handle = ::LoadLibrary(driver_name);
+   //printf("m_driver_handle=%d\n",m_driver_handle);
+   //printf("testerror =%s\n",GetLastError());
+   if (m_driver_handle == NULL)
+      return NULL;
+
+   m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver"));
+   m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver"));
+   m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver"));
+   m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver"));
+   return can_driver_valid()?m_driver_handle:NULL;
+   }
+
+struct driver_data
+   {
+   CO_Data * d;
+   HANDLE receive_thread;
+   void* inst;
+   volatile bool continue_receive_thread;
+   };
+
+driver_procs s_driver_procs;
+
+LIB_HANDLE LoadCanDriver(char* driver_name)
+   {
+		return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name);
+   }
+
+UNS8 canReceive(CAN_PORT fd0, Message *m)
+   {
+  
+   if (fd0 != NULL && s_driver_procs.m_canReceive != NULL)
+	   {
+		  driver_data* data = (driver_data*)fd0;
+		  return (*s_driver_procs.m_canReceive)(data->inst, m);
+	   }
+   return 1;
+   }
+
+void* canReceiveLoop(CAN_PORT fd0)
+   {
+   driver_data* data = (driver_data*)fd0;
+   Message m;
+   while (data->continue_receive_thread)
+      {
+      if (!canReceive(fd0, &m))
+         {
+         EnterMutex();
+         canDispatch(data->d, &m);
+         LeaveMutex();
+         }
+      else
+         {
+		 break;
+         ::Sleep(1);
+         }
+      }
+   return 0;
+   }
+
+/***************************************************************************/
+UNS8 canSend(CAN_PORT fd0, Message *m)
+   {   
+   if (fd0 != NULL && s_driver_procs.m_canSend != NULL)
+      {
+      UNS8 res;
+      driver_data* data = (driver_data*)fd0;
+      res = (*s_driver_procs.m_canSend)(data->inst, m);      
+      if (res)
+         return 1; // OK
+      }
+   return 0; // NOT OK
+   }
+
+/***************************************************************************/
+CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
+   {
+   if (board != NULL && s_driver_procs.m_canOpen != NULL)
+      {
+      void* inst = (*s_driver_procs.m_canOpen)(board);
+      if (inst != NULL)
+         {
+         driver_data* data = new driver_data;
+         data->d = d;
+         data->inst = inst;
+         data->continue_receive_thread = true;
+         CreateReceiveTask(data, &data->receive_thread, (void*)&canReceiveLoop);
+	 EnterMutex();
+         d->canHandle = data;
+         LeaveMutex();
+         return data;
+         }
+      }
+   return NULL;
+   }
+
+/***************************************************************************/
+int canClose(CO_Data * d)
+   {
+   if (s_driver_procs.m_canClose != NULL)
+      {
+		  driver_data* data;
+		  EnterMutex();
+		  if(d->canHandle != NULL){
+			data = (driver_data*)d->canHandle;
+			d->canHandle = NULL;
+			data->continue_receive_thread = false;}
+		  LeaveMutex();
+		  WaitReceiveTaskEnd(&data->receive_thread);
+		  (*s_driver_procs.m_canClose)(data->inst);
+		  delete data;
+		  return 0;
+      }
+   return 0;
+   }
+
+
--- a/examples/Makefile.in	Tue Sep 04 17:47:46 2007 +0200
+++ b/examples/Makefile.in	Mon Sep 10 08:04:32 2007 +0200
@@ -35,6 +35,13 @@
 	$(MAKE) -C TestMasterMicroMod $@
 endif
 
+ifeq ($(TARGET),win32)
+	$(MAKE) -C TestMasterSlave $@
+#	$(MAKE) -C DS401_Master $@
+#	$(MAKE) -C DS401_Slave_Gui $@
+	$(MAKE) -C TestMasterMicroMod $@
+endif
+
 clean:
 ifeq ($(TARGET),hc12)
 	$(MAKE) -C gene_SYNC_HCS12 $@
@@ -47,6 +54,12 @@
 	$(MAKE) -C TestMasterMicroMod $@
 endif
 
+ifeq ($(TARGET),win32)
+	$(MAKE) -C TestMasterSlave $@
+#	$(MAKE) -C DS401_Master $@
+#	$(MAKE) -C DS401_Slave_Gui $@
+	$(MAKE) -C TestMasterMicroMod $@
+endif
 
 
 mrproper: clean
--- a/examples/TestMasterMicroMod/Makefile.in	Tue Sep 04 17:47:46 2007 +0200
+++ b/examples/TestMasterMicroMod/Makefile.in	Mon Sep 10 08:04:32 2007 +0200
@@ -32,13 +32,21 @@
 TARGET = SUB_TARGET
 CAN_DRIVER = SUB_CAN_DRIVER
 TIMERS_DRIVER = SUB_TIMERS_DRIVER
-
+TESTMASTERMICROMOD = "TestMasterMicroMod"
 INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
 
 MASTER_OBJS = TestMaster.o TestMasterMicroMod.o
 
 OBJS = $(MASTER_OBJS) ../../src/libcanfestival.a ../../drivers/$(TARGET)/libcanfestival_$(TARGET).a
 
+ifeq ($(TARGET),win32)
+	TESTMASTERMICROMOD = "TestMasterMicroMod.exe"
+endif
+
+ifeq ($(TIMERS_DRIVER),timers_win32)
+	EXE_CFLAGS =
+endif
+
 ifeq ($(TIMERS_DRIVER),timers_xeno)
 	PROGDEFINES = -DUSE_XENO
 endif
@@ -50,7 +58,7 @@
 
 
 TestMasterMicroMod: TestMaster.c $(OBJS)
-	$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) $(EXE_CFLAGS)
+	g++ $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) $(EXE_CFLAGS)
 
 	
 TestMaster.c: TestMaster.od
@@ -62,7 +70,7 @@
 
 clean:
 	rm -f $(MASTER_OBJS)
-	rm -f TestMasterMicroMod
+	rm -f $(TESTMASTERMICROMOD)
 
 mrproper: clean
 	rm -f TestMaster.c
--- a/examples/TestMasterSlave/Makefile.in	Tue Sep 04 17:47:46 2007 +0200
+++ b/examples/TestMasterSlave/Makefile.in	Mon Sep 10 08:04:32 2007 +0200
@@ -32,6 +32,7 @@
 TARGET = SUB_TARGET
 CAN_DRIVER = SUB_CAN_DRIVER
 TIMERS_DRIVER = SUB_TIMERS_DRIVER
+TESTMASTERSLAVE = "TestMasterSlave"
 
 INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
 
@@ -39,6 +40,14 @@
 
 OBJS = $(MASTER_OBJS) ../../src/libcanfestival.a ../../drivers/$(TARGET)/libcanfestival_$(TARGET).a
 
+ifeq ($(TARGET),win32)
+	TESTMASTERSLAVE = "TestMasterSlave.exe"
+endif
+
+ifeq ($(TIMERS_DRIVER),timers_win32)
+	EXE_CFLAGS =
+endif
+
 ifeq ($(TIMERS_DRIVER),timers_xeno)
 	PROGDEFINES = -DUSE_XENO
 endif
@@ -50,7 +59,7 @@
 
 
 TestMasterSlave: TestSlave.c TestMaster.c $(OBJS)
-	$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) $(EXE_CFLAGS)
+	g++ $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) $(EXE_CFLAGS)
 	
 TestSlave.c: TestSlave.od
 	$(MAKE) -C ../../objdictgen gnosis
@@ -65,8 +74,8 @@
 
 clean:
 	rm -f $(MASTER_OBJS)
-	rm -f TestMasterSlave
-
+	rm -f $(TESTMASTERSLAVE)
+		
 mrproper: clean
 	rm -f TestSlave.c
 	rm -f TestMaster.c