drivers/can_peak_win32/can_peak_win32.c
changeset 145 e747d2e26af0
parent 42 17f0ea205942
child 267 96c688ebcde7
--- a/drivers/can_peak_win32/can_peak_win32.c	Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_peak_win32/can_peak_win32.c	Wed Apr 04 13:04:31 2007 +0200
@@ -1,119 +1,253 @@
 /*
-
-This file is not part of CanFestival.
-This is third party contributed file.
-
-It is provided as-this and without any warranty
-
+This file is part of CanFestival, a library implementing CanOpen Stack. 
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-//****************************************************************************
-// Copyright (C) 2006  PEAK System-Technik GmbH
-//
-// linux@peak-system.com
-// www.peak-system.com
-//
-// This part of software is proprietary. It is allowed to
-// distribute it with CanFestival. 
-//
-// No warranty at all is given.
-//
-// Maintainer(s): Edouard TISSERANT (edouard.tisserant@lolitech.fr)
-//****************************************************************************
-
-/*
-   Obfuscated by COBF (Version 1.06 2006-01-07 by BB) at Wed Aug  9 08:28:43 2006
-*/
-#include<stdio.h>
-#include<string.h>
-#include<stdlib.h>
-#include<errno.h>
-#include<stddef.h>
-#include<sys/ioctl.h>
-#include<fcntl.h>
-#include<signal.h>
-#include<sys/time.h>
-#include<unistd.h>
-#include<pthread.h>
-#include<applicfg.h>
-#include"timer.h"
-#include"can_driver.h"
-#include"timers_driver.h"
-#include"cobf.h"
+#if defined(WIN32) && !defined(__CYGWIN__)
+#define usleep(micro) Sleep(micro%1000 ? (micro/1000) + 1 : (micro/1000))
+#else
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#endif
+
+#include "cancfg.h"
+#include "can_driver.h"
+
 #ifndef extra_PCAN_init_params
