GithubHelp home page GithubHelp logo

Comments (25)

gou4shi1 avatar gou4shi1 commented on May 26, 2024 3

At work right now so I can't test, but adding a ! to

It works like a charm!

from hid-tmff2.

berarma avatar berarma commented on May 26, 2024 2

Are you sure all the comparisons of the current values with the old values are necessary? I remember avoiding them in new-lg4ff, I don't know if that would be possible here but it would sure make things simpler.

For example, I see there's a comparison for the duration. Updating an effect with the same duration is still an update and it should make the effect last longer since the length counter is reset again to its initial value.

With the level, I've seen the parameters are compared but not the final actual values. So the level that needs to apply might be different even though the level parameter is the same on the last and the current updates.

Forgive if I make any mistake, I might have forgotten some details.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024 2

@gou4shi1 Yes, thanks for reminding me, already forgot.

from hid-tmff2.

berarma avatar berarma commented on May 26, 2024 1

Besides the API docs there's the headers file that defines the structs that has some comments. Nothing else that I know.

The driver has to be able to change direction, either dynamically as requested in case the device supports it or by restarting the effect as a fallback.

The docs say that some drivers might do a effect restart when requesting a dynamic direction change and the developer should be OK with that. The developer could also check that the devices they want to support do the right thing for their case.

from hid-tmff2.

gou4shi1 avatar gou4shi1 commented on May 26, 2024 1

I found something suspicious:
The input old of tmff2_upload() is maintained in https://github.com/torvalds/linux/blob/master/drivers/input/ff-core.c#L145, while tmff2_upload() is async, the actual processing logic happens in t300rs_update_constant().
So if the upload frequency is so high, e.g. 8ms in this issue, state->old may be updated to the new value before t300rs_update_constant() processes the new value, thus if (constant.level != constant_old.level) failed.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024 1

Good point, I'll add a slight twist to that: The old parameter in tmff2_upload() is the previous effect uploaded by the user, whereas state->old is intended to be the previous effect uploaded to the device. In theory, as long as an effect has the flag FF_EFFECT_QUEUE_UPLOAD state->old should stay the same, as a newer effect hasn't been uploaded to the device yet, and as such all comparisons should be to what the device is currently (supposedly) doing.

Looking at the code now though, it looks like I'm missing a negation and instead the effect is being updated on every user upload. Oops.

At work right now so I can't test, but adding a ! to

if (test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags))
might fix things.

It might also be worth making this relationship more obvious, for example changing state->old in tmff2_work_handler() somewhere instead of relying on the FFB susbystem's old, but that's probably a secondary task.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024 1

Are you sure all the comparisons of the current values with the old values are necessary?

No, not really, as previously mentioned I've mostly just been copying the Windows driver, which for example seems to not update the duration when the effect is modified (at least when done through ffedit.exe.)

Updating an effect with the same duration is still an update and it should make the effect last longer since the length counter is reset again to its initial value.

Seems reasonable, and if you're doing it I probably should too.

Not to be rude, but where are you getting this information from? As I already mentioned, I know my driver is working like the Windows counterpart when it should be more like a Linux driver, but I honestly have no idea what behaviour is expected on Linux. I couldn't find a mention of this vs. the current behavour in the FFB docs nor the source code.

With the level, I've seen the parameters are compared but not the final actual values. So the level that needs to apply might be different even though the level parameter is the same on the last and the current updates.

The final actual values (for level) are only affected by the direction and the level parameter, as far as I'm aware, and the driver checks if either of these parameters have changed since the last iteration. Or am I misunderstanding something?

Anycase, if you have more insights, please feel free to update me on what else this driver might be doing differently from yours. Getting this driver to (finally?) behave consistently with other ones would be nice.

Thanks for your help.

from hid-tmff2.

berarma avatar berarma commented on May 26, 2024 1

The Linux docs don't explicitly talk about the duration parameter but defines dynamically updating an effect as loading a new one without needing to stop the current one. In addition, I based new-lg4ff on the existing hid-lg4ff driver and used it as reference. I think I managed to have the same behavior.

I'm not 100% sure about everything so discussion is welcome. I should write some tests for ffbtools so we can see how the different drivers behave in these special situations.

from hid-tmff2.

berarma avatar berarma commented on May 26, 2024 1

I remember reading the ff-memless driver code since hid-lg4ff was based on it. It's a simple implementation of the Linux FFB API without hardware details. This base driver is intended for devices that only support one effect of each type played simultaneously. It keeps track of all the effects and mixes them so that the drivers based on it don't have to duplicate the code. I think it's a good reference for details that the Linux docs don't explicitly mention.

In the function at https://github.com/torvalds/linux/blob/e0dccc3b76fb35bb257b4118367a883073d7390e/drivers/input/ff-memless.c#L465 we can see that a dynamical update does use the new duration and even the delay. So if an effect is updated with a delay of 1s and a duration of 2s the effect would pause for 1s then play for 2s independently of the older values.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024 1

This is not strictly related to this ticket, but I'm my defence I apparently hadn't forgotten to apply the direction branch to master.When #44 was merged it seems to have overwritten my direction changes for some reason.

Compare

if ((constant.level != constant_old.level) || (effect.direction != old.direction)) {

and

if (constant.level != constant_old.level) {

Not entirely sure what went wrong, but no harm done.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024

Hi, could you clarify what you mean by 'fails'? Is there an error in dmesg, or does ioctl return an error code or do you just mean that the effect stops playing?

Other than that, I think one issue might be with

effect_.replay.length = 0xffff;

The kernel docs in https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input.h#L302 say

/*

  • All duration values are expressed in ms. Values above 32767 ms (0x7fff)
  • should not be used and have unspecified results.
    */

Assuming that 0xffff works as expected, that's still at most ~60 seconds, could you be running out of effect duration? Try using 0 to make the effect infinite.

Also a sidenote, in https://www.kernel.org/doc/html/latest/input/ff.html#dynamic-update-of-an-effect changing the direction of an effect dynamically is not recommended. I'm pretty sure my driver should handle the situation correctly, but might not work as expected on other wheels and from what I can remember doesn't work on Windows.

from hid-tmff2.

y761823 avatar y761823 commented on May 26, 2024

when I set effect_.replay.length = 0xffff, ffb works as expected but will lose after almost 60s. I'll change it to 0, thanks for the suggestion.
"fails" mean that, for example, my ffb make the steering wheel turns clockwise at first. But when I change direction, the steering wheel still turns clockwise instead of counterclockwise. If it's by design, I think I should upload a new effect for it.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024

Right, yeah, my driver doesn't update the effect if only the direction changes, similar to how the Windows driver works. However, if you change the level of the FFB as well, the direction will be updated at the same time. Although don't rely on this, as stated earlier changing the direction of an effect dynamically isn't a well defined operation.

from hid-tmff2.

berarma avatar berarma commented on May 26, 2024

Right, yeah, my driver doesn't update the effect if only the direction changes, similar to how the Windows driver works. However, if you change the level of the FFB as well, the direction will be updated at the same time. Although don't rely on this, as stated earlier changing the direction of an effect dynamically isn't a well defined operation.

That's not how it works on Linux. I don't see the point in making a Linux driver behave like the Windows one. It should work as defined by the Linux API or we'll see inconsistent behavior between different hardware.

If you're worried about the driver working well on Wine/Proton is equally important to follow the Linux API because that's what Wine/Proton expects and will translate Windows calls accordingly.

The Linux API doc doesn't say you shouldn't change direction dynamically. It says you should expect that some drivers stop and restart the effect when a dynamic change of direction is requested. So it's completely fine to change direction dynamically. The hardware has to support this or restart the effect with the new direction.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024

That's not how it works on Linux. I don't see the point in making a Linux driver behave like the Windows one. It should work as defined by the Linux API or we'll see inconsistent behavior between different hardware.

Out of curiosity, is there more documentation about Linux FFB conventions than https://www.kernel.org/doc/html/latest/input/ff.html? I remember you having to correct me on effect.duration as well.

The Linux API doc doesn't say you shouldn't change direction dynamically. It says you should expect that some drivers stop and restart the effect when a dynamic change of direction is requested. So it's completely fine to change direction dynamically. The hardware has to support this or restart the effect with the new direction

Lazy reading by me, sorry. The context of the restart is not well defined, not the act of changing direction then? Fair enough, should be a reasonably quick fix.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024

I pushed a test commit to https://github.com/Kimplul/hid-tmff2/tree/direction

Don't have access to my wheel at the moment, please feel free to test the branch out.

@Raboebie could you also check if it works?

from hid-tmff2.

y761823 avatar y761823 commented on May 26, 2024

I try to install https://github.com/Kimplul/hid-tmff2/tree/direction but it still not working as expected.
Even if I modify both level and direction, my steering wheel still always turns clockwise.

    if (++cnt % 1000 == 0) {
      effect_.u.constant.level++;
      effect_.direction = -effect_.direction;
      // ffb_need_restart_ = true;  // not restart
    }

Is it that the steering wheel firmware does not support this modification?

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024

it that the steering wheel firmware does not support this modification?

No, the firmware doesn't actually have any concept of 'direction', my driver is just responsible for translating it down into something the wheel should understand. Apparently my driver is not working the way I expected it to, weird.

Did you check that the newer driver is being loaded? Linux pretty often caches modules and you might still be running the old module. You could try adding something like printk("test"); in tmff2_wheel_init to make it more obvious. Although the old driver should still react to level changes, you could try also flipping the level as a sanity check.

And not to be condescending, but also check that you have the correct branch checked out in git.

from hid-tmff2.

y761823 avatar y761823 commented on May 26, 2024

I'm sure I've check out the branch to direction. But I'm not sure if the new driver is used in the kernel (I don't know where I can see the output of printk? I didn't see it).
Other than that, I try to increase the level by 3000 every time, and there is a high probability that it work, but occasionally it does not work, I don't know why.

from hid-tmff2.

Kimplul avatar Kimplul commented on May 26, 2024

I don't know where I can see the output of printk?

dmesg -w

Other than that, I try to increase the level by 3000 every time, and there is a high probability that it work, but occasionally it does not work, I don't know why.

That's pretty weird, might be a timing issue but I'll have to look into it.

from hid-tmff2.

berarma avatar berarma commented on May 26, 2024

I'm sure I've check out the branch to direction. But I'm not sure if the new driver is used in the kernel (I don't know where I can see the output of printk? I didn't see it). Other than that, I try to increase the level by 3000 every time, and there is a high probability that it work, but occasionally it does not work, I don't know why.

I hadn't looked at your code before but now that I did I've seen some things that I think should be commented.

The direction parameter is a uint16 and for wheels should be 0x4000 (left) or 0xC000 (right). Other directions towards the vertical axis should fade out the effect since there's no vertical FFB.

Changing the sign of direction has the effect of mirroring the effect to the other side. Even if it's unsigned it would work.

You're sending effect updates every 8ms even if the effect changes only every 8s·

I've tried the code on my G29 and it works only if I change the direction to 0x4000 or 0xC000.

from hid-tmff2.

gou4shi1 avatar gou4shi1 commented on May 26, 2024

The direction parameter is a uint16 and for wheels should be 0x4000 (left) or 0xC000 (right). Other directions towards the vertical axis should fade out the effect since there's no vertical FFB.

Could you share more about direction? I only see that

	level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff;

in this driver.

from hid-tmff2.

berarma avatar berarma commented on May 26, 2024

The direction parameter is a uint16 and for wheels should be 0x4000 (left) or 0xC000 (right). Other directions towards the vertical axis should fade out the effect since there's no vertical FFB.

Could you share more about direction? I only see that

	level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff;

in this driver.

The direction parameter is an angle expressed as an unsigned 16 bit integer with direction 0 pointing up and direction 0x8000 (180°) pointing down, running counter-clockwise. This is the direction of the force that will be applied and it's exactly how it works on joysticks that have FFB on both axes, X and Y.

Since wheels have only one axis of movement, only the horizontal component of the force is used. With wheels, it doesn't make much sense using values other than 0x4000 or 0xC000 for the direction. They will work but only have the effect of reducing the total force applied.

That line of code takes the horizontal component of the force requested in the parameters and applies it to the wheel. If the direction is up the horizontal component will be 0, if the direction is top/left (45°) the horizontal component will be half the total force, and if the direction is left (90°) the horizontal component will be 100% of the force.

from hid-tmff2.

gou4shi1 avatar gou4shi1 commented on May 26, 2024

That line of code takes the horizontal component of the force requested in the parameters and applies it to the wheel. If the direction is up the horizontal component will be 0, if the direction is top/left (45°) the horizontal component will be half the total force, and if the direction is left (90°) the horizontal component will be 100% of the force.

Thanks for your reply.

from hid-tmff2.

gou4shi1 avatar gou4shi1 commented on May 26, 2024

Will https://github.com/Kimplul/hid-tmff2/tree/direction be merged?

from hid-tmff2.

Related Issues (20)

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.