Hi,
this function retrieves the configuration settings of a given serial port.
Having hardly any C\C++ experience it took me some time to find out that there is a bitmask in the DCB (Device Configuration Block) structure.
Using BuildCommDCB and SetCommState functions it should also be possible to configure a serial port.
Data can be written to a serial port using one of the binary writing functions on this forum.
I appologize for the script not beeing commented at all, also I am not sure if I did everything right. Comments and suggestions are welcome.
Regards,
olfen
Code:
GetCommState(ComPort)
{
/*
http://msdn.microsoft.com/library/en-us/fileio/fs/createfile.asp?frame=true
http://msdn.microsoft.com/library/en-us/devio/base/getcommstate.asp?frame=true
http://msdn.microsoft.com/library/en-us/devio/base/dcb_str.asp
http://msdn.microsoft.com/library/en-us/devio/base/buildcommdcb.asp?frame=true
http://msdn.microsoft.com/library/en-us/devio/base/setcommstate.asp?frame=true
http://msdn.microsoft.com/library/en-us/devio/base/waitcommevent.asp?frame=true
typedef struct _DCB {
DWORD DCBlength; /* sizeof(DCB) */
DWORD BaudRate; /* Baudrate at which running */
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
DWORD fParity: 1; /* Enable parity checking */
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
DWORD fDtrControl:2; /* DTR Flow control */
DWORD fDsrSensitivity:1; /* DSR Sensitivity */
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
DWORD fInX: 1; /* Enable input X-ON/X-OFF */
DWORD fErrorChar: 1; /* Enable Err Replacement */
DWORD fNull: 1; /* Enable Null stripping */
DWORD fRtsControl:2; /* Rts Flow control */
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
DWORD fDummy2:17; /* Reserved */
WORD wReserved; /* Not currently used */
WORD XonLim; /* Transmit X-ON threshold */
WORD XoffLim; /* Transmit X-OFF threshold */
BYTE ByteSize; /* Number of bits/byte, 4-8 */
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */
char XonChar; /* Tx and Rx X-ON character */
char XoffChar; /* Tx and Rx X-OFF character */
char ErrorChar; /* Error replacement char */
char EofChar; /* End of Input character */
char EvtChar; /* Received Event character */
WORD wReserved1; /* Fill for now. */
} DCB, *LPDCB;
Flowcontrol
Xon/Xoff: 21393 -> 0101 0011 1001 0001
Hardware: 24725 -> 0110 0000 1001 0101
Off: 20625 -> 0101 0000 1001 0001
*/
global
local h, cs, ch, port, DCB, Str, Uint
port=com%comport%
h := DllCall("CreateFile","Str", port,"Uint",0x80000000,"Uint",3,"UInt",0,"UInt",3,"Uint",0,"UInt",0)
If (h = -1 or h = 0 or ErrorLevel != 0)
return, -1
VarSetCapacity(DCB, 28, 0)
cs := DllCall("GetCommState", Uint, h, str, DCB)
If (cs = 0 or ErrorLevel != 0)
return, -2
;DCB_DCBlength:=ExtractInteger(DCB, 0, true, 4)
DCB_BaudRate:=ExtractInteger(DCB, 4, true, 4)
DCB_fBitMask:=ExtractInteger(DCB, 8, true, 4)
DCB_fBitMaskDec:=DCB_fBitMask
DCB_fBitMask:=DecToBin(DCB_fBitMask)
StringLeft, DCB_fAbortOnError, DCB_fBitMask, 1
StringMid, DCB_fRtsControl, DCB_fBitMask, 2, 2
StringMid, DCB_fNull, DCB_fBitMask, 4, 1
StringMid, DCB_fErrorChar, DCB_fBitMask, 5, 1
StringMid, DCB_fInX, DCB_fBitMask, 6, 1
StringMid, DCB_fOutX, DCB_fBitMask, 7, 1
StringMid, DCB_fTXContinueOnXoff, DCB_fBitMask, 8, 1
StringMid, DCB_fDsrSensitivity, DCB_fBitMask, 9, 1
StringMid, DCB_fDtrControl, DCB_fBitMask, 10, 2
StringMid, DCB_fOutxDsrFlow, DCB_fBitMask, 12, 1
StringMid, DCB_fOutxCtsFlow, DCB_fBitMask, 13, 1
StringMid, DCB_fParity, DCB_fBitMask, 14, 1
StringRight, DCB_fBinary, DCB_fBitMask, 1
IfEqual, DCB_fDtrControl, 00, SetEnv, DCB_fDtrControl, DTR_CONTROL_DISABLE
IfEqual, DCB_fDtrControl, 01, SetEnv, DCB_fDtrControl, DTR_CONTROL_ENABLE
IfEqual, DCB_fDtrControl, 10, SetEnv, DCB_fDtrControl, DTR_CONTROL_HANDSHAKE
IfEqual, DCB_fRtsControl, 00, SetEnv, DCB_fRtsControl, RTS_CONTROL_DISABLE
IfEqual, DCB_fRtsControl, 01, SetEnv, DCB_fRtsControl, RTS_CONTROL_ENABLE
IfEqual, DCB_fRtsControl, 10, SetEnv, DCB_fRtsControl, RTS_CONTROL_HANDSHAKE
IfEqual, DCB_fRtsControl, 11, SetEnv, DCB_fRtsControl, RTS_CONTROL_TOGGLE
DCB_XonLim:=ExtractInteger(DCB, 14, true, 2)
DCB_XoffLim:=ExtractInteger(DCB, 16, true, 2)
DCB_ByteSize:=ExtractInteger(DCB, 18, true, 1)
DCB_Parity:=ExtractInteger(DCB, 19, true, 1)
IfEqual, DCB_Parity, 2, SetEnv, DCB_Parity, Even
IfEqual, DCB_Parity, 3, SetEnv, DCB_Parity, Mark
IfEqual, DCB_Parity, 0, SetEnv, DCB_Parity, None
IfEqual, DCB_Parity, 1, SetEnv, DCB_Parity, Odd
IfEqual, DCB_Parity, 4, SetEnv, DCB_Parity, Space
DCB_StopBits:=ExtractInteger(DCB, 20, true, 1)
IfEqual, DCB_StopBits, 2, SetEnv, DCB_StopBits, 2
IfEqual, DCB_StopBits, 1, SetEnv, DCB_StopBits, 1,5
IfEqual, DCB_StopBits, 0, SetEnv, DCB_StopBits, 1
DCB_XonChar:=ExtractInteger(DCB, 21, true, 1)
DCB_XoffChar:=ExtractInteger(DCB, 22, true, 1)
DCB_ErrorChar:=ExtractInteger(DCB, 23, true, 1)
DCB_EofChar:=ExtractInteger(DCB, 24, true, 1)
DCB_EvtChar:=ExtractInteger(DCB, 25, true, 1)
ch:=DllCall("CloseHandle", "Uint", h)
If (ch = 0 or ErrorLevel != 0)
return, -3
return, 0
}
ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset.
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process
; (since pSource might contain valid data beyond its first binary zero).
{
Loop %pSize% ; Build the integer by adding up its bytes.
result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1)
if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
return result ; Signed vs. unsigned doesn't matter in these cases.
; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
return -(0xFFFFFFFF - result + 1)
}
DecToBin(In_Val)
{
local bit, bin, dec
if In_Val is not integer
return, "ERROR"
dec:=In_Val
Loop
{
bit:=mod(dec, 2)
dec:=dec//2
bin=%bit%%bin%
IfEqual, dec, 0, break
}
return, %bin%
}
msgbox, % GetCommState(4)
listvars
pause
Edit: Changed naming of variables and return values.