drivers/can_peak_win32/can_peak_win32.c
changeset 714 ab83333fee78
parent 713 ca2c2dad3a22
child 730 b5f4b3e2d01c
--- a/drivers/can_peak_win32/can_peak_win32.c	Sat Feb 04 01:38:15 2012 +0100
+++ b/drivers/can_peak_win32/can_peak_win32.c	Sat Feb 04 17:08:48 2012 +0100
@@ -33,6 +33,21 @@
 #include "cancfg.h"
 #include "can_driver.h"
 #include "def.h"
+
+
+#define VERSION_2
+
+/* dummy implementation for older version. */
+#ifndef VERSION_2
+void CAN_SetRcvEvent(HANDLE hEventx)
+{
+  SetEvent(hEventx);
+}
+#endif
+
+
+
+
 #ifndef extra_PCAN_init_params
 	#define extra_PCAN_init_params /**/
 #else
@@ -56,22 +71,25 @@
 		,print_getenv("PCANInterupt")
 #endif
 
+
 static s_BOARD *first_board = NULL;
-
 //Create the Event for the first board
 HANDLE hEvent1 = NULL;
+CRITICAL_SECTION InitLock1;
+CRITICAL_SECTION InitLock2;
 
 
 #ifdef PCAN2_HEADER_
-	static s_BOARD *second_board = NULL;
-	HANDLE hEvent2 = NULL;
+  static s_BOARD *second_board = NULL;
+  HANDLE hEvent2 = NULL;
 #endif
 
 // Define for rtr CAN message
 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
 
 /***************************************************************************/
