6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 4:09 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sat Nov 08, 2014 11:45 am 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
This might have been covered somewhere, but I'm unable to find it if so.

My 8 bit computer now has a keyboard. Being a true DIYer, I went for the following solution:

1. C64 keyboard with it's 8 x 8 matrix
2. AVR MCU (ATMega 8515 in PLCC44) - This generates scancode events (high bit set for key up). Will eventually deal with key repeats
3. The AVR communicates to port A in a 65C22 VIA, with handshaking using CA1 and CA2
4. An interrupt routine in the MPU pulls off the scancode (acking the byte), optionally translates it to ASCII and stuffs it into a circular buffer. This routine also tracks shift and control keys for ASCII decoding.

(I did try using the synchronous serial port, but it gave me problems with corrupt data so I had to abandon that method.)

The VIA is init'd as follows:

Code:
                lda #0x08
                sta PCR6522
                lda #0x82
                sta IER6522


Anyway, everything is working well and I'm very pleased with myself. :) The AVR code is all written by me, and amazingly I managed to get it all working without even the use of a debug terminal. And I can use my computer, via the V9958 VDC, without a host machine. Well, that's enough trumpet blowing.

What I would like to do next is implement bidirectional comms between the VIA and the AVR. The main reason is to be able to change the key repeat rate, but there might well be other uses. The issue is I'm not sure how to go about it. Obviously in the AVR the main loop will have to poll "something" to work out if the VIA has a byte, but I'm a bit puzzled how to configure it.

Is what I want to do even possible with just a single VIA port? If it's of use, I do have a spare bit available in the data path, since I only need 6 for the scancode plus another bit to indicate if the key is going up or down. I could use that spare bit to indicate the data direction?

If I haven't explained things properly just let me know.

_________________
8 bit fun and games: https://www.aslak.net/


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 08, 2014 3:11 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
It's certainly possible for a VIA's parallel port to converse bidirectionally with another device. It's mostly just a matter of sorting out the etiquette observed by the two processors so things can go smoothly -- almost like the use of a two-way radio, when each party needs to signal end-of-transmission by saying, "over." This allows you to take turns talking and listening. Obviously things have gone awry if both talk at once, or both listen at once. Also be aware that the "both talk at once" condition means contention on the parallel port lines :!: -- which will cause overheating of both the VIA and whatever it's talking to. (Had that bug; learned the hard way! Amazing how hot a VIA can get and still survive... !! )

Many effective protocols are possible. In one scenario, one processor is always the boss, responsible for initiating all transfers, both host-to-slave and slave-to-host. So, for example, the ack sent to the AVR could be an actual byte (rather than just a pulse from CA2). The value of the byte would encode one of two possible messages: ordinary "ack," or "ack, but I also have something else to talk about, and I'm waiting for a cue to proceed."

The unused data line could be handy but it's not essential. Just remember that, regardless of what policy you settle on, one processor must let go of the "bus" (the VIA parallel lines) before the other processor commences to drive it. That's the maneuver you'll want to plan first.

If you're willing to install pullup resistors on the bus then matters get somewhat simpler. In that case the VIA and AVR can behave as "open collector" devices. Rather than outputting 0 or outputting 1 on each bit line, they'd output 0 or switch that bit to its input state and let the pullup do its thing. Easier than it sounds. Basically you write your data bytes to the Data Direction Register, and leave the Output Register all zeros. The open collector approach precludes bus contention, eliminating the fried-chip concern entirely. I'm sure the whole thing can be done without relying on the unused data line you mentioned, but using that line may simplify things -- it's your choice.

Another option to consider is the synchronous-serial link (the VIA shift register). That could act as an entirely separate and independent channel, for example to carry all the VIA-to-AVR traffic. The appeal here is that the parallel lines no longer need to switch direction, simplifying matters considerably. Also the shift register has its own interrupt and flag bits, separate from those for the VIA's parallel port. You could create two simple, separate tasks.

My hunch is this may lead to the best solution, so I suggest you give the shift register another try. When the shift-clock pulses are generated by the VIA there are no pitfalls AFAIK, but the modes where the VIA accepts shift-clock pulses from an external source are potentially tricky. You'll find some helpful info on Garth's web site.

cheers,
Jeff
[Edit: appearance of the VIA SR bug depends on whether the clock pulses are input or output, not whether the serial data is input or output.]

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


Last edited by Dr Jefyll on Sat Nov 08, 2014 9:15 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 08, 2014 5:29 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Very well written Jeff. You described pretty much what I was thinking too. The open collector method would be good as the keyboard data flow is slow enough not to have to worry about slow rise times.

I too think the serial port is the best option. You can take advantage of the AVR's SPI port to received data from the VIA's serial shift register. You could use that unused bit on the parallel port to signal a 6 bit confirmation that the AVR received the request.

Good work Aslak3!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 08, 2014 6:15 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Aslak3 wrote:
(I did try using the synchronous serial port, but it gave me problems with corrupt data so I had to abandon that method.)

I've been using it for 16 years with no problem, but there is a bug in all brands of VIA to work around, which I tell about at viewtopic.php?f=4&t=2175 . It's in in mode 011, in that if the externally supplied shift clock edge on CB1 falls within a few nanoseconds of the falling edge of phase 2, the CB1 edge will be ignored, so you lose a bit. Worse, you'll get framing errors on subsequent data, and they won't get reported. The link shows how to prevent problems. Jeff mentioned my website. My circuit potpourri page (the last page of the 6502 primer) has a lot of circuits for connecting things to a VIA, and many of them have accompanying code linked.

_________________
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: Sat Nov 08, 2014 8:09 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
8BIT wrote:
the keyboard data flow is slow enough not to have to worry about slow rise times.
Yes it's worth noting that rise times can be slow, depending on the value of the pullup resistors, so some NOPs or a brief delay loop is needed to allow bits to rise from 0 to 1 as necessary. The delay could be done either by the transmitting processor prior to outputting the handshake pulse, or by the receiving processor after inputting the handshake pulse. Speaking of handshake, note that writing to the VIA Data Direction Register won't trigger the pulse on CA2. But it's easy to just subsequently write the zero to the output register again, and that will trigger CA2.

This open collector business won't fix your protocol if it's busted, so in that sense its value is somewhat questionable. But at least you can stop worrying about contention. (Also there'll be less current flowing in a case where one but not the other device gets powered down. In your situation you won't encounter this, but it can arise when the parallel port bus connects two separately-powered computers.)

BTW I should mention that writing a 1 to the DDR results in a 0 on the data line, so your data bytes get inverted. That's easily fixed by an EOR #$FF prior to transmission or subsequent to reception -- just a minor detail.

GARTHWILSON wrote:
if the externally supplied shift clock edge on CB1 falls within a few nanoseconds of the falling edge of phase 2, the CB1 edge will be ignored
Thanks for the memory jog, Garth; I see I need to make a small correction to my previous post.

Two possible solutions for the potential problem of a VIA shift reg accepting external clock pulses are (a) don't use those modes; let the VIA generate the pulses, or (b) arrange that the external pulses (from the AVR) are synchronous. To do that, let the AVR derive its clock source from the same oscillator which is used to derive the 6809/VIA clock source. That's not to say they necessarily run at the same frequency, just that their clocks get divided down from a single originating oscillator. This is a powerful remedy for the problematic edge case Garth mentioned, and it might be ridiculously easy to do. The alternative (and still quite easy) solution is to add a 74_74 flipflop as he explains here.

-- Jeff

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


Last edited by Dr Jefyll on Sat Nov 08, 2014 9:59 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 08, 2014 9:56 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8505
Location: Midwestern USA
It might be instructive to look at how the Commodore 64 scanned its keyboard. The C-64 has a matrix keyboard attached to the parallel I/O ports of a 6526 complex interface adapter (these ports are an analog of those in the 6522). The jiffy IRQ handler configures the CIA ports in a certain way that makes it possible to detect if any key has been pressed. I don't recall all of the details anymore about how the ports are strobed to determine which key has been pressed, but that information is available in Mapping the Commodore 64. The rest of it, of course, is using software to relate the keypress to a unique number that the kernel can turn into a PETSCII value. This principle should be applicable to any 6502 machine equipped with a 6522, or even a 6520/21 PIA.

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


Top
 Profile  
Reply with quote  
PostPosted: Sun Nov 09, 2014 10:54 pm 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
There's a lot to take in. Some specific replies:

@BDD:

I could have easily utilised a full VIA and plugged the keyboard directly into that. However, I wanted to avoid keyboard polling in the MPU "at all costs" and make the keyboard completely interrupt driven. I also wanted to do things "differently". Hence the solution involving the AVR controller.

@GARTHWILSON:

I'm not sure exactly what problem I had with the shift register. I was using it in the externally clocked mode. I seemed to be having exactly the same issue as Quinn Dunki had with her 6522:

http://quinndunki.com/blondihacks/?p=1461

I've seen others use the SR with of course excellent results. I don't know. It's certainly a shame not being able to have just 4 wires to the keyboard PCB.

@All:

Thanks for the advice. I will let you know, in this thread, how I get on. It might well be some time, since I'm finally writing a game for my micro. :) And yes, I will be very careful not to put myself in a situation where I'm driving the bus from both ends...

_________________
8 bit fun and games: https://www.aslak.net/


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

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 35 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: