00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00050
00051
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
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
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
00098
00099
00100 #ifdef PCAN2_HEADER_
00101
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
00112
00113
00114 if (Res == CAN_ERR_OK)
00115 {
00116
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
00127
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)
00133 m->rtr = 0;
00134 else
00135 m->rtr = 1;
00136 m->len = peakMsg.LEN;
00137 for (data = 0; data < peakMsg.LEN; data++)
00138 m->data[data] = peakMsg.DATA[data];
00139
00140 }else{
00141
00142
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;
00164 if (m->rtr == 0)
00165 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST;
00166 else
00167 {
00168 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR;
00169 }
00170 peakMsg.LEN = m->len;
00171
00172 for (data = 0; data < m->len; data++)
00173 peakMsg.DATA[data] = m->data[data];
00174 do
00175 {
00176 #ifdef PCAN2_HEADER_
00177
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
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 }