drivers/can_peak_win32/can_peak_win32.c
changeset 714 ab83333fee78
parent 713 ca2c2dad3a22
child 730 b5f4b3e2d01c
equal deleted inserted replaced
712:d1ccff139c17 714:ab83333fee78
    31 #endif
    31 #endif
    32 
    32 
    33 #include "cancfg.h"
    33 #include "cancfg.h"
    34 #include "can_driver.h"
    34 #include "can_driver.h"
    35 #include "def.h"
    35 #include "def.h"
       
    36 
       
    37 
       
    38 #define VERSION_2
       
    39 
       
    40 /* dummy implementation for older version. */
       
    41 #ifndef VERSION_2
       
    42 void CAN_SetRcvEvent(HANDLE hEventx)
       
    43 {
       
    44   SetEvent(hEventx);
       
    45 }
       
    46 #endif
       
    47 
       
    48 
       
    49 
       
    50 
    36 #ifndef extra_PCAN_init_params
    51 #ifndef extra_PCAN_init_params
    37 	#define extra_PCAN_init_params /**/
    52 	#define extra_PCAN_init_params /**/
    38 #else
    53 #else
    39 	long int print_getenv(const char* pcanparam)
    54 	long int print_getenv(const char* pcanparam)
    40 	{
    55 	{
    54 		,print_getenv("PCANHwType")\
    69 		,print_getenv("PCANHwType")\
    55 		,print_getenv("PCANIO_Port")\
    70 		,print_getenv("PCANIO_Port")\
    56 		,print_getenv("PCANInterupt")
    71 		,print_getenv("PCANInterupt")
    57 #endif
    72 #endif
    58 
    73 
       
    74 
    59 static s_BOARD *first_board = NULL;
    75 static s_BOARD *first_board = NULL;
    60 
       
    61 //Create the Event for the first board
    76 //Create the Event for the first board
    62 HANDLE hEvent1 = NULL;
    77 HANDLE hEvent1 = NULL;
       
    78 CRITICAL_SECTION InitLock1;
       
    79 CRITICAL_SECTION InitLock2;
    63 
    80 
    64 
    81 
    65 #ifdef PCAN2_HEADER_
    82 #ifdef PCAN2_HEADER_
    66 	static s_BOARD *second_board = NULL;
    83   static s_BOARD *second_board = NULL;
    67 	HANDLE hEvent2 = NULL;
    84   HANDLE hEvent2 = NULL;
    68 #endif
    85 #endif
    69 
    86 
    70 // Define for rtr CAN message
    87 // Define for rtr CAN message
    71 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
    88 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
    72 
    89 
    73 /***************************************************************************/
    90 /***************************************************************************/
    74 int TranslateBaudeRate(char* optarg){
    91 static int TranslateBaudeRate(char* optarg)
       
    92 {
    75 	if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
    93 	if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
    76 	if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
    94 	if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
    77 	if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
    95 	if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
    78 	if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
    96 	if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
    79 	if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
    97 	if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
    83 	if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
   101 	if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
    84 	if(!strcmp( optarg, "none")) return 0;
   102 	if(!strcmp( optarg, "none")) return 0;
    85 	return 0x0000;
   103 	return 0x0000;
    86 }
   104 }
    87 
   105 
    88 UNS8 canInit (s_BOARD *board)
   106 static UNS8 canInit (s_BOARD *board)
    89 {
   107 {
    90 	int baudrate;
   108 	int baudrate;
    91 	int ret = 0;
   109 	int ret = 0;
    92 
   110 
    93 #ifdef PCAN2_HEADER_
   111 #ifdef PCAN2_HEADER_
    94 	// if not the first handler
   112 	// if not the first handler
    95 	if(second_board == (s_BOARD *)board) {
   113 	if(second_board == (s_BOARD *)board) {
       
   114 		if(hEvent2==NULL)
       
   115 		{	/* Create the Event for the first board */
       
   116 		  hEvent2 = CreateEvent(NULL, // lpEventAttributes
       
   117 							FALSE,  // bManualReset
       
   118 							FALSE,  // bInitialState
       
   119 							"");    // lpName
       
   120 		  InitializeCriticalSection(&InitLock2);
       
   121 		}
       
   122 
       
   123 		EnterCriticalSection(&InitLock2);
    96 		if(baudrate = TranslateBaudeRate(board->baudrate))
   124 		if(baudrate = TranslateBaudeRate(board->baudrate))
    97 		{
   125 		{
    98 			ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
   126 		  ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
    99 			if(ret != CAN_ERR_OK)
   127 		  if(ret != CAN_ERR_OK)
   100 				return 0;
   128 		  {
   101 		}
   129 		    LeaveCriticalSection(&InitLock2);
   102 
   130 		    return 0;
   103 		//Create the Event for the first board
   131 		  }
   104 		if(hEvent2 != NULL){
       
   105 			hEvent2 = CreateEvent(NULL, // lpEventAttributes
       
   106 			                      FALSE,  // bManualReset
       
   107 			                      FALSE,  // bInitialState
       
   108 			                      "");    // lpName
       
   109 		}
   132 		}
   110 		//Set Event Handle for CANReadExt
   133 		//Set Event Handle for CANReadExt
   111 		CAN2_SetRcvEvent(hEvent2);
   134 		CAN2_SetRcvEvent(hEvent2);
       
   135 		LeaveCriticalSection(&InitLock2);
   112 	}
   136 	}
   113 	else
   137 	else
   114 #endif
   138 #endif
   115 	if(first_board == (s_BOARD *)board) {
   139 	if(first_board == (s_BOARD *)board) {
       
   140 		//Create the Event for the first board
       
   141 		if(hEvent1==NULL)
       
   142 		{
       
   143 		  hEvent1 = CreateEvent(NULL, // lpEventAttributes
       
   144 							FALSE,  // bManualReset
       
   145 							FALSE,  // bInitialState
       
   146 							"");    // lpName
       
   147 		  InitializeCriticalSection(&InitLock1);
       
   148                 }
       
   149 
       
   150 		EnterCriticalSection(&InitLock1);
   116 		if(baudrate = TranslateBaudeRate(board->baudrate))
   151 		if(baudrate = TranslateBaudeRate(board->baudrate))
   117 		{
   152 		{
   118 			ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
   153 		  ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params);
   119 			if(ret != CAN_ERR_OK)
   154 		  if(ret != CAN_ERR_OK)
   120 				return 0;
   155 		  {
   121 		}
   156 		    LeaveCriticalSection(&InitLock1);
   122 		//Create the Event for the first board
   157 		    return 0;
   123 		if(hEvent1 != NULL){
   158 		  }
   124 			hEvent1 = CreateEvent(NULL, // lpEventAttributes
       
   125 			                      FALSE,  // bManualReset
       
   126 			                      FALSE,  // bInitialState
       
   127 			                      "");    // lpName
       
   128 		}
   159 		}
   129 		//Set Event Handle for CANReadExt
   160 		//Set Event Handle for CANReadExt
   130 		CAN_SetRcvEvent(hEvent1);
   161 		CAN_SetRcvEvent(hEvent1);
       
   162 		LeaveCriticalSection(&InitLock1);
   131 	}
   163 	}
   132 	return 1;
   164 	return 1;
   133 }
   165 }
   134 
   166 
   135 /********* functions which permit to communicate with the board ****************/
   167 /********* functions which permit to communicate with the board ****************/
   136 UNS8 __stdcall canReceive_driver (CAN_HANDLE fd0, Message * m)
   168 UNS8 LIBAPI canReceive_driver(CAN_HANDLE fd0, Message * m)
   137 {
   169 {
       
   170 static int HeavyCounter = 0;
   138 	int ret=0;
   171 	int ret=0;
   139 	UNS8 data;
   172 	UNS8 data;
   140 	TPCANMsg peakMsg;
   173 	TPCANMsg peakMsg;
       
   174 #ifdef CAN_READ_EX
   141 	TPCANTimestamp peakRcvTime;
   175 	TPCANTimestamp peakRcvTime;
       
   176 #endif
   142 	DWORD Res;
   177 	DWORD Res;
   143 	DWORD result;
   178 	DWORD result;
   144 	// loop until valid message or fatal error
   179 	// loop until valid message or fatal error
   145 	do{
   180 	do{
   146 #ifdef PCAN2_HEADER_
   181 #ifdef PCAN2_HEADER_
   149 			//wait for CAN msg...
   184 			//wait for CAN msg...
   150 			result = WaitForSingleObject(hEvent2, INFINITE);
   185 			result = WaitForSingleObject(hEvent2, INFINITE);
   151 			if (result == WAIT_OBJECT_0)
   186 			if (result == WAIT_OBJECT_0)
   152 				Res = CAN2_ReadEx(&peakMsg, &peakRcvTime);
   187 				Res = CAN2_ReadEx(&peakMsg, &peakRcvTime);
   153 				// Exit receive thread when handle is no more valid
   188 				// Exit receive thread when handle is no more valid
   154 				if(Res & CAN_ERR_ILLHANDLE)
   189 				if(Res & CAN_ERRMASK_ILLHANDLE)
   155 					return 1;
   190 					return 1;
   156 		}
   191 		}
   157 		else
   192 		else
   158 #endif
   193 #endif
   159 
   194 
   160 		// We read the queue looking for messages.
   195 		// We read the queue looking for messages.
   161 		if(first_board == (s_BOARD *)fd0) {
   196 		if(first_board == (s_BOARD *)fd0) 
       
   197 		{
       
   198 #ifdef VERSION_2
   162 			result = WaitForSingleObject(hEvent1, INFINITE);
   199 			result = WaitForSingleObject(hEvent1, INFINITE);
   163 			if (result == WAIT_OBJECT_0)
   200 			if (result == WAIT_OBJECT_0)
       
   201 #endif
   164 			{
   202 			{
       
   203 #ifdef CAN_READ_EX
   165 				Res = CAN_ReadEx(&peakMsg, &peakRcvTime);
   204 				Res = CAN_ReadEx(&peakMsg, &peakRcvTime);
       
   205 #else
       
   206 				Res = CAN_Read(&peakMsg);
       
   207 #endif
   166 				// Exit receive thread when handle is no more valid
   208 				// Exit receive thread when handle is no more valid
   167 				if(Res & CAN_ERR_ILLHANDLE)
   209 #ifdef CAN_ERRMASK_ILLHANDLE
   168 					return 1;
   210 				if(Res & CAN_ERRMASK_ILLHANDLE) return 1;
       
   211 #else
       
   212 				if(Res & CAN_ERR_ILLHANDLE) return 1;
       
   213 #endif				
       
   214 
       
   215 #ifndef VERSION_2
       
   216 				if(Res != CAN_ERR_OK) 
       
   217 					result = WaitForSingleObject(hEvent1, 1);  	//pooling
       
   218 #endif
   169 			}
   219 			}
   170 		}
   220 		}
       
   221 #ifdef VERSION_2
   171 		else
   222 		else
   172 			Res = CAN_ERR_BUSOFF;
   223 			Res = CAN_ERR_BUSOFF;
   173 
   224 #endif
       
   225 		
   174 		// A message was received : we process the message(s)
   226 		// A message was received : we process the message(s)
   175 		if (Res == CAN_ERR_OK)
   227 		if(Res == CAN_ERR_OK)
   176 		{
   228 		{			
   177 			// if something different that 11bit or rtr... problem
   229 		  switch(peakMsg.MSGTYPE)
   178 			if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR))
   230 		  {
   179 			{
   231 		    case MSGTYPE_STATUS:
   180 				if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF)
   232 			  switch(peakMsg.DATA[3])
   181 				{
   233 		          {
   182 					printf ("!!! Peak board read : re-init\n");
   234 			    case CAN_ERR_BUSHEAVY: 
   183 					canInit((s_BOARD*) fd0);
   235 				      break;
   184 					usleep (10000);
   236 		            case CAN_ERR_BUSOFF: 
   185 				}
   237 			              printf ("Peak board read BUSOFF: re-init!!!\n");
   186 
   238 				      canInit((s_BOARD*)fd0);
   187 				// If status, return status if 29bit, return overrun
   239 				      usleep(33);
   188 				return peakMsg.MSGTYPE ==
   240 				      break;
   189 					MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN;
   241 			  }
   190 			}
   242 			  return peakMsg.DATA[3];	/* if something different that 11bit or rtr... problem */
   191 			m->cob_id = peakMsg.ID;
   243 
   192 
   244 		    case MSGTYPE_STANDARD:		/* bits of MSGTYPE_ */
   193 			if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)	/* bits of MSGTYPE_ */
   245 		    case MSGTYPE_EXTENDED:
   194 				m->rtr = 0;
   246 			  m->rtr = 0;
   195 			else
   247 			  break;
   196 				m->rtr = 1;
   248 
   197 			m->len = peakMsg.LEN;	/* count of data bytes (0..8) */
   249 		    case MSGTYPE_RTR:			/* bits of MSGTYPE_ */
   198 			for (data = 0; data < peakMsg.LEN; data++)
   250 			  m->rtr = 1;
   199 				m->data[data] = peakMsg.DATA[data];	/* data bytes, up to 8 */
   251 			  break;
       
   252 
       
   253 		    default: return CAN_ERR_OVERRUN;	/* If status, return status if 29bit, return overrun. */
       
   254 		    
       
   255 		    }
       
   256 
       
   257 		   m->cob_id = peakMsg.ID;				
       
   258 		   if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)  /* bits of MSGTYPE_ */
       
   259                      m->rtr = 0;
       
   260 		   else
       
   261 		     m->rtr = 1;
       
   262 		   m->len = peakMsg.LEN;		/* count of data bytes (0..8) */
       
   263 		   for (data = 0; data < peakMsg.LEN; data++)
       
   264 			m->Data[data] = peakMsg.DATA[data];	/* data bytes, up to 8 */
   200 #if defined DEBUG_MSG_CONSOLE_ON
   265 #if defined DEBUG_MSG_CONSOLE_ON
   201 			MSG("in : ");
   266 			MSG("in : ");
   202 			print_message(m);
   267 			print_message(m);
   203 #endif
   268 #endif
   204 		}
   269 		}
   211 			{
   276 			{
   212 				printf ("canReceive returned error (%d)\n", Res);
   277 				printf ("canReceive returned error (%d)\n", Res);
   213 				return 1;
   278 				return 1;
   214 			}
   279 			}
   215 		}
   280 		}
   216 	}while(Res != CAN_ERR_OK);
   281 	} while(Res != CAN_ERR_OK);
   217 	return 0;
   282 	return 0;
   218 }
   283 }
   219 
   284 
   220 /***************************************************************************/
   285 /***************************************************************************/
   221 UNS8 __stdcall canSend_driver (CAN_HANDLE fd0, Message const * m)
   286 UNS8 LIBAPI canSend_driver(CAN_HANDLE fd0, Message const *m)
   222 {
   287 {
   223 	UNS8 data;
   288 	UNS8 data;
   224 	DWORD localerrno;
       
   225 	TPCANMsg peakMsg;
   289 	TPCANMsg peakMsg;
   226 	peakMsg.ID = m->cob_id;	/* 11/29 bit code */
   290 	peakMsg.ID = m->cob_id;	/* 11/29 bit code */
   227 	if (m->rtr == 0)
   291 	if (m->rtr == 0)
   228 		peakMsg.MSGTYPE = CAN_INIT_TYPE_ST;	/* bits of MSGTYPE_ */
       
   229 	else
       
   230 	{
   292 	{
   231 		peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR;	/* bits of MSGTYPE_ */
   293 	  if(peakMsg.ID > 0x7FF)
   232 	}
   294 		peakMsg.MSGTYPE = MSGTYPE_EXTENDED;	/* bits of MSGTYPE_ */
       
   295 	  else
       
   296 		peakMsg.MSGTYPE = MSGTYPE_STANDARD;	/* bits of MSGTYPE_ */
       
   297 	}
       
   298 	else	
       
   299 		peakMsg.MSGTYPE = MSGTYPE_RTR;		/* bits of MSGTYPE_ */
       
   300 	
   233 	peakMsg.LEN = m->len;
   301 	peakMsg.LEN = m->len;
   234 	/* count of data bytes (0..8) */
   302 	/* count of data bytes (0..8) */
   235 	for (data = 0; data < m->len; data++)
   303 	for (data = 0; data < m->len; data++)
   236 		peakMsg.DATA[data] = m->data[data];	/* data bytes, up to 8 */
   304 		peakMsg.DATA[data] = m->Data[data];	/* data bytes, up to 8 */
   237 
   305 
   238 	do
   306 	do
   239 	{
   307 	{
   240 #ifdef PCAN2_HEADER_
   308 #ifdef PCAN2_HEADER_
   241 		// if not the first handler
   309 		// if not the first handler
   242 		if(second_board == (s_BOARD *)fd0)
   310 		if(second_board == (s_BOARD *)fd0)
   243 		{
   311 		{
   244 			errno = localerrno = CAN2_Write (&peakMsg);
   312 			errno = CAN2_Write (&peakMsg);
   245 		}
   313 		}
   246 		else
   314 		else
   247 #endif
   315 #endif
   248 		if(first_board == (s_BOARD *)fd0)
   316 		if(first_board == (s_BOARD *)fd0)
   249 			{
   317 			{
   250 				errno = localerrno = CAN_Write (&peakMsg);
   318 				errno = CAN_Write (&peakMsg);
   251 			}
   319 			}
   252 		else
   320 		else
   253 			goto fail;
   321 			goto fail;
   254 		if (localerrno)
   322 		if (errno)
   255 		{
   323 		{
   256 			if (localerrno == CAN_ERR_BUSOFF)
   324 			if (errno == CAN_ERR_BUSOFF)
   257 			{
   325 			{
   258 				printf ("!!! Peak board write : re-init\n");
   326 				printf ("!!! Peak board write : re-init\n");
   259 				canInit((s_BOARD*)fd0);
   327 				canInit((s_BOARD*)fd0);
   260 				usleep (10000);
   328 				usleep (10000);
   261 			}
   329 			}
   262 			usleep (1000);
   330 			usleep (1000);
   263 		}
   331 		}
   264 	}
   332 	}
   265 	while (localerrno != CAN_ERR_OK);
   333 	while (errno != CAN_ERR_OK);
   266 #if defined DEBUG_MSG_CONSOLE_ON
   334 #if defined DEBUG_MSG_CONSOLE_ON
   267 	MSG("out : ");
   335 	MSG("out : ");
   268 	print_message(m);
   336 	print_message(m);
   269 #endif
   337 #endif
   270 	return 0;
   338 	return 0;
   271 fail:
   339 fail:
   272 	return 1;
   340 	return 1;
   273 }
   341 }
   274 
   342 
   275 /***************************************************************************/
   343 /***************************************************************************/
   276 UNS8 __stdcall canChangeBaudRate_driver( CAN_HANDLE fd, char* baud)
   344 UNS8 LIBAPI canChangeBaudRate_driver(CAN_HANDLE fd, char* baud)
   277 {
   345 {
   278 	printf("canChangeBaudRate not yet supported by this driver\n");
   346 	printf("canChangeBaudRate not yet supported by this driver\n");
   279 	return 0;
   347 	return 0;
   280 }
   348 }
   281 
   349 
   282 /***************************************************************************/
   350 /***************************************************************************/
   283 CAN_HANDLE __stdcall canOpen_driver (s_BOARD * board)
   351 LIBPUBLIC CAN_HANDLE LIBAPI canOpen_driver(s_BOARD * board)
   284 {
   352 {
   285   char busname[64];
       
   286   char* pEnd;
   353   char* pEnd;
   287   int ret;
   354   int ret;
   288 
   355 
   289   //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0));
   356   //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0));
   290   if (strtol(board->busname, &pEnd,0) == 0)
   357   if (strtol(board->busname, &pEnd,0) == 0)
   306   }
   373   }
   307   #endif
   374   #endif
   308   return NULL;
   375   return NULL;
   309 }
   376 }
   310 
   377 
       
   378 
   311 /***************************************************************************/
   379 /***************************************************************************/
   312 int __stdcall canClose_driver (CAN_HANDLE fd0)
   380 int LIBAPI canClose_driver(CAN_HANDLE fd0)
   313 {
   381 {
   314 #ifdef PCAN2_HEADER_
   382 #ifdef PCAN2_HEADER_
   315       // if not the first handler
   383 	// if not the first handler
   316       if(second_board == (s_BOARD *)fd0)
   384 	if(second_board == (s_BOARD *)fd0)
   317       {
   385 	{
   318            CAN2_SetRcvEvent(NULL);
   386 		CAN2_SetRcvEvent(NULL);
   319            CAN2_Close ();
   387 		CAN2_Close ();		
   320            if(hEvent2)
   388 		if(hEvent2)
   321            {
   389 		{
   322              SetEvent(hEvent2);
   390 		  SetEvent(hEvent2);
   323              CloseHandle(hEvent2);
   391 		  CloseHandle(hEvent2);		
   324              hEvent2 = NULL;
   392 		  hEvent2 = NULL;
   325            }
   393 		}
   326            second_board = (s_BOARD *)NULL;
   394 		second_board = (s_BOARD *)NULL;
   327       }else
   395 	}else
   328 #endif
   396 #endif
   329       if(first_board == (s_BOARD *)fd0)
   397 	if(first_board == (s_BOARD *)fd0)
   330       {
   398 	{
   331            CAN_SetRcvEvent(NULL);
   399 		CAN_SetRcvEvent(NULL);
   332            CAN_Close ();
   400 		CAN_Close ();		
   333            if(hEvent1)
   401 		if(hEvent1) 
   334            {
   402 		{
   335              SetEvent(hEvent1);
   403                   SetEvent(hEvent1);
   336              CloseHandle(hEvent1);
   404 		  CloseHandle(hEvent1);
   337              hEvent1 = NULL;
   405 		  hEvent1 = NULL;
   338             }
   406                 }
   339            first_board = (s_BOARD *)NULL;
   407 		first_board = (s_BOARD *)NULL;
   340       }
   408 	}
   341       return 0;
   409 	return 0;
   342 }
   410 }