rushabhcodes/fidget-counter
A tscircuit package created by rushabhcodes.
- Version
- 1.0.31
- License
- unset
- Stars
- 0
firmware/src/rotation_counter.c
#include "rotation_counter.h"
#include <limits.h>
#include <string.h>
void rotation_invalidate(struct rotation_counter *c)
{
c->tracking = false;
c->remainder_q4 = 0;
}
void rotation_reset(struct rotation_counter *c)
{
memset(c, 0, sizeof(*c));
}
uint32_t rotation_total(const struct rotation_counter *c)
{
return UINT32_MAX - c->forward < c->reverse ? UINT32_MAX : c->forward + c->reverse;
}
enum rotation_result rotation_update(struct rotation_counter *c, uint16_t angle, uint32_t now)
{
if (angle > FIDGET_TURN_Q4) {
rotation_invalidate(c);
return ROTATION_REBASED;
}
if (angle == FIDGET_TURN_Q4) { angle = 0; }
if (!c->tracking || (uint32_t)(now - c->sample_ms) > FIDGET_MAX_SAMPLE_GAP_MS) {
c->reference_q4 = angle;
c->sample_ms = now;
c->remainder_q4 = 0;
c->tracking = true;
return ROTATION_REBASED;
}
c->sample_ms = now;
int32_t delta = (int32_t)angle - c->reference_q4;
if (delta > FIDGET_TURN_Q4 / 2) { delta -= FIDGET_TURN_Q4; }
if (delta < -FIDGET_TURN_Q4 / 2) { delta += FIDGET_TURN_Q4; }
if (delta > FIDGET_MAX_DELTA_Q4 || delta < -FIDGET_MAX_DELTA_Q4) {
c->reference_q4 = angle;
c->remainder_q4 = 0;
return ROTATION_REBASED;
}
/* Hold the reference through sub-degree noise, preserving eventual slow motion. */
if (delta < FIDGET_DEADBAND_Q4 && delta > -FIDGET_DEADBAND_Q4) {
return ROTATION_STILL;
}
c->reference_q4 = angle;
c->remainder_q4 += delta;
if (c->remainder_q4 >= FIDGET_TURN_Q4) {
if (c->forward != UINT32_MAX) { c->forward++; }
c->remainder_q4 -= FIDGET_TURN_Q4;
return ROTATION_COUNTED;
}
if (c->remainder_q4 <= -FIDGET_TURN_Q4) {
if (c->reverse != UINT32_MAX) { c->reverse++; }
c->remainder_q4 += FIDGET_TURN_Q4;
return ROTATION_COUNTED;
}
return ROTATION_MOVED;
}