2 * Copyright © 2022 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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 void (*callback)(void);
29 static struct samd21_exti ao_samd_exti[SAMD21_NUM_EVSYS];
31 static uint32_t ao_exti_inuse;
35 samd21_evsys_isr(void)
40 ao_exti_setup (struct samd21_port *port, uint8_t pin, uint8_t mode, void (*callback)(void))
47 uint8_t id = pin_id(port,pin);
52 for (pint = 0; pint < SAMD21_NUM_EVSYS; pint++)
53 if ((ao_exti_inuse & (1 << pint)) == 0)
56 if (pint == SAMD21_NUM_EVSYS)
57 ao_panic(AO_PANIC_EXTI);
59 if (!(mode & AO_EXTI_PIN_NOCONFIGURE))
60 ao_enable_input(port, pin, mode);
62 ao_arch_block_interrupts();
64 ao_exti_inuse |= mask;
65 ao_pint_enabled &= (uint8_t) ~mask;
67 ao_pint_map[id] = pint;
68 ao_exti_callback[pint] = callback;
70 /* configure gpio to interrupt routing */
71 lpc_scb.pintsel[pint] = id;
73 /* Set edge triggered */
74 lpc_gpio_pin.isel &= ~mask;
76 ao_pint_enabled &= (uint8_t) ~mask;
77 ao_pint_mode[pint] = mode;
78 _ao_exti_set_enable(pint);
80 /* Set interrupt mask and rising/falling mode */
82 prio = AO_LPC_NVIC_MED_PRIORITY;
83 if (mode & AO_EXTI_PRIORITY_LOW)
84 prio = AO_LPC_NVIC_LOW_PRIORITY;
85 else if (mode & AO_EXTI_PRIORITY_HIGH)
86 prio = AO_LPC_NVIC_HIGH_PRIORITY;
88 /* Set priority and enable */
89 lpc_nvic_set_priority(LPC_ISR_PIN_INT0_POS + pint, prio);
90 lpc_nvic_set_enable(LPC_ISR_PIN_INT0_POS + pint);
91 ao_arch_release_interrupts();
96 ao_exti_set_mode(struct samd21_port *port, uint8_t pin, uint8_t mode)
102 uint8_t id = pin_id(port,pin);
103 uint8_t pint = ao_pint_map[id];
105 ao_arch_block_interrupts();
106 ao_pint_mode[pint] = mode;
107 _ao_exti_set_enable(pint);
108 ao_arch_release_interrupts();
113 ao_exti_set_callback(struct samd21_port *port, uint8_t pin, void (*callback)(void))
119 uint8_t id = pin_id(port,pin);
120 uint8_t pint = ao_pint_map[id];
122 ao_exti_callback[pint] = callback;
127 ao_exti_enable(struct samd21_port *port, uint8_t pin)
132 uint8_t id = pin_id(port,pin);
133 uint8_t pint = ao_pint_map[id];
134 uint8_t mask = 1 << pint;
136 ao_arch_block_interrupts();
137 ao_pint_enabled |= mask;
138 _ao_exti_set_enable(pint);
139 ao_arch_release_interrupts();
144 ao_exti_disable(struct samd21_port *port, uint8_t pin)
149 uint8_t id = pin_id(port,pin);
150 uint8_t pint = ao_pint_map[id];
151 uint8_t mask = 1 << pint;
153 ao_arch_block_interrupts();
154 ao_pint_enabled &= (uint8_t) ~mask;
155 _ao_exti_set_enable(pint);
156 ao_arch_release_interrupts();