Scanning a cortron Diablo keyboard


16 Jul 2019, 01:12

I'm working on restoring and converting a Xerox Diablo 1660 keyboard.
it has ITW/Cortron ferrite core switches.
The board is well documented in manuals and patents.

Upon initial power-up one of the caps smoked, and took out several 74 series ICs on the board.
After desoldering several chips and soldering in sockets I got the board to start scanning the matrix.
Next problem is the MCU (and possibly sense amplifier?) requires -12V supply to work.

1640/1640 variant of the keyboard omits the -12 line to MCU and amp, not sure if this was a process change or an error, but my MCU definitely requires it.

My plan is to remove the MCU, add a socket, and use a CY8C-059 to read the matrix.
I've implemented the timing generator as described in the patents below in PSOC Creator, and attached a link to a test of the state machine below.

Plans for the future:
1. Be able to scan the matrix w/ psoc5
2a. remove all non essential logic and self power over usb
2b. remove non-essential FSM states for matrix scanning (current impl uses 33% of UDBs)
3. Increase scan freq (currently is ~100 scans /sec)
4. Remove sense amp and pulse stretcher, and use ADC to read analog value
5. Make Actuation depth configurable
6. Export PSOC Creator project as Makefile, build on linux, port QMK

Simulating the timing generator:

maintenance manual/ schematics: ... _Jul78.pdf

Some photos:

Relevant Patents:

User avatar

16 Jul 2019, 06:25

I happen to have 3 cortrons laying around. In one, I've got permission to replace the MCU and keep the driving logic because I couldn't figure out the analog part, really. Especially puzzling is the output from MCU which feeds back into the analog part depending on the previous key state.
.. I almost reversed the schematics in all 3, but work took the best part of me. I'll try to find the papers.

So, I was using a KitProg (of all things!) to drive the drivers - and was able to get almost (ALMOST) all keys working. Problem was 3-4 keys which register like 1 times out of 10 - and I can't figure out is it because I fucked up timings somewhere or the keys themselves. Lack of logic analyzer shows - just the oscillograph is not a good fit for long sequences.

2b - why do you care? You won't be mass-producing them so shoehorning into 5267 is not a realistic perspective, and otherwise - why bother?
4 - why it's even a separate item?
5 - good luck. Your main problem will be fighting EMI.
6 - why? Building firmware on linux is pointless as you can't change anything - for ANY "hardware" change you'll need Windows environment - and flashing firmware into CY8C5 is a breeze from any of mac/win/linux (not by cypress software - but you can steal my flasher).

"port QMK" - good luck, you'll need it. I started from porting TMK to PSoC5LP and quickly discovered that the part that remains after all the hardware support is literally not worth keeping.

PS: edaplayground link requires login :(
PPS: Have you published your PSoC creator project?

User avatar

16 Jul 2019, 08:53

I've read the patent. Sorry to disappoint you - but "making actuation depth configurable" is not likely to work. According to US3978474 the key in rested state saturates the ferrite core by holding a permanent magnet close to it. is (sorry for Russian. In case you're wondering - this models a very popular electricity-stealing tactics where you get a strong neodymium magnet and place it onto your electricity meter.) a description of how permanent magnet affects a current transformer (those ferrite cores _are_ current transformers). As you can see, very small variation in magnet to transformer distance causes the bulk of the change. So what we will likely see (I'll make a test harness tomorrow to see what actually happens there) is that when the key is at rest, no energy passes thru, and when we press the key slowly - it's nothing-nothing-nothing-A LOT-a lot-a lot.


16 Jul 2019, 14:39

DMA wrote:
16 Jul 2019, 06:25
2b - why do you care? You won't be mass-producing them so shoehorning into 5267 is not a realistic perspective, and otherwise - why bother?
4 - why it's even a separate item?
5 - good luck. Your main problem will be fighting EMI.
6 - why? Building firmware on linux is pointless as you can't change anything - for ANY "hardware" change you'll need Windows environment - and flashing firmware into CY8C5 is a breeze from any of mac/win/linux (not by cypress software - but you can steal my flasher).

"port QMK" - good luck, you'll need it. I started from porting TMK to PSoC5LP and quickly discovered that the part that remains after all the hardware support is literally not worth keeping.

PS: edaplayground link requires login :(
PPS: Have you published your PSoC creator project?
2b. only phi1 and phi3 are driven off chip, i might not need the other states at all. This was my first attempt at writing Verilog, so I guess i just offended me that such a small component took up so much space in the PSOC.
4. it's separate in my head from removing logic that isn't required to read the matrix, like the output buffers and strobe generating flip-flops.
5. This one is more just to see if I can. the patents mention the phi1 off time is also important to let the capacitor that's connected to the top of the matrix recharge.
6. In general, I strongly prefer linux for development, use it for work etc. I am starting to realize that PSOC Creator is pretty awesome though.

Edaplayground code and output:

ChibiOS demo with USBFS Uart example hacked in: ... M3-GENERIC

I've attached the current state of my psoc project to this post.
(14.56 KiB) Downloaded 48 times

User avatar

16 Jul 2019, 18:56

I tried to run creator from linux, but given up. Even if compilation environment is not really windows-specific, the UI is :(

As for writing verilog for psoc - I find it easier to make the equivalent schema from components and let the creator deal with everything else - from verilog to bitstream generation.

chibios - I can't really understand why you would even need OS on things that small. Driving a screen or something like that? But there's no screen..

User avatar

19 Jul 2019, 07:58

OK, I killed 2 days but now I know why reads are so unstable.

Turns out, 74145 is there for a Reason.

The Reason is all 10 outputs are essentially shorted together - well, technically, they're connected via a wire wound thru all of those ferrite cores, so there's some impedance, but inductance is low and the resistance is abysmally low, so a lot of active power is dissipated.
So much, in fact, that voltage sags to 3.8-3.9V at the USB plug, and 74145 itself is slightly warm.
RMS at the plug is 4.42-4.44V, which is very close to absolute minimum of 4.4V.

So after I finish this note, I'm into cutting some wires and direct-driving + direct-sensing. Not sure about output voltage levels - so driving first, sensing later.

Other than that - in my devices 7442 (rows) is driven normally, 0 to 9 (bits 4,5,6,7 - bit 0 being highest frequency), but 74145 is driven in an interesting way: bits 0 and 1 are coming from the MCU, but bits 2 and 3 are modulated by a NAND gate (half of 74LS00N) with positive strobe (φ2 in US3978474A AKA P1 in US4263582).
MCU drives all 16 values, but only 4,5 and 8 to 15 bring any of the outputs low. So, waveform of 1 row looks like this:

Code: Select all

70*us/~~~, subdivisions not to scale.
CLK:   0  1  2  3  4  5  6  7   8  9 10 11 12 13 14 15

A:   ___~~~___~~~___~~~___~~~ ___~~~___~~~___~~~___~~~

B:   ______~~~~~~______~~~~~~ ______~~~~~~______~~~~~~

C:   ~~~~~~~~~~~~~_~~_~~_~~_~ ~~~~~~~~~~~~~_~~_~~_~~_~

D:   ~~~~~~~~~~~~~~~~~~~~~~~~ ~_~~_~~_~~_~~_~~_~~_~~_~

Out: ~~~~~~~~~~~~~_~~_~~~~~~~ ~_~~_~~_~~_~~_~~_~~_~~_~

*) first 63 full periods of A (___~~~) are 70us, followed by 17 periods of 98us, giving full cycle time of 3.3+8.8=12.1 milliseconds.

The strobes themselves are a bit different from the patent - there's a positive strobe (2 lines, absolutely identical) and negative strobe. They are located in the middle of a pulse (20us + strobe + 20us or 40us + strobe + 20us) and shifted 5us front, 10us back:

Code: Select all

PS: __~~~~~_

NS: ~____~~~

IN: ~~___~~~
Comparator (not amplifier! LM319N in my case) generates an extremely short (and very unstable because of power sag: ) pulse - ~150ns. PFN (another half of 74LS00N) takes care of it, presenting MCU with the signal depicted as IN: on previous diagram - from the "ON" of positive strobe to the "OFF" of negative one.

I was able to poll without a single line of Verilog:

Code: Select all

static volatile uint8_t current_key = 0;
static volatile uint8_t drive_code = 4;
static volatile uint8_t current_stage = 0;
//static volatile uint8_t signal = 0;

#define STROBE_START 12

const uint8_t column_LUT[] = {4, 5, 8, 9, 10, 11, 12, 13, 14, 15};

//  Strobe_Write(current_stage);
  switch (current_stage) {
    case 1: {
    case STROBE_START:
//      signal = 0;
    case STROBE_START + 1:
    case READ_POINT:
      debounced_matrix_process(current_key, CyPins_ReadPin(SensePin_0) ? 0 : 1);
      // The range is 0 - number of keys. So at the last key we reset to zero.
      if (current_key >= 99) {
        current_key = 0;
        drive_code = 4;
      } else {
      // Driver generates pulses only at positions 4, 5, 8-15.
      // So we will skip non-coding positions.
      if ((drive_code & 0x0f) == 6) {
        // passed 5. Skip to 8.
        drive_code += 2;
      } else if ((drive_code & 0x0f) == 0) {
        // just passed 15. Advance 4 steps to 4.
        drive_code += 4;
    case STROBE_END:
    case STROBE_END + 1:
    case CYCLE_END:
      current_stage = 0;
Drive and Strobe are control registers (clocked by 200kHz - same clock that drives the DriveIRQ), DrivePins are "resistive pull up" digital outputs, positive strobe (StrobePin_{0,1}) are resistive pullup too, negative strobe (StrobePin_2) is resistive pullup-pulldown.

I would make others pullup/down too - it significantly reduces spikes at the cost of 500ns to reach the logical 1/0 - but pulldown resistors only can pull the inputs down to 1.5V and this is not enough to trigger logical zero. :(

SensePin is digital input, CMOS, buffered.

The code pasted uses longer key scan slot as an attempt to reduce current consumption. It helps - min voltage is about 4.05V. But that's not enough, readouts are still unstable.

User avatar

21 Jul 2019, 08:15

OK, I have good news and bad news. Good news is one can sense keypress depth: - kind of.

The bad news is you have 20 mV of noise and 15 (FIFTEEN) mV of signal, for what seems to be 100 nanoseconds.

Here's non-pressed vs pressed oscillograms for 4-switches in series, loaded by:

Nothing (well, oscillograph probe is some load):
DS1Z_QuickPrint17.png (82.08 KiB) Viewed 1538 times
DS1Z_QuickPrint18.png (79.11 KiB) Viewed 1538 times
100K resistor:
DS1Z_QuickPrint19.png (82.69 KiB) Viewed 1538 times
DS1Z_QuickPrint21.png (83.09 KiB) Viewed 1538 times

Small ceramic capacitor:
DS1Z_QuickPrint22.png (75.25 KiB) Viewed 1538 times
DS1Z_QuickPrint23.png (73.09 KiB) Viewed 1538 times
Looks like capacitor is the best, but 50 nanoseconds is not really workable.

Seems like magvalve scanner will have a lot of passive components.
Need to read on direct current in transformers.

User avatar

21 Jul 2019, 21:08

Turns out the noise was my scope. I remembered the probes have 1x position and remeasured.
It's not that bad, but 50ns measurement window smells like OpAmps - which we have, but they only can be used on specific pins and there are only 4 of them (so either external demux OR external OpAmps OR rewiring of ALL the switches OR using 2(3?) kits and an internal USB hub.)
100KΩ load:
DS1Z_QuickPrint1.png (48.36 KiB) Viewed 1500 times
DS1Z_QuickPrint2.png (48.18 KiB) Viewed 1500 times
No load:
DS1Z_QuickPrint3.png (45.86 KiB) Viewed 1500 times
DS1Z_QuickPrint4.png (46.67 KiB) Viewed 1500 times
Capacitor load
DS1Z_QuickPrint5.png (47.84 KiB) Viewed 1500 times
DS1Z_QuickPrint6.png (48.14 KiB) Viewed 1500 times
Also it seems like external current-limiting resistors (1kΩ) will be needed - current is just too low with internal pullups to produce any meaningful output voltage:
DS1Z_QuickPrint7.png (46.52 KiB) Viewed 1500 times
DS1Z_QuickPrint8.png (47.46 KiB) Viewed 1500 times
Rectifier would save the day - but rectifying 16mV.. haven't seen diodes having forward voltage of <150mV so direct rectification is out of question.

User avatar

22 Jul 2019, 07:12

..there's this wonderful chip, cheap as dirt (about $7 for a hundred) - TA7642. It is an AM radio chip - but if you think about it, AM radio is just a very sensitive rectifier, so hooking a naked TA7642 (w/o compensating resistors - resistor between output and power, cheap diode with 100pF capacitor between output and ground) may just be the ticket.

I'll try to use the op amps - and failing that (which I kind of expect - those opamps GBW is just 3MHz), comparators - to reduce number of external components. But if I'll get sucked in by work - try TA7642, it's likely to work.

User avatar

25 Jul 2019, 00:06

Comparator + VDAC as reference.

VDAC 8mV - noisy resting state, solid pressed. 12mV - solid resting, noisy pressed :/

I mean debouncing is needed anyway, but would like to see something more stable.

User avatar

25 Jul 2019, 11:07

Made a 2-column keyboard - AMux + VDAC + comparator + SR flip-flop, @80MHz.
2-step debouncing is mostly OK, especially if you trim the comparator right between the unstable regions.

Comparators turned out to be seriously badass - can be trimmed +/-16 mV, so can easily shift 3 DAC steps if needed.
Not sure how to represent all this in configuration UI though. Probably won't - auto-trim to zero gives a threshold of ~3 on my rig.

Will make better sequencing logic tomorrow-ish to make it single-shot from the software side (Software will only need to "select column block, drive this row, read that register") and reduce pulse length to ~40-50ns so I can remove current-limiting resistors, reducing number of passive components required to zero.

User avatar

29 Jul 2019, 16:22

Matrix, 4x6, doesn't work and has wildly different characteristics.
In particular, it has huge ripple at the end of the strobe - and that ripple doesn't depend on key state.

Tried some methods, was not successful.

Comparator-based thresholds suck big time - you're blind and must check all the variants.

User avatar

15 Aug 2019, 10:17

OK. I've got this 2x6 piece of matrix (in background) to work.
588-fa229f0c-2233-43d4-ace4-d2ee57e552d0[1].jpg (64.77 KiB) Viewed 1221 times
Scope is invaluable. I screwed up both in hardware (several things) and software (skipping half of the init, then shorting all rows in debouncing by passing zero instead of the row) - and the scope allowed me to figure out that OK, the scanner is now working, the problem is in firmware.

Couldn't do it on ADCs, had to resort to comparators. Trigger levels are FOUR MILLIVOLTS. Step is 4mV, and 8mV doesn't work already - signal is too weak.
Pin placement is trickier than in original CommonSense, because there are 4 MUXes, which strains analog routing a bit. But it's nice to have 4 parallel read channels - things are faster that way.

Here's the sensor:
586-d55fadf5-ddec-445e-b5b0-e5747f82751d[1].jpg (111.41 KiB) Viewed 1221 times
And here's the driver/sequencer:
587-f0dd40b3-2464-4f7a-be6a-a15c055c13db[1].jpg (96.02 KiB) Viewed 1221 times
Will try to graft to this guy over the weekend, see what happens. Today is exactly 11 months since I've got it. Hopefully Sangdrax will be typing on it before it's a year ;D

Post Reply

Return to “Workshop”