User | Revision | Line number | New contents of line |
ganlikun |
0:06036f8bee2d
|
1
|
/* mbed Microcontroller Library
|
ganlikun |
0:06036f8bee2d
|
2
|
*******************************************************************************
|
ganlikun |
0:06036f8bee2d
|
3
|
* Copyright (c) 2014, STMicroelectronics
|
ganlikun |
0:06036f8bee2d
|
4
|
* All rights reserved.
|
ganlikun |
0:06036f8bee2d
|
5
|
*
|
ganlikun |
0:06036f8bee2d
|
6
|
* Redistribution and use in source and binary forms, with or without
|
ganlikun |
0:06036f8bee2d
|
7
|
* modification, are permitted provided that the following conditions are met:
|
ganlikun |
0:06036f8bee2d
|
8
|
*
|
ganlikun |
0:06036f8bee2d
|
9
|
* 1. Redistributions of source code must retain the above copyright notice,
|
ganlikun |
0:06036f8bee2d
|
10
|
* this list of conditions and the following disclaimer.
|
ganlikun |
0:06036f8bee2d
|
11
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
ganlikun |
0:06036f8bee2d
|
12
|
* this list of conditions and the following disclaimer in the documentation
|
ganlikun |
0:06036f8bee2d
|
13
|
* and/or other materials provided with the distribution.
|
ganlikun |
0:06036f8bee2d
|
14
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
ganlikun |
0:06036f8bee2d
|
15
|
* may be used to endorse or promote products derived from this software
|
ganlikun |
0:06036f8bee2d
|
16
|
* without specific prior written permission.
|
ganlikun |
0:06036f8bee2d
|
17
|
*
|
ganlikun |
0:06036f8bee2d
|
18
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
ganlikun |
0:06036f8bee2d
|
19
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
ganlikun |
0:06036f8bee2d
|
20
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
ganlikun |
0:06036f8bee2d
|
21
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
ganlikun |
0:06036f8bee2d
|
22
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
ganlikun |
0:06036f8bee2d
|
23
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
ganlikun |
0:06036f8bee2d
|
24
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
ganlikun |
0:06036f8bee2d
|
25
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
ganlikun |
0:06036f8bee2d
|
26
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
ganlikun |
0:06036f8bee2d
|
27
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
ganlikun |
0:06036f8bee2d
|
28
|
*******************************************************************************
|
ganlikun |
0:06036f8bee2d
|
29
|
*/
|
ganlikun |
0:06036f8bee2d
|
30
|
#include <stddef.h>
|
ganlikun |
0:06036f8bee2d
|
31
|
#include "cmsis.h"
|
ganlikun |
0:06036f8bee2d
|
32
|
#include "gpio_irq_api.h"
|
ganlikun |
0:06036f8bee2d
|
33
|
#include "pinmap.h"
|
ganlikun |
0:06036f8bee2d
|
34
|
#include "mbed_error.h"
|
ganlikun |
0:06036f8bee2d
|
35
|
#include "gpio_irq_device.h"
|
ganlikun |
0:06036f8bee2d
|
36
|
|
ganlikun |
0:06036f8bee2d
|
37
|
#define EDGE_NONE (0)
|
ganlikun |
0:06036f8bee2d
|
38
|
#define EDGE_RISE (1)
|
ganlikun |
0:06036f8bee2d
|
39
|
#define EDGE_FALL (2)
|
ganlikun |
0:06036f8bee2d
|
40
|
#define EDGE_BOTH (3)
|
ganlikun |
0:06036f8bee2d
|
41
|
|
ganlikun |
0:06036f8bee2d
|
42
|
|
ganlikun |
0:06036f8bee2d
|
43
|
typedef struct gpio_channel {
|
ganlikun |
0:06036f8bee2d
|
44
|
uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts
|
ganlikun |
0:06036f8bee2d
|
45
|
uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance
|
ganlikun |
0:06036f8bee2d
|
46
|
GPIO_TypeDef* channel_gpio[MAX_PIN_LINE]; // base address of gpio port group
|
ganlikun |
0:06036f8bee2d
|
47
|
uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group
|
ganlikun |
0:06036f8bee2d
|
48
|
} gpio_channel_t;
|
ganlikun |
0:06036f8bee2d
|
49
|
|
ganlikun |
0:06036f8bee2d
|
50
|
static gpio_irq_handler irq_handler;
|
ganlikun |
0:06036f8bee2d
|
51
|
|
ganlikun |
0:06036f8bee2d
|
52
|
static gpio_channel_t channels[CHANNEL_NUM] = {
|
ganlikun |
0:06036f8bee2d
|
53
|
#ifdef EXTI_IRQ0_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
54
|
{.pin_mask = 0},
|
ganlikun |
0:06036f8bee2d
|
55
|
#endif
|
ganlikun |
0:06036f8bee2d
|
56
|
#ifdef EXTI_IRQ1_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
57
|
{.pin_mask = 0},
|
ganlikun |
0:06036f8bee2d
|
58
|
#endif
|
ganlikun |
0:06036f8bee2d
|
59
|
#ifdef EXTI_IRQ2_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
60
|
{.pin_mask = 0},
|
ganlikun |
0:06036f8bee2d
|
61
|
#endif
|
ganlikun |
0:06036f8bee2d
|
62
|
#ifdef EXTI_IRQ3_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
63
|
{.pin_mask = 0},
|
ganlikun |
0:06036f8bee2d
|
64
|
#endif
|
ganlikun |
0:06036f8bee2d
|
65
|
#ifdef EXTI_IRQ4_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
66
|
{.pin_mask = 0},
|
ganlikun |
0:06036f8bee2d
|
67
|
#endif
|
ganlikun |
0:06036f8bee2d
|
68
|
#ifdef EXTI_IRQ5_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
69
|
{.pin_mask = 0},
|
ganlikun |
0:06036f8bee2d
|
70
|
#endif
|
ganlikun |
0:06036f8bee2d
|
71
|
#ifdef EXTI_IRQ6_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
72
|
{.pin_mask = 0}
|
ganlikun |
0:06036f8bee2d
|
73
|
#endif
|
ganlikun |
0:06036f8bee2d
|
74
|
};
|
ganlikun |
0:06036f8bee2d
|
75
|
|
ganlikun |
0:06036f8bee2d
|
76
|
static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line)
|
ganlikun |
0:06036f8bee2d
|
77
|
{
|
ganlikun |
0:06036f8bee2d
|
78
|
gpio_channel_t *gpio_channel = &channels[irq_index];
|
ganlikun |
0:06036f8bee2d
|
79
|
uint32_t gpio_idx;
|
ganlikun |
0:06036f8bee2d
|
80
|
|
ganlikun |
0:06036f8bee2d
|
81
|
for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) {
|
ganlikun |
0:06036f8bee2d
|
82
|
uint32_t current_mask = (1 << gpio_idx);
|
ganlikun |
0:06036f8bee2d
|
83
|
|
ganlikun |
0:06036f8bee2d
|
84
|
if (gpio_channel->pin_mask & current_mask) {
|
ganlikun |
0:06036f8bee2d
|
85
|
// Retrieve the gpio and pin that generate the irq
|
ganlikun |
0:06036f8bee2d
|
86
|
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]);
|
ganlikun |
0:06036f8bee2d
|
87
|
uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx]));
|
ganlikun |
0:06036f8bee2d
|
88
|
|
ganlikun |
0:06036f8bee2d
|
89
|
// Clear interrupt flag
|
ganlikun |
0:06036f8bee2d
|
90
|
if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) {
|
ganlikun |
0:06036f8bee2d
|
91
|
__HAL_GPIO_EXTI_CLEAR_FLAG(pin);
|
ganlikun |
0:06036f8bee2d
|
92
|
|
ganlikun |
0:06036f8bee2d
|
93
|
if (gpio_channel->channel_ids[gpio_idx] == 0) {
|
ganlikun |
0:06036f8bee2d
|
94
|
continue;
|
ganlikun |
0:06036f8bee2d
|
95
|
}
|
ganlikun |
0:06036f8bee2d
|
96
|
|
ganlikun |
0:06036f8bee2d
|
97
|
// Check which edge has generated the irq
|
ganlikun |
0:06036f8bee2d
|
98
|
if ((gpio->IDR & pin) == 0) {
|
ganlikun |
0:06036f8bee2d
|
99
|
irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL);
|
ganlikun |
0:06036f8bee2d
|
100
|
} else {
|
ganlikun |
0:06036f8bee2d
|
101
|
irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE);
|
ganlikun |
0:06036f8bee2d
|
102
|
}
|
ganlikun |
0:06036f8bee2d
|
103
|
return;
|
ganlikun |
0:06036f8bee2d
|
104
|
}
|
ganlikun |
0:06036f8bee2d
|
105
|
}
|
ganlikun |
0:06036f8bee2d
|
106
|
}
|
ganlikun |
0:06036f8bee2d
|
107
|
error("Unexpected Spurious interrupt, index %d\r\n", irq_index);
|
ganlikun |
0:06036f8bee2d
|
108
|
}
|
ganlikun |
0:06036f8bee2d
|
109
|
|
ganlikun |
0:06036f8bee2d
|
110
|
|
ganlikun |
0:06036f8bee2d
|
111
|
#ifdef EXTI_IRQ0_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
112
|
// EXTI line 0
|
ganlikun |
0:06036f8bee2d
|
113
|
static void gpio_irq0(void)
|
ganlikun |
0:06036f8bee2d
|
114
|
{
|
ganlikun |
0:06036f8bee2d
|
115
|
handle_interrupt_in(0, EXTI_IRQ0_NUM_LINES);
|
ganlikun |
0:06036f8bee2d
|
116
|
}
|
ganlikun |
0:06036f8bee2d
|
117
|
#endif
|
ganlikun |
0:06036f8bee2d
|
118
|
#ifdef EXTI_IRQ1_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
119
|
// EXTI line 1
|
ganlikun |
0:06036f8bee2d
|
120
|
static void gpio_irq1(void)
|
ganlikun |
0:06036f8bee2d
|
121
|
{
|
ganlikun |
0:06036f8bee2d
|
122
|
handle_interrupt_in(1, EXTI_IRQ1_NUM_LINES);
|
ganlikun |
0:06036f8bee2d
|
123
|
}
|
ganlikun |
0:06036f8bee2d
|
124
|
#endif
|
ganlikun |
0:06036f8bee2d
|
125
|
#ifdef EXTI_IRQ2_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
126
|
// EXTI line 2
|
ganlikun |
0:06036f8bee2d
|
127
|
static void gpio_irq2(void)
|
ganlikun |
0:06036f8bee2d
|
128
|
{
|
ganlikun |
0:06036f8bee2d
|
129
|
handle_interrupt_in(2, EXTI_IRQ2_NUM_LINES);
|
ganlikun |
0:06036f8bee2d
|
130
|
}
|
ganlikun |
0:06036f8bee2d
|
131
|
#endif
|
ganlikun |
0:06036f8bee2d
|
132
|
#ifdef EXTI_IRQ3_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
133
|
// EXTI line 3
|
ganlikun |
0:06036f8bee2d
|
134
|
static void gpio_irq3(void)
|
ganlikun |
0:06036f8bee2d
|
135
|
{
|
ganlikun |
0:06036f8bee2d
|
136
|
handle_interrupt_in(3, EXTI_IRQ3_NUM_LINES);
|
ganlikun |
0:06036f8bee2d
|
137
|
}
|
ganlikun |
0:06036f8bee2d
|
138
|
#endif
|
ganlikun |
0:06036f8bee2d
|
139
|
#ifdef EXTI_IRQ4_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
140
|
// EXTI line 4
|
ganlikun |
0:06036f8bee2d
|
141
|
static void gpio_irq4(void)
|
ganlikun |
0:06036f8bee2d
|
142
|
{
|
ganlikun |
0:06036f8bee2d
|
143
|
handle_interrupt_in(4, EXTI_IRQ4_NUM_LINES);
|
ganlikun |
0:06036f8bee2d
|
144
|
}
|
ganlikun |
0:06036f8bee2d
|
145
|
#endif
|
ganlikun |
0:06036f8bee2d
|
146
|
#ifdef EXTI_IRQ5_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
147
|
// EXTI lines 5 to 9
|
ganlikun |
0:06036f8bee2d
|
148
|
static void gpio_irq5(void)
|
ganlikun |
0:06036f8bee2d
|
149
|
{
|
ganlikun |
0:06036f8bee2d
|
150
|
handle_interrupt_in(5, EXTI_IRQ5_NUM_LINES);
|
ganlikun |
0:06036f8bee2d
|
151
|
}
|
ganlikun |
0:06036f8bee2d
|
152
|
#endif
|
ganlikun |
0:06036f8bee2d
|
153
|
#ifdef EXTI_IRQ6_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
154
|
// EXTI lines 10 to 15
|
ganlikun |
0:06036f8bee2d
|
155
|
static void gpio_irq6(void)
|
ganlikun |
0:06036f8bee2d
|
156
|
{
|
ganlikun |
0:06036f8bee2d
|
157
|
handle_interrupt_in(6, EXTI_IRQ6_NUM_LINES);
|
ganlikun |
0:06036f8bee2d
|
158
|
}
|
ganlikun |
0:06036f8bee2d
|
159
|
#endif
|
ganlikun |
0:06036f8bee2d
|
160
|
|
ganlikun |
0:06036f8bee2d
|
161
|
extern GPIO_TypeDef *Set_GPIO_Clock(uint32_t port_idx);
|
ganlikun |
0:06036f8bee2d
|
162
|
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
|
ganlikun |
0:06036f8bee2d
|
163
|
|
ganlikun |
0:06036f8bee2d
|
164
|
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
|
ganlikun |
0:06036f8bee2d
|
165
|
{
|
ganlikun |
0:06036f8bee2d
|
166
|
uint32_t vector = 0;
|
ganlikun |
0:06036f8bee2d
|
167
|
uint32_t irq_index;
|
ganlikun |
0:06036f8bee2d
|
168
|
gpio_channel_t *gpio_channel;
|
ganlikun |
0:06036f8bee2d
|
169
|
uint32_t gpio_idx;
|
ganlikun |
0:06036f8bee2d
|
170
|
|
ganlikun |
0:06036f8bee2d
|
171
|
if (pin == NC) return -1;
|
ganlikun |
0:06036f8bee2d
|
172
|
|
ganlikun |
0:06036f8bee2d
|
173
|
/* Enable SYSCFG Clock */
|
ganlikun |
0:06036f8bee2d
|
174
|
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
ganlikun |
0:06036f8bee2d
|
175
|
|
ganlikun |
0:06036f8bee2d
|
176
|
uint32_t port_index = STM_PORT(pin);
|
ganlikun |
0:06036f8bee2d
|
177
|
uint32_t pin_index = STM_PIN(pin);
|
ganlikun |
0:06036f8bee2d
|
178
|
irq_index = pin_lines_desc[pin_index].irq_index;
|
ganlikun |
0:06036f8bee2d
|
179
|
|
ganlikun |
0:06036f8bee2d
|
180
|
switch (irq_index) {
|
ganlikun |
0:06036f8bee2d
|
181
|
#ifdef EXTI_IRQ0_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
182
|
case 0:
|
ganlikun |
0:06036f8bee2d
|
183
|
vector = (uint32_t)&gpio_irq0;
|
ganlikun |
0:06036f8bee2d
|
184
|
break;
|
ganlikun |
0:06036f8bee2d
|
185
|
#endif
|
ganlikun |
0:06036f8bee2d
|
186
|
#ifdef EXTI_IRQ1_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
187
|
case 1:
|
ganlikun |
0:06036f8bee2d
|
188
|
vector = (uint32_t)&gpio_irq1;
|
ganlikun |
0:06036f8bee2d
|
189
|
break;
|
ganlikun |
0:06036f8bee2d
|
190
|
#endif
|
ganlikun |
0:06036f8bee2d
|
191
|
#ifdef EXTI_IRQ2_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
192
|
case 2:
|
ganlikun |
0:06036f8bee2d
|
193
|
vector = (uint32_t)&gpio_irq2;
|
ganlikun |
0:06036f8bee2d
|
194
|
break;
|
ganlikun |
0:06036f8bee2d
|
195
|
#endif
|
ganlikun |
0:06036f8bee2d
|
196
|
#ifdef EXTI_IRQ3_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
197
|
case 3:
|
ganlikun |
0:06036f8bee2d
|
198
|
vector = (uint32_t)&gpio_irq3;
|
ganlikun |
0:06036f8bee2d
|
199
|
break;
|
ganlikun |
0:06036f8bee2d
|
200
|
#endif
|
ganlikun |
0:06036f8bee2d
|
201
|
#ifdef EXTI_IRQ4_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
202
|
case 4:
|
ganlikun |
0:06036f8bee2d
|
203
|
vector = (uint32_t)&gpio_irq4;
|
ganlikun |
0:06036f8bee2d
|
204
|
break;
|
ganlikun |
0:06036f8bee2d
|
205
|
#endif
|
ganlikun |
0:06036f8bee2d
|
206
|
#ifdef EXTI_IRQ5_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
207
|
case 5:
|
ganlikun |
0:06036f8bee2d
|
208
|
vector = (uint32_t)&gpio_irq5;
|
ganlikun |
0:06036f8bee2d
|
209
|
break;
|
ganlikun |
0:06036f8bee2d
|
210
|
#endif
|
ganlikun |
0:06036f8bee2d
|
211
|
#ifdef EXTI_IRQ6_NUM_LINES
|
ganlikun |
0:06036f8bee2d
|
212
|
case 6:
|
ganlikun |
0:06036f8bee2d
|
213
|
vector = (uint32_t)&gpio_irq6;
|
ganlikun |
0:06036f8bee2d
|
214
|
break;
|
ganlikun |
0:06036f8bee2d
|
215
|
#endif
|
ganlikun |
0:06036f8bee2d
|
216
|
default:
|
ganlikun |
0:06036f8bee2d
|
217
|
error("InterruptIn error: pin not supported.\n");
|
ganlikun |
0:06036f8bee2d
|
218
|
return -1;
|
ganlikun |
0:06036f8bee2d
|
219
|
}
|
ganlikun |
0:06036f8bee2d
|
220
|
|
ganlikun |
0:06036f8bee2d
|
221
|
// Enable GPIO clock
|
ganlikun |
0:06036f8bee2d
|
222
|
GPIO_TypeDef *gpio_add = Set_GPIO_Clock(port_index);
|
ganlikun |
0:06036f8bee2d
|
223
|
|
ganlikun |
0:06036f8bee2d
|
224
|
// Save informations for future use
|
ganlikun |
0:06036f8bee2d
|
225
|
obj->irq_n = pin_lines_desc[pin_index].irq_n;
|
ganlikun |
0:06036f8bee2d
|
226
|
obj->irq_index = pin_lines_desc[pin_index].irq_index;
|
ganlikun |
0:06036f8bee2d
|
227
|
obj->event = EDGE_NONE;
|
ganlikun |
0:06036f8bee2d
|
228
|
obj->pin = pin;
|
ganlikun |
0:06036f8bee2d
|
229
|
|
ganlikun |
0:06036f8bee2d
|
230
|
gpio_channel = &channels[irq_index];
|
ganlikun |
0:06036f8bee2d
|
231
|
gpio_idx = pin_lines_desc[pin_index].gpio_idx;
|
ganlikun |
0:06036f8bee2d
|
232
|
gpio_channel->pin_mask |= (1 << gpio_idx);
|
ganlikun |
0:06036f8bee2d
|
233
|
gpio_channel->channel_ids[gpio_idx] = id;
|
ganlikun |
0:06036f8bee2d
|
234
|
gpio_channel->channel_gpio[gpio_idx] = gpio_add;
|
ganlikun |
0:06036f8bee2d
|
235
|
gpio_channel->channel_pin[gpio_idx] = pin_index;
|
ganlikun |
0:06036f8bee2d
|
236
|
|
ganlikun |
0:06036f8bee2d
|
237
|
irq_handler = handler;
|
ganlikun |
0:06036f8bee2d
|
238
|
|
ganlikun |
0:06036f8bee2d
|
239
|
// Enable EXTI interrupt
|
ganlikun |
0:06036f8bee2d
|
240
|
NVIC_SetVector(obj->irq_n, vector);
|
ganlikun |
0:06036f8bee2d
|
241
|
gpio_irq_enable(obj);
|
ganlikun |
0:06036f8bee2d
|
242
|
|
ganlikun |
0:06036f8bee2d
|
243
|
return 0;
|
ganlikun |
0:06036f8bee2d
|
244
|
}
|
ganlikun |
0:06036f8bee2d
|
245
|
|
ganlikun |
0:06036f8bee2d
|
246
|
void gpio_irq_free(gpio_irq_t *obj)
|
ganlikun |
0:06036f8bee2d
|
247
|
{
|
ganlikun |
0:06036f8bee2d
|
248
|
uint32_t gpio_idx = pin_lines_desc[STM_PIN(obj->pin)].gpio_idx;
|
ganlikun |
0:06036f8bee2d
|
249
|
gpio_channel_t *gpio_channel = &channels[obj->irq_index];
|
ganlikun |
0:06036f8bee2d
|
250
|
|
ganlikun |
0:06036f8bee2d
|
251
|
gpio_irq_disable(obj);
|
ganlikun |
0:06036f8bee2d
|
252
|
gpio_channel->pin_mask &= ~(1 << gpio_idx);
|
ganlikun |
0:06036f8bee2d
|
253
|
gpio_channel->channel_ids[gpio_idx] = 0;
|
ganlikun |
0:06036f8bee2d
|
254
|
gpio_channel->channel_gpio[gpio_idx] = 0;
|
ganlikun |
0:06036f8bee2d
|
255
|
gpio_channel->channel_pin[gpio_idx] = 0;
|
ganlikun |
0:06036f8bee2d
|
256
|
}
|
ganlikun |
0:06036f8bee2d
|
257
|
|
ganlikun |
0:06036f8bee2d
|
258
|
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
ganlikun |
0:06036f8bee2d
|
259
|
{
|
ganlikun |
0:06036f8bee2d
|
260
|
/* Enable / Disable Edge triggered interrupt and store event */
|
ganlikun |
0:06036f8bee2d
|
261
|
if (event == IRQ_RISE) {
|
ganlikun |
0:06036f8bee2d
|
262
|
if (enable) {
|
ganlikun |
0:06036f8bee2d
|
263
|
LL_EXTI_EnableRisingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
264
|
obj->event |= IRQ_RISE;
|
ganlikun |
0:06036f8bee2d
|
265
|
} else {
|
ganlikun |
0:06036f8bee2d
|
266
|
LL_EXTI_DisableRisingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
267
|
obj->event &= ~IRQ_RISE;
|
ganlikun |
0:06036f8bee2d
|
268
|
}
|
ganlikun |
0:06036f8bee2d
|
269
|
}
|
ganlikun |
0:06036f8bee2d
|
270
|
if (event == IRQ_FALL) {
|
ganlikun |
0:06036f8bee2d
|
271
|
if (enable) {
|
ganlikun |
0:06036f8bee2d
|
272
|
LL_EXTI_EnableFallingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
273
|
obj->event |= IRQ_FALL;
|
ganlikun |
0:06036f8bee2d
|
274
|
} else {
|
ganlikun |
0:06036f8bee2d
|
275
|
LL_EXTI_DisableFallingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
276
|
obj->event &= ~IRQ_FALL;
|
ganlikun |
0:06036f8bee2d
|
277
|
}
|
ganlikun |
0:06036f8bee2d
|
278
|
}
|
ganlikun |
0:06036f8bee2d
|
279
|
}
|
ganlikun |
0:06036f8bee2d
|
280
|
|
ganlikun |
0:06036f8bee2d
|
281
|
void gpio_irq_enable(gpio_irq_t *obj)
|
ganlikun |
0:06036f8bee2d
|
282
|
{
|
ganlikun |
0:06036f8bee2d
|
283
|
uint32_t temp = 0;
|
ganlikun |
0:06036f8bee2d
|
284
|
uint32_t port_index = STM_PORT(obj->pin);
|
ganlikun |
0:06036f8bee2d
|
285
|
uint32_t pin_index = STM_PIN(obj->pin);
|
ganlikun |
0:06036f8bee2d
|
286
|
|
ganlikun |
0:06036f8bee2d
|
287
|
/* Select Source */
|
ganlikun |
0:06036f8bee2d
|
288
|
temp = SYSCFG->EXTICR[pin_index >> 2];
|
ganlikun |
0:06036f8bee2d
|
289
|
CLEAR_BIT(temp, (0x0FU) << (4U * (pin_index & 0x03U)));
|
ganlikun |
0:06036f8bee2d
|
290
|
SET_BIT(temp, port_index << (4U * (pin_index & 0x03U)));
|
ganlikun |
0:06036f8bee2d
|
291
|
SYSCFG->EXTICR[pin_index >> 2] = temp;
|
ganlikun |
0:06036f8bee2d
|
292
|
|
ganlikun |
0:06036f8bee2d
|
293
|
LL_EXTI_EnableIT_0_31(1 << pin_index);
|
ganlikun |
0:06036f8bee2d
|
294
|
|
ganlikun |
0:06036f8bee2d
|
295
|
/* Restore previous edge interrupt configuration if applicable */
|
ganlikun |
0:06036f8bee2d
|
296
|
if (obj->event & IRQ_RISE) {
|
ganlikun |
0:06036f8bee2d
|
297
|
LL_EXTI_EnableRisingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
298
|
}
|
ganlikun |
0:06036f8bee2d
|
299
|
if (obj->event & IRQ_FALL) {
|
ganlikun |
0:06036f8bee2d
|
300
|
LL_EXTI_EnableFallingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
301
|
}
|
ganlikun |
0:06036f8bee2d
|
302
|
|
ganlikun |
0:06036f8bee2d
|
303
|
NVIC_EnableIRQ(obj->irq_n);
|
ganlikun |
0:06036f8bee2d
|
304
|
}
|
ganlikun |
0:06036f8bee2d
|
305
|
|
ganlikun |
0:06036f8bee2d
|
306
|
void gpio_irq_disable(gpio_irq_t *obj)
|
ganlikun |
0:06036f8bee2d
|
307
|
{
|
ganlikun |
0:06036f8bee2d
|
308
|
/* Clear EXTI line configuration */
|
ganlikun |
0:06036f8bee2d
|
309
|
LL_EXTI_DisableRisingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
310
|
LL_EXTI_DisableFallingTrig_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
311
|
LL_EXTI_DisableIT_0_31(1 << STM_PIN(obj->pin));
|
ganlikun |
0:06036f8bee2d
|
312
|
NVIC_DisableIRQ(obj->irq_n);
|
ganlikun |
0:06036f8bee2d
|
313
|
NVIC_ClearPendingIRQ(obj->irq_n);
|
ganlikun |
0:06036f8bee2d
|
314
|
}
|
ganlikun |
0:06036f8bee2d
|
315
|
|