Skip to content

Commit

Permalink
Be more consistent about DTR toggling (needed to reset serial devices).
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgiven committed May 1, 2024
1 parent f0b1b61 commit 653a6a0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 16 deletions.
42 changes: 26 additions & 16 deletions lib/usb/serial.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@ class SerialPortImpl : public SerialPort
commtimeouts.ReadIntervalTimeout = 100;
SetCommTimeouts(_handle, &commtimeouts);

if (!EscapeCommFunction(_handle, CLRDTR))
error("Couldn't clear DTR: {}", get_last_error_string());
Sleep(200);
if (!EscapeCommFunction(_handle, SETDTR))
error("Couldn't set DTR: {}", get_last_error_string());
/* Toggle DTR to reset the device. */

toggleDtr();

PurgeComm(_handle,
PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
Expand All @@ -58,6 +56,15 @@ class SerialPortImpl : public SerialPort
}

public:
void toggleDtr() override
{
if (!EscapeCommFunction(_handle, CLRDTR))
error("Couldn't clear DTR: {}", get_last_error_string());
Sleep(200);
if (!EscapeCommFunction(_handle, SETDTR))
error("Couldn't set DTR: {}", get_last_error_string());
}

ssize_t readImpl(uint8_t* buffer, size_t len) override
{
DWORD rlen;
Expand Down Expand Up @@ -98,11 +105,7 @@ class SerialPortImpl : public SerialPort
.StopBits = ONESTOPBIT};
SetCommState(_handle, &dcb);

if (!EscapeCommFunction(_handle, CLRDTR))
error("Couldn't clear DTR: {}", get_last_error_string());
Sleep(200);
if (!EscapeCommFunction(_handle, SETDTR))
error("Couldn't set DTR: {}", get_last_error_string());
toggleDtr();
}

private:
Expand Down Expand Up @@ -163,12 +166,7 @@ class SerialPortImpl : public SerialPort

/* Toggle DTR to reset the device. */

int flag = TIOCM_DTR;
if (ioctl(_fd, TIOCMBIC, &flag) == -1)
error("cannot clear DTR on serial port: {}", strerror(errno));
usleep(200000);
if (ioctl(_fd, TIOCMBIS, &flag) == -1)
error("cannot set DTR on serial port: {}", strerror(errno));
toggleDtr();

/* Flush pending input from a generic greaseweazel device */
tcsetattr(_fd, TCSAFLUSH, &t);
Expand All @@ -180,6 +178,16 @@ class SerialPortImpl : public SerialPort
}

public:
void toggleDtr() override
{
int flag = TIOCM_DTR;
if (ioctl(_fd, TIOCMBIC, &flag) == -1)
error("cannot clear DTR on serial port: {}", strerror(errno));
usleep(200000);
if (ioctl(_fd, TIOCMBIS, &flag) == -1)
error("cannot set DTR on serial port: {}", strerror(errno));
}

ssize_t readImpl(uint8_t* buffer, size_t len) override
{
ssize_t rlen = ::read(_fd, buffer, len);
Expand All @@ -204,6 +212,8 @@ class SerialPortImpl : public SerialPort
tcgetattr(_fd, &t);
cfsetspeed(&t, baudRate);
tcsetattr(_fd, TCSANOW, &t);

toggleDtr();
}

private:
Expand Down
1 change: 1 addition & 0 deletions lib/usb/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class SerialPort
virtual ssize_t readImpl(uint8_t* buffer, size_t len) = 0;
virtual ssize_t write(const uint8_t* buffer, size_t len) = 0;
virtual void setBaudRate(int baudRate) = 0;
virtual void toggleDtr() = 0;

void read(uint8_t* buffer, size_t len);
void read(Bytes& bytes);
Expand Down

0 comments on commit 653a6a0

Please sign in to comment.