2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 #include <ao_quadrature.h>
22 __xdata int32_t ao_quadrature_count;
24 static uint8_t ao_quadrature_state;
26 #define BIT(a,b) ((a) | ((b) << 1))
27 #define STATE(old_a, old_b, new_a, new_b) (((BIT(old_a, old_b) << 2) | BIT(new_a, new_b)))
30 ao_quadrature_isr(void)
32 ao_quadrature_state = ((ao_quadrature_state & 3) << 2);
33 ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_QUADRATURE_A_PIN);
34 ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN) << 1;
36 switch (ao_quadrature_state) {
37 case STATE(0, 1, 0, 0):
38 ao_quadrature_count++;
40 case STATE(1, 0, 0, 0):
41 ao_quadrature_count--;
46 ao_wakeup(&ao_quadrature_count);
50 ao_quadrature_poll(void)
53 ao_arch_critical(ret = ao_quadrature_count;);
58 ao_quadrature_wait(void)
60 ao_sleep(&ao_quadrature_count);
61 return ao_quadrature_poll();
65 ao_quadrature_test(void)
71 c = ao_quadrature_wait();
72 printf ("new count %6d\n", c);
78 uint8_t a, old_a, b, old_b;
82 a = ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_QUADRATURE_A_PIN);
83 b = ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN);
84 if (a != old_a || b != old_b) {
85 printf ("A %d B %d count %ld\n", a, b, ao_quadrature_count);
97 static const struct ao_cmds ao_quadrature_cmds[] = {
98 { ao_quadrature_test, "q\0Test quadrature" },
103 ao_quadrature_init(void)
105 ao_quadrature_count = 0;
107 ao_enable_port(AO_QUADRATURE_PORT);
108 ao_exti_setup(AO_QUADRATURE_PORT, AO_QUADRATURE_A,
109 AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED,
111 ao_exti_enable(AO_QUADRATURE_PORT, AO_QUADRATURE_A);
112 ao_exti_setup(AO_QUADRATURE_PORT, AO_QUADRATURE_B,
113 AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED,
115 ao_exti_enable(AO_QUADRATURE_PORT, AO_QUADRATURE_B);
116 ao_cmd_register(&ao_quadrature_cmds[0]);