title: Windows + SetCommState how to set RTS?
body: <p>I have an application that has been ported up from VC++ 6 where it worked fine.  The code in question uses the WinAPI for a serial device driver.  When ported to VS2012, the same code behaves rather differently.</p>
  
  <p>Create a DCB, set SetCommState and go.  CTS was set high, RTS was set high and you were on your way.</p>
  
  <p>Since ported up to VS2012 Pro MFC, I am finding that it sets up SetCommState the same with or without hardware flow control:</p>
  
  <pre><code>memset(&amp;dcb, 0x00, sizeof(dcb));
  dcb.DCBlength = sizeof(DCB);
  
  // Must be TRUE, only binary mode in Windows
  dcb.fBinary = TRUE;
  dcb.fParity = FALSE;
  
  // XOn/XOff disabled
  dcb.fTXContinueOnXoff = TRUE;
  dcb.fOutX = FALSE;
  dcb.fInX = FALSE;
  dcb.XonLim = 0;
  dcb.XoffLim = 0;
  dcb.XonChar = 0;
  dcb.XoffChar = 0;
  
  // Misc Stuff
  dcb.EofChar = 0;
  dcb.EvtChar = 0;
  dcb.ErrorChar = 0;
  dcb.fErrorChar = FALSE;
  dcb.fNull = FALSE;
  dcb.fAbortOnError = FALSE;
  
  // 8N1 Setup
  dcb.ByteSize = 8;
  dcb.Parity = NOPARITY;
  dcb.StopBits = ONESTOPBIT;
  
  // Baud Rate
  if (dwBaudRate == BAUD_115200)
  {
      dcb.BaudRate = CBR_115200;
  }
  else
  {
      dcb.BaudRate = CBR_38400;
  }
  
  // setup hardware flow control
  if (bHardware == eYesHardwareFlowControl)
  {
      // ================ FLOW CONTROL ON ================
      switch (bIgnoreCTS)
      {
          case eIgnoreCTS:
              dcb.fOutxCtsFlow = FALSE;
              break;
  
          case eEnableCTS:
              dcb.fOutxCtsFlow = TRUE;
              break;
  
          default:
          case eCTSDecideLater:
              dcb.fOutxCtsFlow = TRUE;
              break;
      }
  
      // DSR Flow Control
      dcb.fDsrSensitivity = FALSE;
      dcb.fOutxDsrFlow = FALSE;
  
      // &lt;&lt;Hardware flow control On(TRUE) Off(FALSE)&gt;&gt;
      dcb.fDtrControl = DTR_CONTROL_ENABLE;
  
      // &lt;&lt;Hardware flow control On(_HANDSHAKE) Off(_ENBLE)&gt;&gt;
      dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  }
  else
  {
      // ================ FLOW CONTROL OFF ================
      switch (bIgnoreCTS)
      {
          case eIgnoreCTS:
              dcb.fOutxCtsFlow = FALSE;
              break;
  
          case eEnableCTS:
              dcb.fOutxCtsFlow = TRUE;
              break;
  
          default:
          case eCTSDecideLater:
              dcb.fOutxCtsFlow = FALSE;
              break;
      }
  
      // DSR Flow Control
      dcb.fDsrSensitivity = FALSE;
      dcb.fOutxDsrFlow = FALSE;
  
      dcb.fDtrControl = DTR_CONTROL_ENABLE;
      dcb.fRtsControl = RTS_CONTROL_ENABLE;
  }
  
  if (SetCommState(m_hIdComDev, &amp;dcb) == WINDOWS_API_ZERO_IS_BAD)
  {
      dwLastError = GetLastError();
  }
  </code></pre>
  
  <p>At this point, I have set up the DCB, cleared it.  I don't read in the previous state is I don't want to trust any garbage of anyone that previously used the port. Then I set up every field with Baud, Flow Control and CTS Ignore being the only optional items.</p>
  
  <p>So, what I've noticed is that I can create situation where the Device and the PC don't communicate.  Now, mind you, they always did before and they always work with Hyperterminal, ProComm, TeraTerm and so on.  What I can see is that when these comm programs start (and the old VC++ 6 App), when the device is created and set up, RTS is immediately set high.</p>
  
  <p>Now, my App, once the DCB is set up, SetCommState called; RTS is always LOW.  And when this happens, communications is toast.</p>
  
  <p>I want to FORCE RTS to be high and thought I could do it like this:</p>
  
  <pre><code>if (EscapeCommFunction(m_hIdComDev, CLRRTS) == WINDOWS_API_ZERO_IS_BAD)
  {
      dwLastError = GetLastError();
  }
  
  if (EscapeCommFunction(m_hIdComDev, SETRTS) == WINDOWS_API_ZERO_IS_BAD)
  {
      dwLastError = GetLastError();
  }
  </code></pre>
  
  <p>But this fails, it gives an error 87 (parameter error).  And I cannot quite figure it out.  Even if I just SETRTS high only, it fails.</p>
  
  <p>Any ideas on how I can force Windows to set RTS high after I setup the comm parameters in the DCB?</p>