Jump to content

Photo

RS232 Programming


17 replies to this topic

#1 BeeryMiller OFFLINE  

BeeryMiller

    Moonsweeper

  • 309 posts

Posted Wed Jan 10, 2018 10:57 AM

I need some insight to understand a few things.

 

I'm working with the My-Term source code.  I've never been great with the RS232 programming and have always relied on the code of others and their comments to figure out how they were sending and getting characters from the RS232 port.

 

Is there something special with any of the bits programmers are doing to establish Flow Control?  Or is it just a matter of polling the RS232 with enough frequency to capture the characters.

Specifically, I am trying to make sure I do not drop any characters from the RS232 using the Lantronix UDS-10.  I know at both 19.2K and 38.4K I can drop some characters when I am using Telnet to another telnet BBS.  Is there something I can do to prevent those loss of characters?

 

FWIW, I am using the cable specified in Tim's Port document for cable setup.

 

Thanks for any feedback.  

 

Beery

 

 

 



#2 Willsy OFFLINE  

Willsy

    River Patroller

  • 3,062 posts
  • Location:Uzbekistan (no, really!)

Posted Wed Jan 10, 2018 11:18 AM

Can you not use RTS/CTS handshaking? If you have, say a 64 byte receive buffer, you drop CTS when you have, say, 58 characters in the buffer. That way the UDS should stop sending before you overrun your buffer. Response latency of the UDS 10 (i.e. how long it takes to obey your request to stop) will probably be a function of the baud rate.

99% of folk implement RS232 as a three-wire, but it's far better to implement 5 wire (data with RTS/CTS) if you can.

#3 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 557 posts
  • Location:The Great White North

Posted Wed Jan 10, 2018 11:54 AM

Can you not use RTS/CTS handshaking? If you have, say a 64 byte receive buffer, you drop CTS when you have, say, 58 characters in the buffer. That way the UDS should stop sending before you overrun your buffer. Response latency of the UDS 10 (i.e. how long it takes to obey your request to stop) will probably be a function of the baud rate.

99% of folk implement RS232 as a three-wire, but it's far better to implement 5 wire (data with RTS/CTS) if you can.

 

 

The hardware handshakes are ideal until you discover you are communicating with a system that is slow to recognize them.

 

I have had that happen in the old days.



#4 apersson850 OFFLINE  

apersson850

    Moonsweeper

  • 486 posts

Posted Wed Jan 10, 2018 11:55 AM

He would still have to transfer the data from the UART (or ACC by TI) to the buffer frequently enough to avoid data loss.



#5 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,069 posts
  • Location:Germany

Posted Wed Jan 10, 2018 12:20 PM

From my page on ninerpedia:

 

Software handshaking is within the responsibility of the applications that use the serial connection; it is implemented by sending control bytes (X-ON, X-OFF) over the data line.

Hardware handshaking is possible at two levels:

  •     using RTS and CTS,
  •     using DTR and DSR.

The difference between both is that RTS/CTS handshaking has immediate effect on the transmission of the UART (a cleared CTS line turns off the transmitter of the UART) while DTR/DSR are handled by interrupts that are signaled to the application.



#6 BeeryMiller OFFLINE  

BeeryMiller

    Moonsweeper

  • Topic Starter
  • 309 posts

Posted Wed Jan 10, 2018 12:50 PM

From my page on ninerpedia:

 

Software handshaking is within the responsibility of the applications that use the serial connection; it is implemented by sending control bytes (X-ON, X-OFF) over the data line.

Hardware handshaking is possible at two levels:

  •     using RTS and CTS,
  •     using DTR and DSR.

The difference between both is that RTS/CTS handshaking has immediate effect on the transmission of the UART (a cleared CTS line turns off the transmitter of the UART) while DTR/DSR are handled by interrupts that are signaled to the application.

 

Let's explore this comment a bit further.  As my intentions are for Telnetting purposes with the potential one could either be using the Lantronix UDS-10 or the Wifi2Modem, which method (RTS/CTS or DTR/DSR) would be preferred with a reasonable expectation no characters would be lost?  I assume this is setting a bit on the RS232?

 

Listed below is the RS232 code MyTerm is using.  Can someone comment what would need to be changed?  There is an approximate 8K circular buffer as is right now and I see some places in the program I can speed up character acquisition.

 

Any thoughts appreciated.

 

 

*

* INIT     Initialize RS232
*
 
INIT0  MOV  @CRUBAS,R12  Get CRU base
       LIMI 0            No interrupts
       SBO  0            Turn on RS232 card
       MOV  R12,R9       Save CRU base
       MOV  @PORTDT,R12  Get port address
 
       SBO  31           Start initialization
       LI   R0,>20       Delay counter
INIT1  DEC  R0           Waste time
       JNE  INIT1        Keep waiting
 
       SBZ  13           Start data initialization
       MOV  @PARIDT,R1   Get parity data
       LDCR R1,8         Set parity
       MOV  @BAUDDT,R1   Get baud rate data
       LDCR R1,12        Set baud rate
 
       MOV  R9,R12       Get CRU base
       SBZ  0            Turn off RS232 card
       RTWP              Return to caller
 
 
*
* GETRS    Get a Character from the RS232 Port
*
 
GETRS0 LIMI 0            No interrupts
       BL   @GETRS1      Do routine
       RTWP              Return to caller
 
GETRS1 MOV  @CRUBAS,R12  Get CRU base
       SBO  0            Turn on RS232 card
       MOV  R12,R9       Save CRU base
       MOV  @PORTDT,R12  Get port address
 
       TB   21           Is a character waiting?
       JNE  GETRS3       No, Return to caller
 
       STCR R10,8        Yes, Get character
       SBZ  18           Tell RS232 we have it
       ANDI R10,>7F00    Strip off high bit
       MOV  @CPOINT,R8   Get buffer pointer
       MOVB R10,*R8+     Store character
       CI   R8,>6000     End of memory?
       JL   GETRS2       No, Skip this
       LI   R8,BUFF      Loop to start of buffer
 
GETRS2 MOV  R8,@CPOINT   Store buffer pointer
       SETO @CFLAG       Set buffer flag
 
GETRS3 MOV  R9,R12       Get CRU base
       SBZ  0            Turn off RS232 card
       RT                Return to caller
 
 
*
* ECHO     Echo a Character Over RS232 Port
*
 
ECHO0  MOV  @PORTDT,@RTSVPT   Save port address
 
ECHO0A MOVB *R13,R0           Get character
       MOV  @PORTDT,R12       Get port address
       ANDI R12,>FF00         Get CRU base
       LIMI 0                 No interrupts
       SBO  0                 Turn on RS232 card
       MOV  R12,R9            Save CRU base
       MOV  @PORTDT,R12       Get port address
       SBO  16                Start character send
 
ECHO1  TB   22                Is RS232 ready?
       JNE  ECHO1             No, Keep waiting
 
       LDCR R0,8              Yes, Send character
       SBZ  16                Tell RS232 we're ready
       MOV  R9,R12            Get CRU base
       SBZ  0                 Turn off RS232 card
       MOV  @RTSVPT,@PORTDT   Restore port address
       RTWP                   Return to caller
 


#7 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,069 posts
  • Location:Germany

Posted Wed Jan 10, 2018 2:08 PM

I found it really enlightening to read the 9902 specification: ftp://ftp.whtech.com/datasheets%20and%20manuals/Datasheets%20-%20TI/TMS9902_dataSheet_Jan77.pdf

 

It was this manual that made me understand the RS232 chip operation for the first time.



#8 BeeryMiller OFFLINE  

BeeryMiller

    Moonsweeper

  • Topic Starter
  • 309 posts

Posted Wed Jan 10, 2018 4:12 PM

Thanks for that reference.  That is the first time I have ever seen that datasheet.

Beery



#9 BeeryMiller OFFLINE  

BeeryMiller

    Moonsweeper

  • Topic Starter
  • 309 posts

Posted Wed Feb 21, 2018 6:12 AM

I'm making some headway as of last night with the RTS/CTS handshaking.  Still not quite getting what I want, but a lot closer.  I did determine why my 38.4K baud transfers were failing with the addition of some inline error reporting and have been successful at versions of MDOS with a few temporary fixes.  What I need now is a short hex to decimal display routine shorter than the one I am using.  That will fix one issue and show the progress of the file transfer with a counter.

 

Beery



#10 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 557 posts
  • Location:The Great White North

Posted Wed Feb 21, 2018 9:58 AM

I'm making some headway as of last night with the RTS/CTS handshaking.  Still not quite getting what I want, but a lot closer.  I did determine why my 38.4K baud transfers were failing with the addition of some inline error reporting and have been successful at versions of MDOS with a few temporary fixes.  What I need now is a short hex to decimal display routine shorter than the one I am using.  That will fix one issue and show the progress of the file transfer with a counter.

 

Beery

 

Is there a specific reason yo use 38.4k?

 

In my experience that is a pretty fast data rate for a slow machine.  Without a interrupt driven receive I would think you would do better down at 9600 or below with a machine like the TI-99.



#11 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 557 posts
  • Location:The Great White North

Posted Wed Feb 21, 2018 10:06 AM

 

Let's explore this comment a bit further.  As my intentions are for Telnetting purposes with the potential one could either be using the Lantronix UDS-10 or the Wifi2Modem, which method (RTS/CTS or DTR/DSR) would be preferred with a reasonable expectation no characters would be lost?  I assume this is setting a bit on the RS232?

 

Listed below is the RS232 code MyTerm is using.  Can someone comment what would need to be changed?  There is an approximate 8K circular buffer as is right now and I see some places in the program I can speed up character acquisition.

 

Any thoughts appreciated.

 

 

Also when looking at your buffer code, I think you can replace 4 instructions with 1 AND immediate  instruction if you make your buffer size a power of 2.

* Original code
       MOV  @CPOINT,R8   Get buffer pointer
       MOVB R10,*R8+     Store character
       CI   R8,>6000     End of memory?
       JL   GETRS2       No, Skip this
       LI   R8,BUFF      Loop to start of buffer
* possible (un-tested) replacement code for
* buffer wrapping
* Assumes buffer is >2000 bytes in size

       MOVB R10,*R8+     Store character
       AI   R8,>1FFF        binary wrap R8

Edited by TheBF, Wed Feb 21, 2018 10:08 AM.


#12 --- Ω --- OFFLINE  

--- Ω ---

    --- Ω ---

  • 11,678 posts
  • Location:워싱턴 주

Posted Wed Feb 21, 2018 10:06 AM

 

Is there a specific reason yo use 38.4k?

 

In my experience that is a pretty fast data rate for a slow machine.  Without a interrupt driven receive I would think you would do better down at 9600 or below with a machine like the TI-99.

 

 

 

Pushing the limits and finding out first-hand 'what can be' is a common human trait.  With that in mind, faster could be a reason in itself.

 



#13 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 557 posts
  • Location:The Great White North

Posted Wed Feb 21, 2018 10:28 AM

 

 

Pushing the limits and finding out first-hand 'what can be' is a common human trait.  With that in mind, faster could be a reason in itself.

 

 

:) I will accept that as a noble goal.

 

With serial communication I lean toward reliability over absolute speed so I am biased.



#14 BeeryMiller OFFLINE  

BeeryMiller

    Moonsweeper

  • Topic Starter
  • 309 posts

Posted Wed Feb 21, 2018 12:16 PM

 

:) I will accept that as a noble goal.

 

With serial communication I lean toward reliability over absolute speed so I am biased.

 

I've got a couple of purposes here.  One, I am wanting to get the maximum reliable transfer speed.  I know 38.4K is possible, because Tim has done it.  Once I have that part completed and I am satisfied I can sustain those transfer rates, I want to add multi-file transfer capability.  That way, I can backup the Geneve to a BBS area or to an emulated MAME image of a Geneve running on another computer and not have much to worry about a hard drive crash or other equipment failure. File transfers at 38.4K will be 4 times quicker than a 9600 baud transfer.



#15 BeeryMiller OFFLINE  

BeeryMiller

    Moonsweeper

  • Topic Starter
  • 309 posts

Posted Wed Feb 21, 2018 12:35 PM

 

 

Also when looking at your buffer code, I think you can replace 4 instructions with 1 AND immediate  instruction if you make your buffer size a power of 2.

* Original code
       MOV  @CPOINT,R8   Get buffer pointer
       MOVB R10,*R8+     Store character
       CI   R8,>6000     End of memory?
       JL   GETRS2       No, Skip this
       LI   R8,BUFF      Loop to start of buffer
* possible (un-tested) replacement code for
* buffer wrapping
* Assumes buffer is >2000 bytes in size

       MOVB R10,*R8+     Store character
       AI   R8,>1FFF        binary wrap R8

 

Interesting idea.  I'm going to have to think on this one a bit more.  Actually, my buffer is < 8K as it is whatever space is left between my program space up to >6000.  Right now, the program ends at either >5100 or around >5500.  I need to check the GenLink statement to see if the value it is reporting the code file size, or end of the file of file size + >0400 for the start of the program.  As I add more code, that buffer gets smaller.

 

MyTerm uses other 8K pages for logging buffer, screen buffers.  Within the code/program space, I have buffers for the ANSI character definitions from 128 to 255 and space for a reverse video character definition so that text can be highlighted for Menus.  I may be able to drop/move those storage buffers into another video page.  Come to think of it, I may be able to do the same thing with the phone directory listing as well.

 

I remember years ago I asked Ron Walters how he was able to do some screen pop-ups so quickly.  He had repetitive MOVB *R1+,*R2+ (16X, 32X, or 64X) instructions so there was minimal looping.  All, just video moves.  Made a huge difference in speed.

 

Beery



#16 InsaneMultitasker OFFLINE  

InsaneMultitasker

    Stargunner

  • 1,959 posts

Posted Thu Feb 22, 2018 1:08 PM

Which method are you currently using to receive characters - polling or interrupt?  

 

At 38.4Kbps maximum throughput you need to be able to receive at approximately 3,840 characters/second.  Your rendering routine needs to be able to display (or process, in the case of escape sequences) at a decent speed to minimize buffer overflows and lost characters.  If your display/processing is slower than the character reception routine, you will eventually hit the wall.  TIMXT (the TI f18a terminal emulator) uses a 4K circular buffer which is a reasonably good size at 38.4k, though it still drops characters for long displays or complicated ANSI processing.

 

One thing I notice about your routine is that it has no apparent overflow protection.  If your buffer wraps before you can display what is in the buffer, you will lose the entirety of what is there when the pointer wraps.  To avoid this you can check/track the buffer position or keep track of how many characters are in the buffer, and then decide if you want to ignore any received characters when the buffer is full. 



#17 --- Ω --- OFFLINE  

--- Ω ---

    --- Ω ---

  • 11,678 posts
  • Location:워싱턴 주

Posted Thu Feb 22, 2018 1:13 PM

A version for the SAMS might eliminate the buffer overflow issues.  ;)  Even using a small part of it, 48K, 64K or a 96K scroll back buffer would be awesome!



#18 BeeryMiller OFFLINE  

BeeryMiller

    Moonsweeper

  • Topic Starter
  • 309 posts

Posted Thu Feb 22, 2018 3:12 PM

The code I am using was originally from MyTerm and no overflow protection as you mentioned was present.  At the 2400 to 9600 baud rates back then, and no ANSi, I do not think overflows were much of a concern.  At these higher rates, they are.  As such, I believe I am going to have to modify some buffers from their 8K capacity to something along the 4K size.  I will have to step carefully with that part as there are some hard coded addresses I will need to make sure I catch.

 

Right now, I am strictly polling.  I have not went back to the interrupt driven code yet.  I wrapped up the phone dialer portion of the code, and added TIm's ANSI character definitions from 128 to 255.  That gives me some nicer displays on my BBS.  There was a start on the ANSI sequences by Riccio on the original code, but he just layed the initial groundwork with the control and escape sequences or VT-52 that I can then build upon for the ANSI work.  The first thing I need to do is make sure I capture correctly the ANSI detect sequence and give it a proper response before I build any further.  I've played with that a bit, but not sure if I am losing a byte when I first connect, or I am not terminating the response correctly. 

 

Either way, my focus now has been to resolve the Xmodem transfer issue at 38.4K.  With minimal feedback to the screen, I can sustain for about 200 sectors the transfer of MDOS.  Eventually, at about 75% of the time, I get an overflow on the RS232 port bringing it to a halt on large files.  As I sit here writing this, it just made me think about something I saw in one of the original video routines I questioned to myself last night.  I may need to comment out a line and that may resolve the overflow issue and allow things to sync back up.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users