drivers/win32/win32.c
changeset 556 8296acd119a9
child 577 0bb82be64630
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/win32/win32.c	Wed Jul 15 09:36:36 2009 +0200
@@ -0,0 +1,200 @@
+/*
+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>
+
+#include "canfestival.h"
+#include "timer.h"
+#include "timers_driver.h"
+
+// GetProcAddress doesn't have an UNICODE version for NT
+#ifdef UNDER_CE
+  #define myTEXT(str) TEXT(str)
+#else
+  #define myTEXT(str) str
+#endif
+
+#define MAX_NB_CAN_PORTS 16
+
+typedef UNS8 (CALLBACK* CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
+typedef UNS8 (CALLBACK* CANSEND_DRIVER_PROC)(void* inst, const Message *m);
+typedef void* (CALLBACK* CANOPEN_DRIVER_PROC)(s_BOARD *board);
+typedef int (CALLBACK* CANCLOSE_DRIVER_PROC)(void* inst);
+typedef UNS8 (CALLBACK* CANCHANGEBAUDRATE_DRIVER_PROC)(void* fd, char* baud);
+
+CANRECEIVE_DRIVER_PROC m_canReceive;
+CANSEND_DRIVER_PROC m_canSend;
+CANOPEN_DRIVER_PROC m_canOpen;
+CANCLOSE_DRIVER_PROC m_canClose;
+CANCHANGEBAUDRATE_DRIVER_PROC m_canChangeBaudRate;
+
+/* CAN port structure */
+typedef struct
+{
+  char used;  /**< flag indicating CAN port usage, will be used to abort Receiver task*/
+  CAN_HANDLE fd; /**< CAN port file descriptor*/
+  TASK_HANDLE receiveTask; /**< CAN Receiver task*/
+  CO_Data* d; /**< CAN object data*/
+}CANPort;
+
+CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}};
+
+
+/***************************************************************************/
+UNS8 UnLoadCanDriver(LIB_HANDLE handle)
+{
+	if(handle != NULL)
+	{
+		FreeLibrary(handle);
+		handle=NULL;
+		return 0;
+	}
+	return -1;
+}
+
+/***************************************************************************/
+/**
+ * Loads the dll and get funcs ptr
+ *
+ * @param driver_name String containing driver's dynamic library name
+ * @return Library handle
+ */
+LIB_HANDLE LoadCanDriver(LPCTSTR driver_name)
+{
+	// driver module handle
+	LIB_HANDLE handle = NULL;
+
+	if(handle == NULL)
+	{
+		handle = LoadLibrary(driver_name);
+	}
+	
+	if (!handle) 
+	{
+		fprintf (stderr, "%s\n", GetLastError());
+    	return NULL;
+	}
+
+	m_canReceive = (CANRECEIVE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canReceive_driver"));
+	m_canSend = (CANSEND_DRIVER_PROC)GetProcAddress(handle, myTEXT("canSend_driver"));
+	m_canOpen = (CANOPEN_DRIVER_PROC)GetProcAddress(handle, myTEXT("canOpen_driver"));
+	m_canClose = (CANCLOSE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canClose_driver"));
+	m_canChangeBaudRate = (CANCHANGEBAUDRATE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canChangeBaudRate_driver"));
+	
+	return handle;
+}
+
+/***************************************************************************/
+UNS8 canSend(CAN_PORT port, Message *m)
+{
+	UNS8 res;
+	if (port && (m_canSend != NULL))
+	{
+		res = m_canSend(((CANPort*)port)->fd, m);
+		if (res) return 1; // OK
+	}
+	return 0; // NOT OK
+}
+
+/***************************************************************************/
+void canReceiveLoop(CAN_PORT port)
+{
+	Message m;
+	while(((CANPort*)port)->used)
+	{
+		if(m_canReceive(((CANPort*)port)->fd, &m) != 0) break;
+		EnterMutex();
+		canDispatch(((CANPort*)port)->d, &m);
+		LeaveMutex();
+	}
+}
+
+/***************************************************************************/
+CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
+{
+	int i;
+	for(i=0; i < MAX_NB_CAN_PORTS; i++)
+	{
+		if(!canports[i].used)
+		break;
+	}
+
+	#ifndef NOT_USE_DYNAMIC_LOADING	
+	if (m_canOpen == NULL)
+	{
+	   	fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
+	   	return NULL;
+	}
+	#endif
+	
+	CAN_HANDLE fd0 = m_canOpen(board);
+	if(fd0)
+	{
+		canports[i].used = 1;
+		canports[i].fd = fd0;
+		canports[i].d = d;
+		d->canHandle = (CAN_PORT)&canports[i];
+		CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
+		return (CAN_PORT)&canports[i];
+	}
+	else
+	{
+		MSG("CanOpen : Cannot open board {busname='%s',baudrate='%s'}\n",board->busname, board->baudrate);
+		return NULL;
+	}
+}
+
+/***************************************************************************/
+int canClose(CO_Data * d)
+{
+	UNS8 res;
+	
+	((CANPort*)d->canHandle)->used = 0;
+	CANPort* tmp = (CANPort*)d->canHandle;
+	d->canHandle = NULL;
+	
+	// close CAN port
+	res = m_canClose(tmp->fd);
+
+	// kill receiver task
+	WaitReceiveTaskEnd(&tmp->receiveTask);
+	
+	return res;
+}
+
+UNS8 canChangeBaudRate(CAN_PORT port, char* baud)
+{
+   if(port){
+		UNS8 res;
+	    //LeaveMutex();
+		res = m_canChangeBaudRate(((CANPort*)port)->fd, baud);
+		//EnterMutex();
+		return res; // OK
+	}               
+	return 1; // NOT OK
+}
+