drivers/can_ixxat_win32/ixxat.cpp
changeset 655 ea1ddcc77acf
parent 647 8203ce2b9752
child 683 a3ff0e3e9829
equal deleted inserted replaced
654:fc9af616633d 655:ea1ddcc77acf
    54 #include "can_driver.h"
    54 #include "can_driver.h"
    55 #include "def.h"
    55 #include "def.h"
    56 }
    56 }
    57 #include "VCI2.h"
    57 #include "VCI2.h"
    58 #include "async_access_que.h"
    58 #include "async_access_que.h"
    59 
       
    60 #pragma warning(disable:4996)
       
    61 
    59 
    62 #define CAN_NUM 0
    60 #define CAN_NUM 0
    63 
    61 
    64 class IXXAT
    62 class IXXAT
    65    {
    63    {
    78       // VCI2 handler      
    76       // VCI2 handler      
    79       static void VCI_CALLBACKATTR message_handler(char *msg_str);
    77       static void VCI_CALLBACKATTR message_handler(char *msg_str);
    80       static void VCI_CALLBACKATTR receive_queuedata_handler(UINT16 que_hdl, UINT16 count, VCI_CAN_OBJ* p_obj);
    78       static void VCI_CALLBACKATTR receive_queuedata_handler(UINT16 que_hdl, UINT16 count, VCI_CAN_OBJ* p_obj);
    81       static void VCI_CALLBACKATTR exception_handler(VCI_FUNC_NUM func_num, INT32 err_code, UINT16 ext_err, char* err_str);
    79       static void VCI_CALLBACKATTR exception_handler(VCI_FUNC_NUM func_num, INT32 err_code, UINT16 ext_err, char* err_str);
    82       
    80       
       
    81       static void CALLBACK canBusWatchdog(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime);
       
    82       void watchdog();
    83    private:
    83    private:
    84       UINT16 m_BoardHdl;
    84       UINT16 m_BoardHdl;
    85       UINT16 m_TxQueHdl;
    85       UINT16 m_TxQueHdl;
    86       UINT16 m_RxQueHdl;
    86       UINT16 m_RxQueHdl;
    87       async_access_que<VCI_CAN_OBJ> m_RX_Que;
    87       async_access_que<VCI_CAN_OBJ> m_RX_Que;
    88       static IXXAT* m_callbackPtr;
    88       static IXXAT* m_callbackPtr;
       
    89       static UINT_PTR m_watchdogTimerId;
       
    90       static const unsigned int CAN_BUS_WATCHDOG_INTERVAL_MSEC = 10000;
       
    91 
       
    92       /** Bitmask inside sts from VCI_ReadCanStatus() that defines the can bus off state.*/
       
    93       static const unsigned char STS_CAN_BUS_OFF = 0x80;
       
    94 
       
    95       /** Bitmask inside sts from VCI_ReadCanStatus() that defines the can data overrun state.*/
       
    96       static const unsigned char STS_CAN_DATA_OVERRUN = 0x20;
       
    97 
       
    98       /** Bitmask inside sts from VCI_ReadCanStatus() that defines the remote queue overrun state.*/
       
    99       static const unsigned char STS_REMOTE_QUEUE_OVERRUN = 0x04;
    89    };
   100    };
    90 
   101 
    91 IXXAT *IXXAT::m_callbackPtr = NULL;
   102 IXXAT *IXXAT::m_callbackPtr = NULL;
       
   103 
       
   104 UINT_PTR IXXAT::m_watchdogTimerId = 0;
    92 
   105 
    93 IXXAT::IXXAT(s_BOARD *board) : m_BoardHdl(0xFFFF),
   106 IXXAT::IXXAT(s_BOARD *board) : m_BoardHdl(0xFFFF),
    94                                m_TxQueHdl(0xFFFF),
   107                                m_TxQueHdl(0xFFFF),
    95                                m_RxQueHdl(0xFFFF)
   108                                m_RxQueHdl(0xFFFF)
    96                                
   109                                
   212 
   225 
   213    // definition of Transmit Queue
   226    // definition of Transmit Queue
   214    res = VCI_ConfigQueue(m_BoardHdl, CAN_NUM, VCI_TX_QUE, 100 , 0, 0, 0,  &m_TxQueHdl);
   227    res = VCI_ConfigQueue(m_BoardHdl, CAN_NUM, VCI_TX_QUE, 100 , 0, 0, 0,  &m_TxQueHdl);
   215    
   228    
   216    //  definition of Receive Queue (interrupt mode)
   229    //  definition of Receive Queue (interrupt mode)
   217    res = VCI_ConfigQueue(m_BoardHdl, CAN_NUM, VCI_RX_QUE, 50, 1, 0, 100,  &m_RxQueHdl);
   230    res = VCI_ConfigQueue(m_BoardHdl, CAN_NUM, VCI_RX_QUE, 500, 1, 0, 100,  &m_RxQueHdl);
   218 
   231 
   219    //  assign the all IDs to the Receive Queue
   232    //  assign the all IDs to the Receive Queue
   220    res = VCI_AssignRxQueObj(m_BoardHdl, m_RxQueHdl ,VCI_ACCEPT, 0, 0) ;
   233    res = VCI_AssignRxQueObj(m_BoardHdl, m_RxQueHdl ,VCI_ACCEPT, 0, 0) ;
   221 
   234 
   222    //  And now start the CAN
   235    //  And now start the CAN
   223    res = VCI_StartCan(m_BoardHdl, CAN_NUM);
   236    res = VCI_StartCan(m_BoardHdl, CAN_NUM);
       
   237 
       
   238    //Start CAN Bus-Off watchdog
       
   239    m_watchdogTimerId = SetTimer(NULL, NULL, IXXAT::CAN_BUS_WATCHDOG_INTERVAL_MSEC, IXXAT::canBusWatchdog);
   224    
   240    
   225    return true;
   241    return true;
   226    }
   242    }
   227 
   243 
   228 bool IXXAT::close()
   244 bool IXXAT::close()
   292   char buf[200];
   308   char buf[200];
   293   ::sprintf(buf, "IXXAT Exception: %s (%i / %u) [%s]\n", Num2Function[func_num], err_code, ext_err, err_str);
   309   ::sprintf(buf, "IXXAT Exception: %s (%i / %u) [%s]\n", Num2Function[func_num], err_code, ext_err, err_str);
   294   ::OutputDebugString(buf);
   310   ::OutputDebugString(buf);
   295   }
   311   }
   296 
   312 
       
   313   void IXXAT::watchdog()
       
   314   {
       
   315     VCI_CAN_STS sts;
       
   316     long res = VCI_ReadCanStatus(m_BoardHdl, CAN_NUM, &sts);
       
   317 
       
   318     if (res < 0)
       
   319     {
       
   320       char buf[200];
       
   321       ::sprintf(buf, "\nIXXAT canBusWatchdog: ERROR: Reading the can state failed!\n");
       
   322       ::OutputDebugString(buf);
       
   323     }
       
   324     else
       
   325     {
       
   326       if (sts.sts & (STS_CAN_BUS_OFF | STS_CAN_DATA_OVERRUN | STS_REMOTE_QUEUE_OVERRUN))
       
   327       {
       
   328         if (sts.sts & STS_CAN_BUS_OFF)
       
   329         {
       
   330           ::OutputDebugString("\nIXXAT canBusWatchdog: CAN bus off detected!\n");
       
   331         }
       
   332         if (sts.sts & STS_CAN_DATA_OVERRUN)
       
   333         {
       
   334           ::OutputDebugString("\nIXXAT canBusWatchdog: CAN data overrun detected!\n");
       
   335         }
       
   336         if (sts.sts & STS_REMOTE_QUEUE_OVERRUN)
       
   337         {
       
   338           ::OutputDebugString("\nIXXAT canBusWatchdog: Remote queue overrun detected!\n");
       
   339         }
       
   340 
       
   341         if (VCI_ResetCan(m_BoardHdl, CAN_NUM) < 0)
       
   342         {
       
   343           ::OutputDebugString("\nIXXAT canBusWatchdog: ERROR: Resetting the can module failed!\n");
       
   344         }
       
   345 
       
   346         if (VCI_StartCan(m_BoardHdl, CAN_NUM) < 0)
       
   347         {
       
   348           ::OutputDebugString("\nIXXAT canBusWatchdog: ERROR: Restaring the can module failed!\n");
       
   349         }
       
   350       }
       
   351     }
       
   352 
       
   353     if (SetTimer(NULL, m_watchdogTimerId, IXXAT::CAN_BUS_WATCHDOG_INTERVAL_MSEC, IXXAT::canBusWatchdog) == 0)
       
   354     {
       
   355       char buf[200];
       
   356       ::sprintf(buf, "\nIXXAT canBusWatchdog: ERROR: Creation of the watchdog timer failed!\n");
       
   357       ::OutputDebugString(buf);
       
   358     }
       
   359   }
       
   360 
       
   361 void CALLBACK IXXAT::canBusWatchdog(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
       
   362 {
       
   363    if (m_callbackPtr != NULL)
       
   364       m_callbackPtr->watchdog();
       
   365 }
       
   366 
   297 //------------------------------------------------------------------------
   367 //------------------------------------------------------------------------
   298 extern "C"
   368 extern "C"
   299    UNS8 __stdcall canReceive_driver(CAN_HANDLE inst, Message *m)
   369    UNS8 __stdcall canReceive_driver(CAN_HANDLE inst, Message *m)
   300    {
   370    {
   301      return reinterpret_cast<IXXAT*>(inst)->receive(m) ? 0 : 1;
   371      return reinterpret_cast<IXXAT*>(inst)->receive(m) ? 0 : 1;