mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Allow disconnections to be signaled by drivers
This allows for disconnections to be detected quickly where possible. It also makes sure other driver errors aren't thrown in the event of a disconnection.
This commit is contained in:
committed by
Paul Hollinsky
parent
dfe2d23d85
commit
a5b27a15b0
+29
-12
@@ -1,3 +1,4 @@
|
||||
#include "libusb-1.0/libusb.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
@@ -81,7 +82,7 @@ bool FTDI::open() {
|
||||
}
|
||||
|
||||
bool FTDI::close() {
|
||||
if(!isOpen()) {
|
||||
if(!isOpen() && !isDisconnected()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
@@ -94,9 +95,12 @@ bool FTDI::close() {
|
||||
if(writeThread.joinable())
|
||||
writeThread.join();
|
||||
|
||||
bool ret = ftdi.closeDevice();
|
||||
if(!ret)
|
||||
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
||||
bool ret = true;
|
||||
if(!isDisconnected()) {
|
||||
ret = ftdi.closeDevice();
|
||||
if(!ret)
|
||||
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
||||
}
|
||||
|
||||
uint8_t flush;
|
||||
WriteOperation flushop;
|
||||
@@ -184,11 +188,17 @@ void FTDI::readTask() {
|
||||
constexpr size_t READ_BUFFER_SIZE = 8;
|
||||
uint8_t readbuf[READ_BUFFER_SIZE];
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
while(!closing) {
|
||||
while(!closing && !isDisconnected()) {
|
||||
auto readBytes = ftdi.read(readbuf, READ_BUFFER_SIZE);
|
||||
if(readBytes < 0)
|
||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::EventWarning);
|
||||
else
|
||||
if(readBytes < 0) {
|
||||
if(readBytes == LIBUSB_ERROR_NO_DEVICE || readBytes == LIBUSB_ERROR_PIPE) {
|
||||
if(!isDisconnected()) {
|
||||
disconnected = true;
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
}
|
||||
} else
|
||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::EventWarning);
|
||||
} else
|
||||
readQueue.enqueue_bulk(readbuf, readBytes);
|
||||
}
|
||||
}
|
||||
@@ -196,16 +206,23 @@ void FTDI::readTask() {
|
||||
void FTDI::writeTask() {
|
||||
WriteOperation writeOp;
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
while(!closing) {
|
||||
while(!closing && !isDisconnected()) {
|
||||
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
|
||||
continue;
|
||||
|
||||
size_t offset = 0;
|
||||
while(offset < writeOp.bytes.size()) {
|
||||
auto writeBytes = ftdi.write(writeOp.bytes.data() + offset, (int)writeOp.bytes.size() - offset);
|
||||
if(writeBytes < 0)
|
||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::EventWarning);
|
||||
else
|
||||
if(writeBytes < 0) {
|
||||
if(writeBytes == LIBUSB_ERROR_NO_DEVICE || writeBytes == LIBUSB_ERROR_PIPE) {
|
||||
if(!isDisconnected()) {
|
||||
disconnected = true;
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
}
|
||||
break;
|
||||
} else
|
||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::EventWarning);
|
||||
} else
|
||||
offset += writeBytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,13 @@ bool STM32::open() {
|
||||
return false;
|
||||
}
|
||||
|
||||
fd = ::open(ttyPath.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
// Some devices can take a while to boot
|
||||
for(int i = 0; i != 50; ++i) {
|
||||
fd = ::open(ttyPath.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if(fd != -1)
|
||||
break;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
if(!isOpen()) {
|
||||
//std::cout << "Open of " << ttyPath.c_str() << " failed with " << strerror(errno) << ' ';
|
||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||
@@ -82,7 +88,7 @@ bool STM32::isOpen() {
|
||||
}
|
||||
|
||||
bool STM32::close() {
|
||||
if(!isOpen()) {
|
||||
if(!isOpen() && !isDisconnected()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
@@ -117,7 +123,7 @@ void STM32::readTask() {
|
||||
constexpr size_t READ_BUFFER_SIZE = 2048;
|
||||
uint8_t readbuf[READ_BUFFER_SIZE];
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
while(!closing) {
|
||||
while(!closing && !isDisconnected()) {
|
||||
fd_set rfds = {0};
|
||||
struct timeval tv = {0};
|
||||
FD_SET(fd, &rfds);
|
||||
@@ -126,19 +132,37 @@ void STM32::readTask() {
|
||||
auto bytesRead = ::read(fd, readbuf, READ_BUFFER_SIZE);
|
||||
if(bytesRead > 0)
|
||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||
else {
|
||||
if(!fdIsValid() && !isDisconnected()) {
|
||||
disconnected = true;
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void STM32::writeTask() {
|
||||
WriteOperation writeOp;
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
while(!closing) {
|
||||
while(!closing && !isDisconnected()) {
|
||||
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
|
||||
continue;
|
||||
|
||||
const ssize_t writeSize = (ssize_t)writeOp.bytes.size();
|
||||
ssize_t actualWritten = ::write(fd, writeOp.bytes.data(), writeSize);
|
||||
if(actualWritten != writeSize)
|
||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
||||
if(actualWritten != writeSize) {
|
||||
if(!fdIsValid()) {
|
||||
if(!isDisconnected()) {
|
||||
disconnected = true;
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
}
|
||||
} else
|
||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool STM32::fdIsValid() {
|
||||
struct termios tty = {};
|
||||
return tcgetattr(fd, &tty) == 0 ? true : false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user