CGX 32-key keypad

MMcM

22 Jun 2020, 06:19

I got this CAD keypad from RedMarket, whose prices are quite reasonable for some interesting stuff.
CGX-case-top.jpg
CGX-case-top.jpg (2.26 MiB) Viewed 1357 times
The front is branded CGX, but the back has an Adage QC stamp, so it must have been well after that acquisition had integrated the two companies. The case is dated 6/88 and the PCB 3/88.
CGX-case-bottom.jpg
CGX-case-bottom.jpg (2.15 MiB) Viewed 1357 times
It's like the HP 46086A and even more like the IBM LPFK, in that each switch has an individual red LED. Adage also had their similar devices on their own somewhat earlier workstations.
Adage-4370-NCAD-1984.jpg
Adage-4370-NCAD-1984.jpg (280.48 KiB) Viewed 1357 times
The switches are vintage Cherry MX Whites (the early, less pigmented, ones). The cable is around two meters long and ends in an RJ12.

The PCB has Cherry model number 4060-A.
CGX-PCB-bottom.jpg
CGX-PCB-bottom.jpg (1.99 MiB) Viewed 1357 times
And an MTI manufacturing tag.
CGX-PCB-top.jpg
CGX-PCB-top.jpg (1.78 MiB) Viewed 1357 times
That's a lot of 74-series TTL for a 32-key keyboard from the late '80s. The reason is that there aren't actually any programmable logic elements there: the 40-pin chip is a UART.

Which means that its function can be entirely derived from the schematic:
  • U1, a GI UAR/T (sic), inverts SI to J1:3 and SO to J1:4.
  • Y1, the crystal, clocks it for 9600 baud.
  • U4, a 4-bit counter, divides that same clock signal.
  • U5, a flip-flop, latches the 4 column scan signals and loads them for output into DB1-4.
  • DB5,7-8 are held high.
  • DB6 indicates counter wrap-around.
  • U7-10, latch the LED states; inputs are bussed from U12, another flip-flop, loaded from RD1-4; the outputs go to the individual LEDs; only one row is clocked at a time.
  • RD5 triggers U3, the row counter's, resets RO(1-2).
  • DS is driven by U6, a flip-flop wired as a shift-register and acting as a delay-line from DAV.
And, so, in terms of protocol:
  • The keyboard only outputs a byte immediately after it receives one, so that the host is in charge of higher-level timing. Nothing will happen just connecting up the output serial.
  • The keys and LEDs form eight rows of four columns each.
  • Each received byte sets the current row's LEDs, with zero meaning on, and advances the row number, unless 0x10 is zero, in which case it resets the row number.
  • It is therefore reasonable to initialize or reset communication by sending 0x0F and otherwise use 0x1x.
  • Shortly after receiving an LED byte, the keyboard responds with a button byte for the same row, with one meaning pressed.
  • When the transmitted row number wraps around, the keyboard response has the 0x20 clear.
  • The other three bits are one, so 0xFx means incremented row and 0xDx means started over.
This is a very chatty protocol: the LEDs have to be constantly set, even when not changed, in order to keep up with key presses. Which means that they are effectively PWM'ed at 9600 / 10 / 8 = 120Hz, which is kinda slow, but not impossible.

A Teensy converter.
CGX-converter.jpg
CGX-converter.jpg (1.27 MiB) Viewed 1357 times
I used a 2.0 and a separate 74LS04N inverter, instead of a 3.x with invertable UART signals, out of respect for the three of them in the keypad itself.

For the QMK implementation, I hooked up the LEDs to the existing LED matrix API. There aren't a lot of interesting effects in the library out of the box. And this keypad originally meant to prompt the user though the LEDs, which requires host control, which is unfortunately quite limited in modern keyboards, even with all their backlight features. And, of course, completely unsupported on the operating system side.

So, by way of example, I added a user routine that lights and fades each LED as you press it, along with some default function key assignments.

User avatar
TheInverseKey

22 Jun 2020, 06:29

Nice write up, great that you provided the code as well! :D

Post Reply

Return to “Workshop”