Skip to content

Instantly share code, notes, and snippets.

@MrTrick
Created December 10, 2012 13:49
Show Gist options
  • Save MrTrick/4250652 to your computer and use it in GitHub Desktop.
Save MrTrick/4250652 to your computer and use it in GitHub Desktop.
Dodgy ticker This very frustrating Heisenbug is incrementing the clock twice as fast as it should, except when I put in debugging code or try to step through it with the in-circuit debugger. I've managed to reliably reproduce the buggy behaviour: * B increments the minute_hand variable every 10 seconds, as it's supposed to. (period shortened for…
#define TICK_vect TIMER2_OVF_vect
/**
Initialises Timer 2 to use an external 32.768 kHz crystal.
Timer 2 is configured to generate an interrupt once a second,
that the program may catch and interpret.
*/
void tick_init(void)
{
//Disable any existing interrupts (OCIE2x and TOIE2)
TIMSK2 = 0;
//Select clock source by setting AS2 as appropriate.
ASSR |= 1<<AS2;
//Write new values to TCNT2, OCR2x, and TCCR2x
TCCR2A = (0<<COM2A1)|(0<<COM2B1)|(0<<WGM21)|(0<<WGM20); //Normal operation
TCCR2B = (0<<FOC2A)|(0<<FOC2B)|(0<<WGM22)|(1<<CS22)|(0<<CS21)|(1<<CS20); //Normal operation, with 1/128 prescaling
//Wait for the values to 'stick'
while (ASSR&((1<<TCN2UB)|(1<<TCR2AUB)|(1<<TCR2BUB))) { ; }
//Clear the Timer/Counter2 Interrupt Flags.
TIFR2 |= 1<<TOV2; //Set to clear it? Go figure...
//Enable the overflow interrupt.
TIMSK2 |= 1<<TOIE2;
}
//This code is called every second.
//It should increment the minute_hand variable every 10 seconds and update which LED is lit.
//It's incrementing minute_hand and updating the LED every FIVE seconds.
// volatile unsigned char minute_hand;
// volatile unsigned char hour_hand;
// volatile unsigned short seconds;
/**
* TICK! Once every second, regardless of anything else that happens.
* (Even while sleeping)
*/
ISR(TICK_vect) {
//charlie_off();
//charlie_on(seconds%10);
seconds++;
if (seconds == 10) {
seconds = 0;
if (++minute_hand >= 12) { minute_hand = 0; if (++hour_hand >= 12) hour_hand = 0; }
charlie_off();
charlie_on(minute_hand);
}
}
/**
* TICK! Once every second, regardless of anything else that happens.
* (Even while sleeping)
*/
ISR(TICK_vect) {
252: 1f 92 push r1
254: 0f 92 push r0
256: 0f b6 in r0, 0x3f ; 63
258: 0f 92 push r0
25a: 11 24 eor r1, r1
25c: 2f 93 push r18
25e: 8f 93 push r24
260: 9f 93 push r25
262: ef 93 push r30
264: ff 93 push r31
//charlie_off();
//charlie_on(seconds%10);
seconds++;
266: 80 91 28 01 lds r24, 0x0128
26a: 90 91 29 01 lds r25, 0x0129
26e: 01 96 adiw r24, 0x01 ; 1
270: 90 93 29 01 sts 0x0129, r25
274: 80 93 28 01 sts 0x0128, r24
if (seconds == 10) {
278: 80 91 28 01 lds r24, 0x0128
27c: 90 91 29 01 lds r25, 0x0129
280: 8a 30 cpi r24, 0x0A ; 10
282: 91 05 cpc r25, r1
284: 29 f5 brne .+74 ; 0x2d0 <__vector_9+0x7e>
seconds = 0;
286: 10 92 29 01 sts 0x0129, r1
28a: 10 92 28 01 sts 0x0128, r1
if (++minute_hand >= 12) { minute_hand = 0; if (++hour_hand >= 12) hour_hand = 0; }
28e: 80 91 25 01 lds r24, 0x0125
292: 8f 5f subi r24, 0xFF ; 255
294: 80 93 25 01 sts 0x0125, r24
298: 8c 30 cpi r24, 0x0C ; 12
29a: 58 f0 brcs .+22 ; 0x2b2 <__vector_9+0x60>
29c: 10 92 25 01 sts 0x0125, r1
2a0: 80 91 2a 01 lds r24, 0x012A
2a4: 8f 5f subi r24, 0xFF ; 255
2a6: 80 93 2a 01 sts 0x012A, r24
2aa: 8c 30 cpi r24, 0x0C ; 12
2ac: 10 f0 brcs .+4 ; 0x2b2 <__vector_9+0x60>
2ae: 10 92 2a 01 sts 0x012A, r1
/**
* Switch off all LEDs
*/
inline void charlie_off() {
LED_PORT = 0x00;
2b2: 18 b8 out 0x08, r1 ; 8
LED_DIR = 0x00;
2b4: 17 b8 out 0x07, r1 ; 7
charlie_off();
charlie_on(minute_hand);
2b6: 80 91 25 01 lds r24, 0x0125
/**
* Light a given LED
* @param char c The number of the LED to be lit; 0==12
*/
inline void charlie_on(unsigned char c) {
LED_PORT = charlie_ports[c];
2ba: 90 e0 ldi r25, 0x00 ; 0
2bc: fc 01 movw r30, r24
2be: e4 5f subi r30, 0xF4 ; 244
2c0: fe 4f sbci r31, 0xFE ; 254
2c2: 20 81 ld r18, Z
2c4: 28 b9 out 0x08, r18 ; 8
LED_DIR = charlie_dirs[c];
2c6: 80 50 subi r24, 0x00 ; 0
2c8: 9f 4f sbci r25, 0xFF ; 255
2ca: fc 01 movw r30, r24
2cc: 80 81 ld r24, Z
2ce: 87 b9 out 0x07, r24 ; 7
}
}
2d0: ff 91 pop r31
2d2: ef 91 pop r30
2d4: 9f 91 pop r25
2d6: 8f 91 pop r24
2d8: 2f 91 pop r18
2da: 0f 90 pop r0
2dc: 0f be out 0x3f, r0 ; 63
2de: 0f 90 pop r0
2e0: 1f 90 pop r1
2e2: 18 95 reti
*(COMMON)
COMMON 0x00800125 0x6 buzz_watch_v0.5.o
0x00800125 minute_hand
0x00800126 action
0x00800128 seconds
0x0080012a hour_hand
0x0080012b PROVIDE (__bss_end, .)
0x00000490 __data_load_start = LOADADDR (.data)
0x000004b4 __data_load_end = (__data_load_start + SIZEOF (.data))
//This code is called every second.
//It's the *same* as ISR A, except that the first two lines are uncommented.
//It lights the LED as each second passes, and on the overflow lights the minute.
//It's working properly, it increments minute_hand every TEN seconds.
// volatile unsigned char minute_hand;
// volatile unsigned char hour_hand;
// volatile unsigned short seconds;
/**
* TICK! Once every second, regardless of anything else that happens.
* (Even while sleeping)
*/
ISR(TICK_vect) {
charlie_off();
charlie_on(seconds%10);
seconds++;
if (seconds == 10) {
seconds = 0;
if (++minute_hand >= 12) { minute_hand = 0; if (++hour_hand >= 12) hour_hand = 0; }
charlie_off();
charlie_on(minute_hand);
}
}
/**
* TICK! Once every second, regardless of anything else that happens.
* (Even while sleeping)
*/
ISR(TICK_vect) {
252: 1f 92 push r1
254: 0f 92 push r0
256: 0f b6 in r0, 0x3f ; 63
258: 0f 92 push r0
25a: 11 24 eor r1, r1
25c: 2f 93 push r18
25e: 5f 93 push r21
260: 6f 93 push r22
262: 7f 93 push r23
264: 8f 93 push r24
266: 9f 93 push r25
268: af 93 push r26
26a: bf 93 push r27
26c: ef 93 push r30
26e: ff 93 push r31
/**
* Switch off all LEDs
*/
inline void charlie_off() {
LED_PORT = 0x00;
270: 18 b8 out 0x08, r1 ; 8
LED_DIR = 0x00;
272: 17 b8 out 0x07, r1 ; 7
charlie_off();
charlie_on(seconds%10);
274: 80 91 28 01 lds r24, 0x0128
278: 90 91 29 01 lds r25, 0x0129
/**
* Light a given LED
* @param char c The number of the LED to be lit; 0==12
*/
inline void charlie_on(unsigned char c) {
LED_PORT = charlie_ports[c];
27c: 6a e0 ldi r22, 0x0A ; 10
27e: 70 e0 ldi r23, 0x00 ; 0
280: 0e 94 64 02 call 0x4c8 ; 0x4c8 <__udivmodhi4>
284: fc 01 movw r30, r24
286: e4 5f subi r30, 0xF4 ; 244
288: fe 4f sbci r31, 0xFE ; 254
28a: 20 81 ld r18, Z
28c: 28 b9 out 0x08, r18 ; 8
LED_DIR = charlie_dirs[c];
28e: 80 50 subi r24, 0x00 ; 0
290: 9f 4f sbci r25, 0xFF ; 255
292: fc 01 movw r30, r24
294: 80 81 ld r24, Z
296: 87 b9 out 0x07, r24 ; 7
seconds++;
298: 80 91 28 01 lds r24, 0x0128
29c: 90 91 29 01 lds r25, 0x0129
2a0: 01 96 adiw r24, 0x01 ; 1
2a2: 90 93 29 01 sts 0x0129, r25
2a6: 80 93 28 01 sts 0x0128, r24
if (seconds == 10) {
2aa: 80 91 28 01 lds r24, 0x0128
2ae: 90 91 29 01 lds r25, 0x0129
2b2: 8a 30 cpi r24, 0x0A ; 10
2b4: 91 05 cpc r25, r1
2b6: 29 f5 brne .+74 ; 0x302 <__vector_9+0xb0>
seconds = 0;
2b8: 10 92 29 01 sts 0x0129, r1
2bc: 10 92 28 01 sts 0x0128, r1
if (++minute_hand >= 12) { minute_hand = 0; if (++hour_hand >= 12) hour_hand = 0; }
2c0: 80 91 25 01 lds r24, 0x0125
2c4: 8f 5f subi r24, 0xFF ; 255
2c6: 80 93 25 01 sts 0x0125, r24
2ca: 8c 30 cpi r24, 0x0C ; 12
2cc: 58 f0 brcs .+22 ; 0x2e4 <__vector_9+0x92>
2ce: 10 92 25 01 sts 0x0125, r1
2d2: 80 91 2a 01 lds r24, 0x012A
2d6: 8f 5f subi r24, 0xFF ; 255
2d8: 80 93 2a 01 sts 0x012A, r24
2dc: 8c 30 cpi r24, 0x0C ; 12
2de: 10 f0 brcs .+4 ; 0x2e4 <__vector_9+0x92>
2e0: 10 92 2a 01 sts 0x012A, r1
/**
* Switch off all LEDs
*/
inline void charlie_off() {
LED_PORT = 0x00;
2e4: 18 b8 out 0x08, r1 ; 8
LED_DIR = 0x00;
2e6: 17 b8 out 0x07, r1 ; 7
charlie_off();
charlie_on(minute_hand);
2e8: 80 91 25 01 lds r24, 0x0125
/**
* Light a given LED
* @param char c The number of the LED to be lit; 0==12
*/
inline void charlie_on(unsigned char c) {
LED_PORT = charlie_ports[c];
2ec: 90 e0 ldi r25, 0x00 ; 0
2ee: fc 01 movw r30, r24
2f0: e4 5f subi r30, 0xF4 ; 244
2f2: fe 4f sbci r31, 0xFE ; 254
2f4: 20 81 ld r18, Z
2f6: 28 b9 out 0x08, r18 ; 8
LED_DIR = charlie_dirs[c];
2f8: 80 50 subi r24, 0x00 ; 0
2fa: 9f 4f sbci r25, 0xFF ; 255
2fc: fc 01 movw r30, r24
2fe: 80 81 ld r24, Z
300: 87 b9 out 0x07, r24 ; 7
}
}
302: ff 91 pop r31
304: ef 91 pop r30
306: bf 91 pop r27
308: af 91 pop r26
30a: 9f 91 pop r25
30c: 8f 91 pop r24
30e: 7f 91 pop r23
310: 6f 91 pop r22
312: 5f 91 pop r21
314: 2f 91 pop r18
316: 0f 90 pop r0
318: 0f be out 0x3f, r0 ; 63
31a: 0f 90 pop r0
31c: 1f 90 pop r1
31e: 18 95 reti
*(COMMON)
COMMON 0x00800125 0x6 buzz_watch_v0.5.o
0x00800125 minute_hand
0x00800126 action
0x00800128 seconds
0x0080012a hour_hand
0x0080012b PROVIDE (__bss_end, .)
0x000004f4 __data_load_start = LOADADDR (.data)
0x00000518 __data_load_end = (__data_load_start + SIZEOF (.data))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment