[tuxdroid-svn] r811 - firmware/tuxcore/trunk
Status: Beta
Brought to you by:
ks156
From: jaguarondi <c2m...@c2...> - 2007-12-20 12:10:27
|
Author: jaguarondi Date: 2007-12-20 13:10:23 +0100 (Thu, 20 Dec 2007) New Revision: 811 Modified: firmware/tuxcore/trunk/motors.c Log: * When adding LED PWM, we noticed that the flipper position interrupt was triggered by the LED signal (PC2) while the switch signal (PC1) was around VDD/2. The capacitor that filters the switch signal (PC1) also decreases the rising time so the uncertainty period between which the input pin (PC1) could change from low to high is quite long. During this time, it seems changes of PC2 can affect PC1 directly, probably through crosstalks, and this triggers the flipper interrupt. In order to filter out this glitches, we disabled the interrupt for a couple milliseconds after it occurs the first time. Modified: firmware/tuxcore/trunk/motors.c =================================================================== --- firmware/tuxcore/trunk/motors.c 2007-12-20 11:57:20 UTC (rev 810) +++ firmware/tuxcore/trunk/motors.c 2007-12-20 12:10:23 UTC (rev 811) @@ -161,7 +161,46 @@ } /*! @} */ +/** Counter for flipper interrupt suspend. */ +uint8_t static suspend_flippers_delay = 0; + +/** Flipper interrupt suspend delay. */ +#define SUSPEND_FLIPPERS_DELAY 2 + /** + Suspend the flippers interrupt for debouncing, see the flipper ISR for + details about the problem. + */ +inline static void suspend_flippers_int(void) +{ + suspend_flippers_delay = SUSPEND_FLIPPERS_DELAY; + PCICR &= ~_BV(PCIE1); +} + +/** + Resume the flippers interrupt. + */ +inline static void resume_flippers_int(void) +{ + /* Clear pending interrupts before enabling them. */ + PCIFR = _BV(PCIF1); + PCICR |= _BV(PCIE1); +} + +/** + Resume interrupts when disabled for debouncing. + */ +inline static void manage_interrupts(void) +{ + if (suspend_flippers_delay) + { + suspend_flippers_delay--; + if (!suspend_flippers_delay) + resume_flippers_int(); + } +} + +/** * \name Eyes functions * @{ */ /** \brief Low level access to stop the eyes motor. */ @@ -594,9 +633,19 @@ FLIPPERS_BRAKING_DLY period. So we only count when the switch is pushed but not when it is released. As the interrupt triggers on a signal change, we need to suppress the release interrupt. + + When adding LED PWM, we noticed that the flipper position interrupt was + triggered by the LED signal (PC2) while the switch signal (PC1) was around + VDD/2. The capacitor that filters the switch signal (PC1) also decreases the + rising time so the uncertainty period between which the input pin (PC1) + could change from low to high is quite long. During this time, it seems + changes of PC2 can affect PC1 directly, probably through crosstalks, and + this triggers this interrupt. In order to filter out this glitches, we + disabled the interrupts for a couple milliseconds. */ ISR(SIG_PIN_CHANGE1) { + suspend_flippers_int(); /* We only count when the switch is pushed, not released. */ if (~PSW_FLIPPERS_PIN & PSW_FLIPPERS_MK) { @@ -828,4 +877,7 @@ stop_spinning(); } } + + /* Handle interrupt suspend. */ + manage_interrupts(); } |