/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
-This file is not part of CanFestival.
-This is third party contributed file.
+Copyright (C): Edouard TISSERANT and Francis DUPIN
-It is provided as-this and without any warranty
+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.
-//****************************************************************************
-// 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)
-//****************************************************************************
+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.
-/*
- Obfuscated by COBF (Version 1.06 2006-01-07 by BB) at Tue Aug 8 23:36:30 2006
+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
*/
-#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"
+#include "def.h"
#ifndef extra_PCAN_init_params
-#define extra_PCAN_init_params
+ #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_
-#define pcan_s 2
-#else
-#define pcan_s 1
+static s_BOARD *second_board = NULL;
#endif
-pcan_34 pcan_51{pcan_9 pcan_r;pcan_39 pcan_1;pcan_24*pcan_o;pcan_16*
-pcan_k;}pcan_c;pcan_c pcan_g[pcan_s]={{0,},};pcan_47 pcan_l=pcan_38;
-pcan_12 pcan_x(pcan_n pcan_b){
+
+//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_
-pcan_d(pcan_g!=((pcan_c* )pcan_b))pcan_52(((pcan_c* )pcan_b)->pcan_k
-->pcan_20,pcan_v extra_PCAN_init_params);pcan_j
+ // 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
-pcan_54(((pcan_c* )pcan_b)->pcan_k->pcan_20,pcan_v
-extra_PCAN_init_params);}pcan_t pcan_17(pcan_n pcan_b,pcan_4*pcan_e){
-pcan_t pcan_f;pcan_23 pcan_a;pcan_11 pcan_i;pcan_22(&pcan_l);
+ 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_
-pcan_d(pcan_g!=((pcan_c* )pcan_b))pcan_i=pcan_27(&pcan_a);pcan_j
+ // 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 = 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);
#endif
-pcan_i=pcan_48(&pcan_a);pcan_d(pcan_i==pcan_w){pcan_d(pcan_a.pcan_q&~
-(pcan_14|pcan_10)){pcan_d(pcan_a.pcan_q==pcan_25){pcan_7("\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_x(pcan_b);pcan_y(
-10000);}pcan_u(&pcan_l);pcan_p pcan_a.pcan_q==pcan_28?pcan_a.pcan_8[2
-]:pcan_46;}pcan_e->pcan_13.pcan_15=pcan_a.pcan_18;pcan_d(pcan_a.
-pcan_q==pcan_v)pcan_e->pcan_2=0;pcan_j pcan_e->pcan_2=1;pcan_e->
-pcan_z=pcan_a.pcan_6;pcan_3(pcan_f=0;pcan_f<pcan_a.pcan_6;pcan_f++)pcan_e
-->pcan_f[pcan_f]=pcan_a.pcan_8[pcan_f];}pcan_u(&pcan_l);pcan_p pcan_i
-;}pcan_12 pcan_44(pcan_n pcan_b){pcan_24*pcan_o=((pcan_c* )pcan_b)->
-pcan_o;pcan_4 pcan_e;pcan_19(((pcan_c* )pcan_b)->pcan_r){pcan_11
-pcan_i;pcan_d((pcan_i=pcan_17(pcan_b,&pcan_e))==pcan_w){pcan_26();
-pcan_50(pcan_o,&pcan_e);pcan_30();}pcan_j{pcan_d(!(pcan_i&pcan_31||
-pcan_i&pcan_40||pcan_i&pcan_45)){pcan_7("\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_y(1000);}}}pcan_t pcan_41(
-pcan_n pcan_b,pcan_4*pcan_e){pcan_t pcan_f;pcan_23 pcan_a;pcan_a.
-pcan_18=pcan_e->pcan_13.pcan_15;pcan_d(pcan_e->pcan_2==0)pcan_a.
-pcan_q=pcan_v;pcan_j{pcan_a.pcan_q=pcan_14|pcan_10;}pcan_a.pcan_6=
-pcan_e->pcan_z;pcan_3(pcan_f=0;pcan_f<pcan_e->pcan_z;pcan_f++)pcan_a.
-pcan_8[pcan_f]=pcan_e->pcan_f[pcan_f];pcan_m=pcan_w;pcan_32{pcan_22(&
-pcan_l);
+ }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; /* 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_
-pcan_d(pcan_g!=((pcan_c* )pcan_b))pcan_m=pcan_53(&pcan_a);pcan_j
+ // 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);
+#if defined DEBUG_MSG_CONSOLE_ON
+ MSG("out : ");
+ print_message(m);
#endif
-pcan_m=pcan_43(&pcan_a);pcan_d(pcan_m){pcan_d(pcan_m==pcan_25){pcan_7
-("\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_x(
-pcan_b);pcan_y(10000);}pcan_u(&pcan_l);pcan_y(100);}pcan_j{pcan_u(&
-pcan_l);}}pcan_19(pcan_m!=pcan_w&&((pcan_c* )pcan_b)->pcan_r);pcan_p 0
-;}pcan_n pcan_42(pcan_16*pcan_k){pcan_9 pcan_55[64];pcan_9*pcan_36;
-pcan_21 pcan_h;pcan_3(pcan_h=0;pcan_h<pcan_s;pcan_h++){pcan_d(!pcan_g
-[pcan_h].pcan_r)pcan_56;}pcan_d(pcan_h==pcan_s){pcan_0(pcan_5,"\x4f"
-"\x70\x65\x6e\x20\x66\x61\x69\x6c\x65\x64\x2e\n");pcan_0(pcan_5,"\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_0(pcan_5,"\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_p pcan_37;}pcan_g[pcan_h].pcan_r=1
-;pcan_g[pcan_h].pcan_k=pcan_k;pcan_g[pcan_h].pcan_o=pcan_k->pcan_o;
-pcan_x((pcan_c* )&pcan_g[pcan_h]);pcan_29((pcan_c* )&pcan_g[pcan_h],&
-pcan_g[pcan_h].pcan_1);pcan_p(pcan_c* )&pcan_g[pcan_h];}pcan_21
-pcan_57(pcan_n pcan_b){((pcan_c* )pcan_b)->pcan_r=0;
+ return 0;
+fail:
+ return 1;
+}
+
+/***************************************************************************/
+UNS8 canChangeBaudRate_driver( CAN_HANDLE fd, char* baud)
+{
+ printf("canChangeBaudRate not yet supported by this driver\n");
+ return 0;
+}
+
+/***************************************************************************/
+CAN_HANDLE
+canOpen_driver (s_BOARD * board)
+{
+ char busname[64];
+ char* pEnd;
+
+ //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0));
+ if (strtol(board->busname, &pEnd,0) == 0)
+ {
+ first_board = board;
+ printf ("First Board selected\n");
+ canInit(board);
+ return (CAN_HANDLE)board;
+ }
+ #ifdef PCAN2_HEADER_
+ if (strtol(board->busname, &pEnd,0) == 1)
+ {
+ second_board = board;
+ printf ("Second Board selected\n");
+ canInit(board);
+ return (CAN_HANDLE)board;
+ }
+ #endif
+ return NULL;
+}
+
+/***************************************************************************/
+int
+canClose_driver (CAN_HANDLE fd0)
+{
#ifdef PCAN2_HEADER_
-pcan_d(pcan_g!=((pcan_c* )pcan_b))pcan_49();pcan_j
+ // if not the first handler
+ if(second_board == (s_BOARD *)fd0)
+ {
+ CAN2_Close ();
+ second_board = (s_BOARD *)NULL;
+ }else
#endif
-pcan_35();pcan_33(&((pcan_c* )pcan_b)->pcan_1);pcan_p 0;}
+ if(first_board == (s_BOARD *)fd0)
+ {
+ CAN_Close ();
+ first_board = (s_BOARD *)NULL;
+ }
+ return 0;
+}