Author Topic: TMK keyboard firmware  (Read 818511 times)

0 Members and 1 Guest are viewing this topic.

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #200 on: Thu, 07 November 2013, 13:18:58 »
Does this look right for my matrix file:

Code: [Select]
/* Column pin configuration
 * col: 0   1   2   3   4   5   6   7   8   9
 * pin: E1  C0  C1  C2  C3  E6  F0  F1  F2  F3
 */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRC  &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3);
    PORTC |=  (1<<0 | 1<<1 | 1<<2 | 1<<3);
    DDRE  &= ~(1<<1 | 1<<6);
    PORTE |=  (1<<1 | 1<<6);
    DDRF  &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3);
    PORTF |=  (1<<0 | 1<<1 | 1<<2 | 1<<3);
}

static matrix_row_t read_cols(void)
{
    return (PINE&(1<<1) ? 0 : (1<<0)) |
           (PINC&(1<<0) ? 0 : (1<<1)) |
           (PINC&(1<<1) ? 0 : (1<<2)) |
           (PINC&(1<<2) ? 0 : (1<<3)) |
           (PINC&(1<<3) ? 0 : (1<<4)) |
           (PINE&(1<<6) ? 0 : (1<<5)) |
           (PINF&(1<<0) ? 0 : (1<<6)) |
           (PINF&(1<<1) ? 0 : (1<<7)) |
           (PINF&(1<<2) ? 0 : (1<<8)) |
           (PINF&(1<<3) ? 0 : (1<<9)) ;
}

/* Row pin configuration
 * row: 0   1   2   3   4   5   6   7
 * pin: C4  C5  C6  C7  F4  F5  F6  F7
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRC  &= ~0b11110000;
    PORTC &= ~0b11110000;
    DDRF  &= ~0b11110000;
    PORTF &= ~0b11110000;
}

static void select_row(uint8_t row)
{
    // Output low(DDR:1, PORT:0) to select
    switch (row) {
        case 0:
            DDRC  |= (1<<4);
            PORTC &= ~(1<<4);
            break;
        case 1:
            DDRC  |= (1<<5);
            PORTC &= ~(1<<5);
            break;
        case 2:
            DDRC  |= (1<<6);
            PORTC &= ~(1<<6);
            break;
        case 3:
            DDRC  |= (1<<7);
            PORTC &= ~(1<<7);
            break;
        case 4:
            DDRF  |= (1<<4);
            PORTF &= ~(1<<4);
            break;
        case 5:
            DDRF  |= (1<<5);
            PORTF &= ~(1<<5);
            break;
        case 6:
            DDRF  |= (1<<6);
            PORTF &= ~(1<<6);
            break;
        case 7:
            DDRF  |= (1<<7);
            PORTF &= ~(1<<7);
            break;
    }
}

I didn't understand the matrix file in the hhkb directory, so I used the GH60 as an example.  Should this work?  Why is the hhkb matrix file so different?  I don't see any of the columns/rows information in the hhkb version...


Also, I'm using a teensy 2++.  Just curious, why is there no E2 or E3 pin?  Are these the GND and REF pins in the middle on the right?

On the subject of LED's...I see the hhkb files use this:
Code: [Select]
void led_set(uint8_t usb_led)
{
    if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
        DDRD |= (1<<6);
        PORTD |= (1<<6);
    } else {
        DDRD |= (1<<6);
        PORTD &= ~(1<<6);
    }
}

This means the led on the Teensy will light up, correct?  So no LED's on the actual hhkb, just using the built in one on the chip...


And one last thing:  I successfully compiled the firmware for my keyboard!  Only received one warning:
../../common/action_tapping.c:328: warning "waiting_buffer_has_anykey_pressed" defined but not used
Should I do anything about this?  It doesn't sound too bad...

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #201 on: Thu, 07 November 2013, 16:19:35 »
1) your matrix.c looks ok to me.
2) HHKB has capacitive switches and unusual matrix(which uses multiplexers to select col/row lines and  sensor chip to see switch state).
3) PE2,3 have special functions, not so useful for general I/O use.
4) As for led, you are right. But I don't remember whether it works or not in my HHKB :)
5) you can safely ignore that warning, I'll fix it later.

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #202 on: Sun, 10 November 2013, 17:22:29 »
Just a quick update:  I wired up a 2 key testing keyboard.  So far everything works as expected.  It was pretty cool hitting a key switch (bare with no keycap) that I had just soldered up to a few wires and a diode and have letters pop up on my monitor.

4) As for led, you are right. But I don't remember whether it works or not in my HHKB :)

I can confirm that using the Teensy's built-in LED for the Caps Lock light works perfectly, at least with my hacked together 2 key test board.  So good, that I'm not going to bother wiring up an LED on my final board.


It will probably take me a while longer to get my keyboard built and working the way I want, but I will post back here when I do.  With any luck, I will have something to report/show-off in the next week or two.

Thanks for all the help!!!

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #203 on: Mon, 11 November 2013, 15:40:36 »
Back again so soon?

Sorry, one thing I'm trying is just not working.  I'm sure it's my lack of C experience.

The design I'm working on is using a very limited number of keys.  All of my layer switching is currently done using ACTION_LAYER_TAP_KEY.  So every layer key also doubles as a regular key.  I just don't have space on my board for a key that only works as a layer toggle.

But...I would really like a toggle key...And then I discover ACTION_FUNCTION_TAP...Cool! But, urgh...I can't get it to work!  I want the key to toggle layers only if it is tapped 3 times.  I don't want to accidentally switch to the other layer during normal typing.  If it is tapped only once or twice it will register the regular key.  I tried lots of variations on the same code.  Everything else I tried would register the regular tapped key, but would not toggle layers, no matter how fast or how many times I tapped it.  This is the only one that would actually switch layers:

Code: [Select]
        case TAP3LAY1_T:                                        // Layer 1 toggle on and tap T
                if (tap.count != 3) {
                    add_key(KC_T);
                    send_keyboard_report();
                    del_key(KC_T);
                    send_keyboard_report();
                } else {
                    layer_on(1);
                }
                break;

But a single tap registers "tt" instead of just "t".  So what is happening is I tap once and have "tt", then tap again and have "tttt", then tap a third time and the layers switch.  Why is the T registering twice for each tap?!

Once I solve that, I'm pretty sure I can just add:
Code: [Select]
                } else {
                    add_key(KC_BSPC);
                    send_keyboard_report();
                    del_key(KC_BSPC);
                    send_keyboard_report();
                    add_key(KC_BSPC);
                    send_keyboard_report();
                    del_key(KC_BSPC);
                    send_keyboard_report();
                    layer_on(1);
to get rid of the first two taps before the layers switch.  So a single tap would give you "t", then another tap "tt" then a thrid tap and both "tt" delete and the layers switch.  But first I need to fix whatever is causing it to register twice for each tap...

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #204 on: Tue, 12 November 2013, 01:05:28 »
You should handle release event properly too. Does this work? I didn't compile and test it at all.

Code: [Select]
if (event.pressed) {
    if (tap.count < 3) {
        register_code(KC_T);
    } else {
    }
} else {
   if (tap.count < 3) {
        unregister_code(KC_T)
   } else if (tap.count == 3) {
        register_code(KC_BSPC);
        unregister_code(KC_BSPC);
        register_code(KC_BSPC);
        unregister_code(KC_BSPC);
        layer_invert(1);
   }
}

I'm not sure  this is useful actually for you, this may work on text editor but not on web browser. If you type 'ttt' to change layer then you will get two page history back.

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #205 on: Tue, 12 November 2013, 08:21:38 »
I'm not sure  this is useful actually for you, this may work on text editor but not on web browser. If you type 'ttt' to change layer then you will get two page history back.

Really?!  Which browser does this?  I just tried it on IE8 and Chrome but nothing happened.  Maybe I'm not using the shortcut correctly.

Thanks for the coding help.  I know it may be a silly idea.  Right now I'm just experimenting with different layouts and Fn keys to see what works.

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #206 on: Tue, 12 November 2013, 22:37:38 »
Just in case anyone else is following this...

I had some issues with the code as written from hasu.  It would only register 1 T then nothing until I did a quick triple tap to switch layers.  I think it may have had something to do with having the "unregister_code" nesting in another IF statement.  The following code works perfect:

Code: [Select]
        case TAP3LAY1_T:                                        // Layer 1 toggle on and tap T
            if (event.pressed) {
                if (tap.count != 3) {
                    register_code(KC_T);
                    unregister_code(KC_T);
                } else if (tap.count == 3) {
                    register_code(KC_BSPC);
                    unregister_code(KC_BSPC);
                    register_code(KC_BSPC);
                    unregister_code(KC_BSPC);
                    layer_on(1);
                }
            }
        break;

It's yet to be seen whether this feature will make it in my final board.  I still need an actual board to test my ideas on.  Right now I just have 2 keys wired up so I can test to make sure my mod of the firmware works.  Who knows if I will like using it!  I'm procrastinating on wiring up my board, mainly because I'm not sure if I really like the plate I have.  Another "for parts" vintage board is coming in the mail - should get here tomorrow - so I may start my build then.

As always, thanks for all the help!
Sean

Offline harifun07

  • Posts: 4
Re: TMK keyboard firmware
« Reply #207 on: Tue, 19 November 2013, 05:51:31 »
Excuse me, may I ask a question what this code is used for.

Keyboard.c--void keyboard_task

for (uint8_t c = 0; c < MATRIX_COLS; c++) {
                if (matrix_change & ((matrix_row_t)1<<c)) {
                    action_exec((keyevent_t){
                        .key = (key_t){ .row = r, .col = c },
                        .pressed = (matrix_row & ((matrix_row_t)1<<c)),
                        .time = (timer_read() | 1) /* time should not be 0 */
                    });

I am wondering what is the time used for? Filtering or other use?

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #208 on: Tue, 19 November 2013, 06:40:07 »
.time is used to know elapse of key event by Tapping. Tap key(Dual role key) needs time lapse and its behaviour depends on time factors between key events.
https://github.com/tmk/tmk_keyboard/blob/master/doc/keymap.md#4-tapping
http://geekhack.org/index.php?topic=41685.0

You can find this use of .time In common/action_tapping.c. messy code, though...
I'm not sure I could answer your question, ask me again if you need.

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #209 on: Tue, 26 November 2013, 18:34:51 »
I have a minor problem...

I used PEQL in my keymap. The firmware builds just fine, but my computer doesn't register anything when I press that key. Any ideas?  The key is in a secondary layer, but all the other tenkey codes (like PMNS, PCMM, P1, etc) work just fine.  Thanks for any help!

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #210 on: Tue, 26 November 2013, 20:06:59 »
PEQL indicates = on keypad. Look PC keyboards, you will find they don't have it. So I guess your computer is  Windows and it doesn't support the key from historical reason.

Try other OS if you should use keypad =, otherwise you can just normal =.

Offline metalliqaz

  • * Maker
  • Posts: 4951
  • Location: the Making Stuff subforum
  • Leopold fanboy
Re: TMK keyboard firmware
« Reply #211 on: Tue, 26 November 2013, 20:07:32 »
I have a minor problem...

I used PEQL in my keymap. The firmware builds just fine, but my computer doesn't register anything when I press that key. Any ideas?  The key is in a secondary layer, but all the other tenkey codes (like PMNS, PCMM, P1, etc) work just fine.  Thanks for any help!

Keypad equals is not supported in Windows according to Microsoft's Keyboard Scan Code Specification, unless I'm reading it wrong.  You may have to just map it to the Equals/Plus key

Edit: Darn, ninja'd by Hasu  :))

Offline IvanIvanovich

  • Mr. Silk Underwear
  • Posts: 8199
  • Location: USA
Re: TMK keyboard firmware
« Reply #212 on: Sat, 07 December 2013, 20:23:49 »
Hi,
I wanted to try out the updated firmware on my GH60 rev. A. I still using very old one from first days... anyway I am not understanding all the changes. What do I need to do to this to make it work in current?
Code: [Select]
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /*
     * GH60
     */
    /* Keymap 0: Default Layer
     */
    KEYMAP_ANSI(
        ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC, \
        TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSLS, \
        CAPS,A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,  \
        LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          RSFT, \
        LCTL,LALT,NO,          SPC,                     FN0, RGUI,APP, RCTL),
    /* Overlay 1: Fn mode
     */
    KEYMAP_ANSI(
GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, TRNS, \
TRNS,TRNS, UP,  TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,PAUS,VOLU,VOLD,MUTE, \
TRNS,LEFT,DOWN,RGHT,TRNS,TRNS,TRNS,TRNS,TRNS,INS,HOME, PGUP,      TRNS, \
TRNS,TRNS, MPRV,MPLY,MNXT,TRNS,TRNS,TRNS,DEL,END,PGDN,           TRNS, \
TRNS,TRNS,NO,          TRNS,                     FN0, TRNS,TRNS,TRNS)
};

static const uint8_t PROGMEM overlays[][MATRIX_ROWS][MATRIX_COLS] = {};

/*
 * Fn action definition
 */
static const uint16_t PROGMEM fn_actions[] = {
    [0] = ACTION_KEYMAP_MOMENTARY(1),
};
#endif



#define KEYMAPS_SIZE    (sizeof(keymaps) / sizeof(keymaps[0]))
#define OVERLAYS_SIZE   (sizeof(overlays) / sizeof(overlays[0]))
#define FN_ACTIONS_SIZE (sizeof(fn_actions) / sizeof(fn_actions[0]))

/* translates key to keycode */
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
{
    /* Overlay: 16-31(OVERLAY_BIT(0x10) | overlay_layer) */
    if (layer & OVERLAY_BIT) {
        layer &= OVERLAY_MASK;
        if (layer < OVERLAYS_SIZE) {
            return pgm_read_byte(&overlays[(layer)][(key.row)][(key.col)]);
        } else {
            // XXX: this may cuaes bootlaoder_jump incositent fail.
            //debug("key_to_keycode: overlay "); debug_dec(layer); debug(" is invalid.\n");
            return KC_TRANSPARENT;
        }
    }
    /* Keymap: 0-15 */
    else {
        if (layer < KEYMAPS_SIZE) {
            return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
        } else {
            // XXX: this may cuaes bootlaoder_jump incositent fail.
            //debug("key_to_keycode: base "); debug_dec(layer); debug(" is invalid.\n");
            // fall back to layer 0
            return pgm_read_byte(&keymaps[0][(key.row)][(key.col)]);
        }
    }
}

/* translates Fn keycode to action */
action_t keymap_fn_to_action(uint8_t keycode)
{
    action_t action;
    if (FN_INDEX(keycode) < FN_ACTIONS_SIZE) {
        action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
    } else {
        action.code = ACTION_NO;
    }
    return action;
}
Sorry, but I know nothing about these things and just don't really get these topics.

Offline jorgenslee

  • Posts: 369
  • Location: Philippines
Re: TMK keyboard firmware
« Reply #213 on: Sat, 07 December 2013, 21:45:30 »
@hasu
Please forgive my newbie question, but is there a way to flash your firmware to Poker 2? IF not, are you planning to support it in the future?

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #214 on: Sat, 07 December 2013, 21:52:20 »
Ah, it is old.

1. Copy keymap_plain.c to your own like keymap_ivan.c.
2. just replace keymap(KEYMAP_ANSI) with yours in keymap_ivan.c.
3. place ACTION_LAYER_MOMENTARY(1)  in fn_actions of keymap_ivan.c.
4. run 'make KEYMAP=ivan'

Other code except for keymaps, fn_actions is not needed in keymap_ivan.c now.

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #215 on: Sat, 07 December 2013, 21:57:16 »
@jorgenslee
Maybe No and no.
I don't know actually what conroller Poker2 has, whether it is programmable and whether its toolchain is available free to public.

