📄 spokepov.lss
字号:
memcpy_P(topLine,lines,16);
memcpy_P(botLine,lines+16,16);
#ifdef DYNAMIC
dCode = pgm_read_byte(dInfo);
if (dCode != 0) {
newDynamicPtr = topLine + (dCode & 0x0F);
dynamicType = dCode;
}
dCode = pgm_read_byte(dInfo+1);
if (dCode != 0) {
newDynamicPtr = 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 = 15; // will wrap to 0, the first char
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_l = 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 = 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 = 0;
}
// Delay for a specified number of milliseconds using some
// assembly code. Will this be dependant on the clock speed?
void delay_ms(unsigned char ms)
{
unsigned short delay_count = F_CPU / 4000;
unsigned short cnt;
asm volatile ("\n"
"L_dl1%=:\n\t"
"mov %A0, %A2\n\t"
"mov %B0, %B2\n"
"L_dl2%=:\n\t"
"sbiw %A0, 1\n\t"
"brne L_dl2%=\n\t"
"wdr\n\t"
"dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt)
:"r"(ms), "r"((unsigned short) (delay_count))
);
}
// 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;
13a: 80 93 8c 00 sts 0x008C, r24
13e: 80 93 8b 00 sts 0x008B, r24
142: 80 93 8a 00 sts 0x008A, r24
146: 80 93 89 00 sts 0x0089, r24
clock_scroll(0);
14a: 80 e0 ldi r24, 0x00 ; 0
14c: 98 df rcall .-208 ; 0x7e <clock_scroll>
14e: 08 95 ret
00000150 <__vector_4>:
150: 1f 92 push r1
152: 0f 92 push r0
154: 0f b6 in r0, 0x3f ; 63
156: 0f 92 push r0
158: 11 24 eor r1, r1
15a: 2f 93 push r18
15c: 3f 93 push r19
15e: 4f 93 push r20
160: 5f 93 push r21
162: 6f 93 push r22
164: 7f 93 push r23
166: 8f 93 push r24
168: 9f 93 push r25
16a: af 93 push r26
16c: bf 93 push r27
16e: ef 93 push r30
170: ff 93 push r31
172: 80 91 87 00 lds r24, 0x0087
176: 90 91 88 00 lds r25, 0x0088
17a: 82 56 subi r24, 0x62 ; 98
17c: 92 40 sbci r25, 0x02 ; 2
17e: 08 f0 brcs .+2 ; 0x182 <__vector_4+0x32>
180: a2 c0 rjmp .+324 ; 0x2c6 <__vector_4+0x176>
182: 80 91 6a 00 lds r24, 0x006A
186: 8f 5f subi r24, 0xFF ; 255
188: 80 93 6a 00 sts 0x006A, r24
18c: 80 91 6a 00 lds r24, 0x006A
190: 80 31 cpi r24, 0x10 ; 16
192: 09 f0 breq .+2 ; 0x196 <__vector_4+0x46>
194: 61 c0 rjmp .+194 ; 0x258 <__vector_4+0x108>
196: 10 92 6a 00 sts 0x006A, r1
19a: 80 91 6b 00 lds r24, 0x006B
19e: 8f 5f subi r24, 0xFF ; 255
1a0: 8f 70 andi r24, 0x0F ; 15
1a2: 80 93 6b 00 sts 0x006B, r24
1a6: 80 91 6b 00 lds r24, 0x006B
1aa: e8 2f mov r30, r24
1ac: ff 27 eor r31, r31
1ae: e1 57 subi r30, 0x71 ; 113
1b0: ff 4f sbci r31, 0xFF ; 255
1b2: e0 81 ld r30, Z
1b4: e0 52 subi r30, 0x20 ; 32
1b6: 8e 2f mov r24, r30
1b8: 86 95 lsr r24
1ba: 28 2f mov r18, r24
1bc: 33 27 eor r19, r19
1be: f6 e0 ldi r31, 0x06 ; 6
1c0: 22 0f add r18, r18
1c2: 33 1f adc r19, r19
1c4: fa 95 dec r31
1c6: e1 f7 brne .-8 ; 0x1c0 <__vector_4+0x70>
1c8: 8e 2f mov r24, r30
1ca: 99 27 eor r25, r25
1cc: 81 70 andi r24, 0x01 ; 1
1ce: 90 70 andi r25, 0x00 ; 0
1d0: 88 0f add r24, r24
1d2: 99 1f adc r25, r25
1d4: 28 2b or r18, r24
1d6: 39 2b or r19, r25
1d8: 30 93 6f 00 sts 0x006F, r19
1dc: 20 93 6e 00 sts 0x006E, r18
1e0: 80 91 6b 00 lds r24, 0x006B
1e4: e8 2f mov r30, r24
1e6: ff 27 eor r31, r31
1e8: e1 56 subi r30, 0x61 ; 97
1ea: ff 4f sbci r31, 0xFF ; 255
1ec: e0 81 ld r30, Z
1ee: e0 52 subi r30, 0x20 ; 32
1f0: 8e 2f mov r24, r30
1f2: 86 95 lsr r24
1f4: 28 2f mov r18, r24
1f6: 33 27 eor r19, r19
1f8: 76 e0 ldi r23, 0x06 ; 6
1fa: 22 0f add r18, r18
1fc: 33 1f adc r19, r19
1fe: 7a 95 dec r23
200: e1 f7 brne .-8 ; 0x1fa <__vector_4+0xaa>
202: 8e 2f mov r24, r30
204: 99 27 eor r25, r25
206: 81 70 andi r24, 0x01 ; 1
208: 90 70 andi r25, 0x00 ; 0
20a: 88 0f add r24, r24
20c: 99 1f adc r25, r25
20e: 28 2b or r18, r24
210: 39 2b or r19, r25
212: 30 93 6d 00 sts 0x006D, r19
216: 20 93 6c 00 sts 0x006C, r18
21a: 80 91 6b 00 lds r24, 0x006B
21e: e8 2f mov r30, r24
220: ff 27 eor r31, r31
222: ea 58 subi r30, 0x8A ; 138
224: ff 4f sbci r31, 0xFF ; 255
226: e0 81 ld r30, Z
228: e0 52 subi r30, 0x20 ; 32
22a: 8e 2f mov r24, r30
22c: 86 95 lsr r24
22e: 28 2f mov r18, r24
230: 33 27 eor r19, r19
232: 68 94 set
234: 15 f8 bld r1, 5
236: 22 0f add r18, r18
238: 33 1f adc r19, r19
23a: 16 94 lsr r1
23c: e1 f7 brne .-8 ; 0x236 <__vector_4+0xe6>
23e: 8e 2f mov r24, r30
240: 99 27 eor r25, r25
242: 81 70 andi r24, 0x01 ; 1
244: 90 70 andi r25, 0x00 ; 0
246: 88 0f add r24, r24
248: 99 1f adc r25, r25
24a: 28 2b or r18, r24
24c: 39 2b or r19, r25
24e: 30 93 69 00 sts 0x0069, r19
252: 20 93 68 00 sts 0x0068, r18
256: 1b c0 rjmp .+54 ; 0x28e <__vector_4+0x13e>
258: 80 91 6e 00 lds r24, 0x006E
25c: 90 91 6f 00 lds r25, 0x006F
260: 04 96 adiw r24, 0x04 ; 4
262: 90 93 6f 00 sts 0x006F, r25
266: 80 93 6e 00 sts 0x006E, r24
26a: 80 91 6c 00 lds r24, 0x006C
26e: 90 91 6d 00 lds r25, 0x006D
272: 04 96 adiw r24, 0x04 ; 4
274: 90 93 6d 00 sts 0x006D, r25
278: 80 93 6c 00 sts 0x006C, r24
27c: 80 91 68 00 lds r24, 0x0068
280: 90 91 69 00 lds r25, 0x0069
284: 04 96 adiw r24, 0x04 ; 4
286: 90 93 69 00 sts 0x0069, r25
28a: 80 93 68 00 sts 0x0068, r24
28e: 42 e0 ldi r20, 0x02 ; 2
290: 69 e8 ldi r22, 0x89 ; 137
292: 70 e0 ldi r23, 0x00 ; 0
294: 80 91 6e 00 lds r24, 0x006E
298: 90 91 6f 00 lds r25, 0x006F
29c: 42 d2 rcall .+1156 ; 0x722 <spieeprom_read>
29e: 42 e0 ldi r20, 0x02 ; 2
2a0: 6b e8 ldi r22, 0x8B ; 139
2a2: 70 e0 ldi r23, 0x00 ; 0
2a4: 80 91 6c 00 lds r24, 0x006C
2a8: 90 91 6d 00 lds r25, 0x006D
2ac: 3a d2 rcall .+1140 ; 0x722 <spieeprom_read>
2ae: 42 e0 ldi r20, 0x02 ; 2
2b0: 6d e8 ldi r22, 0x8D ; 141
2b2: 70 e0 ldi r23, 0x00 ; 0
2b4: 80 91 68 00 lds r24, 0x0068
2b8: 90 91 69 00 lds r25, 0x0069
2bc: 32 d2 rcall .+1124 ; 0x722 <spieeprom_read>
2be: 80 91 60 00 lds r24, 0x0060
2c2: dd de rcall .-582 ; 0x7e <clock_scroll>
2c4: 07 c0 rjmp .+14 ; 0x2d4 <__vector_4+0x184>
2c6: f8 94 cli
2c8: 8e b5 in r24, 0x2e ; 46
2ca: 88 7f andi r24, 0xF8 ; 248
2cc: 8e bd out 0x2e, r24 ; 46
2ce: 78 94 sei
2d0: 88 ef ldi r24, 0xF8 ; 248
2d2: 33 df rcall .-410 ; 0x13a <set_all>
2d4: ff 91 pop r31
2d6: ef 91 pop r30
2d8: bf 91 pop r27
2da: af 91 pop r26
2dc: 9f 91 pop r25
2de: 8f 91 pop r24
2e0: 7f 91 pop r23
2e2: 6f 91 pop r22
2e4: 5f 91 pop r21
2e6: 4f 91 pop r20
2e8: 3f 91 pop r19
2ea: 2f 91 pop r18
2ec: 0f 90 pop r0
2ee: 0f be out 0x3f, r0 ; 63
2f0: 0f 90 pop r0
2f2: 1f 90 pop r1
2f4: 18 95 reti
000002f6 <delay_ms>:
2f6: 20 ed ldi r18, 0xD0 ; 208
2f8: 37 e0 ldi r19, 0x07 ; 7
000002fa <L_dl1245>:
2fa: e2 2f mov r30, r18
2fc: f3 2f mov r31, r19
000002fe <L_dl2245>:
2fe: 31 97 sbiw r30, 0x01 ; 1
300: f1 f7 brne .-4 ; 0x2fe <L_dl2245>
302: a8 95 wdr
304: 8a 95 dec r24
306: c9 f7 brne .-14 ; 0x2fa <L_dl1245>
308: 08 95 ret
0000030a <__vector_1>:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -