TMK for a Hot-Splittable Keyboard? Trying to Understand TMK
Posted: 08 May 2017, 01:29
My goals are:
A: To initially get a functioning firmware on my main keyboard, so I can ACTUALLY USE IT!
B: To figure out a way to be able to poll/not poll a port expander over I2C, based on the logic level of a "sense" signal.
So, here's my progress so far.
First, I've made up a nice layout worksheet that has all the electrical rows and columns identified not he physical layout. It's top down view, so it'll be useful for defining my key layout too.
So, I did start with the TMK firmware. If it can do everything I need it to do, then I'll stick with it, but there's always the option of re-flashing the keyboard with something else in the future if I can't integrate the hot swappable port expander functionality into the code. The code for my Column and Row pin definitions are below:
Code: Select all
/* Column pin configuration
* col: 0 1 2 3 4 5 6 7 8 9 10 11 12
* pin: F0 F1 F4 F5 F6 D4 D5 D2 B7 B3 B2 B1 B0
Code: Select all
/* Row pin configuration
* row: 0 1 2 3 4 5 6
* pin: F7 B6 B5 B4 C7 C6 D3
Anyway, since I had to keep the matrix small, That super dense layout has almost no gaps, and row 6 is actually a tight cluster of keys in the top right corner. An alteration part way in resulted in the very top right key having a completely nonsensical matrix position, because the change was literally a bodge. Only three intersections in the entire matrix go unused (c0-r6, c1-r6, and c12-r4). This means my matrix does not directly conform to the physical key layout in some areas (all of Row 6 is in the top right corner, and the bottom row is "electrically" compressed to the left, and then includes the keys physically in the bottom right corner well).
Now, I'm stumped at my current place in the code...
What have not figured out yet, is whether the matrix definitions need to be ordered by electrical sequence, or if the values are arbitrary, and allow for physical sequence (as long as the row and column values are correctly defined). The obviously functional way is to lay the matrix out electrically. This seems to be what's assumed with most keyboards, as most keyboards physical layout and electrical layout probably match.
My question then is which (either, or both, or neither, or 42 ;D ) would be correct?
Electrically based layout:
Code: Select all
#define KEYMAP( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, \
K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, \
K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K5A, K5B, K5C, \
K62, K63, K64, K65, K66, K67, K68, K69, K6A, K6B, K6C \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C }, \
{ KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C }, \
{ KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C }, \
{ KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C }, \
{ KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47, KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_NO }, \
{ KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57, KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_##K5C }, \
{ KC_NO, KC_NO, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67, KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C } \
}
Physically based layout
Code: Select all
#define KEYMAP( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K62, K6B, K6C, K65, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K63, K69, K6A, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K64, K67, K68, \
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K5C, K66, \
K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K5A, K5B, \
K50, K51, K52, K53, K54, K55, K56, K57, K58, K59 \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K62, KC_##K6B, KC_##K6C, KC_##K65 }, \
{ KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K63, KC_NO, KC_##K69, KC_##K6A }, \
{ KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K64, KC_NO, KC_##K67, KC_##K68 }, \
{ KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_NO, KC_NO, KC_##K5C, KC_##K66 }, \
{ KC_##K40, KC_NO, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47, KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_NO, KC_NO, KC_##K5A, KC_##K5B}, \
{ KC_##K50, KC_##K51, KC_##K52, KC_NO, KC_NO, KC_NO, KC_##K53, KC_NO, KC_NO, KC_NO, KC_##K54, KC_##K55, KC_##K56, KC_NO, KC_##K57, KC_##K58, KC_##K59 } \
}
My understanding of the code, is that those lists are not "technically" even different lines... That they are basically one long continuous list, with breaks to make it easier to read. What I don't know is whether the code expects to read the list strictly sequentially, the same way it's scanning the matrix, or whether the code is simply defining the physical layout of the key map and defining what matrix intersection applies to the physical layout. I'm confused!
Basically, is the code:
A: expecting all the rows and columns to be in a neat and orderly incrementing layout (all the columns, in order, 0 to the maximum, for row 0, then repeating for row 1, 2, 3... and so on)
or
B: Is this list arbitrarily defining the row/column intersection values for the (later to be entered) keymap, based on the row and column numbers entered. Basically, saying "I want this layout to have r0-c0 through r0-c12, then r6-c3, r6-c11, r6-c12, and finally r6-c5 in the first physical row of keys"... Basically, so later, when I enter the keymap, it knows that ESC is r0-c0, F1-F12 is r0-c1 through r0-c12, and that F13 is r6c3, F14 is r6-c11, F15 is r6-c12, and the media EJECT key is r6-c5 (using my top row as an example).
Does that make sense?
I suppose I should also add, I know software is flexible, and I can always integrate new features later on. For now, I just wanna get my keyboard up and running. It's been a YEAR! In the long term though, I want to have the code check whether pin E6 changes states. Depending on whether it is high or low, I want to have it scan a 6x6 matrix on a port expander connected over I2C, or to skip the I2C part of the code altogether and ignore that part of the matrix. I don't yet know how I would go about doing this in the code, and I don't even know if this firmware can even be modded to support it at all. Of course, that's the nice thing about software... There's always room for change. I just don't know how.
I think, for the transistor driven under-lighting LEDs in each switch housing, I just want to have a default minimum brightness setting at power up, and the option to change the brightness with the keyboard. I already have the max brightness current limited to stay under the USB max current, but I think at power up it'd be wise to keep total draw under 200 mA, and then let the keyboard negotiate 500 mA if you increase brightness... Again, I imagine it's possible, but I don't know if TMK can do it, or how easy it'd be to mod that functionality in. I just don't want the keyboard to require an external power source to power all the LEDs, nor do I want it to trigger "The USB device is drawing too much power" warnings. It'd be nice if it were possible to cap max brightness based on USB power negotiation. I know devices can request up to 500 mA, but initial connections default to 100 mA (if the devices play friendly with he protocol).