📄 spokepov.lss
字号:
spokepov.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000074a 00000000 00000000 00000094 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 0000000c 00800060 0000074a 000007de 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000044 0080006c 0080006c 000007ea 2**0
ALLOC
3 .noinit 00000000 008000b0 008000b0 000007ea 2**0
CONTENTS
4 .eeprom 00000000 00810000 00810000 000007ea 2**0
CONTENTS
5 .stab 00000354 00000000 00000000 000007ec 2**2
CONTENTS, READONLY, DEBUGGING
6 .stabstr 00000084 00000000 00000000 00000b40 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_aranges 00000028 00000000 00000000 00000bc4 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_pubnames 000001f3 00000000 00000000 00000bec 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_info 00000748 00000000 00000000 00000ddf 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_abbrev 000001f6 00000000 00000000 00001527 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_line 000005cf 00000000 00000000 0000171d 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_str 0000028b 00000000 00000000 00001cec 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__vectors>:
0: 49 c0 rjmp .+146 ; 0x94 <__init>
2: 63 c1 rjmp .+710 ; 0x2ca <__vector_1>
4: 7c c1 rjmp .+760 ; 0x2fe <__vector_2>
6: 5f c0 rjmp .+190 ; 0xc6 <__bad_interrupt>
8: b6 c0 rjmp .+364 ; 0x176 <__vector_4>
a: 5d c0 rjmp .+186 ; 0xc6 <__bad_interrupt>
c: 84 c0 rjmp .+264 ; 0x116 <__vector_6>
e: 5b c0 rjmp .+182 ; 0xc6 <__bad_interrupt>
10: 5a c0 rjmp .+180 ; 0xc6 <__bad_interrupt>
12: 59 c0 rjmp .+178 ; 0xc6 <__bad_interrupt>
14: 58 c0 rjmp .+176 ; 0xc6 <__bad_interrupt>
16: 57 c0 rjmp .+174 ; 0xc6 <__bad_interrupt>
18: 56 c0 rjmp .+172 ; 0xc6 <__bad_interrupt>
1a: 55 c0 rjmp .+170 ; 0xc6 <__bad_interrupt>
1c: 54 c0 rjmp .+168 ; 0xc6 <__bad_interrupt>
1e: 53 c0 rjmp .+166 ; 0xc6 <__bad_interrupt>
20: 52 c0 rjmp .+164 ; 0xc6 <__bad_interrupt>
22: 51 c0 rjmp .+162 ; 0xc6 <__bad_interrupt>
24: 50 c0 rjmp .+160 ; 0xc6 <__bad_interrupt>
00000026 <__ctors_end>:
26: 00 00 nop
28: 01 00 .word 0x0001 ; ????
2a: 00 03 mulsu r16, r16
2c: 00 00 nop
2e: 05 00 .word 0x0005 ; ????
30: 01 01 movw r0, r2
32: 00 02 muls r16, r16
34: 02 00 .word 0x0002 ; ????
36: 04 03 mulsu r16, r20
38: 00 08 sbc r0, r0
3a: 06 01 movw r0, r12
3c: 07 03 mulsu r16, r23
3e: 03 04 cpc r0, r3
40: 05 00 .word 0x0005 ; ????
00000042 <dInfo>:
42: 00 00 2a 00 00 1b 00 00 ..*.....
0000004a <lines>:
4a: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
5a: 20 20 20 20 53 70 6f 6b 65 50 4f 56 20 20 20 20 SpokePOV
6a: 20 20 20 20 52 50 4d 3a 30 30 30 30 20 20 20 20 RPM:0000
7a: 20 20 20 20 52 45 56 3a 30 30 30 30 20 20 20 20 REV:0000
...
0000008b <lineOffsets>:
8b: 00 10 20 00 00 30 00 10 00 .. ..0...
00000094 <__init>:
94: 11 24 eor r1, r1
96: 1f be out 0x3f, r1 ; 63
98: cf ed ldi r28, 0xDF ; 223
9a: cd bf out 0x3d, r28 ; 61
0000009c <__do_copy_data>:
9c: 10 e0 ldi r17, 0x00 ; 0
9e: a0 e6 ldi r26, 0x60 ; 96
a0: b0 e0 ldi r27, 0x00 ; 0
a2: ea e4 ldi r30, 0x4A ; 74
a4: f7 e0 ldi r31, 0x07 ; 7
a6: 03 c0 rjmp .+6 ; 0xae <.do_copy_data_start>
000000a8 <.do_copy_data_loop>:
a8: c8 95 lpm
aa: 31 96 adiw r30, 0x01 ; 1
ac: 0d 92 st X+, r0
000000ae <.do_copy_data_start>:
ae: ac 36 cpi r26, 0x6C ; 108
b0: b1 07 cpc r27, r17
b2: d1 f7 brne .-12 ; 0xa8 <.do_copy_data_loop>
000000b4 <__do_clear_bss>:
b4: 10 e0 ldi r17, 0x00 ; 0
b6: ac e6 ldi r26, 0x6C ; 108
b8: b0 e0 ldi r27, 0x00 ; 0
ba: 01 c0 rjmp .+2 ; 0xbe <.do_clear_bss_start>
000000bc <.do_clear_bss_loop>:
bc: 1d 92 st X+, r1
000000be <.do_clear_bss_start>:
be: a0 3b cpi r26, 0xB0 ; 176
c0: b1 07 cpc r27, r17
c2: e1 f7 brne .-8 ; 0xbc <.do_clear_bss_loop>
c4: 56 c2 rjmp .+1196 ; 0x572 <main>
000000c6 <__bad_interrupt>:
c6: 9c cf rjmp .-200 ; 0x0 <__vectors>
000000c8 <clock_scroll>:
// Sends 4 bytes + sCount extra bits over the serial link
// to implement smooth scrolling. Can be used with a 0
// parameter to just send out the regular 4 bytes.
void clock_scroll(uint8_t sCount) {
c8: cf 93 push r28
ca: c8 2f mov r28, r24
// First, send the basic 4 bytes, they go no matter what
spi_transfer(fleds[0]);
cc: 80 91 8a 00 lds r24, 0x008A
d0: 00 d3 rcall .+1536 ; 0x6d2 <spi_transfer>
spi_transfer(fleds[1]);
d2: 80 91 8b 00 lds r24, 0x008B
d6: fd d2 rcall .+1530 ; 0x6d2 <spi_transfer>
spi_transfer(fleds[2]);
d8: 80 91 8c 00 lds r24, 0x008C
dc: fa d2 rcall .+1524 ; 0x6d2 <spi_transfer>
spi_transfer(fleds[3]);
de: 80 91 8d 00 lds r24, 0x008D
e2: f7 d2 rcall .+1518 ; 0x6d2 <spi_transfer>
// If there is anything to do..
if (sCount != 0) {
e4: cc 23 and r28, r28
e6: 79 f0 breq .+30 ; 0x106 <__stack+0x27>
// If we have < 8 bits to transfer
if (sCount < 8) {
e8: c8 30 cpi r28, 0x08 ; 8
ea: 20 f4 brcc .+8 ; 0xf4 <__stack+0x15>
// Then that is all that we need to do
spi_transfer_n(fleds[4],sCount);
ec: 6c 2f mov r22, r28
ee: 80 91 8e 00 lds r24, 0x008E
f2: 08 c0 rjmp .+16 ; 0x104 <__stack+0x25>
} else {
// First latch out the full first 8 bits
spi_transfer(fleds[4]);
f4: 80 91 8e 00 lds r24, 0x008E
f8: ec d2 rcall .+1496 ; 0x6d2 <spi_transfer>
// How many bits left to do?
sCount = sCount - 8;
fa: c8 50 subi r28, 0x08 ; 8
if (sCount != 0) {
fc: 21 f0 breq .+8 ; 0x106 <__stack+0x27>
spi_transfer_n(fleds[5],sCount);
fe: 6c 2f mov r22, r28
100: 80 91 8f 00 lds r24, 0x008F
104: d8 d2 rcall .+1456 ; 0x6b6 <spi_transfer_n>
}
}
}
// finally, latch the bits into the LEDS
LATCH_SELECT_PORT |= _BV(FRONT);
106: 94 9a sbi 0x12, 4 ; 18
...
NOP; NOP; NOP; NOP;
LATCH_SELECT_PORT &= ~_BV(FRONT);
110: 94 98 cbi 0x12, 4 ; 18
112: cf 91 pop r28
114: 08 95 ret
00000116 <__vector_6>:
}
// TIMER0 interrupt handler. This runs about every 8ms
// AFAICT. It increments the hall_debounce and sensor_timer
// values until they pin.
// QUESTION: what's with the setting and clearing of PORTB0?
// According to the wiring diagram, it isn't connected to
// anything. Is this vestigial code from when you were using
// Pin Change Interrupts? Or is it debugger code so you
// can monitor the pins and tell when something happens.
SIGNAL (SIG_TIMER0_OVF) {
116: 1f 92 push r1
118: 0f 92 push r0
11a: 0f b6 in r0, 0x3f ; 63
11c: 0f 92 push r0
11e: 11 24 eor r1, r1
120: 8f 93 push r24
122: 9f 93 push r25
// *** PORTB |= 0x1;
// Let hall_debounce just wrap around. At worst it'll just
// mess things up for one of the initial speedup rotations
// of the blade...
// if (hall_debounce != 0xFF)
hall_debounce++;
124: 80 91 87 00 lds r24, 0x0087
128: 8f 5f subi r24, 0xFF ; 255
12a: 80 93 87 00 sts 0x0087, r24
if (sensor_timer.bytes.high_byte != 0xFF)
12e: 80 91 89 00 lds r24, 0x0089
132: 8f 3f cpi r24, 0xFF ; 255
134: 49 f0 breq .+18 ; 0x148 <__vector_6+0x32>
sensor_timer.word++;
136: 80 91 88 00 lds r24, 0x0088
13a: 90 91 89 00 lds r25, 0x0089
13e: 01 96 adiw r24, 0x01 ; 1
140: 90 93 89 00 sts 0x0089, r25
144: 80 93 88 00 sts 0x0088, r24
#if NUM_LINES > 0
// Increment the line timer - we only need to do this
// if we are scrolling
line_timer++; // increment the low byte
148: 80 91 62 00 lds r24, 0x0062
14c: 8f 5f subi r24, 0xFF ; 255
14e: 80 93 62 00 sts 0x0062, r24
152: 9f 91 pop r25
154: 8f 91 pop r24
156: 0f 90 pop r0
158: 0f be out 0x3f, r0 ; 63
15a: 0f 90 pop r0
15c: 1f 90 pop r1
15e: 18 95 reti
00000160 <set_all>:
#endif
// *** PORTB &= ~0x1;
}
// Hack - I used to copy the topChar, etc. variables into local
// variables in the TIMER1 routine, but I am running out of stack space. So instead
// I'm going to keep interrupts off during this routine and
// use the regular versions. To make it easy to do this I'm
// remapping the local variables with defines.
// #define USE_LOCAL_TIMER1 1
// If USE_LOCAL_TIMER1 is not defined, then the TIMER1 routine will not
// enable interrupts.
// As we sweep around the circle, we display 256 radial pixel
// lines, once per TIMER1 interrupt. This is broken down into
// 16 16-pixel wide characters, and we have two characters
// stacked vertically. To save time, we keep track of the
// character number, pixel number (in the character), and
// pointers into the eeprom for each of the two chars being
// displayed.
// This code has to be fast enough to complete execution before
// it gets interrupted again - and it must not make any subroutine
// calls, since that'll mess up the stack and cause the entire
// system to reset.
volatile uint16_t topChar = 0; // top character being displayed (address in EEPROM of data)
volatile uint16_t botChar = 0; // bottom character being displayed
volatile uint8_t charNum = 0; // character number
volatile uint8_t pixelNum = 0; // pixel number
#ifdef USE_LOCAL_TIMER1
volatile uint8_t clean = 0; // have these values been changed outside TIMER1?
#endif
#ifdef SMOOTHSCROLL
volatile uint16_t scrollChar = 0; // extra scroll character
#endif
// This routine gets called every time the pixel timer runs down;
// in other words, once per "scan line", 256 times per revolution
// of the SpokePOV. Its purpose is to update the LEDs.
SIGNAL (SIG_TIMER1_COMPA) {
#ifdef USE_LOCALUSE_LOCAL_TIMER1
uint16_t tChar; // local copies of the values
uint16_t bChar;
uint8_t cNum;
uint8_t pNum;
#ifdef SMOOTHSCROLL
uint16_t sChar; // extra scroll character
#endif
// When an interrupt routine is called, interrupts are disabled.
// but it's important to let other interrupts interrupt us, so
// they need to be re-enabled.
sei();
// Copy the volatile variables into their local equivalents
tChar = topChar;
bChar = botChar;
cNum = charNum;
pNum = pixelNum;
#ifdef SMOOTHSCROLL
sChar = scrollChar;
#endif
#else
#define tChar topChar
#define bChar botChar
#define cNum charNum
#define pNum pixelNum
#define sChar scrollChar
#endif
// If it has been less than STANDBY_TIMEOUT seconds since the last time we
// got a Hall Effect sensor update, then proceed as normal and
// update the LEDs.
// QUESTION: what is F_CPU? ANSWER: FREQUENCY OF CPU (clocks/second)
if (sensor_timer.bytes.high_byte < ( (F_CPU/NUM_PIXELS)/256 * STANDBY_TIMEOUT) / 256) {
// *** PORTA |= 0x1;
// The first thing we do is increment our character position; this
// is done here to avoid code duplication. This means that the
// Hall Effect interrupt routine must set them up so they "wrap"
// into the first valid values.
// Move to the next pixel in the character
pNum++;
// If we have moved off the edge of the character, then
// we need to move to the next character
if (pNum == 16) {
// If we will wrap around to the first character, turn off the pixel
// timer, clear the display, and exit. Might speed things up a bit
if (cNum == 15) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -