Intermittent resets - only when pushing buttons

For RTC breakouts, etc., use the Other Products from Adafruit forum

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
madworm_de
 
Posts: 99
Joined: Mon Jun 09, 2008 6:56 am

Re: Intermittent resets - only when pushing buttons

Post by madworm_de »

Seems like a good explanation. This could be tested with inserting a pulse train of square pulses to simulate frequent button presses (in bursts, so it is similar to a bouncing switch). If this theory holds, the clock should reset or at least misbehave if the frequency gets too high.

User avatar
caitsith2
 
Posts: 217
Joined: Thu Jan 18, 2007 11:21 pm

Re: Intermittent resets - only when pushing buttons

Post by caitsith2 »

Well, with the code fix, I could not get it to misbehave. Without it, misbehaving and corrupting the ram is a real problem, which I have managed to reproduce consistently. Maybe a fast square-wave pulse might be able to outrun the interrupt disable code I implemented, but a human most definitely is not able to.

User avatar
mike31416
 
Posts: 126
Joined: Wed Aug 26, 2009 12:06 pm

Re: Intermittent resets - only when pushing buttons

Post by mike31416 »

Is it true that an given interrupt will interrupt its self if the Global Interrupt Enable is enabled after entering the interrupt?

I ran a test and it seems that there are about 700 bytes available for the stack. Each interrupt does 15 register pushes on entry (looked at the dot lss file). I guess if it nests 45 times deep there could be an issue.

Could something else be happening during the nesting other than running out of memory?

User avatar
mike31416
 
Posts: 126
Joined: Wed Aug 26, 2009 12:06 pm

Re: Intermittent resets - only when pushing buttons

Post by mike31416 »

Did a bit more testing to capture the stack pointer. Some background on my test environment...

I am running the clock code on the Arduino with an LCD interface. I created a function that captures the stack pointer and tracks its lowest value. I put calls to the stack capture in the interrupts and in main() I print the value to the LCD every 1/2 second or so. The stack pointer starts at 0x870 and the heap starts at 0x24C (above .bss). The 328P has 2K of RAM and the 168 has 1K. This gives 1572 bytes for the 328P and I guess the 168 would be about 548. I realize I have other things happening with the LCD and other porting changes I had to make, but I think it is still a good approximation of memory usage.

I put calls to the stack capture in the interrupts and see a small decrease when I push buttons 1,2 and 3. I have a wire to ground for the alarm switch. If I disconnect and reconnect the alarm wire, I see the stack low point go to 0x430 and sometimes lower which would mean the 168 might crash with a corrupted stack. I do see crashes sometimes with the 328P. I replaced button 1 (menu button) with a wire at got the same results.

It would seem that a "noisy" switch could cause the problem BANNED describes. I'll try his fix tonight...

madworm_de
 
Posts: 99
Joined: Mon Jun 09, 2008 6:56 am

Re: Intermittent resets - only when pushing buttons

Post by madworm_de »

The fix to the pin change interrupt code works great. It should be included into the official firmware.

I've tortured my clock and not a single crash occurred.

User avatar
mike31416
 
Posts: 126
Joined: Wed Aug 26, 2009 12:06 pm

Re: Intermittent resets - only when pushing buttons

Post by mike31416 »

Worked for me also. Works on the clock and on the ported code. The stack pointer is well behaved!

Many thanks to BANNED!

Mike

User avatar
caitsith2
 
Posts: 217
Joined: Thu Jan 18, 2007 11:21 pm

Re: Intermittent resets - only when pushing buttons

Post by caitsith2 »

Since the firmware fix seems to be working, and is continuing to work, after I have reinstalled the 100K resistor, Definitely include those fixes into the official firmware. The only reason for intermittent resets left, once the fixes to firmware are applied, is strictly cold solder joints and incorrectly or not placed components.

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Re: Intermittent resets - only when pushing buttons

Post by adafruit »

BANNED is magic! :mrgreen:
thanks for finding that bug. we will include it in future kits :D
email support@adafruit and we'll give you a gift certificate for the shop. (send a link to this post)

User avatar
joerg_daehn
 
Posts: 30
Joined: Tue Oct 13, 2009 6:39 pm

Re: Intermittent resets - only when pushing buttons

Post by joerg_daehn »

BANNED wrote:One more final reason for intermittent resets, and this one is software fixable. You are pushing the buttons way too fast.
That happend to me, too. Now if that was a finished product, I would be angry - but as this is a learning experience, I happily ordered the USBtiny-thingy. Wonder how that works out. But I wanted to get into programming anyway , so that's ok. :-)

J. Daehn, Hannover, Germany

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Re: Intermittent resets - only when pushing buttons

Post by adafruit »

if anyone with a kit is really frustrated by this bug (we saw it only very rarely) email support@adafruit and we'll send out a replacement chip with fixed firmware

jsgf
 
Posts: 61
Joined: Mon Oct 26, 2009 1:21 am

Re: Intermittent resets - only when pushing buttons

Post by jsgf »

Note that BANNED's fix is on the right track and will help a lot, but still leaves open a window for the race to occur. A more complete fix needs to disable interrupts before unmasking the interrupt source, so that the return from the interrupt handler will atomically enable interrupts. Without that there's a window between the unmask and the return-from-interrupt which allows more recursion.

Of course the race is tiny and possibly only theoretical, but its fairly easy to fix:

Code: Select all

diff --git a/iv.c b/iv.c
index f29fb88..4732516 100644
--- a/iv.c
+++ b/iv.c
@@ -185,20 +185,23 @@ volatile uint8_t buttonholdcounter = 0;
 // This interrupt detects switches 1 and 3
 SIGNAL(SIG_PIN_CHANGE2) {
   // allow interrupts while we're doing this
+  PCMSK2 = 0;
   sei();
+  // kick the dog
+  kickthedog();
 
   if (! (PIND & _BV(BUTTON1))) {
     // button1 is pressed
     if (! (last_buttonstate & 0x1)) { // was not pressed before
       delayms(10);                    // debounce
       if (PIND & _BV(BUTTON1))        // filter out bounces
-	return;
+	goto out;
       tick();                         // make a noise
       // check if we will snag this button press for snoozing
       if (alarming) {
 	// turn on snooze
 	setsnooze();
-	return;
+	goto out;
       }
       last_buttonstate |= 0x1;
       just_pressed |= 0x1;
@@ -213,7 +216,7 @@ SIGNAL(SIG_PIN_CHANGE2) {
     if (! (last_buttonstate & 0x4)) { // was not pressed before
       delayms(10);                    // debounce
       if (PIND & _BV(BUTTON3))        // filter out bounces
-	return;
+	goto out;
       buttonholdcounter = 2;          // see if we're press-and-holding
       while (buttonholdcounter) {
 	if (PIND & _BV(BUTTON3)) {        // released
@@ -223,11 +226,11 @@ SIGNAL(SIG_PIN_CHANGE2) {
 	  if (alarming) {
 	    // turn on snooze
 	    setsnooze();
-	    return;
+	    goto out;
 	  }
 	  DEBUGP("b3");
 	  just_pressed |= 0x4;
-	  return;
+	  goto out;
 	}
       }
       last_buttonstate |= 0x4;
@@ -237,22 +240,26 @@ SIGNAL(SIG_PIN_CHANGE2) {
     pressed = 0;                      // button released
     last_buttonstate &= ~0x4;
   }
+out:
+  cli();
+  PCMSK2 = _BV(PCINT21) | _BV(PCINT20);
 }
 
 // Just button #2
 SIGNAL(SIG_PIN_CHANGE0) {
+  PCMSK0 = 0;
   sei();
   if (! (PINB & _BV(BUTTON2))) {
     // button2 is pressed
     if (! (last_buttonstate & 0x2)) { // was not pressed before
       delayms(10);                    // debounce
       if (PINB & _BV(BUTTON2))        // filter out bounces
-	return;
+	goto out;
       tick();                         // make a noise
       // check if we will snag this button press for snoozing
       if (alarming) {
-	setsnooze(); 	// turn on snooze
-	return;
+	setsnooze();    // turn on snooze
+	goto out;
       }
       last_buttonstate |= 0x2;
       just_pressed |= 0x2;
@@ -261,6 +268,9 @@ SIGNAL(SIG_PIN_CHANGE0) {
   } else {
     last_buttonstate &= ~0x2;
   }
+out:
+  cli();
+  PCMSK0 = _BV(PCINT0);
 }
 
 // This variable keeps track of whether we have not pressed any
@@ -361,18 +371,22 @@ SIGNAL (TIMER2_OVF_vect) {
   }
 }
 
-SIGNAL(SIG_INTERRUPT0) {
+//Alarm Switch
+SIGNAL(SIG_INTERRUPT0) {  
+  EIMSK = 0;  //Disable this interrupt while we are processing it.
   uart_putchar('i');
   uint8_t x = ALARM_PIN & _BV(ALARM);
   sei();
   delayms(10); // wait for debouncing
   if (x != (ALARM_PIN & _BV(ALARM)))
-    return;
+    goto out;
   setalarmstate();
+out:
+  cli();
+  EIMSK = _BV(INT0);  //And reenable it before exiting.
 }
 
 
-
 SIGNAL(SIG_COMPARATOR) {
   //DEBUGP("COMP");
   if (ACSR & _BV(ACO)) {

User avatar
joerg_daehn
 
Posts: 30
Joined: Tue Oct 13, 2009 6:39 pm

Re: Intermittent resets - only when pushing buttons

Post by joerg_daehn »

@Adafruit:

No need to worry, as far as I am concerned. I am totally happy with the kit, even with a bug. Because I already learned a lot ('bout soldering) and that's good my budding interest in electronics and programming . . . Wanted to get a USBtiny anyway for the dimmer mod.

Keep up the great work!!

Best regards,

J. Daehn

tharlow
 
Posts: 2
Joined: Sun Feb 07, 2010 4:13 pm

Re: Intermittent resets - only when pushing buttons

Post by tharlow »

I recently built the Ice Tube Clock kit, and thanks to the detailed and helpful instructions it worked out great! However (haha)... pushing the buttons in sequence quickly usually causes the clock to behave unpredictably, and patiently pushing them slowly seems to work up until I have pressed the same button, say, half a dozen times. But no matter what I do, after a few button presses something "random" happens to my clock. (After struggling with the button issues, if I leave it in peace the clock works perfectly. :))

Does this mean the replacement chip offer in this thread might apply to me?
adafruit wrote:if anyone with a kit is really frustrated by this bug (we saw it only very rarely) email support@adafruit and we'll send out a replacement chip with fixed firmware
(More boring explanation follows- unfortunately I managed to destroy the board of my USBtinyISP kit through an inept attempt at desoldering a couple of resistors, haha. So a new chip would tide me over until I get the courage to order and assemble another programmer.)

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Re: Intermittent resets - only when pushing buttons

Post by adafruit »

when was your kit purchased?

tharlow
 
Posts: 2
Joined: Sun Feb 07, 2010 4:13 pm

Re: Intermittent resets - only when pushing buttons

Post by tharlow »

The only information I can find is:

Order Number: 39342
Date Ordered: Tuesday 20 October, 2009

(i.e., I can't find exactly when I received the kit... it was back-ordered and wildly popular :))

Locked
Please be positive and constructive with your questions and comments.

Return to “Clock Kits (discontinued)”