-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do a crate that is microcontroller agnostic #14
Comments
@TheZoq2 relevant issue where we can discuss about a keyboard crate. |
Some person that might be interested: @ah- @hdhoang @TyberiusPrime |
Very nice. For it to work with my keyboard, it also has to support split keyboards and backlight. Keebrs deals with the first point really well. Each the boards send coordinates of keys pressed over serial. Whichever board gets a USB connection makes itself master, and you can even chain boards. It would be kind of nice to see something like This would interract with implementaions of some traits like enum EventType {
Press,
Release
}
pub struct KeyEvent {
coords: (u8, u8),
type: EventType
}
// Could be implemented for matrix checks, data from another keyboard etc.
pub trait KeypressSource {
fn events(&mut self) -> Iterator<Item=KeyEvent>
}
pub trait BacklightRenderer {
fn render(<some structure representing>) {}
} What do you think? |
Yeah, that's exactly the kind of feedbacks that I'm looking for. A trait with some kind of combinators/modifiers would be great. For example, something to translate the events, or convert a 8x6 to a 4x12 matrix. I'm not sure I want to manage backlight explicitly, but allowing custom events in the layout would allow to manage other things as lights, sound, screen or anything else. |
Yea, that's something I'd like as well. I imagine being able to do something like let local_scanner = Matrix::new();
let slave_scanner = OtherKeyboardOverSerial::new();
let full_scanner = local_scanner
.merge(slave_scanner.translate(|x, y| x + 6));
let layout = Layout::new();
loop {
let raw_keys = full_scanner.new_keys();
let pressed_keys = layout.translate(raw_keys)
usb.send(pressed_keys)
backlight.new_events(pressed_keys, raw_keys);
} There are probably plenty of issues with this API, but something along those lines would suit all my needs I think |
I'd love to see this done - I miserably failed even abstracting over the pins of one platform. For the 'turning presses into USB-input' part (layers etc...) you might want to check out my keytokey crate, which does this in a totally processor agnostic and flexible way: https://github.com/TyberiusPrime/KeyToKey It's configuration is a departure from the qmk style 'define each key on each layer' approach though. |
Wow, these are both really cool! What are you doing about the USB stack, is there something robust around now? |
keytokey abstracts the usb stack into a trait that collects usb-keycodes for sending by the stack. I have a reference implementation for the bluepill, the stack is borrowed from Keyberon (great work, btw, it's been very robust against my coding mishaps during development). |
@TyberiusPrime For the generic matrix implementation, you can look at https://github.com/TeXitoi/keyberon/blob/master/src/matrix.rs That's not yet finished as you now need to declare your pin like that: pub struct Cols(
pub PB12<Input<PullUp>>,
pub PB13<Input<PullUp>>,
pub PB14<Input<PullUp>>,
pub PB15<Input<PullUp>>,
pub PA8<Input<PullUp>>,
pub PA9<Input<PullUp>>,
pub PA10<Input<PullUp>>,
pub PB5<Input<PullUp>>,
pub PB6<Input<PullUp>>,
pub PB7<Input<PullUp>>,
pub PB8<Input<PullUp>>,
pub PB9<Input<PullUp>>,
);
impl_getter! {
Cols,
dyn _embedded_hal_digital_InputPin,
U12,
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
}
pub struct Rows(
pub PB11<Output<PushPull>>,
pub PB10<Output<PushPull>>,
pub PB1<Output<PushPull>>,
pub PB0<Output<PushPull>>,
pub PA7<Output<PushPull>>,
);
impl_getter! {
Rows,
dyn _embedded_hal_digital_OutputPin,
U5,
[0, 1, 2, 3, 4]
}
let mut matrix = matrix::Matrix::new(
Cols(
gpiob.pb12.into_pull_up_input(&mut gpiob.crh),
gpiob.pb13.into_pull_up_input(&mut gpiob.crh),
gpiob.pb14.into_pull_up_input(&mut gpiob.crh),
gpiob.pb15.into_pull_up_input(&mut gpiob.crh),
gpioa.pa8.into_pull_up_input(&mut gpioa.crh),
gpioa.pa9.into_pull_up_input(&mut gpioa.crh),
gpioa.pa10.into_pull_up_input(&mut gpioa.crh),
gpiob.pb5.into_pull_up_input(&mut gpiob.crl),
gpiob.pb6.into_pull_up_input(&mut gpiob.crl),
gpiob.pb7.into_pull_up_input(&mut gpiob.crl),
gpiob.pb8.into_pull_up_input(&mut gpiob.crh),
gpiob.pb9.into_pull_up_input(&mut gpiob.crh),
),
Rows(
gpiob.pb11.into_push_pull_output(&mut gpiob.crh),
gpiob.pb10.into_push_pull_output(&mut gpiob.crh),
gpiob.pb1.into_push_pull_output(&mut gpiob.crl),
gpiob.pb0.into_push_pull_output(&mut gpiob.crl),
gpioa.pa7.into_push_pull_output(&mut gpioa.crl),
),
);
matrix.clear(); The need to give the |
@ah- For the usb stack, I use https://crates.io/crates/stm32-usbd The hid implementation is https://github.com/TeXitoi/keyberon/blob/master/src/hid.rs and only depend on https://crates.io/crates/usb-device I use it daily without any problem, but I don't have your usecase of pluging and unpluging without a reset of the microcontroller. |
Update: I know have a crate that expose building blocks for constructing a keyboard. I should now be trivial to port keyberon on any MCU supporting It doesn't add any feature, so your use case might not be supported yet (Keyberon is not really event driven for the moment, for example). If you have any feedbacks, feel free to tell! |
Your |
I think it would be super if you did this. I threw together a simple midi one, before and I was thinking of doing a USB hid one, but then stumbled upon this project. It would be awesome to split that into it's own crate. |
I too would like to see |
With 0.1.0 just published, we can close this. |
The idea is to provide all you need to construct your keyboard. It will provide:
The text was updated successfully, but these errors were encountered: