cpu/nrf5xcommon/qdec: allow configuration of count threshold for callback - #22708
leandrolanzieri wants to merge 3 commits into
Conversation
162e27e to
7dc1f0b
Compare
|
Now that #22700 is merged I rebased and also used the chance to rename the struct member to |
|
You may Squash Just to be sure: -since i do not have device at hand- Did you test this? (short setup description and short results 'd be nice) |
This extends the QDEC driver for nrf5x platforms to extend the hardware counter with a software one. In addition to extending the count range, users can now configure the maximum value at which a callback is called.
284acde to
d8abab1
Compare
|
from your test i would have expected or at least not always Am i missing somthing? |
I think so. Samples are different from counts in this context. Does this clarify? |
| if (cb && (conf(qdec)->callback_threshold > 0)) { | ||
| dev(qdec)->EVENTS_REPORTRDY = 0; | ||
| dev(qdec)->INTENSET = QDEC_INTENSET_REPORTRDY_Msk; | ||
| NVIC_EnableIRQ(QDEC_IRQn); | ||
| dev(qdec)->INTENSET = QDEC_INTENSET_ACCOF_Msk; | ||
| } | ||
| else { | ||
| NVIC_DisableIRQ(QDEC_IRQn); | ||
| dev(qdec)->INTENCLR = QDEC_INTENCLR_ACCOF_Msk; | ||
| dev(qdec)->INTENCLR = QDEC_INTENCLR_REPORTRDY_Msk; | ||
| } |
There was a problem hiding this comment.
how about keeping the overflow behaviour when callback_threshold is 0
| if (cb && (conf(qdec)->callback_threshold > 0)) { | |
| dev(qdec)->EVENTS_REPORTRDY = 0; | |
| dev(qdec)->INTENSET = QDEC_INTENSET_REPORTRDY_Msk; | |
| NVIC_EnableIRQ(QDEC_IRQn); | |
| dev(qdec)->INTENSET = QDEC_INTENSET_ACCOF_Msk; | |
| } | |
| else { | |
| NVIC_DisableIRQ(QDEC_IRQn); | |
| dev(qdec)->INTENCLR = QDEC_INTENCLR_ACCOF_Msk; | |
| dev(qdec)->INTENCLR = QDEC_INTENCLR_REPORTRDY_Msk; | |
| } | |
| NVIC_DisableIRQ(QDEC_IRQn); | |
| if ((conf(qdec)->callback_threshold > 0)) { | |
| dev(qdec)->EVENTS_REPORTRDY = 0; | |
| dev(qdec)->INTENSET = QDEC_INTENSET_REPORTRDY_Msk; | |
| } | |
| else { | |
| dev(qdec)->INTENSET = QDEC_INTENCLR_ACCOF_Msk; | |
| } | |
| if (cb) { | |
| NVIC_EnableIRQ(QDEC_IRQn); | |
| } |
reasoning:
EVENTS_REPORTRDY is time based (and count) -> less sleep
overflow will happen less often (depends on the only on the counted distance) -> has a real advantage
There was a problem hiding this comment.
how about keeping the overflow behaviour when callback_threshold is 0
Do you mean that the user would get a callback when the count reaches 1024 or keep the software counter and call back every multiple of 1024? I'm not sure about how this would work.
Keep in mind that this PR also include the software counter.
We could have callback_threshold = 0 a sort of legacy mode that restricts count to +/- 1024 and only uses the overflow interrupt. Probably not the nicest API but it would cover both cases.
Do you have any thoughts on that?
There was a problem hiding this comment.
my thought and reasoning is in the follow up comment
so yes I think it would be nice to have callback_threshold == 0 + callback function to behave like a legacy fallback (overflow only) to avoid the extra interrupts that might wake up the cpu and only have overflow interrupts)
thanks for the clarification so every little step now creates an irq (not callback) after some time and before that only happen when there where to many steps happend ->
|

Contribution description
The current implementation of the QDEC peripheral driver in nrf5x has some limitations.
Unlike the peripheral in the stm32, this driver doesn't allow setting a maximum count for the hardware accumulator to select when the user callback is called. Currently, applications only get a callback if the count has reached -1023 or 1024. Otherwise they need to constantly poll the driver. Which makes it impractical for event-driven applications.
Although the QDEC peripheral API uses
int32_tfor the count, this driver is capped by its hardware accumulator.This PR proposes using a software accumulator for the nrf5x driver, which is updated during the sample report interrupt of the peripheral (instead of the overflow interrupt). Given the way the peripheral works, this has certain caveats, which are documented in the extended
qdec_cont_tstructure. Depending on the use case, users can set theirreport_periodto trade off the amount of interrupts triggered when the encoder moves against the potential overshoot of the configured threshold. The driver allows setting a sample period ofQDEC_REPORTPER_REPORTPER_1Smplin case the user wants to get the callback exactly at that value, and doesn't care about the triggered interrupts.Unlike the stm32 implementation, the interrupt doesn't clear the accumulator (this is up to the user), so users can tell which direction of movement triggered the count overflow, and (in this case) whether the count surpassed the maximum value due to a fast encoder.
Testing procedure
tests/periph/qdecis a good starting point to test this. You can set in your nrf board different values of maximum count and report period.Issues/PRs references
The first three commits in this PR belong to #22700, so you can just ignore them for now. I'll rebase once that's in.
Declaration of AI-Tools / LLMs usage:
AI-Tools / LLMs that were used are: