can_peak_win32.c

Go to the documentation of this file.
00001 /*
00002 This file is part of CanFestival, a library implementing CanOpen Stack. 
00003 
00004 Copyright (C): Edouard TISSERANT and Francis DUPIN
00005 
00006 See COPYING file for copyrights details.
00007 
00008 This library is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU Lesser General Public
00010 License as published by the Free Software Foundation; either
00011 version 2.1 of the License, or (at your option) any later version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 Lesser General Public License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public
00019 License along with this library; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #if defined(WIN32) && !defined(__CYGWIN__)
00024 #define usleep(micro) Sleep(micro%1000 ? (micro/1000) + 1 : (micro/1000))
00025 #else
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <errno.h>
00029 #include <fcntl.h>
00030 #endif
00031 
00032 #include "cancfg.h"
00033 #include "can_driver.h"
00034 
00035 #ifndef extra_PCAN_init_params
00036         #define extra_PCAN_init_params 
00037 #else
00038         #define extra_PCAN_init_params\
00039                 ,getenv("PCANHwType") ? strtol(getenv("PCANHwType"),NULL,0):0\
00040                 ,getenv("PCANIO_Port") ? strtol(getenv("PCANIO_Port"),NULL,0):0\
00041                 ,getenv("PCANInterupt") ? strtol(getenv("PCANInterupt"),NULL,0):0
00042 #endif
00043 
00044 static s_BOARD *first_board = NULL;
00045 #ifdef PCAN2_HEADER_
00046 static s_BOARD *second_board = NULL;
00047 #endif
00048 
00049 //pthread_mutex_t PeakCan_mutex = PTHREAD_MUTEX_INITIALIZER;
00050 
00051 // Define for rtr CAN message
00052 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
00053 
00054 /***************************************************************************/
00055 int TranslateBaudeRate(char* optarg){
00056         if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
00057         if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
00058         if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
00059         if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
00060         if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
00061         if(!strcmp( optarg, "50K")) return CAN_BAUD_50K;
00062         if(!strcmp( optarg, "20K")) return CAN_BAUD_20K;
00063         if(!strcmp( optarg, "10K")) return CAN_BAUD_10K;
00064         if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
00065         if(!strcmp( optarg, "none")) return 0;
00066         return 0x0000;
00067 }
00068 
00069 void
00070 canInit (s_BOARD *board)
00071 {
00072         int baudrate;
00073         
00074 #ifdef PCAN2_HEADER_
00075         // if not the first handler
00076         if(second_board == (s_BOARD *)board)
00077                 if(baudrate = TranslateBaudeRate(board->baudrate))
00078                         CAN2_Init (baudrate,
00079                           CAN_INIT_TYPE_ST extra_PCAN_init_params);
00080 #endif
00081         if(first_board == (s_BOARD *)board)
00082                 if(baudrate = TranslateBaudeRate(board->baudrate))
00083                         CAN_Init (baudrate,
00084                           CAN_INIT_TYPE_ST extra_PCAN_init_params);
00085 }
00086 
00087 /*********functions which permit to communicate with the board****************/
00088 UNS8
00089 canReceive_driver (CAN_HANDLE fd0, Message * m)
00090 {
00091         UNS8 data;
00092         TPCANMsg peakMsg;
00093 
00094         DWORD Res;
00095 
00096         do{
00097                 // We read the queue looking for messages.
00098                 // 
00099                 //pthread_mutex_lock (&PeakCan_mutex);
00100 #ifdef PCAN2_HEADER_
00101                 // if not the first handler
00102                 if(second_board == (s_BOARD *)fd0)
00103                         Res = CAN2_Read (&peakMsg);
00104                 else
00105 #endif
00106                 if(first_board == (s_BOARD *)fd0)
00107                         Res = CAN_Read (&peakMsg);
00108                 else
00109                         Res = CAN_ERR_BUSOFF;
00110         
00111                 // A message was received
00112                 // We process the message(s)
00113                 // 
00114                 if (Res == CAN_ERR_OK)
00115                 {
00116                         // if something different that 11bit or rtr... problem
00117                         if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR))
00118                         {
00119                                 if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF)
00120                                 {
00121                                         printf ("!!! Peak board read : re-init\n");
00122                                         canInit((s_BOARD*) fd0);
00123                                         usleep (10000);
00124                                 }
00125         
00126                                 // If status, return status if 29bit, return overrun
00127                                 //pthread_mutex_unlock (&PeakCan_mutex);
00128                                 return peakMsg.MSGTYPE ==
00129                                         MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN;
00130                         }
00131                         m->cob_id.w = peakMsg.ID;
00132                         if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)        /* bits of MSGTYPE_ */
00133                                 m->rtr = 0;
00134                         else
00135                                 m->rtr = 1;
00136                         m->len = peakMsg.LEN;   /* count of data bytes (0..8) */
00137                         for (data = 0; data < peakMsg.LEN; data++)
00138                                 m->data[data] = peakMsg.DATA[data];     /* data bytes, up to 8 */
00139         
00140                 }else{
00141                 //pthread_mutex_unlock (&PeakCan_mutex);
00142                 //if (Res != CAN_ERR_OK)
00143                 //{
00144                         if (!
00145                                 (Res & CAN_ERR_QRCVEMPTY || Res & CAN_ERR_BUSLIGHT
00146                                  || Res & CAN_ERR_BUSHEAVY))
00147                         {
00148                                 printf ("canReceive returned error (%d)\n", Res);
00149                                 return 1;
00150                         }
00151                         usleep (1000);          
00152                 }
00153         }while(Res != CAN_ERR_OK);
00154         return 0;
00155 }
00156 
00157 /***************************************************************************/
00158 UNS8
00159 canSend_driver (CAN_HANDLE fd0, Message * m)
00160 {
00161         UNS8 data;
00162         TPCANMsg peakMsg;
00163         peakMsg.ID = m->cob_id.w;       /* 11/29 bit code */
00164         if (m->rtr == 0)
00165                 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST;     /* bits of MSGTYPE_ */
00166         else
00167         {
00168                 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_ */
00169         }
00170         peakMsg.LEN = m->len;
00171         /* count of data bytes (0..8) */
00172         for (data = 0; data < m->len; data++)
00173                 peakMsg.DATA[data] = m->data[data];     /* data bytes, up to 8 */
00174         do
00175         {
00176 #ifdef PCAN2_HEADER_
00177                 // if not the first handler
00178                 if(second_board == (s_BOARD *)fd0)
00179                         errno = CAN2_Write (&peakMsg);
00180                 else 
00181 #endif
00182                 if(first_board == (s_BOARD *)fd0)
00183                         errno = CAN_Write (&peakMsg);
00184                 else 
00185                         goto fail;
00186                 if (errno)
00187                 {
00188                         if (errno == CAN_ERR_BUSOFF)
00189                         {
00190                                 printf ("!!! Peak board write : re-init\n");
00191                                 canInit((s_BOARD*)fd0);
00192                                 usleep (10000);
00193                         }
00194                         usleep (1000);
00195                 }
00196         }
00197         while (errno != CAN_ERR_OK);
00198         return 0;
00199 fail:
00200         return 1;
00201 }
00202 
00203 /***************************************************************************/
00204 CAN_HANDLE
00205 canOpen_driver (s_BOARD * board)
00206 {
00207 #ifdef PCAN2_HEADER_
00208         if(first_board != NULL && second_board != NULL)
00209 #else
00210         if(first_board != NULL)
00211 #endif
00212         {
00213                 fprintf (stderr, "Open failed.\n");
00214                 fprintf (stderr,
00215                                  "can_peak_win32.c: no more can port available with this pcan library\n");
00216                 fprintf (stderr,
00217                                  "can_peak_win32.c: please link another executable with another pcan lib\n");
00218                 return NULL;
00219         }
00220 
00221 #ifdef PCAN2_HEADER_
00222         if(first_board == NULL)
00223                 first_board = board;
00224         else
00225                 second_board = board; 
00226 #else
00227         first_board = board;
00228 #endif
00229 
00230         canInit(board);
00231         
00232         return (CAN_HANDLE)board;
00233 }
00234 
00235 /***************************************************************************/
00236 int
00237 canClose_driver (CAN_HANDLE fd0)
00238 {
00239 #ifdef PCAN2_HEADER_
00240         // if not the first handler
00241         if(second_board == (s_BOARD *)fd0)
00242         {
00243                 CAN2_Close ();
00244                 second_board = (s_BOARD *)NULL;
00245         }else   
00246 #endif
00247         if(first_board == (s_BOARD *)fd0)
00248         {
00249                 CAN_Close ();
00250                 first_board = (s_BOARD *)NULL;
00251         }
00252         return 0;
00253 }

Generated on Mon Jul 2 19:10:16 2007 for CanFestival by  doxygen 1.5.1