drivers/win32/win32.cpp
changeset 556 8296acd119a9
parent 555 ee24dcbd3e64
child 557 922873e5b409
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 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(const 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 		  (*s_driver_procs.m_canClose)(data->inst);
       
   211 		  WaitReceiveTaskEnd(&data->receive_thread);
       
   212 		  delete data;
       
   213 		  return 0;
       
   214       }
       
   215    return 0;
       
   216    }
       
   217 
       
   218