2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
5 Copyright (C) Win32 Port Leonid Tochinski
7 See COPYING file for copyrights details.
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.
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.
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
32 #define DLL_CALL(funcname) (*_##funcname)
33 #define FCT_PTR_INIT =NULL
34 #include "canfestival.h"
37 #include "timers_driver.h"
40 typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
41 typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m);
42 typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board);
43 typedef int (*CANCLOSE_DRIVER_PROC)(void* inst);
52 HMODULE load_canfestival_driver(LPCTSTR driver_name);
53 bool can_driver_valid() const;
57 CANRECEIVE_DRIVER_PROC m_canReceive;
58 CANSEND_DRIVER_PROC m_canSend;
59 CANOPEN_DRIVER_PROC m_canOpen;
60 CANCLOSE_DRIVER_PROC m_canClose;
62 // driver module habndle
63 HMODULE m_driver_handle;
66 driver_procs::driver_procs() : m_canReceive(0),
73 driver_procs::~driver_procs()
76 ::FreeLibrary(m_driver_handle);
79 bool driver_procs::can_driver_valid() const
81 return ((m_canReceive != NULL) &&
82 (m_canSend != NULL) &&
83 (m_canOpen != NULL) &&
84 (m_canClose != NULL));
87 // GetProcAddress doesn't have an UNICODE version for NT
89 #define myTEXT(str) TEXT(str)
91 #define myTEXT(str) str
94 HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name)
96 if (can_driver_valid())
97 return m_driver_handle;
98 m_driver_handle = ::LoadLibrary(driver_name);
99 if (m_driver_handle == NULL)
102 m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver"));
103 m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver"));
104 m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver"));
105 m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver"));
106 return can_driver_valid()?m_driver_handle:NULL;
112 HANDLE receive_thread;
114 volatile bool continue_receive_thread;
117 driver_procs s_driver_procs;
119 LIB_HANDLE LoadCanDriver(char* driver_name)
121 return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name);
124 UNS8 canReceive(CAN_PORT fd0, Message *m)
126 if (fd0 != NULL && s_driver_procs.m_canReceive != NULL)
128 driver_data* data = (driver_data*)fd0;
129 return (*s_driver_procs.m_canReceive)(data->inst, m);
134 void* canReceiveLoop(CAN_PORT fd0)
136 driver_data* data = (driver_data*)fd0;
138 while (data->continue_receive_thread)
140 if (!canReceive(fd0, &m))
143 canDispatch(data->d, &m);
155 /***************************************************************************/
156 UNS8 canSend(CAN_PORT fd0, Message *m)
158 if (fd0 != NULL && s_driver_procs.m_canSend != NULL)
161 driver_data* data = (driver_data*)fd0;
163 res = (*s_driver_procs.m_canSend)(data->inst, m);
171 /***************************************************************************/
172 CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
174 if (board != NULL && s_driver_procs.m_canOpen != NULL)
176 void* inst = (*s_driver_procs.m_canOpen)(board);
179 driver_data* data = new driver_data;
182 data->continue_receive_thread = true;
183 CreateReceiveTask(data, &data->receive_thread, &canReceiveLoop);
193 /***************************************************************************/
194 int canClose(CO_Data * d)
196 if (s_driver_procs.m_canClose != NULL)
200 if(d->canHandle != NULL){
201 data = (driver_data*)d->canHandle;
203 data->continue_receive_thread = false;}
205 WaitReceiveTaskEnd(&data->receive_thread);
206 (*s_driver_procs.m_canClose)(data->inst);