drivers/win32/win32.c
changeset 556 8296acd119a9
child 577 0bb82be64630
equal deleted inserted replaced
555:ee24dcbd3e64 556:8296acd119a9
       
     1 /*
       
     2 This file is part of CanFestival, a library implementing CanOpen Stack.
       
     3 
       
     4 Copyright (C): Edouard TISSERANT and Francis DUPIN
       
     5 Copyright (C) Win32 Port Leonid Tochinski
       
     6 
       
     7 See COPYING file for copyrights details.
       
     8 
       
     9 This library is free software; you can redistribute it and/or
       
    10 modify it under the terms of the GNU Lesser General Public
       
    11 License as published by the Free Software Foundation; either
       
    12 version 2.1 of the License, or (at your option) any later version.
       
    13 
       
    14 This library is distributed in the hope that it will be useful,
       
    15 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    17 Lesser General Public License for more details.
       
    18 
       
    19 You should have received a copy of the GNU Lesser General Public
       
    20 License along with this library; if not, write to the Free Software
       
    21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    22 */
       
    23 
       
    24 /*
       
    25  CAN driver interface.
       
    26 */
       
    27 
       
    28 #include <windows.h>
       
    29 
       
    30 #include "canfestival.h"
       
    31 #include "timer.h"
       
    32 #include "timers_driver.h"
       
    33 
       
    34 // GetProcAddress doesn't have an UNICODE version for NT
       
    35 #ifdef UNDER_CE
       
    36   #define myTEXT(str) TEXT(str)
       
    37 #else
       
    38   #define myTEXT(str) str
       
    39 #endif
       
    40 
       
    41 #define MAX_NB_CAN_PORTS 16
       
    42 
       
    43 typedef UNS8 (CALLBACK* CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
       
    44 typedef UNS8 (CALLBACK* CANSEND_DRIVER_PROC)(void* inst, const Message *m);
       
    45 typedef void* (CALLBACK* CANOPEN_DRIVER_PROC)(s_BOARD *board);
       
    46 typedef int (CALLBACK* CANCLOSE_DRIVER_PROC)(void* inst);
       
    47 typedef UNS8 (CALLBACK* CANCHANGEBAUDRATE_DRIVER_PROC)(void* fd, char* baud);
       
    48 
       
    49 CANRECEIVE_DRIVER_PROC m_canReceive;
       
    50 CANSEND_DRIVER_PROC m_canSend;
       
    51 CANOPEN_DRIVER_PROC m_canOpen;
       
    52 CANCLOSE_DRIVER_PROC m_canClose;
       
    53 CANCHANGEBAUDRATE_DRIVER_PROC m_canChangeBaudRate;
       
    54 
       
    55 /* CAN port structure */
       
    56 typedef struct
       
    57 {
       
    58   char used;  /**< flag indicating CAN port usage, will be used to abort Receiver task*/
       
    59   CAN_HANDLE fd; /**< CAN port file descriptor*/
       
    60   TASK_HANDLE receiveTask; /**< CAN Receiver task*/
       
    61   CO_Data* d; /**< CAN object data*/
       
    62 }CANPort;
       
    63 
       
    64 CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}};
       
    65 
       
    66 
       
    67 /***************************************************************************/
       
    68 UNS8 UnLoadCanDriver(LIB_HANDLE handle)
       
    69 {
       
    70 	if(handle != NULL)
       
    71 	{
       
    72 		FreeLibrary(handle);
       
    73 		handle=NULL;
       
    74 		return 0;
       
    75 	}
       
    76 	return -1;
       
    77 }
       
    78 
       
    79 /***************************************************************************/
       
    80 /**
       
    81  * Loads the dll and get funcs ptr
       
    82  *
       
    83  * @param driver_name String containing driver's dynamic library name
       
    84  * @return Library handle
       
    85  */
       
    86 LIB_HANDLE LoadCanDriver(LPCTSTR driver_name)
       
    87 {
       
    88 	// driver module handle
       
    89 	LIB_HANDLE handle = NULL;
       
    90 
       
    91 	if(handle == NULL)
       
    92 	{
       
    93 		handle = LoadLibrary(driver_name);
       
    94 	}
       
    95 	
       
    96 	if (!handle) 
       
    97 	{
       
    98 		fprintf (stderr, "%s\n", GetLastError());
       
    99     	return NULL;
       
   100 	}
       
   101 
       
   102 	m_canReceive = (CANRECEIVE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canReceive_driver"));
       
   103 	m_canSend = (CANSEND_DRIVER_PROC)GetProcAddress(handle, myTEXT("canSend_driver"));
       
   104 	m_canOpen = (CANOPEN_DRIVER_PROC)GetProcAddress(handle, myTEXT("canOpen_driver"));
       
   105 	m_canClose = (CANCLOSE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canClose_driver"));
       
   106 	m_canChangeBaudRate = (CANCHANGEBAUDRATE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canChangeBaudRate_driver"));
       
   107 	
       
   108 	return handle;
       
   109 }
       
   110 
       
   111 /***************************************************************************/
       
   112 UNS8 canSend(CAN_PORT port, Message *m)
       
   113 {
       
   114 	UNS8 res;
       
   115 	if (port && (m_canSend != NULL))
       
   116 	{
       
   117 		res = m_canSend(((CANPort*)port)->fd, m);
       
   118 		if (res) return 1; // OK
       
   119 	}
       
   120 	return 0; // NOT OK
       
   121 }
       
   122 
       
   123 /***************************************************************************/
       
   124 void canReceiveLoop(CAN_PORT port)
       
   125 {
       
   126 	Message m;
       
   127 	while(((CANPort*)port)->used)
       
   128 	{
       
   129 		if(m_canReceive(((CANPort*)port)->fd, &m) != 0) break;
       
   130 		EnterMutex();
       
   131 		canDispatch(((CANPort*)port)->d, &m);
       
   132 		LeaveMutex();
       
   133 	}
       
   134 }
       
   135 
       
   136 /***************************************************************************/
       
   137 CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
       
   138 {
       
   139 	int i;
       
   140 	for(i=0; i < MAX_NB_CAN_PORTS; i++)
       
   141 	{
       
   142 		if(!canports[i].used)
       
   143 		break;
       
   144 	}
       
   145 
       
   146 	#ifndef NOT_USE_DYNAMIC_LOADING	
       
   147 	if (m_canOpen == NULL)
       
   148 	{
       
   149 	   	fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
       
   150 	   	return NULL;
       
   151 	}
       
   152 	#endif
       
   153 	
       
   154 	CAN_HANDLE fd0 = m_canOpen(board);
       
   155 	if(fd0)
       
   156 	{
       
   157 		canports[i].used = 1;
       
   158 		canports[i].fd = fd0;
       
   159 		canports[i].d = d;
       
   160 		d->canHandle = (CAN_PORT)&canports[i];
       
   161 		CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
       
   162 		return (CAN_PORT)&canports[i];
       
   163 	}
       
   164 	else
       
   165 	{
       
   166 		MSG("CanOpen : Cannot open board {busname='%s',baudrate='%s'}\n",board->busname, board->baudrate);
       
   167 		return NULL;
       
   168 	}
       
   169 }
       
   170 
       
   171 /***************************************************************************/
       
   172 int canClose(CO_Data * d)
       
   173 {
       
   174 	UNS8 res;
       
   175 	
       
   176 	((CANPort*)d->canHandle)->used = 0;
       
   177 	CANPort* tmp = (CANPort*)d->canHandle;
       
   178 	d->canHandle = NULL;
       
   179 	
       
   180 	// close CAN port
       
   181 	res = m_canClose(tmp->fd);
       
   182 
       
   183 	// kill receiver task
       
   184 	WaitReceiveTaskEnd(&tmp->receiveTask);
       
   185 	
       
   186 	return res;
       
   187 }
       
   188 
       
   189 UNS8 canChangeBaudRate(CAN_PORT port, char* baud)
       
   190 {
       
   191    if(port){
       
   192 		UNS8 res;
       
   193 	    //LeaveMutex();
       
   194 		res = m_canChangeBaudRate(((CANPort*)port)->fd, baud);
       
   195 		//EnterMutex();
       
   196 		return res; // OK
       
   197 	}               
       
   198 	return 1; // NOT OK
       
   199 }
       
   200