Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SetCommState function fails (error 87)

I'm working on some basic serial communication stuff and I've come across this issue that I can't seem to work around. I'm trying to set my comm state to a certain baud rate, stop bit, parity bit and data size. As shown in my example code below, I'm getting the current COM state from getComState and modifying some values.

    DCB dcb = { 0 };
    // for set timeout for readfile function
    COMMTIMEOUTS timeouts = {   0,  // interval timeout. 0 = not used
                                0,  // read multiplier
                                500, // read constant (milliseconds)
                                0,  // Write multiplier
                                500 // Write Constant
                            };

    if (SetCommTimeouts(usb_device, &timeouts) == FALSE) {
        "ERROR: SetCommTimeouts failed with error %d.\n", GetLastError();

        add_log_trace("ERROR: SetCommTimeouts failed with error %d.\n", GetLastError());
    }

    BOOL fSuccess;
    //  Initialize the DCB structure.
    SecureZeroMemory(&dcb, sizeof(DCB));
    dcb.DCBlength = sizeof(DCB);

    //  Build on the current configuration by first retrieving all current
    //  settings.
    fSuccess = GetCommState(usb_device, &dcb);

    //  Fill in some DCB values and set the com state: 
    //  115,200 bps, 8 data bits, no parity, and 1 stop bit.
    dcb.BaudRate    =   CBR_115200;     //  baud rate
    dcb.ByteSize    =   8;             //  data size, xmit and rcv
    dcb.Parity      =   NOPARITY;      //  parity bit
    dcb.StopBits    =   ONESTOPBIT;    //  stop bit

    fSuccess = SetCommState(usb_device, &dcb);

However, this function tends to fail me no matter what I do. The error is pretty straight forward(error code 87) which signifies that there is an invalid parameter. After doing some research the solution seems pretty obvious. However, I've tried the solutions listed below including some sanity test and nothing seems to work.

  • Setting the DCB struct to only initialize with the size
  • Disabling handshake in the DCB struct
  • Setting the DCB struct to no values
  • Using an alternate way to set the DCB struct besides GetCommState
  • Setting the CommState to the same state that I get from GetCommState
  • Ensuring the COM port name is correct when opening the file

I've also taken into account the remarks that were left by MSDN developers in regards to using the SetComState function however, the function call continues to fail nevertheless.

I've attempted running similar code on a linux box and setting the com port works fine. I came across some articles where they're stating that Windows has messed up their usbser.sys file which handled communication between the OS and the device.

  • Accessing COM-port with Windows 10
  • USB serial interface problems with Windows 10

I'm tempted to try replacing the usbser.sys file with an older one however I'd wanted a second opinion in regards to this issue. Is this a common issue? Is there a more straight forward solution? I'd appreciate if someone could point me in the right direction or correct me in some of my assumptions and methodology. Hopefully this post isn't too board in terms of scope. I'm just trying to set my baud rate right using SetCommState. Lolz.

Thank you

like image 691
Rommel Alonzo Avatar asked Nov 17 '22 18:11

Rommel Alonzo


1 Answers

call GetCommState befor SetCommState

like image 133
Yousri Gafsaoui Avatar answered Jan 15 '23 00:01

Yousri Gafsaoui