CAN-200: test-read.cpp

CAN-200 1.3.0

test-read.cpp
/******************************************************************************
*
* Пример приема кадров по шине CAN с использованием механизма прерываний
*
* Электронная компания "ЭЛКУС", Санкт-Петербург, 2013г.
*****************************************************************************/
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include "../can200-api/can200-api.h"
static void print_frame( RX_TX_Buffer *frame)
{
int i;
printf("Receive frame:\n");
if ( BasicCAN == frame-> FF)
{
printf("Standart ID: %.3Xh\n", (unsigned short)frame-> sID);
}
else
{
printf("Extended ID: %x\n", frame-> extID);
}
printf("RTR: %.1d\n", frame-> RTR);
printf("DLC: %.1d\n", frame-> DLC);
for (i = 0; i < frame->DLC && i < 8; i++)
{
printf("Databyte %d: %.2Xh\n",i,(unsigned char)frame-> DataByte[i]);
}
}
int main(int argc, char *argv[])
{
int device; /* Номер платы */
int channel; /* Номер канала */
int speed; /* Скорость */
int count; /* Количество плат в системе */
HANDLE hCan; /* Хэндл платы */
pFilter_t filter; /* Фильтр для режима PeliCAN */
HANDLE hEvent; /* Событие синхронизации */
TEventData evd; /* Данные принятые от драйвера при обработке прерывания */
TCAN_VPDData conf; /* Информация о плате */
int result; /* Статус завершения операции */
SECURITY_ATTRIBUTES sa4Event; /* Атрибуты безопасности для события синхронизации */
int num_channel;/* Ко-во каналов на плате */
if (argc < 4)
{
printf("Use receive <number_device> <channel> <speed>\n");
return -1;
}
/* Определяем кол-во плат с системе */
result = CAN200_GetNumberDevice(&count);
if ( CAN200_OK != result)
{
printf("Error CAN200_GetNumberDevice (%d, last error = %u)\n", result, GetLastError());
return -1;
}
/* Номер платы */
device = atoi(argv[1]);
if (device < 0 || device >= count)
{
printf("CAN-200PCI(e) #%d not found\n", device);
return -1;
}
/* Номер канала */
channel = atoi(argv[2]);
/* Скорость */
speed = atoi(argv[3]);
if ( CAN_SPEED_1000 != speed && CAN_SPEED_800 != speed &&
CAN_SPEED_500 != speed && CAN_SPEED_250 != speed &&
CAN_SPEED_125 != speed && CAN_SPEED_50 != speed &&
CAN_SPEED_20 != speed && CAN_SPEED_10 != speed)
{
printf("Unexpected speed #%d (expected %d or %d or %d or %d or %d or %d or %d or %d)\n", speed,
CAN_SPEED_1000, CAN_SPEED_800, CAN_SPEED_500, CAN_SPEED_250,
CAN_SPEED_125, CAN_SPEED_50, CAN_SPEED_20, CAN_SPEED_10);
return -1;
}
/* Открываем плату */
hCan = CAN200_Open(device);
if (INVALID_HANDLE_VALUE == hCan)
{
printf("Error open CAN-200 device # %d (last error = %u)\n", device, GetLastError());
exit(-1);
}
/* Читаем конфигурацию */
result = CAN200_GetConfig(hCan, &conf);
if (CAN200_OK != result)
{
printf("Error CAN200_GetConfig (%d, last error = %u)\n", result, GetLastError());
CAN200_Close(hCan);
return -1;
}
/* Кол-во каналов */
result = CAN200_GetNumChannel(hCan, &num_channel);
if (CAN200_OK != result)
{
printf("Error CAN200_GetNumChannel (%d, last error = %u)\n", result, GetLastError());
CAN200_Close(hCan);
return -1;
}
if ((channel < 1) || (channel > num_channel))
{
printf("Unexpected channel #%d (expected %d-%d)\n", channel, 1, num_channel);
CAN200_Close(hCan);
return -1;
}
printf("Board: %s\n", conf. szName);
printf("Serial num.: %s\n", conf. szSN);
printf("Channel: %Xh\n", conf. wPorts[channel - 1]);
printf("IRQ: %.2d\n\n", conf. wIRQ);
/* Режим работы канала - PeliCAN */
result = CAN200_SetWorkMode(hCan, channel, PeliCAN);
if (CAN200_OK != result)
{
printf("Error CAN200_SetWorkMode (%d, last error = %u)\n", result, GetLastError());
CAN200_Close(hCan);
return -1;
}
/* Настройка входного фильтра на прием всех кадров */
filter. Mode = 0;
filter. Filter[0] = filter.Filter[1] = filter.Filter[2] = filter.Filter[3] = 0xff;
filter. Mask[0] = filter.Mask[1] = filter.Mask[2] = filter.Mask[3] = 0xff;
result = CAN200_P_SetInputFilter(hCan, channel, &filter);
if (CAN200_OK != result)
{
printf("Error CAN200_P_SetInputFilter (%d, last error = %u)\n", result, GetLastError());
CAN200_Close(hCan);
return -1;
}
/* Настройка скорости */
result = CAN200_SetCANSpeed(hCan, channel, speed);
if (CAN200_OK != result)
{
printf("Error CAN200_SetCANSpeed (%d, last error = %u)\n", result, GetLastError());
CAN200_Close(hCan);
return -1;
}
/* Разрешаем прерывание по приему данных */
result = CAN200_SetInterruptSource(hCan, channel, 0x01);
if (CAN200_OK != result)
{
printf("Error CAN200_SetInterruptSource (%d, last error = %u)\n", result, GetLastError());
CAN200_Close(hCan);
return -1;
}
/* Создаем событие синхронизации */
sa4Event.nLength = sizeof(sa4Event);
sa4Event.lpSecurityDescriptor = NULL;
sa4Event.bInheritHandle = TRUE;
hEvent = CreateEvent(&sa4Event, TRUE, FALSE, NULL);
if (NULL == hEvent)
{
printf("CreateEvent failed (last error = %u)\n", GetLastError());
CAN200_Close(hCan);
return -1;
}
/* Передаем событие синхронизации драйверу */
result = CAN200_DefEvent(hCan, channel, hEvent);
if (CAN200_OK != result)
{
printf("Error CAN200_DefEvent (%d, last error = %u)\n", result, GetLastError());
CloseHandle(hEvent);
CAN200_Close(hCan);
return -1;
}
/* Отбрасываем ранее принятые пакеты */
do
{
result = CAN200_GetEventData(hCan, channel, &evd);
if (CAN200_OK != result)
{
printf("Error CAN200_GetEventData (%d, last error = %u)\n", result, GetLastError());
CAN200_DefEvent(hCan, channel, NULL);
CloseHandle(hEvent);
CAN200_Close(hCan);
return -1;
}
} while (0 != evd. IntrID);
/* Настройка выходного формирователя */
result = CAN200_SetDriverMode(hCan, channel, 0x1B);
if (CAN200_OK != result)
{
printf("Error CAN200_SetDriverMode (%d, last error = %u)\n", result, GetLastError());
CAN200_DefEvent(hCan, channel, NULL);
CloseHandle(hEvent);
CAN200_Close(hCan);
return -1;
}
printf("Waiting....\n");
while (!_kbhit())
{
/* Обработка принятого кадра */
switch (WaitForSingleObject(hEvent, 200))
{
case WAIT_OBJECT_0:
{
ResetEvent(hEvent);
printf("We got event\n");
do
{
result = CAN200_GetEventData(hCan, channel, &evd);
if (CAN200_OK != result)
{
printf("Error CAN200_GetEventData (%d, last error = %u)\n", result, GetLastError());
CAN200_DefEvent(hCan, channel, NULL);
CloseHandle(hEvent);
CAN200_Close(hCan);
return -1;
}
printf("IntrID = %x\n", evd.IntrID);
if (0 != evd.IntrID)
{
print_frame(&(evd. rxtxbuf));
}
} while (0 != evd.IntrID);
break;
}
case WAIT_TIMEOUT:
default:
{
continue;
}
}
}
/* Удаляем событие синхронизации драйвера */
result = CAN200_DefEvent(hCan, channel, NULL);
if (CAN200_OK != result)
{
printf("Error CAN200_DefEvent (%d, last error = %u)\n", result, GetLastError());
CAN200_DefEvent(hCan, channel, NULL);
CloseHandle(hEvent);
CAN200_Close(hCan);
return -1;
}
CloseHandle(hEvent);
CAN200_Close(hCan);
return 0;
}

CAN-200 documentation. Copyright (c) 2012 - 2017 Elcus Corporation. All rights reserved.