News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

RS232 port init

Started by katvis, March 13, 2011, 10:22:14 PM

Previous topic - Next topic

katvis

Hi guys
I am trying to setup a RS232 port but do not manage yet, any advise please?
Below is the results from a port monitor, I need to turn the RTS and DTR lines off?


<00:11:31.178 SYS>
COM port is opened
<00:11:31.178 SYS>
In/out queue size 20000/20000
<00:11:31.178 SYS>
Purge the serial port: RXCLEAR, TXCLEAR
<00:11:31.178 SYS>
Baud rate 9600
<00:11:31.178 SYS>
RTS on
<00:11:31.178 SYS>
DTR on
<00:11:31.178 SYS>
Data bits=8, Stop bits=1, Parity=Even
<00:11:31.178 SYS>
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x00, Xoff=0x00
<00:11:31.178 SYS>
Handflow: ControlHandShake=(DTR_CONTROL), FlowReplace=(TRANSMIT_TOGGLE, RTS_CONTROL), XonLimit=0, XoffLimit=0
<00:11:32.790 SYS>
COM port is closed

Here is my init data for bitrecord:


;BITRECORD RECORD fBinary:1,fParity:1,fOutxCtsFlow:1,fOutxDsrFlow:1,fDtrControl:2,fDsrSensitivity:1,fTXContinueOnXoff:1,fOutX:1,fInX:1,fErrorChar:1,fNull:1,       fRtsControl:2,fAbortOnError:1,fDummy2:17
message BITRECORD <TRUE,FALSE, 0, 0, DTR_CONTROL_DISABLE, 0, TRUE, 0, 0, 0, 0, RTS_CONTROL_DISABLE, 0, 0>

If I change anything in this init line I can see the result with the following command:
                  mov eax, message

but the changes does not reflect in the port monitor?



clive

Quote from: katvis on March 13, 2011, 10:22:14 PM
Hi guys
I am trying to setup a RS232 port but do not manage yet, any advise please?
Below is the results from a port monitor, I need to turn the RTS and DTR lines off?

Perhaps you just aren't getting the DCB structure set up properly, but you haven't provided a sufficiently complete example to even guess at what's wrong.
It could be a random act of randomness. Those happen a lot as well.

katvis

At the moment I am not trying to do anything fancy yet, what I mean with that is that I am first trying to "hard code" the startup parameters that I want to see, later if this work I will try and code to switch DTR on/off in the code for example.

For now I am trying to place the values I want to see in the port monitor, like DTR=OFF, in the start up structure, I hope this make sense?

So after reading through a few threads describing how the DCB structure works and also explaining the fBits I think I now understand how this works, but I need to test it.


So in the windows.inc file the BITRECORD (fbits) and DCB structure are defined as follows:


BITRECORD RECORD fBinary:1,fParity:1,fOutxCtsFlow:1,fOutxDsrFlow:1,fDtrControl:2,fDsrSensitivity:1,fTXContinueOnXoff:1,fOutX:1,fInX:1,fErrorChar:1,fNull:1,fRtsControl:2,fAbortOnError:1,fDummy2:17

DCB STRUCT
  DCBlength   DWORD        ?
  BaudRate    DWORD        ?
  fbits           BITRECORD  <>
  wReserved  WORD          ?
  XonLim       WORD          ?
  XoffLim       WORD          ?
  ByteSize      BYTE           ?
  Parity          BYTE           ?
  StopBits      BYTE           ?
  XonChar      BYTE           ?
  XoffChar      BYTE           ?
  ErrorChar     BYTE           ?
  EofChar       BYTE           ?
  EvtChar       BYTE           ?
  wReserved1    WORD      ?
DCB ENDS

And from the MASM manual:
MASK and WIDTH.
.DATA
COLOR RECORD blink:1, back:3, intense:1, fore:3
message COLOR <1, 5, 1, 1>
wblink EQU WIDTH blink ; "wblink" = 1
wback EQU WIDTH back ; "wback" = 3
wintens EQU WIDTH intense ; "wintens" = 1
wfore EQU WIDTH fore ; "wfore" = 3
wcolor EQU WIDTH COLOR ; "wcolor" = 8
.CODE
.
.
.
mov ah, message ; Load initial 1101 1001
and ah, NOT MASK back ; Turn off AND 1000 1111
; "back" ---------
; 1000 1001
or ah, MASK blink ; Turn on OR 1000 0000
; "blink" ---------
; 1000 1001
xor ah, MASK intense ; Toggle XOR 0000 1000
; "intense" ---------
; 1000 0001
IF (WIDTH COLOR) GT 8 ; If color is 16 bit, load
mov ax, message ; into 16-bit register
ELSE ; else
mov al, message ; load into low 8-bit register
xor ah, ah ; and clear high 8-bits
ENDIF


So if I understand correctly there are 32 bits in the BITRECORD RECORD and if I want to setup or change this RECORD I have to move the record in a message?

If I do not place any value in the BITRECORD but compile the code as is I assume the default values are accepted which is DTR=on.

My question thus is, if I want to compile the code with DTR=off how do I go about?

I have tried to place this line in the .DATA section:

message BITRECORD <TRUE, FALSE, 0, 0, DTR_CONTROL_DISABLE, 0, TRUE, 0, 0, 0, 0, RTS_CONTROL_DISABLE, 0, 0>

but it made no difference to the DTR startup status. I do not know if there is some more actions to be taken apart from this line to get this settings activated?

and this is the line which I am using to apply the settings?

                  invoke SetCommState, FileHndle, offset dcb    ; Apply the new settings

I hope this makes more sense?
thanx again

katvis


katvis

ok, found the answer, thanks anyway

mov  dcb.fbits, BITRECORD<\
TRUE,\   ; fBinary:1
FALSE,\   ; fParity:1
FALSE,\   ; fOutxCtsFlow:1
FALSE,\   ; fOutxDsrFlow:1
DTR_CONTROL_DISABLE,\   ; fDtrControl:2
FALSE,\   ; fDsrSensitivity:1
TRUE,\   ; fTXContinueOnXoff:1
FALSE,\   ; fOutX:1
FALSE,\   ; fInX:1
TRUE,\   ; fErrorChar:1
FALSE,\   ; fNull:1
RTS_CONTROL_DISABLE,\   ; fRtsControl:2
FALSE,\   ; fAbortOnError:1
NULL>   ; fDummy2:17

clive

You would be well advised to read the current DCB (GetCommState), modify the settings, and then write it back with SetCommState.

You can use the EscapeCommFunction to control the RTS and DTR pins.
It could be a random act of randomness. Those happen a lot as well.

dedndave

back in the days of 16-bit code, i used to be able to create an interrupt handler to detect changes on input pins
it would be nice to know how to do something similar in win 32
it needs to be "right-now" reaction, to use it the way i want - like interrupts
i suppose there is some way to trap the events

katvis

clive thank you very much for this.

I use two different port monitors and both show that the SetCommState does not change the settings. If I monitor the DCB structure in Ollydbg it shows correclty, by that I mean the dcb structure shows correctly and also the fbits value shows correctly according to my settings, also when SetCommState executes it gives a TRUE result which say to me it was successfu,l yet the results in the portmonitors shows differently.


SetSettings:   

                INVOKE    GetCommState,FileHndle,offset dcb ; fill it with the current settings
                                         mov     dcb.DCBlength,sizeof DCB         ; configure the Settings variable                         
mov     dcb.BaudRate,CBR_9600   
mov     dcb.ByteSize,8                        ;
                                         mov     dcb.Parity,EVENPARITY
                                         mov     dcb.StopBits,0                        ; 
mov     dcb.XonLim,0
mov     dcb.XoffLim,0
mov     dcb.XonChar,0
mov     dcb.XoffChar,0

mov     dcb.fbits, BITRECORD<\
TRUE,\    ; fBinary:1
FALSE,\   ; fParity:1
FALSE,\   ; fOutxCtsFlow:1
FALSE,\   ; fOutxDsrFlow:1
DTR_CONTROL_ENABLE,\   ; fDtrControl:2
TRUE,\    ; fDsrSensitivity:1
TRUE,\    ; fTXContinueOnXoff:1
TRUE,\    ; fOutX:1
TRUE,\    ; fInX:1
TRUE,\    ; fErrorChar:1
FALSE,\   ; fNull:1
RTS_CONTROL_ENABLE,\   ; fRtsControl:2
FALSE,\   ; fAbortOnError:1
NULL>     ; fDummy2:17

invoke SetCommState, FileHndle, offset dcb    ; Apply the new settings
                                         ret


This is my call function to set up or change the COMM properties

and this the result in the portmonitor:

<18:30:28.790 SYS>
COM port is opened
<18:30:28.790 SYS>
In/out queue size 20000/20000
<18:30:28.790 SYS>
Purge the serial port: RXCLEAR, TXCLEAR
<18:30:28.790 SYS>
Baud rate 9600
<18:30:28.790 SYS>
RTS off
<18:30:28.790 SYS>
DTR off
<18:30:28.790 SYS>
Data bits=8, Stop bits=1, Parity=Even
<18:30:28.790 SYS>
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x00, Xoff=0x00
<18:30:28.790 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=0, XoffLimit=0
<18:30:29.581 SYS>
COM port is closed





It did work when I use EscapeCommFunction, thank you.


dedndave

i found it....

WaitCommEvent

redskull

The order of the fbits record is reverse what it should be.  MASM treats 'records' in reverse order than C.  It's a known 'quirk'

BITRECORD RECORD fDummy2:17,fAbortOnError:1,fRtsControl:2,fNull:1,fErrorChar:1,fInX:1,fOutX:1,fTXContinueOnXoff:1,fDsrSensitivity:1,fDtrControl:2,fOutxDsrFlow:1,fOutxCtsFlow:1,fParity:1,fBinary:1
Strange women, lying in ponds, distributing swords, is no basis for a system of government

katvis

thank you very much, I reversed the order in my windows.inc file and also the order in the record, works like a charm now..;)



mov     dcb.fbits, BITRECORD<\
NULL,\     ; fDummy2:17
FALSE,\    ; fAbortOnError:1
RTS_CONTROL_DISABLE,\   ; RTS_CONTROL
FALSE,\    ; fNull:1
FALSE,\    ; ERROR_CHAR
FALSE,\    ; AUTO_RECEIVE
FALSE,\    ; AUTO_TRANSMIT
TRUE,\     ; XOFF_CONTINUE
FALSE,\    ; DSR_SENSITIVITY
DTR_CONTROL_DISABLE,\
FALSE,\    ; DSR_HANDSHAKE
FALSE,\    ; CTS_HANDSHAKE
FALSE,\    ; fParity:1
TRUE>      ; fBinary:1



now another question please, how can I change the value in the record easy please? say change the DTR_CONTROL_DISABLE to DTR_CONTROL_ENABLE without the above mov instruction? that is change only one value at a time ?


redskull

You have to do it all with logic operations, coupled with the MASK operator and bit positions.  This is off the top of my head:

mov eax, dcb.fbits                           ; get current values
and eax, NOT MASK fDtrControl                ; zero out the two values to change
mov ecx, DTR_CONTROL_ENABLE SHL fDtrControl  ; create a bitmask of the value we want
or  eax, ecx                                 ; alter the values
mov dcb.fbits, eax                           ; restore to structure


-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

katvis

perfect thank you..;)
page 160 of MASM manual.
Cheers

dedndave

XOR will work   :P
you should be able to toggle one or more bits with one instruction

redskull

Quote from: dedndave on March 16, 2011, 11:42:53 PM
XOR will work   :P
you should be able to toggle one or more bits with one instruction

fDtrControl is multiple bits with three different states, so there is no "toggling".  But for the one bit ones, yes:


or dcb.fbits, MASK fParity  ; set
and dcb.fbits, NOT MASK fParity  ; clear
xor dcb.fbits, MASK fParity ; toggle 


-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government