6 #include "build/assert.h"
15 extiCallbackRec_t
* handler
;
18 extiChannelRec_t extiChannelRecs
[16];
20 // IRQ gouping, same on 103 and 303
21 #define EXTI_IRQ_GROUPS 7
22 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
23 static const uint8_t extiGroups
[16] = { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 };
24 static uint8_t extiGroupPriority
[EXTI_IRQ_GROUPS
];
26 #if defined(STM32F1) || defined(STM32F4)
27 static const uint8_t extiGroupIRQn
[EXTI_IRQ_GROUPS
] = {
36 #elif defined(STM32F3)
37 static const uint8_t extiGroupIRQn
[EXTI_IRQ_GROUPS
] = {
47 # warning "Unknown CPU"
54 // enable AFIO for EXTI support
55 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO
, ENABLE
);
57 #if defined(STM32F3) || defined(STM32F4)
58 /* Enable SYSCFG clock otherwise the EXTI irq handlers are not called */
59 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG
, ENABLE
);
61 memset(extiChannelRecs
, 0, sizeof(extiChannelRecs
));
62 memset(extiGroupPriority
, 0xff, sizeof(extiGroupPriority
));
65 void EXTIHandlerInit(extiCallbackRec_t
*self
, extiHandlerCallback
*fn
)
70 void EXTIConfig(IO_t io
, extiCallbackRec_t
*cb
, int irqPriority
, EXTITrigger_TypeDef trigger
)
73 chIdx
= IO_GPIOPinIdx(io
);
77 // we have only 16 extiChannelRecs
80 extiChannelRec_t
*rec
= &extiChannelRecs
[chIdx
];
81 int group
= extiGroups
[chIdx
];
84 #if defined(STM32F10X)
85 GPIO_EXTILineConfig(IO_GPIO_PortSource(io
), IO_GPIO_PinSource(io
));
86 #elif defined(STM32F303xC)
87 SYSCFG_EXTILineConfig(IO_EXTI_PortSourceGPIO(io
), IO_EXTI_PinSource(io
));
88 #elif defined(STM32F4)
89 SYSCFG_EXTILineConfig(IO_EXTI_PortSourceGPIO(io
), IO_EXTI_PinSource(io
));
91 # warning "Unknown CPU"
93 uint32_t extiLine
= IO_EXTI_Line(io
);
95 EXTI_ClearITPendingBit(extiLine
);
97 EXTI_InitTypeDef EXTIInit
;
98 EXTIInit
.EXTI_Line
= extiLine
;
99 EXTIInit
.EXTI_Mode
= EXTI_Mode_Interrupt
;
100 EXTIInit
.EXTI_Trigger
= trigger
;
101 EXTIInit
.EXTI_LineCmd
= ENABLE
;
102 EXTI_Init(&EXTIInit
);
104 if(extiGroupPriority
[group
] > irqPriority
) {
105 extiGroupPriority
[group
] = irqPriority
;
107 NVIC_InitTypeDef NVIC_InitStructure
;
108 NVIC_InitStructure
.NVIC_IRQChannel
= extiGroupIRQn
[group
];
109 NVIC_InitStructure
.NVIC_IRQChannelPreemptionPriority
= NVIC_PRIORITY_BASE(irqPriority
);
110 NVIC_InitStructure
.NVIC_IRQChannelSubPriority
= NVIC_PRIORITY_SUB(irqPriority
);
111 NVIC_InitStructure
.NVIC_IRQChannelCmd
= ENABLE
;
112 NVIC_Init(&NVIC_InitStructure
);
116 void EXTIRelease(IO_t io
)
118 // don't forget to match cleanup with config
119 EXTIEnable(io
, false);
122 chIdx
= IO_GPIOPinIdx(io
);
126 // we have only 16 extiChannelRecs
129 extiChannelRec_t
*rec
= &extiChannelRecs
[chIdx
];
133 void EXTIEnable(IO_t io
, bool enable
)
135 #if defined(STM32F1) || defined(STM32F4)
136 uint32_t extiLine
= IO_EXTI_Line(io
);
140 EXTI
->IMR
|= extiLine
;
142 EXTI
->IMR
&= ~extiLine
;
143 #elif defined(STM32F303xC)
144 int extiLine
= IO_EXTI_Line(io
);
147 // assume extiLine < 32 (valid for all EXTI pins)
149 EXTI
->IMR
|= 1 << extiLine
;
151 EXTI
->IMR
&= ~(1 << extiLine
);
153 # error "Unsupported target"
157 void EXTI_IRQHandler(void)
159 uint32_t exti_active
= EXTI
->IMR
& EXTI
->PR
;
162 unsigned idx
= 31 - __builtin_clz(exti_active
);
163 uint32_t mask
= 1 << idx
;
164 extiChannelRecs
[idx
].handler
->fn(extiChannelRecs
[idx
].handler
);
165 EXTI
->PR
= mask
; // clear pending mask (by writing 1)
166 exti_active
&= ~mask
;
170 #define _EXTI_IRQ_HANDLER(name) \
178 _EXTI_IRQ_HANDLER(EXTI0_IRQHandler
);
179 _EXTI_IRQ_HANDLER(EXTI1_IRQHandler
);
181 _EXTI_IRQ_HANDLER(EXTI2_IRQHandler
);
182 #elif defined(STM32F3) || defined(STM32F4)
183 _EXTI_IRQ_HANDLER(EXTI2_TS_IRQHandler
);
185 # warning "Unknown CPU"
187 _EXTI_IRQ_HANDLER(EXTI3_IRQHandler
);
188 _EXTI_IRQ_HANDLER(EXTI4_IRQHandler
);
189 _EXTI_IRQ_HANDLER(EXTI9_5_IRQHandler
);
190 _EXTI_IRQ_HANDLER(EXTI15_10_IRQHandler
);