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

add: Cirque Pinnacle trackpad driver #1116

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

crides
Copy link
Contributor

@crides crides commented Feb 3, 2022

This adds the driver for Cirque Pinnacle trackpads. Note this is only the driver, support for fetching the data and binding behaviours to it should be added later as it depends on reworking the sensor subsystem.

The driver uses only the SPI/I2C bus and the dr data ready pin if available.

The implementation of the driver follows the Cirque documentation. While the docs mentions using the sleep mode with high SPI speeds can be a problem, this is not observed in reality (I'm using a SPI clock of 10MHz).

Usage example: https://github.com/crides/zmk/blob/fusion-led-c-config/app/boards/arm/fusion/trackpad.c

@crides
Copy link
Contributor Author

crides commented Apr 12, 2022

For transparency, I've been using this driver on my Fusion board for a while, and it seems to work fine for the most part, but sometimes it can cause weird bugs. I'm only starting to debug this, and I have no idea why (so it could be related to my driver or not) but when it happens it just messes up the screen and the system freezes.

@crides
Copy link
Contributor Author

crides commented Apr 20, 2022

Okay, so this is weird... Cirque has some interesting data format for the relative mode (which is all I use; see page 10). It would be helpful if others can help me see if there's some interpretation problem here or it's just cirque being weird.

So sometimes the driver will output some spuriously large data, and here's some of the instances. handle_trackpad just prints out the signed delta X, delta Y and the button flags, and we only need to focus on the deltas. The pak logs the raw packet data (PacketByte_0 to PacketByte_2 inclusive) if the deltas are too big, and is for the line below. In these testings I just move my finger roughly in a circle.

[00:04:13.368,774] <dbg> trackpad: handle_trackpad: trackpad -3 13 00
[00:04:13.383,758] <dbg> trackpad: handle_trackpad: trackpad 0 10 00
[00:04:13.398,742] <dbg> trackpad: handle_trackpad: trackpad 4 6 00
[00:04:13.413,757] <dbg> trackpad: handle_trackpad: trackpad 4 6 00
[00:04:13.428,741] <dbg> trackpad: handle_trackpad: trackpad 9 6 00
[00:04:13.443,725] <dbg> trackpad: handle_trackpad: trackpad 9 6 00
[00:04:13.458,740] <dbg> trackpad: handle_trackpad: trackpad 12 5 00
[00:04:13.473,724] <wrn> pinnacle: pak 0x08 0c ff
[00:04:13.473,724] <dbg> trackpad: handle_trackpad: trackpad 12 255 00
[00:04:13.488,739] <dbg> trackpad: handle_trackpad: trackpad 12 -1 00
[00:04:13.503,723] <dbg> trackpad: handle_trackpad: trackpad 12 -6 00
[00:04:13.518,707] <dbg> trackpad: handle_trackpad: trackpad 7 -6 00
[00:04:13.533,721] <dbg> trackpad: handle_trackpad: trackpad 1 -9 00
[00:04:13.563,690] <dbg> trackpad: handle_trackpad: trackpad -3 -5 00
[00:04:13.578,704] <dbg> trackpad: handle_trackpad: trackpad -11 -5 00
[00:03:56.470,428] <dbg> trackpad: handle_trackpad: trackpad 7 3 00
[00:03:56.480,072] <dbg> trackpad: handle_trackpad: trackpad 6 2 00
[00:03:56.480,346] <dbg> trackpad: handle_trackpad: trackpad 6 2 00
[00:03:56.488,891] <dbg> trackpad: handle_trackpad: trackpad 5 1 00
[00:03:56.489,135] <dbg> trackpad: handle_trackpad: trackpad 5 1 00
[00:03:56.499,267] <dbg> trackpad: handle_trackpad: trackpad 6 0 00
[00:03:56.514,190] <dbg> trackpad: handle_trackpad: trackpad 6 0 00
[00:03:56.529,205] <wrn> pinnacle: pak 0x08 08 fc
[00:03:56.529,205] <dbg> trackpad: handle_trackpad: trackpad 8 252 00
[00:03:56.529,815] <dbg> trackpad: handle_trackpad: trackpad 16 -4 00
[00:03:56.539,001] <dbg> trackpad: handle_trackpad: trackpad 15 -5 00
[00:03:56.539,245] <dbg> trackpad: handle_trackpad: trackpad 15 -5 00
[00:03:56.549,530] <dbg> trackpad: handle_trackpad: trackpad 12 -6 00
[00:03:56.549,774] <dbg> trackpad: handle_trackpad: trackpad 12 -6 00
[00:03:56.559,173] <dbg> trackpad: handle_trackpad: trackpad 11 -7 00
[00:03:56.574,188] <dbg> trackpad: handle_trackpad: trackpad 9 -8 00
[00:03:48.185,211] <dbg> trackpad: handle_trackpad: trackpad 19 8 00
[00:03:48.193,664] <dbg> trackpad: handle_trackpad: trackpad 24 7 00
[00:03:48.193,939] <dbg> trackpad: handle_trackpad: trackpad 24 7 00
[00:03:48.206,878] <dbg> trackpad: handle_trackpad: trackpad 25 4 00
[00:03:48.221,862] <dbg> trackpad: handle_trackpad: trackpad 24 2 00
[00:03:48.236,846] <wrn> pinnacle: pak 0x08 14 ff
[00:03:48.236,877] <dbg> trackpad: handle_trackpad: trackpad 20 255 00
[00:03:48.237,457] <dbg> trackpad: handle_trackpad: trackpad 17 -1 00
[00:03:48.240,661] <dbg> trackpad: handle_trackpad: trackpad 12 -3 00
[00:03:48.240,905] <dbg> trackpad: handle_trackpad: trackpad 12 -3 00
[00:03:48.251,708] <dbg> trackpad: handle_trackpad: trackpad 7 -3 00
[00:03:48.252,014] <dbg> trackpad: handle_trackpad: trackpad 7 -3 00
[00:03:48.266,845] <dbg> trackpad: handle_trackpad: trackpad 4 -6 00
[00:03:48.281,860] <dbg> trackpad: handle_trackpad: trackpad 0 -11 00

@petejohanson
Copy link
Contributor

@crides Sure seems to be at the "transition point" from positive to negative values for the delta. Is there a moment when the sign bit and the value are "out of sync" perhaps?

@crides
Copy link
Contributor Author

crides commented Apr 20, 2022

Hmm that is very likely.. But the datasheet/comm format doesn't specify anything at all about syncing data, and I'm assuming auto-inc reads should make sure that it doesn't read across update epochs. Seems like something worth asking Cirque sales

@MikaelElkiaer
Copy link

I am building a ffkb with a Nice!nano and a Cirque trackpad, so I could help trying this out - if I could just get a few pointers on how to get started. :)

@crides
Copy link
Contributor Author

crides commented Jun 6, 2022

@MikaelElkiaer Do you have any specific directions you want to look at? If you just wanna use it you should just merge this PR, the mouse PR, and then some version of the example "configuration" code linked in the start. Look around at the configs in the fusion board.

@MikaelElkiaer
Copy link

@MikaelElkiaer Do you have any specific directions you want to look at? If you just wanna use it you should just merge this PR, the mouse PR, and then some version of the example "configuration" code linked in the start. Look around at the configs in the fusion board.

Yeah, I just wanted to try it out and use it.
So this branch is not built on top of the mouse changes?
Thanks for some useful info.

@crides
Copy link
Contributor Author

crides commented Jun 6, 2022 via email

@drzony
Copy link

drzony commented Jul 30, 2022

@crides The fetching is incorrect in your case. The sign is not in the data[1] and data[2] it's in data[0]. So:

    if ((data[0] & 0x10) && data[1] != 0) {
        xDelta = -((int16_t)256 - (int16_t)(data[1]));
    } else {
        xDelta = data[1];
    }
    if ((data[0] & 0x20) && data[2] != 0) {
        yDelta = ((int16_t)256 - (int16_t)(data[2]));
    } else {
        yDelta = -((int16_t)data[2]);
    }
    wheelCount = ((int8_t*)data)[3];

@crides
Copy link
Contributor Author

crides commented Jul 30, 2022

I know that. The problem is that the sign bits and the data bytes may not be synced, and cause weird problems. I've contacted cirque about it, never got a response

@drzony
Copy link

drzony commented Jul 30, 2022

Weird, I'm running relative mode on QMK (just got it merged into develop) and I don't seem to have this problem. (The code above is taken from my test code not QMK, just to be on safe side in terms of licensing, I ported it to QMK afterwards). Maybe try running QMK to compare results (might be some HW issue). Also there is SW_DR bit, maybe it's worth checking it after hardware pin is asserted. I have the trackpad connected via I2C, so that is another variable.

@drzony
Copy link

drzony commented Jul 30, 2022

Also maybe I'm missing something in the code, but the SW_DR flag in REG 0x02 should be cleared after every packet read.
It seems it's only there if the PINNACLE_TRIGGER is enabled. Maybe moving it to the end of fetch would help. I'll try to implement I2C (I'm not sure about licensing issues since I just implemented it in QMK, so maybe I'm not the right person) and do some testing.

@crides
Copy link
Contributor Author

crides commented Jul 30, 2022

I'm not sure why one would clear DR when the trigger is not set, cuz the DR status is not used anyway

@drzony
Copy link

drzony commented Jul 30, 2022

From the spec:

To interrupt or alert the host when data is ready, Pinnacle uses a Hardware Data Ready (HW_DR) signal
(active HIGH) that is triggered by either the Command Complete (SW_CC) flag or the Software Data Ready
(SW_DR) flag in the Status1 register address 0x02. When either software flag is set, the HW_DR (pin 36 PA2)
is also asserted. The SW_DR and SW_CC flags must be manually cleared by the host.
The HW_DR signal remains asserted while either SW_DR or SW_CC is asserted

So my understanding is that SW_DR flag is set by the chip when data is available, this causes HW_DR to be asserted. To clear HW_DR you need to clear both SW_CC and SW_DR flags. I do not have a pin available for use with HW_DR, so I'm using SW_DR to check for data, and then clear it after each read. I'm saying that this might be the cause for out-of-sync data.

@crides
Copy link
Contributor Author

crides commented Nov 25, 2022

Added the I2C part of the driver. Both the I2C and SPI versions use the same devicetree compatible instance, just on different buses.

Copy link
Contributor

@petejohanson petejohanson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the driver work! A few comments/questions for a first pass.

menuconfig PINNACLE
bool "PINNACLE Incremental Encoder Sensor"
depends on GPIO
depends on SPI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
depends on SPI
depends on SPI || I2C

# Copyright (c) 2022 The ZMK Contributors
# SPDX-License-Identifier: MIT

menuconfig PINNACLE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally the folder/file naming should match the Kconfig naming... Which is the authoritative/canonical name for this hardware?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, which is why it's inconsistent. The manufacturer is Cirque, the product is called Glide Point (circle trackpad; though nobody seems to refer it by that name), and the ASIC used on the version sold at Mouser is Pinnacle. There are newer versions of the ASIC, not sure if they are sold in a complete product (so I'm not sure if Glide Point is specific enough, if we want to settle on a name).

#endif
};

DEVICE_DT_INST_DEFINE(0, pinnacle_init, device_pm_control_nop, &pinnacle_data, &pinnacle_config, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &pinnacle_driver_api);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to assume from the get go that we only want to support one instance of this driver?

Seems like a bit of a risk.


#include <init.h>
#include <drivers/sensor.h>
#include <zmk/sensors.h>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I'm curious, how do you compile it when zmk includes are not included in the CMakeLists?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify your problem? I'm having trouble understanding

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I'm trying to compile with rebased main the compiler fails to find zmk/sensors.h include. And I was wondering if it's the case for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely not. I'm guessing you somehow have a ZMK version that's way too old, or maybe the CMake stuff got messed up somehow?

static void pinnacle_work_cb(struct k_work *work) {
struct pinnacle_data *data = CONTAINER_OF(work, struct pinnacle_data, work);
pinnacle_int_cb(data->dev);
pinnacle_write(dev, PINNACLE_STATUS1, 0); // Clear SW_DR

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pinnacle_write(dev, PINNACLE_STATUS1, 0); // Clear SW_DR
pinnacle_write(data->dev, PINNACLE_STATUS1, 0); // Clear SW_DR

@FearlessSpiff
Copy link

FearlessSpiff commented Nov 3, 2023

Did some progress again. Now it fails when linking. And different errors when building the left side and right side. On the left side I have absolutely no clue what might go wrong. On the right side I have at least a problem description which would suggest, that the mouse code is not incorporated. Which might even be true on the peripheral side?!? Any ideas would be nice. Here's the failed build. Thanks!

Edit: Just saw that the zmk-only build was green. :)

Edit 2: I fixed the right build by disabling the stuff in config. Still left with the problem on the left side...

@crides
Copy link
Contributor Author

crides commented Nov 3, 2023

The right side problems are easy, either the mouse stuff wasn't merged properly, or you didn't enable the mouse driver.

For the left side, I don't have any ideas, and you'll have to consult the ZMK/zephyr servers

