nico@215: nico@215: nico@215: CanFestival: drivers/can_peak_win32/can_peak_win32.c Source File nico@215: nico@215: nico@215: nico@215: nico@215:
nico@215:
nico@215:
nico@215:
nico@215: nico@215:

can_peak_win32.c

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

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