1839 lines
64 KiB
Plaintext
1839 lines
64 KiB
Plaintext
|
|
wp_dc22_attiny88.elf: file format elf32-avr
|
|
|
|
Sections:
|
|
Idx Name Size VMA LMA File off Algn
|
|
0 .data 00000004 00800100 000008a8 0000093c 2**0
|
|
CONTENTS, ALLOC, LOAD, DATA
|
|
1 .text 000008a8 00000000 00000000 00000094 2**1
|
|
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
|
2 .bss 00000030 00800104 00800104 00000940 2**0
|
|
ALLOC
|
|
3 .comment 00000030 00000000 00000000 00000940 2**0
|
|
CONTENTS, READONLY
|
|
4 .note.gnu.avr.deviceinfo 0000003c 00000000 00000000 00000970 2**2
|
|
CONTENTS, READONLY
|
|
5 .debug_aranges 00000178 00000000 00000000 000009b0 2**3
|
|
CONTENTS, READONLY, DEBUGGING
|
|
6 .debug_info 00001493 00000000 00000000 00000b28 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
7 .debug_abbrev 00000b12 00000000 00000000 00001fbb 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
8 .debug_line 00000e6a 00000000 00000000 00002acd 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
9 .debug_frame 00000230 00000000 00000000 00003938 2**2
|
|
CONTENTS, READONLY, DEBUGGING
|
|
10 .debug_str 000006f2 00000000 00000000 00003b68 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
11 .debug_loc 000004a9 00000000 00000000 0000425a 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
12 .debug_ranges 000000a8 00000000 00000000 00004703 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
|
|
Disassembly of section .text:
|
|
|
|
00000000 <__vectors>:
|
|
0: 2d c0 rjmp .+90 ; 0x5c <__ctors_end>
|
|
2: 47 c0 rjmp .+142 ; 0x92 <__bad_interrupt>
|
|
4: 46 c0 rjmp .+140 ; 0x92 <__bad_interrupt>
|
|
6: 45 c0 rjmp .+138 ; 0x92 <__bad_interrupt>
|
|
8: 44 c0 rjmp .+136 ; 0x92 <__bad_interrupt>
|
|
a: 43 c0 rjmp .+134 ; 0x92 <__bad_interrupt>
|
|
c: 42 c0 rjmp .+132 ; 0x92 <__bad_interrupt>
|
|
e: 41 c0 rjmp .+130 ; 0x92 <__bad_interrupt>
|
|
10: 40 c0 rjmp .+128 ; 0x92 <__bad_interrupt>
|
|
12: 3f c0 rjmp .+126 ; 0x92 <__bad_interrupt>
|
|
14: 3e c0 rjmp .+124 ; 0x92 <__bad_interrupt>
|
|
16: 3d c0 rjmp .+122 ; 0x92 <__bad_interrupt>
|
|
18: aa c3 rjmp .+1876 ; 0x76e <__vector_12>
|
|
1a: 3b c0 rjmp .+118 ; 0x92 <__bad_interrupt>
|
|
1c: 3a c0 rjmp .+116 ; 0x92 <__bad_interrupt>
|
|
1e: 39 c0 rjmp .+114 ; 0x92 <__bad_interrupt>
|
|
20: 8b c0 rjmp .+278 ; 0x138 <__vector_16>
|
|
22: 37 c0 rjmp .+110 ; 0x92 <__bad_interrupt>
|
|
24: 36 c0 rjmp .+108 ; 0x92 <__bad_interrupt>
|
|
26: 34 c3 rjmp .+1640 ; 0x690 <__vector_19>
|
|
28: bd c1 rjmp .+890 ; 0x3a4 <pegleg_cmd+0x16>
|
|
2a: c0 c1 rjmp .+896 ; 0x3ac <pegleg_cmd+0x1e>
|
|
2c: ca c1 rjmp .+916 ; 0x3c2 <pegleg_cmd+0x34>
|
|
2e: db c1 rjmp .+950 ; 0x3e6 <pegleg_cmd+0x58>
|
|
30: f8 c1 rjmp .+1008 ; 0x422 <__LOCK_REGION_LENGTH__+0x22>
|
|
32: 16 c2 rjmp .+1068 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
34: 28 c2 rjmp .+1104 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
36: 27 c2 rjmp .+1102 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
38: f9 c1 rjmp .+1010 ; 0x42c <__LOCK_REGION_LENGTH__+0x2c>
|
|
3a: 03 c2 rjmp .+1030 ; 0x442 <__LOCK_REGION_LENGTH__+0x42>
|
|
3c: 24 c2 rjmp .+1096 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
3e: 23 c2 rjmp .+1094 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
40: 22 c2 rjmp .+1092 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
42: 21 c2 rjmp .+1090 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
44: 20 c2 rjmp .+1088 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
46: 09 c2 rjmp .+1042 ; 0x45a <__LOCK_REGION_LENGTH__+0x5a>
|
|
48: 0b c2 rjmp .+1046 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
4a: 0a c2 rjmp .+1044 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
4c: 1c c2 rjmp .+1080 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
4e: 1b c2 rjmp .+1078 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
50: 1a c2 rjmp .+1076 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
52: 19 c2 rjmp .+1074 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
54: 18 c2 rjmp .+1072 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
56: 17 c2 rjmp .+1070 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
58: 16 c2 rjmp .+1068 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
5a: 07 c2 rjmp .+1038 ; 0x46a <__LOCK_REGION_LENGTH__+0x6a>
|
|
|
|
0000005c <__ctors_end>:
|
|
5c: 11 24 eor r1, r1
|
|
5e: 1f be out 0x3f, r1 ; 63
|
|
60: cf ef ldi r28, 0xFF ; 255
|
|
62: d2 e0 ldi r29, 0x02 ; 2
|
|
64: de bf out 0x3e, r29 ; 62
|
|
66: cd bf out 0x3d, r28 ; 61
|
|
|
|
00000068 <__do_copy_data>:
|
|
68: 11 e0 ldi r17, 0x01 ; 1
|
|
6a: a0 e0 ldi r26, 0x00 ; 0
|
|
6c: b1 e0 ldi r27, 0x01 ; 1
|
|
6e: e8 ea ldi r30, 0xA8 ; 168
|
|
70: f8 e0 ldi r31, 0x08 ; 8
|
|
72: 02 c0 rjmp .+4 ; 0x78 <__do_copy_data+0x10>
|
|
74: 05 90 lpm r0, Z+
|
|
76: 0d 92 st X+, r0
|
|
78: a4 30 cpi r26, 0x04 ; 4
|
|
7a: b1 07 cpc r27, r17
|
|
7c: d9 f7 brne .-10 ; 0x74 <__do_copy_data+0xc>
|
|
|
|
0000007e <__do_clear_bss>:
|
|
7e: 21 e0 ldi r18, 0x01 ; 1
|
|
80: a4 e0 ldi r26, 0x04 ; 4
|
|
82: b1 e0 ldi r27, 0x01 ; 1
|
|
84: 01 c0 rjmp .+2 ; 0x88 <.do_clear_bss_start>
|
|
|
|
00000086 <.do_clear_bss_loop>:
|
|
86: 1d 92 st X+, r1
|
|
|
|
00000088 <.do_clear_bss_start>:
|
|
88: a4 33 cpi r26, 0x34 ; 52
|
|
8a: b2 07 cpc r27, r18
|
|
8c: e1 f7 brne .-8 ; 0x86 <.do_clear_bss_loop>
|
|
8e: 6d d2 rcall .+1242 ; 0x56a <main>
|
|
90: 09 c4 rjmp .+2066 ; 0x8a4 <_exit>
|
|
|
|
00000092 <__bad_interrupt>:
|
|
92: b6 cf rjmp .-148 ; 0x0 <__vectors>
|
|
|
|
00000094 <adc_init>:
|
|
|
|
/* functions */
|
|
void adc_init()
|
|
{
|
|
// make sure ADC power is enabled
|
|
PRR &= ~_BV(PRADC);
|
|
94: e4 e6 ldi r30, 0x64 ; 100
|
|
96: f0 e0 ldi r31, 0x00 ; 0
|
|
98: 80 81 ld r24, Z
|
|
9a: 8e 7f andi r24, 0xFE ; 254
|
|
9c: 80 83 st Z, r24
|
|
|
|
// clear all settings; set the ADC prescaler bits to get 500KHz ADC clock (SYSCLK/16), disable auto trigger
|
|
ADCSRA = _BV(ADPS2) | _BV(ADPS0) | ~(_BV(ADATE));
|
|
9e: ea e7 ldi r30, 0x7A ; 122
|
|
a0: f0 e0 ldi r31, 0x00 ; 0
|
|
a2: 8f ed ldi r24, 0xDF ; 223
|
|
a4: 80 83 st Z, r24
|
|
|
|
// set to right-aligned mode
|
|
ADMUX &= ~(_BV(ADLAR));
|
|
a6: ac e7 ldi r26, 0x7C ; 124
|
|
a8: b0 e0 ldi r27, 0x00 ; 0
|
|
aa: 8c 91 ld r24, X
|
|
ac: 8f 7d andi r24, 0xDF ; 223
|
|
ae: 8c 93 st X, r24
|
|
|
|
// enable the ADC, enable interrupts
|
|
ADCSRA |= _BV(ADEN) | _BV(ADIE);
|
|
b0: 80 81 ld r24, Z
|
|
b2: 88 68 ori r24, 0x88 ; 136
|
|
b4: 80 83 st Z, r24
|
|
b6: 08 95 ret
|
|
|
|
000000b8 <adc_channel>:
|
|
}
|
|
|
|
void adc_channel(uint8_t channel, uint8_t vref)
|
|
{
|
|
b8: 28 2f mov r18, r24
|
|
// can we set channel?
|
|
if (channel < ADC_CHAN_INVALID) {
|
|
ba: 80 31 cpi r24, 0x10 ; 16
|
|
bc: 88 f4 brcc .+34 ; 0xe0 <adc_channel+0x28>
|
|
// set MUX[3:0] to the specified channel
|
|
ADMUX = (ADMUX & 0xf0) | (channel & 0x0f);
|
|
be: 90 91 7c 00 lds r25, 0x007C ; 0x80007c <__EEPROM_REGION_LENGTH__+0x7f007c>
|
|
c2: 90 7f andi r25, 0xF0 ; 240
|
|
c4: 98 2b or r25, r24
|
|
c6: 90 93 7c 00 sts 0x007C, r25 ; 0x80007c <__EEPROM_REGION_LENGTH__+0x7f007c>
|
|
// also, if this is an actual pin, disable digital input on this pin
|
|
DIDR0 = (channel < 8) ? _BV(channel) : 0;
|
|
ca: 88 30 cpi r24, 0x08 ; 8
|
|
cc: 30 f4 brcc .+12 ; 0xda <adc_channel+0x22>
|
|
ce: 81 e0 ldi r24, 0x01 ; 1
|
|
d0: 01 c0 rjmp .+2 ; 0xd4 <adc_channel+0x1c>
|
|
d2: 88 0f add r24, r24
|
|
d4: 2a 95 dec r18
|
|
d6: ea f7 brpl .-6 ; 0xd2 <adc_channel+0x1a>
|
|
d8: 01 c0 rjmp .+2 ; 0xdc <adc_channel+0x24>
|
|
da: 80 e0 ldi r24, 0x00 ; 0
|
|
dc: 80 93 7e 00 sts 0x007E, r24 ; 0x80007e <__EEPROM_REGION_LENGTH__+0x7f007e>
|
|
}
|
|
|
|
// set the voltage source
|
|
if (vref == ADC_REF_AVCC) {
|
|
e0: 61 30 cpi r22, 0x01 ; 1
|
|
e2: 21 f4 brne .+8 ; 0xec <adc_channel+0x34>
|
|
ADMUX |= (_BV(REFS0));
|
|
e4: 80 91 7c 00 lds r24, 0x007C ; 0x80007c <__EEPROM_REGION_LENGTH__+0x7f007c>
|
|
e8: 80 64 ori r24, 0x40 ; 64
|
|
ea: 05 c0 rjmp .+10 ; 0xf6 <adc_channel+0x3e>
|
|
} else if (vref == ADC_REF_BANDGAP) {
|
|
ec: 62 30 cpi r22, 0x02 ; 2
|
|
ee: 29 f4 brne .+10 ; 0xfa <adc_channel+0x42>
|
|
ADMUX &= ~(_BV(REFS0));
|
|
f0: 80 91 7c 00 lds r24, 0x007C ; 0x80007c <__EEPROM_REGION_LENGTH__+0x7f007c>
|
|
f4: 8f 7b andi r24, 0xBF ; 191
|
|
f6: 80 93 7c 00 sts 0x007C, r24 ; 0x80007c <__EEPROM_REGION_LENGTH__+0x7f007c>
|
|
fa: 08 95 ret
|
|
|
|
000000fc <adc_start>:
|
|
}
|
|
|
|
uint8_t adc_start(uint8_t reread, uint8_t enable_averaging)
|
|
{
|
|
// is a conversion already running?
|
|
if (ADCSRA & _BV(ADSC)) {
|
|
fc: 90 91 7a 00 lds r25, 0x007A ; 0x80007a <__EEPROM_REGION_LENGTH__+0x7f007a>
|
|
100: 29 2f mov r18, r25
|
|
102: 20 74 andi r18, 0x40 ; 64
|
|
104: 96 fd sbrc r25, 6
|
|
106: 15 c0 rjmp .+42 ; 0x132 <adc_start+0x36>
|
|
return 1;
|
|
}
|
|
|
|
// set up amount of times to re-read, and mark the amount of values to average
|
|
adc_reread = reread;
|
|
108: 80 93 0c 01 sts 0x010C, r24 ; 0x80010c <adc_reread>
|
|
adc_averages = enable_averaging ? reread : 0;
|
|
10c: 66 23 and r22, r22
|
|
10e: 11 f0 breq .+4 ; 0x114 <adc_start+0x18>
|
|
110: 98 2f mov r25, r24
|
|
112: 01 c0 rjmp .+2 ; 0x116 <adc_start+0x1a>
|
|
114: 90 e0 ldi r25, 0x00 ; 0
|
|
116: 90 93 04 01 sts 0x0104, r25 ; 0x800104 <__data_end>
|
|
|
|
// start conversion
|
|
adc_busy = 0x80 | (ADMUX & 0x0f);
|
|
11a: 90 91 7c 00 lds r25, 0x007C ; 0x80007c <__EEPROM_REGION_LENGTH__+0x7f007c>
|
|
11e: 9f 70 andi r25, 0x0F ; 15
|
|
120: 90 68 ori r25, 0x80 ; 128
|
|
122: 90 93 1f 01 sts 0x011F, r25 ; 0x80011f <adc_busy>
|
|
ADCSRA |= _BV(ADSC);
|
|
126: 90 91 7a 00 lds r25, 0x007A ; 0x80007a <__EEPROM_REGION_LENGTH__+0x7f007a>
|
|
12a: 90 64 ori r25, 0x40 ; 64
|
|
12c: 90 93 7a 00 sts 0x007A, r25 ; 0x80007a <__EEPROM_REGION_LENGTH__+0x7f007a>
|
|
return 0;
|
|
130: 01 c0 rjmp .+2 ; 0x134 <adc_start+0x38>
|
|
|
|
uint8_t adc_start(uint8_t reread, uint8_t enable_averaging)
|
|
{
|
|
// is a conversion already running?
|
|
if (ADCSRA & _BV(ADSC)) {
|
|
return 1;
|
|
132: 21 e0 ldi r18, 0x01 ; 1
|
|
|
|
// start conversion
|
|
adc_busy = 0x80 | (ADMUX & 0x0f);
|
|
ADCSRA |= _BV(ADSC);
|
|
return 0;
|
|
}
|
|
134: 82 2f mov r24, r18
|
|
136: 08 95 ret
|
|
|
|
00000138 <__vector_16>:
|
|
|
|
|
|
/* ISR */
|
|
ISR(ADC_vect)
|
|
{
|
|
138: 1f 92 push r1
|
|
13a: 0f 92 push r0
|
|
13c: 0f b6 in r0, 0x3f ; 63
|
|
13e: 0f 92 push r0
|
|
140: 11 24 eor r1, r1
|
|
142: 2f 93 push r18
|
|
144: 4f 93 push r20
|
|
146: 5f 93 push r21
|
|
148: 8f 93 push r24
|
|
14a: 9f 93 push r25
|
|
14c: af 93 push r26
|
|
14e: bf 93 push r27
|
|
150: ef 93 push r30
|
|
152: ff 93 push r31
|
|
uint8_t channel;
|
|
|
|
channel = ADMUX & 0x0f;
|
|
154: e0 91 7c 00 lds r30, 0x007C ; 0x80007c <__EEPROM_REGION_LENGTH__+0x7f007c>
|
|
158: ef 70 andi r30, 0x0F ; 15
|
|
|
|
// mark our result in the average table
|
|
if (adc_averages) {
|
|
15a: 20 91 04 01 lds r18, 0x0104 ; 0x800104 <__data_end>
|
|
15e: 22 23 and r18, r18
|
|
160: d1 f0 breq .+52 ; 0x196 <__vector_16+0x5e>
|
|
// except for the first read
|
|
if (adc_averages != adc_reread) {
|
|
162: 80 91 0c 01 lds r24, 0x010C ; 0x80010c <adc_reread>
|
|
166: 28 17 cp r18, r24
|
|
168: b1 f0 breq .+44 ; 0x196 <__vector_16+0x5e>
|
|
// we do successive averaging; it's faster, smaller code, less RAM, and good enough for our purpose
|
|
// update our feedback
|
|
if (channel <= ADC_MAX_FEEDBACK) {
|
|
16a: e9 30 cpi r30, 0x09 ; 9
|
|
16c: a0 f4 brcc .+40 ; 0x196 <__vector_16+0x5e>
|
|
adc_result[channel] = (adc_result[channel] + ADC) >> 1;
|
|
16e: ae 2f mov r26, r30
|
|
170: b0 e0 ldi r27, 0x00 ; 0
|
|
172: aa 0f add r26, r26
|
|
174: bb 1f adc r27, r27
|
|
176: a3 5f subi r26, 0xF3 ; 243
|
|
178: be 4f sbci r27, 0xFE ; 254
|
|
17a: 4d 91 ld r20, X+
|
|
17c: 5c 91 ld r21, X
|
|
17e: 11 97 sbiw r26, 0x01 ; 1
|
|
180: 80 91 78 00 lds r24, 0x0078 ; 0x800078 <__EEPROM_REGION_LENGTH__+0x7f0078>
|
|
184: 90 91 79 00 lds r25, 0x0079 ; 0x800079 <__EEPROM_REGION_LENGTH__+0x7f0079>
|
|
188: 84 0f add r24, r20
|
|
18a: 95 1f adc r25, r21
|
|
18c: 96 95 lsr r25
|
|
18e: 87 95 ror r24
|
|
190: 11 96 adiw r26, 0x01 ; 1
|
|
192: 9c 93 st X, r25
|
|
194: 8e 93 st -X, r24
|
|
}
|
|
}
|
|
}
|
|
|
|
if (adc_reread) {
|
|
196: 80 91 0c 01 lds r24, 0x010C ; 0x80010c <adc_reread>
|
|
19a: 88 23 and r24, r24
|
|
19c: 59 f0 breq .+22 ; 0x1b4 <__vector_16+0x7c>
|
|
adc_reread--;
|
|
19e: 80 91 0c 01 lds r24, 0x010C ; 0x80010c <adc_reread>
|
|
1a2: 81 50 subi r24, 0x01 ; 1
|
|
1a4: 80 93 0c 01 sts 0x010C, r24 ; 0x80010c <adc_reread>
|
|
// start another conversion
|
|
ADCSRA |= _BV(ADSC);
|
|
1a8: 80 91 7a 00 lds r24, 0x007A ; 0x80007a <__EEPROM_REGION_LENGTH__+0x7f007a>
|
|
1ac: 80 64 ori r24, 0x40 ; 64
|
|
1ae: 80 93 7a 00 sts 0x007A, r24 ; 0x80007a <__EEPROM_REGION_LENGTH__+0x7f007a>
|
|
1b2: 11 c0 rjmp .+34 ; 0x1d6 <__vector_16+0x9e>
|
|
} else {
|
|
// determine if we need to update feedback
|
|
if (!adc_averages && channel <= ADC_MAX_FEEDBACK) {
|
|
1b4: 21 11 cpse r18, r1
|
|
1b6: 0d c0 rjmp .+26 ; 0x1d2 <__vector_16+0x9a>
|
|
1b8: e9 30 cpi r30, 0x09 ; 9
|
|
1ba: 58 f4 brcc .+22 ; 0x1d2 <__vector_16+0x9a>
|
|
// not averaging, so just store last result
|
|
adc_result[channel] = ADC;
|
|
1bc: f0 e0 ldi r31, 0x00 ; 0
|
|
1be: 80 91 78 00 lds r24, 0x0078 ; 0x800078 <__EEPROM_REGION_LENGTH__+0x7f0078>
|
|
1c2: 90 91 79 00 lds r25, 0x0079 ; 0x800079 <__EEPROM_REGION_LENGTH__+0x7f0079>
|
|
1c6: ee 0f add r30, r30
|
|
1c8: ff 1f adc r31, r31
|
|
1ca: e3 5f subi r30, 0xF3 ; 243
|
|
1cc: fe 4f sbci r31, 0xFE ; 254
|
|
1ce: 91 83 std Z+1, r25 ; 0x01
|
|
1d0: 80 83 st Z, r24
|
|
}
|
|
|
|
adc_busy = 0;
|
|
1d2: 10 92 1f 01 sts 0x011F, r1 ; 0x80011f <adc_busy>
|
|
}
|
|
1d6: ff 91 pop r31
|
|
1d8: ef 91 pop r30
|
|
1da: bf 91 pop r27
|
|
1dc: af 91 pop r26
|
|
1de: 9f 91 pop r25
|
|
1e0: 8f 91 pop r24
|
|
1e2: 5f 91 pop r21
|
|
1e4: 4f 91 pop r20
|
|
1e6: 2f 91 pop r18
|
|
1e8: 0f 90 pop r0
|
|
1ea: 0f be out 0x3f, r0 ; 63
|
|
1ec: 0f 90 pop r0
|
|
1ee: 1f 90 pop r1
|
|
1f0: 18 95 reti
|
|
|
|
000001f2 <rgbled_io_init>:
|
|
{
|
|
// PortD[4:7] (left) and PortC[0:3] (right) are LEDs
|
|
// Also, Right LEDs are capable of ADC input on ALL pins (ADC[0:3])
|
|
|
|
// set all pins as outputs
|
|
DDRD |= 0xf0;
|
|
1f2: 8a b1 in r24, 0x0a ; 10
|
|
1f4: 80 6f ori r24, 0xF0 ; 240
|
|
1f6: 8a b9 out 0x0a, r24 ; 10
|
|
DDRC |= 0x0f;
|
|
1f8: 87 b1 in r24, 0x07 ; 7
|
|
1fa: 8f 60 ori r24, 0x0F ; 15
|
|
1fc: 87 b9 out 0x07, r24 ; 7
|
|
|
|
#ifdef LED_COMMON_ANODE
|
|
// com-anode: pin is high to disable
|
|
PORTD |= 0xf0;
|
|
1fe: 8b b1 in r24, 0x0b ; 11
|
|
200: 80 6f ori r24, 0xF0 ; 240
|
|
202: 8b b9 out 0x0b, r24 ; 11
|
|
PORTC |= 0x0f;
|
|
204: 88 b1 in r24, 0x08 ; 8
|
|
206: 8f 60 ori r24, 0x0F ; 15
|
|
208: 88 b9 out 0x08, r24 ; 8
|
|
20a: 08 95 ret
|
|
|
|
0000020c <rgbled_update>:
|
|
}
|
|
|
|
// sets the appropriate pins and PWM values for the LED index specified in rgbled_idx.
|
|
// note: this index is updated externally, and not by this function.
|
|
void rgbled_update()
|
|
{
|
|
20c: cf 93 push r28
|
|
20e: df 93 push r29
|
|
// clear all selected LED pins
|
|
// we have to clear the select line then set it because we can't fully disable the PWM for some reason
|
|
#ifdef LED_COMMON_ANODE
|
|
// make sure all pins are high
|
|
PORTD |= 0xf0;
|
|
210: 8b b1 in r24, 0x0b ; 11
|
|
212: 80 6f ori r24, 0xF0 ; 240
|
|
214: 8b b9 out 0x0b, r24 ; 11
|
|
PORTC |= 0x0f;
|
|
216: 88 b1 in r24, 0x08 ; 8
|
|
218: 8f 60 ori r24, 0x0F ; 15
|
|
21a: 88 b9 out 0x08, r24 ; 8
|
|
PORTD &= 0x0f;
|
|
PORTC &= 0xf0;
|
|
#endif
|
|
|
|
// set pwm OCx registers to max
|
|
timer1_set_oca(TIMER1_COMPARE);
|
|
21c: c8 e8 ldi r28, 0x88 ; 136
|
|
21e: d0 e0 ldi r29, 0x00 ; 0
|
|
220: 8e ef ldi r24, 0xFE ; 254
|
|
222: 88 83 st Y, r24
|
|
timer1_set_ocb(TIMER1_COMPARE);
|
|
224: aa e8 ldi r26, 0x8A ; 138
|
|
226: b0 e0 ldi r27, 0x00 ; 0
|
|
228: 8c 93 st X, r24
|
|
DDRB |= (_BV(DDB2) | _BV(DDB1));
|
|
}
|
|
|
|
inline void timer1_set(uint16_t set)
|
|
{
|
|
TCNT1 = set;
|
|
22a: 8a ef ldi r24, 0xFA ; 250
|
|
22c: 90 e0 ldi r25, 0x00 ; 0
|
|
22e: 90 93 85 00 sts 0x0085, r25 ; 0x800085 <__EEPROM_REGION_LENGTH__+0x7f0085>
|
|
232: 80 93 84 00 sts 0x0084, r24 ; 0x800084 <__EEPROM_REGION_LENGTH__+0x7f0084>
|
|
|
|
// now we set the desired LED
|
|
// turn on one LED in each group
|
|
#ifdef LED_COMMON_ANODE
|
|
// make sure active pin is output low and others are high
|
|
PORTD &= ~(_BV(rgbled_idx + 4));
|
|
236: 3b b1 in r19, 0x0b ; 11
|
|
238: 24 e0 ldi r18, 0x04 ; 4
|
|
23a: 2d 0d add r18, r13
|
|
23c: 81 e0 ldi r24, 0x01 ; 1
|
|
23e: 90 e0 ldi r25, 0x00 ; 0
|
|
240: ac 01 movw r20, r24
|
|
242: 01 c0 rjmp .+2 ; 0x246 <rgbled_update+0x3a>
|
|
244: 44 0f add r20, r20
|
|
246: 2a 95 dec r18
|
|
248: ea f7 brpl .-6 ; 0x244 <rgbled_update+0x38>
|
|
24a: 24 2f mov r18, r20
|
|
24c: 20 95 com r18
|
|
24e: 23 23 and r18, r19
|
|
250: 2b b9 out 0x0b, r18 ; 11
|
|
PORTC &= ~(_BV(rgbled_idx));
|
|
252: 28 b1 in r18, 0x08 ; 8
|
|
254: 0d 2c mov r0, r13
|
|
256: 01 c0 rjmp .+2 ; 0x25a <rgbled_update+0x4e>
|
|
258: 88 0f add r24, r24
|
|
25a: 0a 94 dec r0
|
|
25c: ea f7 brpl .-6 ; 0x258 <rgbled_update+0x4c>
|
|
25e: 80 95 com r24
|
|
260: 82 23 and r24, r18
|
|
262: 88 b9 out 0x08, r24 ; 8
|
|
PORTD |= _BV(rgbled_idx) << 4;
|
|
PORTC |= _BV(rgbled_idx);
|
|
#endif
|
|
|
|
// load new pwm OCx values for this LED
|
|
timer1_set_oca(rgbled_pwm_lf[rgbled_idx]);
|
|
264: ed 2d mov r30, r13
|
|
266: f0 e0 ldi r31, 0x00 ; 0
|
|
268: eb 5d subi r30, 0xDB ; 219
|
|
26a: fe 4f sbci r31, 0xFE ; 254
|
|
26c: 8b ef ldi r24, 0xFB ; 251
|
|
26e: 90 81 ld r25, Z
|
|
270: 28 2f mov r18, r24
|
|
272: 29 1b sub r18, r25
|
|
274: 28 83 st Y, r18
|
|
timer1_set_ocb(rgbled_pwm_rt[rgbled_idx]);
|
|
276: ed 2d mov r30, r13
|
|
278: f0 e0 ldi r31, 0x00 ; 0
|
|
27a: ef 5d subi r30, 0xDF ; 223
|
|
27c: fe 4f sbci r31, 0xFE ; 254
|
|
27e: 90 81 ld r25, Z
|
|
280: 89 1b sub r24, r25
|
|
282: 8c 93 st X, r24
|
|
}
|
|
284: df 91 pop r29
|
|
286: cf 91 pop r28
|
|
288: 08 95 ret
|
|
|
|
0000028a <rgbled_sensor_init>:
|
|
// configures the specified LED on the ADC.
|
|
// this function assumes common anode.
|
|
void rgbled_sensor_init(uint8_t led)
|
|
{
|
|
// set the left eye high (fixes color flash/tearing)
|
|
PORTD |= 0xf0;
|
|
28a: 9b b1 in r25, 0x0b ; 11
|
|
28c: 90 6f ori r25, 0xF0 ; 240
|
|
28e: 9b b9 out 0x0b, r25 ; 11
|
|
|
|
// disable both eye's PWM (required for right eye, fixes color flash/tearing in left eye)
|
|
TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0));
|
|
290: e0 e8 ldi r30, 0x80 ; 128
|
|
292: f0 e0 ldi r31, 0x00 ; 0
|
|
294: 90 81 ld r25, Z
|
|
296: 9f 70 andi r25, 0x0F ; 15
|
|
298: 90 83 st Z, r25
|
|
|
|
// ground the LED
|
|
DDRC &= 0xf0; // set all LEDs cathode as inputs
|
|
29a: 97 b1 in r25, 0x07 ; 7
|
|
29c: 90 7f andi r25, 0xF0 ; 240
|
|
29e: 97 b9 out 0x07, r25 ; 7
|
|
MCUCR |= (_BV(PUD)); // globally disable pullups
|
|
2a0: 95 b7 in r25, 0x35 ; 53
|
|
2a2: 90 61 ori r25, 0x10 ; 16
|
|
2a4: 95 bf out 0x35, r25 ; 53
|
|
DDRC |= (_BV(led)); // set our LED as an output
|
|
2a6: 47 b1 in r20, 0x07 ; 7
|
|
2a8: 21 e0 ldi r18, 0x01 ; 1
|
|
2aa: 30 e0 ldi r19, 0x00 ; 0
|
|
2ac: b9 01 movw r22, r18
|
|
2ae: 02 c0 rjmp .+4 ; 0x2b4 <rgbled_sensor_init+0x2a>
|
|
2b0: 66 0f add r22, r22
|
|
2b2: 77 1f adc r23, r23
|
|
2b4: 8a 95 dec r24
|
|
2b6: e2 f7 brpl .-8 ; 0x2b0 <rgbled_sensor_init+0x26>
|
|
2b8: cb 01 movw r24, r22
|
|
2ba: 46 2b or r20, r22
|
|
2bc: 47 b9 out 0x07, r20 ; 7
|
|
PORTC = (PORTC & 0xf0); // set all LEDs cathode low
|
|
2be: 98 b1 in r25, 0x08 ; 8
|
|
2c0: 90 7f andi r25, 0xF0 ; 240
|
|
2c2: 98 b9 out 0x08, r25 ; 8
|
|
PORTB |= (_BV(PORTB2)); // set anode high
|
|
2c4: 2a 9a sbi 0x05, 2 ; 5
|
|
|
|
// reverse LED bias
|
|
PORTC |= (_BV(led)); // set cathode high
|
|
2c6: 98 b1 in r25, 0x08 ; 8
|
|
2c8: 98 2b or r25, r24
|
|
2ca: 98 b9 out 0x08, r25 ; 8
|
|
PORTB &= ~(_BV(PORTB2)); // set anode low
|
|
2cc: 2a 98 cbi 0x05, 2 ; 5
|
|
#else
|
|
//round up by default
|
|
__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
|
|
#endif
|
|
|
|
__builtin_avr_delay_cycles(__ticks_dc);
|
|
2ce: 78 e0 ldi r23, 0x08 ; 8
|
|
2d0: 7a 95 dec r23
|
|
2d2: f1 f7 brne .-4 ; 0x2d0 <rgbled_sensor_init+0x46>
|
|
_delay_us(3); // allow it to charge fully
|
|
|
|
// set LED as input
|
|
DDRC &= ~(_BV(led)); // set led cathode as input
|
|
2d4: 97 b1 in r25, 0x07 ; 7
|
|
2d6: 80 95 com r24
|
|
2d8: 98 23 and r25, r24
|
|
2da: 97 b9 out 0x07, r25 ; 7
|
|
PORTC &= ~(_BV(led)); // set led cathode pullup off
|
|
2dc: 98 b1 in r25, 0x08 ; 8
|
|
2de: 89 23 and r24, r25
|
|
2e0: 88 b9 out 0x08, r24 ; 8
|
|
MCUCR &= ~(_BV(PUD)); // re-enable global pullups
|
|
2e2: 85 b7 in r24, 0x35 ; 53
|
|
2e4: 8f 7e andi r24, 0xEF ; 239
|
|
2e6: 85 bf out 0x35, r24 ; 53
|
|
2e8: 08 95 ret
|
|
|
|
000002ea <rgbled_sensor_sensitivity>:
|
|
}
|
|
|
|
// starts ADC to read the value of charge remaining on the LED
|
|
void rgbled_sensor_sensitivity(uint8_t ledidx, uint8_t sensitivity)
|
|
{
|
|
if (ledidx <= 0x03) {
|
|
2ea: 84 30 cpi r24, 0x04 ; 4
|
|
2ec: 38 f4 brcc .+14 ; 0x2fc <rgbled_sensor_sensitivity+0x12>
|
|
if (sensitivity) {
|
|
2ee: 66 23 and r22, r22
|
|
2f0: 29 f0 breq .+10 ; 0x2fc <rgbled_sensor_sensitivity+0x12>
|
|
rgbled_sensitivity[ledidx] = sensitivity;
|
|
2f2: e8 2f mov r30, r24
|
|
2f4: f0 e0 ldi r31, 0x00 ; 0
|
|
2f6: e0 50 subi r30, 0x00 ; 0
|
|
2f8: ff 4f sbci r31, 0xFF ; 255
|
|
2fa: 60 83 st Z, r22
|
|
2fc: 08 95 ret
|
|
|
|
000002fe <rgbled_sensor_read_idx>:
|
|
}
|
|
}
|
|
|
|
void rgbled_sensor_read_idx(uint8_t ledidx)
|
|
{
|
|
rgbled_read_sel = ledidx & 0x03;
|
|
2fe: 83 70 andi r24, 0x03 ; 3
|
|
300: 80 93 05 01 sts 0x0105, r24 ; 0x800105 <rgbled_read_sel>
|
|
304: 08 95 ret
|
|
|
|
00000306 <rgbled_sensor_read>:
|
|
|
|
void rgbled_sensor_read()
|
|
{
|
|
uint8_t sens;
|
|
|
|
sens = rgbled_sensitivity[rgbled_read_sel];
|
|
306: 80 91 05 01 lds r24, 0x0105 ; 0x800105 <rgbled_read_sel>
|
|
30a: e8 2f mov r30, r24
|
|
30c: f0 e0 ldi r31, 0x00 ; 0
|
|
30e: e0 50 subi r30, 0x00 ; 0
|
|
310: ff 4f sbci r31, 0xFF ; 255
|
|
312: 90 81 ld r25, Z
|
|
if (!sens) sens = 1;
|
|
314: 91 11 cpse r25, r1
|
|
316: 01 c0 rjmp .+2 ; 0x31a <rgbled_sensor_read+0x14>
|
|
318: 91 e0 ldi r25, 0x01 ; 1
|
|
|
|
if (adc_read_step == 0) {
|
|
31a: 2e 2d mov r18, r14
|
|
31c: e1 10 cpse r14, r1
|
|
31e: 03 c0 rjmp .+6 ; 0x326 <rgbled_sensor_read+0x20>
|
|
// adc_init();
|
|
// clear ADC bias by reading ground
|
|
adc_channel(ADC_CHAN_GND, ADC_REF_AVCC);
|
|
320: 61 e0 ldi r22, 0x01 ; 1
|
|
322: 8f e0 ldi r24, 0x0F ; 15
|
|
324: 12 c0 rjmp .+36 ; 0x34a <rgbled_sensor_read+0x44>
|
|
} else if (adc_read_step == 1) {
|
|
326: 21 30 cpi r18, 0x01 ; 1
|
|
328: 19 f4 brne .+6 ; 0x330 <rgbled_sensor_read+0x2a>
|
|
adc_start(0, 0);
|
|
32a: 60 e0 ldi r22, 0x00 ; 0
|
|
32c: 80 e0 ldi r24, 0x00 ; 0
|
|
32e: 18 c0 rjmp .+48 ; 0x360 <rgbled_sensor_read+0x5a>
|
|
} else if (adc_read_step == 2) {
|
|
330: 22 30 cpi r18, 0x02 ; 2
|
|
332: 61 f4 brne .+24 ; 0x34c <rgbled_sensor_read+0x46>
|
|
// if the ADC is done, charge up LED for reading
|
|
if (adc_busy) {
|
|
334: 90 91 1f 01 lds r25, 0x011F ; 0x80011f <adc_busy>
|
|
338: 99 23 and r25, r25
|
|
33a: 19 f0 breq .+6 ; 0x342 <rgbled_sensor_read+0x3c>
|
|
adc_read_step--;
|
|
33c: ee 24 eor r14, r14
|
|
33e: e3 94 inc r14
|
|
340: 08 95 ret
|
|
} else {
|
|
rgbled_sensor_init(rgbled_read_sel);
|
|
342: a3 df rcall .-186 ; 0x28a <rgbled_sensor_init>
|
|
adc_channel(rgbled_read_sel, ADC_REF_NO_SET);
|
|
344: 6f ef ldi r22, 0xFF ; 255
|
|
346: 80 91 05 01 lds r24, 0x0105 ; 0x800105 <rgbled_read_sel>
|
|
34a: b6 ce rjmp .-660 ; 0xb8 <adc_channel>
|
|
}
|
|
} else if (adc_read_step == (2 + sens)) {
|
|
34c: 4e 2d mov r20, r14
|
|
34e: 50 e0 ldi r21, 0x00 ; 0
|
|
350: 89 2f mov r24, r25
|
|
352: 90 e0 ldi r25, 0x00 ; 0
|
|
354: 02 96 adiw r24, 0x02 ; 2
|
|
356: 48 17 cp r20, r24
|
|
358: 59 07 cpc r21, r25
|
|
35a: 19 f4 brne .+6 ; 0x362 <rgbled_sensor_read+0x5c>
|
|
// if vref has changed, it should be stable by now; start reading LED value
|
|
adc_start(3, 1);
|
|
35c: 61 e0 ldi r22, 0x01 ; 1
|
|
35e: 83 e0 ldi r24, 0x03 ; 3
|
|
360: cd ce rjmp .-614 ; 0xfc <adc_start>
|
|
} else if (adc_read_step > (2 + sens)) {
|
|
362: 84 17 cp r24, r20
|
|
364: 95 07 cpc r25, r21
|
|
366: 94 f4 brge .+36 ; 0x38c <rgbled_sensor_read+0x86>
|
|
adc_read_step--;
|
|
368: 21 50 subi r18, 0x01 ; 1
|
|
36a: e2 2e mov r14, r18
|
|
if (!adc_busy) {
|
|
36c: 80 91 1f 01 lds r24, 0x011F ; 0x80011f <adc_busy>
|
|
370: 81 11 cpse r24, r1
|
|
372: 0c c0 rjmp .+24 ; 0x38c <rgbled_sensor_read+0x86>
|
|
// we are done! :) finish up...
|
|
adc_channel(ADC_CHAN_GND, ADC_REF_NO_SET); // change ADC to not look at a real pin
|
|
374: 6f ef ldi r22, 0xFF ; 255
|
|
376: 8f e0 ldi r24, 0x0F ; 15
|
|
378: 9f de rcall .-706 ; 0xb8 <adc_channel>
|
|
rgbled_io_init(); // set LED pins up again
|
|
37a: 3b df rcall .-394 ; 0x1f2 <rgbled_io_init>
|
|
}
|
|
|
|
inline void timer1_pwm_reinit()
|
|
{
|
|
// enable pwm output on OCx pins
|
|
TCCR1A = (_BV(COM1A1)) | (_BV(COM1B1)) | (_BV(WGM11) | ~(_BV(WGM10)));
|
|
37c: 8e ef ldi r24, 0xFE ; 254
|
|
37e: 80 93 80 00 sts 0x0080, r24 ; 0x800080 <__EEPROM_REGION_LENGTH__+0x7f0080>
|
|
|
|
// set OC pins as outputs
|
|
DDRB |= (_BV(DDB2) | _BV(DDB1));
|
|
382: 84 b1 in r24, 0x04 ; 4
|
|
384: 86 60 ori r24, 0x06 ; 6
|
|
386: 84 b9 out 0x04, r24 ; 4
|
|
timer1_pwm_reinit(); // and set up PWM again
|
|
adc_read_mode = 0; // clear ADC read mode
|
|
388: 10 92 20 01 sts 0x0120, r1 ; 0x800120 <adc_read_mode>
|
|
38c: 08 95 ret
|
|
|
|
0000038e <pegleg_cmd>:
|
|
return 0;
|
|
}
|
|
|
|
static uint8_t pegleg_cmd()
|
|
{
|
|
switch (comm_cmd) {
|
|
38e: 8f 2d mov r24, r15
|
|
390: 4f 2d mov r20, r15
|
|
392: 50 e0 ldi r21, 0x00 ; 0
|
|
394: 4a 31 cpi r20, 0x1A ; 26
|
|
396: 51 05 cpc r21, r1
|
|
398: 08 f0 brcs .+2 ; 0x39c <pegleg_cmd+0xe>
|
|
39a: 75 c0 rjmp .+234 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
39c: fa 01 movw r30, r20
|
|
39e: ec 5e subi r30, 0xEC ; 236
|
|
3a0: ff 4f sbci r31, 0xFF ; 255
|
|
3a2: 09 94 ijmp
|
|
// no command: we just ACK this as we shouldn't ever get here
|
|
case MODE_NONE: {
|
|
comm_cmd = 0;
|
|
3a4: f1 2c mov r15, r1
|
|
comm_timeout = 0;
|
|
3a6: 10 92 2a 01 sts 0x012A, r1 ; 0x80012a <comm_timeout>
|
|
break;
|
|
3aa: 08 95 ret
|
|
}
|
|
|
|
// standard commands
|
|
case MODE_EXT_CMD: { // used for more commands
|
|
if (comm_data_idx >= 1) {
|
|
3ac: 80 91 33 01 lds r24, 0x0133 ; 0x800133 <comm_data_idx>
|
|
3b0: 88 23 and r24, r24
|
|
3b2: 09 f4 brne .+2 ; 0x3b6 <pegleg_cmd+0x28>
|
|
3b4: 6c c0 rjmp .+216 ; 0x48e <__LOCK_REGION_LENGTH__+0x8e>
|
|
comm_cmd = comm_data[1];
|
|
3b6: f0 90 30 01 lds r15, 0x0130 ; 0x800130 <comm_data+0x1>
|
|
// set data index to last (will be reset on next data sent)
|
|
// and also reset timeout since this is effectively a new command
|
|
comm_data_idx = COMM_DATA_SIZE - 1;
|
|
3ba: 83 e0 ldi r24, 0x03 ; 3
|
|
3bc: 80 93 33 01 sts 0x0133, r24 ; 0x800133 <comm_data_idx>
|
|
3c0: 50 c0 rjmp .+160 ; 0x462 <__LOCK_REGION_LENGTH__+0x62>
|
|
}
|
|
break;
|
|
}
|
|
|
|
case MODE_LED_SET_LEVEL: { // sets PWM rate for the 8 PWM LEDs
|
|
if (comm_data[0] < 4) {
|
|
3c2: e0 91 2f 01 lds r30, 0x012F ; 0x80012f <comm_data>
|
|
3c6: e4 30 cpi r30, 0x04 ; 4
|
|
3c8: 20 f4 brcc .+8 ; 0x3d2 <pegleg_cmd+0x44>
|
|
rgbled_pwm_lf[comm_data[0]] = comm_data[1];
|
|
3ca: f0 e0 ldi r31, 0x00 ; 0
|
|
3cc: eb 5d subi r30, 0xDB ; 219
|
|
3ce: fe 4f sbci r31, 0xFE ; 254
|
|
3d0: 06 c0 rjmp .+12 ; 0x3de <pegleg_cmd+0x50>
|
|
} else if (comm_data[0] < 8) {
|
|
3d2: e8 30 cpi r30, 0x08 ; 8
|
|
3d4: 08 f0 brcs .+2 ; 0x3d8 <pegleg_cmd+0x4a>
|
|
3d6: 44 c0 rjmp .+136 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
rgbled_pwm_rt[comm_data[0] - 4] = comm_data[1];
|
|
3d8: f0 e0 ldi r31, 0x00 ; 0
|
|
3da: e3 5e subi r30, 0xE3 ; 227
|
|
3dc: fe 4f sbci r31, 0xFE ; 254
|
|
3de: 80 91 30 01 lds r24, 0x0130 ; 0x800130 <comm_data+0x1>
|
|
3e2: 80 83 st Z, r24
|
|
3e4: 3d c0 rjmp .+122 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
}
|
|
|
|
case MODE_TEMPSENSOR_CAL: {
|
|
// to use this function, make sure the temperature has been previously read.
|
|
// calculates the appropriate offset based on the reported temperature.
|
|
if (comm_data_idx >= 1) {
|
|
3e6: 80 91 33 01 lds r24, 0x0133 ; 0x800133 <comm_data_idx>
|
|
3ea: 88 23 and r24, r24
|
|
3ec: 09 f4 brne .+2 ; 0x3f0 <pegleg_cmd+0x62>
|
|
3ee: 4f c0 rjmp .+158 ; 0x48e <__LOCK_REGION_LENGTH__+0x8e>
|
|
// update the offset
|
|
if (adc_result[ADC_CHAN_TEMP]) {
|
|
3f0: 80 91 1d 01 lds r24, 0x011D ; 0x80011d <adc_result+0x10>
|
|
3f4: 90 91 1e 01 lds r25, 0x011E ; 0x80011e <adc_result+0x11>
|
|
3f8: 89 2b or r24, r25
|
|
3fa: 09 f4 brne .+2 ; 0x3fe <pegleg_cmd+0x70>
|
|
3fc: 44 c0 rjmp .+136 ; 0x486 <__LOCK_REGION_LENGTH__+0x86>
|
|
temp_offset = adc_result[ADC_CHAN_TEMP] - (int8_t)comm_data[1];
|
|
3fe: 60 91 1d 01 lds r22, 0x011D ; 0x80011d <adc_result+0x10>
|
|
402: 70 91 1e 01 lds r23, 0x011E ; 0x80011e <adc_result+0x11>
|
|
406: 80 91 30 01 lds r24, 0x0130 ; 0x800130 <comm_data+0x1>
|
|
40a: 68 1b sub r22, r24
|
|
40c: 71 09 sbc r23, r1
|
|
40e: 87 fd sbrc r24, 7
|
|
410: 73 95 inc r23
|
|
412: 70 93 07 01 sts 0x0107, r23 ; 0x800107 <temp_offset+0x1>
|
|
416: 60 93 06 01 sts 0x0106, r22 ; 0x800106 <temp_offset>
|
|
// write it to eeprom
|
|
eeprom_write_word((uint16_t *)EEPROM_ADDR_TEMPCAL, temp_offset);
|
|
41a: 8e e3 ldi r24, 0x3E ; 62
|
|
41c: 90 e0 ldi r25, 0x00 ; 0
|
|
41e: 24 d2 rcall .+1096 ; 0x868 <eeprom_write_word>
|
|
420: 1f c0 rjmp .+62 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
}
|
|
|
|
case MODE_EEPROM_READ: {
|
|
// our data packet is already set; ready for read.
|
|
// but if the host keeps writing...
|
|
if (comm_data_idx > 1) {
|
|
422: 80 91 33 01 lds r24, 0x0133 ; 0x800133 <comm_data_idx>
|
|
426: 82 30 cpi r24, 0x02 ; 2
|
|
428: d8 f4 brcc .+54 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
42a: 1d c0 rjmp .+58 ; 0x466 <__LOCK_REGION_LENGTH__+0x66>
|
|
}
|
|
|
|
// immediate commands
|
|
case MODE_TEMPSENSOR_READ: {
|
|
// attempt another read
|
|
if (!adc_read_mode) {
|
|
42c: 80 91 20 01 lds r24, 0x0120 ; 0x800120 <adc_read_mode>
|
|
430: 81 11 cpse r24, r1
|
|
432: 17 c0 rjmp .+46 ; 0x462 <__LOCK_REGION_LENGTH__+0x62>
|
|
adc_read_mode = 0;
|
|
434: 10 92 20 01 sts 0x0120, r1 ; 0x800120 <adc_read_mode>
|
|
adc_read_step = 0;
|
|
438: e1 2c mov r14, r1
|
|
adc_read_mode = ADC_MODE_TEMPSENSOR;
|
|
43a: 88 e0 ldi r24, 0x08 ; 8
|
|
43c: 80 93 20 01 sts 0x0120, r24 ; 0x800120 <adc_read_mode>
|
|
440: 10 c0 rjmp .+32 ; 0x462 <__LOCK_REGION_LENGTH__+0x62>
|
|
// data will probably be prior data unless the host waits. (need to verify)
|
|
comm_timeout = 0;
|
|
break;
|
|
}
|
|
case MODE_LIGHTSENSOR_READ: {
|
|
if (!adc_read_mode) {
|
|
442: 80 91 20 01 lds r24, 0x0120 ; 0x800120 <adc_read_mode>
|
|
446: 81 11 cpse r24, r1
|
|
448: 0c c0 rjmp .+24 ; 0x462 <__LOCK_REGION_LENGTH__+0x62>
|
|
// set the led and step to first step
|
|
adc_read_mode = 0;
|
|
44a: 10 92 20 01 sts 0x0120, r1 ; 0x800120 <adc_read_mode>
|
|
adc_read_step = 0;
|
|
44e: e1 2c mov r14, r1
|
|
rgbled_sensor_read_idx(comm_data[0]);
|
|
450: 80 91 2f 01 lds r24, 0x012F ; 0x80012f <comm_data>
|
|
454: 54 df rcall .-344 ; 0x2fe <rgbled_sensor_read_idx>
|
|
adc_read_mode = ADC_MODE_LIGHTSENSOR;
|
|
456: 81 e0 ldi r24, 0x01 ; 1
|
|
458: f1 cf rjmp .-30 ; 0x43c <__LOCK_REGION_LENGTH__+0x3c>
|
|
break;
|
|
}
|
|
case MODE_SLEEP: {
|
|
// put this bitch to bed.
|
|
// we'll wake up when we get another I2C command.
|
|
pirate_sleep_mode = SLEEP_MODE_PWR_DOWN;
|
|
45a: 84 e0 ldi r24, 0x04 ; 4
|
|
45c: 80 93 09 01 sts 0x0109, r24 ; 0x800109 <pirate_sleep_mode>
|
|
// TODO: come up with an implementation that isn't shitty
|
|
}
|
|
|
|
case MODE_AUX_PIN_GET: {
|
|
// TODO: implement when response sending is ...implemented
|
|
comm_cmd = 0;
|
|
460: f1 2c mov r15, r1
|
|
comm_timeout = 0;
|
|
462: 10 92 2a 01 sts 0x012A, r1 ; 0x80012a <comm_timeout>
|
|
comm_timeout = 0;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
466: 80 e0 ldi r24, 0x00 ; 0
|
|
|
|
case MODE_AUX_PIN_GET: {
|
|
// TODO: implement when response sending is ...implemented
|
|
comm_cmd = 0;
|
|
comm_timeout = 0;
|
|
break;
|
|
468: 08 95 ret
|
|
}
|
|
case MODE_LIGHTSENSOR_SENS: { // 0x10 0x19 <led 0-3> <sens 1-200>
|
|
if (comm_data_idx >= 1) {
|
|
46a: 80 91 33 01 lds r24, 0x0133 ; 0x800133 <comm_data_idx>
|
|
46e: 88 23 and r24, r24
|
|
470: 71 f0 breq .+28 ; 0x48e <__LOCK_REGION_LENGTH__+0x8e>
|
|
if ((comm_data[0] <= 0x03) && (comm_data[1])) {
|
|
472: 80 91 2f 01 lds r24, 0x012F ; 0x80012f <comm_data>
|
|
476: 84 30 cpi r24, 0x04 ; 4
|
|
478: 98 f7 brcc .-26 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
47a: 60 91 30 01 lds r22, 0x0130 ; 0x800130 <comm_data+0x1>
|
|
47e: 66 23 and r22, r22
|
|
480: 79 f3 breq .-34 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
rgbled_sensor_sensitivity(comm_data[0], comm_data[1]);
|
|
482: 33 df rcall .-410 ; 0x2ea <rgbled_sensor_sensitivity>
|
|
484: ed cf rjmp .-38 ; 0x460 <__LOCK_REGION_LENGTH__+0x60>
|
|
}
|
|
|
|
// invalid commands
|
|
default: {
|
|
// send NAK
|
|
comm_cmd = 0;
|
|
486: f1 2c mov r15, r1
|
|
comm_timeout = 0;
|
|
488: 10 92 2a 01 sts 0x012A, r1 ; 0x80012a <comm_timeout>
|
|
return 1;
|
|
48c: 81 e0 ldi r24, 0x01 ; 1
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
48e: 08 95 ret
|
|
|
|
00000490 <i2c_slave_tx.constprop.4>:
|
|
|
|
/* sending */
|
|
static uint8_t i2c_slave_tx(uint8_t byte, uint8_t is_last_byte)
|
|
{
|
|
// load data
|
|
TWDR = byte;
|
|
490: 80 93 bb 00 sts 0x00BB, r24 ; 0x8000bb <__EEPROM_REGION_LENGTH__+0x7f00bb>
|
|
|
|
// start sending
|
|
TWCR |= _BV(TWINT);
|
|
494: ec eb ldi r30, 0xBC ; 188
|
|
496: f0 e0 ldi r31, 0x00 ; 0
|
|
498: 80 81 ld r24, Z
|
|
49a: 80 68 ori r24, 0x80 ; 128
|
|
49c: 80 83 st Z, r24
|
|
|
|
if (is_last_byte) {
|
|
// this is all the data we have to send; send a nack after this byte
|
|
i2c_disable_slave();
|
|
49e: 80 81 ld r24, Z
|
|
4a0: 8f 7b andi r24, 0xBF ; 191
|
|
4a2: 80 83 st Z, r24
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
4a4: 80 e0 ldi r24, 0x00 ; 0
|
|
4a6: 08 95 ret
|
|
|
|
000004a8 <pegleg_data_tx>:
|
|
/* comms */
|
|
static inline uint8_t pegleg_data_tx()
|
|
{
|
|
uint8_t ret;
|
|
|
|
switch (comm_cmd) {
|
|
4a8: 8f 2d mov r24, r15
|
|
4aa: 88 30 cpi r24, 0x08 ; 8
|
|
4ac: b9 f0 breq .+46 ; 0x4dc <pegleg_data_tx+0x34>
|
|
4ae: 89 30 cpi r24, 0x09 ; 9
|
|
4b0: c1 f0 breq .+48 ; 0x4e2 <pegleg_data_tx+0x3a>
|
|
4b2: 84 30 cpi r24, 0x04 ; 4
|
|
4b4: 51 f5 brne .+84 ; 0x50a <pegleg_data_tx+0x62>
|
|
case MODE_EEPROM_READ: {
|
|
if (comm_data[0] < 64) {
|
|
4b6: 80 91 2f 01 lds r24, 0x012F ; 0x80012f <comm_data>
|
|
4ba: 80 34 cpi r24, 0x40 ; 64
|
|
4bc: 28 f4 brcc .+10 ; 0x4c8 <pegleg_data_tx+0x20>
|
|
i2c_slave_tx(eeprom_read_byte((uint8_t *)(uint16_t)comm_data[0]), 1);
|
|
4be: 90 e0 ldi r25, 0x00 ; 0
|
|
4c0: c8 d1 rcall .+912 ; 0x852 <eeprom_read_byte>
|
|
4c2: e6 df rcall .-52 ; 0x490 <i2c_slave_tx.constprop.4>
|
|
ret = 1;
|
|
4c4: 81 e0 ldi r24, 0x01 ; 1
|
|
4c6: 06 c0 rjmp .+12 ; 0x4d4 <pegleg_data_tx+0x2c>
|
|
} else {
|
|
// invalid address...
|
|
i2c_disable_slave();
|
|
4c8: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
4cc: 8f 7b andi r24, 0xBF ; 191
|
|
4ce: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
ret = 255;
|
|
4d2: 8f ef ldi r24, 0xFF ; 255
|
|
}
|
|
comm_cmd = 0;
|
|
4d4: f1 2c mov r15, r1
|
|
comm_timeout = 0;
|
|
4d6: 10 92 2a 01 sts 0x012A, r1 ; 0x80012a <comm_timeout>
|
|
4da: 08 95 ret
|
|
return ret;
|
|
}
|
|
|
|
case MODE_TEMPSENSOR_READ: {
|
|
i2c_slave_tx(temperature, 1);
|
|
4dc: 80 91 08 01 lds r24, 0x0108 ; 0x800108 <temperature>
|
|
4e0: 0e c0 rjmp .+28 ; 0x4fe <pegleg_data_tx+0x56>
|
|
comm_cmd = 0;
|
|
comm_timeout = 0;
|
|
return 1;
|
|
}
|
|
case MODE_LIGHTSENSOR_READ: {
|
|
i2c_slave_tx(adc_result[comm_data[0] & 0x03] >> 2, 1);
|
|
4e2: e0 91 2f 01 lds r30, 0x012F ; 0x80012f <comm_data>
|
|
4e6: e3 70 andi r30, 0x03 ; 3
|
|
4e8: f0 e0 ldi r31, 0x00 ; 0
|
|
4ea: ee 0f add r30, r30
|
|
4ec: ff 1f adc r31, r31
|
|
4ee: e3 5f subi r30, 0xF3 ; 243
|
|
4f0: fe 4f sbci r31, 0xFE ; 254
|
|
4f2: 80 81 ld r24, Z
|
|
4f4: 91 81 ldd r25, Z+1 ; 0x01
|
|
4f6: 96 95 lsr r25
|
|
4f8: 87 95 ror r24
|
|
4fa: 96 95 lsr r25
|
|
4fc: 87 95 ror r24
|
|
4fe: c8 df rcall .-112 ; 0x490 <i2c_slave_tx.constprop.4>
|
|
comm_cmd = 0;
|
|
500: f1 2c mov r15, r1
|
|
comm_timeout = 0;
|
|
502: 10 92 2a 01 sts 0x012A, r1 ; 0x80012a <comm_timeout>
|
|
return 1;
|
|
506: 81 e0 ldi r24, 0x01 ; 1
|
|
508: 08 95 ret
|
|
}
|
|
|
|
default: {
|
|
// nothing active; invalid :(
|
|
i2c_disable_slave();
|
|
50a: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
50e: 8f 7b andi r24, 0xBF ; 191
|
|
510: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
return 255;
|
|
514: 8f ef ldi r24, 0xFF ; 255
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
516: 08 95 ret
|
|
|
|
00000518 <tempsensor_process>:
|
|
uint8_t tempsensor_process()
|
|
{
|
|
int8_t temp_gain;
|
|
int8_t temp_adj;
|
|
|
|
temp_adj = adc_result[ADC_CHAN_TEMP] - temp_offset; // our offset adjusted temperature
|
|
518: 80 91 1d 01 lds r24, 0x011D ; 0x80011d <adc_result+0x10>
|
|
51c: 90 91 1e 01 lds r25, 0x011E ; 0x80011e <adc_result+0x11>
|
|
520: 90 91 06 01 lds r25, 0x0106 ; 0x800106 <temp_offset>
|
|
524: 89 1b sub r24, r25
|
|
temp_gain = temp_adj >> 3; // our gain adjust amount
|
|
526: 98 2f mov r25, r24
|
|
528: 95 95 asr r25
|
|
52a: 95 95 asr r25
|
|
52c: 95 95 asr r25
|
|
while (temp_gain > 0) {temp_gain--; temp_adj--;}; // correct positive gain
|
|
while (temp_gain < 0) {temp_gain++; temp_adj++;}; // correct negative gain
|
|
|
|
// save temperature
|
|
return temp_adj;
|
|
}
|
|
52e: 89 1b sub r24, r25
|
|
530: 08 95 ret
|
|
|
|
00000532 <tempsensor_read>:
|
|
|
|
void tempsensor_read()
|
|
{
|
|
if (adc_read_step == 0) {
|
|
532: 8e 2d mov r24, r14
|
|
534: e1 10 cpse r14, r1
|
|
536: 03 c0 rjmp .+6 ; 0x53e <tempsensor_read+0xc>
|
|
// select temperature channel
|
|
adc_channel(ADC_CHAN_TEMP, ADC_REF_BANDGAP);
|
|
538: 62 e0 ldi r22, 0x02 ; 2
|
|
53a: 88 e0 ldi r24, 0x08 ; 8
|
|
53c: bd cd rjmp .-1158 ; 0xb8 <adc_channel>
|
|
|
|
} else if (adc_read_step == 3) {
|
|
53e: 83 30 cpi r24, 0x03 ; 3
|
|
540: 19 f4 brne .+6 ; 0x548 <tempsensor_read+0x16>
|
|
// we've waited 1.5ms so the bandgap voltage should have been set.
|
|
// start conversion after bandgap ref change timeout per datasheet
|
|
adc_start(4, 1);
|
|
542: 61 e0 ldi r22, 0x01 ; 1
|
|
544: 84 e0 ldi r24, 0x04 ; 4
|
|
546: da cd rjmp .-1100 ; 0xfc <adc_start>
|
|
|
|
} else if (adc_read_step > 3) {
|
|
548: 84 30 cpi r24, 0x04 ; 4
|
|
54a: 70 f0 brcs .+28 ; 0x568 <tempsensor_read+0x36>
|
|
adc_read_step--;
|
|
54c: 81 50 subi r24, 0x01 ; 1
|
|
54e: e8 2e mov r14, r24
|
|
|
|
if (!adc_busy) {
|
|
550: 80 91 1f 01 lds r24, 0x011F ; 0x80011f <adc_busy>
|
|
554: 81 11 cpse r24, r1
|
|
556: 08 c0 rjmp .+16 ; 0x568 <tempsensor_read+0x36>
|
|
// revert reference to AVCC...per the datasheet only changes to
|
|
// bandgap should take ~1ms but changes back to AVCC seem to
|
|
// take a while to be accurate as well
|
|
adc_channel(ADC_CHAN_GND, ADC_REF_AVCC);
|
|
558: 61 e0 ldi r22, 0x01 ; 1
|
|
55a: 8f e0 ldi r24, 0x0F ; 15
|
|
55c: ad dd rcall .-1190 ; 0xb8 <adc_channel>
|
|
adc_read_mode = 0;
|
|
55e: 10 92 20 01 sts 0x0120, r1 ; 0x800120 <adc_read_mode>
|
|
temperature = tempsensor_process();
|
|
562: da df rcall .-76 ; 0x518 <tempsensor_process>
|
|
564: 80 93 08 01 sts 0x0108, r24 ; 0x800108 <temperature>
|
|
568: 08 95 ret
|
|
|
|
0000056a <main>:
|
|
/* func */
|
|
static void system_init()
|
|
{
|
|
// make SURE we are running at 8MHz
|
|
// do this by first enabling clock divider setup mode,
|
|
CLKPR = _BV(CLKPCE);
|
|
56a: 80 e8 ldi r24, 0x80 ; 128
|
|
56c: 80 93 61 00 sts 0x0061, r24 ; 0x800061 <__EEPROM_REGION_LENGTH__+0x7f0061>
|
|
// and disabling any divider
|
|
CLKPR = 0;
|
|
570: 10 92 61 00 sts 0x0061, r1 ; 0x800061 <__EEPROM_REGION_LENGTH__+0x7f0061>
|
|
}
|
|
|
|
static void system_io_init()
|
|
{
|
|
// enable break-before-make outputs on all IO
|
|
PORTCR |= (_BV(BBMA) | _BV(BBMB) | _BV(BBMC) | _BV(BBMD));
|
|
574: 82 b3 in r24, 0x12 ; 18
|
|
576: 80 6f ori r24, 0xF0 ; 240
|
|
578: 82 bb out 0x12, r24 ; 18
|
|
|
|
// set ALL pins as inputs except PB0
|
|
DDRA = 0x00;
|
|
57a: 1d b8 out 0x0d, r1 ; 13
|
|
DDRB = 0x01;
|
|
57c: 81 e0 ldi r24, 0x01 ; 1
|
|
57e: 84 b9 out 0x04, r24 ; 4
|
|
DDRC = 0x00;
|
|
580: 17 b8 out 0x07, r1 ; 7
|
|
DDRD = 0x00;
|
|
582: 1a b8 out 0x0a, r1 ; 10
|
|
|
|
// and enable pullups (this reduces power consumption)
|
|
// in the case of PB0, set it LOW
|
|
PORTA = 0xff;
|
|
584: cf ef ldi r28, 0xFF ; 255
|
|
586: ce b9 out 0x0e, r28 ; 14
|
|
PORTB = 0xfe;
|
|
588: de ef ldi r29, 0xFE ; 254
|
|
58a: d5 b9 out 0x05, r29 ; 5
|
|
PORTC = 0xff;
|
|
58c: c8 b9 out 0x08, r28 ; 8
|
|
PORTD = 0xff;
|
|
58e: cb b9 out 0x0b, r28 ; 11
|
|
// configure device and IO
|
|
system_init();
|
|
system_io_init();
|
|
|
|
// configure RGBLEDs
|
|
rgbled_io_init();
|
|
590: 30 de rcall .-928 ; 0x1f2 <rgbled_io_init>
|
|
/* configuration */
|
|
static inline void i2c_slave_init(uint8_t address, uint8_t enable_general_addr)
|
|
{
|
|
// set bitrate register, clear prescaler
|
|
// should get us 400KHz (fast mode) max rate
|
|
TWBR = 2;
|
|
592: 22 e0 ldi r18, 0x02 ; 2
|
|
594: 20 93 b8 00 sts 0x00B8, r18 ; 0x8000b8 <__EEPROM_REGION_LENGTH__+0x7f00b8>
|
|
TWSR = ~(_BV(TWPS0) | _BV(TWPS1));
|
|
598: 8c ef ldi r24, 0xFC ; 252
|
|
59a: 80 93 b9 00 sts 0x00B9, r24 ; 0x8000b9 <__EEPROM_REGION_LENGTH__+0x7f00b9>
|
|
|
|
// set slave address and clear address mask
|
|
TWAR = ((address << 1) | (enable_general_addr & 1));
|
|
59e: 86 ee ldi r24, 0xE6 ; 230
|
|
5a0: 80 93 ba 00 sts 0x00BA, r24 ; 0x8000ba <__EEPROM_REGION_LENGTH__+0x7f00ba>
|
|
TWAMR = 0;
|
|
5a4: 10 92 bd 00 sts 0x00BD, r1 ; 0x8000bd <__EEPROM_REGION_LENGTH__+0x7f00bd>
|
|
|
|
// enable auto-ack, enable TWI, and enable the TWI interrupt
|
|
TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
|
|
5a8: 85 e4 ldi r24, 0x45 ; 69
|
|
5aa: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
|
|
/* implementations */
|
|
inline static void timer0_init()
|
|
{
|
|
// make sure timer is enabled
|
|
PRR &= ~PRTIM0;
|
|
5ae: 80 91 64 00 lds r24, 0x0064 ; 0x800064 <__EEPROM_REGION_LENGTH__+0x7f0064>
|
|
5b2: 8a 7f andi r24, 0xFA ; 250
|
|
5b4: 80 93 64 00 sts 0x0064, r24 ; 0x800064 <__EEPROM_REGION_LENGTH__+0x7f0064>
|
|
|
|
// enable timer with prescale divider /64, enable TOP mode
|
|
TCCR0A = _BV(CTC0) | (_BV(CS00) | _BV(CS01) | ~(_BV(CS02)));
|
|
5b8: 9b ef ldi r25, 0xFB ; 251
|
|
5ba: 95 bd out 0x25, r25 ; 37
|
|
|
|
// set TOP level to be 62 to 63 counts; this will result in 2KHz cycle @8MHz
|
|
OCR0A = TIMER0_COMPARE;
|
|
5bc: 8d e3 ldi r24, 0x3D ; 61
|
|
5be: 87 bd out 0x27, r24 ; 39
|
|
|
|
// clear timer
|
|
TCNT0 = 0;
|
|
5c0: 16 bc out 0x26, r1 ; 38
|
|
|
|
// and enable OCA interrupt (we don't use overflow interrupt as we are in TOP mode)
|
|
TIMSK0 = _BV(OCIE0A);
|
|
5c2: 20 93 6e 00 sts 0x006E, r18 ; 0x80006e <__EEPROM_REGION_LENGTH__+0x7f006e>
|
|
#define timer0_set_compare(x) OCR0A = x
|
|
|
|
inline static void timer1_init()
|
|
{
|
|
// make sure timer is enabled
|
|
PRR &= ~PRTIM1;
|
|
5c6: 80 91 64 00 lds r24, 0x0064 ; 0x800064 <__EEPROM_REGION_LENGTH__+0x7f0064>
|
|
5ca: 8c 7f andi r24, 0xFC ; 252
|
|
5cc: 80 93 64 00 sts 0x0064, r24 ; 0x800064 <__EEPROM_REGION_LENGTH__+0x7f0064>
|
|
|
|
// clear PWM OCx
|
|
OCR1AH = 0xff; // sets temp register to 0xff
|
|
5d0: c0 93 89 00 sts 0x0089, r28 ; 0x800089 <__EEPROM_REGION_LENGTH__+0x7f0089>
|
|
OCR1AL = 0xff;
|
|
5d4: c0 93 88 00 sts 0x0088, r28 ; 0x800088 <__EEPROM_REGION_LENGTH__+0x7f0088>
|
|
OCR1BL = 0xff;
|
|
5d8: c0 93 8a 00 sts 0x008A, r28 ; 0x80008a <__EEPROM_REGION_LENGTH__+0x7f008a>
|
|
|
|
// clear timer
|
|
TCNT1H = 0; // sets temp register to 0
|
|
5dc: 10 92 85 00 sts 0x0085, r1 ; 0x800085 <__EEPROM_REGION_LENGTH__+0x7f0085>
|
|
TCNT1L = 0;
|
|
5e0: 10 92 84 00 sts 0x0084, r1 ; 0x800084 <__EEPROM_REGION_LENGTH__+0x7f0084>
|
|
|
|
// enable timer OC1 and OC2 clear on match / set at TOP, set to fast PWM mode 14 (ICR1 compare), prescaler off
|
|
// note: in PWM mode 14, pin PB0 can only be used as an output... =(
|
|
TCCR1A = (_BV(COM1A1)) | (_BV(COM1B1)) | (_BV(WGM11) | ~(_BV(WGM10)));
|
|
5e4: d0 93 80 00 sts 0x0080, r29 ; 0x800080 <__EEPROM_REGION_LENGTH__+0x7f0080>
|
|
TCCR1B = (_BV(WGM12) | _BV(WGM13)) | (_BV(CS10));
|
|
5e8: 89 e1 ldi r24, 0x19 ; 25
|
|
5ea: 80 93 81 00 sts 0x0081, r24 ; 0x800081 <__EEPROM_REGION_LENGTH__+0x7f0081>
|
|
TCCR1C = 0;
|
|
5ee: 10 92 82 00 sts 0x0082, r1 ; 0x800082 <__EEPROM_REGION_LENGTH__+0x7f0082>
|
|
|
|
// store timer1 mode to allow enabling / disabling timer
|
|
timer1_mode = TCCR1A;
|
|
5f2: 80 91 80 00 lds r24, 0x0080 ; 0x800080 <__EEPROM_REGION_LENGTH__+0x7f0080>
|
|
5f6: 80 93 29 01 sts 0x0129, r24 ; 0x800129 <timer1_mode>
|
|
|
|
// set ICR compare to result in a PWM rate of 8MHz / 252, or 32256Hz
|
|
// This is 16 PWM updates per timer0 63-count period (16.25 per 62-count period)
|
|
// In practice we don't get the first PWM output, so we get:
|
|
// 15/16 PWM / (x) LEDs = 31.25% max duty for 3 LED, 23.43% max duty for 4 LED
|
|
ICR1L = TIMER1_COMPARE;
|
|
5fa: 90 93 86 00 sts 0x0086, r25 ; 0x800086 <__EEPROM_REGION_LENGTH__+0x7f0086>
|
|
|
|
// set OC pins as outputs
|
|
DDRB |= (_BV(DDB2) | _BV(DDB1));
|
|
5fe: 84 b1 in r24, 0x04 ; 4
|
|
600: 86 60 ori r24, 0x06 ; 6
|
|
602: 84 b9 out 0x04, r24 ; 4
|
|
|
|
// disable interrupts
|
|
TIMSK1 = 0;
|
|
604: 10 92 6f 00 sts 0x006F, r1 ; 0x80006f <__EEPROM_REGION_LENGTH__+0x7f006f>
|
|
timer0_init();
|
|
// configure led pwm timer
|
|
timer1_init();
|
|
|
|
// initialize adc
|
|
adc_init();
|
|
608: 45 dd rcall .-1398 ; 0x94 <adc_init>
|
|
// todo: figure out wtf I meant by this note in 2014 (this is me in 2023)
|
|
// looking at the code, it looks like a pin needs manually changed to calibrate.
|
|
// todo: add a zeroing offset calibration command to the command protocol?
|
|
|
|
// is pin PA2 low? (pin 3 on attiny88 - is pulled up - short to pin 5 / ground somewhere)
|
|
if ((PINA & _BV(PINA2)) == 0) {
|
|
60a: 62 99 sbic 0x0c, 2 ; 12
|
|
60c: 23 c0 rjmp .+70 ; 0x654 <main+0xea>
|
|
// turn on the ADC, wait for it to warm up
|
|
adc_init();
|
|
60e: 42 dd rcall .-1404 ; 0x94 <adc_init>
|
|
#else
|
|
//round up by default
|
|
__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
|
|
#endif
|
|
|
|
__builtin_avr_delay_cycles(__ticks_dc);
|
|
610: 2f ef ldi r18, 0xFF ; 255
|
|
612: 80 e7 ldi r24, 0x70 ; 112
|
|
614: 92 e0 ldi r25, 0x02 ; 2
|
|
616: 21 50 subi r18, 0x01 ; 1
|
|
618: 80 40 sbci r24, 0x00 ; 0
|
|
61a: 90 40 sbci r25, 0x00 ; 0
|
|
61c: e1 f7 brne .-8 ; 0x616 <main+0xac>
|
|
61e: 00 c0 rjmp .+0 ; 0x620 <main+0xb6>
|
|
620: 00 00 nop
|
|
_delay_ms(100); // todo: is this right? this seems slow
|
|
|
|
// is the pin still low? not a glitch?
|
|
if ((PINA & _BV(PINA2)) == 0) {
|
|
622: 62 99 sbic 0x0c, 2 ; 12
|
|
624: 17 c0 rjmp .+46 ; 0x654 <main+0xea>
|
|
// enable interrupts
|
|
sei();
|
|
626: 78 94 sei
|
|
|
|
// start reading the temp sensor; stall until adc is done
|
|
adc_read_mode = ADC_MODE_TEMPSENSOR;
|
|
628: 88 e0 ldi r24, 0x08 ; 8
|
|
62a: 80 93 20 01 sts 0x0120, r24 ; 0x800120 <adc_read_mode>
|
|
tempsensor_read();
|
|
62e: 81 df rcall .-254 ; 0x532 <tempsensor_read>
|
|
while (adc_busy);
|
|
630: 80 91 1f 01 lds r24, 0x011F ; 0x80011f <adc_busy>
|
|
634: 81 11 cpse r24, r1
|
|
636: fc cf rjmp .-8 ; 0x630 <main+0xc6>
|
|
|
|
// here's our correction factor!
|
|
temp_offset = adc_result[ADC_CHAN_TEMP];
|
|
638: 60 91 1d 01 lds r22, 0x011D ; 0x80011d <adc_result+0x10>
|
|
63c: 70 91 1e 01 lds r23, 0x011E ; 0x80011e <adc_result+0x11>
|
|
640: 70 93 07 01 sts 0x0107, r23 ; 0x800107 <temp_offset+0x1>
|
|
644: 60 93 06 01 sts 0x0106, r22 ; 0x800106 <temp_offset>
|
|
|
|
// write it to eeprom
|
|
eeprom_write_word((uint16_t *)EEPROM_ADDR_TEMPCAL, temp_offset);
|
|
648: 8e e3 ldi r24, 0x3E ; 62
|
|
64a: 90 e0 ldi r25, 0x00 ; 0
|
|
64c: 0d d1 rcall .+538 ; 0x868 <eeprom_write_word>
|
|
|
|
// and that's it - we're done.
|
|
adc_read_mode = 0;
|
|
64e: 10 92 20 01 sts 0x0120, r1 ; 0x800120 <adc_read_mode>
|
|
652: 0d c0 rjmp .+26 ; 0x66e <main+0x104>
|
|
return;
|
|
}
|
|
}
|
|
|
|
// not saving a value - read the value from eeprom
|
|
temp_offset = eeprom_read_word((uint16_t *)EEPROM_ADDR_TEMPCAL);
|
|
654: 8e e3 ldi r24, 0x3E ; 62
|
|
656: 90 e0 ldi r25, 0x00 ; 0
|
|
658: 03 d1 rcall .+518 ; 0x860 <eeprom_read_word>
|
|
|
|
// does it seem invalid?
|
|
if (temp_offset > 560) {
|
|
65a: 81 33 cpi r24, 0x31 ; 49
|
|
65c: 22 e0 ldi r18, 0x02 ; 2
|
|
65e: 92 07 cpc r25, r18
|
|
660: 14 f0 brlt .+4 ; 0x666 <main+0xfc>
|
|
// yeah, this isn't right. load rough value for 0degC from datasheet.
|
|
// but you really should calibrate your chip, you lazy fuck.
|
|
temp_offset = 273;
|
|
662: 81 e1 ldi r24, 0x11 ; 17
|
|
664: 91 e0 ldi r25, 0x01 ; 1
|
|
666: 90 93 07 01 sts 0x0107, r25 ; 0x800107 <temp_offset+0x1>
|
|
66a: 80 93 06 01 sts 0x0106, r24 ; 0x800106 <temp_offset>
|
|
tempsensor_cal();
|
|
|
|
// and now we wait.
|
|
while (1) {
|
|
// set sleep mode, then set for idle sleep (CPU off, all peripherals on)
|
|
set_sleep_mode(pirate_sleep_mode);
|
|
66e: 83 b7 in r24, 0x33 ; 51
|
|
670: 89 7f andi r24, 0xF9 ; 249
|
|
672: 90 91 09 01 lds r25, 0x0109 ; 0x800109 <pirate_sleep_mode>
|
|
676: 89 2b or r24, r25
|
|
678: 83 bf out 0x33, r24 ; 51
|
|
pirate_sleep_mode = SLEEP_MODE_IDLE;
|
|
67a: 10 92 09 01 sts 0x0109, r1 ; 0x800109 <pirate_sleep_mode>
|
|
|
|
// re-enable interrupts and nap.
|
|
sei();
|
|
67e: 78 94 sei
|
|
sleep_mode();
|
|
680: 83 b7 in r24, 0x33 ; 51
|
|
682: 81 60 ori r24, 0x01 ; 1
|
|
684: 83 bf out 0x33, r24 ; 51
|
|
686: 88 95 sleep
|
|
688: 83 b7 in r24, 0x33 ; 51
|
|
68a: 8e 7f andi r24, 0xFE ; 254
|
|
68c: 83 bf out 0x33, r24 ; 51
|
|
68e: ef cf rjmp .-34 ; 0x66e <main+0x104>
|
|
|
|
00000690 <__vector_19>:
|
|
|
|
#include "config.h"
|
|
|
|
|
|
ISR(TWI_vect)
|
|
{
|
|
690: 1f 92 push r1
|
|
692: 0f 92 push r0
|
|
694: 0f b6 in r0, 0x3f ; 63
|
|
696: 0f 92 push r0
|
|
698: 11 24 eor r1, r1
|
|
69a: 2f 93 push r18
|
|
69c: 3f 93 push r19
|
|
69e: 4f 93 push r20
|
|
6a0: 5f 93 push r21
|
|
6a2: 6f 93 push r22
|
|
6a4: 7f 93 push r23
|
|
6a6: 8f 93 push r24
|
|
6a8: 9f 93 push r25
|
|
6aa: af 93 push r26
|
|
6ac: bf 93 push r27
|
|
6ae: ef 93 push r30
|
|
6b0: ff 93 push r31
|
|
// i2c is low priority - allow it to be interrupted
|
|
// sei();
|
|
|
|
// figure out wtf to do
|
|
switch (TWSR & 0xf8) { // TWI state
|
|
6b2: 80 91 b9 00 lds r24, 0x00B9 ; 0x8000b9 <__EEPROM_REGION_LENGTH__+0x7f00b9>
|
|
6b6: 88 7f andi r24, 0xF8 ; 248
|
|
6b8: 80 3a cpi r24, 0xA0 ; 160
|
|
6ba: f1 f1 breq .+124 ; 0x738 <__vector_19+0xa8>
|
|
6bc: 60 f4 brcc .+24 ; 0x6d6 <__vector_19+0x46>
|
|
6be: 88 36 cpi r24, 0x68 ; 104
|
|
6c0: 09 f4 brne .+2 ; 0x6c4 <__vector_19+0x34>
|
|
6c2: 3f c0 rjmp .+126 ; 0x742 <__vector_19+0xb2>
|
|
6c4: 28 f4 brcc .+10 ; 0x6d0 <__vector_19+0x40>
|
|
6c6: 88 23 and r24, r24
|
|
6c8: 91 f1 breq .+100 ; 0x72e <__vector_19+0x9e>
|
|
6ca: 80 36 cpi r24, 0x60 ; 96
|
|
6cc: d1 f1 breq .+116 ; 0x742 <__vector_19+0xb2>
|
|
6ce: 34 c0 rjmp .+104 ; 0x738 <__vector_19+0xa8>
|
|
6d0: 80 38 cpi r24, 0x80 ; 128
|
|
6d2: 39 f0 breq .+14 ; 0x6e2 <__vector_19+0x52>
|
|
6d4: 31 c0 rjmp .+98 ; 0x738 <__vector_19+0xa8>
|
|
6d6: 88 3b cpi r24, 0xB8 ; 184
|
|
6d8: 41 f1 breq .+80 ; 0x72a <__vector_19+0x9a>
|
|
6da: 70 f5 brcc .+92 ; 0x738 <__vector_19+0xa8>
|
|
6dc: 88 3a cpi r24, 0xA8 ; 168
|
|
6de: 29 f1 breq .+74 ; 0x72a <__vector_19+0x9a>
|
|
6e0: 2b c0 rjmp .+86 ; 0x738 <__vector_19+0xa8>
|
|
case 0x78: {
|
|
// unused: this is for genaddr mode.
|
|
}
|
|
*/
|
|
case 0x80: { // slave data receive w/ACK returned
|
|
if (pegleg_data_rx(TWDR)) {
|
|
6e2: 80 91 bb 00 lds r24, 0x00BB ; 0x8000bb <__EEPROM_REGION_LENGTH__+0x7f00bb>
|
|
return 0;
|
|
}
|
|
|
|
static uint8_t pegleg_data_rx(uint8_t data)
|
|
{
|
|
if (comm_cmd == MODE_NONE) {
|
|
6e6: f1 10 cpse r15, r1
|
|
6e8: 0f c0 rjmp .+30 ; 0x708 <__vector_19+0x78>
|
|
// we aren't processing any commands, so this must be a new command/request.
|
|
// first 4 bits = command
|
|
comm_cmd = data >> 4;
|
|
6ea: 98 2f mov r25, r24
|
|
6ec: 92 95 swap r25
|
|
6ee: 9f 70 andi r25, 0x0F ; 15
|
|
6f0: f9 2e mov r15, r25
|
|
// last 4 bits = optional data
|
|
comm_data[0] = data & 0x0f;
|
|
6f2: 98 2f mov r25, r24
|
|
6f4: 9f 70 andi r25, 0x0F ; 15
|
|
6f6: 90 93 2f 01 sts 0x012F, r25 ; 0x80012f <comm_data>
|
|
|
|
// clear our data watchdog and data index
|
|
comm_data_idx = 0;
|
|
6fa: 10 92 33 01 sts 0x0133, r1 ; 0x800133 <comm_data_idx>
|
|
comm_timeout = 0;
|
|
6fe: 10 92 2a 01 sts 0x012A, r1 ; 0x80012a <comm_timeout>
|
|
|
|
// if this is an immediate command, process it
|
|
if (data & 0x80) {
|
|
702: 87 ff sbrs r24, 7
|
|
704: 1e c0 rjmp .+60 ; 0x742 <__vector_19+0xb2>
|
|
706: 0a c0 rjmp .+20 ; 0x71c <__vector_19+0x8c>
|
|
return pegleg_cmd();
|
|
}
|
|
} else {
|
|
// command in progress - add data and continue
|
|
comm_data_idx++;
|
|
comm_data_idx &= (COMM_DATA_SIZE - 1); // data will LOOP in case of problems; TODO: NAK on failure
|
|
708: e0 91 33 01 lds r30, 0x0133 ; 0x800133 <comm_data_idx>
|
|
70c: ef 5f subi r30, 0xFF ; 255
|
|
70e: e3 70 andi r30, 0x03 ; 3
|
|
710: e0 93 33 01 sts 0x0133, r30 ; 0x800133 <comm_data_idx>
|
|
comm_data[comm_data_idx] = data;
|
|
714: f0 e0 ldi r31, 0x00 ; 0
|
|
716: e1 5d subi r30, 0xD1 ; 209
|
|
718: fe 4f sbci r31, 0xFE ; 254
|
|
71a: 80 83 st Z, r24
|
|
return pegleg_cmd();
|
|
71c: 38 de rcall .-912 ; 0x38e <pegleg_cmd>
|
|
71e: 88 23 and r24, r24
|
|
720: 81 f0 breq .+32 ; 0x742 <__vector_19+0xb2>
|
|
// I wanted to send a NAK, but TWI already sent an ACK. oh fucking well.
|
|
// send NACK if any further packets are received
|
|
i2c_disable_slave();
|
|
722: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
726: 8f 7b andi r24, 0xBF ; 191
|
|
728: 0a c0 rjmp .+20 ; 0x73e <__vector_19+0xae>
|
|
}
|
|
case 0xb8: { // slave read continues, master ACK'd last packet
|
|
// do we have a mode in progress?
|
|
// NOTE: by default, slave tx modes won't unset, but slave mode will be disabled
|
|
// when the last packet is sent, and re-enabled on the following ACK/NACK.
|
|
pegleg_data_tx();
|
|
72a: be de rcall .-644 ; 0x4a8 <pegleg_data_tx>
|
|
break;
|
|
72c: 0a c0 rjmp .+20 ; 0x742 <__vector_19+0xb2>
|
|
}
|
|
|
|
// ** ERROR AND UNHANDLED ** //
|
|
case 0x00: { // bus error
|
|
// set TWSTO, clear TWINT (by setting) as per datasheet
|
|
TWCR |= (_BV(TWSTO)) | (_BV(TWINT));
|
|
72e: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
732: 80 69 ori r24, 0x90 ; 144
|
|
734: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
break;
|
|
}
|
|
default: {
|
|
// something unhandled? fuck it, we want to be a slave.
|
|
// reset everything and start over.
|
|
i2c_enable_slave();
|
|
738: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
73c: 80 64 ori r24, 0x40 ; 64
|
|
73e: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
}
|
|
}
|
|
|
|
// done with this TWI bit
|
|
i2c_clear_int_flag();
|
|
742: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
746: 80 68 ori r24, 0x80 ; 128
|
|
748: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
}
|
|
74c: ff 91 pop r31
|
|
74e: ef 91 pop r30
|
|
750: bf 91 pop r27
|
|
752: af 91 pop r26
|
|
754: 9f 91 pop r25
|
|
756: 8f 91 pop r24
|
|
758: 7f 91 pop r23
|
|
75a: 6f 91 pop r22
|
|
75c: 5f 91 pop r21
|
|
75e: 4f 91 pop r20
|
|
760: 3f 91 pop r19
|
|
762: 2f 91 pop r18
|
|
764: 0f 90 pop r0
|
|
766: 0f be out 0x3f, r0 ; 63
|
|
768: 0f 90 pop r0
|
|
76a: 1f 90 pop r1
|
|
76c: 18 95 reti
|
|
|
|
0000076e <__vector_12>:
|
|
#include "i2c_interrupt.h"
|
|
|
|
|
|
/* ISR handlers */
|
|
ISR(TIMER0_COMPA_vect)
|
|
{
|
|
76e: 1f 92 push r1
|
|
770: 0f 92 push r0
|
|
772: 0f b6 in r0, 0x3f ; 63
|
|
774: 0f 92 push r0
|
|
776: 11 24 eor r1, r1
|
|
778: 2f 93 push r18
|
|
77a: 3f 93 push r19
|
|
77c: 4f 93 push r20
|
|
77e: 5f 93 push r21
|
|
780: 6f 93 push r22
|
|
782: 7f 93 push r23
|
|
784: 8f 93 push r24
|
|
786: 9f 93 push r25
|
|
788: af 93 push r26
|
|
78a: bf 93 push r27
|
|
78c: ef 93 push r30
|
|
78e: ff 93 push r31
|
|
* at the faster speed, this is ~3968 cycles/loop @8MHz.
|
|
****/
|
|
|
|
/* TIMEKEEPING */
|
|
// we only count a total of 10 seconds this way before we loop.
|
|
tim0_milli++;
|
|
790: 80 91 0b 01 lds r24, 0x010B ; 0x80010b <tim0_milli>
|
|
794: 8f 5f subi r24, 0xFF ; 255
|
|
if (tim0_milli >= 200) {
|
|
796: 88 3c cpi r24, 0xC8 ; 200
|
|
798: 18 f4 brcc .+6 ; 0x7a0 <__vector_12+0x32>
|
|
* at the faster speed, this is ~3968 cycles/loop @8MHz.
|
|
****/
|
|
|
|
/* TIMEKEEPING */
|
|
// we only count a total of 10 seconds this way before we loop.
|
|
tim0_milli++;
|
|
79a: 80 93 0b 01 sts 0x010B, r24 ; 0x80010b <tim0_milli>
|
|
79e: 0c c0 rjmp .+24 ; 0x7b8 <__vector_12+0x4a>
|
|
if (tim0_milli >= 200) {
|
|
tim0_milli = 0;
|
|
7a0: 10 92 0b 01 sts 0x010B, r1 ; 0x80010b <tim0_milli>
|
|
tim0_centi++;
|
|
7a4: 80 91 0a 01 lds r24, 0x010A ; 0x80010a <tim0_centi>
|
|
7a8: 8f 5f subi r24, 0xFF ; 255
|
|
if (tim0_centi >= 100) {
|
|
7aa: 84 36 cpi r24, 0x64 ; 100
|
|
7ac: 18 f4 brcc .+6 ; 0x7b4 <__vector_12+0x46>
|
|
/* TIMEKEEPING */
|
|
// we only count a total of 10 seconds this way before we loop.
|
|
tim0_milli++;
|
|
if (tim0_milli >= 200) {
|
|
tim0_milli = 0;
|
|
tim0_centi++;
|
|
7ae: 80 93 0a 01 sts 0x010A, r24 ; 0x80010a <tim0_centi>
|
|
7b2: 02 c0 rjmp .+4 ; 0x7b8 <__vector_12+0x4a>
|
|
if (tim0_centi >= 100) {
|
|
tim0_centi = 0;
|
|
7b4: 10 92 0a 01 sts 0x010A, r1 ; 0x80010a <tim0_centi>
|
|
}
|
|
}
|
|
|
|
// 2khz fix. our timer isn't evenly divisible to get our 2K, so we do this...
|
|
OCR0A = (OCR0A == TIMER0_COMPARE) ? TIMER0_COMPARE + 1 : TIMER0_COMPARE;
|
|
7b8: 87 b5 in r24, 0x27 ; 39
|
|
7ba: 8d 33 cpi r24, 0x3D ; 61
|
|
7bc: 11 f0 breq .+4 ; 0x7c2 <__vector_12+0x54>
|
|
7be: 8d e3 ldi r24, 0x3D ; 61
|
|
7c0: 01 c0 rjmp .+2 ; 0x7c4 <__vector_12+0x56>
|
|
7c2: 8e e3 ldi r24, 0x3E ; 62
|
|
7c4: 87 bd out 0x27, r24 ; 39
|
|
|
|
|
|
/* ADC / LIGHT SENSOR / TEMP SENSOR */
|
|
// main adc handler
|
|
if (adc_read_mode) {
|
|
7c6: 80 91 20 01 lds r24, 0x0120 ; 0x800120 <adc_read_mode>
|
|
7ca: 88 23 and r24, r24
|
|
7cc: 71 f0 breq .+28 ; 0x7ea <__vector_12+0x7c>
|
|
switch (adc_read_mode) {
|
|
7ce: 80 91 20 01 lds r24, 0x0120 ; 0x800120 <adc_read_mode>
|
|
7d2: 81 30 cpi r24, 0x01 ; 1
|
|
7d4: 21 f0 breq .+8 ; 0x7de <__vector_12+0x70>
|
|
7d6: 88 30 cpi r24, 0x08 ; 8
|
|
7d8: 19 f4 brne .+6 ; 0x7e0 <__vector_12+0x72>
|
|
case ADC_MODE_TEMPSENSOR: {
|
|
tempsensor_read();
|
|
7da: ab de rcall .-682 ; 0x532 <tempsensor_read>
|
|
break;
|
|
7dc: 01 c0 rjmp .+2 ; 0x7e0 <__vector_12+0x72>
|
|
}
|
|
case ADC_MODE_LIGHTSENSOR: {
|
|
rgbled_sensor_read();
|
|
7de: 93 dd rcall .-1242 ; 0x306 <rgbled_sensor_read>
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (adc_read_step <= 0xfe) {
|
|
7e0: 8e 2d mov r24, r14
|
|
7e2: 8f 3f cpi r24, 0xFF ; 255
|
|
7e4: 11 f0 breq .+4 ; 0x7ea <__vector_12+0x7c>
|
|
adc_read_step++;
|
|
7e6: 8f 5f subi r24, 0xFF ; 255
|
|
7e8: e8 2e mov r14, r24
|
|
|
|
|
|
/* LEDs */
|
|
// TODO: test common cathode mode
|
|
// figure out next LED to update (order is always RGB(X) repeating)
|
|
if (adc_read_mode != ADC_MODE_LIGHTSENSOR) {
|
|
7ea: 80 91 20 01 lds r24, 0x0120 ; 0x800120 <adc_read_mode>
|
|
7ee: 81 30 cpi r24, 0x01 ; 1
|
|
7f0: 41 f0 breq .+16 ; 0x802 <__vector_12+0x94>
|
|
rgbled_idx++;
|
|
7f2: 81 e0 ldi r24, 0x01 ; 1
|
|
7f4: 8d 0d add r24, r13
|
|
#ifdef LED_RGBX_4LED
|
|
rgbled_idx &= 0x03;
|
|
#else
|
|
if (rgbled_idx > 2) {
|
|
7f6: 83 30 cpi r24, 0x03 ; 3
|
|
7f8: 10 f4 brcc .+4 ; 0x7fe <__vector_12+0x90>
|
|
|
|
/* LEDs */
|
|
// TODO: test common cathode mode
|
|
// figure out next LED to update (order is always RGB(X) repeating)
|
|
if (adc_read_mode != ADC_MODE_LIGHTSENSOR) {
|
|
rgbled_idx++;
|
|
7fa: d8 2e mov r13, r24
|
|
7fc: 01 c0 rjmp .+2 ; 0x800 <__vector_12+0x92>
|
|
#ifdef LED_RGBX_4LED
|
|
rgbled_idx &= 0x03;
|
|
#else
|
|
if (rgbled_idx > 2) {
|
|
rgbled_idx = 0;
|
|
7fe: d1 2c mov r13, r1
|
|
}
|
|
#endif
|
|
|
|
// and now update them
|
|
rgbled_update();
|
|
800: 05 dd rcall .-1526 ; 0x20c <rgbled_update>
|
|
}
|
|
|
|
|
|
/* COMMAND IO */
|
|
// stop processing the command if it isn't complete in 100ms.
|
|
if (comm_cmd != MODE_NONE) {
|
|
802: ff 20 and r15, r15
|
|
804: a1 f0 breq .+40 ; 0x82e <__vector_12+0xc0>
|
|
if (++comm_timeout >= 50) {
|
|
806: 80 91 2a 01 lds r24, 0x012A ; 0x80012a <comm_timeout>
|
|
80a: 8f 5f subi r24, 0xFF ; 255
|
|
80c: 80 93 2a 01 sts 0x012A, r24 ; 0x80012a <comm_timeout>
|
|
810: 82 33 cpi r24, 0x32 ; 50
|
|
812: 68 f0 brcs .+26 ; 0x82e <__vector_12+0xc0>
|
|
comm_cmd = MODE_NONE;
|
|
814: f1 2c mov r15, r1
|
|
comm_timeout = 0;
|
|
816: 10 92 2a 01 sts 0x012A, r1 ; 0x80012a <comm_timeout>
|
|
i2c_disable_slave();
|
|
81a: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
81e: 8f 7b andi r24, 0xBF ; 191
|
|
820: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
i2c_enable_slave();
|
|
824: 80 91 bc 00 lds r24, 0x00BC ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
828: 80 64 ori r24, 0x40 ; 64
|
|
82a: 80 93 bc 00 sts 0x00BC, r24 ; 0x8000bc <__EEPROM_REGION_LENGTH__+0x7f00bc>
|
|
}
|
|
}
|
|
|
|
/* PROFILING */
|
|
// determine how much CPU usage we are consuming
|
|
tim0_profiler = TCNT0;
|
|
82e: 86 b5 in r24, 0x26 ; 38
|
|
}
|
|
830: ff 91 pop r31
|
|
832: ef 91 pop r30
|
|
834: bf 91 pop r27
|
|
836: af 91 pop r26
|
|
838: 9f 91 pop r25
|
|
83a: 8f 91 pop r24
|
|
83c: 7f 91 pop r23
|
|
83e: 6f 91 pop r22
|
|
840: 5f 91 pop r21
|
|
842: 4f 91 pop r20
|
|
844: 3f 91 pop r19
|
|
846: 2f 91 pop r18
|
|
848: 0f 90 pop r0
|
|
84a: 0f be out 0x3f, r0 ; 63
|
|
84c: 0f 90 pop r0
|
|
84e: 1f 90 pop r1
|
|
850: 18 95 reti
|
|
|
|
00000852 <eeprom_read_byte>:
|
|
852: f9 99 sbic 0x1f, 1 ; 31
|
|
854: fe cf rjmp .-4 ; 0x852 <eeprom_read_byte>
|
|
856: 81 bd out 0x21, r24 ; 33
|
|
858: f8 9a sbi 0x1f, 0 ; 31
|
|
85a: 99 27 eor r25, r25
|
|
85c: 80 b5 in r24, 0x20 ; 32
|
|
85e: 08 95 ret
|
|
|
|
00000860 <eeprom_read_word>:
|
|
860: a8 e1 ldi r26, 0x18 ; 24
|
|
862: b0 e0 ldi r27, 0x00 ; 0
|
|
864: 42 e0 ldi r20, 0x02 ; 2
|
|
866: 05 c0 rjmp .+10 ; 0x872 <eeprom_read_blraw>
|
|
|
|
00000868 <eeprom_write_word>:
|
|
868: 10 d0 rcall .+32 ; 0x88a <eeprom_write_byte>
|
|
86a: 27 2f mov r18, r23
|
|
86c: 0f c0 rjmp .+30 ; 0x88c <eeprom_write_r18>
|
|
|
|
0000086e <eeprom_read_block>:
|
|
86e: dc 01 movw r26, r24
|
|
870: 86 2f mov r24, r22
|
|
|
|
00000872 <eeprom_read_blraw>:
|
|
872: e8 2f mov r30, r24
|
|
874: f9 99 sbic 0x1f, 1 ; 31
|
|
876: fe cf rjmp .-4 ; 0x874 <eeprom_read_blraw+0x2>
|
|
878: 05 c0 rjmp .+10 ; 0x884 <eeprom_read_blraw+0x12>
|
|
87a: e1 bd out 0x21, r30 ; 33
|
|
87c: f8 9a sbi 0x1f, 0 ; 31
|
|
87e: e3 95 inc r30
|
|
880: 00 b4 in r0, 0x20 ; 32
|
|
882: 0d 92 st X+, r0
|
|
884: 41 50 subi r20, 0x01 ; 1
|
|
886: c8 f7 brcc .-14 ; 0x87a <eeprom_read_blraw+0x8>
|
|
888: 08 95 ret
|
|
|
|
0000088a <eeprom_write_byte>:
|
|
88a: 26 2f mov r18, r22
|
|
|
|
0000088c <eeprom_write_r18>:
|
|
88c: f9 99 sbic 0x1f, 1 ; 31
|
|
88e: fe cf rjmp .-4 ; 0x88c <eeprom_write_r18>
|
|
890: 1f ba out 0x1f, r1 ; 31
|
|
892: 81 bd out 0x21, r24 ; 33
|
|
894: 20 bd out 0x20, r18 ; 32
|
|
896: 0f b6 in r0, 0x3f ; 63
|
|
898: f8 94 cli
|
|
89a: fa 9a sbi 0x1f, 2 ; 31
|
|
89c: f9 9a sbi 0x1f, 1 ; 31
|
|
89e: 0f be out 0x3f, r0 ; 63
|
|
8a0: 01 96 adiw r24, 0x01 ; 1
|
|
8a2: 08 95 ret
|
|
|
|
000008a4 <_exit>:
|
|
8a4: f8 94 cli
|
|
|
|
000008a6 <__stop_program>:
|
|
8a6: ff cf rjmp .-2 ; 0x8a6 <__stop_program>
|