HaoboGu / rmk

Rust keyboard firmware library with layers, macros, real-time keymap editing, wireless(BLE) and split support
https://haobogu.github.io/rmk/
Apache License 2.0
399 stars 33 forks source link

Support for keypad keycodes #111

Open jackbrad1ey opened 4 days ago

jackbrad1ey commented 4 days ago

Hey there, I'm not entirely sure if this already exists, from my hunting through the documentation and the code it doesn't seem to. But is there a way to support keypad keycodes? For example I want dedicated keys for characters such as #, ^, & and so on, rather than shift + some number. If there is already another feature within rmk that implements this behaviour then please direct me in that direction.

HaoboGu commented 4 days ago

You can do it using WithModifier key. Actually, vial automatically converts those keycode to WithModifier key:

image

I chose # at the bottom, and it was converted to LShift(Kc3) key by vial

jackbrad1ey commented 3 days ago

Ah interesting, I'm curious how this is implemented behind the scenes. I wrote some keyboard firmware for myself recently and got stuck at this roadblock. Are you only including a single keycode per HID report to get around this issue? And then just activating modifiers as needed on a per-keycode basis?

HaoboGu commented 3 days ago

yeah you're right. This is done by activating modifier and the key then releasing modifier when the key is released.

jackbrad1ey commented 3 days ago

Cool, didn't think about doing it that way. Cheers for the help.

jackbrad1ey commented 3 days ago

Actually apologies one last thing, is there any way to implement the LShift(Kc3) for example, within the keyboard.toml file? Or would it need to be done through Vial?

HaoboGu commented 3 days ago

ahh, it's not implemented yet in keyboard.toml. you can only config it in Vial. it's not difficult to implement though. I could add it before next release.

jackbrad1ey commented 3 days ago

I'm happy to try give it a shot if you want, I'm still fairly new to Rust and haven't looked at the rmk codebase much, but sounds like a task that would help me get a bit more familiar with the language

HaoboGu commented 3 days ago

I'm happy to try give it a shot if you want, I'm still fairly new to Rust and haven't looked at the rmk codebase much, but sounds like a task that would help me get a bit more familiar with the language

Sure!

The following is a simple guide:

The keyboard.toml parsing code is at rmk-macro, which reads keyboard.toml and generates Rust code at compile time.

The layout parsing is at rmk-macro/src/layout.rs, in which parse_key function is what you should edit -- this function parses string at each position in the keymap and converts it to the RMK KeyAction. You can start here.

jackbrad1ey commented 2 days ago

Thanks for the pointers, I managed to get that stuff implemented pretty quick. I think I'm misunderstanding the build process however, do I still need to update my vial.json in order to successfully generate the correct layout? Or is that just a separate method of creating a layout to be flashed. At the moment when flashing with just the keyboard.toml holding my layout, it does a whole lotta nothing so I think I'm misunderstanding how vial plays into this.

HaoboGu commented 1 day ago

No, you don't need to update vial.json.

vial.json is used only for showing Vial the keyboard's layout, while the keymap is set in keyobard.toml

Both layout and keymap should be consist with the physical PCB.

jackbrad1ey commented 1 day ago

Right, that's what I had assumed. Is the main branch stable? I was using a basic key layout as a test and tried building using the main branch rmk and once I flashed the keyboard didn't output anything or get recognised as a HID device at all. I'll look into it, I presume I've just missed something somewhere.

HaoboGu commented 1 day ago

Yes, main branch is stable. What device do you use? If you're using a debug probe, there should be logs showing you what happens

jackbrad1ey commented 1 day ago

My board has an RP2040, I don't have a debug probe I'm just flashing over USB

HaoboGu commented 1 day ago

can you share your Cargo.toml and keyboard.toml? Or a project that reproduces the issue

jackbrad1ey commented 1 day ago

For sure, I'll make some gists so you can see them This one has the keyboard.toml: https://gist.github.com/jackbrad1ey/ead5f29425ffe137d2c59755a430d151 And this one has the cargo.toml: https://gist.github.com/jackbrad1ey/0df14653025c63737ff95c0706b4ed78

I cloned rmk and put this in the examples folder for testing, it builds just fine but when I flash my board nothing much seems to happen. It isn't recognising it as a HID device. image

jackbrad1ey commented 23 hours ago

Just as a little more context in case it helps, this is the whole project I'm trying to build (pretend this is in the examples/use_config folder of the root rmk directory) keyboard_firmware.zip

HaoboGu commented 15 hours ago

okay, thanks for the code, I'll check it tomorrow

HaoboGu commented 15 hours ago

I did a quick check of your Cargo.toml, you can try to increase the embassy-executor's task arena size, as the following:

embassy-executor = { version = "0.6", features = [
    "defmt",
    "arch-cortex-m",
    "task-arena-size-32768",  # Add this line!
    "executor-thread",
    "integrated-timers",
] }

All other things look good.

jackbrad1ey commented 11 hours ago

Well that seemed to do the trick perfectly, what does that do exactly? Am I just allocating more memory for the tasks?

jackbrad1ey commented 11 hours ago

Anyhow, with that out of the way, seems the changes I made are working well. I'm not too sure if this is what you had in mind when implementing this but I made it similar to the "layer shift with modifier combination". Rather than passing in a layer number and the modifier combination, you instead pass in the keycode and the modifier combination with what I've implemented, I just named it WM for "With Modifier", is this what you envisioned or should it be more along the lines of having LShift(keycode) become valid? image

HaoboGu commented 8 hours ago

Well that seemed to do the trick perfectly, what does that do exactly? Am I just allocating more memory for the tasks?

yes, each key in the keymap requires some memory. The default setting seems not enough for a larger keyboard. I've increased the allocated memory in the template ensuring there is enough memory for most keyboards.

HaoboGu commented 8 hours ago

Anyhow, with that out of the way, seems the changes I made are working well. I'm not too sure if this is what you had in mind when implementing this but I made it similar to the "layer shift with modifier combination". Rather than passing in a layer number and the modifier combination, you instead pass in the keycode and the modifier combination with what I've implemented, I just named it WM for "With Modifier", is this what you envisioned or should it be more along the lines of having LShift(keycode) become valid?

image

great! I think WM is fine. Would you like to create a PR for it?