1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-17 02:52:12 +01:00

Now able (hopefully) to unplug USB device from PC whilst the GCS is still connected to it via USB .. in WINDOWS ONLY.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2913 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
pip 2011-02-28 00:34:31 +00:00 committed by pip
parent 011abe3117
commit a2cf1c4673
4 changed files with 195 additions and 107 deletions

View File

@ -45,6 +45,7 @@ static const int WRITE_SIZE = 64;
// *********************************************************************************
/**
* Thread to desynchronize reading from the device
@ -85,6 +86,8 @@ protected:
};
// *********************************************************************************
/**
* This class is nearly the same than RawHIDReadThread but for writing
*/
@ -126,7 +129,7 @@ protected:
bool m_running;
};
// *********************************************************************************
RawHIDReadThread::RawHIDReadThread(RawHID *hid)
: m_hid(hid),
@ -206,6 +209,8 @@ RawHIDWriteThread::RawHIDWriteThread(RawHID *hid)
{
}
// *********************************************************************************
RawHIDWriteThread::~RawHIDWriteThread()
{
m_running = false;
@ -283,20 +288,28 @@ qint64 RawHIDWriteThread::getBytesToWrite()
return m_writeBuffer.size();
}
// *********************************************************************************
RawHID::RawHID(const QString &deviceName)
:QIODevice(),
serialNumber(deviceName),
m_deviceNo(-1),
m_readThread(NULL),
m_writeThread(NULL)
m_writeThread(NULL),
m_mutex(NULL)
{
//find the device the user want to open and close the other
m_mutex = new QMutex(QMutex::Recursive);
// detect if the USB device is unplugged
QObject::connect(&dev, SIGNAL(deviceUnplugged(int)), this, SLOT(onDeviceUnplugged(int)));
//find the device the user want to open and close the other
int opened = dev.open(USB_MAX_DEVICES, USB_VID, USB_PID, USB_USAGE_PAGE, USB_USAGE);
//for each devices found, get serial number and close
for (int i=0; i<opened; i++)
for (int i = 0; i < opened; i++)
{
if(deviceName == dev.getserial(i))
if (deviceName == dev.getserial(i))
m_deviceNo = i;
else
dev.close(i);
@ -318,46 +331,72 @@ RawHID::RawHID(const QString &deviceName)
RawHID::~RawHID()
{
if(m_readThread)
dev.close(m_deviceNo);
if (m_readThread)
delete m_readThread;
if(m_writeThread)
if (m_writeThread)
delete m_writeThread;
}
void RawHID::onDeviceUnplugged(int num)
{
if (num != m_deviceNo)
return;
// the USB device has been unplugged
close();
}
bool RawHID::open(OpenMode mode)
{
if(m_deviceNo < 0)
QMutexLocker locker(m_mutex);
if (m_deviceNo < 0)
return false;
QIODevice::open(mode);
if(!m_readThread)
m_readThread = new RawHIDReadThread(this);
if (!m_readThread)
m_readThread = new RawHIDReadThread(this);
if(!m_writeThread)
m_writeThread = new RawHIDWriteThread(this);
if (!m_writeThread)
m_writeThread = new RawHIDWriteThread(this);
if (m_readThread) m_readThread->start(); // Pip
if (m_writeThread) m_writeThread->start(); // Pip
return true;
}
void RawHID::close()
{
emit aboutToClose();
if(m_readThread) {
m_readThread->terminate();
delete m_readThread; // calls wait
m_readThread = NULL;
}
emit aboutToClose();
if(m_writeThread) {
m_writeThread->terminate();
delete m_writeThread;
m_writeThread = NULL;
}
m_mutex->lock();
if (m_readThread)
{
m_readThread->terminate();
delete m_readThread; // calls wait
m_readThread = NULL;
}
if (m_writeThread)
{
m_writeThread->terminate();
delete m_writeThread;
m_writeThread = NULL;
}
dev.close(m_deviceNo);
m_mutex->unlock();
emit closed();
dev.close(m_deviceNo);
QIODevice::close();
}
@ -368,21 +407,42 @@ bool RawHID::isSequential() const
qint64 RawHID::bytesAvailable() const
{
return m_readThread->getBytesAvailable() + QIODevice::bytesAvailable();
QMutexLocker locker(m_mutex);
if (!m_readThread)
return -1;
return m_readThread->getBytesAvailable() + QIODevice::bytesAvailable();
}
qint64 RawHID::bytesToWrite() const
{
QMutexLocker locker(m_mutex);
if (!m_writeThread)
return -1;
return m_writeThread->getBytesToWrite() + QIODevice::bytesToWrite();
}
qint64 RawHID::readData(char *data, qint64 maxSize)
{
return m_readThread->getReadData(data, maxSize);
QMutexLocker locker(m_mutex);
if (!m_readThread || !data)
return -1;
return m_readThread->getReadData(data, maxSize);
}
qint64 RawHID::writeData(const char *data, qint64 maxSize)
{
return m_writeThread->pushDataToWrite(data, maxSize);
QMutexLocker locker(m_mutex);
if (!m_writeThread || !data)
return -1;
return m_writeThread->pushDataToWrite(data, maxSize);
}
// *********************************************************************************

View File

@ -1,77 +1,87 @@
/**
******************************************************************************
*
* @file rawhid.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup RawHIDPlugin Raw HID Plugin
* @{
* @brief Impliments a HID USB connection to the flight hardware as a QIODevice
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RAWHID_H
#define RAWHID_H
#include "rawhid_global.h"
#include <QThread>
#include <QIODevice>
#include <QMutex>
#include <QByteArray>
#include "pjrc_rawhid.h"
//helper classes
class RawHIDReadThread;
class RawHIDWriteThread;
/**
* The actual IO device that will be used to communicate
* with the board.
*/
class RAWHID_EXPORT RawHID : public QIODevice
{
friend class RawHIDReadThread;
friend class RawHIDWriteThread;
public:
RawHID();
RawHID(const QString &deviceName);
virtual ~RawHID();
virtual bool open(OpenMode mode);
virtual void close();
virtual bool isSequential() const;
protected:
virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize);
virtual qint64 bytesAvailable() const;
virtual qint64 bytesToWrite() const;
QString serialNumber;
int m_deviceNo;
pjrc_rawhid dev;
RawHIDReadThread *m_readThread;
RawHIDWriteThread *m_writeThread;
};
#endif // RAWHID_H
/**
******************************************************************************
*
* @file rawhid.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup RawHIDPlugin Raw HID Plugin
* @{
* @brief Impliments a HID USB connection to the flight hardware as a QIODevice
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RAWHID_H
#define RAWHID_H
#include "rawhid_global.h"
#include <QThread>
#include <QIODevice>
#include <QMutex>
#include <QByteArray>
#include "pjrc_rawhid.h"
//helper classes
class RawHIDReadThread;
class RawHIDWriteThread;
/**
* The actual IO device that will be used to communicate
* with the board.
*/
class RAWHID_EXPORT RawHID : public QIODevice
{
Q_OBJECT
friend class RawHIDReadThread;
friend class RawHIDWriteThread;
public:
RawHID();
RawHID(const QString &deviceName);
virtual ~RawHID();
virtual bool open(OpenMode mode);
virtual void close();
virtual bool isSequential() const;
signals:
void closed();
public slots:
void onDeviceUnplugged(int num);
protected:
virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize);
virtual qint64 bytesAvailable() const;
virtual qint64 bytesToWrite() const;
QString serialNumber;
int m_deviceNo;
pjrc_rawhid dev;
RawHIDReadThread *m_readThread;
RawHIDWriteThread *m_writeThread;
QMutex *m_mutex;
};
#endif // RAWHID_H

View File

@ -171,6 +171,17 @@ void RawHIDConnection::onRawHidDestroyed(QObject *obj) // Pip
RawHidHandle = NULL;
}
void RawHIDConnection::onRawHidClosed()
{
if (RawHidHandle)
{
// delete RawHidHandle;
// RawHidHandle = NULL;
emit deviceClosed(this);
}
}
QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
{
//added by andrew
@ -181,7 +192,11 @@ QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
//return new RawHID(deviceName);
RawHidHandle = new RawHID(deviceName);
connect(RawHidHandle, SLOT(destroyed(QObject *)), this, SLOT(onRawHidDestroyed(QObject *))); // Pip
if (RawHidHandle)
{
connect(RawHidHandle, SIGNAL(closed()), this, SLOT(onRawHidClosed()), Qt::QueuedConnection);
connect(RawHidHandle, SIGNAL(destroyed(QObject *)), this, SLOT(onRawHidDestroyed(QObject *)), Qt::QueuedConnection);
}
return RawHidHandle;
}
@ -197,7 +212,7 @@ void RawHIDConnection::closeDevice(const QString &deviceName)
delete RawHidHandle;
RawHidHandle = NULL;
emit deviceClosed(this); // Pip
emit deviceClosed(this);
}
//end added by andrew
}

View File

@ -94,6 +94,9 @@ public:
signals:
void deviceClosed(QObject *obj); // Pip
public slots:
void onRawHidClosed();
protected slots:
void onEnumerationChanged();