Soarer's Keyboard Controller firmware
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
Here is my Controller firmware for AVR microcontrollers with hardware USB, e.g. Teensy 2.0, Teensy++ 2.0.
The main difference between this and other controller firmwares is that all configuration is performed using a config file, rather than modifying the C source code. A few example matrix configs are included, covering some very different keyboards.
Retrete was the initial guinea pig with his vintage Kevex terminal - the discussion there serves as an example walk-though of how to apply this firmware to a keyboard. Two videos as well!
The best way to approach making the matrix config is to first set it up with all keys set to 'UNASSIGNED', then to use hid_listen to see which matrix code fires for each key and debug any wiring problems. That way you don't get unintended keystrokes sent to your OS, which could be painful!
All of the features of my Converter (NKRO, remapping, layer, macro, etc) are supported (except, of course, 'ifset').
Matrix scans can include 'classic' matrix (direct connections to rows and columns), multiplexed (strobes are driven through a decoder), and unstrobed (where individual keys are connected to pins). Various polarity and mode settings are available to cover many requirements. There's also options for scan rate, debouncing time and mode, including turbo mode which adds no delay, and a blocking flag to enable de-ghosting.
Currently at beta stage, with only bugfixes and minor changes expected before the first proper release. There is a single .html page included in the zip describing the Controller specific configuration - you'll also need the docs from my Converter (available on DT and GH).
Required hardware is an AVR microcontroller with more than 16KB RAM, and hardware USB with a decent amount of buffer memory. This includes the ATmega32U4 and better, but does NOT include the ATmega32U2.
The main difference between this and other controller firmwares is that all configuration is performed using a config file, rather than modifying the C source code. A few example matrix configs are included, covering some very different keyboards.
Retrete was the initial guinea pig with his vintage Kevex terminal - the discussion there serves as an example walk-though of how to apply this firmware to a keyboard. Two videos as well!
The best way to approach making the matrix config is to first set it up with all keys set to 'UNASSIGNED', then to use hid_listen to see which matrix code fires for each key and debug any wiring problems. That way you don't get unintended keystrokes sent to your OS, which could be painful!
All of the features of my Converter (NKRO, remapping, layer, macro, etc) are supported (except, of course, 'ifset').
Matrix scans can include 'classic' matrix (direct connections to rows and columns), multiplexed (strobes are driven through a decoder), and unstrobed (where individual keys are connected to pins). Various polarity and mode settings are available to cover many requirements. There's also options for scan rate, debouncing time and mode, including turbo mode which adds no delay, and a blocking flag to enable de-ghosting.
Currently at beta stage, with only bugfixes and minor changes expected before the first proper release. There is a single .html page included in the zip describing the Controller specific configuration - you'll also need the docs from my Converter (available on DT and GH).
Required hardware is an AVR microcontroller with more than 16KB RAM, and hardware USB with a decent amount of buffer memory. This includes the ATmega32U4 and better, but does NOT include the ATmega32U2.
- Attachments
-
- Soarer_Controller_v1.20_beta4.zip
- (446.02 KiB) Downloaded 2763 times
Last edited by Soarer on 03 Nov 2013, 16:10, edited 2 times in total.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Fantastic timing, Soarer. I'll give this a shot in my little hand wired 60%.
What software tools do we need? I was daunted when trying Hasu's, by the fiddliness of installing the appropriately old version of the PJRC dev tools on my G4 iMac. Less is definitely more, for me. In physical layouts and software dependencies!
What software tools do we need? I was daunted when trying Hasu's, by the fiddliness of installing the appropriately old version of the PJRC dev tools on my G4 iMac. Less is definitely more, for me. In physical layouts and software dependencies!
- Halvar
- Location: Baden, DE
- Main keyboard: IBM Model M SSK / Filco MT 2
- Favorite switch: Beam & buckling spring, Monterey, MX Brown
- DT Pro Member: 0051
Downloaded and sifting through the documentation. This seems to make it way easier for anyone to build a custom keyboard or revive a vintage keyboard matrix, as you don't even need a development environment or programming skills. Great stuff Soarer!
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Excellent! Editing text files and running (often self-hacked) make scripts are what I do. Had to build my own hid_listen for PowerPC as well as scas, scwr etc. for the converter. Piece of cake.
I'm away from the computer so can't delve around until later. But it's sounding good. Just like Soarer's last magnum opus.
I'm away from the computer so can't delve around until later. But it's sounding good. Just like Soarer's last magnum opus.
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
Hopefully just what is included in the zip, plus hid_listen from PJRC, plus whatever loader your breakout board's bootloader requires (e.g. Teensy loader for Teensy).Muirium wrote:What software tools do we need?
What OS are you running? The OS-X build of my tools is compiles under Snow Leopard, and to be honest I'm not really sure which OS versions they will work on!
But, if my converter's tools work for you, then these will too
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
I run Leopard on the old iMac (which I keep in my workshop for iTunes, so it's also conveniently placed for keyboard programming) and your converter tools compile quite nicely with a little coercion. So I should be in luck! Thanks again.
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
In many ways this is simply an extension of that! I'm hoping this beta keeps people happy for quite a while, so I can look at putting some of the configurable pin stuff into the converter code - easy for the LEDs and switch inputs, not so easy for the clock signal that drives an interruptMuirium wrote:Just like Soarer's last magnum opus.
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
They must sell so many of them though; I doubt even all keyboard projects account for much of it!Halvar wrote:Just ordered another Teensy. PIRJ should start paying you a commission, Soarer. (I know there are alternatives)
True about alternatives for Teensy 2.0, but the one that's much cheaper doesn't have all the pins broken out
Teensy++ 2.0 doesn't have many viable alternatives at all... and full-size keyboards with direct (non-multiplexed) connections to the matrix will probably require the number of pins it's got.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Reuse is just as welcome for we users of your controller as it is for your own efforts, as "this is a UNIX system, I know this!" Reading through the one and only doc just now, I like what I see. And here is my first question.
Here's my 15x5 matrix. I have diodes hooked to the rows by their cathodes.
What strobe_mode should I use (I assume the default of course) and which axis shall I make the strobes and which the senses?
Here's my 15x5 matrix. I have diodes hooked to the rows by their cathodes.
What strobe_mode should I use (I assume the default of course) and which axis shall I make the strobes and which the senses?
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
Default strobe mode is good - a bit safer to strobe low, and doesn't need extra resistors to pull-down. Your diodes are reversed compared to say a Cherry 'board (which would strobe many columns and sense 8 rows), but if you strobe the 5 rows and sense the 15 columns, it should work out fine!
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Cool! I simply copied Matt3o's method of hand wiring a matrix, right down to diode polarity. Conveniently, strobing rows and sensing columns that means my .sc config file will have the matrix written out in the same orientation as the physical board, which ought to save me a few headaches.
The (legged / prototyping) Teensy 2 I just flashed with the firmware happened to already have your converter installed on it from previous work. This confused me when it still reported to the computer as "Soarer's Keyboard Converter", and even responds nicely to the converter version of scinfo! But of course both converter and controller are built from the same base, so I figured it out after a while.
Incidentally, the only downside I can think of to this ingenious extension of your converter is that tmk_keyboard lets you name your keyboard over USB. While a nice feature, I never did get quite as far as successfully compiling it! But so far so good with yours.
The (legged / prototyping) Teensy 2 I just flashed with the firmware happened to already have your converter installed on it from previous work. This confused me when it still reported to the computer as "Soarer's Keyboard Converter", and even responds nicely to the converter version of scinfo! But of course both converter and controller are built from the same base, so I figured it out after a while.
Incidentally, the only downside I can think of to this ingenious extension of your converter is that tmk_keyboard lets you name your keyboard over USB. While a nice feature, I never did get quite as far as successfully compiling it! But so far so good with yours.
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
Hmm, that's something I missed then!
Actually, another painkiller might be to define an extra dummy sense line, so that the hex scancodes that hid_listen spits out are easy to translate. Just use an unused pin or one of the other sense pins again, but set all keys to be unassigned.
Actually, another painkiller might be to define an extra dummy sense line, so that the hex scancodes that hid_listen spits out are easy to translate. Just use an unused pin or one of the other sense pins again, but set all keys to be unassigned.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Here's my code, punched in while scrutinising the matrix picture above and the finished keyboard with caps on it! Note how wide it looks. That's largely thanks to UNASSIGNED and a few other long names. They're not a problem in formatting code for the converter, but when writing a matrix out like this, it'd be nice to have shorthand versions.
Pin D6 is the one to avoid, right?
Built and written to the Teensy. Now I'd better hook up some strobes and senses!
Code: Select all
# Muirium's Shiny 60%
matrix
scanrate 1
debounce 5
blocking 0
sense PF7 PB6 PB5 PB4 PD7 PD4 PD5 PC7 PC6 PD3 PD2 PD1 PD0 PB7 PB3 PB2
strobe PF0 esc 1 2 3 4 5 6 7 8 9 0 minus equal back_quote system_power UNASSIGNED
strobe PF1 tab q w e r t y u i o p left_brace right_brace UNASSIGNED backspace UNASSIGNED
strobe PF4 caps_lock a s d f g h j k l semicolon quote UNASSIGNED enter UNASSIGNED UNASSIGNED
strobe PF5 lshift z x c v b n m comma period slash UNASSIGNED rshift UNASSIGNED FN1 UNASSIGNED
strobe PF6 lctrl lalt lgui UNASSIGNED UNASSIGNED space UNASSIGNED UNASSIGNED UNASSIGNED rgui ralt UNASSIGNED rctrl UNASSIGNED pad_enter UNASSIGNED
end
Built and written to the Teensy. Now I'd better hook up some strobes and senses!
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
Yeah, PD6 has the LED on it, and my firmware still uses it - I guess that should be configurable too!
The names are only used in the tools, so you could add some aliases to the table in common/hid_tokens.cpp and recompile. I might add a short name for 'unassigned' (probably 'none'), but the rest don't bother me
The names are only used in the tools, so you could add some aliases to the table in common/hid_tokens.cpp and recompile. I might add a short name for 'unassigned' (probably 'none'), but the rest don't bother me
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
And now my little keyboard is up and running. Thanks Soarer. This controller is perfect! I can have my cake and eat it. The same layers and macros on my eighties IBMs and brand new USB keyboard, exactly where my fingers want them. Genius.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
I'm thinking about trying this on a hand wired matrix without any diodes, built specifically to test the blocking logic. Not because I'm short of diodes but because I'm investigating what this controller could do for a currently 2KRO 122 key Model M.
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
I expect it will be the same. As in, my logic is conservative, and I expect IBM's is too!
I tried to think of a way to allow certain cases, but it gets horribly compicated. Consider four keys on a matrix:
A B
C D
If all positions have switches, D would ghost when A+B+C are pressed. So, conservative logic blocks after two of {A,B,C} are pressed. The code is a fairly simple loop which checks how many other keys are pressed on each pressed key's row and column - if it's one or more on each, then it blocks.
If there is no key at position D, then it wouldn't ghost with A+B+C. But, any logic that would allow that has to cope with all kinds of circuitous routes around the matrix. As far as I can tell it's simply not practical, and perhaps not even possible. I guess a 'gaming optimised' matrix simply puts it's groups of non-blocking keys on the same row or somesuch (for a blocking matrix, the maximum number of keys that can be pressed without blocking is num_columns - 1 + num_rows - 1).
Bear in mind that after say A+B are pressed, pressing C also presses D, even if there is no switch on the board. So the controller sees them both at the same time, and all it has to go on is the current and previous states. For a bigger matrix than 2x2, it gets even less information...
A B C D E
F G H I J
K L M N O
P Q R S T
Say B+C+D+E + F+K+P are pressed. That's fine, no blocking. Then A gets pressed as well. Boom, EVERY key on that matrix is pressed!
I tried to think of a way to allow certain cases, but it gets horribly compicated. Consider four keys on a matrix:
A B
C D
If all positions have switches, D would ghost when A+B+C are pressed. So, conservative logic blocks after two of {A,B,C} are pressed. The code is a fairly simple loop which checks how many other keys are pressed on each pressed key's row and column - if it's one or more on each, then it blocks.
If there is no key at position D, then it wouldn't ghost with A+B+C. But, any logic that would allow that has to cope with all kinds of circuitous routes around the matrix. As far as I can tell it's simply not practical, and perhaps not even possible. I guess a 'gaming optimised' matrix simply puts it's groups of non-blocking keys on the same row or somesuch (for a blocking matrix, the maximum number of keys that can be pressed without blocking is num_columns - 1 + num_rows - 1).
Bear in mind that after say A+B are pressed, pressing C also presses D, even if there is no switch on the board. So the controller sees them both at the same time, and all it has to go on is the current and previous states. For a bigger matrix than 2x2, it gets even less information...
A B C D E
F G H I J
K L M N O
P Q R S T
Say B+C+D+E + F+K+P are pressed. That's fine, no blocking. Then A gets pressed as well. Boom, EVERY key on that matrix is pressed!
Last edited by Soarer on 06 Nov 2013, 18:32, edited 1 time in total.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
The annoying thing about this Model M is that blocking happens pretty quickly even with the mods. I pile those on frequently in routine text editing, and one example on that board is that I can Shift+Control+Arrow Key with one Control and not the other. Grr!
I have pictures of the matrix I could post that I shot while doing its bolt mod. The traces look like some thought did indeed go into rerouting them from the obvious, but its designers priorities were for its terminal system, not my own selection of keys.
And that's why NKRO matters, folks. It's all about which keys get tangled up in limited rollover.
I have pictures of the matrix I could post that I shot while doing its bolt mod. The traces look like some thought did indeed go into rerouting them from the obvious, but its designers priorities were for its terminal system, not my own selection of keys.
And that's why NKRO matters, folks. It's all about which keys get tangled up in limited rollover.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Is there a maximum matrix size for this controller, besides the available pins themselves? I'm thinking about an NKRO USB mod to an 8x16 PS/2 Tipro…
I like the Tipro's layer locks and lights, but its (reprogramming) software is a pain and I don't have PS/2 ports on most my computers anyway, so it's getting little use. A hand wired matrix and a Teensy++ 2 might just do the trick.
I like the Tipro's layer locks and lights, but its (reprogramming) software is a pain and I don't have PS/2 ports on most my computers anyway, so it's getting little use. A hand wired matrix and a Teensy++ 2 might just do the trick.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Great! Expect no less!Soarer wrote:It should handle 256 keys, with no limit on the shape of the matrix (besides available pins).
I don't think it does, in fact. The current rollover is pretty weak, but the software's so opaque to me I need to open it up to be sure. Lemme get my screwdriver… No diodes here. (Unless they're hidden on the top side under the plate?) That explains it. This matrix is just as naturally limited as my Model Ms, but (with a lot of de/soldering) it doesn't have to stay that way.Not sure why hand-wired... unless it doesn't have diodes...?
The only thing I'll lose (besides the crummy software and rollover) is layer locks. Well, it's not like I was using those at this rate. But if and when, they'd make a fine addition to the controller and converter suite. Unlike my own builds, this keyboard has all the layer indicator lights already in place.
I guess it's the same deal with the Teensy++ 2 and how many pins you can actually use: beware the one with the LED on it?
Hmm… I think recognise this guy: You have rivals in Slovenia!
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
Ha! But a lesser chip, with no USB
So, no diodes. Will take a bit of track cutting - you might get away with not having to desolder it, since most of the switches have the track to the more central pin visible on the back. Although, the pattern isn't as regular for those few switches near the chips, hmm.
Teensy++ 2.0 has so many pins that the onboard LED isn't likely to get in the way! But yeah, avoid it.
So, no diodes. Will take a bit of track cutting - you might get away with not having to desolder it, since most of the switches have the track to the more central pin visible on the back. Although, the pattern isn't as regular for those few switches near the chips, hmm.
Teensy++ 2.0 has so many pins that the onboard LED isn't likely to get in the way! But yeah, avoid it.
- lamune
- Main keyboard: IBM 122
- Main mouse: Razer Habu
- Favorite switch: Buckling spring
- DT Pro Member: -
Soarer - any idea why upgrading to the new beta firmware would cause the keyboard to not work at all? hid_listen doesn't even show the converter initialize. It's detected, but there's no communication. Reverting to 1.10, all is well.
Also, any movement toward a KVM-friendly option? The hard connects/disconnects between machines is really killing me
Also, any movement toward a KVM-friendly option? The hard connects/disconnects between machines is really killing me
- Soarer
- Location: UK
- Favorite switch: F
- DT Pro Member: -
You're gonna kick yourself This is Controller, not Converter!
Can't promise when anything KVM friendly will come along (pretty busy at the moment), but haven't forgotten about it. I guess we could try a test first that simply removes the NKRO/Media endpoint.
Can't promise when anything KVM friendly will come along (pretty busy at the moment), but haven't forgotten about it. I guess we could try a test first that simply removes the NKRO/Media endpoint.
- lamune
- Main keyboard: IBM 122
- Main mouse: Razer Habu
- Favorite switch: Buckling spring
- DT Pro Member: -
Oh, duh. Sorry, I think I needed more sleep!
I'm not sure what component of the converter is not "KVM safe" - it may be the high-speed mode or something else. In BIOS mode, as an example, it's especially bad- if you press a "nonstandard" key, the keyboard stops working entirely. Anyway, off topic at this point, but I'm still willing to beta-test!
I'm not sure what component of the converter is not "KVM safe" - it may be the high-speed mode or something else. In BIOS mode, as an example, it's especially bad- if you press a "nonstandard" key, the keyboard stops working entirely. Anyway, off topic at this point, but I'm still willing to beta-test!
-
- Location: Belgium, land of Liberty Wafles and Freedom Fries
- Main keyboard: G80-3K with Clears
- Favorite switch: Capacitative BS
- DT Pro Member: 0049
I've been thinking about experimenting with touch buttons on a 60% keyboard so that I have some easy-to-hold Fn buttons.
I found a simple touch detection circuit on the Internet (see http://www.eeweb.com/blog/extreme_circu ... h-detector ) using a Schmitt-trigger. Electronics isn't my forte, so I'd like to know if it is a good idea to connect the output of that IC directly a pin of the Atmel microcontroller without a resistor. If it does need a resistor, what value would you propose?
Also, I guess I'd have to add an "unstrobed" line in my matrix, right?
I found a simple touch detection circuit on the Internet (see http://www.eeweb.com/blog/extreme_circu ... h-detector ) using a Schmitt-trigger. Electronics isn't my forte, so I'd like to know if it is a good idea to connect the output of that IC directly a pin of the Atmel microcontroller without a resistor. If it does need a resistor, what value would you propose?
Also, I guess I'd have to add an "unstrobed" line in my matrix, right?
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Unstrobed: yes. So you'd better have a spare pin. As for electronic concerns, I defer to those with >0.5 clues on the matter.
Where are you planning on putting the pad? Looks like it needs direct exposure on the keyboard exterior, and to be electrically insulated from ground etc. too.
Where are you planning on putting the pad? Looks like it needs direct exposure on the keyboard exterior, and to be electrically insulated from ground etc. too.