]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - drivers/win32/win32.cpp
af90fe5b00283f8d9ecac0047dc6265fa2482ba6
[CanFestival-3.git] / drivers / win32 / win32.cpp
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 extern "C"
31    {
32 #define DLL_CALL(funcname) (*_##funcname)
33 #define FCT_PTR_INIT =NULL
34 #include "canfestival.h"
35 #include "timer.h"
36
37 #include "timers_driver.h"
38    };
39
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);
44
45
46 class driver_procs
47    {
48    public:
49       driver_procs();
50       ~driver_procs();
51
52       HMODULE load_canfestival_driver(LPCTSTR driver_name);
53       bool can_driver_valid() const;
54
55    public:
56       // can driver
57       CANRECEIVE_DRIVER_PROC m_canReceive;
58       CANSEND_DRIVER_PROC m_canSend;
59       CANOPEN_DRIVER_PROC m_canOpen;
60       CANCLOSE_DRIVER_PROC m_canClose;
61
62       // driver module habndle
63       HMODULE m_driver_handle;
64    };
65
66 driver_procs::driver_procs() : m_canReceive(0),
67       m_canSend(0),
68       m_canOpen(0),
69       m_canClose(0),
70       m_driver_handle(0)
71    {}
72
73 driver_procs::~driver_procs()
74    {
75    if (m_driver_handle)
76       ::FreeLibrary(m_driver_handle);
77    }
78
79 bool driver_procs::can_driver_valid() const
80    {
81    return ((m_canReceive != NULL) &&
82            (m_canSend != NULL) &&
83            (m_canOpen != NULL) &&
84            (m_canClose != NULL));
85    }
86
87 // GetProcAddress doesn't have an UNICODE version for NT
88 #ifdef UNDER_CE
89   #define myTEXT(str) TEXT(str)
90 #else
91   #define myTEXT(str) str
92 #endif
93
94 HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name)
95    {
96   //LPCTSTR driver1 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll";
97   //LPCTSTR driver2 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll";
98   //printf("can_driver_valid=%d\n",can_driver_valid());
99    if (can_driver_valid())
100       return m_driver_handle;
101    printf("driver_name=%s\n",driver_name);
102    m_driver_handle = ::LoadLibrary(driver_name);
103    //printf("m_driver_handle=%d\n",m_driver_handle);
104    //printf("testerror =%s\n",GetLastError());
105    if (m_driver_handle == NULL)
106       return NULL;
107
108    m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver"));
109    m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver"));
110    m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver"));
111    m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver"));
112    return can_driver_valid()?m_driver_handle:NULL;
113    }
114
115 struct driver_data
116    {
117    CO_Data * d;
118    HANDLE receive_thread;
119    void* inst;
120    volatile bool continue_receive_thread;
121    };
122
123 driver_procs s_driver_procs;
124
125 LIB_HANDLE LoadCanDriver(char* driver_name)
126    {
127                 return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name);
128    }
129
130 UNS8 canReceive(CAN_PORT fd0, Message *m)
131    {
132   
133    if (fd0 != NULL && s_driver_procs.m_canReceive != NULL)
134            {
135                   driver_data* data = (driver_data*)fd0;
136                   return (*s_driver_procs.m_canReceive)(data->inst, m);
137            }
138    return 1;
139    }
140
141 void* canReceiveLoop(CAN_PORT fd0)
142    {
143    driver_data* data = (driver_data*)fd0;
144    Message m;
145    while (data->continue_receive_thread)
146       {
147       if (!canReceive(fd0, &m))
148          {
149          EnterMutex();
150          canDispatch(data->d, &m);
151          LeaveMutex();
152          }
153       else
154          {
155                  break;
156          ::Sleep(1);
157          }
158       }
159    return 0;
160    }
161
162 /***************************************************************************/
163 UNS8 canSend(CAN_PORT fd0, Message *m)
164    {   
165    if (fd0 != NULL && s_driver_procs.m_canSend != NULL)
166       {
167       UNS8 res;
168       driver_data* data = (driver_data*)fd0;
169       res = (*s_driver_procs.m_canSend)(data->inst, m);      
170       if (res)
171          return 1; // OK
172       }
173    return 0; // NOT OK
174    }
175
176 /***************************************************************************/
177 CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
178    {
179    if (board != NULL && s_driver_procs.m_canOpen != NULL)
180       {
181       void* inst = (*s_driver_procs.m_canOpen)(board);
182       if (inst != NULL)
183          {
184          driver_data* data = new driver_data;
185          data->d = d;
186          data->inst = inst;
187          data->continue_receive_thread = true;
188          CreateReceiveTask(data, &data->receive_thread, (void*)&canReceiveLoop);
189          EnterMutex();
190          d->canHandle = data;
191          LeaveMutex();
192          return data;
193          }
194       }
195    return NULL;
196    }
197
198 /***************************************************************************/
199 int canClose(CO_Data * d)
200    {
201    if (s_driver_procs.m_canClose != NULL)
202       {
203                   driver_data* data;
204                   EnterMutex();
205                   if(d->canHandle != NULL){
206                         data = (driver_data*)d->canHandle;
207                         d->canHandle = NULL;
208                         data->continue_receive_thread = false;}
209                   LeaveMutex();
210                   WaitReceiveTaskEnd(&data->receive_thread);
211                   (*s_driver_procs.m_canClose)(data->inst);
212                   delete data;
213                   return 0;
214       }
215    return 0;
216    }
217
218