views:

842

answers:

2

Hi I have the need to find the Baud rate and other settings for a serial port, Looking about on the web, it looks like I should be using GetCommConfig, This returns a TCommConfig record with what I assume is the data I need. The problem is the function I wote returns the wrong values.

The code below looks like it is working, but the baud rate is always 1200, which looking in windows device manager (and altering port settings), is wrong.

I have tried calling it like so:

ComPort('com1');
ComPort('COM1');
ComPort('COM1:');
ComPort('COM4');
ComPort('COM9');

the first 4 are valid but return 1200 and the 5th is invalid and returns 0

function ComPort(l_port:String):TCommConfig;
{Gets the comm port settings}
    var
    ComFile: THandle;
    PortName: array[0..80] of Char;
    size: cardinal;
    CommConfig:TCommConfig;
begin
    FillChar(Result, SizeOf(TCommConfig), 0);//blank return value

    try
        StrPCopy(PortName,l_port);
        ComFile := CreateFile(PortName,GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,0{ FILE_ATTRIBUTE_NORMAL},0);
        try
            if (ComFile <> INVALID_HANDLE_VALUE) then
            begin
                FillChar(CommConfig, SizeOf(TCommConfig), 0);//blank record
                CommConfig.dwSize := sizeof(TCommConfig);//set size
                //CommConfig.dcb.DCBlength := SizeOf(_dcb);
                size := sizeof(TCommConfig);

                if (GetCommConfig(ComFile,CommConfig,size)) then
                begin
                    Result := CommConfig;
                end;
            end;
        finally
           CloseHandle(ComFile);
        end;
    except
        Showmessage('Unable to open port ' + l_port);
    end;
end;

Stepping through the code, the first 4 always hit the line Result := CommConfig;, so the GetCommConfig is retuning a valid code, so I must be missing something.

I have tryed verious other things, such as setting the length of the dcb record, but all have the same result, as baud of 1200.

Does anyone know where I am going wrong?

+3  A: 

The baud rate and other settings for a serial port, are set when the serial port is opened. I think you are reading default values.

lg
I thought that was what CreateFile was doing, opening a connection to the port?
Re0sless
+2  A: 

It turns out I was using the wrong function, I should have been using GetDefaultCommConfig and not the GetCommConfig that I was using.

By the look if it, and please correct me if I am wrong, GetDefaultCommConfig returns the settings from windows and GetCommConfig returns the settings of the open connection to the port, writefile opens the port up as it see fit (ignoring the default settings), which is where the 1200 baud rate was coming from.

If this helps anyone in the future, here is the function I came up with.

function ComPort(l_port:String):TCommConfig;
{Gets the comm port settings (use '\\.\' for com 10..99) }
    var
    size: cardinal;
    CommConfig:TCommConfig;
begin
    FillChar(Result, SizeOf(TCommConfig), 0);

    //strip trailing : as it does not work with it
    if (RightStr(l_port,1) = ':') then l_port := LeftStr(l_port,Length(l_port)-1);

    try
        FillChar(CommConfig, SizeOf(TCommConfig), 0);
        CommConfig.dwSize := sizeof(TCommConfig);

        size := sizeof(TCommConfig);

        if (GetDefaultCommConfig(PChar(l_port),CommConfig,size)) then
        begin
            Result := CommConfig;
        end
        //if port is not found add unc path and check again
        else if (GetDefaultCommConfig(PChar('\\.\' + l_port),CommConfig,size)) then
        begin
            Result := CommConfig;
        end
    except
        Showmessage('Unable to open port ' + l_port);
    end;
end;
Re0sless