-int TranslateBaudeRate(char* optarg){
+static int TranslateBaudeRate(char* optarg)
+{
 	if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
 	if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
 	if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
@@ -85,7 +103,7 @@
 	return 0x0000;
 }
 
-UNS8 canInit (s_BOARD *board)
+static UNS8 canInit (s_BOARD *board)
 {
 	int baudrate;
 	int ret = 0;
@@ -93,52 +111,69 @@
 #ifdef PCAN2_HEADER_
 	// if not the first handler
 	if(second_board == (s_BOARD *)board) {
+		if(hEvent2==NULL)
+		{	/* Create the Event for the first board */
+		  hEvent2 = CreateEvent(NULL, // lpEventAttributes
+							FALSE,  // bManualReset
+							FALSE,  // bInitialState
+							"");    // lpName
+		  InitializeCriticalSection(&InitLock2);
+		}
+
+		EnterCriticalSection(&InitLock2);
 		if(baudrate = TranslateBaudeRate(board->baudrate))
 		{
-			ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
-			if(ret != CAN_ERR_OK)
-				return 0;
-		}
-
-		//Create the Event for the first board
-		if(hEvent2 != NULL){
-			hEvent2 = CreateEvent(NULL, // lpEventAttributes
-			                      FALSE,  // bManualReset
-			                      FALSE,  // bInitialState
-			                      "");    // lpName
+		  ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
+		  if(ret != CAN_ERR_OK)
+		  {
+		    LeaveCriticalSection(&InitLock2);
+		    return 0;
+		  }
 		}
 		//Set Event Handle for CANReadExt
 		CAN2_SetRcvEvent(hEvent2);
+		LeaveCriticalSection(&InitLock2);
 	}
 	else
 #endif
 	if(first_board == (s_BOARD *)board) {
+		//Create the Event for the first board
+		if(hEvent1==NULL)
+		{
+		  hEvent1 = CreateEvent(NULL, // lpEventAttributes
+							FALSE,  // bManualReset
+							FALSE,  // bInitialState
+							"");    // lpName
+		  InitializeCriticalSection(&InitLock1);
+                }
+
+		EnterCriticalSection(&InitLock1);
 		if(baudrate = TranslateBaudeRate(board->baudrate))
 		{
-			ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
-			if(ret != CAN_ERR_OK)
-				return 0;
-		}
-		//Create the Event for the first board
-		if(hEvent1 != NULL){
-			hEvent1 = CreateEvent(NULL, // lpEventAttributes
-			                      FALSE,  // bManualReset
-			                      FALSE,  // bInitialState
-			                      "");    // lpName
+		  ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
+		  if(ret != CAN_ERR_OK)
+		  {
+		    LeaveCriticalSection(&InitLock1);
+		    return 0;
+		  }
 		}
 		//Set Event Handle for CANReadExt
 		CAN_SetRcvEvent(hEvent1);
+		LeaveCriticalSection(&InitLock1);
 	}
 	return 1;
 }
 
 /********* functions which permit to communicate with the board ****************/
-UNS8 __stdcall canReceive_driver (CAN_HANDLE fd0, Message * m)
-{
+UNS8 LIBAPI canReceive_driver(CAN_HANDLE fd0, Message * m)
+{
+static int HeavyCounter = 0;
 	int ret=0;
 	UNS8 data;
 	TPCANMsg peakMsg;
+#ifdef CAN_READ_EX
 	TPCANTimestamp peakRcvTime;
+#endif
 	DWORD Res;
 	DWORD result;
 	// loop until valid message or fatal error
@@ -151,52 +186,82 @@
 			if (result == WAIT_OBJECT_0)
 				Res = CAN2_ReadEx(&peakMsg, &peakRcvTime);
 				// Exit receive thread when handle is no more valid
-				if(Res & CAN_ERR_ILLHANDLE)
+				if(Res & CAN_ERRMASK_ILLHANDLE)
 					return 1;
 		}
 		else
 #endif
 
 		// We read the queue looking for messages.
-		if(first_board == (s_BOARD *)fd0) {
+		if(first_board == (s_BOARD *)fd0) 
+		{
+#ifdef VERSION_2
 			result = WaitForSingleObject(hEvent1, INFINITE);
 			if (result == WAIT_OBJECT_0)
+#endif
 			{
+#ifdef CAN_READ_EX
 				Res = CAN_ReadEx(&peakMsg, &peakRcvTime);
+#else
+				Res = CAN_Read(&peakMsg);
+#endif
 				// Exit receive thread when handle is no more valid
-				if(Res & CAN_ERR_ILLHANDLE)
-					return 1;
+#ifdef CAN_ERRMASK_ILLHANDLE
+				if(Res & CAN_ERRMASK_ILLHANDLE) return 1;
+#else
+				if(Res & CAN_ERR_ILLHANDLE) return 1;
+#endif				
+
+#ifndef VERSION_2
+				if(Res != CAN_ERR_OK) 
+					result = WaitForSingleObject(hEvent1, 1);  	//pooling
+#endif
 			}
 		}
+#ifdef VERSION_2
 		else
 			Res = CAN_ERR_BUSOFF;
-
+#endif
+		
 		// A message was received : we process the message(s)
-		if (Res == CAN_ERR_OK)
-		{
-			// if something different that 11bit or rtr... problem
-			if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR))
-			{
-				if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF)
-				{
-					printf ("!!! Peak board read : re-init\n");
-					canInit((s_BOARD*) fd0);
-					usleep (10000);
-				}
-
-				// If status, return status if 29bit, return overrun
-				return peakMsg.MSGTYPE ==
-					MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN;
-			}
-			m->cob_id = peakMsg.ID;
-
-			if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)	/* bits of MSGTYPE_ */
-				m->rtr = 0;
-			else
-				m->rtr = 1;
-			m->len = peakMsg.LEN;	/* count of data bytes (0..8) */
-			for (data = 0; data < peakMsg.LEN; data++)
-				m->data[data] = peakMsg.DATA[data];	/* data bytes, up to 8 */
+		if(Res == CAN_ERR_OK)
+		{			
+		  switch(peakMsg.MSGTYPE)
+		  {
+		    case MSGTYPE_STATUS:
+			  switch(peakMsg.DATA[3])
+		          {
+			    case CAN_ERR_BUSHEAVY: 
+				      break;
+		            case CAN_ERR_BUSOFF: 
+			              printf ("Peak board read BUSOFF: re-init!!!\n");
+				      canInit((s_BOARD*)fd0);
+				      usleep(33);
+				      break;
+			  }
+			  return peakMsg.DATA[3];	/* if something different that 11bit or rtr... problem */
+
+		    case MSGTYPE_STANDARD:		/* bits of MSGTYPE_ */
+		    case MSGTYPE_EXTENDED:
+			  m->rtr = 0;
+			  break;
+
+		    case MSGTYPE_RTR:			/* bits of MSGTYPE_ */
+			  m->rtr = 1;
+			  break;
+
+		    default: return CAN_ERR_OVERRUN;	/* If status, return status if 29bit, return overrun. */
+		    
+		    }
+
+		   m->cob_id = peakMsg.ID;				
+		   if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)  /* bits of MSGTYPE_ */
+                     m->rtr = 0;
+		   else
+		     m->rtr = 1;
+		   m->len = peakMsg.LEN;		/* count of data bytes (0..8) */
+		   for (data = 0; data < peakMsg.LEN; data++)
+			m->Data[data] = peakMsg.DATA[data];	/* data bytes, up to 8 */
 #if defined DEBUG_MSG_CONSOLE_ON
 			MSG("in : ");
 			print_message(m);
@@ -213,27 +278,30 @@
 				return 1;
 			}
 		}
-	}while(Res != CAN_ERR_OK);
+	} while(Res != CAN_ERR_OK);
 	return 0;
 }
 
 /***************************************************************************/
