Home:ALL Converter>Windows Error 87 when raising DTR line (serial)

Windows Error 87 when raising DTR line (serial)

Ask Time:2016-05-19T02:32:22         Author:Valarauca

Json Formatter

I am attempting to communicate with a serial device over a TTL->RS-232 converter. This converter requires power be sent on the DTR and RTS lines.

// imports
extern crate serial; //see: https://dcuddeback.github.io/serial-rs/serial/index.html
use std::env;
use std::io;
use std::time::Duration;
use std::process::exit;
use std::io::prelude::*;
use serial::prelude::*;
use serial::{BaudRate, CharSize, Parity, StopBits, FlowControl, SystemPort, PortSettings, Error};
use std::mem;

#[inline]
fn display_error_message(err: &Error, msg: &str) -> ! {
    println!("{}", msg);
    println!("Error Code: {:?}", err.raw_os_error());
    println!("Error:  {:?}", err);
    exit(0);
}

fn main() {
    // open port
    let mut port = match serial::open("COM3") {
        Err(ref e) => display_error_message(e, "Error opening serial port"),
        Ok(x) => x,
    };
    // push settings to stack
    let settings = PortSettings {
        baud_rate: BaudRate::Baud115200,
        char_size: CharSize::Bits8,
        parity: Parity::ParityNone,
        stop_bits: StopBits::Stop1,
        flow_control: FlowControl::FlowNone,
    };
    // configure port
    match port.configure(&settings) {
        Ok(_) => {}
        Err(ref e) => display_error_message(e, "Error configuring serial port."),
    };
    // set rts
    match port.set_rts(true) {
        Ok(_) => {}
        Err(ref e) => display_error_message(e, "Error setting RTS line"),
    };
    // set DTR
    match port.set_dtr(true) {
        Ok(_) => {}
        Err(ref e) => display_error_message(e, "Error setting DTR line"),
    };
    // allocate readbuffer on stack
    let mut rb: [u8; 1] = [0u8; 1];
    // allocate buffer to hold output
    let mut out: String = String::with_capacity(1024);
    // loop while reading
    loop {
        match port.read(&mut rb) {
            Ok(_) => {}
            Err(ref e) => {
                println!("Error reading serial port.");
                println!("Error:  {:?}", e);
                exit(0);
            }
        };
        match rb[0] {
            // Linefeed
            10 => {
                println!("{}<LF>", &out);
                out = String::with_capacity(1024);
            }
            // carriage return
            13 => {
                println!("{}<CR>", &out);
                out = String::with_capacity(1024);
            }
            // normal chars
            32...126 => {
                let temp: u32 = rb[0].clone() as u32;
                let ch: char = unsafe { mem::transmute(temp) };
                out.push(ch);
            }
            // everything else
            x => {
                println!("Non standard character encountered");
                println!("Value:  {:?}", x);
                exit(0);
            }
        };
    }
}

The source code is also on the Rust Playground and Github.

I am using the serial-rs library and Rust 1.8 (GNU ABI Windows 7 x64 Professional).

My error occurs on line 46:

 match port.set_dtr( true ) {
     Ok(_) => { },
     Err(ref e) => display_error_message(e,"Error setting DTR line")
 };

This returns error code 87 (on Windows 7). The standard serial-rs doesn't save the error code so I'm using my own fork (pending a PR).

This error is from a malformed system call. Diving into serial-rs one will see set_dtr(bool) is just wrapping a call to EscapeCommFunction(2) first call, second call, third call. The arguments codes appear correct.

Compiling with the MSVC toolchain results in same error, placing the DTR call before RTS call results in same error.

Raising DTR and RTS at the same time works in py-serial, but I can't write to the port while doing so. See other issue

Author:Valarauca,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/37307559/windows-error-87-when-raising-dtr-line-serial
yy