altos: Add 'void' to function declarations with no params.
[fw/altos] / src / stmf0 / ao_exti_stm.c
1 /*
2  * Copyright © 2016 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 static void     (*ao_exti_callback[16])(void);
23
24 uint32_t        ao_last_exti;
25
26 static void ao_exti_range_isr(uint8_t first, uint8_t last, uint16_t mask) {
27         uint16_t        pending = (ao_last_exti = stm_exti.pr) & mask;
28         uint8_t         pin;
29         static uint16_t last_mask;
30         static uint8_t  last_pin;
31
32         if (pending == last_mask) {
33                 stm_exti.pr = last_mask;
34                 (*ao_exti_callback[last_pin])();
35                 return;
36         }
37         stm_exti.pr = pending;
38         for (pin = first; pin <= last; pin++)
39                 if ((pending & ((uint32_t) 1 << pin)) && ao_exti_callback[pin]) {
40                         last_mask = (1 << pin);
41                         last_pin = pin;
42                         (*ao_exti_callback[pin])();
43                 }
44 }
45
46 void stm_exti0_1_isr(void) { ao_exti_range_isr(0, 1, 0x0003); }
47 void stm_exti2_3_isr(void) { ao_exti_range_isr(2, 3, 0x000c); }
48 void stm_exti4_15_isr(void) { ao_exti_range_isr(4, 15, 0xfff0); }
49
50 void
51 ao_exti_setup (struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)(void)) {
52         uint32_t        mask = 1 << pin;
53         uint32_t        pupdr;
54         uint8_t         irq;
55         uint8_t         prio;
56
57         ao_exti_callback[pin] = callback;
58
59         /* configure gpio to interrupt routing */
60         stm_exticr_set(gpio, pin);
61
62         if (!(mode & AO_EXTI_PIN_NOCONFIGURE)) {
63                 /* configure pin as input, setting selected pull-up/down mode */
64                 stm_moder_set(gpio, pin, STM_MODER_INPUT);
65                 switch (mode & (AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_PULL_DOWN)) {
66                 case 0:
67                 default:
68                         pupdr  = STM_PUPDR_NONE;
69                         break;
70                 case AO_EXTI_MODE_PULL_UP:
71                         pupdr = STM_PUPDR_PULL_UP;
72                         break;
73                 case AO_EXTI_MODE_PULL_DOWN:
74                         pupdr = STM_PUPDR_PULL_DOWN;
75                         break;
76                 }
77                 stm_pupdr_set(gpio, pin, pupdr);
78         }
79
80         /* Set interrupt mask and rising/falling mode */
81         stm_exti.imr &= ~mask;
82         if (mode & AO_EXTI_MODE_RISING)
83                 stm_exti.rtsr |= mask;
84         else
85                 stm_exti.rtsr &= ~mask;
86         if (mode & AO_EXTI_MODE_FALLING)
87                 stm_exti.ftsr |= mask;
88         else
89                 stm_exti.ftsr &= ~mask;
90
91         if (pin <= 1)
92                 irq = STM_ISR_EXTI0_1_POS;
93         else if (pin <= 3)
94                 irq = STM_ISR_EXTI2_3_POS;
95         else
96                 irq = STM_ISR_EXTI4_15_POS;
97
98         /* Set priority */
99         prio = AO_STM_NVIC_MED_PRIORITY;
100         if (mode & AO_EXTI_PRIORITY_LOW)
101                 prio = AO_STM_NVIC_LOW_PRIORITY;
102         else if (mode & AO_EXTI_PRIORITY_HIGH)
103                 prio = AO_STM_NVIC_HIGH_PRIORITY;
104
105         stm_nvic_set_priority(irq, prio);
106         stm_nvic_set_enable(irq);
107 }
108
109 void
110 ao_exti_set_mode(struct stm_gpio *gpio, uint8_t pin, uint8_t mode) {
111         (void) gpio;
112
113         uint32_t        mask = 1 << pin;
114
115         if (mode & AO_EXTI_MODE_RISING)
116                 stm_exti.rtsr |= mask;
117         else
118                 stm_exti.rtsr &= ~mask;
119         if (mode & AO_EXTI_MODE_FALLING)
120                 stm_exti.ftsr |= mask;
121         else
122                 stm_exti.ftsr &= ~mask;
123 }
124
125 void
126 ao_exti_set_callback(struct stm_gpio *gpio, uint8_t pin, void (*callback)(void)) {
127         (void) gpio;
128         ao_exti_callback[pin] = callback;
129 }
130
131 void
132 ao_exti_enable(struct stm_gpio *gpio, uint8_t pin) {
133         uint32_t        mask = (1 << pin);
134         (void) gpio;
135         stm_exti.pr = mask;
136         stm_exti.imr |= (1 << pin);
137 }
138
139 void
140 ao_exti_disable(struct stm_gpio *gpio, uint8_t pin) {
141         uint32_t        mask = (1 << pin);
142         (void) gpio;
143         stm_exti.imr &= ~mask;
144         stm_exti.pr = mask;
145 }
146
147 void
148 ao_exti_init(void)
149 {
150 }