Skip to content
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

Pointing device #9

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft

Pointing device #9

wants to merge 9 commits into from

Conversation

Univa
Copy link
Owner

@Univa Univa commented Apr 4, 2024

Applicable Changes

  • Feature addition
  • Modification to behaviour of existing functionality (potential breaking change)
  • Modification to existing public APIs (potential breaking change)
  • Bug fix
  • User docs modification
  • Rust toolchain updates
  • Dependency updates
  • Workflow change (GitHub Actions)
  • Repository housekeeping (e.g. READMEs, licensing, templates, etc.)

Related Issues

#8

Description of Changes

Added a pointing module to support pointing devices like a mouse or touchpad. Note that this only adds support for pointing devices over USB for now. Bluetooth support to come later.

Testing Instructions

Try out the IQS5xx pointing driver in your main.rs (assuming a non-split keyboard):

#[keyboard(
    usb,
    pointer(
        driver_setup_fn = test_pointer,
    )
)]
struct MyKeyboard;

impl rumcake::pointer::PointingDevice for MyKeyboard {
    type MouseEventCollector = Self;
}
impl rumcake::pointer::MouseEventCollector for MyKeyboard {}
async fn test_pointer() -> impl rumcake::pointer::PointingDriver {
    rumcake::drivers::iqs5xx::setup_driver(
        setup_i2c! {
            /* ... */
        },
        input_pin!( /* pin identifier */ ),
        output_pin!( /* pin identifier */ ),
    )
}

The touchpad should be capable of basic cursor movements, scrolling (with two fingers sliding), left-clicks (via single finger tap), right-clicks (via two finger tap), and left-click holding (press hold).

More complicated behaviour can be implemented by overriding the implementation of tick and handle_event in the IQS5xxPointingDriver trait

Check-list

  • I have updated or added to the user docs where applicable
  • I have tested the changes on real hardware if applicable
  • The changes do not break compilations with other potentially related feature flags
  • Credit given where applicable

@Univa
Copy link
Owner Author

Univa commented Apr 4, 2024

@wallamide Would you be able to test the IQS5xx driver? I don't have access to a touchpad, so whatever I added in here is just best effort. I didn't aim to replicate the implementation that you provided for now, since I'm not sure whether that would be a sane default behaviour. If you would like to have functionality similar to that, you can always reimplement IQS5xxPointingDriver yourself with your own types (particularly handle_event in the trait allows you to register touchpad events however you want).

@Univa Univa linked an issue Apr 4, 2024 that may be closed by this pull request
4 tasks
@wallamide
Copy link

@Univa thanks for the ping! i'm sadly recovering from being sick so i'll need to check this out in a day or so.

looking this over, i had a few questions:

  • it looks like i'll need to connect rdy/scl/sda/3.3v/gnd/rst on the trackpad to my mcu, correct?
  • this should be compatible with a nice!nano v2 build right?
  • is there via(l) compatibility with the pointer?

thanks again for sharing and i'm looking forward to checking this out!

@Univa
Copy link
Owner Author

Univa commented Apr 5, 2024

@Univa thanks for the ping! i'm sadly recovering from being sick so i'll need to check this out in a day or so.

looking this over, i had a few questions:

* it looks like i'll need to connect rdy/scl/sda/3.3v/gnd/rst on the trackpad to my mcu, correct?

* this should be compatible with a nice!nano v2 build right?

* is there via(l) compatibility with the pointer?

thanks again for sharing and i'm looking forward to checking this out!

@wallamide
Copy link

wallamide commented Apr 6, 2024

@Univa thanks again for answering my questions! one last question before i get to this: is there anything preventing me from using the trackpad with a split keyboard on the peripheral/right half? like on zmk for a while you could only add a pointer to the main half not to the peripheral.

just to let you know my plan, i'll be testing out the default functionality with a firmware of just the pointer and giving feedback then i was hoping to try flashing a my layout and making sure it's still working the same. then i'd like to get familiar with the default for a bit and try modifying it.

@Univa
Copy link
Owner Author

Univa commented Apr 7, 2024

@Univa thanks again for answering my questions! one last question before i get to this: is there anything preventing me from using the trackpad with a split keyboard on the peripheral/right half? like on zmk for a while you could only add a pointer to the main half not to the peripheral.

just to let you know my plan, i'll be testing out the default functionality with a firmware of just the pointer and giving feedback then i was hoping to try flashing a my layout and making sure it's still working the same. then i'd like to get familiar with the default for a bit and try modifying it.

Usage of the trackpad isn't supported on a peripheral side yet since there is no enum variant in MessageToCentral that would be responsible for carrying the input data. Adding support for that shouldn't be too difficult, though. I can get around to that soon.

@wallamide
Copy link

i was unable to get my firmware to build. i used cargo generate to create a test firmware and i keep getting this error when trying to build:

error: failed to run custom build command for `rust-lzma v0.6.0`

Caused by:
  process didn't exit successfully: `C:\...\pointer-test\target\debug\build\rust-lzma-61258936f45e49e9\build-script-build` (exit code: 101)
  --- stderr
  thread 'main' panicked at C:\Users\...\.cargo\registry\src\index.crates.io-6f17d22bba15001f\rust-lzma-0.6.0\build.rs:13:14:
  Could not find liblzma using vcpkg: VcpkgNotFound("No vcpkg installation found. Set the VCPKG_ROOT environment variable or run 'vcpkg integrate install'")
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

i'm running on windows 11.

@Univa
Copy link
Owner Author

Univa commented Apr 8, 2024

I don't develop on windows, but it looks like you might be missing vcpkg?

also does some slight api changes:
- CentralDevice::Layout is now optional
- MATRIX_EVENTS get published events from the matrix polling task and central task, instead of peripheral task and layout collect task
- split setup function for iqs5xx into two different types: one for default behavior, and another for custom implementor of IQS5xxEventHandler
- mouse tasks are now split into two: polling task and mouse event collection task (similar to matrix polling and layout collect)
- PeripheralDevice::get_matrix_events_channel changed to return a channel of MessageToCentral instead
@Univa
Copy link
Owner Author

Univa commented Apr 10, 2024

@wallamide I added support for a peripheral-side pointing device, but it may not be entirely stable. The last commit also changes some of the API, so I also updated the instructions in the original comment.

Peripheral side should look something like this:

#[keyboard(
    usb,
    split_peripheral(
        driver_setup_fn = setup_split_driver
    ),
    pointer(
        driver_setup_fn = test_pointer,
    )
)]
struct MyKeyboard;

async fn test_pointer() -> impl rumcake::pointer::PointingDriver {
    // ...
}
impl rumcake::pointer::PointingDevice for MyKeyboard {
    type PeripheralDeviceType = Self; // send mouse events to a central device
}

impl rumcake::split::peripheral::PeripheralDevice for MyKeyboard {}
async fn setup_split_driver() -> impl rumcake::split::peripheral::PeripheralDeviceDriver {
    // ...
}

Central should look like:

#[keyboard(
    usb,
    split_central(
        driver_setup_fn = setup_split_driver
    )
)]
struct MyKeyboard;

// collects mouse events from peripherals
impl rumcake::pointer::MouseEventCollector for MyKeyboard {}

impl rumcake::split::central::CentralDevice for MyKeyboard {
    type MouseEventCollector = Self;
}
async fn setup_split_driver() -> impl rumcake::split::central::CentralDeviceDriver {
    // ...
}

@wallamide
Copy link

thanks for the update! i actually am unable to build a basic firmware using the template for the split, though it's looking like this is the result of the refactor. i'll see if i can get it compiling using just the example code in a sec. were you able to check my repo linked above to make sure what i had originally should be working?

@Univa
Copy link
Owner Author

Univa commented Apr 11, 2024

My bad, I totally forgot to update those templates. I pushed some updates which should hopefully work now. If you use those templates, then add my example code from my previous comment, you should be able to get something compiling.

@wallamide
Copy link

okay, so i'm unsure what i need to change atm, but i'm getting a few errors from this pointer setup function:

async fn test_pointer() -> impl rumcake::pointer::PointingDriver {
    rumcake::drivers::iqs5xx::setup_driver(
        setup_i2c! {
            interrupt: P0_22,
            i2c: P0_24,
            sda: P0_17,
            scl: P0_20,
        }, 
        input_pin!(P0_24),
        output_pin!(P0_22),
    )
}

here's the main errors, i can post the full log if you need as well. i definitely recommend adding an i2c docs page when you have time or i could help once we can get this sorted out.

error[E0412]: cannot find type `P0_22` in module `$crate::interrupt::typelevel`
error[E0425]: cannot find value `P0_22` in module `rumcake::hw::platform::embassy_nrf::interrupt`
error[E0277]: the trait bound `P0_24: rumcake::hw::platform::embassy_nrf::twim::Instance` is not satisfied

@Univa
Copy link
Owner Author

Univa commented Apr 14, 2024

i2c should be one of the TWISPI peripherals: https://docs.embassy.dev/embassy-nrf/git/nrf52840/twim/trait.Instance.html#implementors

interrupt should be the corresponding interrupts for that chosen i2c peripheral: https://docs.embassy.dev/embassy-nrf/git/nrf52840/twim/trait.Instance.html#implementors

So, you can change the setup_i2c to something like this:

setup_i2c! {
    interrupt: SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0,
    i2c: TWISPI0,
    sda: P0_17,
    scl: P0_20,
},

I'll add docs to the API reference at some point to hopefully clarify this stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add touchpad support
2 participants