drivers/win32/drivers_win32.cpp
changeset 145 e747d2e26af0
child 149 fe50ada8020b
equal deleted inserted replaced
144:3ebf16150b2e 145:e747d2e26af0
       
     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 "nvram_driver.h"
       
    38 #include "lss_driver.h"
       
    39 #include "timers_driver.h"
       
    40    };
       
    41 
       
    42 typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
       
    43 typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m);
       
    44 typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board);
       
    45 typedef int (*CANCLOSE_DRIVER_PROC)(void* inst);
       
    46 
       
    47 typedef int (*NVRAM_OPEN_PROC)(void);
       
    48 typedef void (*NVRAM_CLOSE_PROC)(void);
       
    49 typedef char (*NVRAM_WRITE_PROC)(int type, int access_attr, void *data);
       
    50 typedef char (*NVRAM_READ_PROC)(int type, int access_attr, void *data);
       
    51 
       
    52 typedef void (*LED_SET_REDGREEN_PROC)(CO_Data *d, unsigned char bits);
       
    53 
       
    54 typedef UNS8 (*BAUDRATE_VALID_PROC)(UNS32 table_index);
       
    55 typedef void (*BAUDRATE_SET_PROC)(UNS8 table_index);
       
    56 
       
    57 class driver_procs
       
    58    {
       
    59    public:
       
    60       driver_procs();
       
    61       ~driver_procs();
       
    62 
       
    63       HMODULE load_canfestival_driver(LPCTSTR driver_name);
       
    64       bool can_driver_valid() const;
       
    65 
       
    66    public:
       
    67       // can driver
       
    68       CANRECEIVE_DRIVER_PROC m_canReceive;
       
    69       CANSEND_DRIVER_PROC m_canSend;
       
    70       CANOPEN_DRIVER_PROC m_canOpen;
       
    71       CANCLOSE_DRIVER_PROC m_canClose;
       
    72 
       
    73       // nvram driver
       
    74       NVRAM_OPEN_PROC m_nvram_open;
       
    75       NVRAM_CLOSE_PROC m_nvram_close;
       
    76       NVRAM_WRITE_PROC m_nvram_write;
       
    77       NVRAM_READ_PROC m_nvram_read;
       
    78       // led driver
       
    79       LED_SET_REDGREEN_PROC m_led_set_redgreen;
       
    80       // lss driver
       
    81       BAUDRATE_VALID_PROC m_baudrate_valid;
       
    82       BAUDRATE_SET_PROC m_baudrate_set;
       
    83 
       
    84       // driver module habndle
       
    85       HMODULE m_driver_handle;
       
    86    };
       
    87 
       
    88 driver_procs::driver_procs() : m_canReceive(0),
       
    89       m_canSend(0),
       
    90       m_canOpen(0),
       
    91       m_canClose(0),
       
    92       m_nvram_open(0),
       
    93       m_nvram_close(0),
       
    94       m_nvram_write(0),
       
    95       m_nvram_read(0),
       
    96       m_led_set_redgreen(),
       
    97       m_baudrate_valid(0),
       
    98       m_baudrate_set(0),
       
    99       m_driver_handle(0)
       
   100    {}
       
   101 
       
   102 driver_procs::~driver_procs()
       
   103    {
       
   104    if (m_driver_handle)
       
   105       ::FreeLibrary(m_driver_handle);
       
   106    }
       
   107 
       
   108 bool driver_procs::can_driver_valid() const
       
   109    {
       
   110    return ((m_canReceive != NULL) &&
       
   111            (m_canSend != NULL) &&
       
   112            (m_canOpen != NULL) &&
       
   113            (m_canClose != NULL));
       
   114    }
       
   115 
       
   116 // GetProcAddress doesn't have an UNICODE version for NT
       
   117 #ifdef UNDER_CE
       
   118   #define myTEXT(str) TEXT(str)
       
   119 #else
       
   120   #define myTEXT(str) str
       
   121 #endif
       
   122 
       
   123 HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name)
       
   124    {
       
   125    if (can_driver_valid())
       
   126       return m_driver_handle;
       
   127    m_driver_handle = ::LoadLibrary(driver_name);
       
   128    if (m_driver_handle == NULL)
       
   129       return NULL;
       
   130 
       
   131    m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver"));
       
   132    m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver"));
       
   133    m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver"));
       
   134    m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver"));
       
   135 
       
   136    m_nvram_open = (NVRAM_OPEN_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_open_driver"));
       
   137    m_nvram_close = (NVRAM_CLOSE_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_close_driver"));
       
   138    m_nvram_write = (NVRAM_WRITE_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_write_driver"));
       
   139    m_nvram_read = (NVRAM_READ_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_read_driver"));
       
   140 
       
   141    m_led_set_redgreen = (LED_SET_REDGREEN_PROC)::GetProcAddress(m_driver_handle, myTEXT("led_set_redgreen_driver"));
       
   142 
       
   143    m_baudrate_valid = (BAUDRATE_VALID_PROC)::GetProcAddress(m_driver_handle, myTEXT("baudrate_valid_driver"));
       
   144    m_baudrate_set = (BAUDRATE_SET_PROC)::GetProcAddress(m_driver_handle, myTEXT("baudrate_set_driver"));
       
   145 
       
   146    return can_driver_valid()?m_driver_handle:NULL;
       
   147    }
       
   148 
       
   149 struct driver_data
       
   150    {
       
   151    CO_Data * d;
       
   152    HANDLE receive_thread;
       
   153    void* inst;
       
   154    volatile bool continue_receive_thread;
       
   155    };
       
   156 
       
   157 driver_procs s_driver_procs;
       
   158 
       
   159 LIB_HANDLE LoadCanDriver(char* driver_name)
       
   160    {
       
   161 		return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name);
       
   162    }
       
   163 
       
   164 UNS8 canReceive(CAN_PORT fd0, Message *m)
       
   165    {
       
   166    if (fd0 != NULL && s_driver_procs.m_canReceive != NULL)
       
   167 	   {
       
   168 		  driver_data* data = (driver_data*)fd0;
       
   169 		  return (*s_driver_procs.m_canReceive)(data->inst, m);
       
   170 	   }
       
   171    return 1;
       
   172    }
       
   173 
       
   174 void* canReceiveLoop(CAN_PORT fd0)
       
   175    {
       
   176    driver_data* data = (driver_data*)fd0;
       
   177    Message m;
       
   178    while (data->continue_receive_thread)
       
   179       {
       
   180       if (!canReceive(fd0, &m))
       
   181          {
       
   182          EnterMutex();
       
   183          canDispatch(data->d, &m);
       
   184          LeaveMutex();
       
   185          }
       
   186       else
       
   187          {
       
   188 		 break;
       
   189          ::Sleep(1);
       
   190          }
       
   191       }
       
   192    return 0;
       
   193    }
       
   194 
       
   195 /***************************************************************************/
       
   196 UNS8 canSend(CAN_PORT fd0, Message *m)
       
   197    {
       
   198    if (fd0 != NULL && s_driver_procs.m_canSend != NULL)
       
   199       {
       
   200       driver_data* data = (driver_data*)fd0;
       
   201       if ((*s_driver_procs.m_canSend)(data->inst, m))
       
   202          return 0;
       
   203       }
       
   204    return 1;
       
   205    }
       
   206 
       
   207 /***************************************************************************/
       
   208 CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
       
   209    {
       
   210    if (board != NULL && s_driver_procs.m_canOpen != NULL)
       
   211       {
       
   212       void* inst = (*s_driver_procs.m_canOpen)(board);
       
   213       if (inst != NULL)
       
   214          {
       
   215          driver_data* data = new driver_data;
       
   216          data->d = d;
       
   217          data->inst = inst;
       
   218          data->continue_receive_thread = true;
       
   219          CreateReceiveTask(data, &data->receive_thread, &canReceiveLoop);
       
   220          return data;
       
   221          }
       
   222       }
       
   223    return NULL;
       
   224    }
       
   225 
       
   226 /***************************************************************************/
       
   227 int canClose(CAN_PORT fd0)
       
   228    {
       
   229    if (fd0 != NULL && s_driver_procs.m_canClose != NULL)
       
   230       {
       
   231       driver_data* data = (driver_data*)fd0;
       
   232       data->continue_receive_thread = false;
       
   233       WaitReceiveTaskEnd(&data->receive_thread);
       
   234       (*s_driver_procs.m_canClose)(data->inst);
       
   235       delete data;
       
   236       return 0;
       
   237       }
       
   238    return 0;
       
   239    }
       
   240 
       
   241 /***************************************************************************/
       
   242 int nvram_open(void)
       
   243    {
       
   244    if (s_driver_procs.m_nvram_read != NULL)
       
   245       return (*s_driver_procs.m_nvram_open)();
       
   246    return -1;
       
   247    }
       
   248 
       
   249 void nvram_close(void)
       
   250    {
       
   251    if (s_driver_procs.m_nvram_close != NULL)
       
   252       (*s_driver_procs.m_nvram_close)();
       
   253    }
       
   254 
       
   255 char nvram_write(int type, int access_attr, void *data)
       
   256    {
       
   257    if (s_driver_procs.m_nvram_write != NULL)
       
   258       return (*s_driver_procs.m_nvram_write)(type, access_attr, data);
       
   259    return 0;
       
   260    }
       
   261 
       
   262 char nvram_read(int type, int access_attr, void *data)
       
   263    {
       
   264    if (s_driver_procs.m_nvram_read != NULL)
       
   265       return (*s_driver_procs.m_nvram_read)(type, access_attr, data);
       
   266    return 0;
       
   267    }
       
   268 
       
   269 /***************************************************************************/
       
   270 
       
   271 void led_set_redgreen(CO_Data *d, unsigned char bits)
       
   272    {
       
   273    if (s_driver_procs.m_led_set_redgreen != NULL)
       
   274       (*s_driver_procs.m_led_set_redgreen)(d, bits);
       
   275    }
       
   276 
       
   277 /***************************************************************************/
       
   278 
       
   279 UNS8 baudrate_valid(UNS32 table_index)
       
   280    {
       
   281    if (s_driver_procs.m_baudrate_valid != NULL)
       
   282       return (*s_driver_procs.m_baudrate_valid)(table_index);
       
   283    return 0;
       
   284    }
       
   285 
       
   286 void baudrate_set(UNS8 table_index)
       
   287    {
       
   288    if (s_driver_procs.m_baudrate_set != NULL)
       
   289       (*s_driver_procs.m_baudrate_set)(table_index);
       
   290    }