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

RFC: Design concept #29

Open
peterhinch opened this issue Aug 20, 2023 · 2 comments
Open

RFC: Design concept #29

peterhinch opened this issue Aug 20, 2023 · 2 comments

Comments

@peterhinch
Copy link

For context please see this doc on the design of encoder drivers and this driver.

The following specifics are potential issues:

  1. The runtime of the ISR's is relatively long, and may be extended if there are user callbacks. This runs the risk of reentrancy because the frequency of contact bounce may be arbitrarily high.
  2. The latency incurred by soft ISR's increases the risk of reentrancy or missed bounce transitions.
  3. User callbacks run in an ISR context. This can cause unexpected hazards particularly if the callbacks run complex code.
  4. It is possible to design the ISR's so that they run very fast by replacing the lookup tables with bitwise logic and by delegating to a non-ISR task operations such as rate division, end-stops and running callbacks.
  5. Doing this enables callbacks to run outside of an ISR context removing concurrency hazards.

The driver cited above has the following characteristics. ISR's run in 36μs on a Pyboard 1.1 and 50μs on ESP32 (soft ISR's run fast, but are subject to latency of multiple ms). The ISR design aims to allow for potential latency, detecting missed bounce transitions. Hard ISR's are used if available because latency limits allowable rotational speed.

@miketeachman
Copy link
Owner

Hi Peter,
Thanks for these options to improve this implementation! Sorry for the long delay in responding. It's been a busy summer and MicroPython fun has taken a back seat. I'll try to carve out some time to dig into your encoder implementation.

The first question I have is about reentrancy. On the ESP32 and ESP8266 ports the pin interrupt code queues the callbacks into the scheduler. This should protect the rotary callback code from reentrancy issues as this code will run to completion before it is called again by the scheduler. I assumed that the other ports (stm32, mimxrt, rp2, ...) would be consistent in how the pin callbacks are handled (even though they don't appear to use the scheduler). But, maybe that is a wrong assumption?

@peterhinch
Copy link
Author

IRQ's may be hard or soft. Soft IRQ's are run by the scheduler and are protected, however they suffer latency measured in ms. Hard IRQ's are only supported on some platforms (e.g. STM). They run with latency on the order of 15μs. Coding them requires care - see para on reentrancy.

There is the option always to use soft IRQ's.

One potential issue with latency/slow ISR's is that pulses might be missed. In many cases with a rotary control the user would never notice. The case where the encoder driver tracks mechanical detents is where missing pulses could matter, with alignment gradually drifting.

As a bit of background nearly 50 years ago (!) I designed a hardware interface for an optical encoder. It was on a machine tool and had to be pulse-perfect. That was a baptism of fire. For a digital circuit involving a handful of simple chips it was remarkably hard to get right and was my first encounter with metastability - something little-known in 1974.

I know we discussed encoders in the past and I'm not sure at what point we left the discussion - I have talked with a number of people and thought it worth sharing the outcome with you. It was only when I was planning adding encoder support to micro-gui that I realised that there was a risk of great swathes of GUI code running in an ISR context.

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

No branches or pull requests

2 participants