RS232... here goes!
Re: RS232... here goes!
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?
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: RS232... here goes!
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.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: RS232... here goes!
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 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.
Re: RS232... here goes!
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.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: RS232... here goes!
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\.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: RS232... here goes!
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.
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!
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: RS232... here goes!
GARTHWILSON wrote:
...but I can't think of any reason you would ever want the '51 ACIA on NMI\.
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!
Re: RS232... here goes!
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!
.
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!
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: RS232... here goes!
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.
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.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: RS232... here goes!
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.
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
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 + 3Code: 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 haltcpuCode: 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
RTSThe 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
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: RS232... here goes!
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:
To init the 65C51, this is also quite simple:
Now, with the latest WDC chip, Xmit is broken, so here's a delay routine you can modify as required:
To use the delay routine, modify the CHOUT routine as:
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
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, RETURNCode: 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 callerCode: 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)
;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
;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
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: RS232... here goes!
Hi Floobydust
Thanks for the information.
Here's a schematic of how things are wired up. I have the 65C51 mapped to $4020: 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.
Thanks for the information.
Here's a schematic of how things are wired up. I have the 65C51 mapped to $4020: 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.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: RS232... here goes!
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: RS232... here goes!
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.
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.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: RS232... here goes!
banedon wrote:
Pin 8 (CTS): 0v
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?