mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
POSIX: STM32: Handle re-enumeration when changing modes
This commit is contained in:
@@ -14,6 +14,12 @@
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
STM32::~STM32() {
|
||||
awaitModeChangeComplete();
|
||||
if(isOpen())
|
||||
close();
|
||||
}
|
||||
|
||||
bool STM32::open() {
|
||||
if(isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error);
|
||||
@@ -111,6 +117,12 @@ bool STM32::close() {
|
||||
WriteOperation flushop;
|
||||
while (readQueue.try_dequeue(flush)) {}
|
||||
while (writeQueue.try_dequeue(flushop)) {}
|
||||
|
||||
if(modeChanging) {
|
||||
modeChanging = false;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||
return open(); // Reopen the reenumerated device
|
||||
}
|
||||
|
||||
if(ret == 0) {
|
||||
return true;
|
||||
@@ -120,6 +132,18 @@ bool STM32::close() {
|
||||
}
|
||||
}
|
||||
|
||||
void STM32::modeChangeIncoming() {
|
||||
modeChanging = true;
|
||||
}
|
||||
|
||||
void STM32::awaitModeChangeComplete() {
|
||||
std::unique_lock<std::mutex> lk(modeChangeMutex);
|
||||
if(modeChanging && !modeChangeThread.joinable()) // Waiting for the thread to start
|
||||
modeChangeCV.wait_for(lk, std::chrono::seconds(1), [this] { return modeChangeThread.joinable(); });
|
||||
if(modeChangeThread.joinable())
|
||||
modeChangeThread.join();
|
||||
}
|
||||
|
||||
void STM32::readTask() {
|
||||
constexpr size_t READ_BUFFER_SIZE = 2048;
|
||||
uint8_t readbuf[READ_BUFFER_SIZE];
|
||||
@@ -131,10 +155,27 @@ void STM32::readTask() {
|
||||
tv.tv_usec = 50000; // 50ms
|
||||
::select(fd + 1, &rfds, NULL, NULL, &tv);
|
||||
auto bytesRead = ::read(fd, readbuf, READ_BUFFER_SIZE);
|
||||
if(bytesRead > 0)
|
||||
if(bytesRead > 0) {
|
||||
#if 0 // Perhaps helpful for debugging :)
|
||||
std::cout << "Read data: (" << bytesRead << ')' << std::hex << std::endl;
|
||||
for(int i = 0; i < bytesRead; i += 16) {
|
||||
for(int j = 0; j < std::min<int>(bytesRead - i, 16); j++)
|
||||
std::cout << std::setw(2) << std::setfill('0') << uint32_t(readbuf[i+j]) << ' ';
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::dec << std::endl;
|
||||
#endif
|
||||
|
||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||
else {
|
||||
if(!fdIsValid() && !isDisconnected()) {
|
||||
} else {
|
||||
if(modeChanging) {
|
||||
// We were expecting a disconnect for reenumeration
|
||||
modeChangeThread = std::thread([this] {
|
||||
modeChangeCV.notify_all();
|
||||
close(); // Which will trigger an open() due to modeChanging
|
||||
});
|
||||
break;
|
||||
} else if(!closing && !fdIsValid() && !isDisconnected()) {
|
||||
disconnected = true;
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user