mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
GCS OSX: More refinements to the USB code to make it more robust and work for reset/halt.
This commit is contained in:
parent
e027c25071
commit
59dcbf5cb6
@ -125,6 +125,7 @@ private:
|
||||
IOHIDManagerRef hid_manager;
|
||||
IOHIDDeviceRef dev;
|
||||
CFRunLoopRef the_correct_runloop;
|
||||
CFRunLoopRef received_runloop;
|
||||
|
||||
static const int BUFFER_SIZE = 64;
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
|
@ -92,6 +92,8 @@ int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
|
||||
Q_ASSERT(hid_manager == NULL);
|
||||
Q_ASSERT(device_open == false);
|
||||
|
||||
attach_count = 0;
|
||||
|
||||
// Start the HID Manager
|
||||
hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) {
|
||||
@ -163,12 +165,11 @@ int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
|
||||
*/
|
||||
int pjrc_rawhid::receive(int, void *buf, int len, int timeout)
|
||||
{
|
||||
m_readMutex->lock();
|
||||
QMutexLocker locker(m_readMutex);
|
||||
Q_UNUSED(locker);
|
||||
|
||||
if (!device_open) {
|
||||
m_readMutex->unlock();
|
||||
if (!device_open)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Pass information to the callback to stop this run loop and signal if a timeout occurred
|
||||
struct timeout_info info;
|
||||
@ -183,6 +184,8 @@ int pjrc_rawhid::receive(int, void *buf, int len, int timeout)
|
||||
timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + (double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context);
|
||||
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
|
||||
|
||||
received_runloop = CFRunLoopGetCurrent();
|
||||
|
||||
// Run the CFRunLoop until either a timeout or data is available
|
||||
while(1) {
|
||||
if (buffer_count != 0) {
|
||||
@ -200,7 +203,7 @@ int pjrc_rawhid::receive(int, void *buf, int len, int timeout)
|
||||
CFRunLoopTimerInvalidate(timer);
|
||||
CFRelease(timer);
|
||||
|
||||
m_readMutex->unlock();
|
||||
received_runloop = NULL;
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -240,7 +243,8 @@ int pjrc_rawhid::send(int, void *buf, int len, int timeout)
|
||||
{
|
||||
// This lock ensures that when closing we don't do it until the
|
||||
// write has terminated (and then the device_open flag is set to false)
|
||||
m_writeMutex->lock();
|
||||
QMutexLocker locker(m_writeMutex);
|
||||
Q_UNUSED(locker);
|
||||
|
||||
if(!device_open || unplugged) {
|
||||
return -1;
|
||||
@ -256,13 +260,17 @@ int pjrc_rawhid::send(int, void *buf, int len, int timeout)
|
||||
QTimer::singleShot(timeout, &el, SLOT(quit()));
|
||||
el.exec();
|
||||
|
||||
m_writeMutex->unlock();
|
||||
|
||||
return sender.result;
|
||||
}
|
||||
|
||||
//! Get the serial number for a HID device
|
||||
QString pjrc_rawhid::getserial(int num) {
|
||||
QMutexLocker locker(m_readMutex);
|
||||
Q_UNUSED(locker);
|
||||
|
||||
if (!device_open || unplugged)
|
||||
return "";
|
||||
|
||||
CFTypeRef serialnum = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDSerialNumberKey));
|
||||
if(serialnum && CFGetTypeID(serialnum) == CFStringGetTypeID())
|
||||
{
|
||||
@ -280,8 +288,7 @@ QString pjrc_rawhid::getserial(int num) {
|
||||
void pjrc_rawhid::close(int)
|
||||
{
|
||||
// Make sure any pending locks are done
|
||||
m_writeMutex->lock();
|
||||
m_readMutex->lock();
|
||||
QMutexLocker lock(m_writeMutex);
|
||||
|
||||
if (device_open) {
|
||||
device_open = false;
|
||||
@ -299,12 +306,6 @@ void pjrc_rawhid::close(int)
|
||||
dev = NULL;
|
||||
hid_manager = NULL;
|
||||
}
|
||||
|
||||
// Must unlock to prevent deadlock in any read/write threads which will then fail
|
||||
// because device_open is false\
|
||||
m_writeMutex->unlock();
|
||||
m_readMutex->unlock();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,8 +324,8 @@ void pjrc_rawhid::input(uint8_t *data, CFIndex len)
|
||||
memcpy(buffer, &data[0], len);
|
||||
buffer_count = len;
|
||||
|
||||
if (the_correct_runloop)
|
||||
CFRunLoopStop(the_correct_runloop);
|
||||
if (received_runloop)
|
||||
CFRunLoopStop(received_runloop);
|
||||
}
|
||||
|
||||
//! Callback for the HID driver on an input report
|
||||
@ -376,6 +377,7 @@ void pjrc_rawhid::attach(IOHIDDeviceRef d)
|
||||
|
||||
attach_count++;
|
||||
device_open = true;
|
||||
unplugged = false;
|
||||
}
|
||||
|
||||
//! Called from the USB system and forwarded to the instance (context)
|
||||
|
@ -307,8 +307,10 @@ RawHID::RawHID(const QString &deviceName)
|
||||
// detect if the USB device is unplugged
|
||||
QObject::connect(&dev, SIGNAL(deviceUnplugged(int)), this, SLOT(onDeviceUnplugged(int)));
|
||||
|
||||
m_writeThread = new RawHIDWriteThread(this);
|
||||
|
||||
// Starting the read thread will lock the m_startexMutex until the
|
||||
// device is opened
|
||||
// device is opened (which happens in that thread).
|
||||
m_readThread = new RawHIDReadThread(this);
|
||||
m_readThread->start();
|
||||
|
||||
@ -334,12 +336,12 @@ bool RawHID::openDevice() {
|
||||
m_startedMutex->unlock();
|
||||
|
||||
//didn't find the device we are trying to open (shouldnt happen)
|
||||
device_open = opened >= 0;
|
||||
if (opened < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_writeThread = new RawHIDWriteThread(this);
|
||||
m_writeThread->start();
|
||||
|
||||
return true;
|
||||
|
@ -84,6 +84,7 @@ protected:
|
||||
|
||||
int m_deviceNo;
|
||||
pjrc_rawhid dev;
|
||||
bool device_open;
|
||||
|
||||
RawHIDReadThread *m_readThread;
|
||||
RawHIDWriteThread *m_writeThread;
|
||||
|
@ -87,11 +87,13 @@ DFUObject::DFUObject(bool _debug,bool _use_serial,QString portname):
|
||||
m_eventloop.exec();
|
||||
QList<USBPortInfo> devices;
|
||||
devices = USBMonitor::instance()->availableDevices(0x20a0,-1,-1,USBMonitor::Bootloader);
|
||||
if (devices.length()==1 && hidHandle.open(1,devices.first().vendorID,devices.first().productID,0,0)==1) {
|
||||
qDebug()<<"OP_DFU detected first time";
|
||||
mready=true;
|
||||
QTimer::singleShot(200,&m_eventloop, SLOT(quit()));
|
||||
m_eventloop.exec();
|
||||
if (devices.length()==1) {
|
||||
if (hidHandle.open(1,devices.first().vendorID,devices.first().productID,0,0)==1) {
|
||||
mready=true;
|
||||
QTimer::singleShot(200,&m_eventloop, SLOT(quit()));
|
||||
m_eventloop.exec();
|
||||
} else
|
||||
hidHandle.close(0);
|
||||
} else {
|
||||
// Wait for the board to appear on the USB bus:
|
||||
USBSignalFilter filter(0x20a0,-1,-1,USBMonitor::Bootloader);
|
||||
@ -117,7 +119,8 @@ DFUObject::DFUObject(bool _debug,bool _use_serial,QString portname):
|
||||
mready=true;
|
||||
qDebug() << "Detected";
|
||||
break;
|
||||
}
|
||||
} else
|
||||
hidHandle.close(0);
|
||||
} else {
|
||||
qDebug() << devices.length() << " device(s) detected, don't know what to do!";
|
||||
mready = false;
|
||||
@ -173,7 +176,6 @@ bool DFUObject::enterDFU(int const &devNumber)
|
||||
buf[9] = 1; //DFU Data3
|
||||
|
||||
int result = sendData(buf, BUF_LEN);
|
||||
// int result = hidHandle.send(0,buf, BUF_LEN, 500);
|
||||
if(result<1)
|
||||
return false;
|
||||
if(debug)
|
||||
@ -218,7 +220,6 @@ bool DFUObject::StartUpload(qint32 const & numberOfBytes, TransferTypes const &
|
||||
|
||||
int result = sendData(buf, BUF_LEN);
|
||||
delay::msleep(1000);
|
||||
// int result = hidHandle.send(0,buf, BUF_LEN, 5000);
|
||||
|
||||
if(debug)
|
||||
qDebug() << result << " bytes sent";
|
||||
@ -443,7 +444,6 @@ bool DFUObject::StartDownloadT(QByteArray *fw, qint32 const & numberOfBytes, Tra
|
||||
buf[9] = 1; //DFU Data3
|
||||
|
||||
int result = sendData(buf, BUF_LEN);
|
||||
//int result = hidHandle.send(0,buf, BUF_LEN, 500);
|
||||
if(debug)
|
||||
qDebug() << "StartDownload:"<<numberOfPackets<<"packets"<<" Last Packet Size="<<lastPacketCount<<" "<<result << " bytes sent";
|
||||
float percentage;
|
||||
@ -459,7 +459,6 @@ bool DFUObject::StartDownloadT(QByteArray *fw, qint32 const & numberOfBytes, Tra
|
||||
laspercentage=(int)percentage;
|
||||
|
||||
result = receiveData(buf,BUF_LEN);
|
||||
//result = hidHandle.receive(0,buf,BUF_LEN,5000);
|
||||
if(debug)
|
||||
qDebug() << result << " bytes received"<<" Count="<<x<<"-"<<(int)buf[2]<<";"<<(int)buf[3]<<";"<<(int)buf[4]<<";"<<(int)buf[5]<<" Data="<<(int)buf[6]<<";"<<(int)buf[7]<<";"<<(int)buf[8]<<";"<<(int)buf[9];
|
||||
if(x==numberOfPackets-1)
|
||||
@ -510,7 +509,6 @@ int DFUObject::AbortOperation(void)
|
||||
buf[9] = 0;
|
||||
|
||||
return sendData(buf, BUF_LEN);
|
||||
//return hidHandle.send(0,buf, BUF_LEN, 500);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -540,7 +538,6 @@ int DFUObject::JumpToApp(bool safeboot)
|
||||
}
|
||||
|
||||
return sendData(buf, BUF_LEN);
|
||||
//return hidHandle.send(0,buf, BUF_LEN, 500);
|
||||
}
|
||||
|
||||
OP_DFU::Status DFUObject::StatusRequest()
|
||||
@ -558,11 +555,9 @@ OP_DFU::Status DFUObject::StatusRequest()
|
||||
buf[9] = 0;
|
||||
|
||||
int result = sendData(buf, BUF_LEN);
|
||||
//int result = hidHandle.send(0,buf, BUF_LEN, 10000);
|
||||
if(debug)
|
||||
qDebug() << "StatusRequest: " << result << " bytes sent";
|
||||
result = receiveData(buf,BUF_LEN);
|
||||
// result = hidHandle.receive(0,buf,BUF_LEN,10000);
|
||||
if(debug)
|
||||
qDebug() << "StatusRequest: " << result << " bytes received";
|
||||
if(buf[1]==OP_DFU::Status_Rep)
|
||||
@ -623,9 +618,6 @@ bool DFUObject::findDevices()
|
||||
buf[9] = 0;
|
||||
int result = sendData(buf, BUF_LEN);
|
||||
result = receiveData(buf,BUF_LEN);
|
||||
// int result = hidHandle.send(0,buf, BUF_LEN, 5000);
|
||||
// result = hidHandle.receive(0,buf,BUF_LEN,5000);
|
||||
//devices[x].ID=buf[9];
|
||||
devices[x].ID=buf[14];
|
||||
devices[x].ID=devices[x].ID<<8 | (quint8)buf[15];
|
||||
devices[x].BL_Version=buf[7];
|
||||
@ -681,8 +673,6 @@ bool DFUObject::EndOperation()
|
||||
buf[9] = 0;
|
||||
|
||||
int result = sendData(buf, BUF_LEN);
|
||||
// int result = hidHandle.send(0,buf, BUF_LEN, 5000);
|
||||
// hidHandle.receive(0,buf,BUF_LEN,5000);
|
||||
if(debug)
|
||||
qDebug() << result << " bytes sent";
|
||||
if(result>0)
|
||||
|
@ -378,7 +378,8 @@ void UploaderGadgetWidget::systemSafeBoot()
|
||||
}
|
||||
|
||||
/**
|
||||
Tells the system to boot (from Bootloader state)
|
||||
* Tells the system to boot (from Bootloader state)
|
||||
* @param[in] safeboot Indicates whether the firmware should use the stock HWSettings
|
||||
*/
|
||||
void UploaderGadgetWidget::commonSystemBoot(bool safeboot)
|
||||
{
|
||||
@ -547,6 +548,7 @@ void UploaderGadgetWidget::systemRescue()
|
||||
m_config->rescueButton->setEnabled(false);
|
||||
currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards.
|
||||
}
|
||||
|
||||
void UploaderGadgetWidget::perform()
|
||||
{
|
||||
if(m_progress->value()==19)
|
||||
|
Loading…
x
Reference in New Issue
Block a user