RS232... here goes!

For discussing the 65xx hardware itself or electronics projects.
User avatar
banedon
Posts: 742
Joined: 08 Sep 2013
Location: A missile silo somewhere under southern England

Re: RS232... here goes!

Post by banedon »

Here's an oddity: I've had a book called Microprocessor System Design by Michael Spinks since the 1990s. It says (on page 23) that +12V is HI and -12V is LOW for RS232. Has this ever been true?
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: RS232... here goes!

Post by floobydust »

BigDumbDinosaur wrote:
floobydust wrote:
JP3 just allows me to place the 6551 interrupt to either the CPU IRQ or NMI (did the same for the 65C22 on the same PCB). The diode is not needed... I was thinking that WDC might have made the IRQ output drive on later chips similar to the newer style W65C22. If I were to redo the board again, I wouldn't bother with JP3.
I was wondering about the diode, which would not have worked as expected.
I have 3 board sets with the diode and jumper installed and they've been working fine for 2+ years now, so I'm not sure what you're hinting to.
User avatar
MichaelM
Posts: 761
Joined: 23 Apr 2012
Location: Huntsville, AL

Re: RS232... here goes!

Post by MichaelM »

banedon wrote:
Here's an oddity: I've had a book called Microprocessor System Design by Michael Spinks since the 1990s. It says (on page 23) that +12V is HI and -12V is LOW for RS232. Has this ever been true?
The RS-232 interface standard typically operated with transmitted signalling levels of +12V and -12V. The receivers have always had threshold levels near +3V and -3V. This means that at the receive end of an RS-232 interface, a signal greater than +3V will be interpreted as a "mark" and a signal less than -3V will be interpreted as a "space". On the logic side of the RS-232 transmitters and receivers, a "mark" level is associated with a logic 0 signal, and a "space" level is associated with a logic 1 signal.

The transmit data idle signal level from a standard UART is a logic 1. With the inherent inverter in the RS-232 driver, the idle signal level of an RS-232 output is -12V, i.e. "space". Because of the inherent inversion in the RS-232 drivers and receivers, the modem control signals such as DTR (Data Terminal Ready), RTS (Ready to Send), CTS (Clear To Send), DSR (Data Set Ready), DCD (Data Carrier Detect), and RI (Ring Indicate) are inverted coming out of or into the UART. Thus, when these signals are asserted, their RS-232 levels must be greater than +3V.

For many years, RS-232 connected pointing devices such as mice have been powered from the RS-232 DTR signal. When the port is opened, the device driver generally sets DTR to a logic 1. It is inverted on its way out of the UART so it arrives as a logic 0 at the logic side of the RS-232 driver, which in turn inverts it again and drives it to a signal level that is typically between +6V and +12V. it is from this positive signal level the logic of the mouse is powered.

Most RS-232 transceivers manufactured today utilize a charge pump instead of operating from triple supplies: +5V (logic) and ±12V. The charge pump circuits boost (double) the logic supply voltage to between +6V (+3.3V logic) and +10V (+5V logic) and inverts that doubled voltage to get the required negative supply which will typically range between -6V and -10V.

Mr. Spinks was making some simplifying statements in his description of the characteristics of RS-232 signals. RS-232 signal levels are a bit more complex. But the amazing thing to me is how well the interface was conceptualized so many years ago so that we are able to still use it effectively today. I have my doubts about the longevity of many of the other standards such as USB that we use everyday.
Michael A.
User avatar
banedon
Posts: 742
Joined: 08 Sep 2013
Location: A missile silo somewhere under southern England

Re: RS232... here goes!

Post by banedon »

floobydust wrote:
JP3 just allows me to place the 6551 interrupt to either the CPU IRQ or NMI (did the same for the 65C22 on the same PCB). The diode is not needed... I was thinking that WDC might have made the IRQ output drive on later chips similar to the newer style W65C22. If I were to redo the board again, I wouldn't bother with JP3.
Is the diode for older open drain style 6551s so that you cab make it non-open driain (using a pull-up resistor elsehwhere)?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: RS232... here goes!

Post by GARTHWILSON »

WDC's data sheet says the IRQ\ output is open-drain; so you'll need a pull-up resistor.

I like to leave the choice for a '22 VIA to be on either NMI\ or IRQ\, but I can't think of any reason you would ever want the '51 ACIA on NMI\.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: RS232... here goes!

Post by BigDumbDinosaur »

floobydust wrote:
BigDumbDinosaur wrote:
floobydust wrote:
JP3 just allows me to place the 6551 interrupt to either the CPU IRQ or NMI (did the same for the 65C22 on the same PCB). The diode is not needed... I was thinking that WDC might have made the IRQ output drive on later chips similar to the newer style W65C22. If I were to redo the board again, I wouldn't bother with JP3.
I was wondering about the diode, which would not have worked as expected.
I have 3 board sets with the diode and jumper installed and they've been working fine for 2+ years now, so I'm not sure what you're hinting to.
Let me slightly rephrase: it may not work as expected.

According the WDC data sheets, the MPU's /IRQ input should be sunk to at least Vcc × 0.2 when an interrupt occurs, which in a 5 volt system would be 1 volt maximum. The 65C51 can pull its /IRQ output down to approximately 0.4 volts, assuming the current being sunk is no more than about 1.6 ma. However, that value is quoted with Vcc = 4.75, not 5 volts, so it can't be depended on in all cases.

The forward drop of a 1N4148 in this type of circuit will typically be 0.6 to 0.7 volts, but could go higher, depending on operating temperature. Hence when the 65C51 asserts /IRQ the MPU will likely see 1.0 volt at /IRQ, which is on the ragged edge of not being a valid low.

You should use a small signal Schottky diode in this application, most of which have a forward drop of no more than 0.4 volts at maximum rated current. For example, an NXP BAT85 has a forward drop of 320 millivolts at 1.0 ma with a junction temperature of 25° C. Even at 10 ma, the forward drop is only 400mv. With such a diode and assuming a 3.3K pullup, /IRQ at the MPU would be sunk to 720mv, well within spec.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: RS232... here goes!

Post by BigDumbDinosaur »

GARTHWILSON wrote:
...but I can't think of any reason you would ever want the '51 ACIA on NMI\.
Ditto on that.

If a UART (any, not just the 6551) is connected to /NMI, some interesting programming problems arise. The basic issue is that /NMI is edge-sensitive, and hence multiple interrupts cannot be detected. Since any UART operating in interrupt-driven mode can potentially generate coincidental interrupts, the potential exists for one of the interrupts to be missed. If the missed interrupt is caused by RxD, an incoming byte could be left behind, causing an overrun error. If TxD has interrupted coincidentally to or very shortly after RxD, /NMI may be permanently held down by the transmitter, eventually causing the system to deadlock.

A hardware design maxim has always said that /NMI should be reserved for one high-priority event. I recommend that you heed that maxim and save yourself more than a little grief.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
banedon
Posts: 742
Joined: 08 Sep 2013
Location: A missile silo somewhere under southern England

Re: RS232... here goes!

Post by banedon »

I've finally gotten around to wiring in the WDC 65C51N and Max238.
I've got to work out how to program it, but I think I'll start off by trying a loop which just keeps sending a character pattern then see if I can pick it up on my PC using PuTTY.
Time to play! :mrgreen:.
IMG_4495.JPG
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: RS232... here goes!

Post by floobydust »

Congrats on getting everything up and running!

The 65C51 is generally simple to program (look at the 65C02 mini BIOS I posted a while back), but if you have the new WDC 65C51, it likely has the xmit status bit defect and you'll need to provide a timing delay on sending data. As the xmit status bit is stuck on, you can't use it to determine when the transmitter is ready to send another byte. Depending on your data rate, you'll need to adjust the timing delay to wait long enough before sending another byte. I posted code in another thread here over a year ago on making it work. Receive on the other hand works perfectly fine and can be used with interrupt-driven code as well.
User avatar
banedon
Posts: 742
Joined: 08 Sep 2013
Location: A missile silo somewhere under southern England

Re: RS232... here goes!

Post by banedon »

Can someone verify that my programming of the ACIA is correct?
It's supposed to set the chip up for 8 data bit, 1 stop bit, sending at 150 baud.
I haven't bothered setting up IRQ as I'm transmitting and as there is still an xmit bug ...

The ACIAinit routine is called to set the ACIA up, a few other bits and bobs are then done and finally the CPUhalt routine is called. This is where I've inserted a repeating loop to send the ascii code for 'A' repeatedly

I've fitted a 2MHz oscillator for testing purposes.

Code: Select all

VIA = &4010
VIA_outA = VIA + 1
VIA_DDRA = VIA + 3

ACIA = &4020                             <---- Base address for the ACIA
ACIA_Transfer = ACIA + 0
ACIA_ResetStatus = ACIA + 1
ACIA_Command = ACIA + 2
ACIA_Control = ACIA + 3

Code: Select all

.haltcpu
# endless loop at the end


LDY#0
.loopDELAYacia
LDX#0
.loopDELAYaciaX
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
INX
CPX#254
BNE loopDELAYaciaX
INY
CPY#254
BNE loopDELAYacia

# ACIA Command register

LDA #65
STA ACIA_Transfer                             <---- send '65'

JMP haltcpu

Code: Select all

.ACIAinit
# Reset the ACIA
LDA#0
STA ACIA_ResetStatus                             <---- reset the ACIA

# Control register
# 1 stop bit, 8 bits word length, Baud rate clock,
# 150 baud
LDA #%00010101
STA ACIA_Control                             <---- send control register

LDA #%11000110
STA ACIA_Command                             <---- send command register
RTS

The code currently gives the following output on the attached DB9 connector:

T1OUT - DS9 pin 3 = -10V
T2OUT - DS9 pin 4 = +10V
T3OUT - DS9 pin 7 = +10V

R1IN - DS9 pin 2 = -10V
R2IN - DS9 pin 8 = 0V
R3IN - DS9 pin 6 = 0V
R4IN - DS9 pin 1 = -10V

ACIA pin 7 - XTAL2 = 1.8432MHz
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: RS232... here goes!

Post by floobydust »

Well, a couple things, looks like you've set the transmit IRQ active. Second, better to explain your output wiring of the RS-232 port, as RTS, CTS, DTR, RxD, etc., rather than T1, R2, etc.. And what are you using to determine that you are transmitting? Case in point, certain control lines for the chip hardware need to be at certain logic states. Usually a null modem connection to another machine's RS-232 port with a terminal program controlling it. This way you can see if you are transmitting. I use ExtraPutty as a terminal program with RTS/CTS handshaking and a 5-wire modem.

As for the code, there's basically 3 needed routines to run the 65C51; An init routine to set the chip up, a receive routine that can poll for a character available and a transmit routine to send a character. The send/receive routines for polled I/O are dirt simple and rely on reading the status register to determine if a character is available to receive or if the transmitter is able to send a character. For example, here's a polled I/O transmit routine:

Code: Select all

CHOUT     PHA           ;Save ACCUMULATOR on STACK
CHOUTL    LDA  SIOSTAT  ;Read ACIA status register
         AND  #$10     ;Isolate transmit data register status bit
         BEQ  CHOUTL    ;LOOP back to CHOUTL IF transmit data register is full
         PLA           ; ELSE, restore ACCUMULATOR from STACK
         STA  SIODAT   ;Write byte to ACIA transmit data register
         RTS           ;Done CHOUT subroutine, RETURN
To init the 65C51, this is also quite simple:

Code: Select all

INIT_6551
;Init the 65C51
					SEI	;Disable Interrupts
					LDA	#$00 	;Get a zero
					STA	SIOSTAT	;write to status register, reset 6551
					LDA	#$1F 	;Get Control reg config, 8-bits, 1 stop-bit, 19.2K baud
					STA	SIOCTL	 ;Write to the Control Register for 6551
					LDA	#$0B 	;Get Command Reg config, No parity, Rcv mode normal, no Tx/Rx IRQ
					STA	SIOCMD	;Write to Command Register for 6551
					CLI	;Re-enable Interrupts
					RTS	;Return to caller
Now, with the latest WDC chip, Xmit is broken, so here's a delay routine you can modify as required:

Code: Select all

; Latest WDC 65C51 has a bug - Xmit bit in status register is stuck on
; IRQ driven transmit is not possible as a result - interrupts are endlessly triggered
; Polled I/O mode also doesn't work as the Xmit bit is polled - delay routine is the only option
; The following delay routine kills time to allow W65C51 to complete a character transmit
; 0.523 milliseconds required loop time for 19,200 baud rate
; Microsecond routine takes 524 clock cycles to complete - X Reg is used for the count loop
; Y Reg is loaded with the CPU clock rate in MHz (whole increments only) and used as a multiplier
;
DELAY_6551	PHY								;Save Y Reg (3 clk cycles)
			PHX								;Save X Reg (3 clk cycles)
DELAY_LOOP	LDY	#10 					;Get delay value (clock rate in MHz 2 clock cycles)
;
MICROSECOND	LDX	#$68					;Seed X reg for 1ms (2 clk cycles)
DELAY_1		DEX								;Decrement low index (2 clk cycles)
			BNE	DELAY_1				;Loop back until done (3 clk cycles if yes, 2 clock)
;
			DEY								;Decrease by one (2 clk cycles)
			BNE	MICROSECOND		;Loop until done (3 clk cycles if yes, 2 clock)
			PLX								;Restore X Reg (4 clk cycles)
			PLY								;Restore Y Reg (4 clk cycles)
DELAY_DONE	RTS								;Delay done, return (6 clk cycles)
;
To use the delay routine, modify the CHOUT routine as:

Code: Select all

CHOUT     PHA           ;Save ACCUMULATOR on STACK
;
;	Modification below for WDC 6551 chips - Xmit bit stuck on, need delay routine rather than polling - sucks.
;
CHOUTL    LDA  SIOSTAT  ;Read ACIA status register
;         AND  #$10     ;Isolate transmit data register status bit
;         BEQ  CHOUTL    ;LOOP back to CHOUTL IF transmit data register is full
         PLA           ;ELSE, restore ACCUMULATOR from STACK
         STA  SIODAT   ;Write byte to ACIA transmit data register
         JSR	DELAY_6551	 ;Required delay - Comment out for working 6551/65C51!      
         RTS           ;Done CHOUT subroutine, RETURN
;
The above code segments will work with a 5-wire null-modem running at 19.2K baud to an async terminal. The delay values are for a 10MHz 65C02 processor and the latest WDC 65C51.
Hope this helps. Also, perhaps a full schematic of you 6551/Max238 interface would be helpful if the above doesn't work for you. Also, here's a link to some basic info on RS-232 null modem configs:

http://www.ethernut.de/en/documents/rs232primer.html
User avatar
banedon
Posts: 742
Joined: 08 Sep 2013
Location: A missile silo somewhere under southern England

Re: RS232... here goes!

Post by banedon »

Hi Floobydust

Thanks for the information.
Here's a schematic of how things are wired up. I have the 65C51 mapped to $4020:
RS232C_W65C51N.png
The modem cable is a straight through DB9 one and I have it connected to a serial port on my PC and have set PuTTY up to listen on it it (COM3).
PuTTY & COM3 works with the RS232C to RS423 cable I use for xfering info from my PC to my BBC Micro B+ at 9600 baud - so the port seems ok.

I've set PuTTY up to run at 150 baud, 8 data bits, 1 stop bit, no parity, no flow control.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: RS232... here goes!

Post by GARTHWILSON »

Are you saying you aren't getting anything? It sounds like you don't have an oscilloscope, but there are things you can try with a cheap piezoelectric beeper element like I show at http://wilsonminesco.com/6502primer/debug.html . Put one from the RxC pin to ground. You should be able to hear the baud rate generator. Then put it from TxD to ground. You should be able to hear the characters coming out. Same for pin 3 of the DB9. If you do hear it and the PC isn't picking up the character, you might have a mismatch in bit rate, use of parity, etc..
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
banedon
Posts: 742
Joined: 08 Sep 2013
Location: A missile silo somewhere under southern England

Re: RS232... here goes!

Post by banedon »

I am using a 'scope, but the signals were solid.
BTW do I need to use a null modem cable? Mine is straight through...

[edit] just retested with with Floobydusts code and I'm still seeing:
Pin 1 (DCD) : -10v
Pin 2 (RXD) : -10v
Pin 3 (TXD) : -10v
Pin 4 (DTR) : +10v
Pin 5 (0V) : 0v
Pin 6 (DSR) : 0v
Pin 7 (RTS) : +10v
Pin 8 (CTS): 0v
Pin 9 (Ring) : 0v

[edit] Just found a wiring issue. Fixing that now and will retest.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: RS232... here goes!

Post by GARTHWILSON »

banedon wrote:
Pin 8 (CTS): 0v
The transmitter is disabled if CTS is not true. It needs to be near ground at the '51 and positive voltage at the DB9.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Post Reply