6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 10, 2024 8:42 pm

All times are UTC




Post new topic Reply to topic  [ 55 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
PostPosted: Thu Jun 06, 2024 7:34 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 490
As mentioned over here I had to give up my clever plan of working around the WDC65C51 transmit bug by wait-stating a vintage part. So I put a regular WDC one in there. This is the first time I've used one of these. I have it wired up like this:
Attachment:
Screen Shot 2024-06-06 at 2.00.46 PM.png
Screen Shot 2024-06-06 at 2.00.46 PM.png [ 80.71 KiB | Viewed 772 times ]
It's connected to a serial port (a real one) on an old Thinkpad over a serial cable (also a real one! :) ) I've got a few simple routines for testing, using polling (for receiving) and delay loops (for transmitting).
Code:
_ACIA_init:
;       Initilaize Serial Interface N-8-1, 19200, no parity, no echo,
;       interupts are disabled
;       Modifies: flags
                pha
                sta     ACIA_STATUS             ; soft reset (any write)
                lda     #$1F                    ; N-8-1, 19200
                sta     ACIA_CTRL
                lda     #$0B                    ; No parity, no echo, interrupts disabled
                sta     ACIA_CMD
                pla
                rts

_ACIA_cin:
                lda     ACIA_STATUS
                and     #$08
                beq     _ACIA_cin
                lda     ACIA_DATA
                rts

_ACIA_cout:
;       Outputs a character from .A to the Serial Interface
;       Modifies: flags
                pha
                sta     ACIA_DATA
                jsr     tx_delay                ; Delay loop for buggy WDC ACIA
                pla
                rts

tx_delay:
                phx
                phy

                ldy     #16
@1:
                ldx     #100
@2:
                dex
                bne     @2
                dey
                bne     @1

                ply
                plx
                rts

; =-=-=-=-=-=-=-=-=

;       call init routines
                jsr     _ACIA_init

_main:
                jsr     _ACIA_cin       ; get a character
                jsr     _ACIA_cout      ; echo it
                bra     _main           ; forever
This is mostly working, but every so often I get a glitched character. Let's say I start out at the top left of my terminal emulator and just hold down the space-bar. Mostly I get spaces echoed back to me. But every so often, say 2 - 4 times per screen, I get an @ symbol instead. This happens with other characters too, but my terminal (PuTTY) prints a grey box when it gets a non-printing character, so I can't tell exactly what happens for each different character when there's a glitch. The glitches are consistent, in the sense that it's always an @ symbol when I'm sending spaces. I think that this is some kind of serial timing issue. My "S"BC seems very stable overall. I've got it booting from ROM, copying to RAM, banking out the ROM, running from RAM. The VIAs and ACIA never seem to miss being selected, even though I'm running pretty fast (16MHz), and the CPU never misses an instruction, or jumps to bad code or anything.

I'm not sure how to troubleshoot this; The glitches don't seem to happen with any predictable frequency. My tools are a DMM, my old analogue scope, and Hoglet's decoder software with an fx2 "logic analyzer" board.

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 06, 2024 7:43 pm 
Offline
User avatar

Joined: Tue Feb 28, 2023 11:39 pm
Posts: 256
Location: Texas
Just a hunch, but I see that you've elected not to use the flow control. Could it be that the laptop is sending ever so slightly too quickly before the 6502 has a chance to empty the one character buffer in the 6551?

I had some similar issues with the 16C550C I was using from my desktop to my 6502, and using the RTS/CTS hardware flow control fixed that right up.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 06, 2024 8:05 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 490
Hi Yuri! Could be. In fact, I'm feeling like that's likely. After I posted the above, I did a little software troubleshooting and it seems that the glitches are all receiving. The "S"BC is transmitting fine. I'll try adding a send delay loop. ;) (I'll push the button more slowly!) and see what happens. I guess it's time to go read up on RTS/CTS. Hope it's not too complicated!

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 06, 2024 8:10 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1485
Location: Scotland
Paganini wrote:
Hi Yuri! Could be. In fact, I'm feeling like that's likely. After I posted the above, I did a little software troubleshooting and it seems that the glitches are all receiving. The "S"BC is transmitting fine. I'll try adding a send delay loop. ;) (I'll push the button more slowly!) and see what happens. I guess it's time to go read up on RTS/CTS. Hope it's not too complicated!


Or just use a lower baud rate.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 06, 2024 10:12 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 490
Yuri wrote:
Just a hunch, but I see that you've elected not to use the flow control. Could it be that the laptop is sending ever so slightly too quickly before the 6502 has a chance to empty the one character buffer in the 6551?

I had some similar issues with the 16C550C I was using from my desktop to my 6502, and using the RTS/CTS hardware flow control fixed that right up.


Hey Yuri, would you mind sharing exactly what you did? I did some poking around this afternoon, but I haven't been able to get hardware flow control working at all. I found Lee Davison's guide here: http://www.6502.org/users/mycorner/6502/acia/index.html It seems like he has RTS/CTS hooked up to pins 6 and 7, whereas all the pinouts I found on the internet say that they should go to 7 and 8. I'm working with jumper wires, though, so it was easy to try both. I don't seem to able to send to the SBC *at all* when I use RTS/CTS. I adjusted my schematic:
Attachment:
Screen Shot 2024-06-06 at 4.56.34 PM.png
Screen Shot 2024-06-06 at 4.56.34 PM.png [ 54.28 KiB | Viewed 750 times ]

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 06, 2024 10:24 pm 
Offline
User avatar

Joined: Tue Feb 28, 2023 11:39 pm
Posts: 256
Location: Texas
Paganini wrote:
Yuri wrote:
Just a hunch, but I see that you've elected not to use the flow control. Could it be that the laptop is sending ever so slightly too quickly before the 6502 has a chance to empty the one character buffer in the 6551?

I had some similar issues with the 16C550C I was using from my desktop to my 6502, and using the RTS/CTS hardware flow control fixed that right up.


Hey Yuri, would you mind sharing exactly what you did? I did some poking around this afternoon, but I haven't been able to get hardware flow control working at all. I found Lee Davison's guide here: http://www.6502.org/users/mycorner/6502/acia/index.html It seems like he has RTS/CTS hooked up to pins 6 and 7, whereas all the pinouts I found on the internet say that they should go to 7 and 8. I'm working with jumper wires, though, so it was easy to try both. I don't seem to able to send to the SBC *at all* when I use RTS/CTS. I adjusted my schematic:
Attachment:
Screen Shot 2024-06-06 at 4.56.34 PM.png


I don't have an exact circuit for mine but the general idea is that:

Side A : RTS <- Side B : CTS
Side A : CTS -> Side B : RTS

You still have to control the status of the lines through software, but the difference is that the signals are async to the data that is traveling.

My driver is here:
https://github.com/Kelmar/Lemon/blob/main/src/serial.s

This is for the 16C550C, but the principle is the same, you want to drive the CTS line high (low level logic) to tell the other end to stop transmitting until you are ready to receive the next character.

With puTTY, Tera Term, etc, you'll need to enable the hardware flow control in there as well.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 06, 2024 10:32 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
I have sample ACIA-receive interrupt code in the 6502 interrupts primer, at http://wilsonminesco.com/6502interrupts/#3.1

_________________
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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 06, 2024 11:19 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8481
Location: Midwestern USA
Paganini wrote:
I'm not sure how to troubleshoot this...

You could begin by making sure all inputs are connected.  In your first schematic, you’ve left DSR floating.  Due to the 6551’s brain-dead design, DSR should be tied to ground, unless being actively controlled by a modem.  With DSR floating, connectivity can come and go due to noise riding on the unterminated input.

Also, if you plan to run above 9600 bpS, you should implement hardware flow control.

I can’t read your second schematic due to it being in color, so I don’t know if you did anything with DSR and/or CTS and RTS.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 07, 2024 12:44 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
I used a 65c51 on my workbench computer to program bluetooth modules for work starting four years ago, at 115,200bps, with no hardware handshake, and it works reliably and consistently.  I've used the 65c51 for decades (although not WDC's newer ones) and never had any trouble with it.  Everything I've ever done with the 65c51 worked on first try, except when I lacked a capacitor in the crystal circuit.  I could wish that a couple of the functions had been separated rather than being controlled by the same bit in the command register; but it hasn't been any real problem in my applications, and separating them would have required adding another register-select pin.  I do however advocate hardware handshaking when it can be done.  And never leave a CMOS input floating!

_________________
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?


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 07, 2024 2:13 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
GARTHWILSON wrote:
And never leave a CMOS input floating!
... remembering of course the same warning for the inputs for other MOS families such as NMOS (the basis for older 65xx chips and others).

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 07, 2024 4:53 am 
Online

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 958
Location: Potsdam, DE
Yuri,

Unmentioned, or I failed to note it, is a comparison of the two serial clock speeds. They *must* be within 5% (total) of each other to allow synchronisation... it's possible that the laptop is running a touch slow (though I'd be surprised) or that your SBC is running fast (perhaps more likely? How do you generate your clock?)

The serial protocol sends the low bit first, immediately after a start bit, and samples in the middle of the expected sample - that is, the receiver sees the start pulse, confirms half a bit-period later that it's still low, and thereafter samples every bit period. Which means that if you're half a bit period out in the baud rate clock by the end of the transmitted word, you're reading the wrong sample. The two characters you mention have bit patterns like this:
Code:
space   0000001001
@sign   0000000101

so it doesn't take much of a timing error to read one as the other. If this is happening you might expect to see an error from your ACIA complaining about the lack of a stop bit when you receive the @.

One way you might compare these rates is to send 'U' characters continuously from each end (ascii code 0x55) and check the bit timing on a scope.

It's important to realise that a timing error like this is irrespective of the actual baud rate - it is the percentage difference between the rates that is significant.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 07, 2024 7:01 am 
Offline
User avatar

Joined: Tue Feb 28, 2023 11:39 pm
Posts: 256
Location: Texas
barnacle wrote:
Yuri,

Unmentioned, or I failed to note it, is a comparison of the two serial clock speeds. They *must* be within 5% (total) of each other to allow synchronisation... it's possible that the laptop is running a touch slow (though I'd be surprised) or that your SBC is running fast (perhaps more likely? How do you generate your clock?)


Think you meant to direct this at Paganini :mrgreen:

I wouldn't be surprised to find that to be a possibility though. However, in my setup, like I said, adding the hardware flow control fixed the problem for me.

My system works quite nicely coping/repeating some pretty large chunks of text without any issues.

(The only thing I've discovered with my setup is it seems that my 16C550C gets very unhappy if I swap my WDC65C02 for a WDC65C816 :( )

Edit:
It also got unhappy when I bumped the clock from 6.29375Mhz to 8Mhz, but that was an easy fix.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 07, 2024 3:01 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 490
Yuri, thanks for sharing your code!

OK, let's regroup.

I have a 4MHz breadboard computer. Using a Rockwell 65C51 I built a 3-wire serial connection. That one works fine. I duplicated that on an I/O board for Blue August, my faster wire-wrap-on-protoboard computer. Using the same Rockwell 65C51 and running Blue August at 4MHz, the duplicate 3-wire serial connection works fine. I replaced the Rockwell part with a WDC65C51 and clocked Blue August back up to 16MHz. Now the 3-wire serial connection mostly works, but with intermittent glitches when receiving. In all of these cases, the baud rate is set to 19,200. Yuri suggests that the bit rate on the laptop might be too fast and suggests I add flow control. That seems like a good idea to me! There does not seem to be a lot of info about how to do this floating around the web, though. Here's how I think it works, but I must be making a mistake somewhere, because when I do this the serial connection doesn't work at all.

CTS\: This is an input on the ACIA - pin 9. It needs to connect to an output pin on the logic side of the MAX232. R1OUT is connected to RxD (pin 12 -> 12!), but R2OUT is free. That is pin 9 on the MAX232, so pin 9 goes to pin 9. This signal comes into the MAX232 on the RS232 side on pin 8. That pin connects to pin 7 on my serial header, but might need to connect to pin 8 there depending on whether or not I'm using a crossover cable. I connect it with a Dupont wire so I can try both ways. The cable comes from the late 90s when I used it to play Quake with a friend. :) There is no way to interact with CTS\ in software; it's not reported in any register. It seems to work like a G\ or E\ input - when it is asserted low, the ACIA simply stops.

RTS\: This is an output on the ACIA - pin 8. It needs to connect to an input pin on the logic side of the MAX232. T2IN is free. That is pin 10. This signal emerges from the MAX232 on the RS232 side on pin 7. This should go to pin 8 on my serial header, but might need to go to pin 7, depending on my cable, again. RTS\ is software controlled. Asserting it low by writing the appropriate value to bits 2-3 of the ACIA command register tells the other end of the connection that the ACIA is ready to receive. Right now my firmware sets RTS\ low when the ACIA is initialized, and then leaves it alone.

I would think that, after changing my terminal emulator settings to use RTS/CTS flow control, the above would mimic the situation where there is no flow control at all. Since RTS\ is always low, the laptop will send to the ACIA as fast as it can, and I should see it mostly working with the occasional timing glitch. What do I see is nothing at all.

If I manually ground CTS\ (pin 9) on the ACIA, then I can send and receive, even with hardware flow control set in my terminal emulator. But there doesn't seem to be any pin on my DB9 header that is ever driven low by the host laptop.

Also, I can't get the board to glitch today, which makes me think the problem might be temperature-related. My "workshop" is in the garage now, which is not climate controlled. Still, it was only in the 90˚F range yesterday. Not close to 70˚C! :D

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 07, 2024 3:20 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 490
Hi Niel,

barnacle wrote:
Unmentioned, or I failed to note it, is a comparison of the two serial clock speeds. They *must* be within 5% (total) of each other to allow synchronisation... it's possible that the laptop is running a touch slow (though I'd be surprised) or that your SBC is running fast (perhaps more likely? How do you generate your clock?)


The system clock is a 32MHz half-can divided down by an `AC163. It's Jeff's clock-stretcher circuit; however, the clock only stretches immediately after power-on when the 6502 is copying the ROM into RAM. Once it's running from RAM it runs at 16MHz.

The ACIA uses its internal baud rate generator, clocked by a 1.832etc. half-can hanging off the XTAL1 input (pin 6).

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 07, 2024 3:38 pm 
Offline

Joined: Wed Nov 16, 2011 9:39 am
Posts: 68
Since you are reading and writing in sequence, your write routine is wasting cycles where received data could appear. Like Garth suggests, I would recommend to use an interrupt handler for the receive part, as per the 6502 interrupt primer, which would service your reads even if you are blocking writes. I use it successfully with 230400 baud, with my 6502 running at 3.6864 MHz (shared clock with the 65c51 to save board space).


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 55 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 36 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: