- ao_quadrature_state = ((ao_quadrature_state & 3) << 2);
- ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_QUADRATURE_A_PIN);
- ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN) << 1;
-
- switch (ao_quadrature_state) {
- case STATE(0, 1, 0, 0):
- ao_quadrature_count++;
- break;
- case STATE(1, 0, 0, 0):
- ao_quadrature_count--;
- break;
- default:
- return;
+ ao_quadrature_count[q] += step;
+#if AO_EVENT
+ ao_event_put_isr(AO_EVENT_QUADRATURE, q, step);
+#endif
+ ao_wakeup(&ao_quadrature_count[q]);
+}
+
+#if AO_QUADRATURE_SINGLE_CODE
+struct ao_quadrature_step {
+ uint8_t inc;
+ uint8_t dec;
+};
+
+static struct ao_quadrature_step ao_quadrature_steps[4] = {
+ [0] = { .inc = 1, .dec = 2 },
+ [1] = { .inc = 3, .dec = 0 },
+ [3] = { .inc = 2, .dec = 1 },
+ [2] = { .inc = 0, .dec = 3 },
+};
+#endif
+
+static void
+_ao_quadrature_set(uint8_t q, uint8_t new) {
+ uint8_t old = ao_quadrature_state[q];
+
+#ifdef AO_QUADRATURE_SINGLE_CODE
+ if (new == ao_quadrature_steps[old].inc) {
+ _ao_quadrature_queue(q, 1);
+ } else if (new == ao_quadrature_steps[old].dec) {
+ _ao_quadrature_queue(q, -1);
+ }
+#else
+ if (old != new && new == 0) {
+ if (old == 2)
+ _ao_quadrature_queue(q, 1);
+ else if (old == 1)
+ _ao_quadrature_queue(q, -1);