6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 12:47 pm

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Struggling with the ACIA
PostPosted: Tue Oct 17, 2023 6:11 pm 
Offline

Joined: Tue Sep 26, 2023 2:39 pm
Posts: 3
Introduction
As with many others, I got started playing with the 6502 after watching Ben Eater's series of videos. I quickly became frustrated with all of the wires and flakiness of a breadboard and decided to design a simple PCB to continue exploring the 6502. During research for my PCB design project, I quickly found my way to Mr. Wilson's excellent site and tried to follow many of his suggestions and guidelines. The result is what I call the u6502. My overall goal was to make something simple enough that I could understand it but capable enough to be a useful long-term learning platform. With that in mind, I started with Mr. Wilson's example schematic and added a second VIA and an ACIA along with some simple additional support circuitry.

My initial schematic revision:
Attachment:
File comment: Rev0 schematic
u6502-rev0-schematic.png
u6502-rev0-schematic.png [ 406.32 KiB | Viewed 8766 times ]


I used a 100mm^2 4-layer PCB design with a signal, ground, ground, signal stack up to keep production costs low.

PCB Front:
Attachment:
File comment: PCB front
front.png
front.png [ 429.95 KiB | Viewed 8766 times ]


PCB Back:
Attachment:
File comment: PCB back
back.png
back.png [ 357.28 KiB | Viewed 8766 times ]


The following image shows the rev0 PCB in place in my "development system".
Attachment:
File comment: Rev0 PCB in situ
IMG_2714.jpg
IMG_2714.jpg [ 4.43 MiB | Viewed 8766 times ]


The Problem
My initial testing seems to show that the VIAs are working as expected and I am able to drive a common 16-character LCD with only minor issues. However, I have been completely unsuccessful in my attempts at interacting with the ACIA. I have not been able to get any serial data into or out of the RX/TX pins on the ACIA. I have tried the following troubleshooting steps:
  • Validate CS logic with a logic analyzer. I think the chip is being correctly addressed, however, I only have a cheap 8-channel LA and am not 100% certain.
  • Validate clock signals on PHI2 and XTAL1. Both the PHI2 clock and 1.8432MHz baud rate clock seem to be producing clean signals and are connected to the correct pins.
  • Review assembly listing file and compare with known working examples.
    Attachment:
    File comment: Test program listing file
    acia-test.txt [13.04 KiB]
    Downloaded 64 times

Here is the snippet from the listing file that covers the ACIA setup and data sending:
Code:
008092  1               .include "serial.s"
008092  2               ; ACIA Include File
008092  2               
008092  2               ACIA_DATA   = $4400
008092  2               ACIA_STATUS = $4401
008092  2               ACIA_CMD    = $4402
008092  2               ACIA_CTRL   = $4403
008092  2               
008092  2               .segment "CODE"
008092  2               
008092  2               init_acia:
008092  2  48               pha
008093  2  9C 01 44         stz ACIA_STATUS ; clear status register
008096  2  A9 1E            lda #%00011110  ; 8-N-1, 9600 baud
008098  2  8D 03 44         sta ACIA_CTRL   ; set control register
00809B  2  A9 0B            lda #%00001011  ; No parity or rcv echo, RTS true, receive IRQ but no
00809D  2  8D 02 44         sta ACIA_CMD    ; set command register
0080A0  2  68               pla
0080A1  2  60               rts
0080A2  2               
0080A2  2               acia_send_char:
0080A2  2  48               pha
0080A3  2  8D 00 44         sta ACIA_DATA
0080A6  2  A9 FF            lda #$FF
0080A8  2               @tx_delay:
0080A8  2  3A               dec
0080A9  2  D0 FD            bne @tx_delay
0080AB  2  68               pla
0080AC  2  60               rts


Any suggestions or ideas about additional troubleshooting steps would be very greatly appreciated!


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 17, 2023 6:48 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Welcome!

Your code looks good (including the loop part when you're waiting after writing the byte - since it's a well-known bug in ACIA which prevents "TX buffer empty" flag from being set properly).
One small note: your comment says "receive IRQ but no" - looks like it's truncated, but I assume you're expecting ACIA to fire an IRQ when data is received? If so, bit 1 of command register should be set to 0 - see https://www.westerndesigncenter.com/wdc ... 65c51n.pdf (page 13)

Also, in case you're not connecting /DSR, /DCD, & /CTS lines anywhere (e. g. if you're probing your UART with a logic analyzer, or using USB-UART converter), you should tie them low, otherwise they will prevent you from sending/receiving the data.
Here's an excerpt from Garth's RS-232 primer on this:
Quote:
The 6551 ACIA (UART) will not send data if CTS is not true, and it won't receive if DCD is not true. This doesn't mean you absolutely have to use CTS and DCD. If you only want a two- or three-wire interface with no hardware handshaking, then ground these UART inputs so the 6551 will run.


Here's another good article that I used to get my ACIA up & running: http://retro.hansotten.nl/6502-sbc/lee- ... acia-6551/

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 17, 2023 6:56 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Welcome Greg, and very nice first post with lots of details - and a nicely laid out system you've built. I can't help with the 6551 but wish you all the best with it! My only suggestion would be to make it transmit something before getting receive to work, but that's not from experience with this particular chip.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 17, 2023 7:02 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
I was going to suggest what Andrew said, about DCD and CTS, but he beat me to it. :D

On the subject of the LCD, let met suggest going through http://wilsonminesco.com/6502primer/LCDcode.asm which has LCD code in several forms, particularly the part about writing the functions set three times, to get an always-reliable setup.  We had occasional problems at work until an applications engineer sent us code that showed this, which is information that you don't get in the data sheets.

_________________
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: Tue Oct 17, 2023 7:24 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
I see that you're using a PIO delay loop to regulate transmission, which is indeed necessary with the current production ACIAs. However, you should consider whether it's introducing enough delay.

The loop you have will perform 255 loops, consuming 5 cycles per loop, for a total of 1275 cycles. With a 1MHz Phi2 clock, that corresponds to 1.275 milliseconds. At 9600 baud 8N1, you need 10 bit times with each bit occupying 1/9600 sec, so 1/960 sec in total, which is 1.042 milliseconds. So the delay loop should work, and indeed there should be about a 20-25% margin between characters.

I would suggest setting up your SBC to continuously print characters (eg. ASCII 42 is '*') and use your scope or analyser to see whether the Tx output line shows a pattern consistent with the above.

One obvious cause of not getting such output would be if the /CTS line (which may be floating in your design) is going high (inactive). The /CTS line is not even connected to your FTDI header. The ACIA will interpret that as a demand to stop transmitting! At the very least, add a weak pull-down resistor so that if it isn't actively driven, it will default to active-low.

There's another important point, which is that a normal RS-232 port (such as on the back of a PC) uses very different voltage levels than the ACIA. NEVER directly connect the ACIA to a serial port - it will be damaged. Use a level-shifter device, such as the MAX232, to do the necessary voltage translation. Some of FTDI's devices use "normal" TTL voltages, and these won't cause any damage - but MAKE SURE that it specifies "TTL-232" and not "RS-232 levels", since they also make a lot of devices with the latter.

As for your address decoding, I do notice one or two problems here. You've avoided the pitfall of qualifying the ACIA's CS lines with Phi2 (though really the RAM chip doesn't need this either), but the RAM chip is decoded to be active across all addresses below $8000 - and only the /OE line tied to A14 prevents it from conflicting the data bus when reading your devices. This does not, however, prevent writes to your devices from causing aliasing writes to RAM at $040x, $100x and $200x respectively. The rule of thumb is that you should have mutually exclusive chip-selects for address decoding (the 74HC138 and 74HC139 are particularly useful for this) that are not Phi2-qualified, and that /WE and /OE for asynchronous devices (your RAM and ROM) should be generated as simple combinations of R/W and Phi2.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 17, 2023 7:32 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
Chromatix wrote:
but the RAM chip is decoded to be active across all addresses below $8000 - and only the /OE line tied to A14 prevents it from conflicting the data bus when reading your devices.  This does not, however, prevent writes to your devices from causing aliasing writes to RAM at $040x, $100x and $200x respectively.  The rule of thumb is that you should have mutually exclusive chip-selects for address decoding (the 74HC138 and 74HC139 are particularly useful for this), and that /WE and /OE for asynchronous devices (your RAM and ROM) should be generated as simple combinations of R/W and Phi2.

I missed this the first time around; but although it's labeled "16k RAM" (which is rare, as they go 2K, 8K, 32K, 128K, 512K), he's actually using a 32K RAM and A14 is indeed connected to an address input (not just the OE\ input), avoiding the problem you mention.  So like I've done, he's only using half the RAM, while the other half sits there harmlessly.

_________________
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: Tue Oct 17, 2023 8:24 pm 
Offline

Joined: Tue Sep 26, 2023 2:39 pm
Posts: 3
Thanks all for the warm welcome and quick replies!

Quote:
Also, in case you're not connecting /DSR, /DCD, & /CTS lines anywhere (e. g. if you're probing your UART with a logic analyzer, or using USB-UART converter), you should tie them low, otherwise they will prevent you from sending/receiving the data.

Andrew, is this also the case for the W65C51N? I should have been more specific in my description. I am using all current production CMOS ICs from WDC. Either way, I will run my test program again after grounding those lines.

Quote:
On the subject of the LCD, let met suggest going through http://wilsonminesco.com/6502primer/LCDcode.asm which has LCD code in several forms, particularly the part about writing the functions set three times, to get an always-reliable setup. We had occasional problems at work until an applications engineer sent us code that showed this, which is information that you don't get in the data sheets.

Mr. Wilson, I knew that you had example code for this somewhere but couldn't remember where when I was troubleshooting the LCD. Thanks for reminding me! Given that I was able to get it printing at all I was fairly sure that my problems were just software. I did wonder about using a MOSFET gated by the RESb signal to power down the LCD during reset to clear the LCD controller's internal state. But my experiments with that approach have proved unfruitful thus far.

Quote:
As for your address decoding, I do notice one or two problems here. You've avoided the pitfall of qualifying the ACIA's CS lines with Phi2 (though really the RAM chip doesn't need this either), but the RAM chip is decoded to be active across all addresses below $8000 - and only the /OE line tied to A14 prevents it from conflicting the data bus when reading your devices.

Chromatix, Mr. Wilson is correct in that I am only using 16k of the 32k RAM as in his example SBC schematic. I followed the address decoding example in the 6502 Primer so any errors in implementation here would be from my own ignorance/inexperience. But if I understand it correctly then I shouldn't have to worry about any bus contention between my RAM and IO.

Quote:
There's another important point, which is that a normal RS-232 port (such as on the back of a PC) uses very different voltage levels than the ACIA. NEVER directly connect the ACIA to a serial port - it will be damaged.

This is a great reminder. I am aware of this and all of my testing has either been with a logic analyzer or a cheap TTL FTDI to USB adapter.

Thanks again to everyone for responding to my questions so quickly. I will try out the suggestions soon and report back.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 17, 2023 9:12 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
GregCoonrod wrote:
Quote:
Also, in case you're not connecting /DSR, /DCD, & /CTS lines anywhere (e. g. if you're probing your UART with a logic analyzer, or using USB-UART converter), you should tie them low, otherwise they will prevent you from sending/receiving the data.

Andrew, is this also the case for the W65C51N? I should have been more specific in my description. I am using all current production CMOS ICs from WDC. Either way, I will run my test program again after grounding those lines.

It's not clear whether the W65c51N has an internal pull-up on the /CTS line etc. An old NMOS device would have one, which would hold the line in the inactive state if left open. A CMOS device may or may not not have it, and if left floating it could drift to either state and/or react to high-frequency noise. So whatever type of device you have, you MUST pull /CTS low for the transmitter to be enabled.

It's also unclear whether the W65c51N reacts in the same way as older devices to the /DCD line. Older versions of the ACIA may discard a character being received when /DCD goes high, on the grounds that it is likely corrupted, and won't enable the receiver unless it's pulled low. To be on the safe side, tie it down with a weak resistor, and do the same for /DSR just so that it doesn't float around randomly (it doesn't affect the receiver or transmitter functions).

/DTR and /RTS are outputs driven by the ACIA, so you wouldn't tie those either way. Just be aware that the ACIA drives /RTS according to an obsolete "peripheral mode" protocol, not the modern "peer to peer" protocol, ie. it won't tell the remote end to stop transmitting if the receive buffer is full.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 20, 2023 1:01 am 
Offline

Joined: Tue Sep 26, 2023 2:39 pm
Posts: 3
Pulldowns on the right signals and a MAX232 transceiver did the trick!
Attachment:
File comment: It works!
serialout.png
serialout.png [ 27.97 KiB | Viewed 8640 times ]


Thanks again, everyone!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 13 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: