TMK keyboard firmware collection

User avatar
Ray

05 May 2015, 23:18

okay, did some testing: second question is solved fine. now I can do e.g. shift-clicks without dropping out of my mouselayer - mostly, at least I don't get unwanted keypresses for now.

and for the bootloader, 4096 did the trick. Dunno, why it works with any value after flashing, though.

User avatar
hasu

06 May 2015, 01:23

Do you have code repository? I'm interested in how you changed code for that shift-click problem.

Actually what do you use as controller? If you use Teensy it should be 512bytes(Teensy) or 1024bytes(Teensy++).
BOOTLOADER_SIZE depends on MCU's Boot Size Configuration(BOOTSZ fuse), see datasheet.

4096 is too lage for Teensy bootloader(half-Kay) and you jump into wrong address(32K-4K=28K) in the end. You are OK as long as the jump destination of flash is empty(NOP codes). When your firmware size grows beyond 28K you'll get into runaway by your firmware code at 28K.


EDIT: Added some description on FAQ. See this entry also.
https://github.com/tmk/tmk_keyboard/wik ... oesnt-work

User avatar
Ray

06 May 2015, 13:43

turns out I was ignoring what I learned about software-testing and didn't check some cases...
right now, any keydown (incl. mods) I break out of my mouselayer (on which I have mousekeys next to my trackpoint), but moving the trackpoint brings me back in, so I am kinda ok.

snip from action.c

Code: Select all

/* Key and Mods */
        case ACT_LMODS:
        case ACT_RMODS:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
                                                                action.key.mods<<4;
                if (event.pressed) {
                    /* if no mousekeys are pressed but other regular keys,
                     * turn off the MOUSE_LAYER*/
                    if( action.key.kind == ACT_LMODS 
                            && action.key.mods == 0 
                            && tp_buttons==0) {
                        mouse_layer_helper = ML_UNSET;
                        layer_off(MOUSE_LAYER);
                    }
                    if (mods) {
                        add_weak_mods(mods);
                        send_keyboard_report();
                    }
                    register_code(action.key.code);
                } else {
                    unregister_code(action.key.code);
                    if (mods) {
                        del_weak_mods(mods);
                        send_keyboard_report();
                    }
                }
            }
            break;
looks like action.key.kind == ACT_LMODS && action.key.mods == 0 evaluates to true even for my KC_LSFT and KC_LCTL.

As for the bootloader, I also expected it to be 512bytes, but I guess that's what I get for buying cheap (for a teensy) stuff on ebay :|
4096 works for me, so I go for it right now. I don't think I will run out of flash with this project.
I am still puzzled why it did work right after flashing, though. It would take me too long to figure out anyways.

I will try to set up github, so I can give back to you and the community
Edit: I did set up github with my hacky code, if you want to take a look: https://github.com/3ner/tmk_keyboard/
my changes to mousekeys and the related stuff is in action.c, action_layer.c, ps2mouse.c, ps2mouse.h
this was done with the mentality, if it works it's good. Not really maintainable or better than the original I guess.

Vizir

08 May 2015, 18:19

I'm trying to add OLED display to the IBM F-122 keyboard and integrate the code into terminal_usb converter. Using u8glib, I can't get tmk to boot properly on the teensy++2.0. And this is when I'm just including the .c files to the Makefile. I'm not doing any calls to them at all. Here's what I've done:

Makefile:

Code: Select all

GFX_DIR = u8glib/src
OLED_ENABLE = yes # OLED Display
ifdef OLED_ENABLE
    __AVR__ = yes
    SRC += \
    	u8g_dev_ssd1351_128x128.c \
    	u8g_com_api.c \
    	u8g_com_atmega_hw_spi.c \
    	u8g_pbxh24.c \
    	u8g_delay.c \
    	u8g_com_io.c \
    	u8g_com_atmega_sw_spi.c \
    	u8g_pbxh16.c \
    	u8g_pb8h8.c \
    	u8g_state.c \
    	u8g_page.c \
    	u8g_pb.c \
    	u8g_bitmap.c \
    	u8g_circle.c \
    	u8g_clip.c \
    	u8g_ellipse.c \
    	u8g_font.c \
    	u8g_font_data.c \
    	u8g_line.c \
    	u8g_rect.c \
    	u8g_rot.c \
    	u8g_scale.c \
    	u8g_u8toa.c \
    	u8g_u16toa.c \
    	u8g_ll_api.c 
    VPATH += $(GFX_DIR)/
    OPT_DEFS += -DDISPLAY_ENABLE
    # Tell u8glib how to support hardware SPI:
    OPT_DEFS += -D__AT_AT90USB1286__

endif
If I do this:

Code: Select all

#OLED_ENABLE = yes
tmk works fine.

If I do this:

Code: Select all

OLED_ENABLE = yes
the teensy goes back into bootloader after I click the reboot button. it never starts. Any clues why?

User avatar
hasu

09 May 2015, 05:23

Ray wrote: turns out I was ignoring what I learned about software-testing and didn't check some cases...
right now, any keydown (incl. mods) I break out of my mouselayer (on which I have mousekeys next to my trackpoint), but moving the trackpoint brings me back in, so I am kinda ok.

snip from action.c

Code: Select all

/* Key and Mods */
        case ACT_LMODS:
        case ACT_RMODS:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
                                                                action.key.mods<<4;
                if (event.pressed) {
                    /* if no mousekeys are pressed but other regular keys,
                     * turn off the MOUSE_LAYER*/
                    if( action.key.kind == ACT_LMODS 
                            && action.key.mods == 0 
                            && tp_buttons==0) {
                        mouse_layer_helper = ML_UNSET;
                        layer_off(MOUSE_LAYER);
                    }
                    if (mods) {
                        add_weak_mods(mods);
                        send_keyboard_report();
                    }
                    register_code(action.key.code);
                } else {
                    unregister_code(action.key.code);
                    if (mods) {
                        del_weak_mods(mods);
                        send_keyboard_report();
                    }
                }
            }
            break;
looks like action.key.kind == ACT_LMODS && action.key.mods == 0 evaluates to true even for my KC_LSFT and KC_LCTL.
Ah, my bad. You also need to use these macros in addition of those to discriminate between keys and modifiers.
https://github.com/tmk/tmk_keyboard/blo ... .h#L28-L29

User avatar
hasu

09 May 2015, 05:37

Vizir wrote: I'm trying to add OLED display to the IBM F-122 keyboard and integrate the code into terminal_usb converter. Using u8glib, I can't get tmk to boot properly on the teensy++2.0. And this is when I'm just including the .c files to the Makefile. I'm not doing any calls to them at all. Here's what I've done:

... snip ...

the teensy goes back into bootloader after I click the reboot button. it never starts. Any clues why?
I don't think those compiled objects are linked if as long as you don't use them(calling those functions).
So just adding .c files to Makfile should not have effect on final binary.

Are you using any those library functions?

Vizir

09 May 2015, 20:37

I'm only adding them to the makefile. The files get compiled into .o objects then they are also linked at the end, I think. I'll post the output of the make when I return home. I am not calling any functions. Not even including the .h files. I can post the code if you want to take a look.

User avatar
Ray

09 May 2015, 22:46

Ray wrote: looks like action.key.kind == ACT_LMODS && action.key.mods == 0 evaluates to true even for my KC_LSFT and KC_LCTL.
(action.key.code & 0b11111100)!=KC_LCTRL does the trick for me. Comparing keycodes to the 8 mods is easyer for me than understanding that union.

User avatar
hasu

10 May 2015, 02:42

Vizir, due to a missing compile flag GCC doesn't remove unused objects. I guess this causes memory is run out with huge font and other data(huge data in BSS) perhaps, so firmware run awary when it was compiled with the library.

Try this patch.

Code: Select all

diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk
index a790f87..860fc1a 100644
--- a/tmk_core/rules.mk
+++ b/tmk_core/rules.mk
@@ -124,6 +124,7 @@ CFLAGS += -O$(OPT)
 CFLAGS += -funsigned-char
 CFLAGS += -funsigned-bitfields
 CFLAGS += -ffunction-sections
+CFLAGS += -fdata-sections
 CFLAGS += -fno-inline-small-functions
 CFLAGS += -fpack-struct
 CFLAGS += -fshort-enums

Vizir

11 May 2015, 22:45

That fixed the bootloop. Thanks hasu! now to see why u8glib doesn't want to work using C. Arduino/C++ interfaces work great.

User avatar
hasu

18 May 2015, 18:15

Recently added keymaps for 77-key and 107-key to IBM 4704 converter. Thanks orihalcon.

And protocol handling bug was fixed today, it seems like this solves key stuck and drop problem.
https://github.com/tmk/tmk_keyboard/com ... 0bfc1ca090


IBM 4704 converter:
https://geekhack.org/index.php?topic=54706.0
https://github.com/tmk/tmk_keyboard/tre ... bm4704_usb

User avatar
copter
Last Man Standing

25 May 2015, 12:49

Any chance that you could add PS/2 protocol support to the computer side, meaning that it would be possible to connect custom etc matrix to PS/2 bus on the computer?

ruslan

09 Jun 2015, 13:48

Hi!
I use tmk firmware with Teensy++ 2.0 to make KVM from old dead laptop HP Omnibook XE3.
I fork your repo and use phantom keyboard folder as template.
https://github.com/ruslan-ohitin/tmk_ke ... nibook_xe3

All works fine except one thing - I can't use modifier keys with keys from same row in the matrix.
LShift + Z, RShift + Q not working, system registers only modifier key press, without letter key.
LShift + Q, RShift + Z - OK.

The same situation with ALT and CTRL keys.

My matrix:
Spoiler:
Image
I'll be glad of any help.

User avatar
hasu

09 Jun 2015, 22:43

It seems like ghost block is related to your problem, I guess your matrix wiring has something wrong or ghost blocking code has a bug. Anyway you can observe matrix on/off state with 'hid_listen' to see how it goes on your matrix.

Add this code in matrix_init() to enable matrix debug print.

Code: Select all

debug_matrix = true;
And try removing 'MATRIX_HAS_GHOST' from config.h to see whether ghost blocking have effect upon.

User avatar
Ray

16 Jun 2015, 15:11

Is it possible to get a Layerswitching key,
• that's a normal key on tap
• acts like ACTION_LAYER_MODS on holding the key, i.e. switches the layer with modifier on for it.

Maybe it is somewhere in action_code.h, but I have serious issues understanding that.
I guess I can do it with action_function() if there's no action for that niche case.

User avatar
hasu

18 Jun 2015, 05:31

You are right, action like that is not supported by default. You have to write code in action_function().

User avatar
hypkx
Chasing the Dream

13 Aug 2015, 10:01

hello, some days ago I build a converter box.
Currently for to converter, ADB to USB and PS2 to USB.
The problem is PS2 to USB don't work.
The story from the beginning:
First I build a ADB to USB converter (with a teensy), works perfectly.
Then I build a PS2 to USB converter on the same teensy, because I want to use multible converters at one teensy.
But it don't work, I checked everything, but I don't understand why I don't work.
Then I just soldered the PS2 to USB converter on the teensy to test if it works then.
After loading the software multible times, my PS2 keyboard works for 10 minutes and the the converter stopped working.
Since this event the PS2 to USB converter don't work ever again.
Also the ADB to USB converter stopped working, so I used a switch (a switched that switches to lines simultaneously), then the ADB to USB converter works again.

The current situation is that ADB to USB works perfectly and PS2 to USB works not.
The light (LEDs) on the PS2 keyboard flashes when I plugged the keyboard in.

I don't have any Idea why It don't work, it should every thing be right, maybe my teensy is damaged or some pins don't work. I checked my soldering, everything is ok.

I hope somebody can help me.

Converter box.
Spoiler:
Image
Image
Here is my drawing of circuit diagram, it isn't super professionell.
If something isn't clear just ask.
I know the location for pins on the teensy are in real different.

Code: Select all


                     -------------------------------------
                    |                                     |
                    |                                     |
      PS2 port      |                       ADB port      |
                    |                                     |
  clock  Vcc Data  GND              Data  Vcc   GND       |
    |     |   |                       |    |     |        |
    |     |    -----     -------------     |     |        |
    |     |         |   |                  |     |        |
    |     |         |   |                  |     |        |
    |     |         |   |                  |     |        |
    |      --------(|)-(|)----    ---------       --------|
    |               |   |    |   |                        |
    |               |   |    |   |                        |
    |               |   |    |   |                        |
     --------       |   |    |   |                        |
             |       \ /     |   |                        |
             |        |      |   |                        |
             |        |       \ /                         |
             |        |        |                          |
             |        |        |                          |
             |        |        |                          |
             |        |        |                          |
             |---R---(|)-------|                          |
             |        |        |                          |
             |        |        |                          |
             |        |        |                          |
             |        |        |                          |
             |        |---R----|                          |
             |        |        |                          |
             |        |        |                          |
             |        |        |                          |
             |        |        |       ----R--LED----     |
             |        |        |      |              |    |
             |        |        |      |              |    |
             |        |        |      |    ------    |    |
             |        |         ------ ---Vcc GND|--------
             o        |                   |      |
             |        |         -----------PD0   |
             |        |           ADB on  |      |
          |     |      ----o---           |      |
          |     |               ----------|PD2   |
          |     |           PS2 port on   |      |
          |     |                         |      |
 ADB port on     -------------------------|PD5   |
                   PS2 port on             ------

User avatar
hasu

13 Aug 2015, 12:16

Are you sure configure correctly for those PD2 and PD5?
Post your config.h and Makefile for PS/2 converter.

User avatar
hypkx
Chasing the Dream

14 Aug 2015, 09:39

Thanks for the hint, I overlooked that I had to modify the software if I want to use these pin configuration. Now I reconnected the wires to the standard configuration (data PD0 / clock PD1), but it won't work.
btw. I tested soarers converter again, it also don't work (the only thing that works on soarers converter are the keyboard-LEDs if I tap numlock on the keyboard, but only on my XT keyboard).
Any idea?

User avatar
HzFaq

20 Oct 2015, 22:49

I'm having some issues compiling Alps64 firmware and I'm not sure if it's my computer that's the problem (had some random errors I can't figure out the cause of since moving to Win10). I can compile literally all my other TMK firmwares (Phantom, Ergodox, HID Liber, GH60, ADB converter) but not the Alsp64 one, I just get the below error (even with unedited firmware fresh from the TMK git). Any ideas?

Code: Select all

mkdir -p obj_alps64/protocol/lufa
Compiling C: ../../tmk_core/protocol/lufa/lufa.c
avr-gcc -c -mmcu=atmega32u2 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=4096 -DF_USB=16000000UL -DARCH=ARCH_AVR8 -DUSB_DEVICE_ONLY -DUSE_FLASH_DESCRIPTORS -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" -DFIXED_CONTROL_ENDPOINT_SIZE=8  -DFIXED_NUM_CONFIGURATIONS=1 -DPROTOCOL_LUFA -DBOOTMAGIC_ENABLE -DMOUSEKEY_ENABLE -DMOUSE_ENABLE -DEXTRAKEY_ENABLE -DCONSOLE_ENABLE -DCOMMAND_ENABLE -DVERSION=unknown -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fdata-sections -fno-inline-small-functions -fpack-struct -fshort-enums -fno-strict-aliasing -Wall -Wstrict-prototypes -Wa,-adhlns=obj_alps64/protocol/lufa/lufa.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_alps64_protocol_lufa_lufa.o.d  ../../tmk_core/protocol/lufa/lufa.c -o obj_alps64/protocol/lufa/lufa.o
../../tmk_core/protocol/lufa/lufa.c: In function 'EVENT_USB_Device_Suspend':
../../tmk_core/protocol/lufa/lufa.c:182: warning: implicit declaration of function 'matrix_power_down'
../../tmk_core/protocol/lufa/lufa.c: In function 'setup_mcu':
../../tmk_core/protocol/lufa/lufa.c:576: warning: implicit declaration of function 'clock_prescale_set'
../../tmk_core/protocol/lufa/lufa.c:576: error: 'clock_div_1' undeclared (first use in this function)
../../tmk_core/protocol/lufa/lufa.c:576: error: (Each undeclared identifier is reported only once
../../tmk_core/protocol/lufa/lufa.c:576: error: for each function it appears in.)
make: *** [obj_alps64/protocol/lufa/lufa.o] Error 1

User avatar
hasu

20 Oct 2015, 22:55

Probably you need newer toolchain, old WinAVR deosn't have enough support for ATMega32u2 unfortunately IIRC.
You can download Atmel GCC toolchain from their website, you will need to registration though.

User avatar
scottc

20 Oct 2015, 22:58

I'm installing the compiler on Mac OS here, I'll let you know if it's your environment or if you're just insane!

Edit: works with avr-gcc 4.9.2 here!

User avatar
HzFaq

20 Oct 2015, 23:17

Legend, thanks dude. I'm just waiting for an email from Atmel now before giving it a try.

Thanks too Scott, I would never bet against my own insanity :D.

User avatar
flabbergast

21 Oct 2015, 00:09

hasu wrote: Probably you need newer toolchain, old WinAVR deosn't have enough support for ATMega32u2 unfortunately IIRC.
You can download Atmel GCC toolchain from their website, you will need to registration though.
100 times this! Someone should update the old guides here - I've seen this happen several times in the last few months. It's not just 32u2 that borks out.

BTW, I tend to recommend to Windows people getting MSYS or cygwin and then avr-gcc from here.

User avatar
HzFaq

21 Oct 2015, 01:27

Solution was this, thanks all.

User avatar
Ray

10 Apr 2016, 11:39

I got a question that is kind of a generic C programming problem, but applied to TMK here.
I want to clean up my code, so it might get pulled by hasu, or at least it is easier to work with for third persons pulling from my repo https://github.com/3ner/tmk_keyboard

action_layer.c uses a global variable uint32_t layer_state that I want to read from outside that file.
Having done more Java than C projects, a getter-function is what I kind of expect to use, and I am sure it would work fine. But I have never seen a getter in C and I wonder if there's another sensible way to do that in C (making layer_state extern being the non-sensible way)

User avatar
Halvar

10 Apr 2016, 12:34

Well as you know, C is not an object-oriented language. There are no classes, no properties and no language-supported getters/setters.

Global variables in C are global in the sense of totally global, like a static class in Java. You also can't define different global variables with the same name in two files, or you'll get a linker error. If layer_state is a global variable you can just use it everywhere in your code as if it was a local variable.

What you have to do though is to make the type of the variable known in the file where you're using it. That doesn't happen automatically. It's done by declaring the variable in the file where you're using it as "extern".

layer_state is already a global variable. If you want to use it in another file you declare it as "extern", that's a totally normal thing to do in C.

If hasu didn't want you to do that, he could have written something akin to a getter function in his code and asked you to please use that instead of the global variable.

That would look as crude as

Code: Select all

function uint32_t get_layer_state() {
  //maybe do other stuff
  return(layer_state);
}
In the context of a microcontroller with the memory constraints of the AVR chips, you only do this where it's really needed.

In other words: use extern. :?

User avatar
Ray

10 Apr 2016, 13:10

Thanks for the answer
Now that you say that, I see hasu uses extern in action_layer.h
So yes, he probably wants us to use the global variable globally ;)
Well, I can't imagine why my brain didn't want to see that :?

User avatar
obfuscated

11 Apr 2016, 01:41

Halvar wrote: You also can't define different global variables with the same name in two files, or you'll get a linker error.
I don't think this is 100% correct. You can mark global variables (and functions) with the static keyword and they'll become visible only in the current translation unit. :roll:

User avatar
Halvar

11 Apr 2016, 07:07

You're right. "Static" global variables aren't that global. You can actually use that fact for some kind of encapsulation without classes. hasu didn't do that here though.

Post Reply

Return to “Workshop”