31
31
#include "cmsis.h"
32
32
33
33
#include "gpio_irq_api.h"
34
+ #include "pinmap.h"
34
35
#include "error.h"
35
36
36
37
#define EDGE_NONE (0)
37
38
#define EDGE_RISE (1)
38
39
#define EDGE_FALL (2)
39
40
#define EDGE_BOTH (3)
40
41
41
- #define CHANNEL_NUM (16 )
42
+ #define CHANNEL_NUM (4 )
42
43
43
- static uint32_t channel_ids [CHANNEL_NUM ] = {0 };
44
+ static uint32_t channel_ids [CHANNEL_NUM ] = {0 , 0 , 0 , 0 };
45
+ static uint32_t channel_gpio [CHANNEL_NUM ] = {0 , 0 , 0 , 0 };
46
+ static uint32_t channel_pin [CHANNEL_NUM ] = {0 , 0 , 0 , 0 };
44
47
45
48
static gpio_irq_handler irq_handler ;
46
49
47
- static void handle_interrupt_in (uint32_t channel ) {
48
- if (channel_ids [channel ] == 0 ) return ;
50
+ static void handle_interrupt_in (uint32_t irq_index ) {
49
51
50
- uint32_t exti_line = (uint32_t )(1 << channel );
51
- if (EXTI_GetITStatus (exti_line ) != RESET )
52
+ // Retrieve the gpio and pin that generate the irq
53
+ GPIO_TypeDef * gpio = (GPIO_TypeDef * )(channel_gpio [irq_index ]);
54
+ uint32_t pin = (uint32_t )(1 << channel_pin [irq_index ]);
55
+
56
+ // Clear interrupt flag
57
+ if (EXTI_GetITStatus (pin ) != RESET )
52
58
{
53
- EXTI_ClearITPendingBit (exti_line );
59
+ EXTI_ClearITPendingBit (pin );
54
60
}
55
61
56
- // Warning:
57
- // On this device we don't know if a rising or falling event occured.
58
- // In case both rise and fall events are set, only the FALL event will be reported.
59
- if (EXTI -> FTSR & ( uint32_t )( 1 << channel ) ) {
60
- irq_handler (channel_ids [channel ], IRQ_FALL );
62
+ if ( channel_ids [ irq_index ] == 0 ) return ;
63
+
64
+ // Check which edge has generated the irq
65
+ if (( gpio -> IDR & pin ) == 0 ) {
66
+ irq_handler (channel_ids [irq_index ], IRQ_FALL );
61
67
}
62
- else {
63
- irq_handler (channel_ids [channel ], IRQ_RISE );
68
+ else {
69
+ irq_handler (channel_ids [irq_index ], IRQ_RISE );
64
70
}
65
71
}
66
72
73
+ // The irq_index is passed to the function
67
74
static void gpio_irq0 (void ) {handle_interrupt_in (0 );}
68
75
static void gpio_irq1 (void ) {handle_interrupt_in (1 );}
69
76
static void gpio_irq2 (void ) {handle_interrupt_in (2 );}
70
77
static void gpio_irq3 (void ) {handle_interrupt_in (3 );}
71
- static void gpio_irq4 (void ) {handle_interrupt_in (4 );}
72
- static void gpio_irq5 (void ) {handle_interrupt_in (5 );}
73
- static void gpio_irq6 (void ) {handle_interrupt_in (6 );}
74
- static void gpio_irq7 (void ) {handle_interrupt_in (7 );}
75
- static void gpio_irq8 (void ) {handle_interrupt_in (8 );}
76
- static void gpio_irq9 (void ) {handle_interrupt_in (9 );}
77
- static void gpio_irq10 (void ) {handle_interrupt_in (10 );}
78
- static void gpio_irq11 (void ) {handle_interrupt_in (11 );}
79
- static void gpio_irq12 (void ) {handle_interrupt_in (12 );}
80
- static void gpio_irq13 (void ) {handle_interrupt_in (13 );}
81
- static void gpio_irq14 (void ) {handle_interrupt_in (14 );}
82
- static void gpio_irq15 (void ) {handle_interrupt_in (15 );}
78
+
79
+ extern uint32_t Set_GPIO_Clock (uint32_t port_idx );
83
80
84
81
int gpio_irq_init (gpio_irq_t * obj , PinName pin , gpio_irq_handler handler , uint32_t id ) {
85
- IRQn_Type irq_n = (IRQn_Type )0 ;
82
+ IRQn_Type irq_n = (IRQn_Type )0 ;
86
83
uint32_t vector = 0 ;
87
-
84
+ uint32_t irq_index ;
85
+
88
86
if (pin == NC ) return -1 ;
89
87
90
88
uint32_t port_index = STM_PORT (pin );
91
89
uint32_t pin_index = STM_PIN (pin );
92
-
93
- // Select irq number and vector
94
- switch (pin_index ) {
95
- case 0 :
96
- irq_n = EXTI0_IRQn ;
90
+
91
+ // Select irq number and interrupt routine
92
+ switch (pin ) {
93
+ case PC_13 : // User button
94
+ irq_n = EXTI15_10_IRQn ;
97
95
vector = (uint32_t )& gpio_irq0 ;
96
+ irq_index = 0 ;
98
97
break ;
99
- case 1 :
100
- irq_n = EXTI1_IRQn ;
101
- vector = (uint32_t )& gpio_irq1 ;
102
- break ;
103
- case 2 :
104
- irq_n = EXTI2_IRQn ;
105
- vector = (uint32_t )& gpio_irq2 ;
106
- break ;
107
- case 3 :
98
+ case PB_3 :
108
99
irq_n = EXTI3_IRQn ;
109
- vector = (uint32_t )& gpio_irq3 ;
100
+ vector = (uint32_t )& gpio_irq1 ;
101
+ irq_index = 1 ;
110
102
break ;
111
- case 4 :
103
+ case PB_4 :
112
104
irq_n = EXTI4_IRQn ;
113
- vector = (uint32_t )& gpio_irq4 ;
105
+ vector = (uint32_t )& gpio_irq2 ;
106
+ irq_index = 2 ;
114
107
break ;
115
- case 5 :
116
- irq_n = EXTI9_5_IRQn ;
117
- vector = (uint32_t )& gpio_irq5 ;
118
- break ;
119
- case 6 :
108
+ case PB_5 :
120
109
irq_n = EXTI9_5_IRQn ;
121
- vector = (uint32_t )& gpio_irq6 ;
122
- break ;
123
- case 7 :
124
- irq_n = EXTI9_5_IRQn ;
125
- vector = (uint32_t )& gpio_irq7 ;
126
- break ;
127
- case 8 :
128
- irq_n = EXTI9_5_IRQn ;
129
- vector = (uint32_t )& gpio_irq8 ;
130
- break ;
131
- case 9 :
132
- irq_n = EXTI9_5_IRQn ;
133
- vector = (uint32_t )& gpio_irq9 ;
110
+ vector = (uint32_t )& gpio_irq3 ;
111
+ irq_index = 3 ;
134
112
break ;
135
- case 10 :
136
- irq_n = EXTI15_10_IRQn ;
137
- vector = (uint32_t )& gpio_irq10 ;
138
- break ;
139
- case 11 :
140
- irq_n = EXTI15_10_IRQn ;
141
- vector = (uint32_t )& gpio_irq11 ;
142
- break ;
143
- case 12 :
144
- irq_n = EXTI15_10_IRQn ;
145
- vector = (uint32_t )& gpio_irq12 ;
146
- break ;
147
- case 13 :
148
- irq_n = EXTI15_10_IRQn ;
149
- vector = (uint32_t )& gpio_irq13 ;
150
- break ;
151
- case 14 :
152
- irq_n = EXTI15_10_IRQn ;
153
- vector = (uint32_t )& gpio_irq14 ;
154
- break ;
155
- case 15 :
156
- irq_n = EXTI15_10_IRQn ;
157
- vector = (uint32_t )& gpio_irq15 ;
158
- break ;
159
113
default :
114
+ error ("This pin is not supported with InterruptIn.\n" );
160
115
return -1 ;
161
116
}
162
-
117
+
163
118
// Enable GPIO clock
164
- switch (port_index ) {
165
- case PortA :
166
- RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOA , ENABLE );
167
- break ;
168
- case PortB :
169
- RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOB , ENABLE );
170
- break ;
171
- case PortC :
172
- RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOC , ENABLE );
173
- break ;
174
- case PortD :
175
- RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOD , ENABLE );
176
- break ;
177
- case PortH :
178
- RCC_AHBPeriphClockCmd (RCC_AHBPeriph_GPIOH , ENABLE );
179
- break ;
180
- default :
181
- error ("GPIO port number is not correct." );
182
- break ;
183
- }
184
-
119
+ uint32_t gpio_add = Set_GPIO_Clock (port_index );
120
+
185
121
// Enable SYSCFG clock
186
122
RCC_APB2PeriphClockCmd (RCC_APB2Periph_SYSCFG , ENABLE );
187
123
@@ -207,20 +143,23 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
207
143
NVIC_SetVector (irq_n , vector );
208
144
NVIC_EnableIRQ (irq_n );
209
145
210
- // Save for future use
211
- obj -> ch = pin_index ;
146
+ // Save informations for future use
212
147
obj -> irq_n = irq_n ;
148
+ obj -> irq_index = irq_index ;
213
149
obj -> event = EDGE_NONE ;
150
+ channel_ids [irq_index ] = id ;
151
+ channel_gpio [irq_index ] = gpio_add ;
152
+ channel_pin [irq_index ] = pin_index ;
214
153
215
- channel_ids [obj -> ch ] = id ;
216
-
217
154
irq_handler = handler ;
218
155
219
156
return 0 ;
220
157
}
221
158
222
159
void gpio_irq_free (gpio_irq_t * obj ) {
223
- channel_ids [obj -> ch ] = 0 ;
160
+ channel_ids [obj -> irq_index ] = 0 ;
161
+ channel_gpio [obj -> irq_index ] = 0 ;
162
+ channel_pin [obj -> irq_index ] = 0 ;
224
163
// Disable EXTI line
225
164
EXTI_InitTypeDef EXTI_InitStructure ;
226
165
EXTI_StructInit (& EXTI_InitStructure );
@@ -231,7 +170,9 @@ void gpio_irq_free(gpio_irq_t *obj) {
231
170
void gpio_irq_set (gpio_irq_t * obj , gpio_irq_event event , uint32_t enable ) {
232
171
EXTI_InitTypeDef EXTI_InitStructure ;
233
172
234
- EXTI_InitStructure .EXTI_Line = (uint32_t )(1 << obj -> ch );
173
+ uint32_t pin_index = channel_pin [obj -> irq_index ];
174
+
175
+ EXTI_InitStructure .EXTI_Line = (uint32_t )(1 << pin_index );
235
176
EXTI_InitStructure .EXTI_Mode = EXTI_Mode_Interrupt ;
236
177
237
178
if (event == IRQ_RISE ) {
0 commit comments