fredag 10. juli 2015

Decoding the 68b01 keyboard scanner

Returning to the Prophet VS service manual, I noticed that the output bus from the keyboard scanner runs through a set of latches. This means that bus communication is one way only. In addition to the bus, the only pins connecting the scanner to the main MCU are the KYBD and KYINT lines. Thus, the communication protocol should be fairly simple.

I connected logic probes to various parts of the 68B01 and its surrounding components. First to the CD4022 octal counter to see how the keyboard lines are scanned. Then to the rows to see which ones are connected to the first and second set of keys. I registered the data on the output bus while pressing keys to understand the protocol. I also checked the KYBD and KYINT lines while monitoring the data bus to see how the MCUs interacted.

The velocity was a bit trickier to get right. I needed to know the interval between hitting the first key and the second key, and at the same time registering the data bus output. I only have 8 probes on my logic decoder, but luckily, the velocity is 7 bit only, and by ignoring the least significant bit I could still get quite accurate velocity measurements.

What I found was that certain number of rounds of scanning the keys in between first and second keys made contact corresponded to a certain velocity. In other words, there is no 'free running' counter used for calculating velocity, one only needs to know how many times the keys have been scanned. This makes sense, as the only legal intervals corresponds to the times the keys are scanned.

I got a nice surprise when I made a plot of the velocity versus the scan cycle count. It turns out the velocity is a faux exponential curve, much like the way an analog audio-scale potentiometer works. For the first quarter of the measured cycles the velocity follows a steep line. For the other three quarters it follows a much flatter line. This, of course, makes calculating the velocity much easier (without the use of a lookup table. In that case any curve would be equally simple).
Plot of cycles vs velocity

(Disclaimer: The lines measured are not perfectly flat even if I try correcting for a +/- 1 error. This means that there is actually some kind of timer involved that is not connected directly to the keyscanner cycles. However, when recreating the program it will be sufficient to count cycles as long as cycle lengths are constant)

Here are some details about the scanner:

The keys are scanned column-by-column. The first column is turned on for about 70uS, the rest for 52uS. The total period (time between successive scans of the same column) is 432uS, giving a scan frequency of about 2.3kHz.
The three first columns and their scan pulses
The columns are scanned by clocking a CD4022 octal counter. Each clock pulse is approximately 2.5uS wide. The carry out from the CD4022 alternates between 0 and 1 every four clock pulses.

Data transfer works like this:

When the scanner has something to send, it lowers the KYINT line. At the same time, it puts the data on the output bus. Approximately 10uS later, the main MCU lowers the KYBD line. This turns on the 74HC367 transparent latches and puts the data on the databus, and at the same time signals to the scanner that it is reading data. KYBD stays low for about 0.25uS. The scanner waits an additional 10uS and then puts the next data byte on the output bus. The main MCU seems to read the data bus until it gets a 0 (0 on the bus is not a valid note on or velocity).

The data format is equally simple:

Note on is sent as two bytes: Note and Velocity
Note off is sent as a single byte: Note.

Both note and velocity are seven bit values. To differenciate between Note on and off, the MSB is always 1 for note on and 0 for note off. MSB is always 0 for velocities.

The lowest key on the keyboard, C0, is sent as x0100100 (x being 1 or 0 depending on note on/off), so the note value to send is simply 36 + key number.


Time t from key is pressed until it reaches bottom is x * 432uS + 571uS, where x is the number of times the first switch is scanned before it reaches bottom.

An approximation to the velocity transfer curve is as follows (not rounded):
[0, 1]: y = 127
[2,19]: y = 124 + (1867uS - t) / 80
[20,69]: y = 38 + (8779uS - t) / 570
[70, ->: y = 0

If more than 70 scan cycles are reached without the key hitting the bottom, a note on with velocity 0 is sent (and a note off is sent when the key is released later).

x = number of key scan cycles
y = velocity sent to master

This will of course not be an easily calculateable curve, so one is better off using a lookup table.

Top three: colum enable. Line four: key start switch, line five: key bottom switch. Pulses on key lines show when they are read. It seems that a lot of work is done when the first switch is turned on, making the initial delay longer than normal.

Important I/O pins:

Pins 13-20 corresponds to row 0-7 of the key press start switches
Pins 37-30 corresponds to row 0-7 of the key at bottom switches (NB: reverse order!)
Pins 22-29 are the output data bus pins
Pin 8 is clocking the CD4022 column selector
Pin 9 reads the carry bit from the CD4022
Pin 12 is the KYINT bit that must be set low before data transfer
Pin 39 is the KYBD bit that can be used to detect that the master reads the data.

2 kommentarer:

  1. Hi. Interesting project. Funny you mentioned the faux exponential curve in audio pots. I heard about it not until recently after watching a video by Julian Ilett: "Investigation: Are Log Potentiometers really Logarithmic?" .. .. He is working on a "ETI Vocoder".
    Hans Petter

    1. This one?

      Yeah, I read a bit about the audio pots a while back, and think I also found some thorough discussion of how to make a more "correct" approximation of the curve using a linear pot in "Small signal audio design" by Douglas Self.