Есть проблема при приеме на стороне компа. Прибор шлет к компу допустим 7 байт. Иногда и редко функция приема возвращает эти несчастные 7 байт, но часто возвращает только 2 байта. А я знаю, что прибор точно шлет 7 байт. Функция приема реализована в драйвере. Может какие-то значения таймаутов или еще что-то нужно настроить...
Внизу cImitator - это объект класса FTDI.
Код
private FTDI cImitator;
Код такой. Сначала шлем пакет от компа к плате используя эту функцию:
Код
private eWakeTransportError ewtSendData(byte[] bTxData, uint uiTxDataLength)
{
if(!cImitator.IsOpen)
{
return eWakeTransportError.ERR_PORT_NOT_OPENED;
}
// Сбросим входные и выходные буфера.
eStatus = cImitator.Purge(FTDI.FT_PURGE.FT_PURGE_TX);
if (eStatus != FTDI.FT_STATUS.FT_OK)
{
return eWakeTransportError.ERR_PURGE_TX;
}
eStatus = cImitator.Purge(FTDI.FT_PURGE.FT_PURGE_RX);
if (eStatus != FTDI.FT_STATUS.FT_OK)
{
return eWakeTransportError.ERR_PURGE_RX;
}
// Пишем на выход.
uint uiNumBytesWriten = 0;
eStatus = cImitator.Write(bTxData, (int)uiTxDataLength, ref uiNumBytesWriten);
if (eStatus != FTDI.FT_STATUS.FT_OK)
{
return eWakeTransportError.ERR_WRITE_ERROR;
}
return eWakeTransportError.ERR_NO;
}
{
if(!cImitator.IsOpen)
{
return eWakeTransportError.ERR_PORT_NOT_OPENED;
}
// Сбросим входные и выходные буфера.
eStatus = cImitator.Purge(FTDI.FT_PURGE.FT_PURGE_TX);
if (eStatus != FTDI.FT_STATUS.FT_OK)
{
return eWakeTransportError.ERR_PURGE_TX;
}
eStatus = cImitator.Purge(FTDI.FT_PURGE.FT_PURGE_RX);
if (eStatus != FTDI.FT_STATUS.FT_OK)
{
return eWakeTransportError.ERR_PURGE_RX;
}
// Пишем на выход.
uint uiNumBytesWriten = 0;
eStatus = cImitator.Write(bTxData, (int)uiTxDataLength, ref uiNumBytesWriten);
if (eStatus != FTDI.FT_STATUS.FT_OK)
{
return eWakeTransportError.ERR_WRITE_ERROR;
}
return eWakeTransportError.ERR_NO;
}
Потом принимаем ответный пакет от платы:
Код
private eWakeTransportError ewtRecvData(ref byte[] bRxData, ref uint uiRxDataLength)
{
// Ждем события FT_EVENT_RXCHAR в истечении времени iRxTimeout.
if (DataReceived.WaitOne(iRxTimeout, true)) // iRxTimeout = 5000 мс
{ // Определяем какое количество байт данных мы приняли.
if ((eStatus = cImitator.GetRxBytesAvailable(ref uiRxDataLength)) != FTDI.FT_STATUS.FT_OK)
{
uiRxDataLength = 0;
return eWakeTransportError.ERR_GET_BYTES_AVAILABLE;
}
bRxData = new byte[uiRxDataLength];
uint readData = 0;
// Считываем даные в приемный буфер.
if ((eStatus = cImitator.Read(bRxData, uiRxDataLength, ref readData)) != FTDI.FT_STATUS.FT_OK)
{
uiRxDataLength = 0;
return eWakeTransportError.ERR_READ_ERROR;
}
}
else
{
return eWakeTransportError.ERR_READ_TIMEOUT;
}
return eWakeTransportError.ERR_NO;
}
{
// Ждем события FT_EVENT_RXCHAR в истечении времени iRxTimeout.
if (DataReceived.WaitOne(iRxTimeout, true)) // iRxTimeout = 5000 мс
{ // Определяем какое количество байт данных мы приняли.
if ((eStatus = cImitator.GetRxBytesAvailable(ref uiRxDataLength)) != FTDI.FT_STATUS.FT_OK)
{
uiRxDataLength = 0;
return eWakeTransportError.ERR_GET_BYTES_AVAILABLE;
}
bRxData = new byte[uiRxDataLength];
uint readData = 0;
// Считываем даные в приемный буфер.
if ((eStatus = cImitator.Read(bRxData, uiRxDataLength, ref readData)) != FTDI.FT_STATUS.FT_OK)
{
uiRxDataLength = 0;
return eWakeTransportError.ERR_READ_ERROR;
}
}
else
{
return eWakeTransportError.ERR_READ_TIMEOUT;
}
return eWakeTransportError.ERR_NO;
}
DataReceived - это вот что:
Код
private EventWaitHandle DataReceived = new EventWaitHandle(false, EventResetMode.AutoReset);
Перед тем как слать и принимать пакеты, этот объект был привязан к событию приема данных.
Код
cImitator.SetEventNotification(FTDI.FT_EVENTS.FT_EVENT_RXCHAR, DataReceived);
Еще я задал таймауты чтения и записи так:
Код
eStatus = cImitator.SetTimeouts(5000, 0);
Весь косяк происходит в функции ewtRecvData().
Функция GetRxBytesAvailable() возвращает значение 2 байта вместо 7, соответственно Read() читает только 2 байта.
Может я неправильно пользуюсь объектом DataReceived и методом WaitOne? И поэтому чтение происходит не правильно. Кстати я плохо представляю зачем нужен второй параметр в WaitOne. Но я его устанавливал и в true и в false - не помогло.
Идею использовать DataReceived я взял отсюда <a href="http://ctieware.eng.monash.edu.au/twiki/pub/WSensornets/SecondGenerationPacketRadioModule/Window1.xaml.cs.html" target="_blank">http://ctieware.eng.monash.edu.au/twiki/pu...w1.xaml.cs.html</a>. Там правда чтение производится как бесконечная процедура в параллельно запущенном потоке. Но я решил что можно обойтись и без этого.
Вообщем подскажите кто знает что я делаю не так?
Спасибо
