Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

Intermittent resets - only when pushing buttons
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Re: Intermittent resets - only when pushing buttons

by madworm_de on Wed Oct 21, 2009 12:51 pm

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.
NO LARDO CHIPS
madworm_de
 
Posts: 99
Joined: Mon Jun 09, 2008 6:56 am

Re: Intermittent resets - only when pushing buttons

by caitsith2 on Wed Oct 21, 2009 5:37 pm

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.

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

Re: Intermittent resets - only when pushing buttons

by mike31416 on Wed Oct 21, 2009 7:07 pm

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?

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

Re: Intermittent resets - only when pushing buttons

by mike31416 on Wed Oct 21, 2009 8:31 pm

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 caitsith2 describes. I'll try his fix tonight...

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

Re: Intermittent resets - only when pushing buttons

by madworm_de on Thu Oct 22, 2009 12:14 pm

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.
NO LARDO CHIPS
madworm_de
 
Posts: 99
Joined: Mon Jun 09, 2008 6:56 am

Re: Intermittent resets - only when pushing buttons

by mike31416 on Thu Oct 22, 2009 7:05 pm

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

Many thanks to caitsith2!

Mike

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

Re: Intermittent resets - only when pushing buttons

by caitsith2 on Thu Oct 22, 2009 9:04 pm

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.

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

Re: Intermittent resets - only when pushing buttons

by adafruit on Sat Oct 24, 2009 1:22 pm

caitsith 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)

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

Re: Intermittent resets - only when pushing buttons

by joerg_daehn on Fri Nov 06, 2009 12:59 pm

caitsith2 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

joerg_daehn
 
Posts: 30
Joined: Tue Oct 13, 2009 6:39 pm
Location: Hannover, Germany

Re: Intermittent resets - only when pushing buttons

by adafruit on Fri Nov 06, 2009 2:31 pm

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

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

Re: Intermittent resets - only when pushing buttons

by jsgf on Fri Nov 06, 2009 3:30 pm

Note that caitsith2'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 | TOGGLE FULL SIZE
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)) {
Advanced IceTubeClock Firmware download Source Git Wiki
jsgf
 
Posts: 61
Joined: Mon Oct 26, 2009 1:21 am

Re: Intermittent resets - only when pushing buttons

by joerg_daehn on Sat Nov 07, 2009 3:04 pm

@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

joerg_daehn
 
Posts: 30
Joined: Tue Oct 13, 2009 6:39 pm
Location: Hannover, Germany

Re: Intermittent resets - only when pushing buttons

by tharlow on Wed Feb 24, 2010 3:14 am

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.)
tharlow
 
Posts: 2
Joined: Sun Feb 07, 2010 4:13 pm

Re: Intermittent resets - only when pushing buttons

by adafruit on Wed Feb 24, 2010 11:45 am

when was your kit purchased?

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

Re: Intermittent resets - only when pushing buttons

by tharlow on Wed Feb 24, 2010 3:22 pm

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 :))
tharlow
 
Posts: 2
Joined: Sun Feb 07, 2010 4:13 pm

Please be positive and constructive with your questions and comments.