Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set DTR/RTS state that will be used when CreateFile() opens COM port

Tags:

I wrote/support a terminal emulator called uCon (http://www.umonfw.com/ucon). Its all based on "good-ole" Win32, and is entirely in 'C'. I was recently asked to support the ability to have uCon attach to a COM port and set up DTR/RTS for purposes outside of RS232 flow control. I know I can do this after CreateFile() is called using EscapeCommFunction() and/or SetCommState(); however, these functions can only be called AFTER CreateFile() returns a handle to the opened port. Unfortunately, when CreateFile() opens the port, it sets DTR/RTS to their default state, which may (or may not) be different than the state that I wish to keep DTR in.

For example, assume the user has a board connected to the PC's serial port, and the DTR line is used to put the board in some non-standard state. With DTR inactive, the board runs "normal", but occasionally DTR-active is used to transition the hardware to some other state.

In most cases I've seen, CreateFile() brings DTR active, then my call to clear DTR brings it back to inactive; however, that's a glitch I need to avoid. I found a function set called GetDefaultCommConfig() & SetDefaultCommConfig() but have not been able to get them to work successfully. So, my question is this...

Is there a way to pre-define the default state that will be established on the RS232 control lines when CreateFile() is called? Has anyone used GetDefaultCommConfig()/SetDefaultCommConfig() successfully?

It seems to me that this should allow me to pre-establish the value of DTR to be used when CreateFile() is called...

 
int
EstablishDefaultDTR(char *comPortName, int dtr)
{
    COMMCONFIG  cc;
    DWORD   bsize = sizeof(COMMCONFIG);

    if (GetDefaultCommConfig(comPortName,&cc,&bsize) == 0) {
        ShowLastError("GetDefaultCommConfig()");
        return(-1);
    }

    if (dtr)
       cc.dcb.fDtrControl = DTR_CONTROL_ENABLE ;
    else
       cc.dcb.fDtrControl = DTR_CONTROL_DISABLE ;

    if (SetDefaultCommConfig(comPortName,&cc,bsize) == 0) {
        ShowLastError("SetDefaultCommConfig()");
        return(-1);
    }
}

But, as you may have already guessed, it doesn't. Any ideas?

like image 525
Ed. Avatar asked Jun 04 '09 14:06

Ed.


2 Answers

Might not be the fastest way, but this works:

#include <stdlib.h>
#include <stdio.h>

int
EstablishDefaultDTR(char *comPortName, int dtr){
    char commandString[256];
    if ( !system(NULL) ){
        ShowLastError("system()");
        return(-1);
    }        
    sprintf( commandString, "MODE %s dtr=%s%", comPortName, dtr? "on":"off"  );
    return system( commandString );
}
like image 71
dario_ramos Avatar answered Oct 02 '22 13:10

dario_ramos


You're not initializing the COMMCONFIG structure. That could well be the problem since the documentation explicitly says that you must set dwSize at least

cc.dwSize = sizeof( COMMCONFIG );

like image 25
Paul Mitchell Avatar answered Oct 02 '22 13:10

Paul Mitchell