 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
olfen
Joined: 04 Jun 2005 Posts: 99 Location: Stuttgart, Germany
|
Posted: Thu May 25, 2006 3:16 pm Post subject: DllCall to GetCommState |
|
|
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.
Last edited by olfen on Fri May 26, 2006 11:55 am; edited 2 times in total |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10464
|
Posted: Fri May 26, 2006 12:27 am Post subject: |
|
|
| Nice-looking script. I like how you documented the complete structure and the purpose of each of its members. |
|
| Back to top |
|
 |
olfen
Joined: 04 Jun 2005 Posts: 99 Location: Stuttgart, Germany
|
Posted: Fri May 26, 2006 9:30 am Post subject: |
|
|
| Quote: |
I like how you documented the complete structure and the purpose of each of its members. |
I have to disappoint you. It is extracted from Winbase.h .
Meanwhile, I also got BuildCommDCB and SetCommState working and am looking forward to posting it after further testing.
Browsing MSDN I stumbled across WaitCommEvent:
| Quote: |
The WaitCommEvent function waits for an event to occur for a specified communications device. The set of events that are monitored by this function is contained in the event mask associated with the device handle.
The WaitCommEvent function should be executed as an overlapped operation so the other threads of the process can perform I/O operations during the wait.
|
Can it be "executed as an overlapped operation" in AutoHotkey?
Would this make it possible to have a rudimentary serial terminal? |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10464
|
Posted: Sat May 27, 2006 1:01 am Post subject: |
|
|
| olfen wrote: | | Can [WaitCommEvent] be "executed as an overlapped operation" in AutoHotkey? Would this make it possible to have a rudimentary serial terminal? | I don't know enough about it to give a useful answer. Maybe someone else here knows. |
|
| Back to top |
|
 |
wisely Guest
|
Posted: Sun Oct 14, 2007 2:27 am Post subject: |
|
|
| Quote: | I also got BuildCommDCB and SetCommState working and am looking forward to posting it after further testing.
Browsing MSDN I stumbled across WaitCommEvent: |
olfen, please i would like to know when you are going to post your working BuildCommDCB and SetCommState functions
And thanks for the GetCommState function |
|
| Back to top |
|
 |
olfen
Joined: 04 Jun 2005 Posts: 99 Location: Stuttgart, Germany
|
Posted: Sun Oct 14, 2007 9:35 am Post subject: |
|
|
Sorry, I had forgotten about it. I cannot remember, if this snippet works ok. Please test. | Code: | #NoEnv
; http://msdn2.microsoft.com/en-us/library/aa363214.aspx
VarSetCapacity(DCB, 28)
; http://msdn.microsoft.com/library/en-us/devio/base/buildcommdcb.asp
; The string must have the same form as the mode command's command-line arguments:
; COMx[:][baud=b][parity=p][data=d][stop=s][to={on|off}][xon={on|off}][odsr={on|off}][octs={on|off}][dtr={on|off|hs}][rts={on|off|hs|tg}][idsr={on|off}]
mode = COM1:baud=9600 parity=N data=8 stop=1
DllCall("BuildCommDCB", "str",mode, "uint",&DCB)
; http://msdn2.microsoft.com/en-us/library/aa363858.aspx
hCOMM := DllCall("CreateFile", "Str","COM1:" ,"Uint",0x80000000, "Uint",3, "UInt",0, "UInt",3, "Uint",0, "UInt",0)
; http://msdn2.microsoft.com/en-us/library/aa363436.aspx
DllCall("SetCommState", "Uint",hCOMM, "uint",&DCB)
DllCall("CloseHandle", "Uint",hCOMM) |
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|