-UNS8 __stdcall canSend_driver (CAN_HANDLE fd0, Message const * m)
+UNS8 LIBAPI canSend_driver(CAN_HANDLE fd0, Message const *m)
 {
 	UNS8 data;
-	DWORD localerrno;
 	TPCANMsg peakMsg;
 	peakMsg.ID = m->cob_id;	/* 11/29 bit code */
 	if (m->rtr == 0)
-		peakMsg.MSGTYPE = CAN_INIT_TYPE_ST;	/* bits of MSGTYPE_ */
-	else
 	{
-		peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR;	/* bits of MSGTYPE_ */
-	}
+	  if(peakMsg.ID > 0x7FF)
+		peakMsg.MSGTYPE = MSGTYPE_EXTENDED;	/* bits of MSGTYPE_ */
+	  else
+		peakMsg.MSGTYPE = MSGTYPE_STANDARD;	/* bits of MSGTYPE_ */
+	}
+	else	
+		peakMsg.MSGTYPE = MSGTYPE_RTR;		/* bits of MSGTYPE_ */
+	
 	peakMsg.LEN = m->len;
 	/* count of data bytes (0..8) */
 	for (data = 0; data < m->len; data++)
-		peakMsg.DATA[data] = m->data[data];	/* data bytes, up to 8 */
+		peakMsg.DATA[data] = m->Data[data];	/* data bytes, up to 8 */
 
 	do
 	{
@@ -241,19 +309,19 @@
 		// if not the first handler
 		if(second_board == (s_BOARD *)fd0)
 		{
-			errno = localerrno = CAN2_Write (&peakMsg);
+			errno = CAN2_Write (&peakMsg);
 		}
 		else
 #endif
 		if(first_board == (s_BOARD *)fd0)
 			{
-				errno = localerrno = CAN_Write (&peakMsg);
+				errno = CAN_Write (&peakMsg);
 			}
 		else
 			goto fail;
-		if (localerrno)
-		{
-			if (localerrno == CAN_ERR_BUSOFF)
+		if (errno)
+		{
+			if (errno == CAN_ERR_BUSOFF)
 			{
 				printf ("!!! Peak board write : re-init\n");
 				canInit((s_BOARD*)fd0);
@@ -262,7 +330,7 @@
 			usleep (1000);
 		}
 	}
-	while (localerrno != CAN_ERR_OK);
+	while (errno != CAN_ERR_OK);
 #if defined DEBUG_MSG_CONSOLE_ON
 	MSG("out : ");
 	print_message(m);
@@ -273,16 +341,15 @@
 }
 
 /***************************************************************************/
-UNS8 __stdcall canChangeBaudRate_driver( CAN_HANDLE fd, char* baud)
+UNS8 LIBAPI canChangeBaudRate_driver(CAN_HANDLE fd, char* baud)
 {
 	printf("canChangeBaudRate not yet supported by this driver\n");
 	return 0;
 }
 
 /***************************************************************************/
-CAN_HANDLE __stdcall canOpen_driver (s_BOARD * board)
-{
-  char busname[64];
+LIBPUBLIC CAN_HANDLE LIBAPI canOpen_driver(s_BOARD * board)
+{
   char* pEnd;
   int ret;
 
@@ -308,35 +375,36 @@
   return NULL;
 }
 
+
 /***************************************************************************/
-int __stdcall canClose_driver (CAN_HANDLE fd0)
+int LIBAPI canClose_driver(CAN_HANDLE fd0)
 {
 #ifdef PCAN2_HEADER_
-      // if not the first handler
-      if(second_board == (s_BOARD *)fd0)
-      {
-           CAN2_SetRcvEvent(NULL);
-           CAN2_Close ();
-           if(hEvent2)
-           {
-             SetEvent(hEvent2);
-             CloseHandle(hEvent2);
-             hEvent2 = NULL;
-           }
-           second_board = (s_BOARD *)NULL;
-      }else
-#endif
-      if(first_board == (s_BOARD *)fd0)
-      {
-           CAN_SetRcvEvent(NULL);
-           CAN_Close ();
-           if(hEvent1)
-           {
-             SetEvent(hEvent1);
-             CloseHandle(hEvent1);
-             hEvent1 = NULL;
-            }
-           first_board = (s_BOARD *)NULL;
-      }
-      return 0;
-}
+	// if not the first handler
+	if(second_board == (s_BOARD *)fd0)
+	{
+		CAN2_SetRcvEvent(NULL);
+		CAN2_Close ();		
+		if(hEvent2)
+		{
+		  SetEvent(hEvent2);
+		  CloseHandle(hEvent2);		
+		  hEvent2 = NULL;
+		}
+		second_board = (s_BOARD *)NULL;
+	}else
+#endif
+	if(first_board == (s_BOARD *)fd0)
+	{
+		CAN_SetRcvEvent(NULL);
+		CAN_Close ();		
+		if(hEvent1) 
+		{
+                  SetEvent(hEvent1);
+		  CloseHandle(hEvent1);
+		  hEvent1 = NULL;
+                }
+		first_board = (s_BOARD *)NULL;
+	}
+	return 0;
+}