-#define extra_PCAN_init_params
-#else
-#define extra_PCAN_init_params , pcan_o("PCANHwType") ? pcan_6(  \
-pcan_o("PCANHwType"), pcan_v,0):0 , pcan_o("PCANIO_Port") ? pcan_6(  \
-pcan_o("PCANIO_Port"), pcan_v,0):0 , pcan_o("PCANInterupt") ? pcan_6( \
- pcan_o("PCANInterupt"), pcan_v,0):0
-#endif
-#ifdef PCAN2_HEADER_
-#define pcan_t 2
-#else
-#define pcan_t 1
-#endif
-pcan_37 pcan_53{pcan_11 pcan_r;pcan_41 pcan_5;pcan_26*pcan_s;pcan_27*
-pcan_l;}pcan_c;pcan_c pcan_h[pcan_t]={{0,},};pcan_48 pcan_k=pcan_40;
-pcan_14 pcan_0(pcan_m pcan_b){
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_55(((pcan_c* )pcan_b)->pcan_l
-->pcan_20,pcan_y extra_PCAN_init_params);pcan_j
-#endif
-pcan_57(((pcan_c* )pcan_b)->pcan_l->pcan_20,pcan_y
-extra_PCAN_init_params);}pcan_u pcan_17(pcan_m pcan_b,pcan_8*pcan_e){
-pcan_u pcan_f;pcan_24 pcan_a;pcan_13 pcan_i;pcan_19(&pcan_k);
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_i=pcan_31(&pcan_a);pcan_j
-#endif
-pcan_i=pcan_51(&pcan_a);pcan_d(pcan_i==pcan_w){pcan_d(pcan_a.pcan_n&~
-(pcan_28|pcan_15)){pcan_d(pcan_a.pcan_n==pcan_23){pcan_2("\x21\x21"
-"\x21\x20\x50\x65\x61\x6b\x20\x62\x6f\x61\x72\x64\x20\x72\x65\x61\x64"
-"\x20\x3a\x20\x72\x65\x2d\x69\x6e\x69\x74\n");pcan_0(pcan_b);pcan_x(
-10000);}pcan_z(&pcan_k);pcan_q pcan_a.pcan_n==pcan_32?pcan_a.pcan_12[
-2]:pcan_50;}pcan_e->pcan_16.pcan_25=pcan_a.pcan_18;pcan_d(pcan_a.
-pcan_n==pcan_y)pcan_e->pcan_9=0;pcan_j pcan_e->pcan_9=1;pcan_e->
-pcan_1=pcan_a.pcan_7;pcan_3(pcan_f=0;pcan_f<pcan_a.pcan_7;pcan_f++)pcan_e
-->pcan_f[pcan_f]=pcan_a.pcan_12[pcan_f];}pcan_z(&pcan_k);pcan_q pcan_i
-;}pcan_14 pcan_47(pcan_m pcan_b){pcan_26*pcan_s=((pcan_c* )pcan_b)->
-pcan_s;pcan_8 pcan_e;pcan_21(((pcan_c* )pcan_b)->pcan_r){pcan_13
-pcan_i;pcan_d((pcan_i=pcan_17(pcan_b,&pcan_e))==pcan_w){pcan_30();
-pcan_54(pcan_s,&pcan_e);pcan_35();}pcan_j{pcan_d(!(pcan_i&pcan_33||
-pcan_i&pcan_42||pcan_i&pcan_49)){pcan_2("\x63\x61\x6e\x52\x65\x63\x65"
-"\x69\x76\x65\x20\x72\x65\x74\x75\x72\x6e\x65\x64\x20\x65\x72\x72\x6f"
-"\x72\x20\x28\x25\x64\x29\n",pcan_i);}pcan_x(1000);}}}pcan_u pcan_43(
-pcan_m pcan_b,pcan_8*pcan_e){pcan_u pcan_f;pcan_24 pcan_a;pcan_a.
-pcan_18=pcan_e->pcan_16.pcan_25;pcan_d(pcan_e->pcan_9==0)pcan_a.
-pcan_n=pcan_y;pcan_j{pcan_a.pcan_n=pcan_28|pcan_15;}pcan_a.pcan_7=
-pcan_e->pcan_1;pcan_3(pcan_f=0;pcan_f<pcan_e->pcan_1;pcan_f++)pcan_a.
-pcan_12[pcan_f]=pcan_e->pcan_f[pcan_f];pcan_p=pcan_w;pcan_36{pcan_19(
-&pcan_k);
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_p=pcan_56(&pcan_a);pcan_j
-#endif
-pcan_p=pcan_46(&pcan_a);pcan_d(pcan_p){pcan_d(pcan_p==pcan_23){pcan_2
-("\x21\x21\x21\x20\x50\x65\x61\x6b\x20\x62\x6f\x61\x72\x64\x20\x77"
-"\x72\x69\x74\x65\x20\x3a\x20\x72\x65\x2d\x69\x6e\x69\x74\n");pcan_0(
-pcan_b);pcan_x(10000);}pcan_z(&pcan_k);pcan_x(100);}pcan_j{pcan_z(&
-pcan_k);}}pcan_21(pcan_p!=pcan_w&&((pcan_c* )pcan_b)->pcan_r);pcan_q 0
-;}pcan_m pcan_44(pcan_27*pcan_l){pcan_11 pcan_58[64];pcan_11*pcan_39;
-pcan_22 pcan_g;pcan_3(pcan_g=0;pcan_g<pcan_t;pcan_g++){pcan_d(!pcan_h
-[pcan_g].pcan_r)pcan_45;}pcan_d(pcan_g==pcan_t){pcan_4(pcan_10,"\x4f"
-"\x70\x65\x6e\x20\x66\x61\x69\x6c\x65\x64\x2e\n");pcan_4(pcan_10,""
-"\x63\x61\x6e\x5f\x70\x65\x61\x6b\x5f\x77\x69\x6e\x33\x32\x2e\x63\x3a"
-"\x20\x6e\x6f\x20\x6d\x6f\x72\x65\x20\x63\x61\x6e\x20\x70\x6f\x72\x74"
-"\x20\x61\x76\x61\x69\x6c\x61\x62\x6c\x65\x20\x77\x69\x74\x68\x20\x74"
-"\x68\x69\x73\x20\x70\x63\x61\x6e\x20\x6c\x69\x62\x72\x61\x72\x79\n");
-pcan_4(pcan_10,"\x63\x61\x6e\x5f\x70\x65\x61\x6b\x5f\x77\x69\x6e\x33"
-"\x32\x2e\x63\x3a\x20\x70\x6c\x65\x61\x73\x65\x20\x6c\x69\x6e\x6b\x20"
-"\x61\x6e\x6f\x74\x68\x65\x72\x20\x65\x78\x65\x63\x75\x74\x61\x62\x6c"
-"\x65\x20\x77\x69\x74\x68\x20\x61\x6e\x6f\x74\x68\x65\x72\x20\x70\x63"
-"\x61\x6e\x20\x6c\x69\x62\n");pcan_q pcan_v;}pcan_h[pcan_g].pcan_r=1;
-pcan_h[pcan_g].pcan_l=pcan_l;pcan_h[pcan_g].pcan_s=pcan_l->pcan_s;
-pcan_0((pcan_c* )&pcan_h[pcan_g]);pcan_34((pcan_c* )&pcan_h[pcan_g],&
-pcan_h[pcan_g].pcan_5);pcan_q(pcan_c* )&pcan_h[pcan_g];}pcan_22
-pcan_59(pcan_m pcan_b){((pcan_c* )pcan_b)->pcan_r=0;
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_52();pcan_j
-#endif
-pcan_38();pcan_29(&((pcan_c* )pcan_b)->pcan_5);pcan_q 0;}
+	#define extra_PCAN_init_params /**/
+#else
+	#define extra_PCAN_init_params\
+		,getenv("PCANHwType") ? strtol(getenv("PCANHwType"),NULL,0):0\
+		,getenv("PCANIO_Port") ? strtol(getenv("PCANIO_Port"),NULL,0):0\
+		,getenv("PCANInterupt") ? strtol(getenv("PCANInterupt"),NULL,0):0
+#endif
+
+static s_BOARD *first_board = NULL;
+#ifdef PCAN2_HEADER_
+static s_BOARD *second_board = NULL;
+#endif
+
+//pthread_mutex_t PeakCan_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// Define for rtr CAN message
+#define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
+
+/***************************************************************************/
+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;
+	if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
+	if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
+	if(!strcmp( optarg, "50K")) return CAN_BAUD_50K;
+	if(!strcmp( optarg, "20K")) return CAN_BAUD_20K;
+	if(!strcmp( optarg, "10K")) return CAN_BAUD_10K;
+	if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
+	if(!strcmp( optarg, "none")) return 0;
+	return 0x0000;
+}
+
+void
+canInit (s_BOARD *board)
+{
+	int baudrate;
+	
+#ifdef PCAN2_HEADER_
+	// if not the first handler
+	if(second_board == (s_BOARD *)board)
+		if(baudrate = TranslateBaudeRate(board->baudrate))
+			CAN2_Init (baudrate,
+			  CAN_INIT_TYPE_ST extra_PCAN_init_params);
+#endif
+	if(first_board == (s_BOARD *)board)
+		if(baudrate = TranslateBaudeRate(board->baudrate))
+			CAN_Init (baudrate,
+			  CAN_INIT_TYPE_ST extra_PCAN_init_params);
+}
+
+/*********functions which permit to communicate with the board****************/
+UNS8
+canReceive_driver (CAN_HANDLE fd0, Message * m)
+{
+	UNS8 data;
+	TPCANMsg peakMsg;
+
+	DWORD Res;
+
+	do{
+		// We read the queue looking for messages.
+		// 
+		//pthread_mutex_lock (&PeakCan_mutex);
+#ifdef PCAN2_HEADER_
+		// if not the first handler
+		if(second_board == (s_BOARD *)fd0)
+			Res = CAN2_Read (&peakMsg);
+		else
+#endif
+		if(first_board == (s_BOARD *)fd0)
+			Res = CAN_Read (&peakMsg);
+		else
+			Res = CAN_ERR_BUSOFF;
+	
+		// 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
+				//pthread_mutex_unlock (&PeakCan_mutex);
+				return peakMsg.MSGTYPE ==
+					MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN;
+			}
+			m->cob_id.w = 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 */
+	
+		}else{
+		//pthread_mutex_unlock (&PeakCan_mutex);
+		//if (Res != CAN_ERR_OK)
+		//{
+			if (!
+				(Res & CAN_ERR_QRCVEMPTY || Res & CAN_ERR_BUSLIGHT
+				 || Res & CAN_ERR_BUSHEAVY))
+			{
+				printf ("canReceive returned error (%d)\n", Res);
+				return 1;
+			}
+			usleep (1000);		
+		}
+	}while(Res != CAN_ERR_OK);
+	return 0;
+}
+
+/***************************************************************************/
+UNS8
+canSend_driver (CAN_HANDLE fd0, Message * m)
+{
+	UNS8 data;
+	TPCANMsg peakMsg;
+	peakMsg.ID = m->cob_id.w;	/* 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_ */
+	}
+	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 */
+	do
+	{
+#ifdef PCAN2_HEADER_
+		// if not the first handler
+		if(second_board == (s_BOARD *)fd0)
+			errno = CAN2_Write (&peakMsg);
+		else 
+#endif
+		if(first_board == (s_BOARD *)fd0)
+			errno = CAN_Write (&peakMsg);
+		else 
+			goto fail;
+		if (errno)
+		{
+			if (errno == CAN_ERR_BUSOFF)
+			{
+				printf ("!!! Peak board write : re-init\n");
+				canInit((s_BOARD*)fd0);
+				usleep (10000);
+			}
+			usleep (1000);
+		}
+	}
+	while (errno != CAN_ERR_OK);
+	return 0;
+fail:
+	return 1;
+}
+
+/***************************************************************************/
+CAN_HANDLE
+canOpen_driver (s_BOARD * board)
+{
+#ifdef PCAN2_HEADER_
+	if(first_board != NULL && second_board != NULL)
+#else
+	if(first_board != NULL)
+#endif
+	{
+		fprintf (stderr, "Open failed.\n");
+		fprintf (stderr,
+				 "can_peak_win32.c: no more can port available with this pcan library\n");
+		fprintf (stderr,
+				 "can_peak_win32.c: please link another executable with another pcan lib\n");
+		return NULL;
+	}
+
+#ifdef PCAN2_HEADER_
+	if(first_board == NULL)
+		first_board = board;
+	else
+		second_board = board; 
+#else
+	first_board = board;
+#endif
+
+	canInit(board);
+	
+	return (CAN_HANDLE)board;
+}
+
+/***************************************************************************/
+int
+canClose_driver (CAN_HANDLE fd0)
+{
+#ifdef PCAN2_HEADER_
+	// if not the first handler
+	if(second_board == (s_BOARD *)fd0)
+	{
+		CAN2_Close ();
+		second_board = (s_BOARD *)NULL;
+	}else	
+#endif
+	if(first_board == (s_BOARD *)fd0)
+	{
+		CAN_Close ();
+		first_board = (s_BOARD *)NULL;
+	}
+	return 0;
+}