@@ -138,26 +138,43 @@ static void avr_extint_irq_notify(struct avr_irq_t * irq, uint32_t value, void *
138
138
{
139
139
/**
140
140
Datasheet excerpt:
141
- >When the external interrupt is enabled and is configured as level triggered (only INT0/INT1),
142
- >the interrupt will trigger as long as the pin is held low.
143
- Thus we have to query the pin value continiously while it's held low and try to trigger the interrupt.
144
- This can be expensive, so avr_extint_set_strict_lvl_trig function provisioned to allow the user
145
- to turn this feature off. In this case bahaviour will be similar to the falling edge interrupt.
141
+ > When the external interrupt is enabled and is configured
142
+ > as level triggered (only INT0/INT1), the interrupt
143
+ > will trigger as long as the pin is held low.
144
+ Thus we have to query the pin value continuously while
145
+ it's held low and try to trigger the interrupt.
146
+ This can be expensive, so avr_extint_set_strict_lvl_trig()
147
+ function provisioned to allow the user to turn
148
+ this feature off. In this case behaviour will be similar
149
+ to the falling edge interrupt.
146
150
*/
147
151
if (!value ) {
148
- if (avr -> sreg [S_I ]) {
149
- uint8_t raised = avr_regbit_get (avr , p -> eint [irq -> irq ].vector .raised ) || p -> eint [irq -> irq ].vector .pending ;
150
- if (!raised )
151
- avr_raise_interrupt (avr , & p -> eint [irq -> irq ].vector );
152
- }
153
- if (p -> eint [irq -> irq ].strict_lvl_trig ) {
154
- avr_extint_poll_context_t * poll = malloc (sizeof (avr_extint_poll_context_t ));
152
+ uint8_t raised ;
153
+
154
+ raised = (avr_regbit_get (
155
+ avr ,
156
+ p -> eint [irq -> irq ].vector .raised ) ||
157
+ p -> eint [irq -> irq ].vector .pending );
158
+ if (!raised )
159
+ avr_raise_interrupt (avr , & p -> eint [irq -> irq ].vector );
160
+ if (!raised && p -> eint [irq -> irq ].vector .pending ) {
161
+ avr_extint_poll_context_t * poll ;
162
+
163
+ /* Interrupt pending, so start fast timer to re-enable
164
+ * it if the pin level does not change in the handler.
165
+ */
166
+
167
+ poll = malloc (sizeof (avr_extint_poll_context_t ));
155
168
if (poll ) {
156
169
poll -> eint_no = irq -> irq ;
157
170
poll -> extint = p ;
158
- avr_cycle_timer_register (avr , 1 , avr_extint_poll_level_trig , poll );
171
+ avr_cycle_timer_register (
172
+ avr , 1 , avr_extint_poll_level_trig , poll );
159
173
}
160
174
}
175
+ } else {
176
+ avr_clear_interrupt (avr , & p -> eint [irq -> irq ].vector );
177
+ // If running, timer will clear on next call.
161
178
}
162
179
}
163
180
break ;
0 commit comments