Kvaser CANLIB: Welcome to Kvaser CANLIB!
swc.c
/*
** Copyright 2000 by KVASER AB
** P.O Box 4076 SE-51104 KINNAHULT, SWEDEN
** E-mail: staff@kvaser.se WWW: http://www.kvaser.se
**
** This software is furnished under a license and may be used and copied
** only in accordance with the terms of such license.
**
**
** Description:
**
**
*/
/*
** Test program for SWC piggybacks on PCIcan.
** Not yet tested with LAPcan + DRVcan S
**
*/
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <windows.h>
#include <canlib.h>
#ifdef __BORLANDC__
#pragma argsused
#endif
void Usage(int argc, char* argv[])
{
printf("\nSWC Test Program\n");
printf("\n");
printf("\nUsage: swc [flags]\n");
printf(" -aX Use channel number X as source\n");
printf(" -bY Use channel number Y as destination\n");
printf(" (note: X must be different from Y. Default X=0, Y=1)\n");
exit(1);
}
int doWakeup;
int first, second;
void Check(char* id, canStatus stat)
{
char buf[50];
if (stat != canOK) {
buf[0] = '\0';
canGetErrorText(stat, buf, sizeof(buf));
printf("%s: failed, stat=%d (%s)\n", id, (int)stat, buf);
}
}
//
// Setup a CAN controller.
//
int InitCtrl(int ctrl, BYTE btr0, BYTE btr1, int mode)
{
int stat;
int hnd;
if (hnd < 0) {
Check("canOpenChannel", (canStatus)hnd);
exit(1);
}
stat = canSetBusParamsC200(hnd, btr0, btr1);
if (stat < 0) {
printf("canSetBusParamsC200 failed, stat=%d\n", stat);
}
stat = canBusOn(hnd);
if (stat < 0) {
printf("canBusOn failed, stat=%d\n", stat);
}
stat = canSetDriverMode(hnd, mode, 0);
if (stat < 0) {
printf("canSetDriverMode failed, stat=%d\n", stat);
}
return hnd;
}
//
// PumpMessages is a routine that sends a number of messages
// from one handle to another.
//
void PumpMessages(int srcHandle, int dstHandle, int nrMsgs)
{
int i, j, k, m;
canStatus stat;
long id;
BYTE msg[8];
const long srcID = 300L;
// First, queue nrMsgs messages to the first handle.
for (i=0; i<nrMsgs; i++) {
stat = canWrite(srcHandle, srcID, &i, 8, doWakeup?canMSG_WAKEUP:0);
Check("canWrite", stat);
}
// Then, wait for the transmission to complete.
// An error here usually means we are alone on the bus,
// or that the bus is not terminated properly.
stat = canWriteSync(srcHandle, 5000);
Check("canWriteSync", stat);
// Now, let's verify ge got them all.
i=j=k=m=0;
while (canRead(dstHandle, &id, msg, NULL, NULL, NULL) == canOK) {
if (msg[0] != i) j++;
if (msg[0] == i-1) k++;
if (id != srcID) m++;
i++;
}
// The status code will be canERR_NOMSG (-2) (and the loop will
// terminate) when there are no more messages to read.
// Issue an error message if it's necessary. Let's hope not.
if ((i != nrMsgs) || j || k || m) {
printf("Read %d messages, expected %d; %d corrupt, %d dropped, %d unexpected id.\n",
i, nrMsgs, j, k, m);
}
}
//
// FillCircuit queues nrMsgs messages to a handle, but
// increases the identifier by one for each message.
//
// The contents of each message will 0..nrMsgs-1 in the
// two (four for Win32) first bytes.
//
void FillCircuit(int srcHandle, int nrMsgs, int startId)
{
int i;
canStatus stat;
long srcID = startId;
for (i=0; i<nrMsgs; i++) {
stat = canWrite(srcHandle, srcID++, &i, sizeof(int), doWakeup?canMSG_WAKEUP:0);
Check("canWrite", stat);
}
}
//
// Setup two handles and send several messages back and forth.
//
void PerformTest(BYTE btr0, BYTE btr1, int mode)
{
int handle1;
int handle2;
handle1 = InitCtrl(first, btr0, btr1, mode);
handle2 = InitCtrl(second, btr0, btr1, mode);
//
// First, send a couple of messages from one controller to another.
//
printf("Sending 100 messages from A to B.\n");
PumpMessages(handle1, handle2, 100);
printf("Sending 100 messages in the opposite direction.\n");
PumpMessages(handle2, handle1, 100);
printf("Sending 150 messages from A to B.\n");
PumpMessages(handle1, handle2, 150);
printf("Sending 150 messages in the opposite direction.\n");
PumpMessages(handle2, handle1, 150);
canClose(handle1);
canClose(handle2);
}
//
//
void main(int argc, char* argv[])
{
int i;
printf("\nWelcome to the SWC Piggyback Test!\n");
//
// First, parse the command-line arguments.
//
first = 0;
second = 1;
for (i=1; i<argc; i++) {
int tmp, c;
if (sscanf(argv[i], "-a%d%c", &tmp, &c) == 1) {
first = tmp;
} else if (sscanf(argv[i], "-b%d%c", &tmp, &c) == 1) {
second = tmp;
} else {
Usage(argc, argv);
}
}
doWakeup = 0;
printf("15.686 kbps...\n");
PerformTest(0x5D, 0x4a, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
printf("20 kbps...\n");
PerformTest(0x58, 0x3a, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
printf("33.333 kbps...\n");
PerformTest(0x53, 0x36, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
printf("50 kbps...\n");
PerformTest(0x4f, 0x16, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
printf("Going to fast mode. Insert load resistor (180 Ohm CAN_H to GND):");
(void)getchar();
printf("15.686 kbps...\n");
PerformTest(0x5D, 0x4a, canTRANSCEIVER_LINEMODE_SWC_FAST);
printf("20 kbps...\n");
PerformTest(0x58, 0x3a, canTRANSCEIVER_LINEMODE_SWC_FAST);
printf("33.333 kbps...\n");
PerformTest(0x53, 0x36, canTRANSCEIVER_LINEMODE_SWC_FAST);
printf("50 kbps...\n");
PerformTest(0x4f, 0x16, canTRANSCEIVER_LINEMODE_SWC_FAST);
printf("80 kbps...\n");
PerformTest(0x49, 0x16, canTRANSCEIVER_LINEMODE_SWC_FAST);
printf("100 kbps...\n");
PerformTest(0x47, 0x16, canTRANSCEIVER_LINEMODE_SWC_FAST);
printf("And now a couple of WAKEUPs:");
(void)getchar();
doWakeup = 1;
printf("15.686 kbps...\n");
PerformTest(0x5D, 0x4a, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
printf("20 kbps...\n");
PerformTest(0x58, 0x3a, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
printf("33.333 kbps...\n");
PerformTest(0x53, 0x36, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
printf("50 kbps...\n");
PerformTest(0x4f, 0x16, canTRANSCEIVER_LINEMODE_SWC_NORMAL);
}