Skip to content

Comps: Fix missed conversion to new api - #4567

Closed
Sigma1912 wants to merge 1 commit into
LinuxCNC:masterfrom
Sigma1912:x2nist-comps_Fix_missed_conversion_to_new_api
Closed

Sigma1912 wants to merge 1 commit into
LinuxCNC:masterfrom
Sigma1912:x2nist-comps_Fix_missed_conversion_to_new_api

Conversation

@Sigma1912

Copy link
Copy Markdown
Contributor

Two places did not get converted to the new hal api.

momentary2nist gets now uses a stashed pin state
toggle2nist now uses the state variable instead of having to read the pin

Also changes two misleading comments as the input pin change is debounced after the conditions are met.

Tested on real hardware

@Sigma1912
Sigma1912 force-pushed the x2nist-comps_Fix_missed_conversion_to_new_api branch from eddbaa4 to fe78b58 Compare September 19, 2026 09:18
@grandixximo

Copy link
Copy Markdown
Contributor

Question on the premise: on and off are bool out pins, so halcompile already generates #define on (hal_get_bool(__comp_inst->on_p)) for them. Doesn't the bare read in the reset condition already go through the new getter API? If so, wouldn't this be a consistency cleanup (stash reads into locals, avoid reading back our own outputs) rather than a missed conversion? Or is there a case where the bare read actually misbehaves?

One thing I noticed in the toggle2nist hunk: with state == 0 / state == 1 the reset condition stays true at idle (device off, button released), so pulse_length gets pinned at 0 instead of counting up between pulses. Harmless as far as I can tell, arguably even cleaner, but it is a small behavior change. Intended?

@Sigma1912

Sigma1912 commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Exposed as the casual programmer, again. :/

Background:
I noticed intermittent problems when testing 'toggle2nist.comp' on real hardware where the output pulse was sometimes (1 in ~30 transitions) not recognized by the following halui logic. Apparently because it was not long enough:

Screenshot from 2026-09-18 16-16-22

I was fairly certain that I had not seen this behavior before porting the components to the new api so I had a closer look and after changing those 'on', 'off' reads the issue was gone.

Doesn't the bare read in the reset condition already go through the new getter API?

You are right, it should. I was thinking along the lines that I shouldn't read the pins I had just written to but that doesn't actually happen in the same cycle. So admittedly this is a case of 'I seem to have fixed it but I don't know why'. Maybe @BsAtHome knows?

One thing I noticed in the toggle2nist hunk: with state == 0 / state == 1 the reset condition stays true at idle (device off, button released), so pulse_length gets pinned at 0 instead of counting up between pulses. Harmless as far as I can tell, arguably even cleaner, but it is a small behavior change. Intended?

Good catch, I didn't notice that. As usual, you have much more analytical eye the me.

@Sigma1912
Sigma1912 marked this pull request as draft September 19, 2026 10:56
@grandixximo

Copy link
Copy Markdown
Contributor

Ok, then this is not about the new API, but about the behavior change I flagged, that did seem indeed to be a better behavior.
It was not intended but it's actually what fixed your issue ;-)

Comment thread src/hal/components/momentary2nist.comp Outdated
Comment on lines +48 to +49
rtapi_bool on_val = on;
rtapi_bool off_val = off;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure what you are trying to gain by this. The values of on and off are only read once in the second else if. They are set in other clauses, but their written values do not depend on what was read.
Therefore, you are not gaining anything by doing this. Actually, you are making things slightly worse. The if(in_val...) clause, which unconditionally writes the pins now has both read (because you said to at the top) and then written with no reference to their original values.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Indeed.

@Sigma1912

Copy link
Copy Markdown
Contributor Author

My apologies, I totally did not analyze the actual issue. I'll come back when I have actually done the homework ...

Comment thread src/hal/components/toggle2nist.comp Outdated
debounce_cntr = 0;
}
} else if ((!ison_val && off) || (ison_val && on) || (pulse_length > max_pulse_length)) {
} else if ((!ison_val && state == 0) || (ison_val && state == 1) || (pulse_length > max_pulse_length)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Where does pulse_length get reset when a new pulse starts? At idle it counts 0..max and only the timeout branch zeroes it, so a fresh pulse inherits a random residual count and can expire a cycle or two in. Doesn't that explain the 1-in-30 short pulses on your scope?

This hunk pins it at 0 in the matched idle states, which is why your test passed. But what about startup with is_on already high, or a device switched externally while the button is held (ison_val and state disagree)? Wouldn't pulse_length = 0; next to state = 1; debounce_cntr = 0; in both edge branches cover every path?

Comment thread src/hal/components/momentary2nist.comp Outdated
debounce_cntr = 0;
}
} else if ((!ison_val && off) || (ison_val && on) || (pulse_length > max_pulse_length)) {
} else if ((!ison_val && off_val) || (ison_val && on_val) || (pulse_length > max_pulse_length)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This comp keeps the original condition, so pulse_length still free-runs at idle here. Same starved-pulse failure you scoped on toggle2nist, isn't it? Same reset in both edge branches should fix it.

Both 'momentary2nist' and 'toggle2nist' suffer from a loose pulse_length counter that leads
to 'on'-,'off'-signals getting cut short because the counter is not reset properly and counts when idling.

The counter is now reset when the pins are changed and no longer counts when the component is idle.

Also changes two misleading comments as the input pin change is debounced after the conditions are met.
@Sigma1912
Sigma1912 force-pushed the x2nist-comps_Fix_missed_conversion_to_new_api branch from fe78b58 to bb2f7c6 Compare September 19, 2026 13:50
@Sigma1912 Sigma1912 closed this Sep 19, 2026
@Sigma1912
Sigma1912 deleted the x2nist-comps_Fix_missed_conversion_to_new_api branch September 19, 2026 14:01
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.

3 participants