OpcUaCanOpen
CANopen OPC-UA server
kvcan.cpp
Go to the documentation of this file.
1 // This is the main DLL file.
2 
3 #include "kvcan.h"
4 
6 // kvCann.cpp: implementation of the KVCanScan class.
8 //#include "CCanCallback.h"
9 #include <time.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "gettimeofday.h"
13 
14 bool initLibarary = false;
15 #ifdef WIN32
16  extern "C" __declspec(dllexport) CCanAccess *getCanbusAccess()
17 #else
19 #endif
20  {
21  CCanAccess *cc;
22  cc = new KVCanScan;
23 
24  return cc;
25  }
26 
28 {
29  canInitializeLibrary();
30  return ;
31 }
32 
33 #ifdef WIN32
34 void CANLIBAPI KVCanScan::CanScanControlThread(int handle, void* pCanScan, unsigned int notifyEvent)
35 {
36  canStatus Status;
37  CanMsgStruct msg ;
38  unsigned long timeout = 1000;
39 
40  KVCanScan *ppcs = reinterpret_cast<KVCanScan *>(pCanScan);
41 // printf("Read Status %d\n",notifyEvent);
42  switch (notifyEvent) {
43  case canNOTIFY_RX:
44  unsigned int len,flag;
45  unsigned long ttime;
46  msg.c_id = 0;
47  Status = canReadWait(handle,&msg.c_id,&msg.c_data,&len,&flag,&ttime,timeout);
48 
49  msg.c_time.tv_sec = ttime / 1000000;
50  msg.c_time.tv_usec = ttime % 1000000;
51  msg.c_dlc = len;
52  msg.c_ff = flag;
53  if (Status == canERR_NOMSG)
54  {
55  break;
56  }
57  if (msg.c_ff & canMSG_ERROR_FRAME) {
58  Status = canIoCtl(handle,canIOCTL_CLEAR_ERROR_COUNTERS,NULL,0);
59 
60  break;
61  }
62  if (msg.c_ff & canSTAT_ERROR_PASSIVE) {
63 
64  break;
65  }
66 
67  if (Status == canOK) {
68  ppcs->canMessageCame(msg);
69 // printf("id = %d\n",msg.c_id);
70 
71  }
72  else {
73  ppcs->sendErrorCode(Status);
74  }
75  }
76 
77  return;
78 }
79 #else
80 void CANLIBAPI KVCanScan::CanScanControlThread(canNotifyData *cnd)
81 {
82  canStatus Status;
83  CanMsgStruct msg;
84  unsigned long timeout = 1000;
85  unsigned int dlc,ff;
86  KVCanScan *ppcs = reinterpret_cast<KVCanScan *>(cnd->tag);
87 
88  switch (cnd->eventType ) {
89  case canEVENT_RX:
90  dlc = (unsigned int )msg.c_dlc;
91  ff = (unsigned int )msg.c_ff;
92 
93  Status = canReadWait(ppcs->canObjHandler,&msg.c_id,&msg.c_data,&dlc,&ff,(unsigned long *)&msg.c_time,timeout);
94  if (Status == canERR_NOMSG)
95  {
96  break;
97  }
98  if (msg.c_ff & canMSG_ERROR_FRAME) {
99  Status = canIoCtl(ppcs->canObjHandler,canIOCTL_CLEAR_ERROR_COUNTERS,NULL,0);
100 
101  break;
102  }
103  if (msg.c_ff & canSTAT_ERROR_PASSIVE) {
104 
105  break;
106  }
107 
108  if (Status == canOK) {
109  ppcs->cb->FireOnChange(ppcs->canObjHandler,&msg);
110 
111  }
112  else {
113  ppcs->sendErrorCode(Status);
114  }
115  }
116 
117  return;
118 }
119 #endif
120 
122 {
123  run_can = false;
124  canClose(canObjHandler);
125 }
126 
127 bool KVCanScan::configureCanboard(const char *name,const char *parameters)
128 {
129  canStatus Status = canOK;
130 
131  unsigned int tseg1 = 0;
132  unsigned int tseg2 = 0;
133  unsigned int sjw = 0;
134  unsigned int noSamp = 0;
135  unsigned int syncmode = 0;
136  unsigned int m_usedBaudRate = 125000;
137 // unsigned long flag;
138 
139  int numPar; //check
140 
141  sscanf(name,"%d",&numChannel);
142  if (parameters)
143  numPar = sscanf(parameters,"%d %d %d %d %d %d",&m_usedBaudRate,&tseg1,&tseg2,&sjw,&noSamp,&syncmode);
144  printf("Par %d %d %d %d %d %d\n",m_usedBaudRate,tseg1,tseg2,sjw,noSamp,syncmode);
145 
146  canObjHandler = canOpenChannel(numChannel,canOPEN_EXCLUSIVE | canOPEN_OVERRIDE_EXCLUSIVE | canOPEN_REQUIRE_INIT_ACCESS);
147  if (canObjHandler >= 0) {
148  printf("Handler = %d %d\n",canObjHandler,numChannel);
149  switch(m_usedBaudRate) {
150  case 1000000:
151  m_usedBaudRate = BAUD_1M;
152  break;
153  case 500000:
154  m_usedBaudRate = BAUD_500K;
155  break;
156  case 250000:
157  m_usedBaudRate = BAUD_250K;
158  break;
159  case 125000:
160  m_usedBaudRate = BAUD_125K;
161  break;
162  case 100000:
163  m_usedBaudRate = BAUD_100K;
164  break;
165  case 62500:
166  m_usedBaudRate = BAUD_62K;
167  break;
168  case 50000:
169  m_usedBaudRate = BAUD_50K;
170  break;
171  default:
172  printf("Baudrate set to 125 kbit/s. \n");
173  m_usedBaudRate = BAUD_125K;
174  break;
175  }
176 
177  canSetBusParams(canObjHandler,m_usedBaudRate,tseg1,tseg2,sjw,noSamp,syncmode);
178  Status = canIoCtl(canObjHandler,canIOCTL_FLUSH_RX_BUFFER,NULL,NULL);
179  canBusOn(canObjHandler);
180 
181  bus_status = canOK;
182 #ifdef WIN32
183  Status = kvSetNotifyCallback(canObjHandler,KVCanScan::CanScanControlThread,this,canNOTIFY_RX);
184 #else
185  Status = canSetNotify(canObjHandler,KVCanScan::CanScanControlThread,canNOTIFY_RX,this);
186 #endif
187  return true;
188  }
189  return false;
190 }
191 
192 bool KVCanScan::sendErrorCode(long status)
193 {
194  timeval ftTimeStamp;
195  if (status != bus_status) {
196  gettimeofday(&ftTimeStamp,0);
197  char *errMess;
198  getErrorMessage(status,&errMess);
199  canMessageError(status,errMess,ftTimeStamp );
200  bus_status = (canStatus)status;
201 
202  }
203  if (status != canOK) {
204  status = canIoCtl(canObjHandler,canIOCTL_CLEAR_ERROR_COUNTERS,NULL,0);
205  return false;
206  }
207  return true;
208 }
209 
210 bool KVCanScan::sendMessage(short cobID, unsigned char len, unsigned char *message)
211 {
212  canStatus Status;
213 
214  Status = canWrite(canObjHandler,cobID,message,len,0);
215 // printf("Send %d Status %d\n",cobID,Status);
216  if (Status != canOK) {
217  if (Status == canERR_TXBUFOFL) {
218  Status = canWriteSync(canObjHandler,Timeout);
219  if (Status == canOK) {
220  Status = canWrite(canObjHandler,cobID,message,len,0);
221  }
222  else {
223  Status = canFlushTransmitQueue(canObjHandler);
224  }
225  }
226  }
227 
228  return sendErrorCode(Status);
229 }
230 
232 {
233  canStatus Status;
234  char msg[8];
235 
236  Status = canWrite(canObjHandler,cobID,msg,0,canMSG_RTR );
237  if (Status != canOK) {
238  if (Status == canERR_TXBUFOFL) {
239  Status = canWriteSync(canObjHandler,Timeout);
240  if (Status == canOK) {
241  Status = canWrite(canObjHandler,cobID,msg,0,canMSG_RTR);
242  }
243  }
244  }
245  return sendErrorCode(Status);
246 }
247 
248 bool KVCanScan::createBUS(const char *name ,const char *parameters )
249 {
250  if (!configureCanboard(name,parameters))
251  return false;
252  // Initialization for Scan
253  return true;
254 }
255 
256 bool KVCanScan::getErrorMessage(long error, char **message)
257 {
258  char tmp[300];
259 
260  canGetErrorText((canStatus)error, tmp, sizeof(tmp));
261  *message = new char[strlen(tmp)+1];
262  strcpy(*message,tmp);
263  return true;
264 }