📄 spokepov.lss
字号:
5fe: 10 92 83 00 sts 0x0083, r1
602: 10 92 82 00 sts 0x0082, r1
606: 08 95 ret
00000608 <main>:
}
int main(void) {
608: cf ed ldi r28, 0xDF ; 223
60a: d0 e0 ldi r29, 0x00 ; 0
60c: de bf out 0x3e, r29 ; 62
60e: cd bf out 0x3d, r28 ; 61
uint8_t cmd; // the reason we reset
// MCUSR is the MCU Status Register (page 40). It tells us
// why we reset, and a reset is the only way to get here.
cmd = MCUSR;
610: 84 b7 in r24, 0x34 ; 52
// The first order of business is to tell the chip that
// we've got things under control.
MCUSR = 0;
612: 14 be out 0x34, r1 ; 52
// Turn on watchdog timer immediately, this protects against
// a 'stuck' system by resetting it.
// WDTCSR is the Watchdog Timer Control Register (page 45).
// We set it so that it'll generate a watchdog interrupt
// every second. The idea is that if things mess up,
// the watchdog will kickstart us.
WDTCSR = _BV(WDE) | _BV(WDP2) | _BV(WDP1); // 1 second
614: 8e e0 ldi r24, 0x0E ; 14
616: 81 bd out 0x21, r24 ; 33
// Initialize the various pins of the ATMEL, and set up
// the interrupts.
ioinit();
618: dc df rcall .-72 ; 0x5d2 <ioinit>
// Show that we are active.
set_all(~0x01);
61a: 8e ef ldi r24, 0xFE ; 254
61c: 0a de rcall .-1004 ; 0x232 <set_all>
// enable the interrupts. I think this is not needed
// since it'll immediately be done by the loop, below.
sei();
61e: 78 94 sei
// Loop until we timeout, at which point the ATMEL is
// put to sleep. If the communications routine timed
// out, or the user pressed the button for >500ms,
// then sensor_timer will be 0xFFFF and we'll immediately
// sleep.
// Change to for (;;) to see if it makes any difference
for (;;) {
// Reset the watchdog Timer.
//
// QUESTION: What's with toggling the PD0 output line here?
// it doesn't seem to be connected to anything according to
// the circuit diagram...
// *** PORTD |= 0x1;
asm("wdr");
620: a8 95 wdr
// *** PORTD &= ~0x1;
// If the sensor_timer (incremented by TIMER0) maxes out
// (in about 3 minutes), then sleep everything.
if (sensor_timer.bytes.high_byte == 0xFF) {
622: 80 91 83 00 lds r24, 0x0083
626: 8f 3f cpi r24, 0xFF ; 255
628: 71 f4 brne .+28 ; 0x646 <main+0x3e>
// Avoid pesky interruptions
cli();
62a: f8 94 cli
// Turn off all LEDs - I guess LED 0 is one of the "invisible ones"
set_all(0xFF);
62c: 02 de rcall .-1020 ; 0x232 <set_all>
// Turn off power to the Hall Effect sensor.
SENSOR_PORT &= ~_BV(SENSORPOWER);
62e: 96 98 cbi 0x12, 6 ; 18
// Deselect EEPROM
SPIEE_CS_PORT |= _BV(SPIEE_CS); // pull CS high to deselect
630: c4 9a sbi 0x18, 4 ; 24
// Turn off Watchdog (must be restarted when we get the wakeup)
// Wakeup will be via the button interrupt.
WDTCSR |= _BV(WDCE) | _BV(WDE);
632: 81 b5 in r24, 0x21 ; 33
634: 88 61 ori r24, 0x18 ; 24
636: 81 bd out 0x21, r24 ; 33
WDTCSR = 0;
638: 11 bc out 0x21, r1 ; 33
MCUCR |= _BV(SM1) | _BV(SM0) | _BV(SE);
63a: 85 b7 in r24, 0x35 ; 53
63c: 80 67 ori r24, 0x70 ; 112
63e: 85 bf out 0x35, r24 ; 53
// Re-enable interrupts so we can get the wakeup!
sei();
640: 78 94 sei
// Go into sleep mode
asm("sleep");
642: 88 95 sleep
644: ed cf rjmp .-38 ; 0x620 <main+0x18>
} else {
// Do we have dynamic updating to do?
#ifdef DYNAMIC
uint8_t tBytes; // Number of bytes to transfer
// Use unions to overlay variables and save some space
union {
char *fPtr; // from pointer
var16bit divisor; // the divisor for RPM
} a;
union {
char *tPtr; // to pointer
char *divTable; // divisor table
} b;
// Update the dynamic data display
switch (dynamicType & 0xF0) {
646: 80 91 7c 00 lds r24, 0x007C
64a: 99 27 eor r25, r25
64c: 80 7f andi r24, 0xF0 ; 240
64e: 90 70 andi r25, 0x00 ; 0
650: 80 32 cpi r24, 0x20 ; 32
652: 91 05 cpc r25, r1
654: 71 f0 breq .+28 ; 0x672 <main+0x6a>
656: 81 32 cpi r24, 0x21 ; 33
658: 91 05 cpc r25, r1
65a: 1c f4 brge .+6 ; 0x662 <main+0x5a>
65c: 40 97 sbiw r24, 0x10 ; 16
65e: 29 f0 breq .+10 ; 0x66a <main+0x62>
660: 6d c0 rjmp .+218 ; 0x73c <main+0x134>
662: c0 97 sbiw r24, 0x30 ; 48
664: 09 f4 brne .+2 ; 0x668 <main+0x60>
666: 66 c0 rjmp .+204 ; 0x734 <main+0x12c>
668: 69 c0 rjmp .+210 ; 0x73c <main+0x134>
#ifdef DYNAMIC_REVCOUNT // Rev counter compiled in?
case 0x10: // Rev counter
tBytes = 4; // number of bytes we'll move down below
66a: 94 e0 ldi r25, 0x04 ; 4
a.fPtr = (char *)dynamicREV;
66c: c3 e7 ldi r28, 0x73 ; 115
66e: d0 e0 ldi r29, 0x00 ; 0
break; // gets put into dynamicBuffer in reverse order.
670: 66 c0 rjmp .+204 ; 0x73e <main+0x136>
#endif
#ifdef DYNAMIC_RPM // RPM counter compiled in?
case 0x20:
// CODE NOT YET OPTIMIZED FOR SPACE.
// Initialize the RPM counter to 0
dynamicRPM[0]=dynamicRPM[1]=dynamicRPM[2] = '0';
672: 80 e3 ldi r24, 0x30 ; 48
674: 80 93 72 00 sts 0x0072, r24
678: 80 91 72 00 lds r24, 0x0072
67c: 80 93 71 00 sts 0x0071, r24
680: 80 91 71 00 lds r24, 0x0071
684: 80 93 70 00 sts 0x0070, r24
// Get a copy of the TIMER1 value that we need to divide 732 by
a.divisor.word = OCR1A;
688: ca b5 in r28, 0x2a ; 42
68a: db b5 in r29, 0x2b ; 43
// Start out pointing to the SECOND element of the div732 array.
// We need to set to the second one because the min value of the
// OCR1A hibyte (max speed) is 01, and we'll do at most 7 shifts
// before we see a bit. But there are 8 bits after that that
// might get looked at, so the div732 table must be 8 entries long.
// We also add 2 so that we are pointing at the last byte of each
// entry.
b.divTable = (char *)(div732+5); // 3 bytes per entry
68c: ab e2 ldi r26, 0x2B ; 43
68e: b0 e0 ldi r27, 0x00 ; 0
// Shift the divisor to the left and the divtable pointer to the
// right until the high bit of the divisor is set
while (a.divisor.bytes.high_byte < 0x80) {
a.divisor.word = a.divisor.word << 1;
b.divTable = b.divTable + 3;
690: d7 fd sbrc r29, 7
692: 04 c0 rjmp .+8 ; 0x69c <main+0x94>
694: cc 0f add r28, r28
696: dd 1f adc r29, r29
698: 13 96 adiw r26, 0x03 ; 3
69a: fa cf rjmp .-12 ; 0x690 <main+0x88>
}
// Once we have found the high bit, that tells us the fastest
// the device could possibly be rotating. Any other set bits in
// a.divisor mean that the RPM is lower. So what we do is clear
// the high bit and add in our partial sums only when the bits
// in the remainder are ** 0 **. Since we just cleared the
// high bit, it'll get counted. If all the bits are zero, all
// the sums will be added.
// NOTE: could be made smaller by using a.divisor.bytes.high_byte
// below, sacrificing a bit of accuracy at very high speeds.
a.divisor.word = a.divisor.word & 0x7FFF;
69c: df 77 andi r29, 0x7F ; 127
while (b.divTable > div732) {
if (a.divisor.bytes.high_byte < 0x80) {
// Add in the least significant bit. Since the table is actual
// byte values, we don't need to deal with an ascii conversion
dynamicRPM[0] = dynamicRPM[0] + pgm_read_byte(b.divTable--);
if (dynamicRPM[0] > '9') {
dynamicRPM[0] = dynamicRPM[0] - 10;
dynamicRPM[1]++;
}
// repeat for second byte...
dynamicRPM[1] = dynamicRPM[1] + pgm_read_byte(b.divTable--);
if (dynamicRPM[1] > '9') {
dynamicRPM[1] = dynamicRPM[1] - 10;
dynamicRPM[2]++;
}
// and for third, but no carry needed this time
dynamicRPM[2] = dynamicRPM[2] + pgm_read_byte(b.divTable--);
// At this point, we've already subtracted 3 from b.divTable, so we're
// ready to go for the next loop.
} else {
// But if we didn't add anything in, we need to shift b.divTable
b.divTable = b.divTable - 3;
}
// And finally move to the next bit
a.divisor.word = a.divisor.word << 1;
69e: 80 e0 ldi r24, 0x00 ; 0
6a0: a6 32 cpi r26, 0x26 ; 38
6a2: b8 07 cpc r27, r24
6a4: 09 f0 breq .+2 ; 0x6a8 <main+0xa0>
6a6: 08 f4 brcc .+2 ; 0x6aa <main+0xa2>
6a8: 41 c0 rjmp .+130 ; 0x72c <main+0x124>
6aa: d7 fd sbrc r29, 7
6ac: 3b c0 rjmp .+118 ; 0x724 <main+0x11c>
6ae: fb 2f mov r31, r27
6b0: ea 2f mov r30, r26
6b2: 11 97 sbiw r26, 0x01 ; 1
6b4: c8 95 lpm
6b6: 90 2d mov r25, r0
6b8: 80 91 70 00 lds r24, 0x0070
6bc: 89 0f add r24, r25
6be: 80 93 70 00 sts 0x0070, r24
6c2: 80 91 70 00 lds r24, 0x0070
6c6: 8a 33 cpi r24, 0x3A ; 58
6c8: 50 f0 brcs .+20 ; 0x6de <main+0xd6>
6ca: 80 91 70 00 lds r24, 0x0070
6ce: 8a 50 subi r24, 0x0A ; 10
6d0: 80 93 70 00 sts 0x0070, r24
6d4: 80 91 71 00 lds r24, 0x0071
6d8: 8f 5f subi r24, 0xFF ; 255
6da: 80 93 71 00 sts 0x0071, r24
6de: fb 2f mov r31, r27
6e0: ea 2f mov r30, r26
6e2: 11 97 sbiw r26, 0x01 ; 1
6e4: c8 95 lpm
6e6: 90 2d mov r25, r0
6e8: 80 91 71 00 lds r24, 0x0071
6ec: 89 0f add r24, r25
6ee: 80 93 71 00 sts 0x0071, r24
6f2: 80 91 71 00 lds r24, 0x0071
6f6: 8a 33 cpi r24, 0x3A ; 58
6f8: 50 f0 brcs .+20 ; 0x70e <main+0x106>
6fa: 80 91 71 00 lds r24, 0x0071
6fe: 8a 50 subi r24, 0x0A ; 10
700: 80 93 71 00 sts 0x0071, r24
704: 80 91 72 00 lds r24, 0x0072
708: 8f 5f subi r24, 0xFF ; 255
70a: 80 93 72 00 sts 0x0072, r24
70e: fb 2f mov r31, r27
710: ea 2f mov r30, r26
712: 11 97 sbiw r26, 0x01 ; 1
714: c8 95 lpm
716: 90 2d mov r25, r0
718: 80 91 72 00 lds r24, 0x0072
71c: 89 0f add r24, r25
71e: 80 93 72 00 sts 0x0072, r24
722: 01 c0 rjmp .+2 ; 0x726 <main+0x11e>
724: 13 97 sbiw r26, 0x03 ; 3
726: cc 0f add r28, r28
728: dd 1f adc r29, r29
72a: b9 cf rjmp .-142 ; 0x69e <main+0x96>
}
// And when that's all done, we just set up for the move
tBytes = 3;
72c: 93 e0 ldi r25, 0x03 ; 3
a.fPtr = (char *)dynamicRPM;
72e: c0 e7 ldi r28, 0x70 ; 112
730: d0 e0 ldi r29, 0x00 ; 0
break;
732: 05 c0 rjmp .+10 ; 0x73e <main+0x136>
#endif
#ifdef DYNAMIC_TIME // Clock compiled in?
case 0x30: // Rev counter
tBytes = 8; // number of bytes we'll move down below
734: 98 e0 ldi r25, 0x08 ; 8
a.fPtr = (char *)dynamicTime;
736: c8 e6 ldi r28, 0x68 ; 104
738: d0 e0 ldi r29, 0x00 ; 0
break; // gets put into dynamicBuffer in reverse order.
73a: 01 c0 rjmp .+2 ; 0x73e <main+0x136>
#endif
default: // This will get executed if no dynamic data
tBytes = 0x00; // and will clear things.
73c: 90 e0 ldi r25, 0x00 ; 0
}
// If we have bytes to transfer, and if the dynamic display
// is still active, then transfer the bytes into the display
cli();
73e: f8 94 cli
if ( (dynamicType != 0x00) && (tBytes != 0x00) ) {
740: 80 91 7c 00 lds r24, 0x007C
744: 88 23 and r24, r24
746: 59 f0 breq .+22 ; 0x75e <main+0x156>
748: 99 23 and r25, r25
74a: 49 f0 breq .+18 ; 0x75e <main+0x156>
b.tPtr = (char *)dynamicPtr; // we now know dynamicPtr is valid
74c: a0 91 7d 00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -