example/c/j1587/j1587example.c
/*
** Copyright 2006-2007 by KVASER AB, SWEDEN
** WWW: http://www.kvaser.com
**
** This software is furnished under a license and may be used and copied
** only in accordance with the terms of such license.
**
** Description:
** Example program for J1587 Linx.
** Use together with two J1587 linx units connected with a loopback cable
** Supply 12 VDC to pin 9. No termination, pullup etc needed.
** ---------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <memory.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include <conio.h>
#include <mmsystem.h>
#include "j1587lib.h"
#include "canlib.h"
#include "j1587example.h"
#include "util.h"
// defines
#define j1587WriteMessage(a,b,c) j1587WriteMessageWait(a,b,c,1,1000)
#define LENGTH_1_1 6
#define LENGTH_1_4 8
#define MAX_TIMER_DIFF 20
// Limit the inaccuracy of each measurement
#define MAX_MEASURE_DIFF (MAX_TIMER_DIFF/3)
#define ERR_ARGUMENTS 8001
#define ERR_BITRATE 8002
#define ERR_WRONG_ID_OR_DATA 8003
#define ERR_WRONG_ID 8004
#define ERR_WRITE_TIMEOUT 8005
#define ERR_WRITE_FAILED 8006
#define ERR_STR_MISMATCH 8007
#define ERR_WAKEUP 8008
#define ERR_NOTHING_TO_READ 8009
#define ERR_TIME_DIFF 8010
#define ERR_ILLEGAL_MSG 8011
#define ERR_LEGAL_MSG 8012
J1587Handle Master;
int Bitrate;
int LoopCount;
char ListOfTests[64];
//--------------------------------------------------------------------
void Usage (void)
{
printf("\nThis program demonstrates the Kvaser Linx J1587 APIs.\n");
printf("(The progran is a part of CANLIB SDK, see http://www.kvaser.com\n");
printf("\nUsage: program [flags]\n");
printf(" -mX Use Channel X as Normal\n");
printf(" -sY Use Channel Y as Node\n");
printf(" (note: X must be different from Y. Default X=0, Y=1)\n");
printf(" -Bnnn Set the speed to nnn bit/s [default 10 000 bit/s].\n");
printf(" -Lnnn Run nnn loops.\n");
printf(" -T=xxxx Run only tests xxxx where x is a letter a..z\n");
printf(" -NT=xxxx Don't run tests xxxx where x is a letter a..z\n");
printf(" -test=n Run only test number n.\n");
exit(ERR_ARGUMENTS);
}
//--------------------------------------------------------------------
int main (int argc, char* argv[])
{
int i;
// Default values.
Master = 0;
Slave = 1;
Bitrate = 9600;
LoopCount = 1;
strcpy(ListOfTests, "abcdefghijklmnopqrstuvwxyz");
// Parse the command line.
for (i = 1; i < argc; i++) {
int tmp;
char c;
char tmpS[1024];
if (sscanf(argv[i], "-m%d%c", &tmp, &c) == 1) Master = tmp;
else if (sscanf(argv[i], "-s%d%c", &tmp, &c) == 1) Slave = tmp;
else if (sscanf(argv[i], "-B%d%c", &tmp, &c) == 1) Bitrate = tmp;
else if (sscanf(argv[i], "-L%d%c", &tmp, &c) == 1) LoopCount = tmp;
else if (sscanf(argv[i], "-L=%d%c", &tmp, &c) == 1) LoopCount = tmp;
else if (sscanf(argv[i], "-T=%s", tmpS) == 1) {
if (strchr(tmpS, ',') != NULL) {
// Format -T=n,n,n,n
char *s;
strcpy(ListOfTests, "");
s = strtok(tmpS, ",");
while (s != NULL) {
char tmp[2];
tmp[0] = atoi(s) + 'a' - 1;
tmp[1] = 0;
strcat(ListOfTests, tmp);
s = strtok(NULL, ",");
}
}
else {
// Format -T=abcdefg
strcpy(ListOfTests, tmpS);
}
}
else if (sscanf(argv[i], "-NT=%s", tmpS) == 1) {
if (strchr(tmpS, ',') != NULL) {
// Format -NT=n,n,n,n
char *s;
s = strtok(tmpS, ",");
while (s != NULL) {
ListOfTests[atoi(s)-1] = '@';
s = strtok(NULL, ",");
}
} else {
// Format -NT=abcdefg
int i;
for (i=0; i<(int)strlen(tmpS); i++) {
char *c = strchr(ListOfTests, tmpS[i]);
if (c) *c = '@'; // This means 'no test'
}
}
}
else if (sscanf(argv[i], "-test=%d%c", &tmp, &c) == 1) {
ListOfTests[0] = 'a' + tmp - 1;
ListOfTests[1] = '\0';
}
else Usage();
}
PerformTest(argc, argv);
return 0;
}
//--------------------------------------------------------------------
void PerformTest (int argc, char **argv)
{
int masterHandle, slaveHandle;
int i;
printf("*** Begin Test ***\n");
if (Bitrate > 20000)
{
printf("Unsupported bitrate, choose max bitrate 20 000 kbits/s");
exit(ERR_BITRATE);
}
masterHandle = j1587OpenChannel(Master, J1587_NORMAL | J1587_WRITE);
CheckAndPrintError(masterHandle, "ERROR: j1587OpenChannel M failed");
slaveHandle = j1587OpenChannel(Slave, J1587_NORMAL | J1587_READ);
CheckAndPrintError(slaveHandle, "ERROR: j1587OpenChannel S failed");
stat = j1587SetBitrate(masterHandle, Bitrate);
CheckAndPrintError(stat, "ERROR: j1587SetBitrate M failed");
stat = j1587SetBitrate(slaveHandle, Bitrate);
CheckAndPrintError(stat, "ERROR: j1587SetBitrate S failed");
stat = j1587BusOn(masterHandle);
CheckAndPrintError(stat, "ERROR: j1587BusOn M failed");
stat = j1587BusOn(slaveHandle);
CheckAndPrintError(stat, "ERROR: j1587BusOn S failed");
for (i = 0; i < LoopCount; i++) {
int j;
printf("\n*** Loop %d *** (", i);
for (j = 0; j < argc; j++)
printf("%s ", argv[j]);
printf(")\n");
fflush(stdout);
for (j = 0; j < (int)strlen(ListOfTests); j++) {
int run = 1;
switch (ListOfTests[j] - 'a' + 1) {
case 0: continue;
case 1: Test1(masterHandle, slaveHandle); break;
case 2: Test2(masterHandle, slaveHandle); break;
case 3: Test3(masterHandle, slaveHandle); break;
case 4: Test4(masterHandle, slaveHandle); break;
default:
run = 0;
break;
}
if (run) {
printf("\n");
fflush(stdout);
}
}
if (_kbhit() && _getch() == 27) {
break;
}
}
stat = j1587BusOff(masterHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOff M failed");
stat = j1587BusOff(slaveHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOff S failed");
stat = j1587Close(masterHandle);
CheckAndPrintError(stat,"ERROR: j1587Close M failed");
stat = j1587Close(slaveHandle);
CheckAndPrintError(stat,"ERROR: j1587Close S failed");
printf("\n*** Test Completed Successfully (%d loops) ***\n", LoopCount);
}
//--------------------------------------------------------------------
int setup(int handle)
{
return j1587Configure(handle,
}
//--------------------------------------------------------------------
// simple test - update, request and read
void Test1(int mHandle, int sHandle)
{
int i;
int curId = 0;
int rec, sent;
int loop = 0;
int stat;
char buffer[256];
unsigned char msg[256];
unsigned int len;
DWORD dt, t0;
stat = j1587BusOff(mHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOff M failed");
stat = j1587BusOff(sHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOff S failed");
stat = j1587BusOn(mHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOn M failed");
stat = j1587BusOn(sHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOn S failed");
stat = setup(mHandle);
CheckAndPrintError(stat, "ERROR: j1587SetupJ1587 M failed");
stat = setup(sHandle);
CheckAndPrintError(stat, "ERROR: j1587SetupJ1587 S failed");
// Send a number of messages from master
// Read all messages from slave and make sure all messages arrived
printf("1.1 ");
rec = 0;
sent = 25;
for (i = 0; i < sent; i++)
{
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "KV %d", curId + i);
stat = j1587WriteMessage(mHandle, buffer, LENGTH_1_1);
CheckAndPrintError(stat, "ERROR: j1587WriteMessage failed");
}
stat = j1587WriteSync(mHandle, &msgInfo, 1000);
CheckAndPrintError(stat, "ERROR: j1587WriteSync failed");
t0 = timeGetTime();
while(rec < sent)
{
if (j1587ReadMessageWait(sHandle, msg, &len, &msgInfo, 10) == j1587OK) {
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "KV %d", rec);
if ((len != LENGTH_1_1) || memcmp(msg, buffer, len)) {
printf("Bad data returned for message %d (%d/%d)\n",
rec, len, LENGTH_1_1);
for (i = 0; i < (int)len; i++) {
printf("%02x/%02x ", msg[i], buffer[i]);
}
printf("\n");
}
rec++;
}
if (timeGetTime() - t0 > (unsigned int)(sent * 20))
break;
}
if (rec != sent)
{
printf("ERROR: Sent %d, got %d\n", sent, rec);
}
// Tests writeSync
printf("1.2 ");
t0 = timeGetTime();
stat = j1587WriteSync(mHandle, &msgInfo, 100);
dt = timeGetTime() - t0;
CheckAndPrintError(stat,"ERROR: j1587WriteSync failed");
if (dt > 30) {
printf("ERROR: j1587WriteSync took %d ms\n", dt);
exit(ERR_WRITE_TIMEOUT);
}
// Take master offbuss and try to send a message
// Go on bus again and try to send and receive
printf("1.3 ");
stat = j1587BusOff(mHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOff failed");
stat = j1587WriteMessage(mHandle, buffer, 8);
if (stat != j1587ERR_NOTRUNNING)
{
printf("ERROR: j1587WriteMessage failed %d\n", stat);
exit(ERR_WRITE_FAILED);
}
stat = j1587BusOn(mHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOn failed");
stat = j1587WriteMessage(mHandle, buffer, 8);
CheckAndPrintError(stat,"ERROR: j1587WriteMessage failed");
stat = j1587WriteSync(mHandle, &msgInfo, 1000);
CheckAndPrintError(stat,"ERROR: j1587WriteSync failed");
j1587ReadMessageWait(sHandle, msg, &len, &msgInfo, 1000);
CheckAndPrintError(stat,"ERROR: j1587ReadMessageWait failed");
stat = setup(mHandle);
CheckAndPrintError(stat, "ERROR: j1587SetupJ1587 M failed");
stat = setup(sHandle);
CheckAndPrintError(stat, "ERROR: j1587SetupJ1587 S failed");
// Send a number of messages from normal
// Read all messages from node and make sure all messages arrived
printf("1.4 ");
{
rec = 0;
sent = 25;
for (i = 0; i < sent; i++) {
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "KV %d", curId + i);
stat = j1587WriteMessage(mHandle, buffer, LENGTH_1_4);
CheckAndPrintError(stat,"ERROR: j1587WriteMessage failed");
}
stat = j1587WriteSync(mHandle, &msgInfo, 3000);
CheckAndPrintError(stat,"ERROR: j1587WriteSync failed");
t0 = timeGetTime();
while (rec < sent) {
if (j1587ReadMessageWait(sHandle, msg, &len, &msgInfo, 10) == j1587OK) {
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "KV %d", rec);
if ((len != LENGTH_1_4) || memcmp(msg, buffer, len)) {
printf("Bad data returned for message %d (%d/%d)\n",
rec, len, LENGTH_1_4);
for(i = 0; i < (int)len; i++) {
printf("%02x/%02x ", msg[i], buffer[i]);
}
printf("\n");
}
rec++;
}
if (timeGetTime() - t0 > (unsigned int)(sent * 20))
break;
}
if (rec != sent) {
printf("ERROR: Sent %d, got %d\n", sent, rec);
}
}
}
//--------------------------------------------------------------------
// Get info
void Test2(int mHandle, int sHandle)
{
unsigned char bootVerMajor[256];
unsigned char bootVerMinor[256];
unsigned char bootVerBuild[256];
unsigned char appVerMajor[256];
unsigned char appVerMinor[256];
unsigned char appVerBuild[256];
int stat;
printf("2.1 ");
stat = j1587GetFirmwareVersion(mHandle, bootVerMajor, bootVerMinor, bootVerBuild,
appVerMajor, appVerMinor, appVerBuild);
CheckAndPrintError(stat,"ERROR: j1587GetFirmwareVersion failed");
//printf("\nBoot ver %d.%d.%d\n", bootVerMajor, bootVerMinor, bootVerBuild);
//printf("App ver %d.%d.%d\n", appVerMajor, appVerMinor, appVerBuild);
}
// Same as canlib\src\test\Test7\test8.c
// Tests j1587ReadTimer
//--------------------------------------------------------------------
void Test3(int mHandle, int sHandle)
{
int i;
DWORD t0, dt, t1, t2, delta;
printf("3.1 ");
do {
t2 = timeGetTime();
t0 = j1587ReadTimer(mHandle);
t1 = timeGetTime();
} while (abs(t2 - t1) > MAX_MEASURE_DIFF);
dt = t1 - t0;
for (i = 0; i < 100; i++) {
do {
t2 = timeGetTime();
t0 = j1587ReadTimer(mHandle);
t1 = timeGetTime();
} while (abs(t2 - t1) > MAX_MEASURE_DIFF);
delta = t1 - t0;
if ((abs(delta - dt)) > MAX_TIMER_DIFF) {
// The resolution of timeGetTime() is set as low as possible
// by testur.c. (hardware dependent, but most likely 1 ms)
printf("3.1 Delta T=%d (ms), loops=%d", abs(delta - dt), i);
exit(ERR_TIME_DIFF);
}
}
printf("3.2 ");
do {
t2 = timeGetTime();
t0 = j1587ReadTimer(mHandle);
t1 = timeGetTime();
} while (abs(t2 - t1) > MAX_MEASURE_DIFF);
dt = t1 - t0;
for (i = 0; i < 50; i++) {
do {
t2 = timeGetTime();
t0 = j1587ReadTimer(mHandle);
t1 = timeGetTime();
} while (abs(t2 - t1) > MAX_MEASURE_DIFF);
delta = t1 - t0;
if ((abs(delta - dt)) > MAX_TIMER_DIFF) {
// The resolution of timeGetTime() is set as low as possible
// (hardware dependent, but most likely 1 ms)
printf("3.2 Delta T=%d (ms), loops=%d", abs(delta - dt), i);
exit(ERR_TIME_DIFF);
}
Sleep(10);
}
}
//--------------------------------------------------------------------
// test j1587SetupIllegalMessage and j1587SetupLIN
void Test4(int mHandle, int sHandle)
{
char buffer[8];
int stat;
unsigned char msg[8];
unsigned int len;
stat = j1587BusOff(mHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOff M failed");
stat = j1587BusOff(sHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOff S failed");
stat = j1587BusOn(mHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOn M failed");
stat = j1587BusOn(sHandle);
CheckAndPrintError(stat,"ERROR: j1587BusOn S failed");
Sleep(125);
sprintf(buffer, "Legal");
printf("4.1 ");
stat = j1587WriteMessage(mHandle, buffer, sizeof(buffer));
CheckAndPrintError(stat,"ERROR: j1587WriteMessage failed");
Sleep(125);
stat = j1587ReadMessageWait(sHandle, msg, &len, &msgInfo, 1000);
CheckAndPrintError(stat,"ERROR: j1587ReadMessageWait failed");
}