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; |