aa865cc2d2aef6103466ab3a019f54fb05a3ddac
[fw/altos] / src / samd21 / ao_exti_samd21.c
1 /*
2  * Copyright © 2022 Keith Packard <keithp@keithp.com>
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <ao.h>
20 #include <ao_exti.h>
21
22 struct samd21_exti {
23         void    (*callback)(void);
24         uint8_t port;
25         uint8_t pin;
26 };
27
28 #if 0
29 static struct samd21_exti ao_samd_exti[SAMD21_NUM_EVSYS];
30
31 static uint32_t ao_exti_inuse;
32 #endif
33
34 void
35 samd21_evsys_isr(void)
36 {
37 }
38
39 void
40 ao_exti_setup (struct samd21_port *port, uint8_t pin, uint8_t mode, void (*callback)(void))
41 {
42         (void) port;
43         (void) pin;
44         (void) mode;
45         (void) callback;
46 #if 0
47         uint8_t         id = pin_id(port,pin);
48         uint8_t         pint;
49         uint8_t         mask;
50         uint8_t         prio;
51
52         for (pint = 0; pint < SAMD21_NUM_EVSYS; pint++)
53                 if ((ao_exti_inuse & (1 << pint)) == 0)
54                         break;
55
56         if (pint == SAMD21_NUM_EVSYS)
57                 ao_panic(AO_PANIC_EXTI);
58
59         if (!(mode & AO_EXTI_PIN_NOCONFIGURE))
60                 ao_enable_input(port, pin, mode);
61
62         ao_arch_block_interrupts();
63         mask = (1 << pint);
64         ao_exti_inuse |= mask;
65         ao_pint_enabled &= (uint8_t) ~mask;
66
67         ao_pint_map[id] = pint;
68         ao_exti_callback[pint] = callback;
69
70         /* configure gpio to interrupt routing */
71         lpc_scb.pintsel[pint] = id;
72
73         /* Set edge triggered */
74         lpc_gpio_pin.isel &= ~mask;
75
76         ao_pint_enabled &= (uint8_t) ~mask;
77         ao_pint_mode[pint] = mode;
78         _ao_exti_set_enable(pint);
79
80         /* Set interrupt mask and rising/falling mode */
81
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;
87
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();
92 #endif
93 }
94
95 void
96 ao_exti_set_mode(struct samd21_port *port, uint8_t pin, uint8_t mode)
97 {
98         (void) port;
99         (void) pin;
100         (void) mode;
101 #if 0
102         uint8_t         id = pin_id(port,pin);
103         uint8_t         pint = ao_pint_map[id];
104
105         ao_arch_block_interrupts();
106         ao_pint_mode[pint] = mode;
107         _ao_exti_set_enable(pint);
108         ao_arch_release_interrupts();
109 #endif
110 }
111
112 void
113 ao_exti_set_callback(struct samd21_port *port, uint8_t pin, void (*callback)(void))
114 {
115         (void) port;
116         (void) pin;
117         (void) callback;
118 #if 0
119         uint8_t         id = pin_id(port,pin);
120         uint8_t         pint = ao_pint_map[id];
121
122         ao_exti_callback[pint] = callback;
123 #endif
124 }
125
126 void
127 ao_exti_enable(struct samd21_port *port, uint8_t pin)
128 {
129         (void) port;
130         (void) pin;
131 #if 0
132         uint8_t         id = pin_id(port,pin);
133         uint8_t         pint = ao_pint_map[id];
134         uint8_t         mask = 1 << pint;
135
136         ao_arch_block_interrupts();
137         ao_pint_enabled |= mask;
138         _ao_exti_set_enable(pint);
139         ao_arch_release_interrupts();
140 #endif
141 }
142
143 void
144 ao_exti_disable(struct samd21_port *port, uint8_t pin)
145 {
146         (void) port;
147         (void) pin;
148 #if 0
149         uint8_t         id = pin_id(port,pin);
150         uint8_t         pint = ao_pint_map[id];
151         uint8_t         mask = 1 << pint;
152
153         ao_arch_block_interrupts();
154         ao_pint_enabled &= (uint8_t) ~mask;
155         _ao_exti_set_enable(pint);
156         ao_arch_release_interrupts();
157 #endif
158 }
159
160 void
161 ao_exti_init(void)
162 {
163 }