#include "candemo.h"
#include "stdio.h"
unsigned int m_usedBaudRate = 0;
unsigned int m_usedId;
unsigned int m_usedFlags = 0;
unsigned int m_Verbose = 1;
driverData m_channelData;
driverData *m_DriverConfig = &m_channelData;
void help(void)
{
printf("\n********************************************\n*\n");
printf("* Keyboard commands:\n");
printf("* t Transmit a Message\n");
printf("* b Transmit a Message Burst\n");
printf("* r Select Remote Message\n");
printf("* S Request chip status\n");
printf("* s Read chip status\n");
printf("* o On/Off Bus\n");
printf("* c/C/1-9 Select Channel\n");
printf("* i/I Select Transmit Id (Up/Down)\n");
printf("* x Select Extended Id\n");
printf("* m Toggle Output Mode\n");
printf("* v Toggle Logging to Screen\n");
printf("* T Toggle transmission acknowledges for the current channel\n");
printf("* k Read the clock (call kvReadTimer)\n");
printf("* h Help\n");
printf("* d Print Driver Configuration\n");
printf("* e Clear Screen\n");
printf("* y Clear Error Status and Counters\n");
printf("* ESC Exit\n*\n*");
printf("\n********************************************\n");
}
void printDriverConfig( void )
{
unsigned int i;
printf("\nDriver Configuration:\n ChannelCount=%u\n", m_DriverConfig->channelCount);
for (i = 0; i < m_DriverConfig->channelCount; i++) {
printf(" %s : Channel %d, isOnBus=%d, Baudrate=%u",
m_DriverConfig->channel[i].name,
m_DriverConfig->channel[i].channel,
m_DriverConfig->channel[i].isOnBus,
m_usedBaudRate);
switch(m_usedBaudRate) {
printf("canBITRATE_1M");
break;
printf("canBITRATE_500K");
break;
printf("canBITRATE_250K");
break;
printf("canBITRATE_125K");
break;
printf("canBITRATE_100K");
break;
printf("canBITRATE_62K");
break;
printf("canBITRATE_50K");
break;
default:
printf("UNKNOWN");
}
printf("\n ");
printf("Drivermode=canDRIVER_NORMAL\n");
} else {
printf ("Drivermode=canDRIVER_SILENT\n");
}
}
printf("\n\n");
}
void InitDriver(void)
{
int i;
memset(m_channelData.channel, 0, sizeof(m_channelData.channel));
for (i = 0; i < MAX_CHANNELS; i++) {
m_channelData.channel[i].isOnBus = 0;
m_channelData.channel[i].channel = -1;
m_channelData.channel[i].txAck = 0;
}
m_channelData.channelCount = 0;
for (i = 0; (unsigned int)i < m_channelData.channelCount; i++) {
m_channelData.channel[i].channel = i;
m_channelData.channel[i].name,
sizeof(m_channelData.channel[i].name));
&m_channelData.channel[i].hwType,
sizeof(DWORD));
if (hnd < 0) {
PRINTF_ERR(("ERROR canOpenChannel() in initDriver() FAILED Err= %d. <line: %d>\n",
hnd, __LINE__));
}
else {
m_channelData.channel[i].hnd = hnd;
PRINTF_ERR(("ERROR canIoCtl(canIOCTL_FLUSH_TX_BUFFER) FAILED, Err= %d <line: %d>\n",
stat, __LINE__));
}
if (i == 0) {
switch(m_usedBaudRate) {
case 1000000:
break;
case 500000:
break;
case 250000:
break;
case 125000:
break;
case 100000:
break;
case 62500:
break;
case 50000:
break;
default:
printf("Baudrate set to 125 kbit/s. \n");
break;
}
}
if (stat < 0) {
PRINTF_ERR(("ERROR canSetBusParams() in InitDriver(). Err = %d <line: %d>\n",
stat, __LINE__));
}
}
printf("\n");
}
void Cleanup(void)
{
unsigned int i;
for (i = 0; i < m_channelData.channelCount; i++) {
PRINTF_ERR(("ERROR canBusOff() FAILED Err= %d. <line: %d>\n", stat, __LINE__));
PRINTF_ERR(("ERROR canClose() in Cleanup() FAILED Err= %d. <line: %d>\n",
stat, __LINE__));
}
}
}
int CheckAbort(void)
{
INPUT_RECORD ir;
unsigned long n;
GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &n);
while (n > 0) {
ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &ir, 1, &n);
if ((n == 1) && (ir.EventType == KEY_EVENT)) {
if (ir.Event.KeyEvent.bKeyDown)
return TRUE;
}
n--;
}
return FALSE;
}
{
unsigned char msg[8];
int i;
if (!m_Verbose) print = FALSE;
if (print) {
printf("Ch:%u ID:%08x DLC:%zu Flg:%02x Data:",
m_usedChannel, m_usedId, sizeof(msg), m_usedFlags);
}
for (i = 0; i < 8; i++) {
msg[i] = (unsigned char) i;
if (print) printf("%02x ", msg[i]);
}
if (print) printf("\n");
return canWrite(m_DriverConfig->channel[m_usedChannel].hnd, m_usedId,
msg, sizeof(msg), m_usedFlags);
}
int main(int argc, char **argv)
{
HANDLE th[MAX_CHANNELS + 1];
static int running = 1;
DWORD active_handle;
char c;
unsigned int i;
m_usedId = 0;
m_usedChannel = 0;
system("cls");
printf("\n\nWelcome to yet another CANLIB Test Application, compiled at " __DATE__ "\n"
"(Check out http://www.kvaser.com for more info.)\n\n"
"Usage:\n"
" CANdemo [baudrate] [identifier]\n"
"Press h for help\n\n\n -----------------------------------------------------------------\n\n");
if (argc > 1) {
m_usedBaudRate = atoi(argv[1]);
if (m_usedBaudRate) {
printf("Baudrate = %u\n\n", m_usedBaudRate);
argc--;
argv++;
}
}
if (argc > 1) {
sscanf (argv[1], "%x", &m_usedId );
if (m_usedId) {
printf("Identifier = 0x%x\n\n", m_usedId);
}
}
InitDriver();
th[0] = GetStdHandle(STD_INPUT_HANDLE);
if (th[0] == INVALID_HANDLE_VALUE)
PRINTF_ERR(("ERROR inv handle (std_input). <line: %d>\n", __LINE__));
for (i = 1; i < (m_channelData.channelCount + 1); i++) {
HANDLE tmp;
stat =
canBusOn(m_channelData.channel[i-1].hnd);
if (stat < 0) {
PRINTF_ERR(("ERROR canBusOn(). Err = %d <line: %d>\n", stat, __LINE__));
}
else {
m_DriverConfig->channel[i-1].isOnBus = 1;
}
stat =
canIoCtl(m_channelData.channel[i-1].hnd,
&tmp,
sizeof(tmp));
if (stat < 0) {
PRINTF_ERR(("canIoCtl(canIOCTL_GET_EVENTHANDLE) FAILED. Err = %d <line: %d>\n",
stat, __LINE__));
}
th[i] = tmp;
}
printDriverConfig();
printf("\n");
while (running) {
active_handle = WaitForMultipleObjects(m_channelData.channelCount + 1,
th,
FALSE ,
INFINITE);
if (((active_handle - WAIT_OBJECT_0) > 0) &&
((active_handle - WAIT_OBJECT_0) <= m_channelData.channelCount))
{
unsigned int j;
long id;
unsigned char data[8];
unsigned int dlc;
unsigned int flags;
DWORD time;
int moreDataExist;
do {
moreDataExist = 0;
for (i = 0; i < m_channelData.channelCount; i++) {
stat =
canRead(m_channelData.channel[i].hnd, &
id, &data[0], &dlc, &flags, &time);
switch (stat) {
if (m_Verbose) {
printf("RxMsg: Ch:%d ID:%08lx DLC:%u Flg:%02x T:%08lx Data:",
m_channelData.channel[i].channel, id, dlc, flags, time);
for (j = 0; j < dlc; j++) {
printf("%02x ", data[j]);
}
}
printf("\n");
}
moreDataExist = 1;
break;
break;
default:
PRINTF_ERR(("ERROR canRead() FAILED, Err= %d <line: %d>\n", stat, __LINE__));
break;
}
}
} while (moreDataExist);
}
else if (active_handle == WAIT_OBJECT_0)
{
unsigned long n;
INPUT_RECORD ir;
ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &ir, 1, &n);
if ((n == 1) && (ir.EventType == KEY_EVENT)) {
if (ir.Event.KeyEvent.bKeyDown) {
switch ((c = ir.Event.KeyEvent.uChar.AsciiChar)) {
case 'V':
case 'v':
m_Verbose = !m_Verbose;
if (m_Verbose) printf("Logging to screen ON. \n");
else printf("Logging to screen OFF. \n");
break;
case 't':
{
if (m_Verbose) {
printf("TxMsg: ");
}
if (m_DriverConfig->channel[m_usedChannel].isOnBus == 0) {
printf("Cannot transmit message. \n");
printf("Channel %d is OFF bus. \n", m_usedChannel);
break;
}
stat = TransmitMessage(TRUE);
if (stat < 0) {
PRINTF_ERR(("ERROR TransmitMessage() FAILED Err= %d <line: %d>\n",
stat, __LINE__));
}
}
break;
case 'T':
{
int tmp;
if (m_Verbose) {
printf("Toggling TxAcks on channel %d", m_usedChannel);
}
tmp = m_DriverConfig->channel[m_usedChannel].txAck? 0 : 1;
stat =
canIoCtl(m_DriverConfig->channel[m_usedChannel].hnd,
&tmp,
sizeof(tmp));
m_DriverConfig->channel[m_usedChannel].txAck = tmp;
printf(" - now %s\n", tmp? "on" : "off");
} else {
printf(" failed with error %d on line %d\n", stat, __LINE__);
}
}
break;
case 'k':
{
unsigned int can_time;
stat =
kvReadTimer(m_DriverConfig->channel[m_usedChannel].hnd, &can_time);
printf("Time on channel %d: 0x%08x\n", m_usedChannel, can_time);
} else {
printf("kvReadTimer() failed with error %d on line %d\n", stat, __LINE__);
}
}
break;
case 'B':
case 'b':
{
if (m_Verbose) printf("Transmit message BURST. \n");
unsigned char msg[8];
int i;
if (m_DriverConfig->channel[m_usedChannel].isOnBus == 0) {
printf("Cannot transmit burst. \n");
printf("Channel %d is OFF bus. \n", m_usedChannel);
break;
}
for (i = 0; i < 8; i++) {
msg[i] = (unsigned char) i;
}
printf("Press any key to stop.\n");
for (i = 0; ; i++) {
for (int j = 0; j < 250; j++) {
stat = TransmitMessage(FALSE);
char err[100];
printf("ERROR: %s\n", err);
break;
}
}
break;
stat =
canWriteSync(m_DriverConfig->channel[m_usedChannel].hnd, 2000);
char err[100];
printf("ERROR: %s\n", err);
break;
}
if ((i % 20) == 0) {
printf("*");
if (CheckAbort()) {
printf("\nTransmission finished\n");
break;
}
}
}
stat =
canIoCtl(m_DriverConfig->channel[m_usedChannel].hnd,
NULL,
NULL);
PRINTF_ERR(("ERROR canIoCtl() in 'b' FAILED. Err = %d <line: %d>\n", stat, __LINE__));
}
break;
}
case 'R':
case 'r':
if (m_Verbose) {
printf(
"Now sending %s frames.\n", (m_usedFlags &
canMSG_RTR) ?
"remote" :
"data");
}
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
m_usedChannel = c - '1';
goto select;
case 'C':
m_usedChannel--;
if (m_usedChannel < 0)
m_usedChannel = m_channelData.channelCount - 1;
if (m_Verbose)
printf("Current channel = %d \n", m_usedChannel);
break;
case 'c':
m_usedChannel++;
select:
if (m_usedChannel >= (int)m_channelData.channelCount)
m_usedChannel = 0;
if (m_Verbose)
printf("Current channel = %d \n", m_usedChannel);
break;
case 'X':
case 'x':
if (m_Verbose) {
printf("Now sending %s frames.\n",
(m_usedFlags &
canMSG_EXT) ?
"extended" :
"standard");
}
break;
case 'i':
m_usedId++;
if (m_Verbose)
printf("Id set to 0x%08x\n", m_usedId);
break;
case 'I':
if (m_usedId > 0) m_usedId--;
if (m_Verbose)
printf("Id set to 0x%08x\n", m_usedId);
break;
case 'S':
PRINTF_ERR(("ERROR canRequestChipStatus() FAILED. Err= %d <line: %d>\n", stat, __LINE__));
}
break;
case 's':
if (m_Verbose) {
printf("Channel %d is ", m_usedChannel);
if (m_DriverConfig->channel[m_usedChannel].isOnBus)
printf("ON bus. \n");
else printf("OFF bus. \n");
}
if (m_Verbose) {
DWORD flags;
if ((stat =
canReadStatus(m_DriverConfig->channel[m_usedChannel].hnd, &flags)) !=
canOK) {
PRINTF_ERR(("ERROR canReadStatus() FAILED. Err= %d <line: %d>\n", stat, __LINE__));
}
else {
printf("Bus status : ");
printf("canSTAT_ERROR_PASSIVE ");
printf("canSTAT_BUS_OFF ");
printf("canSTAT_ERROR_WARNING ");
printf("canSTAT_ERROR_ACTIVE ");
printf("canSTAT_TX_PENDING ");
printf("canSTAT_RX_PENDING ");
printf("canSTAT_TXERR ");
printf("canSTAT_RXERR ");
printf("canSTAT_HW_OVERRUN ");
printf("canSTAT_SW_OVERRUN ");
printf("\n");
}
}
break;
case 'M':
case 'm':
{
if (stat < 0) {
PRINTF_ERR(("ERROR canSetBusOutputControl(). Err = %d <line: %d>\n", stat, __LINE__));
}
else {
if (m_Verbose) printf("Channel %d Drivermode set to canDRIVER_SILENT. \n", m_usedChannel);
}
}
else {
if (stat < 0) {
PRINTF_ERR(("ERROR canBusOn(). Err = %d <line: %d>\n", stat, __LINE__));
}
else {
if (m_Verbose) printf("Channel %d Drivermode set to canDRIVER_NORMAL. \n", m_usedChannel);
}
}
}
break;
case 'O':
case 'o':
{
if (m_DriverConfig->channel[m_usedChannel].isOnBus) {
stat =
canBusOff(m_DriverConfig->channel[m_usedChannel].hnd);
if (stat < 0) {
PRINTF_ERR(("ERROR canBusOff(). Err = %d <line: %d>\n", stat, __LINE__));
}
else {
if (m_Verbose) printf("Channel %d Off bus. \n", m_usedChannel);
m_DriverConfig->channel[m_usedChannel].isOnBus = 0;
}
}
else {
stat =
canBusOn(m_DriverConfig->channel[m_usedChannel].hnd);
if (stat < 0) {
PRINTF_ERR(("ERROR canBusOn(). Err = %d <line: %d>\n", stat, __LINE__));
}
else {
if (m_Verbose) printf("Channel %d On bus. \n", m_usedChannel);
m_DriverConfig->channel[m_usedChannel].isOnBus = 1;
}
}
}
break;
case 27:
case 'q':
case 'Q':
running = FALSE;
break;
case 'H':
case 'h':
help();
break;
case 'E':
case 'e':
system("cls");
break;
case 'D':
case 'd':
printDriverConfig();
break;
case 'y':
case 'Y':
{
stat =
canIoCtl(m_DriverConfig->channel[m_usedChannel].hnd,
NULL,
NULL);
if (stat < 0) {
PRINTF_ERR(("ERROR canIoCtl(). Err = %d <line: %d>\n", stat, __LINE__));
}
else {
printf("Error counters cleared successfully.\n");
}
}
break;
default:
break;
}
}
}
}
}
Cleanup();
return NULL;
}