libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
exti_common_all.c
Go to the documentation of this file.
1/** @addtogroup exti_file EXTI peripheral API
2 * @ingroup peripheral_apis
3 */
4/*
5 * This file is part of the libopencm3 project.
6 *
7 * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz>
8 * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
9 *
10 * This library is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library. If not, see <http://www.gnu.org/licenses/>.
22 *
23 * This provides the code for the "next gen" EXTI block provided in F2/F4/F7/L1
24 * devices. (differences only in the source selection)
25 */
26/**@{*/
27
28
31
32#if defined(EXTI_EXTICR)
33 #define EXTICR_SELECTION_FIELDSIZE EXTI_EXTICR_FIELDSIZE
34 #define EXTICR_SELECTION_REG(x) EXTI_EXTICR(x)
35#elif defined(AFIO_EXTICR)
36 #define EXTICR_SELECTION_FIELDSIZE AFIO_EXTICR_FIELDSIZE
37 #define EXTICR_SELECTION_REG(x) AFIO_EXTICR(x)
38#else
40 #define EXTICR_SELECTION_FIELDSIZE SYSCFG_EXTICR_FIELDSIZE
41 #define EXTICR_SELECTION_REG(x) SYSCFG_EXTICR(x)
42#endif
43
44void exti_set_trigger(uint32_t extis, enum exti_trigger_type trig)
45{
46 switch (trig) {
48 EXTI_RTSR |= extis;
49 EXTI_FTSR &= ~extis;
50 break;
52 EXTI_RTSR &= ~extis;
53 EXTI_FTSR |= extis;
54 break;
56 EXTI_RTSR |= extis;
57 EXTI_FTSR |= extis;
58 break;
59 }
60}
61
62void exti_enable_request(uint32_t extis)
63{
64 /* Enable interrupts. */
65 EXTI_IMR |= extis;
66
67 /* Enable events. */
68 EXTI_EMR |= extis;
69}
70
71void exti_disable_request(uint32_t extis)
72{
73 /* Disable interrupts. */
74 EXTI_IMR &= ~extis;
75
76 /* Disable events. */
77 EXTI_EMR &= ~extis;
78}
79
80/*
81 * Reset the interrupt request by writing a 1 to the corresponding
82 * pending bit register.
83 */
84void exti_reset_request(uint32_t extis)
85{
86#if defined(EXTI_RPR1) && defined(EXTI_FPR1)
87 EXTI_RPR1 = extis;
88 EXTI_FPR1 = extis;
89#else
90 EXTI_PR = extis;
91#endif
92}
93
94/*
95 * Check the flag of a given EXTI interrupt.
96 * */
97uint32_t exti_get_flag_status(uint32_t exti)
98{
99#if defined(EXTI_RPR1) && defined(EXTI_FPR1)
100 return (EXTI_RPR1 & exti) | (EXTI_FPR1 & exti);
101#else
102 return EXTI_PR & exti;
103#endif
104}
105
106/*
107 * Remap an external interrupt line to the corresponding pin on the
108 * specified GPIO port.
109 *
110 * TODO: This could be rewritten in fewer lines of code.
111 */
112void exti_select_source(uint32_t exti, uint32_t gpioport)
113{
114 uint32_t line;
115 for (line = 0; line < 16; line++) {
116 if (!(exti & (1 << line))) {
117 continue;
118 }
119
120 uint32_t bits = 0;
121
122 switch (gpioport) {
123 case GPIOA:
124 bits = 0;
125 break;
126 case GPIOB:
127 bits = 1;
128 break;
129 case GPIOC:
130 bits = 2;
131 break;
132 case GPIOD:
133 bits = 3;
134 break;
135#if defined(GPIOE) && defined(GPIO_PORT_E_BASE)
136 case GPIOE:
137 bits = 4;
138 break;
139#endif
140#if defined(GPIOF) && defined(GPIO_PORT_F_BASE)
141 case GPIOF:
142 bits = 5;
143 break;
144#endif
145#if defined(GPIOG) && defined(GPIO_PORT_G_BASE)
146 case GPIOG:
147 bits = 6;
148 break;
149#endif
150#if defined(GPIOH) && defined(GPIO_PORT_H_BASE)
151 case GPIOH:
152 bits = 7;
153 break;
154#endif
155#if defined(GPIOI) && defined(GPIO_PORT_I_BASE)
156 case GPIOI:
157 bits = 8;
158 break;
159#endif
160#if defined(GPIOJ) && defined(GPIO_PORT_J_BASE)
161 case GPIOJ:
162 bits = 9;
163 break;
164#endif
165#if defined(GPIOK) && defined(GPIO_PORT_K_BASE)
166 case GPIOK:
167 bits = 10;
168 break;
169#endif
170 }
171
172 uint8_t shift = (uint8_t)(EXTICR_SELECTION_FIELDSIZE * (line % 4));
173 uint32_t mask = ((1 << EXTICR_SELECTION_FIELDSIZE) - 1) << shift;
174 uint32_t reg = line / 4;
175
176 EXTICR_SELECTION_REG(reg) = (EXTICR_SELECTION_REG(reg) & ~mask) | (bits << shift);
177 };
178}
179/**@}*/
180
exti_trigger_type
@ EXTI_TRIGGER_RISING
@ EXTI_TRIGGER_FALLING
@ EXTI_TRIGGER_BOTH
void exti_disable_request(uint32_t extis)
#define EXTICR_SELECTION_FIELDSIZE
uint32_t exti_get_flag_status(uint32_t exti)
void exti_select_source(uint32_t exti, uint32_t gpioport)
void exti_set_trigger(uint32_t extis, enum exti_trigger_type trig)
void exti_reset_request(uint32_t extis)
void exti_enable_request(uint32_t extis)
#define EXTICR_SELECTION_REG(x)
#define EXTI_EMR
EXTI Event Mask Register.
#define EXTI_IMR
EXTI Interrupt Mask Registers.
#define EXTI_RTSR
EXTI Rising Trigger Selection Register.
#define EXTI_PR
EXTI Pending Register.
#define EXTI_FTSR
EXTI Falling Triger Selection Register.
#define GPIOG
#define GPIOK
#define GPIOC
#define GPIOF
#define GPIOB
#define GPIOD
#define GPIOJ
#define GPIOA
#define GPIOI
#define GPIOH
#define GPIOE