Начал работать с платой сопряжения по мультиплексному каналу TE1-PCI от фирмы Элкус.
У меня две платы вставлены в PCI слоты одного компьютера.
Используется 32-битная ОС Windows 7.
Собирается исполняемый файл в Borland Develper Studio 2006 - Borland® C++Builder® Preview for Microsoft® Windows™ Version 10.0.2151.25345.
Драйвер ELCUS ELECTRONIC CO (дата разработки 10.02.2006).
У меня проблема с обменом сообщений между двумя платами,
одна из которых контроллер канала=КК, а другая - оконечное устройство=ОУ.
В функции main приводится код, который я использую.
Размерность передаваемых массивов выбирается как SZ=32.
Во первых, функции bcputblk, bcgetblk отрабатывают таким образом,
что массивы записываются не совсем правильно.
А именно (я попутно смотрю базу с помощью tmk.exe -- тестовой программе для просмотра отдельных слов сообщения и другой детальной информации; устройство может работать в ней и как КК и ОУ).
Во-первых,
при обределении USE_BLK=NO , USE_BCSTARTX=NO , USE_MODE=NO
в этом случае всякий массив (произвольной длины от 1..32 слов) прекрасно передается в обоих направлениях, все работает прекрасно. Но тот же самый эффект должен достигаться и при использовании функций из семейства bcputblk\\bcgetblk (об этом далее). Эти конструкции описаны в примерах. Но в примерах кода слишкоом много кода, который на данном этапе мне не нужен (там производится обработка прерываний, ожиданий и обработка ситуации "обонент занят").
Во-вторых,
при обределении USE_BLK=YES , USE_BCSTARTX=NO , USE_MODE=NO
передается в обоих направлениях (связка КК-ОУ и обратно ОУ-КК) только первая половина массива. Остальная часть (ту которую вернули Оу-КК) заполнена нулями.
В-третьих,
при обределении USE_BLK=YES , USE_BCSTARTX=NO , USE_MODE=YES
возможно, (для п.2) причина неправильного "поведения" в режиме работы ОУ... Попробовал установить//поменять режим rtdefmode - включил флаговый режим и работу с аппаратным битом. В результате получил мусор... Первая половина возвращенного массива сдвинута <<4 и смещена на 1 адрес//элемент.
В-четвертых,
при обределении USE_BLK=NO , USE_BCSTARTX=NO , USE_MODE=YES
в этом случае передается почти правильно, но элементы сдвинуты на 1. Из-за этого сравнение не проходит.
Если кто-то работал с этими платами или знает в чем я ошибаюсь -
буду признателен.
С уважением, Олег Л.
Код: Выделить всё
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "wdmtmkv2.cpp"
//=======================================================
void lastOne()
{
const short SZ = 32,
Base = 1,
rtAddr = 0x1B, /*27*/
rtSubAddr = 0x1E; /*30*/
int awBuf[SZ], back[SZ], bcBack[SZ], foo[SZ];
int KS, OS, size, i;
TTmkEventData tmkEvD;
#define YES 1
#define NO 0
#define USE_BLK YES // первый в сигнатуре.
#define USE_BCSTARTX NO // 2-й в сигнатуре.
#define USE_MODE YES // 3-й в сигнатуре.
#define FLAG_MODE NO
#define RESIZE_SZ NO
#if RESIZE_SZ==YES
size = 2 * SZ;
#else
size = 1 * SZ;
#endif
for (register int i=0; i<size; i++)
{
awBuf[i] = (rtSubAddr<<2) | i & 0x1F ;
back[i] = bcBack[i] = 0;
}
TmkOpen();
// Подготовить 0-плату в режиме КК.
if (tmkconfig(0))
{
printf("tmkconfig(0) error\n");
}
bcreset();
bcdefbase(Base);
// Подготовить 1-плату в режиме ОУ.
if (tmkconfig(1))
{
printf("tmkconfig(1) error\n");
}
rtreset();
rtdefaddress(rtAddr);
#if USE_MODE==YES
int rtMode = rtgetmode();
if (rtdefmode(rtMode
#if FLAG_MODE==YES
|RT_FLAG_MODE
#endif
|RT_HBIT_MODE)) std::cout << "\nThere is an error with rtdefmode.\n";
rtMode = rtgetmode();
#endif
rtdefsubaddr(RT_TRANSMIT, rtSubAddr);
rtclrflag();
rtdefsubaddr(RT_RECEIVE, rtSubAddr);
rtclrflag();
//{-> Подготовка сообщения.
tmkselect(0);
KS = CW(rtAddr, RT_RECEIVE, rtSubAddr, size);
bcputw(0, KS);
#if USE_BLK==YES
bcputblk(1, awBuf, size); Sleep(200);
#else
for (i=0; i<SZ; i++) bcputw(i+1, awBuf[i]); Sleep(200);
#endif
//<-}
//{-> Отправка через МКИО сообщения.
#if USE_BCSTARTX==YES
bcstartx(Base, DATA_BC_RT | CX_STOP | CX_BUS_A | CX_NOSIG); Sleep(200);
#else
bcstart(Base, DATA_BC_RT); Sleep(200);
#endif
tmkgetevd(&tmkEvD);
//<-}
//{-> Перезапись информационных слов из п\адреса приема
// в подадрес передачи.
tmkselect(1);
#if USE_BLK==YES
rtgetblk(0, back, size);
#else
for (i=0; i<SZ; i++) back[i]=rtgetw(i); Sleep(200);
#endif
rtdefsubaddr(RT_TRANSMIT, rtSubAddr);
#if USE_BLK==YES
rtputblk(0, back, size);
#else
for (i=0; i<SZ; i++) rtputw(i, back[i]); Sleep(200);
#endif
//<-}
//{-> Запрос подготовленного сообщения из ОУ.
tmkselect(0);
KS = CW(rtAddr, RT_TRANSMIT, rtSubAddr, size);
bcputw(0, KS); Sleep(200);
#if USE_BCSTARTX==YES
bcstartx(Base, DATA_RT_BC | CX_STOP | CX_BUS_A | CX_NOSIG); Sleep(200);
#else
bcstart(Base, DATA_RT_BC); Sleep(200);
#endif
//<-}
//{-> Подготовка полученного массива для сравнения с исходным.
#if USE_BLK==YES
bcgetblk(2, bcBack, size);
#else
for (i=0; i<SZ; i++) bcBack[i]=bcgetw(i+2); Sleep(200);
#endif
showMassiveAndCheck(SZ, awBuf, bcBack);
//<-}
#undef YES
#undef NO
#undef USE_BLK
#undef USE_BCSTARTX
#undef USE_MODE
return;
}
Код: Выделить всё
bool showMassiveAndCheck(int sz, int mas1[], int mas2[])
{
// Compare two massive. If they are same it returns true.
bool hasError;
hasError = false;
printf("\n\n\t\tPlata-0 \t Plata-1\n");
for (register int j=0; j<sz; j++)
{
if (mas1[j]!=mas2[j])
{
printf("i= %2d :\t\t0x%X \t\t 0x%X \t(bad)\n", j, mas1[j], mas2[j]);
hasError = true;
}
else
{
printf("i= %2d :\t\t0x%X \t\t 0x%X \n", j, mas1[j], mas2[j]);
}
}
if (!hasError) printf("All is good. The massives are same!!!\n\n");
return (hasError);
}