@FearlessSpiff
Copy link

The right side problems are easy, either the mouse stuff wasn't merged properly, or you didn't enable the mouse driver.

For the left side, I don't have any ideas, and you'll have to consult the ZMK/zephyr servers

After many hours searching I could fix it with this. Coming from the Java world I have no idea how this can compile but then fail linking... Now have to add the actual trackpad... :)

@crides
Copy link
Contributor Author

crides commented Nov 4, 2023

Oh, because all of the initialization code in zephyr is stored in order of the priority in the binary. The macros just generate linker sections

@FearlessSpiff
Copy link

After everything out of the way I was able to install the firmware. Already fixed the wrong i2c address but still init fails:

[00:00:00.383,422] <wrn> pinnacle: pinnacle start
[00:00:00.383,453] <err> pinnacle: i2c addr: 2a
[00:00:00.883,514] <err> i2c_nrfx_twi: Error on I2C line occurred for message 0
[00:00:00.883,636] <err> pinnacle: can't reset -5

I know the trackpad is working with an Elite-C on QMK.

Shy question: Was this tested with I2C? I can only find working SPI code... Or what am I missing? Also checked QMK code which looks similar to this... Will dig deeper tomorrow. Thanks!

@crides
Copy link
Contributor Author

crides commented Nov 4, 2023

Not sure what's happening, but given that this is the first I2C call, it's likely that there's some problem on your bus. I would check that there's pullup on the bus, you didn't swap SDA and SCL, and continuity is good. Oscilloscope/logic analyzer would be the next step.

Shy question: Was this tested with I2C?

Valid question. Not me. I think 1 or 2 people on the ZMK discord tested and had success with it

I can only find working SPI code... Or what am I missing?

There's definitely I2C code

@FearlessSpiff
Copy link

Not sure what's happening, but given that this is the first I2C call, it's likely that there's some problem on your bus. I would check that there's pullup on the bus, you didn't swap SDA and SCL, and continuity is good. Oscilloscope/logic analyzer would be the next step.

Yeah, I know it is working because of the tests with an Elite-C MCU and QMK.

There's definitely I2C code

Sure, I meant in the open wild. I can see the I2C code in the driver.

Will investigate further. Thanks!

@FearlessSpiff
Copy link

FearlessSpiff commented Nov 6, 2023

After a lot of debugging and some help from SplitKB Discord I had external power turned off. :( So now I know I2C is working also tested with an OLED on ZMK on the keyboard. I now get a new error for the first call to I2C i2c_nrfx_twi: Error 0x0BAE0001 occurred for message 0 This seams to be an NACK for the address. So I checked there and found that in the Cirque Documentation Chapter 7.1 they talk about shifting bits for the address and then ORing with 1 when reading. I tried that for writing only atm on my branch with:

static int pinnacle_write(const struct device *dev, const uint8_t addr, const uint8_t val) {
    const struct pinnacle_config *config = dev->config;
    const struct i2c_dt_spec *spec = &config->bus;

    return i2c_reg_write_byte(spec->bus, spec->addr << 1, PINNACLE_WRITE | addr, val);
}

But still the same problem. Any idea what could be wrong?
Thanks again for looking into it...

Edit
The old call was just return i2c_reg_write_byte_dt(&config->bus, PINNACLE_WRITE | addr, val);

@FearlessSpiff
Copy link

As a follow up I tried to write the reset command to every I2C address on the bus in this commit but it can't do it anywhere. So something seams to be off unfortunately.

@crides
Copy link
Contributor Author

crides commented Nov 6, 2023

I don't remember the address needs to be shifted. Also I can't really help much without an oscilloscope

Just checking: have you desoldered R1 on the cirque, for switching to I2C mode?

@FearlessSpiff
Copy link

FearlessSpiff commented Nov 7, 2023

Just checking: have you desoldered R1 on the cirque, for switching to I2C mode?

Yes, i switched to I2C and 5V. For anybody interested here's a great resource explaining it. Although I just soldered everything to the test pads without adapter PCB. It works fine in QMK.

I can't see anything on my oscilloscope. I ordered a logic analyzer from Aliexpress. This means a 2+ weeks break from the project...

I read the I2C Cirque documentation a lot and can't figure out the START command in the code. Just the STOP as a flag. But I guess this is done deeper in the I2C driver... I think without logic analyzer I am blind atm. :(

@drzony
Copy link

drzony commented Nov 7, 2023

As far as I remember ZMK has some issues with reinitializing I2C after sleep (this might have been fixed) and when the ext power is toggled. So you need to make sure that the ext power is ON on startup. I would try first on the master side with USB plugged in, that might save you some debugging time.

@crides
Copy link
Contributor Author

crides commented Nov 7, 2023

I can't see anything on my oscilloscope. I ordered a logic analyzer from Aliexpress. This means a 2+ weeks break from the project...

@FearlessSpiff if you're still having issues, you could just post a scope screenshot here. If it proves to be too complex to debug, we could move to some other channel to debug and summarize back here

@FearlessSpiff
Copy link

@FearlessSpiff if you're still having issues, you could just post a scope screenshot here. If it proves to be too complex to debug, we could move to some other channel to debug and summarize back here

Thanks. Long time since I worked with these things. I just can't capture the start. And then it's just 5V...
As I am an inpatient person I now ordered a logic analyzer from a local dealer. It should arrive this week if I'm lucky.

@FearlessSpiff
Copy link

I'm back... ;) Although without good news but a LA. I could now capture I2C init done by QMK where the trackpad is working and by ZMK where it doesn't. Unfortunatley I can't make a lot out of it. I just see that it is different and the trackpad returns NACK so it seams. Same as the error code told me in the running code. Maybe somebody knows more than me when having a look at this. Thanks

QMK, working

QMK-working

ZMK, not working

ZMK-not-working

@crides
Copy link
Contributor Author

crides commented Nov 10, 2023

I think it should be pretty clear then. Check that it's powered and the pins are indeed wired correctly

@FearlessSpiff
Copy link

I think it should be pretty clear then. Check that it's powered and the pins are indeed wired correctly

Unfortunately it is. I can just switch the MCU to the Elite-C with QMK and everything works.

@FearlessSpiff
Copy link

FearlessSpiff commented Nov 10, 2023

I think it should be pretty clear then. Check that it's powered and the pins are indeed wired correctly

Oh, I only have 3.3V on the trackpad. Shouldn't this be 5V? Have to check it...

Edit I guess this is it! I desoldered R7 and R8 to make it 5V and the N!N is only 3.3V. Good thing I have another Cirque lying around...

@drzony
Copy link

drzony commented Nov 10, 2023

@FearlessSpiff I think on 3.3V MCUs you need to leave the 5V resistors (R7, R8) on the trackpad. It depends on the board you are using, AFAIR splitkb ones connect 3.3V to I2C connector, but you can add a wire connecting it to power for LEDs. Check on their discord/schematic docs

@FearlessSpiff
Copy link

Finally it is initalizing! Thanks to everybody! I am now at the next problem by not beeing able to set a trigger. I changed SENSOR_TRIG_DATA_READY to SENSOR_TRIG_TIMER:

static int trackpad_init() {
    struct sensor_trigger trigger = {
        .type = SENSOR_TRIG_TIMER,
        .chan = SENSOR_CHAN_ALL,
    };
    printk("trackpad");
    if (sensor_trigger_set(trackpad, &trigger, handle_trackpad) < 0) {
        LOG_ERR("can't set trigger");
        return -EIO;
    };
    return 0;
}

I can't find much in the docu, neither when googling for examples. Any idea? Thanks!

@drzony
Copy link

drzony commented Nov 10, 2023

Finally it is initalizing! Thanks to everybody! I am now at the next problem by not beeing able to set a trigger. I changed SENSOR_TRIG_DATA_READY to SENSOR_TRIG_TIMER:

static int trackpad_init() {
    struct sensor_trigger trigger = {
        .type = SENSOR_TRIG_TIMER,
        .chan = SENSOR_CHAN_ALL,
    };
    printk("trackpad");
    if (sensor_trigger_set(trackpad, &trigger, handle_trackpad) < 0) {
        LOG_ERR("can't set trigger");
        return -EIO;
    };
    return 0;
}

I can't find much in the docu, neither when googling for examples. Any idea? Thanks!

PINNACLE_TRIGGER_NONE is probably what you are looking for. And then probably some task to fetch data.

@FearlessSpiff
Copy link

AFAIK PINNACLE_TRIGGER_NONE is to disable DR functionality, which is the default kconfig setting. Therefore it does not compile with this.

@FearlessSpiff
Copy link

Btw, I now logged the errorcode when calling sensor_trigger_set which is -88

@drzony
Copy link

drzony commented Nov 10, 2023

AFAIK PINNACLE_TRIGGER_NONE is to disable DR functionality, which is the default kconfig setting. Therefore it does not compile with this.

When PINNACLE_TRIGGER_NONE is used, then trigger_set is not available, see around line 264 in pinnacle.c. When not using DR pin, you'll need to poll the sensor, I think the code for the mouse you are using needs the trigger. From what I understand, you would need to set up a timer or fetch data in some already running task.

@FearlessSpiff
Copy link

Thanks. I get it now. I guess I will need to create a thread and poll the sensor there. Or check schematics of my Aurora and maybe add a DR line somewhere. What advantages would it have to have a DR line? Is this just better for battery-life and that's it?

@FrostKiwi
Copy link

Does anyone know what has to be done to get this done on a theoretical level, considering the new ZMK firmware structure? My ZMK config for reference: https://github.com/FrostKiwi/zmk-config

@FrostKiwi
Copy link

I merged this PR into zmkfirmware/main here: https://github.com/FrostKiwi/zmk (main branch) with this commit: FrostKiwi@03a055d and these correction commits: FrostKiwi@7220070 FrostKiwi@dfb326f

The firmware builds successfully without the driver being included: https://github.com/FrostKiwi/zmk-config/actions/runs/11378828087 but fails with the driver being included via CONFIG_PINNACLE=y: https://github.com/FrostKiwi/zmk-config/actions/runs/11379092737/job/31656277722

/tmp/zmk-config/zmk/app/module/drivers/sensor/pinnacle/pinnacle.c:3:10: fatal error: init.h: No such file or directory
    3 | #include <init.h>
      |          ^~~~~~~~

I have a Kyria rev3, nice!nano2, Cirque trackpad on both sites hooked up to i2c.
When this PR was created, Mouse button support didn't yet hit main yet. But now this is the case and mouse buttons work just fine on my Kyria rev3 via https://zmk.dev/docs/keymaps/behaviors/mouse-emulation Now to the trackpad and this PR.

@caksoylar
Copy link
Contributor

You should try using https://github.com/petejohanson/cirque-input-module (which is a module) along with either #2027 or #2477. I am not sure if the current state of this PR is compatible with these two, but I am sure that you need one of those branches for the Cirque to work.

@FrostKiwi
Copy link

@caksoylar Ohh, I never knew of this module system! So the way I understand is: Go with #2027 as the base, it's only 2 months behind main and #2477 is in early infancy. @petejohanson do you agree with the assessment of those PRs?

Include the module. This seems easy and I can follow. But how do you glue it together?
The module describes a couple of settings: https://github.com/petejohanson/cirque-input-module/blob/main/dts/bindings/input/cirque%2Cpinnacle-common.yaml but where do I set them and how does ZMK know which I2C address to use? In the keymap like:

&trackpad {
    compatible = "cirque,pinnacle";
    reg = <???>;  # I2C address for the trackpad
    dr-gpios = <???>;
    x-axis-z-min = <5>;
    y-axis-z-min = <4>;
    sensitivity = "2x";
    rotate-90;
};

Looking at the source code of #2027 and seeing CONFIG_ZMK_MOUSE=y, I guess this is an extension of https://zmk.dev/docs/keymaps/behaviors/mouse-emulation. So the cirque module just assumes mouse emulation to be present and works or does there some configuration need to be done gluing both together?

@caksoylar
Copy link
Contributor

caksoylar commented Oct 17, 2024

I think Pete summarized these two PRs pretty well in the latter's description:

This is the planned successor to #2027 that integrates a more flexible input processing system inspired by the work by badjeff. I will leave #2027 alone for now, but this PR is intended to be the version that's targeted to actually merge.

WARNING The work in this PR is subject to ZERO API/code/config stability guarantees. If you want something that won't randomly break on you, keep using #2027. Only use the branch from this PR if you are willing to accept that, follow the PR closely for any changes, and are technical enough to solve any problems that occur from using it.

You can see an example I2C usage (with 2027) here, there is an SPI version there as well. (dr-gpios is the GPIO you connect the DR pin to like &pro_micro 9 which is required by the driver.)

CONFIG_ZMK_MOUSE symbol enables mouse emulation altogether, which is necessary for the device to present as a mouse to the computer. Hence it's necessary for any pointing device use.

As an aside, I'd recommend you join the ZMK Discord which has a dedicated channel for pointing devices experimentation. It is difficult to do back-and-forth here for providing any sort of help with experimental features.

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.

10 participants