📄 spokepov.lss
字号:
}
}
#else
// we could do this just once when the app initializes, but
// for now, let's do it here. Later we'll move it.
// Note that when there are only two lines, there is no
// need for the lineOffset array, and it is not used.
cur_line = line_shift = 0;
memcpy_P(topLine,lines,16);
memcpy_P(botLine,lines+16,16);
#ifdef DYNAMIC
dCode = pgm_read_byte(dInfo);
if (dCode != 0) {
dynamicPtr = topLine + (dCode & 0x0F);
dynamicType = dCode;
}
dCode = pgm_read_byte(dInfo+1);
if (dCode != 0) {
dynamicPtr = botLine + (dCode & 0x0F);
dynamicType = dCode;
}
#endif
#endif
// Set the character and pixel numbers so they will overflow
// on the next pixel interrupt, and cause the correct data to
// be loaded.
charNum = 31; // will wrap to 0, the first char. Not set to 15 as you might
// expect, because when it hits 15 again, the pixel output
// routine will shut down. But (31+1) mod 16 = (15+1) mod 16...
pixelNum = 15; // will wrap to 0, the first pixel
#ifdef USE_LOCAL_TIMER1
clean = 0; // flag that we changed things
#endif
// Start TIMER1 on its merry way...
TCCR1B |= _BV(CS10); // increment at clock/1
TIMSK |= _BV(OCIE1A); // enable interrupt when it matches OCR1A
} else {
// Since we don't have a valid setting for the rotation
// speed, set a couple of LEDs to let the human know we
// aren't dead yet, and turn off the timer.
set_all(~0x03);
TCCR1B &= ~_BV(CS10); // no incrementing = no interrupting
// reset the line timers so that when we get a valid spinup,
// they will start clocking the lines across the display
line_timer = SCROLLSPEED; // delay figure, will trigger wrap
line_shift = 0x0f; // subcharacter shift, will trigger wrap
cur_line = 0xff; // will wrap to first line
}
// Whether we're displaying or not, we reset sensor_timer so we can
// time the next revolution.
sensor_timer.word = 0;
}
// Finally, reset hall_debounce so we won't execute the timer reset code
// until the Hall Effect sensor hasn't bothered us for a reasonable while.
hall_debounce = 0;
// *** PORTB &= ~0x8;
}
// Initialize the IO pins on the ATMEL.
void ioinit(void) {
// Set the data direction for the PORTD and PORTB pins; see the
// circuit diagram for more information on this.
DDRD = 0x73; // input on PD2 (button), PD3 (sensor), all other output
DDRB = 0xDF; // input on MOSI/DI (for SPI), all others output
// Deselect EEPROM. Not being an EE, I'm not going to worry about
// how the ATMEL talks to the EEPROM. It's black magic.
PORTB = _BV(SPIEE_CS);
// Just above, we set PD2 and PD3 to input. If we now set those
// bits to 1, they set into pullup mode (again, not EE, claim
// ignorance), which is essential for them to work. We also set
// the SENSORPOWER bit to 1, which sends out little dribbles of
// electrons to the hall effect sensor (see circuit diagram)
//
// Finally, we write 0's to the FRONT and BACK pins, which control
// which bank of 30 LEDs we are talking to. Having both of these
// on at the same time probably causes horrible things to happen.
PORTD = (_BV(BUTTON) | _BV(SENSOR) | _BV(SENSORPOWER))
& ~_BV(FRONT) & ~_BV(BACK);
// Rather than poll to see when the hall effect sensor and
// button are pressed, we configure an interrupt handler. If you
// look at the circuit diagram, you'll see that PD3 and PD2, which
// are wired to SENSOR IN and BUTTON IN, do double-duty as INT1
// and INT0. They are both SUPPOSEDLY set to interrupt on the
// falling edge of a pulse from the devices. (Page 63)
// POSSIBLE BUG: ISC0{1,0} seems to be being set to 00, not 10
// as ISC1{1,0} is being set to. So ISC0 will trigger when
// the button interrupt line goes low. Either this is a bug,
// or the original comment was not correct (likely, IMHO)
MCUCR = _BV(ISC11) & ~_BV(ISC01) & ~_BV(ISC00) & ~_BV(ISC10);
// Activate the interrupts by setting the General Interrupt Mask
// Register (Page 63)
GIMSK = _BV(INT1) | _BV(INT0);
// The ATMEL has built-in timers that can trigger an interrupt.
// SpokePOV uses them to update the LEDs 256 times per rotation.
// Timer 0 is set to update at a rate system-clock / 256 and
// interrupt when it overflows (8 bit). This means that it
// triggers every 65536 cycles.
TCCR0A = 0; // normal, overflow (count up to 256 == num pixels)
TCCR0B = _BV(CS02); // clk/256
TIMSK |= _BV(TOIE0); // turn on overflow interrupt
// Timer 1 (T1) is the pixel timer, which is used to update the
// LEDs 256 times per rotation. It's set up as a normal timer
// as well. See Page 108&71; it is apparently being set into CTC
// mode 4. This means that the counter is compared to a 16-bit value
// and interrupts when it reaches this value.
//
// Adjusting this value is how the SpokePOV compensates for
// changes in the rotation speed of the device.
//
// Note that at this point, the timer is initialized, but not
// activated.
TCCR1A = 0;
TCCR1B = _BV(WGM12);
// Clear the debounce values, which I haven't sussed out yet.
hall_debounce = 0;
sensor_timer.word = 0;
}
// Turn on a single LED, turning off all the other LEDs
//void set_led(uint8_t led) {
// fleds[0] = fleds[1] = fleds[2] = fleds[3] = 0xFF;
// fleds[led >> 3] = ~_BV(led & 0x7F);
// clock_scroll(0);
//}
// Set all the LEDs on a side to have the same
// repeating 8-bit value (ie: 0x00 = all on, 0xFF = all off)
// Added by RJW to permit a more comprehensive reset display
void set_all(uint8_t blockValue) {
fleds[0] = fleds[1] = fleds[2] = fleds[3] = blockValue;
160: 80 93 8d 00 sts 0x008D, r24
164: 80 93 8c 00 sts 0x008C, r24
168: 80 93 8b 00 sts 0x008B, r24
16c: 80 93 8a 00 sts 0x008A, r24
clock_scroll(0);
170: 80 e0 ldi r24, 0x00 ; 0
172: aa df rcall .-172 ; 0xc8 <clock_scroll>
174: 08 95 ret
00000176 <__vector_4>:
176: 1f 92 push r1
178: 0f 92 push r0
17a: 0f b6 in r0, 0x3f ; 63
17c: 0f 92 push r0
17e: 11 24 eor r1, r1
180: 2f 93 push r18
182: 3f 93 push r19
184: 4f 93 push r20
186: 5f 93 push r21
188: 6f 93 push r22
18a: 7f 93 push r23
18c: 8f 93 push r24
18e: 9f 93 push r25
190: af 93 push r26
192: bf 93 push r27
194: ef 93 push r30
196: ff 93 push r31
198: 80 91 89 00 lds r24, 0x0089
19c: 82 30 cpi r24, 0x02 ; 2
19e: 08 f0 brcs .+2 ; 0x1a2 <__vector_4+0x2c>
1a0: 7e c0 rjmp .+252 ; 0x29e <__vector_4+0x128>
1a2: 80 91 6e 00 lds r24, 0x006E
1a6: 8f 5f subi r24, 0xFF ; 255
1a8: 80 93 6e 00 sts 0x006E, r24
1ac: 80 91 6e 00 lds r24, 0x006E
1b0: 80 31 cpi r24, 0x10 ; 16
1b2: d9 f5 brne .+118 ; 0x22a <__vector_4+0xb4>
1b4: 80 91 6f 00 lds r24, 0x006F
1b8: 8f 30 cpi r24, 0x0F ; 15
1ba: 29 f4 brne .+10 ; 0x1c6 <__vector_4+0x50>
1bc: 8e b5 in r24, 0x2e ; 46
1be: 88 7f andi r24, 0xF8 ; 248
1c0: 8e bd out 0x2e, r24 ; 46
1c2: 8f ef ldi r24, 0xFF ; 255
1c4: 70 c0 rjmp .+224 ; 0x2a6 <__vector_4+0x130>
1c6: 10 92 6e 00 sts 0x006E, r1
1ca: 80 91 6f 00 lds r24, 0x006F
1ce: 8f 5f subi r24, 0xFF ; 255
1d0: 8f 70 andi r24, 0x0F ; 15
1d2: 80 93 6f 00 sts 0x006F, r24
1d6: 80 91 6f 00 lds r24, 0x006F
1da: e8 2f mov r30, r24
1dc: ff 27 eor r31, r31
1de: e0 57 subi r30, 0x70 ; 112
1e0: ff 4f sbci r31, 0xFF ; 255
1e2: 80 81 ld r24, Z
1e4: 99 27 eor r25, r25
1e6: 80 97 sbiw r24, 0x20 ; 32
1e8: 88 0f add r24, r24
1ea: 99 1f adc r25, r25
1ec: 90 93 73 00 sts 0x0073, r25
1f0: 80 93 72 00 sts 0x0072, r24
1f4: 80 91 6f 00 lds r24, 0x006F
1f8: e8 2f mov r30, r24
1fa: ff 27 eor r31, r31
1fc: e0 56 subi r30, 0x60 ; 96
1fe: ff 4f sbci r31, 0xFF ; 255
200: 80 81 ld r24, Z
202: 99 27 eor r25, r25
204: 80 97 sbiw r24, 0x20 ; 32
206: 88 0f add r24, r24
208: 99 1f adc r25, r25
20a: 90 93 71 00 sts 0x0071, r25
20e: 80 93 70 00 sts 0x0070, r24
212: 80 91 6f 00 lds r24, 0x006F
216: e8 2f mov r30, r24
218: ff 27 eor r31, r31
21a: e9 58 subi r30, 0x89 ; 137
21c: ff 4f sbci r31, 0xFF ; 255
21e: 80 81 ld r24, Z
220: 99 27 eor r25, r25
222: 80 97 sbiw r24, 0x20 ; 32
224: 88 0f add r24, r24
226: 99 1f adc r25, r25
228: 1a c0 rjmp .+52 ; 0x25e <__vector_4+0xe8>
22a: 80 91 72 00 lds r24, 0x0072
22e: 90 91 73 00 lds r25, 0x0073
232: 80 54 subi r24, 0x40 ; 64
234: 9f 4f sbci r25, 0xFF ; 255
236: 90 93 73 00 sts 0x0073, r25
23a: 80 93 72 00 sts 0x0072, r24
23e: 80 91 70 00 lds r24, 0x0070
242: 90 91 71 00 lds r25, 0x0071
246: 80 54 subi r24, 0x40 ; 64
248: 9f 4f sbci r25, 0xFF ; 255
24a: 90 93 71 00 sts 0x0071, r25
24e: 80 93 70 00 sts 0x0070, r24
252: 80 91 6c 00 lds r24, 0x006C
256: 90 91 6d 00 lds r25, 0x006D
25a: 80 54 subi r24, 0x40 ; 64
25c: 9f 4f sbci r25, 0xFF ; 255
25e: 90 93 6d 00 sts 0x006D, r25
262: 80 93 6c 00 sts 0x006C, r24
266: 42 e0 ldi r20, 0x02 ; 2
268: 6a e8 ldi r22, 0x8A ; 138
26a: 70 e0 ldi r23, 0x00 ; 0
26c: 80 91 72 00 lds r24, 0x0072
270: 90 91 73 00 lds r25, 0x0073
274: 38 d2 rcall .+1136 ; 0x6e6 <spieeprom_read>
276: 42 e0 ldi r20, 0x02 ; 2
278: 6c e8 ldi r22, 0x8C ; 140
27a: 70 e0 ldi r23, 0x00 ; 0
27c: 80 91 70 00 lds r24, 0x0070
280: 90 91 71 00 lds r25, 0x0071
284: 30 d2 rcall .+1120 ; 0x6e6 <spieeprom_read>
286: 42 e0 ldi r20, 0x02 ; 2
288: 6e e8 ldi r22, 0x8E ; 142
28a: 70 e0 ldi r23, 0x00 ; 0
28c: 80 91 6c 00 lds r24, 0x006C
290: 90 91 6d 00 lds r25, 0x006D
294: 28 d2 rcall .+1104 ; 0x6e6 <spieeprom_read>
296: 80 91 60 00 lds r24, 0x0060
29a: 16 df rcall .-468 ; 0xc8 <clock_scroll>
29c: 05 c0 rjmp .+10 ; 0x2a8 <__vector_4+0x132>
29e: 8e b5 in r24, 0x2e ; 46
2a0: 88 7f andi r24, 0xF8 ; 248
2a2: 8e bd out 0x2e, r24 ; 46
2a4: 88 ef ldi r24, 0xF8 ; 248
2a6: 5c df rcall .-328 ; 0x160 <set_all>
2a8: ff 91 pop r31
2aa: ef 91 pop r30
2ac: bf 91 pop r27
2ae: af 91 pop r26
2b0: 9f 91 pop r25
2b2: 8f 91 pop r24
2b4: 7f 91 pop r23
2b6: 6f 91 pop r22
2b8: 5f 91 pop r21
2ba: 4f 91 pop r20
2bc: 3f 91 pop r19
2be: 2f 91 pop r18
2c0: 0f 90 pop r0
2c2: 0f be out 0x3f, r0 ; 63
2c4: 0f 90 pop r0
2c6: 1f 90 pop r1
2c8: 18 95 reti
000002ca <__vector_1>:
2ca: 1f 92 push r1
2cc: 0f 92 push r0
2ce: 0f b6 in r0, 0x3f ; 63
2d0: 0f 92 push r0
2d2: 11 24 eor r1, r1
2d4: 8f 93 push r24
2d6: 82 9b sbis 0x10, 2 ; 16
2d8: fe cf rjmp .-4 ; 0x2d6 <__vector_1+0xc>
2da: 80 91 89 00 lds r24, 0x0089
2de: 8f 3f cpi r24, 0xFF ; 255
2e0: 29 f4 brne .+10 ; 0x2ec <__vector_1+0x22>
2e2: 10 92 89 00 sts 0x0089, r1
2e6: 88 e0 ldi r24, 0x08 ; 8
2e8: 81 bd out 0x21, r24 ; 33
2ea: ff cf rjmp .-2 ; 0x2ea <__vector_1+0x20>
2ec: 8f ef ldi r24, 0xFF ; 255
2ee: 80 93 89 00 sts 0x0089, r24
2f2: 8f 91 pop r24
2f4: 0f 90 pop r0
2f6: 0f be out 0x3f, r0 ; 63
2f8: 0f 90 pop r0
2fa: 1f 90 pop r1
2fc: 18 95 reti
000002fe <__vector_2>:
2fe: 1f 92 push r1
300: 0f 92 push r0
302: 0f b6 in r0, 0x3f ; 63
304: 0f 92 push r0
306: 11 24 eor r1, r1
308: 0f 93 push r16
30a: 1f 93 push r17
30c: 2f 93 push r18
30e: 3f 93 push r19
310: 4f 93 push r20
312: 5f 93 push r21
314: 6f 93 push r22
316: 7f 93 push r23
318: 8f 93 push r24
31a: 9f 93 push r25
31c: af 93 push r26
31e: bf 93 push r27
320: cf 93 push r28
322: ef 93 push r30
324: ff 93 push r31
326: a8 95 wdr
328: 80 91 87 00 lds r24, 0x0087
32c: 85 30 cpi r24, 0x05 ; 5
32e: 08 f4 brcc .+2 ; 0x332 <__vector_2+0x34>
330: ef c0 rjmp .+478 ; 0x510 <__vector_2+0x212>
332: 1d bc out 0x2d, r1 ; 45
334: 1c bc out 0x2c, r1 ; 44
336: 80 91 88 00 lds r24, 0x0088
33a: 8f 3f cpi r24, 0xFF ; 255
33c: 09 f4 brne .+2 ; 0x340 <__vector_2+0x42>
33e: d6 c0 rjmp .+428 ; 0x4ec <__vector_2+0x1ee>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -