Code Monkey home page Code Monkey logo

keyberon's People

Contributors

adminxvii avatar atykhyy avatar borisfaure avatar camrbuss avatar daehyeok avatar dariogoetz avatar disasm avatar dkm avatar hdhoang avatar help-14 avatar ithinuel avatar jamesmunns avatar jedrzejboczar avatar jtroo avatar mriise avatar nashenas88 avatar nomisiv avatar peauters avatar riskable avatar rwalkr avatar simmsb avatar skelebot avatar texitoi avatar valpackett avatar wezm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keyberon's Issues

Problems with the `impl_heterogenous_array` macro

Hi! I'm trying to get my keyboard based on a SAM21 MCU up and running on keyberon. When declaring Pins I've run into an issue with the impl_heterogenous_array macro as it seems to expect exactly the pin declaration as implemented in the stm32f0xx_hal. When I do a pin declaration as it's possible with the atsamd_hal:

pub struct Cols(
    Pin<v2::PA02,Input<PullUp>>,
    Pin<v2::PA04,Input<PullUp>>,
    Pin<v2::PA10,Input<PullUp>>,
    Pin<v2::PA11,Input<PullUp>>,
    Pin<v2::PA09,Input<PullUp>>,
);

The macro doesn't work for that. The errors that are thrown tell me that some traits are not implemented:
error[E0277]: the trait bound atsamd_hal::gpio::v2::Pin<PA02, atsamd_hal::gpio::v2::Input<atsamd_hal::gpio::v2::PullUp>>: _embedded_hal_digital_InputPin is not satisfied

Strangely it works with the implementation of the rows which is exactly the same:

pub struct Rows(
    Pin<v2::PA06,Output<PushPull>>,
    Pin<v2::PA05,Output<PushPull>>,
    Pin<v2::PA07,Output<PushPull>>,
    Pin<v2::PA08,Output<PushPull>>,
);
impl_heterogenous_array! {
    Rows,
    dyn OutputPin<Error = Infallible>,
    U4,
    [0, 1, 2, 3]
}

This is very confusing for me and I'd appreciate some help with it. I'm really new with rust and I cannot for the life of me figure out how to change my declarations to be accepted by the macro. If there's another method to do the same that the macro does just for my use case but without the macro that would be enough already, too.
Thanks in advance

Tap hold interval

The field is present in the config (to let the option to release 0.2 without implementing this feature).

We can add a tap_hold_interval corresponding to the maximal time within if you tap and hold the key, it will do the tap action, and stay holded, to allow holding the tapping behavior.

The continuation of #33

Layer modifiers only add/stack and don't work as expected

My keyboard has two function keys ("Fun" and "More Fun"). I have defined these keys as l(1) and l(2). I've also configured "Fun-More Fun" and "More Fun-Fun" (both held at once) to invoke l(3): Layer 1 has "More Fun" set to l(3) and layer 2 has "Fun" set to l(3) so if both keys are held down (regardless of order) it should invoke layer 3 but that's not what's happening. Instead of invoking layer 3, pressing both "Fun" and "More Fun" invokes layer 4.

I believe this is because of how Layout.current_layer() (https://github.com/TeXitoi/keyberon/blob/master/src/layout.rs#L396) is defined:

   fn current_layer(&self) -> usize {
        let mut iter = self.states.iter().filter_map(State::get_layer);
        let mut layer = match iter.next() {
            None => self.default_layer,
            Some(l) => l,
        };
        for l in iter {
            layer += l;
        }
        layer
    }

Rather than looking at the layer number specified by Action::Layer() it is merely adding the current layer number (say, 1) to the layer defined for that key (say, 3 which would result in 4). The test case I've come up with is this:

  • Define two keys: One as l(1) and one as l(2).
  • Define both those keys to go to l(3) when the other is pressed.
  • Press both at the same time and it behaves as if you defined them as l(4) instead of l(3).

I haven't figured out how to fix this yet otherwise I'd submit a PR ๐Ÿ˜„

BTW: I discovered this when I was trying to define "LAlt-Fun-Up" (LAlt configured as l(4) in layer 1) to send a thumbs up sequence (๐Ÿ‘) on layer 4 while having "RAlt-More Fun-Up" (LAlt configured as l(5) in layer 2) send a top arrow (๐Ÿ”) on layer 5. It just wasn't working right.

debouncer finetuning

Keen to hear others thoughts on debouncing. I have good days and bad days for debouncing. I think switching it from 5 to 7 helps.

But I'm also curious if there's other algorythms we could try. Typically it's always that I get two of the same letter. Happy to try some stuff, just not quite sure what else to try.

implementing new keyboard

Hi,

i try to implement a new keyboard in keyberon is a 5x13 with an encoder and few led and a strip.
At the moment all is working in qmk.
here is what I did
https://github.com/m-lego/m65
it is practically a copy paste clean from keyberon-f4

now questions I have.

  1. are encoders supported?
  2. are led strips supported?
  3. is there any contribution guide?
  4. can i implement qmk tap dance? now i have two taps toggle the layer permanently 0/x and puts a led on/off to indicate which layer is active
  5. utf-8 support?

now issues i have... I did not test extensively my keyberon firmware but one issue I noticed is

  1. shift + a gives me A| which indicates to me something nefarious with the pins I use. but I do not see that in qmk

Remove possible panics in layout.rs

fn key_codes can panic because it does array access without checking bounds. If there is no element in the layout, just do nothing instead of panicking.

Support for home row mods?

Is it possible to create home row mods? What I mean is alt, Ctrl, GUI and shift on asdf and jkl;

I know that tap-hold is supported, but that doesn't work for home row mods. Just like in qmk you need to add some special funktions to make it work.

Chording aka two keys at the same time to create a keypress

Having realised on matrix keyboards that one can press two keys down fairly easily with one finger by aiming in between them I think that opens up opportunities that should be exlored as if you pick the rigth key combos the false positive rate would be rare.

I'm raising this issue as something that I'd like to see done - I'm not expecting anyone to else to do it (but feel free if the urge takes you). I might get around to doing it soon but am juggling a few things at the moment - not least of which is trying to learn 'hands down' as a keyboard layout.

Teensy LC support?

Hi, I want to build a keyboard and I want to use Rust instead of QMK. I have some Teensy LC lying around I want to use for the build.

Does this firmware support Teensy LC?

Regards and merry Christmas

v0.2.0 Release?

heapless 0.7 is nice, would you mind pushing a new release for 0.2.0?

Do a crate that is microcontroller agnostic

The idea is to provide all you need to construct your keyboard. It will provide:

  • the machinery to do the matrix, allowing the user to choose the pins (almost done)
  • the debouncer (it's already generic enough I think)
  • the layout, that takes in parameters the description of the layers provided by the user
  • the hid to be used with usb-device
  • some examples using the crate based on the bluepill and rtfm

Wakeup Computer from S3 Suspend

I am having difficulty getting my keyboard to wakeup my computer from an S3 suspend.

I am running Linux Kernel 5.10 and have a custom STM32F072 keyboard and can enter sleep with the MediaSleep keycode, but cannot seem to wake my computer with a button press. QMK on the same keyboard does wake up my machine, so I do not believe it is a hardware issue. I also tested with the Keyseebee firmware after just changing the pins, and still was unable to wake my machine.

Has anyone else had this issue? I looked into the stm32-usbd repository for suspend and resume but am not sure if those are even the correct functions to call.

BTW amazing library! I love the new CustomAction functionality for entering DFU.

Best method for keeping track of binary repos using keyberon for popular keyboards

What is the best way the keyberon "community" can keep track of keyboard firmware that has been put together for common keyboards?

If the designer of the keyboard supports QMK, but someone else writes a keyberon firmware for the board, it would be nice to keep track of this.

It seems like most popular keyboards running a Arm Cortex-M MCU could be running keyberon, and it would be nice to share this work with newcomers.

I see the readme starts to do this, but that could get really unwieldy.

Option to filter keys when using HoldTap mods/layers

Related to #33 it would also be useful to be able to ignore certain keys when using holdtap

This is primarily useful when using holdtap on alphas, such as with homerow mods, where it helps to ignore keys adjacent to mods for reliability. Personally I would like to ignore all keys on the same half of my board so that mods are always pressed with the opposite hand.

Note: there is no built-in support for this in QMK as far as I know, so people implement this manually, such as here

Emulating typing

Hey there,

I'm currently making a rubberducky clone (https://hak5.org/products/usb-rubber-ducky-deluxe) with some Rust firmware and was wondering how good this crate would be to send arbitrary inputs via usb (similar to native keyboard macros maybe?) or if I should manually implement it instead. Any thoughts?

Thanks :)

Implement nesting of layers

alt - f1

I have an alt key that also puts me in layer 2. if I then press a key to get to layer 3 as well then when I press the F1 key I get what's in layer 2 for that not what's in layer 3.

If instead I press layer 3 and then press alt (which in this case is a plain alt and not messing with layers) and then press the F1 key it all works fine. Would be great if both roads lead to the same place. Is this possible?

Teensy LC support?

Hi, I want to build a keyboard and I want to use Rust instead of QMK. I have some Teensy LC lying around I want to use for the build.

Does this firmware support Teensy LC?

Regards and merry Christmas

HoldMultiTap Actions

Without going all the way to Morse code style beats it'd be nice to extend the HoldTap (or have another action type) to have double/triple click style actions.

An example usecase for that is:

  • Single tap : k(PScreen)
  • Double tap : k(ScrollLock)
  • Triple tap : k(Menu)
  • Hold : l(1)

USB not enumerating on stm32f042xx

Mostly out of curiosity I tried to run keyberon on a STM32F042F6P6 (it has enough flash and built-in USB), but the device does not enumerate and UsbDevice.poll always returns false. I constructed a minimal example:

#![no_std]
#![no_main]

extern crate panic_halt;

use cortex_m_rt::entry;

use stm32f0xx_hal as hal;
use hal::prelude::*;

use usb_device::class::UsbClass;
use usb_device::bus::UsbBusAllocator;
use hal::usb;

#[entry]
fn main() -> ! {
    let mut p = hal::pac::Peripherals::take().unwrap();
    static mut USB_BUS: Option<UsbBusAllocator<hal::usb::UsbBusType>> = None;

    let mut rcc = p
        .RCC
        .configure()
        .hsi48()
        .enable_crs(p.CRS)
        .sysclk(48.mhz())
        .pclk(24.mhz())
        .freeze(&mut p.FLASH);

    let gpioa = p.GPIOA.split(&mut rcc);

    let usb = usb::Peripheral {
        usb: p.USB,
        pin_dm: gpioa.pa11,
        pin_dp: gpioa.pa12,
    };
    let usb_bus = unsafe {
        USB_BUS = Some(stm32f0xx_hal::usb::UsbBusType::new(usb));
        USB_BUS.as_ref().unwrap()
    };

    let mut usb_class = keyberon::new_class(usb_bus, ());
    let mut usb_dev = keyberon::new_device(usb_bus);
    
    loop {
        if usb_dev.poll(&mut [&mut usb_class]) {
            // This is never reached
            usb_class.poll();
        }
    }
}

This code depends directly on the master branch of keyberon. Dmesg -w always shows

new full-speed USB device number 55 using xhci_hcd
Device not responding to setup address.
Device not responding to setup address.
device not accepting address 55, error -71

not-so-latest stable rust breaks things

I'm getting this with latest rust:
cortex_m_rt::HardFault_ (ef=0x20004e08) at C:\Users\giles.cargo\registry\src\github.com-1ecc6299db9ec823\cortex-m-rt-0.6.12\src\lib.rs:552

1.47 is fine. Will binary chop.

What's the minimal required MCU?

Hi, I want to make a keyboard PCB and I want to use keyberon as firmware. I have some questions to select a MCU.

What is the minimal required MCU for keyberon?
How much flash, RAM, clock frequency?
Is EEPROM useful or not supported at all?
Is a Cortex-M0 enough?

Happy new year

Request: Single tap mod keys

I am guessing I am not the only one to want to try this. Specifically I would like to try it on shift as that is the most commonly used modifier.

Maybe the easist way to do this is detect if a shift is pressed and relesed but no other key strokes have occured in the meantime. That would not require any timings. If that was detected we could wrap the next keystroke down with a shift down before and a shift up immediately after. no need I would think to wait till the pressed key had arrisen.

Thoughts?

Add support for media buttons

At the moment Keyberon has support for key codes in the Generic Desktop Ctrls usage page. This includes the key codes up to and including RGui which has value 0xE7.

There is support in the HID spec for some more controls that might be useful to add that are in the Consumer Control page.
These could include pulled from QMK:

// 15.5 Display Controls
    SNAPSHOT               = 0x065,
    BRIGHTNESS_UP          = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf
    BRIGHTNESS_DOWN        = 0x070,
    // 15.7 Transport Controls
    TRANSPORT_RECORD       = 0x0B2,
    TRANSPORT_FAST_FORWARD = 0x0B3,
    TRANSPORT_REWIND       = 0x0B4,
    TRANSPORT_NEXT_TRACK   = 0x0B5,
    TRANSPORT_PREV_TRACK   = 0x0B6,
    TRANSPORT_STOP         = 0x0B7,
    TRANSPORT_EJECT        = 0x0B8,
    TRANSPORT_RANDOM_PLAY  = 0x0B9,
    TRANSPORT_STOP_EJECT   = 0x0CC,
    TRANSPORT_PLAY_PAUSE   = 0x0CD,
    // 15.9.1 Audio Controls - Volume
    AUDIO_MUTE             = 0x0E2,
    AUDIO_VOL_UP           = 0x0E9,
    AUDIO_VOL_DOWN         = 0x0EA,
    // 15.15 Application Launch Buttons
    AL_CC_CONFIG           = 0x183,
    AL_EMAIL               = 0x18A,
    AL_CALCULATOR          = 0x192,
    AL_LOCAL_BROWSER       = 0x194,
    AL_LOCK                = 0x19E,
    AL_CONTROL_PANEL       = 0x19F,
    AL_ASSISTANT           = 0x1CB,
    AL_KEYBOARD_LAYOUT     = 0x1AE,
    // 15.16 Generic GUI Application Controls
    AC_MINIMIZE            = 0x206,
    AC_SEARCH              = 0x221,
    AC_HOME                = 0x223,
    AC_BACK                = 0x224,
    AC_FORWARD             = 0x225,
    AC_STOP                = 0x226,
    AC_REFRESH             = 0x227,
    AC_BOOKMARKS           = 0x22A

I'm opening this issue to start a discussion on if/how this could be implemented.

In order to implement this, the report descriptor would need to be updated to include a second report on the Consumer Control page. This would mean that report IDs would need to be introduced and key codes routed to the correct report and multiple reports would need to be sent via the usb class.

I was thinking that KbHidReport could be extended to store two reports internally and then write one or two reports as bytes depending on what keys have been pressed.

What do you think?

Release shift action

My use case is to have \ and / on a single key.
To get a \ I want to press this key without shift.
To get a / I want to press this key while holding shift.

/ is non-shifted on the US layout and thus this would require multiple actions:

  • temporally releasing shift
  • press / key
  • holding shift again to recreate the correct state

Looking at the code, I think I need a new Action which creates a CustomEvent::Release? I am pretty lost though, due to my unfamiliarity with Rust. Happy to dig in deeper with your guidance, though.

keyboard layout prettyness

The layers design takes a lot of work to keep looking neat. Lots of tabbing to make sure it alligns nicely in a grid.

Wondering if there's a nicer way... I think there's some nice ideas here:
https://github.com/qmk/qmk_firmware/blob/master/layouts/community/ortho_5x14/yet-another-developer/keymap.c

but wrapped all into one. Half of me thinks that ideally rustfmt could do a better job with arrays ( rust-lang/rustfmt#4710 ) but half of me thinks some macro magic might be the answer...

Implement Custom action

First of all thanks for the code, I love my DIY keyboard with own keybindings,
my question is now is there a why so simulate the mouse.
So that I have mouse-like with arrow keys.
Or is that in plan?

keyberon without RTIC

Is there any example of using Keyberon without RTIC?

I am trying to put together a keypad using a Longan Nano board which features a RISC-V MCU.
RTIC at the moment is not supported outside of cortex MCUs, so I cannot use it.

In particular I am trying to figure out how to replace

fn send_report(iter: impl Iterator<Item = KeyCode>, usb_class: &mut resources::usb_class<'_>) {
    use rtic::Mutex;
    let report: KbHidReport = iter.collect();
    if usb_class.lock(|k| k.device_mut().set_keyboard_report(report.clone())) {
        while let Ok(0) = usb_class.lock(|k| k.write(report.as_bytes())) {}
    }
}

Handle errors from embedded_hal

For the moment, we only support Error = Void, which is quite limiting. Matrix::get should return a Result with the error. We will force that the errors on InputPin and OutputPin are of the same type.

Additional configuration for HoldTap

To be able to use home row mods it's useful to able to tweak HoldTap. For example like IGNORE_MOD_TAP_INTERRUPT and PERMISSIVE_HOLD in QMK.

@TeXitoi Proposition:

The different behaviors:

  • Default: our actual, corresponding to QMK default for LT, or IGNORE_MOD_TAP_INTERRUPT for MT.
  • HoldOnOtherKeyPress: if a key is pressed during a HoldTap it waiting for deciding what to do, it hold now. Corresponding to the functionnality of the same name on QMK LT
  • PermissiveHold: if a key is released and pressed during a HoldTap waiting, it hold now.Corresponding to the functionnality of the same name on QMK LT.

Also, we can add a tap_hold_duration corresponding to the maximal time within if you tap and hold the key, it will do the tap action, and stay holded, to allow holding the tapping behavior. (moved in #37)

It can be modeled as:

pub enum HoldTapConfig {
    Default,
    HoldOnOtherKeyPress,
    PermissiveHold,
}

pub enum Action {
    // ...
    HoldTap {
        hold: &'static Action,
        tap: &'static Action,
        timeout: u16,
        tap_hold_interval: u16,
        config: HoldTapConfig,
    },
}

That's a breaking change.

Implement multikey

Implement, when typing on a key, multiple keys are sends (as if all the keys are pressed at the same time.

Support for DIRECT_PIN from QMK?

Hi, I have a split keyboard with a WeAct Mini F4, where the switches are connected directly to the pins of the controller. It currently runs on QMK, but I'm planning on switching to keyberon. I took a brief look at the codebase, and it seems that there's currently no support for something like "DIRECT_PIN" from QMK.

I guess using a "ghost pin" (such as the A13/A14 pin used for serial debugging/flashing the MCU) would be the best bet for the firmware as it currently is? Breakout board's pinout. I use DFU for flashing, so it won't bother me to use those pins.

But that approach would not work if there are no free pins available on the controller, so in the meantime I guess I would also be interested in exploring a similar feature for keyberon. Would you be willing to entertain a PR for the same? (I currently have no clue as to how it will integrate in the existing code, but that's for later ๐Ÿ˜„ )

KiCAD schematic for one half of the keyboard (the "other" side is the same)
Image 03-12-2021 at 08 47

In case someone is looking at this issue and does not know what is DIRECT_PIN, here's a very short explanation: A switch is connected to (say) pin P1 on the MCU, with the other terminal of the switch being connected to GND. Pin P1 is set internally as "pull-up high". Then, whenever the switch is pressed, P1 gets pulled low. Its actually pretty much the same as the current matrix implementation: just that there is no "row" --> it's always GND.
The get function from matrix.rs would then become:

pub fn get<E>(&mut self) -> Result<PressedKeys<CS, RS>, E>
    where
        C: InputPin<Error = E>,
        R: OutputPin<Error = E>,
    {
        let mut keys = PressedKeys::default();

       //  for (ri, row) in (&mut self.rows).iter_mut().enumerate() {
       //     row.set_low()?;
            for (ci, col) in (&self.cols).iter().enumerate() {
                keys.0[ri][ci] = col.is_low()?;
            }
      //      row.set_high()?;
      //  }
        Ok(keys)
    }

The above code will obviously not work with the current implementation ;) .

Please let me know if I missed mentioning something!

USB won't register anything beyond the first report

This isn't a bug in keyberon, but a call for help :).

I'm hacking a firmware based on keyberon and a library
called keytokey (unreleased...) that turns key-streams into usb key outputs,
and is supposed to abstract away from the keyboard firmware and allows
unit testing of arbitrary keyboard inputs. That part is mostly done, and should
support most of what QMK offers in this regard.

My issue is with the USB-Hid stuff -
I'm getting the computer to read the first report, but as soon as I want to send another one (be it empty or another key press), my firmware hangs and the computers autorepeat keeps repeating that first keypress.

Perhaps you might have run into a similar problem?

Code is at https://github.com/TyberiusPrime/stm32f103_k2k/tree/master/src
guess you,d want to look into usbout first.

Thank you so very much for getting HID working on Rust+Stm32!

Is the Ferris 0.2 supported by keyberon?

I want to build a keyboard like the Ferris and I want to be able to use keyberon and QMK as firmware. As far as I know the Ferris has QMK support.

The Ferris 2.0 uses a MCP23017 IO expander. Is this supported by keyberon? The only split keyboard with keyberon support is keyseebee, but this has no QMK support as far as I know.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.