Offline jorgenslee

  • Posts: 369
  • Location: Philippines
Re: TMK keyboard firmware
« Reply #216 on: Sat, 07 December 2013, 23:43:16 »
@jorgenslee
Maybe No and no.
I don't know actually what conroller Poker2 has, whether it is programmable and whether its toolchain is available free to public.

Ahh I see Thanks for the quick response. I really like the idea of SpaceFN which your firmware supports. Hope it could be supported in nearly not that distant future...  ^-^

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #217 on: Tue, 10 December 2013, 11:47:23 »
I'm revisiting this:

Code: [Select]
        case LAYER2_QMARK:                                      // Layer 2 momentary with tap '?'
            if (event.pressed) {
                if (tap.count == 0 || tap.interrupted) {
                    layer_on(2);
                } else {
                    add_mods(MOD_BIT(KC_LSFT));
                    add_key(KC_SLSH);
                    send_keyboard_report();
                    del_mods(MOD_BIT(KC_LSFT));
                    del_key(KC_SLSH);
                    send_keyboard_report();
                }
            } else {
                if (tap.count == 0 || tap.interrupted) {
                    layer_off(2);
                }
            }
        break;

This works great.  But I'm wondering if it would be possible to add another IF statement in here to register something else if SHIFT is pressed.  For example, could I make the key register " ? " when pressed by itself and " / " when pressed with SHIFT?  So the opposite of the standard key...

Also, it doesn't have to include the layer switching.  I'm just experimenting with different layouts that don't use the standard shift keys.

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #218 on: Tue, 10 December 2013, 12:32:19 »
You can see if SHIFT is down with inspecting 'keyboard_report' of action_util.h.

Like:
    keyobard_report->mods & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))

See report.h for definition of keyboard_report.


EDIT: s/&&/&/; replaced logical conditional with bit operator.
« Last Edit: Tue, 10 December 2013, 17:34:13 by hasu »

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #219 on: Tue, 10 December 2013, 15:38:07 »
I'm sorry...I'm really not sure what this means.  Keep in mind that I know very little programming.

In action_util.h I see this:
Code: [Select]
/* inspect */
uint8_t has_anykey(void);
uint8_t has_anymod(void);
uint8_t get_first_key(void);

This is the same file that the "add_mods", "add_key", "del_mods", etc are defined.  But I don't understand how the inspect items are used...

And I *really* don't understand the report.h file.  Looks like it defines the media and system buttons and the NKRO protocol.  Then I see this:
Code: [Select]
typedef union {
    uint8_t raw[REPORT_SIZE];
    struct {
        uint8_t mods;
        uint8_t reserved;
        uint8_t keys[REPORT_KEYS];
    };
#ifdef NKRO_ENABLE
    struct {
        uint8_t mods;
        uint8_t bits[REPORT_BITS];
    } nkro;
#endif
} __attribute__ ((packed)) report_keyboard_t;
/*
typedef struct {
    uint8_t mods;
    uint8_t reserved;
    uint8_t keys[REPORT_KEYS];
} __attribute__ ((packed)) report_keyboard_t;
*/

typedef struct {
    uint8_t buttons;
    int8_t x;
    int8_t y;
    int8_t v;
    int8_t h;
} __attribute__ ((packed)) report_mouse_t;

Which I have no clue what it does...And there is that bit in the middle commented out.

Any additional hand holding would be greatly appreciated.  Can you give me an example of how to inspect the keyboard report?

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #220 on: Tue, 10 December 2013, 15:39:50 »
Also, a few misc questions:

1. What are weak mod keys?
2. What are oneshot keys?
3. What are the 3-5 mouse buttons?  1 and 2 are the left and right buttons, not sure about the rest.

Thanks for all the help!

Offline metalliqaz

  • * Maker
  • Posts: 4951
  • Location: the Making Stuff subforum
  • Leopold fanboy
Re: TMK keyboard firmware
« Reply #221 on: Tue, 10 December 2013, 17:14:23 »
Also, a few misc questions:

1. What are weak mod keys?
2. What are oneshot keys?
3. What are the 3-5 mouse buttons?  1 and 2 are the left and right buttons, not sure about the rest.

Thanks for all the help!

I think weak mods are just a concept used internally for the modmap that can be overridden by other things going on

Oneshot mods are described here

Windows supports mice with more than 2 buttons.  You probably already know button-3, clicking the scroll wheel on your mouse.  4 and 5 are less common but there are applications that support functions for those button events.

EDIT: mistakes
« Last Edit: Tue, 10 December 2013, 17:21:51 by metalliqaz »

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #222 on: Tue, 10 December 2013, 19:26:06 »
You can see current key state recognized by host with 'keyboard_report'.
'keyboard_report' is defined in action_util.c/h and you can find its structure in report.h. See this.
Code: [Select]
    struct {
        uint8_t mods;
        uint8_t reserved;
        uint8_t keys[REPORT_KEYS];
    };

keyboard_report is actually 8-byte arrary of USB keyboard report defined in its spec. (REPORT_KEYS=6) 'mods' retains modifier state, 'reserved' is unused, and 'keys' is 6-byte array which can retain 6 keys pressed at most.
Code: [Select]
0       |1       |2       |3       |4       |5       |6       |7
--------+--------+--------+--------+--------+--------+--------+--------
mods    |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5]

keyboard_report->mods is comprised of 8bits indicate modifier key each like:
Code: [Select]
0       |1       |2       |3       |4       |5       |6       |7
--------+--------+--------+--------+--------+--------+--------+--------
Lcontrol|Lshift  |Lalt    |Lgui    |Rcontrol|Rshift  |Ralt    |Rgui

So you can see if SHIFT keys are pressed down by
Code: [Select]
if ( keyboard_report->mods & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) )



Also, a few misc questions:

1. What are weak mod keys?
2. What are oneshot keys?
3. What are the 3-5 mouse buttons?  1 and 2 are the left and right buttons, not sure about the rest.

Weak mod are used by internal action or macro which does not accompany with real user key action. Not well designed yet, ignore at the moment.

Oneshot mod: My English is always confusing but you'll get it.
https://github.com/tmk/tmk_keyboard/blob/master/doc/keymap.md#43-oneshot-modifier


Traditionally mouse has 3 buttons and button 3 is middle button. As metalliqaz said, more than that it has no common usage convetion, I think.

tmk_keyboard supports 5 buttons with its mouse report descriptor. In my Xorg environment I can use BTN1-3 as conventional left, right and middle buttons but BTN4-5 are recognized as button 8 and 9 interestingly :) Meanwhile vertical and horizontal wheel motion is interpreted as button 4-7 in Xorg :o

In windows I don't know how they are handled, but I can use both wheels and button 4,5 as expected. Button 4 and 5 do browser back and forward.

Offline jeffgran

  • Posts: 126
  • Location: Denver
Re: TMK keyboard firmware
« Reply #223 on: Tue, 10 December 2013, 21:10:43 »
hasu: I have been using the "ACTION_MODS_TAP_KEY" and I like it, but I wanted to change the behavior because it's too slow for me. I would like to change the behavior so that the "hold" modifier activates even if you release the modifier key before, as long as you hold it down for long enough first (maybe 100-200ms?). Could you point me in the right direction? I am happy to hack on the code myself but I'm not that good with C so if you tell me where to look I can try it...

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #224 on: Wed, 11 December 2013, 00:51:57 »
jeffgran,
Only one configurable parameter of tap key(dual role key) is TAPPING_TERM, which is 200ms by default and defined in common/action_tapping.h. You can change TAPPING_TERM in your config.h, my setting is 300ms in keyboard/hhkb/config.h(and my typing speed is 70wpm at most in typeracer.com), by the way.

To tweak other behaviour of tap key you need to fiddle with my dirty code. You can find tapping logic in common/action_tapping.c.



Hmm, TAPPING_TERM may mitigate your problem but it doesn't seem to be a true solution. I think you need to tweak code to change behaviour as you expect.

My dual role implementation is optimized to place additional role on normal key without explicit conscious. Meanwhile you likely want to give other role on modifier key. I think this two variants of dual role key need different optimized behaviour.

At this time tmk_keyboard is optimized for former variant only. I'll try to implement to support both of two variants later, but it'll take long.


Offline IvanIvanovich

  • Mr. Silk Underwear
  • Posts: 8199
  • Location: USA
Re: TMK keyboard firmware
« Reply #225 on: Wed, 11 December 2013, 17:38:56 »
OK so if I understood it right I am supposed to end up with this?
Code: [Select]
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* 0: qwerty */
    KEYMAP_ANSI(
        ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC, \
        TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,BSLS, \
        CAPS,A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,  \
        LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          RSFT, \
        LCTL,LALT,NO,          SPC,                     FN0, RGUI,APP, RCTL),
    /* Overlay 1: Fn mode
     */
    KEYMAP_ANSI(
GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, TRNS, \
TRNS,TRNS, UP,  TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,PAUS,VOLU,VOLD,MUTE, \
TRNS,LEFT,DOWN,RGHT,TRNS,TRNS,TRNS,TRNS,TRNS,INS,HOME, PGUP,      TRNS, \
TRNS,TRNS, MPRV,MPLY,MNXT,TRNS,TRNS,TRNS,DEL,END,PGDN,           TRNS, \
TRNS,TRNS,NO,          TRNS,                     FN0, TRNS,TRNS,TRNS)
};
const uint16_t PROGMEM fn_actions[] = ACTION_LAYER_MOMENTARY(1);

It compiles OK. I had some troubles getting to flash but was able to do so after erasing first. First layer is mostly OK, but it have ~` instead ESC like I want for some reason. 2nd layer is all wrong, have those all over in places I didn't specify. I don't know what wrong.
« Last Edit: Wed, 11 December 2013, 19:41:53 by IvanIvanovich »

Offline jeffgran

  • Posts: 126
  • Location: Denver
Re: TMK keyboard firmware
« Reply #226 on: Wed, 11 December 2013, 18:34:55 »
Thanks hasu!

I have been playing with the code and trying to understand my problem. I have identified 3 different issues that I have below:
1.
Code: [Select]
Space(tap)/Layer5(hold)  ~~~~~~~~~~~~~_______~~~~~~~~~~~~~
f(Layer0)/=(Layer5)      ~~~~~~~~~~~~~~~____~~~~~~~~~~~~~~~
TAPPING_TERM                         |----------|

expected output: "="
got:             " f"
2.
Code: [Select]
Space(tap)/Layer5(hold)  ~~~~~~~___~~~_________~~~~~___~~~
f(Layer0)/=(Layer5)      ___~~~~~~~~~~~~_____~~~~~~~~~~~~~
TAPPING_TERM                         |----------|

expected output: "f = "
got:             "f  f "
3.
Code: [Select]
t                        ~______~~~~~~~~~~~~~~~~~~~~~~~~~~
h                        ~~~~~~______~~~~~~~~~~~~~~~~~~~~~
i(tap)/ Layer8(hold)     ~~~~~~~~~~~______~~~~~~~~~~~~~~~~
s(Layer0)/ { (layer5)    ~~~~~~~~~~~~~~~~______~~~~~~~~~~~
Space(tap)/Layer5(hold)  ~~~~~~~~~~~~~~~~~~~~~_______~~~~~
TAPPING_TERM                        |----------|

expected output: "this "
got:             "thi{"

1. I was able to solve by using lines 100-111 in action_tapping.c (I commented out the `#if TAPPING_TERM >= 500` and `#endif` lines)
2. I have not been able to figure out which branch of code this case falls into or how to make it process this as a hold rather than a tap. But even if I hold "space" down longer than the TAPPING_TERM, the fact that I tapped it right before that seems to make it impossible to layer shift. I have to wait until it times out in between a tap and a hold.
3. I think this was caused by my "fix" for 1. It seems like it just needs to take into account which tap/hold key was pressed, because in my case one layer switch key was pressed and then a different one was pressed, but the second one seems to be the one that affected the middle key...

Hope that makes sense. I saw your issue #49 in github to refactor that tapping code. I think it would be helpful to make a state machine out of it or something. I think I may try to refactor it maybe in the next few weeks, just to see if I can do it. Unless you are already working on that? If I came up with something would you be willing to look at it and merge it in if you like it?

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #227 on: Wed, 11 December 2013, 22:39:45 »
IvanIvanovich,
I don't know why you got ` intead of esc clearly. But boot magic may causes those problem. Try disabling boot magic build option. And you have wrong fn_actions, note that it is array.

EDIT: In fact you cannot omit '{}', I mean.
« Last Edit: Thu, 12 December 2013, 01:35:57 by hasu »

Offline domoaligato

  • * Exquisite Elder
  • Posts: 1672
  • Location: USA
  • All your base are belong to us!
    • All your base are belong to us!
Re: TMK keyboard firmware
« Reply #228 on: Wed, 11 December 2013, 23:41:34 »
I have no idea what revision I am on but on my gh60 rev. a with your firmware I have ` instead of esc everytime I plug it in. I have just dealt with it and pressed fn + q to change it every time I plug in my keyboard assuming that was the default behavior.

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #229 on: Thu, 12 December 2013, 00:09:58 »
jeffgran,
great diagram, it clearly make sense to me. Interesting test cases.

Frist, tuning of dual role key all has trade-off and depends on one's fingering, typing habit and speed. No configuration can handle every cases perfectly. We will have to compromise some points. That being said, we can pursue better configuration or implementation of dual role key. IMO.

1. This option allows you to access hold action(=) preferentially. Meanwhile it may prevent you from typing fast, you always must release space bar before releaseing f key to get " f". This is exactly the trade-off you cannot get both.
I'll make this option cofigurable in config.h.

2. hmm, I didn't find this case. My implementation offers key repeat with 'tap and hold'(sequential tap). This repeat likely causes this problem. If you press a key within TAPPING_TERM after tap, the key is recognaized as tap action(space) immediately.
It may exist better implementation of this and I should add configure option for 'tap and hold' repeat, too.
https://github.com/tmk/tmk_keyboard/blob/master/common/action_tapping.c#L231

3. Wierd. I may be a bug. Or buffer overflow may cause this situation. What if you increase WAITTING_BUFFER_SIZE of action_tapping.h?


My code is full of bug fixes and heuristic rules derived from my experience and preference. No apparent theory. It is very confusing even to me :) It certainly needs refactoring or rewrite from scratch. I don't statrt to work at all yet because that is no little job and its complexity scares me.
If you work on this it would be very helpful.

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #230 on: Thu, 12 December 2013, 00:15:31 »
I have no idea what revision I am on but on my gh60 rev. a with your firmware I have ` instead of esc everytime I plug it in. I have just dealt with it and pressed fn + q to change it every time I plug in my keyboard assuming that was the default behavior.

Did you try clear eeprom? You can do this with dfu-programmer, I think.
Or did you try boot magic configuration clear? I guess space+backspace or Fn+backspace, it depends on you configure.h.

EDIT: I guess your eeprom was wrongly programmed and it causes this problem, to solve you will need clear the eeprom with either ways.

1. run 'make dfu-ee'
2. plug in pressing space and backspace
« Last Edit: Thu, 12 December 2013, 01:42:25 by hasu »

Offline jeffgran

  • Posts: 126
  • Location: Denver
Re: TMK keyboard firmware
« Reply #231 on: Thu, 12 December 2013, 20:36:53 »
Thanks for you help hasu!

My bug #3 has not been happening any more -- it must have been a problem with something I did the other day. Did not have that problem all day today.

I started working on rewriting action_tapping -- you're right, it's complicated. :) I'll see if I can get it to work. Do you have a way of doing automated tests or anything? If I get it to work for my use case it will be hard to know whether I broke other peoples' use cases..

Offline showvim

  • Posts: 1
Re: TMK keyboard firmware
« Reply #232 on: Fri, 13 December 2013, 03:10:58 »
Please~ I want to this function,How to do ? Thank you very much!
normal esc = esc,
fn + esc = ~,
fn + shift + esc = `
Do you understand me ? My English is poor,So sorry~

Offline domoaligato

  • * Exquisite Elder
  • Posts: 1672
  • Location: USA
  • All your base are belong to us!
    • All your base are belong to us!
Re: TMK keyboard firmware
« Reply #233 on: Fri, 13 December 2013, 09:01:10 »
I have no idea what revision I am on but on my gh60 rev. a with your firmware I have ` instead of esc everytime I plug it in. I have just dealt with it and pressed fn + q to change it every time I plug in my keyboard assuming that was the default behavior.

Did you try clear eeprom? You can do this with dfu-programmer, I think.
Or did you try boot magic configuration clear? I guess space+backspace or Fn+backspace, it depends on you configure.h.

EDIT: I guess your eeprom was wrongly programmed and it causes this problem, to solve you will need clear the eeprom with either ways.

1. run 'make dfu-ee'
2. plug in pressing space and backspace


thanks i will try tha this weekend when i have a chance.

Offline IvanIvanovich

  • Mr. Silk Underwear
  • Posts: 8199
  • Location: USA
Re: TMK keyboard firmware
« Reply #234 on: Fri, 13 December 2013, 14:57:48 »
showvim, you can look from code I posted. It's how I have mine to work.

IvanIvanovich,
I don't know why you got ` intead of esc clearly. But boot magic may causes those problem. Try disabling boot magic build option. And you have wrong fn_actions, note that it is array.

EDIT: In fact you cannot omit '{}', I mean.
Thanks. I guess instead of telling me I had error, it was using keymap from another like Poker or something??? Weird.
I thought new was supposed to have NKRO? I still only have 6.
« Last Edit: Fri, 13 December 2013, 15:03:39 by IvanIvanovich »

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #235 on: Fri, 13 December 2013, 19:58:59 »
Thanks for you help hasu!

My bug #3 has not been happening any more -- it must have been a problem with something I did the other day. Did not have that problem all day today.

I started working on rewriting action_tapping -- you're right, it's complicated. :) I'll see if I can get it to work. Do you have a way of doing automated tests or anything? If I get it to work for my use case it will be hard to know whether I broke other peoples' use cases..

Yea, that is what I am thinking of, but I don't start it yet. I think it needs C unit test framework and various test cases. The tapping code can be tested on PC because most of it doesn't depend on AVR specific function.

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #236 on: Fri, 13 December 2013, 20:15:48 »
showvim,
You can't do that easily with placing keycodes. You need to write code in keymap function action.
https://github.com/tmk/tmk_keyboard/blob/master/doc/keymap.md#24-function-action
Spec of function action is not fixed and not documented yet. If you want to try this you need to read code yourself.

Ivan, NKRO need to be enable explicitly with command. LShift+RShift+N, probably.
https://github.com/tmk/tmk_keyboard#magic-comannds


Offline codyeatworld

  • * Destiny Supporter
  • Posts: 944
  • Location: Bay Area, California
Re: TMK keyboard firmware
« Reply #237 on: Fri, 13 December 2013, 20:48:54 »
Is it possible to use this firmware on a 38gt pcb? It uses an aikon controller 2.7b

Being able to use the keyboard in the bios is a big feature for me, asI multiboot different operating systems frequently.
Your firmware is the only one that lets me do this, I run a bit older motherboard, an asus x58, but I don't think thats the problem.

I actually bust out an old ps/2 keyboard just to press the arrow key to select windows/mac when I turn on my computer.

Keyboards that do not work in bios for me:
  • KMAC original
  • Kitty Pad
  • 38gt
  • lz-gh
  • gh60 rev. A with original firmware

Keyboards that work in bios for me:
  • gh60 rev. A with tmk
  • poker 2

Thanks for the kickass firmware and hard work everybody too!
« Last Edit: Fri, 13 December 2013, 20:53:50 by codyeatworld »




Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #238 on: Fri, 13 December 2013, 22:25:10 »
Good to hear tmk works for you.
I for one rarely use my keyboard on BIOS and bootloaders such like grub and  I didn't test it thoroughly.

I think you can use tmk_keyboard built with V-USB on Aikon hardware, but it seems to be difficult to access schematic and code of the keyboard.

Offline codyeatworld

  • * Destiny Supporter
  • Posts: 944
  • Location: Bay Area, California
Re: TMK keyboard firmware
« Reply #239 on: Sat, 14 December 2013, 15:11:17 »
I'm not really sure what you mean build with v-usb?

This is the only thing I've found about an aikon schematic, and it is almost two years old:
http://deskthority.net/workshop-f7/building-and-using-the-aikon-controller-t15.html

I'm not sure if things have changed since then, but I might be able to get the new information if it has changed.




Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #240 on: Sat, 14 December 2013, 18:37:24 »
V-USB is one of USB stack used in tmk_keyboard. tmk supports three USB stack LUFA, PJRC and V-USB. gh60 uses LUFA by default.
http://www.obdev.at/products/vusb/index.html

