Announcement

Collapse
No announcement yet.

Controlling CTS RTS lines on serial ports

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Controlling CTS RTS lines on serial ports

    I have developed a set of programs that will reside on two
    different computers. I need to be able to use the cts/rts lines
    as independent digital signal lines. I do not want the status
    of these lines to affect the transmission of data but to just
    be free toggling lines. Is this possible and if so how do I
    manipulate the lines without having to "close" and re "open" the
    port.

    Thanks for any help
    Dan Symonds


    ------------------

  • #2
    From what I've read in past postings, if I recall correctly, you
    have to directly manipulate the serial port registers programmatically
    (the STATUS registers, maybe?). I have NO idea how to determine
    the memory addresses for these registers, or which bits to manipulate,
    or what they have to be set to to do what. Sorry I couldn't be of
    more help.

    I do not know if it's possible to manipulate those lines without
    affecting the data transmissions.

    ------------------
    Clay C. Clear

    mailto:[email protected][email protected]</A>

    [This message has been edited by Clay Clear (edited August 06, 2002).]

    Comment


    • #3
      Originally posted by Dan Symonds:
      I do not want the status of these lines to affect the
      transmission of data......
      If you don't want hardware flow control, you will have to go to
      software (Xon/Xoff) flow control. Use the following syntax:

      OPEN COMx,9600,n,8,1,rs,cs,ds,cd" as #x

      This will disable both lines. However, if you go this route and
      install the programs in a windows box, you may be looking at
      problems. windows has a tendency of interferring with Xon/Xoff
      flow signals and you may wind up with garbled data at the
      receiving end.


      ------------------


      [This message has been edited by Mel Bishop (edited August 06, 2002).]
      There are no atheists in a fox hole or the morning of a math test.
      If my flag offends you, I'll help you pack.

      Comment


      • #4
        Dan,
        something like this should do the job..

        ComAddr%=&h03f8 'the address of the COM port to use
        OUT ComAddr%+4,2 'set RTS line high (+ve)
        OUT ComAddr%+4,0 'set RTS line low (-ve)

        IF INP(ComAddr%+6) AND 16 THEN CTS%=1 ELSE CTS%=0 'read the CTS line

        Paul.

        Comment


        • #5
          Paul:
          This is exactly what I am looking for. If I set the port as
          "Com1:9600,n,8,1,cs,ds,cd" for example, will using your
          have any effect on the "normal" communications stream?

          Thanks

          ------------------

          Comment


          • #6
            Dan,
            <<will using your have any effect on the "normal" communications stream?>>

            probably not, but the best thing to do is try it and see.
            If it doesn't work then ask Lance to get you the right OPEN COM parameters to ignore the control lines. He'll have them written down somewhere. As long as PB is set to ignore them then there will be no problem.

            Paul.



            ------------------

            Comment


            • #7
              Several years ago, when I used TurboBasic (PB/DOS parent) I encountered some errors on using COMs on specific PCs - I wasn't able to understand the reason. What I did is to write some routines to INP & OUT the UART registers, to perform what I needed. Those routines included Port initialize, Tx and Rx.

              This way, no OPEN statement needed, nor PRINTs or INPUTs. PB/DOS doesn't even know you are using the serial port; if you don't enable the interrupts, neither DOS/Windows knows it. The serial port controller is completely in your hands.

              What follows are the routines to Tx and Rx:
              Code:
              %UartData = 0                 ' Tx / Rx data                        (r/w)
              %UartDivL = 0                 ' baud rate generator, lsb            (r/w)
              %UartDivM = 1                 ' baud rate generator, msb            (r/w)
              %UartIer  = 1                 ' interrupt enable register           (r/w)
              %UartIir  = 2                 ' interrupt identificator register    (r  )
              %UartLcr  = 3                 ' line control register               (r/w)
              %UartMcr  = 4                 ' modem control register              (r/w)
              %UartLsr  = 5                 ' line status register                (r  )
              %UartMsr  = 6                 ' modem status register               (r  )
              %UartScrt = 7                 ' scratch pad register                (r/w)
               
              BaseUart% = 1018              ' COM1 (3F8 hex)
               
              sub InitUart                  ' I hope I didn't forget anything...
              shared BaseUart%
                out BASEuart% + %UartLcr,  131   ' 8 bit, 1 stop, no parity + flag to set baud divisor
                out BASEuart% + %UartDivM,   0   ' )_ 4800 baud
                out BASEuart% + %UartDivL,  24   ' )
                out BASEuart% + %UartLcr,    3   ' 8 bit, 1 stop, no parity 
                out BASEuart% + %UartMcr,    0   ' initial lines status
              end sub
               
              sub TxUart( s$ )          ' string TX
              shared BASEuart%
              local  i%
                for i% = 1 to len( s$ )
                  while ( inp( BASEuart% + %UartLsr ) and 32 ) = 0
                  wend
                  out BASEuart% + %UartData, asc( mid$( s$, i%, 1 ) )
                next i%
              end sub
               
              def fnStsUart%            ' returns 1 if RX caharacter present
              shared BASEuart%
                fnStsUart% = inp( BASEuart% + %UartLsr ) and 1
              end def
               
              def fnRxUart%             ' returns the RX character (to use after StsUart% returned 1)
              shared BASEuart%
                fnRxUart% = inp( BASEuart% + %UartData )
              end def
              The init can be modified to manage the RX FIFO, and the CTS and RTS control lines can be added.

              These routines also worked for a while with PB/DOS. Of course they don't work under Win NT or Win 2k... this is the reason I no longer use them.

              [added later]

              To set the RTS and test the CTS: (I didn't try it...)
              Code:
              def fnUartCTS%          ' returns 1 or 0 depending on CTS status
              shared BASEuart%
                fnUartCTS% = ( INP( BaseUart% + %UartMsr ) and 16 ) \ 16
              end def
               
              sub SetUartRTS( flag% )
              shared BASEuart%
                if flag% <> 0 ten
                  OUT BaseUart% + %UartMcr, INP( BaseUart% + %UartMcr ) or 2
                else
                  OUT BaseUart% + %UartMcr, INP( BaseUart% + %UartMcr ) and 254
                end if
              end sub
              Aldo

              ------------------

              [This message has been edited by Aldo Cavini (edited August 07, 2002).]
              Rgds, Aldo

              Comment


              • #8
                Aldo, Clay and all ..

                One of the reasons I didn't post here is sort of:

                The init can be modified to manage the RX FIFO, and the CTS and RTS
                control lines can be added.

                These routines also worked for a while with PB/DOS. Of course they
                don't work under Win NT or Win 2k... this is the reason I no longer
                use them.
                Nor native OS/2 in the exact same way but different from WIN.

                I did this whole routine with the 8350 UART's back in the days of
                the Heathkit H-89's for specific control of com ports for telegraph
                transmitter control via relays. Of course then came packet and ..
                well never minde. I still have my H-89 by the way. Then came OS/2!

                Well, OS/2's a little more versitile in some ways than WIN-whatever
                of modern form. You still can get at the hardware if you really want
                to do that! But .. as someone once posted to me, Mike, communications
                in OS/2's a whole nother ball game, son!

                It is. And a different one yet for WIN-NT too, so said here and lots
                of other places, which I've not gone into, but is covered by PB in
                more modern forms of compiler interface.

                I know there are a lot of folks exerting visual pressure on Bob and
                the crew for when in PB going to REALLY be available for a new version
                of DOS, and LINUX and ... Well I might want this too!

                But as you are finding out, hitting a moving target for both the
                communications I/O world and video ain't all that easy at the low
                levels needed to make the compiler and its output do the job perfectly
                with just that lowly line or two of source code we take so much for
                granted!

                I've been watching this thread very closely to see exactly what can
                be posted to help you. I want to see exactly what I'd have to do
                with essentially the same assembly language work that's been offered
                to you here already, to cross it over to WIN-NT and so on.

                It almost has to mean there will have to be a separate source code
                technique that you will have to use depending on whether the code
                is running on modern WIN-NT+ boxen or on the old form. Sort of like
                using the 'which are we under' code to determine WIN or DOS for a
                PB 3.5 program running under DOS-VDM's in OS/2 or WIN whatever! Then
                you use different assembler code to switch the time slice releasing
                for keyboard I/O. And you have to use different techniques yet,
                for example, in C++ compilation with Watcomm C++ for cross platform
                work on a sort of common source for DOS/WIN and OS/2 there. It
                actually takes conditional code switching, at least for me, to get
                this going in Watcomm C++. I bet, sort of, that it will take the
                same sort of techniques in the future, to optimize source for
                producing cross platform work for DOS/WIN and LINUX from PB!

                But maybe not, maybe not. Bob and the crew are awfully good!

                I am hoping to see a source code published comparison from the
                assembler to whatever has to be used to do this with WIN-NT+. I
                know these things can be done by specialized work. But I've not
                seen how to do it yet.

                Perhaps some of the development tricks that surely must be at the
                core of the assembler work on PB that is going forward for PB for
                DOS future and LINUX and so on can be posted here.

                While I'm *NOT* asking for release information, it would surely help
                a few people seriously interested in comm port work, both standard
                and USB style, to offer us guidelines on what to expect when!

                OTOH .. I would be completely happy to be told, "MIke, that's one of
                the areas we are still working on .. getting your one line magic to
                work cross platform!" After playing with this in DOS and looking at
                OS/2 ... I'll understand. I'll understand. I also understand exactly
                why Bob wants no code sold before it's time, moving target well known!

                What really could come out of this discussion could sure help with
                planning for the future of communications I/O work with PB, if that
                part of the work has been carefully going on already though...



                ------------------
                Mike Luther
                [email protected]
                Mike Luther
                [email protected]

                Comment


                • #9
                  Aldo's code has a small error in the base address of the COMM port 1.
                  After, and only after, this change the code will indeed output data to COM1.
                  For COM2 use 2F8hex as address

                  Code:
                       BaseUart% = 1018              ' COM1 (3F8 hex)
                  
                  should be:
                       BaseUart% = 1016              ' COM1 (3F8 hex)
                  
                  or even better:
                  
                       BaseUart% = &h03F8     'to use PB's internal recalculation and avoid miscalculations
                  Henk Broekhuizen, PA3BLP
                  powerbasicforum -at- doorhet.net
                  Sexbierum, The Netherlands
                  ========================

                  Comment

                  Working...
                  X