greg@267: /* greg@267: This file is part of CanFestival, a library implementing CanOpen Stack. greg@267: greg@267: Copyright (C): Edouard TISSERANT and Francis DUPIN greg@267: Copyright (C) Win32 Port Leonid Tochinski greg@267: greg@267: See COPYING file for copyrights details. greg@267: greg@267: This library is free software; you can redistribute it and/or greg@267: modify it under the terms of the GNU Lesser General Public greg@267: License as published by the Free Software Foundation; either greg@267: version 2.1 of the License, or (at your option) any later version. greg@267: greg@267: This library is distributed in the hope that it will be useful, greg@267: but WITHOUT ANY WARRANTY; without even the implied warranty of greg@267: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU greg@267: Lesser General Public License for more details. greg@267: greg@267: You should have received a copy of the GNU Lesser General Public greg@267: License along with this library; if not, write to the Free Software greg@267: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA greg@267: */ greg@267: greg@267: /* greg@267: CAN driver interface. greg@267: */ greg@267: greg@267: #include greg@267: greg@267: extern "C" greg@267: { greg@267: #define DLL_CALL(funcname) (*_##funcname) greg@267: #define FCT_PTR_INIT =NULL greg@267: #include "canfestival.h" greg@267: #include "timer.h" greg@267: greg@267: #include "timers_driver.h" greg@267: }; greg@267: greg@267: typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m); greg@267: typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m); greg@267: typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board); greg@267: typedef int (*CANCLOSE_DRIVER_PROC)(void* inst); greg@267: greg@267: greg@267: class driver_procs greg@267: { greg@267: public: greg@267: driver_procs(); greg@267: ~driver_procs(); greg@267: greg@267: HMODULE load_canfestival_driver(LPCTSTR driver_name); greg@267: bool can_driver_valid() const; greg@267: greg@267: public: greg@267: // can driver greg@267: CANRECEIVE_DRIVER_PROC m_canReceive; greg@267: CANSEND_DRIVER_PROC m_canSend; greg@267: CANOPEN_DRIVER_PROC m_canOpen; greg@267: CANCLOSE_DRIVER_PROC m_canClose; greg@267: greg@267: // driver module habndle greg@267: HMODULE m_driver_handle; greg@267: }; greg@267: greg@267: driver_procs::driver_procs() : m_canReceive(0), greg@267: m_canSend(0), greg@267: m_canOpen(0), greg@267: m_canClose(0), greg@267: m_driver_handle(0) greg@267: {} greg@267: greg@267: driver_procs::~driver_procs() greg@267: { greg@267: if (m_driver_handle) greg@267: ::FreeLibrary(m_driver_handle); greg@267: } greg@267: greg@267: bool driver_procs::can_driver_valid() const greg@267: { greg@267: return ((m_canReceive != NULL) && greg@267: (m_canSend != NULL) && greg@267: (m_canOpen != NULL) && greg@267: (m_canClose != NULL)); greg@267: } greg@267: greg@267: // GetProcAddress doesn't have an UNICODE version for NT greg@267: #ifdef UNDER_CE greg@267: #define myTEXT(str) TEXT(str) greg@267: #else greg@267: #define myTEXT(str) str greg@267: #endif greg@267: greg@267: HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name) greg@267: { greg@267: //LPCTSTR driver1 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll"; greg@267: //LPCTSTR driver2 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll"; greg@267: //printf("can_driver_valid=%d\n",can_driver_valid()); greg@267: if (can_driver_valid()) greg@267: return m_driver_handle; greg@267: printf("driver_name=%s\n",driver_name); greg@267: m_driver_handle = ::LoadLibrary(driver_name); greg@267: //printf("m_driver_handle=%d\n",m_driver_handle); greg@267: //printf("testerror =%s\n",GetLastError()); greg@267: if (m_driver_handle == NULL) greg@267: return NULL; greg@267: greg@267: m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver")); greg@267: m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver")); greg@267: m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver")); greg@267: m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver")); greg@267: return can_driver_valid()?m_driver_handle:NULL; greg@267: } greg@267: greg@267: struct driver_data greg@267: { greg@267: CO_Data * d; greg@267: HANDLE receive_thread; greg@267: void* inst; greg@267: volatile bool continue_receive_thread; greg@267: }; greg@267: greg@267: driver_procs s_driver_procs; greg@267: etisserant@480: LIB_HANDLE LoadCanDriver(const char* driver_name) greg@267: { greg@267: return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name); greg@267: } greg@267: greg@267: UNS8 canReceive(CAN_PORT fd0, Message *m) greg@267: { greg@267: greg@267: if (fd0 != NULL && s_driver_procs.m_canReceive != NULL) greg@267: { greg@267: driver_data* data = (driver_data*)fd0; greg@267: return (*s_driver_procs.m_canReceive)(data->inst, m); greg@267: } greg@267: return 1; greg@267: } greg@267: greg@267: void* canReceiveLoop(CAN_PORT fd0) greg@267: { greg@267: driver_data* data = (driver_data*)fd0; greg@267: Message m; greg@267: while (data->continue_receive_thread) greg@267: { greg@267: if (!canReceive(fd0, &m)) greg@267: { greg@267: EnterMutex(); greg@267: canDispatch(data->d, &m); greg@267: LeaveMutex(); greg@267: } greg@267: else greg@267: { greg@267: break; greg@267: ::Sleep(1); greg@267: } greg@267: } greg@267: return 0; greg@267: } greg@267: greg@267: /***************************************************************************/ greg@267: UNS8 canSend(CAN_PORT fd0, Message *m) greg@267: { greg@267: if (fd0 != NULL && s_driver_procs.m_canSend != NULL) greg@267: { greg@267: UNS8 res; greg@267: driver_data* data = (driver_data*)fd0; greg@267: res = (*s_driver_procs.m_canSend)(data->inst, m); greg@267: if (res) greg@267: return 1; // OK greg@267: } greg@267: return 0; // NOT OK greg@267: } greg@267: greg@267: /***************************************************************************/ greg@267: CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d) greg@267: { greg@267: if (board != NULL && s_driver_procs.m_canOpen != NULL) greg@267: { greg@267: void* inst = (*s_driver_procs.m_canOpen)(board); greg@267: if (inst != NULL) greg@267: { greg@267: driver_data* data = new driver_data; greg@267: data->d = d; greg@267: data->inst = inst; greg@267: data->continue_receive_thread = true; greg@267: CreateReceiveTask(data, &data->receive_thread, (void*)&canReceiveLoop); greg@267: EnterMutex(); greg@267: d->canHandle = data; greg@267: LeaveMutex(); greg@267: return data; greg@267: } greg@267: } greg@267: return NULL; greg@267: } greg@267: greg@267: /***************************************************************************/ greg@267: int canClose(CO_Data * d) greg@267: { greg@267: if (s_driver_procs.m_canClose != NULL) greg@267: { greg@267: driver_data* data; greg@267: EnterMutex(); greg@267: if(d->canHandle != NULL){ greg@267: data = (driver_data*)d->canHandle; greg@267: d->canHandle = NULL; greg@267: data->continue_receive_thread = false;} greg@267: LeaveMutex(); greg@514: (*s_driver_procs.m_canClose)(data->inst); greg@267: WaitReceiveTaskEnd(&data->receive_thread); greg@267: delete data; greg@267: return 0; greg@267: } greg@267: return 0; greg@267: } greg@267: greg@267: