Skip to content

Commit 2c96042

Browse files
committed
Fix Ixxat driver. Fixes #3
1 parent ec7570d commit 2c96042

11 files changed

Lines changed: 88 additions & 169 deletions

src/CANvenient.c

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,14 @@ char can_error_reason[1024] = {0};
2525

2626
CANVENIENT_API int can_find_interfaces(void)
2727
{
28-
int status;
29-
30-
status = ixxat_find_interfaces();
31-
if (status < 0)
32-
{
33-
return status;
34-
}
35-
36-
status = peak_find_interfaces();
37-
if (status < 0)
38-
{
39-
return status;
40-
}
41-
42-
status = kvaser_find_interfaces();
43-
if (status < 0)
44-
{
45-
return status;
46-
}
47-
48-
status = socketcan_find_interfaces();
49-
if (status < 0)
50-
{
51-
return status;
52-
}
53-
54-
status = tinycan_find_interfaces();
55-
if (status < 0)
56-
{
57-
return status;
58-
}
59-
60-
return softing_find_interfaces();
28+
ixxat_find_interfaces();
29+
peak_find_interfaces();
30+
kvaser_find_interfaces();
31+
socketcan_find_interfaces();
32+
tinycan_find_interfaces();
33+
softing_find_interfaces();
34+
35+
return 0;
6136
}
6237

6338
CANVENIENT_API void can_release_interfaces(void)
@@ -176,7 +151,6 @@ CANVENIENT_API int can_update(int index)
176151
return peak_update(index);
177152
case CAN_VENDOR_SOCKETCAN:
178153
return socketcan_update(index);
179-
break;
180154
case CAN_VENDOR_SOFTING:
181155
return softing_update(index);
182156
case CAN_VENDOR_MHS:
@@ -279,7 +253,7 @@ CANVENIENT_API int can_set_baudrate(int index, enum can_baudrate baud)
279253
}
280254
}
281255

282-
CANVENIENT_API int can_send(int index, struct can_frame* frame)
256+
CANVENIENT_API int can_send(int index, const struct can_frame* frame)
283257
{
284258
if (index < 0 || index >= CAN_MAX_INTERFACES)
285259
{

src/drivers/CANvenient_Ixxat.c

Lines changed: 70 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ typedef struct ixxat_ctx
2424
{
2525
VCIID device_id;
2626
u32 bus_no;
27-
ICanChannel* pChannel;
27+
ICanObject* pCanObject;
2828
IFifoReader* pReader;
2929
IFifoWriter* pWriter;
3030

@@ -69,7 +69,7 @@ int ixxat_find_interfaces(void)
6969
{
7070
for (u32 bus = 0; bus < features.BusSocketCount; bus++)
7171
{
72-
if (features.BusSocketType[bus])
72+
if (VCI_BUS_TYPE(features.BusSocketType[bus]) == VCI_BUS_CAN)
7373
{
7474
ixxat_ctx_t* ctx;
7575
char socket_name[256];
@@ -95,8 +95,8 @@ int ixxat_find_interfaces(void)
9595

9696
if (0 != find_free_interface_slot(&free_index))
9797
{
98-
/* No free slot available: skip. */
99-
continue;
98+
/* No free slot available: stop. */
99+
break;
100100
}
101101

102102
name_len = strnlen(socket_name, sizeof(socket_name));
@@ -116,7 +116,7 @@ int ixxat_find_interfaces(void)
116116
}
117117
ctx->device_id = devInfo.VciObjectId;
118118
ctx->bus_no = bus;
119-
ctx->pChannel = NULL;
119+
ctx->pCanObject = NULL;
120120
ctx->pReader = NULL;
121121
ctx->pWriter = NULL;
122122

@@ -151,9 +151,7 @@ int ixxat_open(int index)
151151
IVciDeviceManager* pDevMan = NULL;
152152
IVciDevice* pDevice = NULL;
153153
IBalObject* pBal = NULL;
154-
ICanControl* pControl = NULL;
155-
ICanSocket* pSocket = NULL;
156-
ICanChannel* pChannel = NULL;
154+
ICanObject* pCanObj = NULL;
157155
CANINITLINE initLine;
158156
HRESULT hr;
159157
u8 bt0;
@@ -185,57 +183,47 @@ int ixxat_open(int index)
185183
pDevice->lpVtbl->Release(pDevice);
186184
if (FAILED(hr) || NULL == pBal)
187185
{
186+
set_error_reason("Failed to open BAL component.");
188187
return -1;
189188
}
190189

191-
hr = pBal->lpVtbl->OpenSocket(pBal, ctx->bus_no, &IID_ICanControl, (PVOID*)&pControl);
192-
if (SUCCEEDED(hr) && NULL != pControl)
193-
{
194-
ixxat_baudrate_to_btr(can_interface[index].baudrate, &bt0, &bt1);
195-
initLine.bOpMode = CAN_OPMODE_STANDARD | CAN_OPMODE_EXTENDED | CAN_OPMODE_ERRFRAME;
196-
initLine.bReserved = 0;
197-
initLine.bBtReg0 = bt0;
198-
initLine.bBtReg1 = bt1;
199-
pControl->lpVtbl->InitLine(pControl, &initLine);
200-
pControl->lpVtbl->StartLine(pControl);
201-
pControl->lpVtbl->Release(pControl);
202-
}
203-
204-
hr = pBal->lpVtbl->OpenSocket(pBal, ctx->bus_no, &IID_ICanSocket, (PVOID*)&pSocket);
190+
hr = pBal->lpVtbl->OpenSocket(pBal, ctx->bus_no, &IID_ICanObject, (PVOID*)&pCanObj);
205191
pBal->lpVtbl->Release(pBal);
206-
if (FAILED(hr) || NULL == pSocket)
192+
if (FAILED(hr) || NULL == pCanObj)
207193
{
208-
set_error_reason("Failed to open CAN socket.");
194+
set_error_reason("Failed to open CAN object.");
209195
return -1;
210196
}
211197

212-
hr = pSocket->lpVtbl->CreateChannel(pSocket, FALSE, &pChannel);
213-
pSocket->lpVtbl->Release(pSocket);
214-
if (FAILED(hr) || NULL == pChannel)
215-
{
216-
set_error_reason("Failed to create CAN channel.");
217-
return -1;
218-
}
198+
ixxat_baudrate_to_btr(can_interface[index].baudrate, &bt0, &bt1);
199+
initLine.bOpMode = CAN_OPMODE_STANDARD | CAN_OPMODE_EXTENDED | CAN_OPMODE_ERRFRAME;
200+
initLine.bReserved = 0;
201+
initLine.bBtReg0 = bt0;
202+
initLine.bBtReg1 = bt1;
219203

220-
hr = pChannel->lpVtbl->Initialize(pChannel, 1024, 128);
204+
pCanObj->lpVtbl->ResetLine(pCanObj);
205+
hr = pCanObj->lpVtbl->InitLine(pCanObj, &initLine, 1024, 128);
221206
if (FAILED(hr))
222207
{
223-
pChannel->lpVtbl->Release(pChannel);
224-
set_error_reason("Failed to initialize CAN channel.");
208+
pCanObj->lpVtbl->Release(pCanObj);
209+
set_error_reason("Failed to initialize CAN line.");
225210
return -1;
226211
}
227212

228-
hr = pChannel->lpVtbl->Activate(pChannel);
213+
pCanObj->lpVtbl->SetAccFilter(pCanObj, CAN_FILTER_STD, CAN_ACC_CODE_ALL, CAN_ACC_MASK_ALL);
214+
pCanObj->lpVtbl->SetAccFilter(pCanObj, CAN_FILTER_EXT, CAN_ACC_CODE_ALL, CAN_ACC_MASK_ALL);
215+
216+
hr = pCanObj->lpVtbl->StartLine(pCanObj);
229217
if (FAILED(hr))
230218
{
231-
pChannel->lpVtbl->Release(pChannel);
232-
set_error_reason("Failed to activate CAN channel.");
219+
pCanObj->lpVtbl->Release(pCanObj);
220+
set_error_reason("Failed to start CAN line.");
233221
return -1;
234222
}
235223

236-
pChannel->lpVtbl->GetReader(pChannel, &ctx->pReader);
237-
pChannel->lpVtbl->GetWriter(pChannel, &ctx->pWriter);
238-
ctx->pChannel = pChannel;
224+
pCanObj->lpVtbl->GetReceiveFifo(pCanObj, &ctx->pReader);
225+
pCanObj->lpVtbl->GetTransmitFifo(pCanObj, &ctx->pWriter);
226+
ctx->pCanObject = pCanObj;
239227
can_interface[index].opened = 1;
240228

241229
return 0;
@@ -264,13 +252,14 @@ void ixxat_close(int index)
264252
ctx->pReader->lpVtbl->Release(ctx->pReader);
265253
ctx->pReader = NULL;
266254
}
267-
if (ctx->pChannel)
255+
if (ctx->pCanObject)
268256
{
269-
ctx->pChannel->lpVtbl->Deactivate(ctx->pChannel);
270-
ctx->pChannel->lpVtbl->Release(ctx->pChannel);
271-
ctx->pChannel = NULL;
257+
ctx->pCanObject->lpVtbl->StopLine(ctx->pCanObject);
258+
ctx->pCanObject->lpVtbl->Release(ctx->pCanObject);
259+
ctx->pCanObject = NULL;
272260
}
273261
}
262+
can_interface[index].opened = 0;
274263

275264
#else
276265
set_error_reason("Ixxat driver is only supported on Windows.");
@@ -326,9 +315,7 @@ int ixxat_set_baudrate(int index, enum can_baudrate baud)
326315
IVciDeviceManager* pDevMan = NULL;
327316
IVciDevice* pDevice = NULL;
328317
IBalObject* pBal = NULL;
329-
ICanControl* pControl = NULL;
330-
ICanSocket* pSocket = NULL;
331-
ICanChannel* pChannel = NULL;
318+
ICanObject* pCanObj = NULL;
332319
CANINITLINE initLine;
333320
HRESULT hr;
334321
u8 bt0;
@@ -340,7 +327,7 @@ int ixxat_set_baudrate(int index, enum can_baudrate baud)
340327
return -1;
341328
}
342329

343-
/* Release existing channel resources. */
330+
/* Release existing resources. */
344331
if (ctx->pWriter)
345332
{
346333
ctx->pWriter->lpVtbl->Release(ctx->pWriter);
@@ -351,39 +338,11 @@ int ixxat_set_baudrate(int index, enum can_baudrate baud)
351338
ctx->pReader->lpVtbl->Release(ctx->pReader);
352339
ctx->pReader = NULL;
353340
}
354-
if (ctx->pChannel)
355-
{
356-
ctx->pChannel->lpVtbl->Deactivate(ctx->pChannel);
357-
ctx->pChannel->lpVtbl->Release(ctx->pChannel);
358-
ctx->pChannel = NULL;
359-
}
360-
361-
/* Stop the CAN line before changing baudrate. */
362-
hr = VciGetDeviceManager(&pDevMan);
363-
if (SUCCEEDED(hr) && NULL != pDevMan)
341+
if (ctx->pCanObject)
364342
{
365-
hr = pDevMan->lpVtbl->OpenDevice(pDevMan, &ctx->device_id, &pDevice);
366-
if (SUCCEEDED(hr) && NULL != pDevice)
367-
{
368-
hr = pDevice->lpVtbl->OpenComponent(pDevice, &CLSID_VCIBAL, &IID_IBalObject, (PVOID*)&pBal);
369-
if (SUCCEEDED(hr) && NULL != pBal)
370-
{
371-
hr = pBal->lpVtbl->OpenSocket(pBal, ctx->bus_no, &IID_ICanControl, (PVOID*)&pControl);
372-
if (SUCCEEDED(hr) && NULL != pControl)
373-
{
374-
pControl->lpVtbl->StopLine(pControl);
375-
pControl->lpVtbl->ResetLine(pControl);
376-
pControl->lpVtbl->Release(pControl);
377-
pControl = NULL;
378-
}
379-
pBal->lpVtbl->Release(pBal);
380-
pBal = NULL;
381-
}
382-
pDevice->lpVtbl->Release(pDevice);
383-
pDevice = NULL;
384-
}
385-
pDevMan->lpVtbl->Release(pDevMan);
386-
pDevMan = NULL;
343+
ctx->pCanObject->lpVtbl->StopLine(ctx->pCanObject);
344+
ctx->pCanObject->lpVtbl->Release(ctx->pCanObject);
345+
ctx->pCanObject = NULL;
387346
}
388347

389348
hr = VciGetDeviceManager(&pDevMan);
@@ -409,54 +368,43 @@ int ixxat_set_baudrate(int index, enum can_baudrate baud)
409368
return -1;
410369
}
411370

412-
hr = pBal->lpVtbl->OpenSocket(pBal, ctx->bus_no, &IID_ICanControl, (PVOID*)&pControl);
413-
if (SUCCEEDED(hr) && NULL != pControl)
414-
{
415-
ixxat_baudrate_to_btr(baud, &bt0, &bt1);
416-
initLine.bOpMode = CAN_OPMODE_STANDARD | CAN_OPMODE_EXTENDED | CAN_OPMODE_ERRFRAME;
417-
initLine.bReserved = 0;
418-
initLine.bBtReg0 = bt0;
419-
initLine.bBtReg1 = bt1;
420-
pControl->lpVtbl->InitLine(pControl, &initLine);
421-
pControl->lpVtbl->StartLine(pControl);
422-
pControl->lpVtbl->Release(pControl);
423-
}
424-
425-
hr = pBal->lpVtbl->OpenSocket(pBal, ctx->bus_no, &IID_ICanSocket, (PVOID*)&pSocket);
371+
hr = pBal->lpVtbl->OpenSocket(pBal, ctx->bus_no, &IID_ICanObject, (PVOID*)&pCanObj);
426372
pBal->lpVtbl->Release(pBal);
427-
if (FAILED(hr) || NULL == pSocket)
373+
if (FAILED(hr) || NULL == pCanObj)
428374
{
429-
set_error_reason("Failed to open CAN socket.");
375+
set_error_reason("Failed to open CAN object.");
430376
return -1;
431377
}
432378

433-
hr = pSocket->lpVtbl->CreateChannel(pSocket, FALSE, &pChannel);
434-
pSocket->lpVtbl->Release(pSocket);
435-
if (FAILED(hr) || NULL == pChannel)
436-
{
437-
set_error_reason("Failed to create CAN channel.");
438-
return -1;
439-
}
379+
ixxat_baudrate_to_btr(baud, &bt0, &bt1);
380+
initLine.bOpMode = CAN_OPMODE_STANDARD | CAN_OPMODE_EXTENDED | CAN_OPMODE_ERRFRAME;
381+
initLine.bReserved = 0;
382+
initLine.bBtReg0 = bt0;
383+
initLine.bBtReg1 = bt1;
440384

441-
hr = pChannel->lpVtbl->Initialize(pChannel, 1024, 128);
385+
pCanObj->lpVtbl->ResetLine(pCanObj);
386+
hr = pCanObj->lpVtbl->InitLine(pCanObj, &initLine, 1024, 128);
442387
if (FAILED(hr))
443388
{
444-
pChannel->lpVtbl->Release(pChannel);
445-
set_error_reason("Failed to initialize CAN channel.");
389+
pCanObj->lpVtbl->Release(pCanObj);
390+
set_error_reason("Failed to initialize CAN line.");
446391
return -1;
447392
}
448393

449-
hr = pChannel->lpVtbl->Activate(pChannel);
394+
pCanObj->lpVtbl->SetAccFilter(pCanObj, CAN_FILTER_STD, CAN_ACC_CODE_ALL, CAN_ACC_MASK_ALL);
395+
pCanObj->lpVtbl->SetAccFilter(pCanObj, CAN_FILTER_EXT, CAN_ACC_CODE_ALL, CAN_ACC_MASK_ALL);
396+
397+
hr = pCanObj->lpVtbl->StartLine(pCanObj);
450398
if (FAILED(hr))
451399
{
452-
pChannel->lpVtbl->Release(pChannel);
453-
set_error_reason("Failed to activate CAN channel.");
400+
pCanObj->lpVtbl->Release(pCanObj);
401+
set_error_reason("Failed to start CAN line.");
454402
return -1;
455403
}
456404

457-
pChannel->lpVtbl->GetReader(pChannel, &ctx->pReader);
458-
pChannel->lpVtbl->GetWriter(pChannel, &ctx->pWriter);
459-
ctx->pChannel = pChannel;
405+
pCanObj->lpVtbl->GetReceiveFifo(pCanObj, &ctx->pReader);
406+
pCanObj->lpVtbl->GetTransmitFifo(pCanObj, &ctx->pWriter);
407+
ctx->pCanObject = pCanObj;
460408
can_interface[index].baudrate = baud;
461409

462410
return 0;
@@ -469,7 +417,7 @@ int ixxat_set_baudrate(int index, enum can_baudrate baud)
469417
#endif
470418
}
471419

472-
int ixxat_send(int index, struct can_frame* frame)
420+
int ixxat_send(int index, const struct can_frame* frame)
473421
{
474422
#ifdef _WIN32
475423

@@ -486,7 +434,8 @@ int ixxat_send(int index, struct can_frame* frame)
486434

487435
msg.dwMsgId = frame->can_id;
488436
msg.uMsgInfo.Bytes.bType = CAN_MSGTYPE_DATA;
489-
msg.uMsgInfo.Bytes.bFlags = (frame->can_dlc & CAN_MSGFLAGS_DLC);
437+
msg.uMsgInfo.Bytes.bFlags = (frame->can_dlc & CAN_MSGFLAGS_DLC) |
438+
(frame->can_id > 0x7FF ? CAN_MSGFLAGS_EXT : 0);
490439

491440
for (i = 0; i < frame->can_dlc && i < 8; i += 1)
492441
{
@@ -525,18 +474,14 @@ int ixxat_recv(int index, struct can_frame* frame, u64* timestamp)
525474
return -1;
526475
}
527476

528-
hr = ctx->pReader->lpVtbl->GetDataEntry(ctx->pReader, &msg);
529-
if (S_OK != hr)
530-
{
531-
set_error_reason("No message available.");
532-
return -1;
533-
}
534-
535-
if (CAN_MSGTYPE_DATA != msg.uMsgInfo.Bytes.bType)
477+
do
536478
{
537-
set_error_reason("No message available.");
538-
return -1;
539-
}
479+
hr = ctx->pReader->lpVtbl->GetDataEntry(ctx->pReader, &msg);
480+
if (S_OK != hr)
481+
{
482+
return -1;
483+
}
484+
} while (CAN_MSGTYPE_DATA != msg.uMsgInfo.Bytes.bType);
540485

541486
frame->can_id = msg.dwMsgId;
542487
frame->can_dlc = msg.uMsgInfo.Bytes.bFlags & CAN_MSGFLAGS_DLC;

0 commit comments

Comments
 (0)