If you want to port the firmware to 38gt, you need to do theese
1) look into matrix circuit with multimeter unless it is open
2) wirte code in matrix.c
3) build with V-USB stack

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #241 on: Fri, 20 December 2013, 23:16:07 »
You can see if SHIFT keys are pressed down by
Code: [Select]
if ( keyboard_report->mods & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) )

This works great! 

Another question: is there a way to find the state of CAPS?  Not just whether it is currently pressed, but if the caps lock is on or not?

I would like to use the CAPS state in an IF statement.

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #242 on: Sat, 21 December 2013, 17:38:39 »
What you can know is only LED state of Caps lock, it can be checked with host_keyboard_leds() like:

    if (host_keyboard_leds() | (1<<USB_LED_CAPS_LOCK))

But you can't know actual host state of Caps lock.
Host may send command to keyboard to control LED indicator but may not. It depends on OS/application implementation. Applicaton can send LED command to keyboard regardless of host state. Or imagine you have two keyboards on a host and you press capslock key, some OS sends LED command to all keyboards but other sends only to the keyboard.

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #243 on: Thu, 02 January 2014, 23:28:22 »
Added my first project in this year, this is not a serious keyboard for daily use. TRS-80 model 100 is supported now. This old tiny but complete computer has serial terminal software in its ROM, this application sends out ASCII codes for keys. This project is a converter which translates ASCII into USB HID and makes the lovely comp revived as keyboard hooked up to modern computer.



https://github.com/tmk/tmk_keyboard/tree/master/converter/ascii_usb

Offline sean4star

  • Posts: 59
  • Location: Arlington, TX
Re: TMK keyboard firmware
« Reply #244 on: Fri, 03 January 2014, 16:30:29 »
That's a cool looking mod!

FYI, matt3o over at deskthority put together a nice simple tutorial for using your firmware.
HERE


Also, I'm having a good time creating my own key functions using the ACTION_FUNCTION_TAP.  This gives the user huge flexibility in making any custom design they can dream up.


Quick question:  I've used the layer_on(X) and layer_off(X) events, but is there a similar toggle event?

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #245 on: Fri, 03 January 2014, 19:26:37 »
Nice write up, subscribed the thread.

When you use ACTION_FUNCTION, no API for toggling layer. Just use layer_on, _off or _invertert, there are many ways to implement toggle feature. For example,
On originate layer you just do layer_invert(x) [or layer_on(x)] on *release* event of a key and  do nothing on press. On destination layer(x) you also do layer_invert(x) [or layer_off(x)] on release and do nothing on press. Voila!
This is just what ACTION_LAYER_TOGGLE does.

Offline hydrospell

  • * Destiny Supporter
  • Posts: 272
  • Location: Singapore
  • some keyboard thing
    • octobrain
Re: TMK keyboard firmware
« Reply #246 on: Sun, 05 January 2014, 09:12:03 »
hasu I know you probably heard this more than a couple of times already, but...

I made a keyboard from scratch and managed to load tmk_keyboard into a Teensy to use it as firmware. So a fully functional keyboard was born today from components thanks to your excellent firmware!!  :thumb:

Thanks once again for the awesome, easy to use code.
⌨ Filco MJ2 MX Blues / M0116 Orange Alps / Homemade 60% MX Reds / M0110

Cherry MX art prints 20/50 still available!

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #247 on: Sun, 05 January 2014, 22:34:40 »
hydrospell, thanks
it feels nice to get feedback on my work in particular if it is positive :D

and congrats on success of your project!

Offline bcg

  • Posts: 112
Re: TMK keyboard firmware
« Reply #248 on: Thu, 09 January 2014, 00:13:41 »
Hasu,

What is the best way to tell which layer(s) are active?  Right now I have configured 2 layers, 1 default and the other a momentary layer activated by one of two function keys.  I'm thinking of making one of the function keys a "lock" for that layer and I want to have an LED as an indicator... so I'd like to be able to tell if the second layer is active at some point and turn on/off the LED appropriately

BTW thank you for merging in my NeXT converter code... so far the firmware is working great and makes the board really nice to use.  Its only 2KRO but it is made with black Alps switches and nice doubleshot caps, and I'm guessing is kind of rare because I don't think there could have been that many NeXT computers made... and its fun to think that the web might have been invented on that keyboard because Tim Berners-Lee invented HTTP and the first web browser on a NeXT station :)  Anyhow I'm hoping to post some details on it soon but I've just been so busy lately.

Thanks for your help
:wq!

Offline hasu

  • Thread Starter
  • Posts: 3471
  • Location: Tokyo, Japan
  • @tmk
    • tmk keyboard firmware project
Re: TMK keyboard firmware
« Reply #249 on: Thu, 09 January 2014, 01:47:12 »
Hi,
You can see active layers on layer_state and default_layer_state of action_layer.h. To get real state of layers you need to see both.

    uint32_t real_state = (layer_state | default_layer_state);

Each bit indicates state of a layer; bit0 has state of layer0, bit31 has layer31 and 0/1 means off/on.


Ah, it is you! I didn't find it on github :D
I've not got my hands on any NeXT keyboard yet, it looks attractive and inrigues me. Occasionally I can find them here but its price is steep.
Looking forward to your post about it. Anyway, great job!

FYI, you can access his non-ADB NeXT converter here.
https://github.com/tmk/tmk_keyboard/tree/master/converter/next_usb