ardupilot/Tools/PPMEncoder/default/ap_ppm_encoder.lss

2637 lines
94 KiB
Plaintext

ap_ppm_encoder.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000014 00800100 00000c1e 00000cd2 2**0
CONTENTS, ALLOC, LOAD, DATA
1 .text 00000c1e 00000000 00000000 000000b4 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .bss 0000001c 00800114 00800114 00000ce6 2**0
ALLOC
3 .eeprom 00000035 00810000 00810000 00000ce6 2**0
CONTENTS, ALLOC, LOAD, DATA
4 .debug_aranges 00000020 00000000 00000000 00000d1b 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_pubnames 0000022c 00000000 00000000 00000d3b 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_info 00000914 00000000 00000000 00000f67 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_abbrev 00000262 00000000 00000000 0000187b 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_line 00000c94 00000000 00000000 00001add 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_frame 00000100 00000000 00000000 00002774 2**2
CONTENTS, READONLY, DEBUGGING
10 .debug_str 0000043c 00000000 00000000 00002874 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_loc 000003b4 00000000 00000000 00002cb0 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_ranges 00000018 00000000 00000000 00003064 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 34 00 jmp 0x68 ; 0x68 <__ctors_end>
4: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
8: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
10: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
14: 0c 94 3f 02 jmp 0x47e ; 0x47e <__vector_5>
18: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
1c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
20: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
24: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
28: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
2c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
30: 0c 94 14 02 jmp 0x428 ; 0x428 <__vector_12>
34: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
38: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
3c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
40: 0c 94 03 02 jmp 0x406 ; 0x406 <__vector_16>
44: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
48: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
4c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
50: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
54: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
58: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
5c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
60: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
64: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
00000068 <__ctors_end>:
68: 11 24 eor r1, r1
6a: 1f be out 0x3f, r1 ; 63
6c: cf ef ldi r28, 0xFF ; 255
6e: d8 e0 ldi r29, 0x08 ; 8
70: de bf out 0x3e, r29 ; 62
72: cd bf out 0x3d, r28 ; 61
00000074 <__do_copy_data>:
74: 11 e0 ldi r17, 0x01 ; 1
76: a0 e0 ldi r26, 0x00 ; 0
78: b1 e0 ldi r27, 0x01 ; 1
7a: ee e1 ldi r30, 0x1E ; 30
7c: fc e0 ldi r31, 0x0C ; 12
7e: 02 c0 rjmp .+4 ; 0x84 <.do_copy_data_start>
00000080 <.do_copy_data_loop>:
80: 05 90 lpm r0, Z+
82: 0d 92 st X+, r0
00000084 <.do_copy_data_start>:
84: a4 31 cpi r26, 0x14 ; 20
86: b1 07 cpc r27, r17
88: d9 f7 brne .-10 ; 0x80 <.do_copy_data_loop>
0000008a <__do_clear_bss>:
8a: 11 e0 ldi r17, 0x01 ; 1
8c: a4 e1 ldi r26, 0x14 ; 20
8e: b1 e0 ldi r27, 0x01 ; 1
90: 01 c0 rjmp .+2 ; 0x94 <.do_clear_bss_start>
00000092 <.do_clear_bss_loop>:
92: 1d 92 st X+, r1
00000094 <.do_clear_bss_start>:
94: a0 33 cpi r26, 0x30 ; 48
96: b1 07 cpc r27, r17
98: e1 f7 brne .-8 ; 0x92 <.do_clear_bss_loop>
9a: 0e 94 57 04 call 0x8ae ; 0x8ae <main>
9e: 0c 94 0d 06 jmp 0xc1a ; 0xc1a <_exit>
000000a2 <__bad_interrupt>:
a2: 0c 94 00 00 jmp 0 ; 0x0 <__vectors>
000000a6 <eeprom_read_byte>:
/** \ingroup avr_eeprom
Read one byte from EEPROM address \a __p.
*/
__ATTR_PURE__ static __inline__ uint8_t eeprom_read_byte (const uint8_t *__p)
{
a6: 9c 01 movw r18, r24
do {} while (!eeprom_is_ready ());
a8: f9 99 sbic 0x1f, 1 ; 31
aa: fe cf rjmp .-4 ; 0xa8 <eeprom_read_byte+0x2>
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
ac: 32 bd out 0x22, r19 ; 34
ae: 21 bd out 0x21, r18 ; 33
/* Use inline assembly below as some AVRs have problems with accessing
EECR with STS instructions. For example, see errata for ATmega64.
The code below also assumes that EECR and EEDR are in the I/O space.
*/
uint8_t __result;
__asm__ __volatile__
b0: f8 9a sbi 0x1f, 0 ; 31
b2: 80 b5 in r24, 0x20 ; 32
: "i" (_SFR_IO_ADDR(EECR)),
"i" (EERE),
"i" (_SFR_IO_ADDR(EEDR))
);
return __result;
}
b4: 08 95 ret
000000b6 <eeprom_write_byte>:
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
b6: 9c 01 movw r18, r24
do {} while (!eeprom_is_ready ());
b8: f9 99 sbic 0x1f, 1 ; 31
ba: fe cf rjmp .-4 ; 0xb8 <eeprom_write_byte+0x2>
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
bc: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
be: 32 bd out 0x22, r19 ; 34
c0: 21 bd out 0x21, r18 ; 33
#endif
EEDR = __value;
c2: 60 bd out 0x20, r22 ; 32
__asm__ __volatile__ (
c4: 0f b6 in r0, 0x3f ; 63
c6: f8 94 cli
c8: fa 9a sbi 0x1f, 2 ; 31
ca: f9 9a sbi 0x1f, 1 ; 31
cc: 0f be out 0x3f, r0 ; 63
[__sreg] "i" (_SFR_IO_ADDR(SREG)),
[__eemwe] "i" (EEMWE),
[__eewe] "i" (EEWE)
: "r0"
);
}
ce: 08 95 ret
000000d0 <initialize_mcu>:
void initialize_mcu(void)
{
unsigned char x = 0;
unsigned int eep_address = 0;
asm("cli");
d0: f8 94 cli
STOP_TIMER0();
d2: 15 bc out 0x25, r1 ; 37
RESET_TIMER0();
d4: a8 9a sbi 0x15, 0 ; 21
d6: 16 bc out 0x26, r1 ; 38
d8: 10 92 1d 01 sts 0x011D, r1
/* Enable pwm mode 15 (fast pwm with top=OCR1A) and stop the timer. */
/* The timer compare module must be configured before the DDR register. */
// THE PPM GENERATOR IS CONFIGURED HERE !
#if RC_PPM_OUTPUT_TYPE == 0 // NEGATIVE PULSES
RC_TIMER1_MODE_REG = (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10);
dc: 83 e3 ldi r24, 0x33 ; 51
de: 80 93 80 00 sts 0x0080, r24
#endif
#if RC_PPM_OUTPUT_TYPE == 1 // POSITIVE PULSES
RC_TIMER1_MODE_REG = (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10);
#warning PPM output type set to POSITIVE PULSE
#endif
RC_TIMER1_PRESCALER_REG = (1<<WGM13)|(1<<WGM12);
e2: 88 e1 ldi r24, 0x18 ; 24
e4: 80 93 81 00 sts 0x0081, r24
RC_TIMER1_COMP1_REG = RC_RESET_PW_TIMER_VAL;
e8: 8c ee ldi r24, 0xEC ; 236
ea: 9c e2 ldi r25, 0x2C ; 44
ec: 90 93 89 00 sts 0x0089, r25
f0: 80 93 88 00 sts 0x0088, r24
RC_TIMER1_COMP2_REG = RC_PPM_SYNC_PW_VAL;
f4: 8c e2 ldi r24, 0x2C ; 44
f6: 91 e0 ldi r25, 0x01 ; 1
f8: 90 93 8b 00 sts 0x008B, r25
fc: 80 93 8a 00 sts 0x008A, r24
RC_TIMER1_TIMSK |= (1<<OCIE1B);
100: 80 91 6f 00 lds r24, 0x006F
104: 84 60 ori r24, 0x04 ; 4
106: 80 93 6f 00 sts 0x006F, r24
RC_TIMER1_TIFR |= ( (1<<OCIE1B)|(1<<TOIE1) );
10a: 86 b3 in r24, 0x16 ; 22
10c: 85 60 ori r24, 0x05 ; 5
10e: 86 bb out 0x16, r24 ; 22
/*Enable timer0 overflow interupt and timer1 compare B interrupt */
RC_TIMER0_TIMSK |= (1<<TOIE0);
110: 80 91 6e 00 lds r24, 0x006E
114: 81 60 ori r24, 0x01 ; 1
116: 80 93 6e 00 sts 0x006E, r24
RC_TIMER0_TIFR |= (1<<TOIE0);
11a: a8 9a sbi 0x15, 0 ; 21
RC_LED_PORT_OUT_REG &= (~(1<<RC_LED_PIN));
11c: 28 98 cbi 0x05, 0 ; 5
RC_LED_PORT_DDR_REG |= (1<<RC_LED_PIN);
11e: 20 9a sbi 0x04, 0 ; 4
LED_ON();
120: 28 9a sbi 0x05, 0 ; 5
RC_MUX_PORT_OUT_REG &= (~(1<<RC_MUX_PIN));
122: 29 98 cbi 0x05, 1 ; 5
RC_MUX_PORT_DDR_REG |= (1<<RC_MUX_PIN);
124: 21 9a sbi 0x04, 1 ; 4
MUX_ON();
126: 29 9a sbi 0x05, 1 ; 5
// make the setup pin an input and activate the pull up resistor on the setup pin.
RC_SETUP_DDR_REG &= (~(1<<RC_SETUP_PIN));
128: 24 98 cbi 0x04, 4 ; 4
RC_SETUP_PORT_OUT_REG |= (1<<RC_SETUP_PIN);
12a: 2c 9a sbi 0x05, 4 ; 5
/* configure the servo pins as inputs and activate their pull up resistors for noise reduction. */
RC_SERVO_PORT_DDR_REG = 0;
12c: 1a b8 out 0x0a, r1 ; 10
RC_SERVO_PORT_OUT_REG = 0xFF;
12e: 8f ef ldi r24, 0xFF ; 255
130: 8b b9 out 0x0b, r24 ; 11
isr_channel_number = RC_PPM_GEN_CHANNELS;
132: 88 e0 ldi r24, 0x08 ; 8
134: 80 93 15 01 sts 0x0115, r24
rc_lost_channel = (RC_LOST_CHANNEL-1);
138: 82 e0 ldi r24, 0x02 ; 2
13a: 80 93 12 01 sts 0x0112, r24
ppm_off_threshold = RC_PPM_OFF_THRESHOLD_VAL;
13e: 89 ee ldi r24, 0xE9 ; 233
140: 97 e0 ldi r25, 0x07 ; 7
142: 90 93 11 01 sts 0x0111, r25
146: 80 93 10 01 sts 0x0110, r24
14a: 80 ef ldi r24, 0xF0 ; 240
14c: 93 e0 ldi r25, 0x03 ; 3
14e: 10 c0 rjmp .+32 ; 0x170 <initialize_mcu+0xa0>
// VERSION CONTROL
x=0;
eep_address = (E2END - (sizeof(version_info)-1));
while(version_info[x])
{
if( (eep_address) < E2END)
150: 23 e0 ldi r18, 0x03 ; 3
152: 8f 3f cpi r24, 0xFF ; 255
154: 92 07 cpc r25, r18
156: 58 f4 brcc .+22 ; 0x16e <initialize_mcu+0x9e>
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
do {} while (!eeprom_is_ready ());
158: f9 99 sbic 0x1f, 1 ; 31
15a: fe cf rjmp .-4 ; 0x158 <initialize_mcu+0x88>
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
15c: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
15e: 92 bd out 0x22, r25 ; 34
160: 81 bd out 0x21, r24 ; 33
#endif
EEDR = __value;
162: e0 bd out 0x20, r30 ; 32
__asm__ __volatile__ (
164: 0f b6 in r0, 0x3f ; 63
166: f8 94 cli
168: fa 9a sbi 0x1f, 2 ; 31
16a: f9 9a sbi 0x1f, 1 ; 31
16c: 0f be out 0x3f, r0 ; 63
{
eeprom_write_byte( (unsigned char*)eep_address, version_info[x]);
}
eep_address++;
16e: 01 96 adiw r24, 0x01 ; 1
rc_lost_channel = (RC_LOST_CHANNEL-1);
ppm_off_threshold = RC_PPM_OFF_THRESHOLD_VAL;
// VERSION CONTROL
x=0;
eep_address = (E2END - (sizeof(version_info)-1));
while(version_info[x])
170: e8 2f mov r30, r24
172: e0 5f subi r30, 0xF0 ; 240
174: f0 e0 ldi r31, 0x00 ; 0
176: e0 50 subi r30, 0x00 ; 0
178: ff 4f sbci r31, 0xFF ; 255
17a: e0 81 ld r30, Z
17c: ee 23 and r30, r30
17e: 41 f7 brne .-48 ; 0x150 <initialize_mcu+0x80>
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
do {} while (!eeprom_is_ready ());
180: f9 99 sbic 0x1f, 1 ; 31
182: fe cf rjmp .-4 ; 0x180 <initialize_mcu+0xb0>
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
184: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
186: 8f ef ldi r24, 0xFF ; 255
188: 93 e0 ldi r25, 0x03 ; 3
18a: 92 bd out 0x22, r25 ; 34
18c: 81 bd out 0x21, r24 ; 33
#endif
EEDR = __value;
18e: 10 bc out 0x20, r1 ; 32
__asm__ __volatile__ (
190: 0f b6 in r0, 0x3f ; 63
192: f8 94 cli
194: fa 9a sbi 0x1f, 2 ; 31
196: f9 9a sbi 0x1f, 1 ; 31
198: 0f be out 0x3f, r0 ; 63
eep_address++;
x++;
}
eeprom_write_byte((unsigned char*)E2END, '\0'); //Terminate the version control string.
asm("sei");
19a: 78 94 sei
/* give some time for the pull up resistors to work. ~30 ms * 3 = 90 ms */
LED_OFF();
19c: 28 98 cbi 0x05, 0 ; 5
RESET_START_TIMER0();
19e: 15 bc out 0x25, r1 ; 37
1a0: a8 9a sbi 0x15, 0 ; 21
1a2: 16 bc out 0x26, r1 ; 38
1a4: 10 92 1d 01 sts 0x011D, r1
1a8: 82 e0 ldi r24, 0x02 ; 2
1aa: 85 bd out 0x25, r24 ; 37
1ac: 90 e0 ldi r25, 0x00 ; 0
for(x=0; x<3; x++)
{
wdt_reset();
1ae: a8 95 wdr
RESET_TIMER0();
1b0: a8 9a sbi 0x15, 0 ; 21
1b2: 16 bc out 0x26, r1 ; 38
1b4: 10 92 1d 01 sts 0x011D, r1
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
1b8: 80 91 1d 01 lds r24, 0x011D
1bc: 86 37 cpi r24, 0x76 ; 118
1be: e0 f3 brcs .-8 ; 0x1b8 <initialize_mcu+0xe8>
asm("sei");
/* give some time for the pull up resistors to work. ~30 ms * 3 = 90 ms */
LED_OFF();
RESET_START_TIMER0();
for(x=0; x<3; x++)
1c0: 9f 5f subi r25, 0xFF ; 255
1c2: 93 30 cpi r25, 0x03 ; 3
1c4: a1 f7 brne .-24 ; 0x1ae <initialize_mcu+0xde>
wdt_reset();
RESET_TIMER0();
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
}
x = 0;
STOP_TIMER0();
1c6: 15 bc out 0x25, r1 ; 37
RESET_TIMER0();
1c8: a8 9a sbi 0x15, 0 ; 21
1ca: 16 bc out 0x26, r1 ; 38
1cc: 10 92 1d 01 sts 0x011D, r1
LED_ON();
1d0: 28 9a sbi 0x05, 0 ; 5
to the timer1 compare module to initialize.
The timer1 compare module as the Mega 168 manual states must be initialized before setting the DDR register
of the OCR1X pins.
*/
//RC_PPM_PORT_OUT_REG &= (~(1<<RC_PPM_PIN));
RC_PPM_PORT_DDR_REG |= (1<<RC_PPM_PIN);
1d2: 22 9a sbi 0x04, 2 ; 4
return;
}
1d4: 08 95 ret
000001d6 <detect_connected_channels>:
/*22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222*/
/*33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333*/
unsigned char detect_connected_channels(void)
{
1d6: cf 93 push r28
1d8: df 93 push r29
/*
There must be no error in which channels are connected to the encoder
because this will have devastating effects later on.
*/
wdt_reset();
1da: a8 95 wdr
RESET_START_TIMER0();
1dc: 15 bc out 0x25, r1 ; 37
1de: a8 9a sbi 0x15, 0 ; 21
1e0: 16 bc out 0x26, r1 ; 38
1e2: 10 92 1d 01 sts 0x011D, r1
1e6: 82 e0 ldi r24, 0x02 ; 2
1e8: 85 bd out 0x25, r24 ; 37
1ea: f0 91 19 01 lds r31, 0x0119
1ee: a0 e0 ldi r26, 0x00 ; 0
1f0: 20 e0 ldi r18, 0x00 ; 0
1f2: 30 e0 ldi r19, 0x00 ; 0
for(channel=0; channel < RC_SERVO_INPUT_CHANNELS; channel++)
1f4: c1 e0 ldi r28, 0x01 ; 1
1f6: d0 e0 ldi r29, 0x00 ; 0
1f8: 29 c0 rjmp .+82 ; 0x24c <detect_connected_channels+0x76>
{
servo_connected = 0;
for(y=0; y<5; y++)
{
wdt_reset();
1fa: a8 95 wdr
RESET_TIMER0();
1fc: a8 9a sbi 0x15, 0 ; 21
1fe: 16 bc out 0x26, r1 ; 38
200: 10 92 1d 01 sts 0x011D, r1
204: e0 e0 ldi r30, 0x00 ; 0
206: 11 c0 rjmp .+34 ; 0x22a <detect_connected_channels+0x54>
x=0;
while(timer0.timer0[1] <= RC_MAX_TIMEOUT_VAL )
{
if(RC_SERVO_PORT_PIN_REG & (1<<channel)) { x=timer0.timer0[1]; }
208: 89 b1 in r24, 0x09 ; 9
20a: 90 e0 ldi r25, 0x00 ; 0
20c: 86 23 and r24, r22
20e: 97 23 and r25, r23
210: 89 2b or r24, r25
212: 11 f0 breq .+4 ; 0x218 <detect_connected_channels+0x42>
214: e0 91 1d 01 lds r30, 0x011D
if( (timer0.timer0[1] - x) >= RC_PULSE_TIMEOUT_VAL ){ servo_connected++; break; }
218: 80 91 1d 01 lds r24, 0x011D
21c: 90 e0 ldi r25, 0x00 ; 0
21e: 8e 1b sub r24, r30
220: 91 09 sbc r25, r1
222: 09 97 sbiw r24, 0x09 ; 9
224: 10 f0 brcs .+4 ; 0x22a <detect_connected_channels+0x54>
226: 5f 5f subi r21, 0xFF ; 255
228: 04 c0 rjmp .+8 ; 0x232 <detect_connected_channels+0x5c>
for(y=0; y<5; y++)
{
wdt_reset();
RESET_TIMER0();
x=0;
while(timer0.timer0[1] <= RC_MAX_TIMEOUT_VAL )
22a: 80 91 1d 01 lds r24, 0x011D
22e: 87 37 cpi r24, 0x77 ; 119
230: 58 f3 brcs .-42 ; 0x208 <detect_connected_channels+0x32>
{
if(RC_SERVO_PORT_PIN_REG & (1<<channel)) { x=timer0.timer0[1]; }
if( (timer0.timer0[1] - x) >= RC_PULSE_TIMEOUT_VAL ){ servo_connected++; break; }
}
if(servo_connected >= 3){ channel_mask |= (1<<channel); connected_channels++; break; }
232: 53 30 cpi r21, 0x03 ; 3
234: 18 f0 brcs .+6 ; 0x23c <detect_connected_channels+0x66>
236: f6 2b or r31, r22
238: af 5f subi r26, 0xFF ; 255
23a: 03 c0 rjmp .+6 ; 0x242 <detect_connected_channels+0x6c>
RESET_START_TIMER0();
for(channel=0; channel < RC_SERVO_INPUT_CHANNELS; channel++)
{
servo_connected = 0;
for(y=0; y<5; y++)
23c: 4f 5f subi r20, 0xFF ; 255
23e: 45 30 cpi r20, 0x05 ; 5
240: e1 f6 brne .-72 ; 0x1fa <detect_connected_channels+0x24>
242: 2f 5f subi r18, 0xFF ; 255
244: 3f 4f sbci r19, 0xFF ; 255
because this will have devastating effects later on.
*/
wdt_reset();
RESET_START_TIMER0();
for(channel=0; channel < RC_SERVO_INPUT_CHANNELS; channel++)
246: 28 30 cpi r18, 0x08 ; 8
248: 31 05 cpc r19, r1
24a: 51 f0 breq .+20 ; 0x260 <detect_connected_channels+0x8a>
24c: be 01 movw r22, r28
24e: 02 2e mov r0, r18
250: 02 c0 rjmp .+4 ; 0x256 <detect_connected_channels+0x80>
252: 66 0f add r22, r22
254: 77 1f adc r23, r23
256: 0a 94 dec r0
258: e2 f7 brpl .-8 ; 0x252 <detect_connected_channels+0x7c>
25a: 50 e0 ldi r21, 0x00 ; 0
25c: 40 e0 ldi r20, 0x00 ; 0
25e: cd cf rjmp .-102 ; 0x1fa <detect_connected_channels+0x24>
260: f0 93 19 01 sts 0x0119, r31
}
}
#endif
return(connected_channels);
}
264: 8a 2f mov r24, r26
266: df 91 pop r29
268: cf 91 pop r28
26a: 08 95 ret
0000026c <get_channel_pw>:
{
unsigned int pw = 0;
unsigned char pw_measurement_started = 0;
wdt_reset();
26c: a8 95 wdr
/* The servo input pins are already configured as inputs with pullup resistors. */
// First we must disable the pin interrupt.
RC_PIN_INT_EN_REG &= (~(1<<RC_PIN_INT_EN_BIT));
26e: 90 91 68 00 lds r25, 0x0068
272: 9b 7f andi r25, 0xFB ; 251
274: 90 93 68 00 sts 0x0068, r25
//Now we must load the pin interrupt mask register.
RC_PIN_INT_MASK_REG = (1<<pin);
278: 21 e0 ldi r18, 0x01 ; 1
27a: 30 e0 ldi r19, 0x00 ; 0
27c: 02 c0 rjmp .+4 ; 0x282 <get_channel_pw+0x16>
27e: 22 0f add r18, r18
280: 33 1f adc r19, r19
282: 8a 95 dec r24
284: e2 f7 brpl .-8 ; 0x27e <get_channel_pw+0x12>
286: 20 93 6d 00 sts 0x006D, r18
//Clear any pin interrupt flag set.
RC_PIN_INT_FLAG_REG |= (1<<RC_PIN_INT_FLAG_BIT);
28a: da 9a sbi 0x1b, 2 ; 27
// Clear the pin interrupt ISR detection variable
pin_interrupt_detected = 0;
28c: 10 92 14 01 sts 0x0114, r1
// Finally we can enable the pin interrupt again.
RC_PIN_INT_EN_REG |= (1<<RC_PIN_INT_EN_BIT);
290: 80 91 68 00 lds r24, 0x0068
294: 84 60 ori r24, 0x04 ; 4
296: 80 93 68 00 sts 0x0068, r24
// Set and start timer1
RESET_START_TIMER0();
29a: 15 bc out 0x25, r1 ; 37
29c: a8 9a sbi 0x15, 0 ; 21
29e: 16 bc out 0x26, r1 ; 38
2a0: 10 92 1d 01 sts 0x011D, r1
2a4: 82 e0 ldi r24, 0x02 ; 2
2a6: 85 bd out 0x25, r24 ; 37
2a8: 40 e0 ldi r20, 0x00 ; 0
2aa: 50 e0 ldi r21, 0x00 ; 0
2ac: 60 e0 ldi r22, 0x00 ; 0
while(1)
{
/* Wait until the pin change state. */
do{
if( timer0.timer0[1] >= RC_MAX_TIMEOUT_VAL )
2ae: 80 91 1d 01 lds r24, 0x011D
2b2: 86 37 cpi r24, 0x76 ; 118
2b4: 18 f0 brcs .+6 ; 0x2bc <get_channel_pw+0x50>
2b6: 20 e0 ldi r18, 0x00 ; 0
2b8: 30 e0 ldi r19, 0x00 ; 0
2ba: 1f c0 rjmp .+62 ; 0x2fa <get_channel_pw+0x8e>
{
return(0);
}
}while( pin_interrupt_detected == 0 );
2bc: 80 91 14 01 lds r24, 0x0114
2c0: 88 23 and r24, r24
2c2: a9 f3 breq .-22 ; 0x2ae <get_channel_pw+0x42>
pin_interrupt_detected = 0;
2c4: 10 92 14 01 sts 0x0114, r1
if( RC_SERVO_PORT_PIN_REG & (1<<pin) ) /* if the pin is high then give it a time stamp */
2c8: 89 b1 in r24, 0x09 ; 9
2ca: 90 e0 ldi r25, 0x00 ; 0
2cc: 82 23 and r24, r18
2ce: 93 23 and r25, r19
2d0: 89 2b or r24, r25
2d2: 31 f0 breq .+12 ; 0x2e0 <get_channel_pw+0x74>
{
pw = isr_timer0_16;
2d4: 40 91 16 01 lds r20, 0x0116
2d8: 50 91 17 01 lds r21, 0x0117
2dc: 61 e0 ldi r22, 0x01 ; 1
2de: e7 cf rjmp .-50 ; 0x2ae <get_channel_pw+0x42>
pw_measurement_started = 1; /* signal that this channel got it's timer stamp.*/
}else{
// If the pin is low and it already has a time stamp then we are done.
if( pw_measurement_started )
2e0: 66 23 and r22, r22
2e2: 29 f3 breq .-54 ; 0x2ae <get_channel_pw+0x42>
{
pw = isr_timer0_16 - pw;
2e4: 20 91 16 01 lds r18, 0x0116
2e8: 30 91 17 01 lds r19, 0x0117
2ec: 24 1b sub r18, r20
2ee: 35 0b sbc r19, r21
}
}
}
/*Stop the timer */
STOP_TIMER0();
2f0: 15 bc out 0x25, r1 ; 37
RESET_TIMER0();
2f2: a8 9a sbi 0x15, 0 ; 21
2f4: 16 bc out 0x26, r1 ; 38
2f6: 10 92 1d 01 sts 0x011D, r1
return((unsigned int)pw);
}
2fa: c9 01 movw r24, r18
2fc: 08 95 ret
000002fe <wait_for_rx>:
}
#else
void wait_for_rx(void)
{
2fe: 0f 93 push r16
300: 1f 93 push r17
unsigned int pw=0;
unsigned char x = 0;
unsigned char servo_connected = 0;
unsigned char channel = 0;
RESET_START_TIMER0();
302: 15 bc out 0x25, r1 ; 37
304: a8 9a sbi 0x15, 0 ; 21
306: 16 bc out 0x26, r1 ; 38
308: 10 92 1d 01 sts 0x011D, r1
30c: 82 e0 ldi r24, 0x02 ; 2
30e: 85 bd out 0x25, r24 ; 37
310: 00 e0 ldi r16, 0x00 ; 0
do{
for(channel=0; channel < RC_SERVO_INPUT_CHANNELS; channel++)
{
wdt_reset();
RESET_TIMER0();
312: 61 e0 ldi r22, 0x01 ; 1
314: 70 e0 ldi r23, 0x00 ; 0
316: 24 c0 rjmp .+72 ; 0x360 <wait_for_rx+0x62>
RESET_START_TIMER0();
do{
for(channel=0; channel < RC_SERVO_INPUT_CHANNELS; channel++)
{
wdt_reset();
318: a8 95 wdr
RESET_TIMER0();
31a: a8 9a sbi 0x15, 0 ; 21
31c: 16 bc out 0x26, r1 ; 38
31e: 10 92 1d 01 sts 0x011D, r1
322: 9b 01 movw r18, r22
324: 00 2e mov r0, r16
326: 02 c0 rjmp .+4 ; 0x32c <wait_for_rx+0x2e>
328: 22 0f add r18, r18
32a: 33 1f adc r19, r19
32c: 0a 94 dec r0
32e: e2 f7 brpl .-8 ; 0x328 <wait_for_rx+0x2a>
330: 40 e0 ldi r20, 0x00 ; 0
332: 0f c0 rjmp .+30 ; 0x352 <wait_for_rx+0x54>
servo_connected = 0;
x=0;
while(timer0.timer0[1] <= RC_MAX_TIMEOUT_VAL )
{
if(RC_SERVO_PORT_PIN_REG & (1<<channel)) { x=timer0.timer0[1]; }
334: 89 b1 in r24, 0x09 ; 9
336: 90 e0 ldi r25, 0x00 ; 0
338: 82 23 and r24, r18
33a: 93 23 and r25, r19
33c: 89 2b or r24, r25
33e: 11 f0 breq .+4 ; 0x344 <wait_for_rx+0x46>
340: 40 91 1d 01 lds r20, 0x011D
if( (timer0.timer0[1] - x) >= RC_PULSE_TIMEOUT_VAL ){ servo_connected = 1; break; }
344: 80 91 1d 01 lds r24, 0x011D
348: 90 e0 ldi r25, 0x00 ; 0
34a: 84 1b sub r24, r20
34c: 91 09 sbc r25, r1
34e: 09 97 sbiw r24, 0x09 ; 9
350: 50 f4 brcc .+20 ; 0x366 <wait_for_rx+0x68>
{
wdt_reset();
RESET_TIMER0();
servo_connected = 0;
x=0;
while(timer0.timer0[1] <= RC_MAX_TIMEOUT_VAL )
352: 80 91 1d 01 lds r24, 0x011D
356: 87 37 cpi r24, 0x77 ; 119
358: 68 f3 brcs .-38 ; 0x334 <wait_for_rx+0x36>
35a: 12 c0 rjmp .+36 ; 0x380 <wait_for_rx+0x82>
35c: 00 e0 ldi r16, 0x00 ; 0
35e: dc cf rjmp .-72 ; 0x318 <wait_for_rx+0x1a>
unsigned char servo_connected = 0;
unsigned char channel = 0;
RESET_START_TIMER0();
do{
for(channel=0; channel < RC_SERVO_INPUT_CHANNELS; channel++)
360: 08 30 cpi r16, 0x08 ; 8
362: d0 f2 brcs .-76 ; 0x318 <wait_for_rx+0x1a>
364: fb cf rjmp .-10 ; 0x35c <wait_for_rx+0x5e>
366: 10 e0 ldi r17, 0x00 ; 0
//Now test the found channel for a proper servo pulse.
x = 0;
while(1)
{
pw=get_channel_pw(channel);
368: 80 2f mov r24, r16
36a: 0e 94 36 01 call 0x26c ; 0x26c <get_channel_pw>
if( (pw > RC_SERVO_MIN_PW_VAL) && (pw < RC_SERVO_MAX_PW_VAL) ) { x++; }else{ x=0; }
36e: 81 52 subi r24, 0x21 ; 33
370: 93 40 sbci r25, 0x03 ; 3
372: 87 57 subi r24, 0x77 ; 119
374: 95 40 sbci r25, 0x05 ; 5
376: b8 f7 brcc .-18 ; 0x366 <wait_for_rx+0x68>
378: 1f 5f subi r17, 0xFF ; 255
if(x >= 3) { break; }
37a: 13 30 cpi r17, 0x03 ; 3
37c: a8 f3 brcs .-22 ; 0x368 <wait_for_rx+0x6a>
37e: 02 c0 rjmp .+4 ; 0x384 <wait_for_rx+0x86>
unsigned char servo_connected = 0;
unsigned char channel = 0;
RESET_START_TIMER0();
do{
for(channel=0; channel < RC_SERVO_INPUT_CHANNELS; channel++)
380: 0f 5f subi r16, 0xFF ; 255
382: ee cf rjmp .-36 ; 0x360 <wait_for_rx+0x62>
if( (pw > RC_SERVO_MIN_PW_VAL) && (pw < RC_SERVO_MAX_PW_VAL) ) { x++; }else{ x=0; }
if(x >= 3) { break; }
}
return;
}
384: 1f 91 pop r17
386: 0f 91 pop r16
388: 08 95 ret
0000038a <load_failsafe_values>:
/*77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777*/
/*88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888*/
void load_failsafe_values(void)
{
wdt_reset();
38a: a8 95 wdr
isr_channel_pw[0] = RC_FS_CH_1_TIMER_VAL;
38c: 8c ed ldi r24, 0xDC ; 220
38e: 95 e0 ldi r25, 0x05 ; 5
390: 90 93 1f 01 sts 0x011F, r25
394: 80 93 1e 01 sts 0x011E, r24
#if RC_PPM_GEN_CHANNELS >= 2
isr_channel_pw[1] = RC_FS_CH_2_TIMER_VAL;
398: 90 93 21 01 sts 0x0121, r25
39c: 80 93 20 01 sts 0x0120, r24
#endif
#if RC_PPM_GEN_CHANNELS >= 3
isr_channel_pw[2] = RC_FS_CH_3_TIMER_VAL;
3a0: 28 ee ldi r18, 0xE8 ; 232
3a2: 33 e0 ldi r19, 0x03 ; 3
3a4: 30 93 23 01 sts 0x0123, r19
3a8: 20 93 22 01 sts 0x0122, r18
#endif
#if RC_PPM_GEN_CHANNELS >= 4
isr_channel_pw[3] = RC_FS_CH_4_TIMER_VAL;
3ac: 90 93 25 01 sts 0x0125, r25
3b0: 80 93 24 01 sts 0x0124, r24
#endif
#if RC_PPM_GEN_CHANNELS >= 5
isr_channel_pw[4] = RC_FS_CH_5_TIMER_VAL;
3b4: 30 93 27 01 sts 0x0127, r19
3b8: 20 93 26 01 sts 0x0126, r18
#endif
#if RC_PPM_GEN_CHANNELS >= 6
isr_channel_pw[5] = RC_FS_CH_6_TIMER_VAL;
3bc: 30 93 29 01 sts 0x0129, r19
3c0: 20 93 28 01 sts 0x0128, r18
#endif
#if RC_PPM_GEN_CHANNELS >= 7
isr_channel_pw[6] = RC_FS_CH_7_TIMER_VAL;
3c4: 30 93 2b 01 sts 0x012B, r19
3c8: 20 93 2a 01 sts 0x012A, r18
#endif
#if RC_PPM_GEN_CHANNELS >= 8
isr_channel_pw[7] = RC_FS_CH_8_TIMER_VAL;
3cc: 30 93 2d 01 sts 0x012D, r19
3d0: 20 93 2c 01 sts 0x012C, r18
#endif
#if RC_PPM_GEN_CHANNELS >= 9
isr_channel_pw[8] = RC_FS_CH_8_TIMER_VAL;
#endif
isr_channel_pw[RC_PPM_GEN_CHANNELS] = RC_RESET_PW_TIMER_VAL;
3d4: 8c ee ldi r24, 0xEC ; 236
3d6: 9c e2 ldi r25, 0x2C ; 44
3d8: 90 93 2f 01 sts 0x012F, r25
3dc: 80 93 2e 01 sts 0x012E, r24
return;
}
3e0: 08 95 ret
000003e2 <mux_control>:
/*12121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212*/
void mux_control(void)
{
long PULSE_WIDTH = isr_channel_pw[RC_MUX_CHANNEL-1];
3e2: 80 91 2c 01 lds r24, 0x012C
3e6: 90 91 2d 01 lds r25, 0x012D
#if RC_MUX_REVERSE == 0
if((PULSE_WIDTH>RC_MUX_MIN)&&(PULSE_WIDTH<RC_MUX_MAX))
3ea: a0 e0 ldi r26, 0x00 ; 0
3ec: b0 e0 ldi r27, 0x00 ; 0
3ee: 01 97 sbiw r24, 0x01 ; 1
3f0: a1 09 sbc r26, r1
3f2: b1 09 sbc r27, r1
3f4: 81 5e subi r24, 0xE1 ; 225
3f6: 94 40 sbci r25, 0x04 ; 4
3f8: a0 40 sbci r26, 0x00 ; 0
3fa: b0 40 sbci r27, 0x00 ; 0
3fc: 10 f4 brcc .+4 ; 0x402 <mux_control+0x20>
{
MUX_ON();
3fe: 29 9a sbi 0x05, 1 ; 5
400: 08 95 ret
}
else
{
MUX_OFF();
402: 29 98 cbi 0x05, 1 ; 5
404: 08 95 ret
00000406 <__vector_16>:
/* INTERRUPT SERVICE ROUTINES */
/********************************************************************************************************/
//ISR(TIMER0_OVF_vect, ISR_NAKED)
ISR(TIMER0_OVF_vect)
{
406: 1f 92 push r1
408: 0f 92 push r0
40a: 0f b6 in r0, 0x3f ; 63
40c: 0f 92 push r0
40e: 11 24 eor r1, r1
410: 8f 93 push r24
timer0.timer0[1]++;
412: 80 91 1d 01 lds r24, 0x011D
416: 8f 5f subi r24, 0xFF ; 255
418: 80 93 1d 01 sts 0x011D, r24
return;
}
41c: 8f 91 pop r24
41e: 0f 90 pop r0
420: 0f be out 0x3f, r0 ; 63
422: 0f 90 pop r0
424: 1f 90 pop r1
426: 18 95 reti
00000428 <__vector_12>:
modifying their buffers and not the actual registers.
Both actual registers are updated when the timer reaches the OCR1A (TOP) value automatically.
This way the OCR1B interrupt can be delayed as needed without any loss of timing accuracy.
*/
ISR(TIMER1_COMPB_vect)
{
428: 1f 92 push r1
42a: 0f 92 push r0
42c: 0f b6 in r0, 0x3f ; 63
42e: 0f 92 push r0
430: 11 24 eor r1, r1
432: 8f 93 push r24
434: 9f 93 push r25
436: ef 93 push r30
438: ff 93 push r31
asm("sei");
43a: 78 94 sei
}
#endif
#if RC_CONSTANT_PPM_FRAME_TIME == 0
isr_channel_number++;
43c: 80 91 15 01 lds r24, 0x0115
440: 8f 5f subi r24, 0xFF ; 255
442: 80 93 15 01 sts 0x0115, r24
if( isr_channel_number >= (RC_PPM_GEN_CHANNELS + 1) ) {isr_channel_number = 0; }
446: 80 91 15 01 lds r24, 0x0115
44a: 89 30 cpi r24, 0x09 ; 9
44c: 10 f0 brcs .+4 ; 0x452 <__vector_12+0x2a>
44e: 10 92 15 01 sts 0x0115, r1
RC_TIMER1_COMP1_REG = isr_channel_pw[isr_channel_number];
452: e0 91 15 01 lds r30, 0x0115
456: f0 e0 ldi r31, 0x00 ; 0
458: ee 0f add r30, r30
45a: ff 1f adc r31, r31
45c: e2 5e subi r30, 0xE2 ; 226
45e: fe 4f sbci r31, 0xFE ; 254
460: 80 81 ld r24, Z
462: 91 81 ldd r25, Z+1 ; 0x01
464: 90 93 89 00 sts 0x0089, r25
468: 80 93 88 00 sts 0x0088, r24
#endif
return;
}
46c: ff 91 pop r31
46e: ef 91 pop r30
470: 9f 91 pop r25
472: 8f 91 pop r24
474: 0f 90 pop r0
476: 0f be out 0x3f, r0 ; 63
478: 0f 90 pop r0
47a: 1f 90 pop r1
47c: 18 95 reti
0000047e <__vector_5>:
/********************************************************************************************************/
ISR(PCINT2_vect)
{
47e: 1f 92 push r1
480: 0f 92 push r0
482: 0f b6 in r0, 0x3f ; 63
484: 0f 92 push r0
486: 11 24 eor r1, r1
488: 8f 93 push r24
48a: 9f 93 push r25
timer0.timer0[0]= TCNT0;
48c: 86 b5 in r24, 0x26 ; 38
48e: 80 93 1c 01 sts 0x011C, r24
if( RC_TIMER0_TIFR & (1<<TOIE0) ){RC_TIMER0_TIFR |= (1<<TOIE0); timer0.timer0[1]++; timer0.timer0[0]= 0; }
492: a8 9b sbis 0x15, 0 ; 21
494: 08 c0 rjmp .+16 ; 0x4a6 <__vector_5+0x28>
496: a8 9a sbi 0x15, 0 ; 21
498: 80 91 1d 01 lds r24, 0x011D
49c: 8f 5f subi r24, 0xFF ; 255
49e: 80 93 1d 01 sts 0x011D, r24
4a2: 10 92 1c 01 sts 0x011C, r1
isr_timer0_16 = timer0.timer0_16;
4a6: 80 91 1c 01 lds r24, 0x011C
4aa: 90 91 1d 01 lds r25, 0x011D
4ae: 90 93 17 01 sts 0x0117, r25
4b2: 80 93 16 01 sts 0x0116, r24
pin_interrupt_detected = 1;
4b6: 81 e0 ldi r24, 0x01 ; 1
4b8: 80 93 14 01 sts 0x0114, r24
return;
}
4bc: 9f 91 pop r25
4be: 8f 91 pop r24
4c0: 0f 90 pop r0
4c2: 0f be out 0x3f, r0 ; 63
4c4: 0f 90 pop r0
4c6: 1f 90 pop r1
4c8: 18 95 reti
000004ca <write_default_values_to_eeprom>:
/*33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333*/
/*44444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444*/
void write_default_values_to_eeprom(void)
{
4ca: cf 93 push r28
4cc: df 93 push r29
4ce: c4 e1 ldi r28, 0x14 ; 20
4d0: d0 e0 ldi r29, 0x00 ; 0
Write a word \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_word (uint16_t *__p, uint16_t __value)
{
#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
__eewr_word (__p, __value, eeprom_write_byte);
4d2: ce 01 movw r24, r28
4d4: 69 ee ldi r22, 0xE9 ; 233
4d6: 77 e0 ldi r23, 0x07 ; 7
4d8: 4b e5 ldi r20, 0x5B ; 91
4da: 50 e0 ldi r21, 0x00 ; 0
4dc: 0e 94 e4 05 call 0xbc8 ; 0xbc8 <__eewr_word>
4e0: 22 96 adiw r28, 0x02 ; 2
unsigned char x = 0;
for(x=0; x<(sizeof(ppm_off_threshold_e)/sizeof(int)); x++)
4e2: 30 e0 ldi r19, 0x00 ; 0
4e4: ca 32 cpi r28, 0x2A ; 42
4e6: d3 07 cpc r29, r19
4e8: a1 f7 brne .-24 ; 0x4d2 <write_default_values_to_eeprom+0x8>
4ea: 8a e2 ldi r24, 0x2A ; 42
4ec: 90 e0 ldi r25, 0x00 ; 0
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
#endif
EEDR = __value;
4ee: 22 e0 ldi r18, 0x02 ; 2
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
do {} while (!eeprom_is_ready ());
4f0: f9 99 sbic 0x1f, 1 ; 31
4f2: fe cf rjmp .-4 ; 0x4f0 <write_default_values_to_eeprom+0x26>
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
4f4: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
4f6: 92 bd out 0x22, r25 ; 34
4f8: 81 bd out 0x21, r24 ; 33
#endif
EEDR = __value;
4fa: 20 bd out 0x20, r18 ; 32
__asm__ __volatile__ (
4fc: 0f b6 in r0, 0x3f ; 63
4fe: f8 94 cli
500: fa 9a sbi 0x1f, 2 ; 31
502: f9 9a sbi 0x1f, 1 ; 31
504: 0f be out 0x3f, r0 ; 63
506: 01 96 adiw r24, 0x01 ; 1
{
eeprom_write_word(&ppm_off_threshold_e[x], RC_PPM_OFF_THRESHOLD_VAL);
}
for(x=0; x < (sizeof(rc_lost_channel_e)/sizeof(char)); x++)
508: 30 e0 ldi r19, 0x00 ; 0
50a: 85 33 cpi r24, 0x35 ; 53
50c: 93 07 cpc r25, r19
50e: 81 f7 brne .-32 ; 0x4f0 <write_default_values_to_eeprom+0x26>
{
eeprom_write_byte(&rc_lost_channel_e[x], (RC_LOST_CHANNEL - 1));
}
rc_lost_channel = (RC_LOST_CHANNEL - 1);
510: 82 e0 ldi r24, 0x02 ; 2
512: 80 93 12 01 sts 0x0112, r24
ppm_off_threshold = RC_PPM_OFF_THRESHOLD_VAL;
516: 89 ee ldi r24, 0xE9 ; 233
518: 97 e0 ldi r25, 0x07 ; 7
51a: 90 93 11 01 sts 0x0111, r25
51e: 80 93 10 01 sts 0x0110, r24
return;
}
522: df 91 pop r29
524: cf 91 pop r28
526: 08 95 ret
00000528 <check_for_setup_mode>:
/*66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666*/
/*77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777*/
void check_for_setup_mode(void)
{
528: 0f 93 push r16
52a: 1f 93 push r17
52c: cf 93 push r28
52e: df 93 push r29
unsigned char x = 0;
unsigned char y = 0;
//We have to make sure that the setup mode is requested.
wdt_reset();
530: a8 95 wdr
x=0;
y=0;
setup_mode = 1;
RESET_START_TIMER0();
532: 15 bc out 0x25, r1 ; 37
534: a8 9a sbi 0x15, 0 ; 21
536: 16 bc out 0x26, r1 ; 38
538: 10 92 1d 01 sts 0x011D, r1
53c: 82 e0 ldi r24, 0x02 ; 2
53e: 85 bd out 0x25, r24 ; 37
540: 90 e0 ldi r25, 0x00 ; 0
do{
if( (RC_SETUP_PIN_REG & (1<<RC_SETUP_PIN)) == 0){ x++; }else{ x=0; }
542: 1c 9b sbis 0x03, 4 ; 3
544: 02 c0 rjmp .+4 ; 0x54a <check_for_setup_mode+0x22>
546: 90 e0 ldi r25, 0x00 ; 0
548: 01 c0 rjmp .+2 ; 0x54c <check_for_setup_mode+0x24>
54a: 9f 5f subi r25, 0xFF ; 255
{
if(timer0.timer0[1] > RC_MAX_TIMEOUT_VAL ){setup_mode = 0; break; }
54c: 80 91 1d 01 lds r24, 0x011D
550: 87 37 cpi r24, 0x77 ; 119
552: 08 f0 brcs .+2 ; 0x556 <check_for_setup_mode+0x2e>
554: e7 c0 rjmp .+462 ; 0x724 <check_for_setup_mode+0x1fc>
}
}while(x < 100);
556: 94 36 cpi r25, 0x64 ; 100
558: a0 f3 brcs .-24 ; 0x542 <check_for_setup_mode+0x1a>
55a: d9 c0 rjmp .+434 ; 0x70e <check_for_setup_mode+0x1e6>
/****************************************************************************************************/
wdt_reset();
success = 0;
if(channels_in_use > 1 )
{
if( channel_mask & (1<<(RC_LOST_CHANNEL - 1)) )
55c: 80 91 19 01 lds r24, 0x0119
560: 82 ff sbrs r24, 2
562: 8e c0 rjmp .+284 ; 0x680 <check_for_setup_mode+0x158>
{
rc_lost_channel = (RC_LOST_CHANNEL - 1);
564: 82 e0 ldi r24, 0x02 ; 2
566: 80 93 12 01 sts 0x0112, r24
56a: 8a e2 ldi r24, 0x2A ; 42
56c: 90 e0 ldi r25, 0x00 ; 0
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
#endif
EEDR = __value;
56e: 22 e0 ldi r18, 0x02 ; 2
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
do {} while (!eeprom_is_ready ());
570: f9 99 sbic 0x1f, 1 ; 31
572: fe cf rjmp .-4 ; 0x570 <check_for_setup_mode+0x48>
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
574: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
576: 92 bd out 0x22, r25 ; 34
578: 81 bd out 0x21, r24 ; 33
#endif
EEDR = __value;
57a: 20 bd out 0x20, r18 ; 32
__asm__ __volatile__ (
57c: 0f b6 in r0, 0x3f ; 63
57e: f8 94 cli
580: fa 9a sbi 0x1f, 2 ; 31
582: f9 9a sbi 0x1f, 1 ; 31
584: 0f be out 0x3f, r0 ; 63
586: 01 96 adiw r24, 0x01 ; 1
for(x=0; x < (sizeof(rc_lost_channel_e)/sizeof(char)); x++)
588: 30 e0 ldi r19, 0x00 ; 0
58a: 85 33 cpi r24, 0x35 ; 53
58c: 93 07 cpc r25, r19
58e: 81 f7 brne .-32 ; 0x570 <check_for_setup_mode+0x48>
590: 2e c0 rjmp .+92 ; 0x5ee <check_for_setup_mode+0xc6>
eeprom_write_byte(&rc_lost_channel_e[x], rc_lost_channel);
}
success += 1;
}
}else if(channels_in_use == 1)
592: 81 30 cpi r24, 0x01 ; 1
594: 09 f0 breq .+2 ; 0x598 <check_for_setup_mode+0x70>
596: 74 c0 rjmp .+232 ; 0x680 <check_for_setup_mode+0x158>
{
for(x=0; x < RC_SERVO_INPUT_CHANNELS; x++)
{
if(channel_mask & (1<<x))
598: 80 91 19 01 lds r24, 0x0119
59c: 48 2f mov r20, r24
59e: 50 e0 ldi r21, 0x00 ; 0
5a0: 20 e0 ldi r18, 0x00 ; 0
5a2: 30 e0 ldi r19, 0x00 ; 0
5a4: 62 2f mov r22, r18
5a6: ca 01 movw r24, r20
5a8: 02 2e mov r0, r18
5aa: 02 c0 rjmp .+4 ; 0x5b0 <check_for_setup_mode+0x88>
5ac: 95 95 asr r25
5ae: 87 95 ror r24
5b0: 0a 94 dec r0
5b2: e2 f7 brpl .-8 ; 0x5ac <check_for_setup_mode+0x84>
5b4: 80 ff sbrs r24, 0
5b6: 15 c0 rjmp .+42 ; 0x5e2 <check_for_setup_mode+0xba>
{
rc_lost_channel = x;
5b8: 20 93 12 01 sts 0x0112, r18
5bc: 8a e2 ldi r24, 0x2A ; 42
5be: 90 e0 ldi r25, 0x00 ; 0
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
do {} while (!eeprom_is_ready ());
5c0: f9 99 sbic 0x1f, 1 ; 31
5c2: fe cf rjmp .-4 ; 0x5c0 <check_for_setup_mode+0x98>
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
5c4: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
5c6: 92 bd out 0x22, r25 ; 34
5c8: 81 bd out 0x21, r24 ; 33
#endif
EEDR = __value;
5ca: 60 bd out 0x20, r22 ; 32
__asm__ __volatile__ (
5cc: 0f b6 in r0, 0x3f ; 63
5ce: f8 94 cli
5d0: fa 9a sbi 0x1f, 2 ; 31
5d2: f9 9a sbi 0x1f, 1 ; 31
5d4: 0f be out 0x3f, r0 ; 63
5d6: 01 96 adiw r24, 0x01 ; 1
for(x=0; x < (sizeof(rc_lost_channel_e)/sizeof(char)); x++)
5d8: 40 e0 ldi r20, 0x00 ; 0
5da: 85 33 cpi r24, 0x35 ; 53
5dc: 94 07 cpc r25, r20
5de: 81 f7 brne .-32 ; 0x5c0 <check_for_setup_mode+0x98>
5e0: 06 c0 rjmp .+12 ; 0x5ee <check_for_setup_mode+0xc6>
5e2: 2f 5f subi r18, 0xFF ; 255
5e4: 3f 4f sbci r19, 0xFF ; 255
success += 1;
}
}else if(channels_in_use == 1)
{
for(x=0; x < RC_SERVO_INPUT_CHANNELS; x++)
5e6: 28 30 cpi r18, 0x08 ; 8
5e8: 31 05 cpc r19, r1
5ea: e1 f6 brne .-72 ; 0x5a4 <check_for_setup_mode+0x7c>
5ec: 49 c0 rjmp .+146 ; 0x680 <check_for_setup_mode+0x158>
/****************************************************************************************************/
/* NOW WE NEED TO FIND THE THRESHOLD PULSE WIDTH THAT WILL BE USED AN A TX SIGNAL LOST TRIGGER */
/****************************************************************************************************/
if(success == 1)
{
wdt_reset();
5ee: a8 95 wdr
5f0: c0 e0 ldi r28, 0x00 ; 0
5f2: d0 e0 ldi r29, 0x00 ; 0
5f4: 10 e0 ldi r17, 0x00 ; 0
5f6: 00 e0 ldi r16, 0x00 ; 0
y = 0;
pw_buffer = 0;
for(x=0; x < 10; x++)
{
pw=get_channel_pw(rc_lost_channel);
5f8: 80 91 12 01 lds r24, 0x0112
5fc: 0e 94 36 01 call 0x26c ; 0x26c <get_channel_pw>
600: 9c 01 movw r18, r24
if(pw >= RC_SERVO_MIN_PW_VAL && pw <= RC_SERVO_MAX_PW_VAL)
602: 80 52 subi r24, 0x20 ; 32
604: 93 40 sbci r25, 0x03 ; 3
606: 89 57 subi r24, 0x79 ; 121
608: 95 40 sbci r25, 0x05 ; 5
60a: 18 f4 brcc .+6 ; 0x612 <check_for_setup_mode+0xea>
{
pw_buffer += pw;
60c: c2 0f add r28, r18
60e: d3 1f adc r29, r19
y++;
610: 0f 5f subi r16, 0xFF ; 255
if(success == 1)
{
wdt_reset();
y = 0;
pw_buffer = 0;
for(x=0; x < 10; x++)
612: 1f 5f subi r17, 0xFF ; 255
614: 1a 30 cpi r17, 0x0A ; 10
616: 81 f7 brne .-32 ; 0x5f8 <check_for_setup_mode+0xd0>
{
pw_buffer += pw;
y++;
}
}
pw_buffer /= y;
618: ce 01 movw r24, r28
61a: 60 2f mov r22, r16
61c: 70 e0 ldi r23, 0x00 ; 0
61e: 0e 94 f9 05 call 0xbf2 ; 0xbf2 <__udivmodhi4>
wdt_reset();
622: a8 95 wdr
if( (pw_buffer >= RC_PPM_OFF_UPPER_WINDOW_VAL) && (pw_buffer <= RC_SERVO_MAX_PW_VAL) )
624: cb 01 movw r24, r22
626: 84 5a subi r24, 0xA4 ; 164
628: 96 40 sbci r25, 0x06 ; 6
62a: 85 5f subi r24, 0xF5 ; 245
62c: 91 40 sbci r25, 0x01 ; 1
62e: 88 f4 brcc .+34 ; 0x652 <check_for_setup_mode+0x12a>
630: c4 e1 ldi r28, 0x14 ; 20
632: d0 e0 ldi r29, 0x00 ; 0
Write a word \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_word (uint16_t *__p, uint16_t __value)
{
#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
__eewr_word (__p, __value, eeprom_write_byte);
634: 8b 01 movw r16, r22
636: 07 5e subi r16, 0xE7 ; 231
638: 1f 4f sbci r17, 0xFF ; 255
63a: ce 01 movw r24, r28
63c: b8 01 movw r22, r16
63e: 4b e5 ldi r20, 0x5B ; 91
640: 50 e0 ldi r21, 0x00 ; 0
642: 0e 94 e4 05 call 0xbc8 ; 0xbc8 <__eewr_word>
646: 22 96 adiw r28, 0x02 ; 2
{
for(x=0; x<(sizeof(ppm_off_threshold_e)/sizeof(int)); x++)
648: 80 e0 ldi r24, 0x00 ; 0
64a: ca 32 cpi r28, 0x2A ; 42
64c: d8 07 cpc r29, r24
64e: a9 f7 brne .-22 ; 0x63a <check_for_setup_mode+0x112>
650: 65 c0 rjmp .+202 ; 0x71c <check_for_setup_mode+0x1f4>
{
eeprom_write_word(&ppm_off_threshold_e[x], (pw_buffer+RC_PPM_OFF_OFFSET_VAL));
}
success += 1;
}else if( (pw_buffer <= RC_PPM_OFF_LOWER_WINDOW_VAL) && (pw_buffer >= RC_SERVO_MIN_PW_VAL) )
652: cb 01 movw r24, r22
654: 80 52 subi r24, 0x20 ; 32
656: 93 40 sbci r25, 0x03 ; 3
658: 85 5f subi r24, 0xF5 ; 245
65a: 91 40 sbci r25, 0x01 ; 1
65c: 88 f4 brcc .+34 ; 0x680 <check_for_setup_mode+0x158>
65e: c4 e1 ldi r28, 0x14 ; 20
660: d0 e0 ldi r29, 0x00 ; 0
662: 8b 01 movw r16, r22
664: 09 51 subi r16, 0x19 ; 25
666: 10 40 sbci r17, 0x00 ; 0
668: ce 01 movw r24, r28
66a: b8 01 movw r22, r16
66c: 4b e5 ldi r20, 0x5B ; 91
66e: 50 e0 ldi r21, 0x00 ; 0
670: 0e 94 e4 05 call 0xbc8 ; 0xbc8 <__eewr_word>
674: 22 96 adiw r28, 0x02 ; 2
{
for(x=0; x<(sizeof(ppm_off_threshold_e)/sizeof(int)); x++)
676: 80 e0 ldi r24, 0x00 ; 0
678: ca 32 cpi r28, 0x2A ; 42
67a: d8 07 cpc r29, r24
67c: a9 f7 brne .-22 ; 0x668 <check_for_setup_mode+0x140>
67e: 4e c0 rjmp .+156 ; 0x71c <check_for_setup_mode+0x1f4>
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
}
}
}else{
write_default_values_to_eeprom();
680: 0e 94 65 02 call 0x4ca ; 0x4ca <write_default_values_to_eeprom>
{
LED_ON();
for(x=0; x<30; x++)
{
wdt_reset();
RESET_START_TIMER0();
684: 32 e0 ldi r19, 0x02 ; 2
686: 22 e0 ldi r18, 0x02 ; 2
688: 21 c0 rjmp .+66 ; 0x6cc <check_for_setup_mode+0x1a4>
if(success == 2)
{
RC_SETUP_PORT_OUT_REG &= (~(1<<RC_SETUP_PIN));
while(1)
{
LED_ON();
68a: 28 9a sbi 0x05, 0 ; 5
68c: 90 e0 ldi r25, 0x00 ; 0
for(x=0; x<3; x++)
{
wdt_reset();
68e: a8 95 wdr
RESET_START_TIMER0();
690: 15 bc out 0x25, r1 ; 37
692: a8 9a sbi 0x15, 0 ; 21
694: 16 bc out 0x26, r1 ; 38
696: 10 92 1d 01 sts 0x011D, r1
69a: 25 bd out 0x25, r18 ; 37
/* delay ~30 ms * 3 = 100 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
69c: 80 91 1d 01 lds r24, 0x011D
6a0: 86 37 cpi r24, 0x76 ; 118
6a2: e0 f3 brcs .-8 ; 0x69c <check_for_setup_mode+0x174>
{
RC_SETUP_PORT_OUT_REG &= (~(1<<RC_SETUP_PIN));
while(1)
{
LED_ON();
for(x=0; x<3; x++)
6a4: 9f 5f subi r25, 0xFF ; 255
6a6: 93 30 cpi r25, 0x03 ; 3
6a8: 91 f7 brne .-28 ; 0x68e <check_for_setup_mode+0x166>
wdt_reset();
RESET_START_TIMER0();
/* delay ~30 ms * 3 = 100 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
}
LED_OFF();
6aa: 28 98 cbi 0x05, 0 ; 5
6ac: 90 e0 ldi r25, 0x00 ; 0
for(x=0; x<30; x++)
{
wdt_reset();
6ae: a8 95 wdr
RESET_START_TIMER0();
6b0: 15 bc out 0x25, r1 ; 37
6b2: a8 9a sbi 0x15, 0 ; 21
6b4: 16 bc out 0x26, r1 ; 38
6b6: 10 92 1d 01 sts 0x011D, r1
6ba: 35 bd out 0x25, r19 ; 37
/* delay ~30 ms * 30 = 900 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
6bc: 80 91 1d 01 lds r24, 0x011D
6c0: 86 37 cpi r24, 0x76 ; 118
6c2: e0 f3 brcs .-8 ; 0x6bc <check_for_setup_mode+0x194>
RESET_START_TIMER0();
/* delay ~30 ms * 3 = 100 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
}
LED_OFF();
for(x=0; x<30; x++)
6c4: 9f 5f subi r25, 0xFF ; 255
6c6: 9e 31 cpi r25, 0x1E ; 30
6c8: 91 f7 brne .-28 ; 0x6ae <check_for_setup_mode+0x186>
6ca: df cf rjmp .-66 ; 0x68a <check_for_setup_mode+0x162>
}else{
write_default_values_to_eeprom();
while(1)
{
LED_ON();
6cc: 28 9a sbi 0x05, 0 ; 5
6ce: 90 e0 ldi r25, 0x00 ; 0
for(x=0; x<30; x++)
{
wdt_reset();
6d0: a8 95 wdr
RESET_START_TIMER0();
6d2: 15 bc out 0x25, r1 ; 37
6d4: a8 9a sbi 0x15, 0 ; 21
6d6: 16 bc out 0x26, r1 ; 38
6d8: 10 92 1d 01 sts 0x011D, r1
6dc: 25 bd out 0x25, r18 ; 37
/* delay ~30 ms * 30 = 900 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
6de: 80 91 1d 01 lds r24, 0x011D
6e2: 86 37 cpi r24, 0x76 ; 118
6e4: e0 f3 brcs .-8 ; 0x6de <check_for_setup_mode+0x1b6>
}else{
write_default_values_to_eeprom();
while(1)
{
LED_ON();
for(x=0; x<30; x++)
6e6: 9f 5f subi r25, 0xFF ; 255
6e8: 9e 31 cpi r25, 0x1E ; 30
6ea: 91 f7 brne .-28 ; 0x6d0 <check_for_setup_mode+0x1a8>
wdt_reset();
RESET_START_TIMER0();
/* delay ~30 ms * 30 = 900 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
}
LED_OFF();
6ec: 28 98 cbi 0x05, 0 ; 5
6ee: 90 e0 ldi r25, 0x00 ; 0
for(x=0; x<3; x++)
{
wdt_reset();
6f0: a8 95 wdr
RESET_START_TIMER0();
6f2: 15 bc out 0x25, r1 ; 37
6f4: a8 9a sbi 0x15, 0 ; 21
6f6: 16 bc out 0x26, r1 ; 38
6f8: 10 92 1d 01 sts 0x011D, r1
6fc: 35 bd out 0x25, r19 ; 37
/* delay ~30 ms * 3 = 100 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
6fe: 80 91 1d 01 lds r24, 0x011D
702: 86 37 cpi r24, 0x76 ; 118
704: e0 f3 brcs .-8 ; 0x6fe <check_for_setup_mode+0x1d6>
RESET_START_TIMER0();
/* delay ~30 ms * 30 = 900 milliseconds */
while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL );
}
LED_OFF();
for(x=0; x<3; x++)
706: 9f 5f subi r25, 0xFF ; 255
708: 93 30 cpi r25, 0x03 ; 3
70a: 91 f7 brne .-28 ; 0x6f0 <check_for_setup_mode+0x1c8>
70c: df cf rjmp .-66 ; 0x6cc <check_for_setup_mode+0x1a4>
if(setup_mode)
{
/****************************************************************************************************/
/* FIRST WE MUST FIND WHICH CHANNEL WILL BE USED AS A TX SIGNAL LOST INDICATOR */
/****************************************************************************************************/
wdt_reset();
70e: a8 95 wdr
success = 0;
if(channels_in_use > 1 )
710: 80 91 18 01 lds r24, 0x0118
714: 82 30 cpi r24, 0x02 ; 2
716: 08 f0 brcs .+2 ; 0x71a <check_for_setup_mode+0x1f2>
718: 21 cf rjmp .-446 ; 0x55c <check_for_setup_mode+0x34>
71a: 3b cf rjmp .-394 ; 0x592 <check_for_setup_mode+0x6a>
/****************************************************************************************************/
/* LASTLY WE MUST INDICATE TO THE USER IF THE SETUP PROCEDURE WAS SUCCESSFUL */
/****************************************************************************************************/
if(success == 2)
{
RC_SETUP_PORT_OUT_REG &= (~(1<<RC_SETUP_PIN));
71c: 2c 98 cbi 0x05, 4 ; 5
{
LED_ON();
for(x=0; x<3; x++)
{
wdt_reset();
RESET_START_TIMER0();
71e: 32 e0 ldi r19, 0x02 ; 2
720: 22 e0 ldi r18, 0x02 ; 2
722: b3 cf rjmp .-154 ; 0x68a <check_for_setup_mode+0x162>
}
} // End of "if(setup_mode)" statement.
return;
}
724: df 91 pop r29
726: cf 91 pop r28
728: 1f 91 pop r17
72a: 0f 91 pop r16
72c: 08 95 ret
0000072e <load_values_from_eeprom>:
11 copies of each variable are read and if more than 50% + 1 values are the same and within limits
this value is taken to be valid.
If not all 11 values are the same then the array is written again with this 50% +1 value.
*/
void load_values_from_eeprom(void)
{
72e: 6f 92 push r6
730: 7f 92 push r7
732: 8f 92 push r8
734: 9f 92 push r9
736: bf 92 push r11
738: cf 92 push r12
73a: df 92 push r13
73c: ef 92 push r14
73e: ff 92 push r15
740: 0f 93 push r16
742: 1f 93 push r17
744: cf 93 push r28
746: df 93 push r29
unsigned char match_upper_limit = 0;
unsigned char match_lower_limit = 0;
unsigned char x = 0;
unsigned char y = 0;
wdt_reset();
748: a8 95 wdr
74a: 6a e2 ldi r22, 0x2A ; 42
74c: 70 e0 ldi r23, 0x00 ; 0
74e: ab 01 movw r20, r22
11 copies of each variable are read and if more than 50% + 1 values are the same and within limits
this value is taken to be valid.
If not all 11 values are the same then the array is written again with this 50% +1 value.
*/
void load_values_from_eeprom(void)
{
750: eb 01 movw r28, r22
752: 2b 96 adiw r28, 0x0b ; 11
/** \ingroup avr_eeprom
Read one byte from EEPROM address \a __p.
*/
__ATTR_PURE__ static __inline__ uint8_t eeprom_read_byte (const uint8_t *__p)
{
do {} while (!eeprom_is_ready ());
754: f9 99 sbic 0x1f, 1 ; 31
756: fe cf rjmp .-4 ; 0x754 <load_values_from_eeprom+0x26>
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
758: 52 bd out 0x22, r21 ; 34
75a: 41 bd out 0x21, r20 ; 33
/* Use inline assembly below as some AVRs have problems with accessing
EECR with STS instructions. For example, see errata for ATmega64.
The code below also assumes that EECR and EEDR are in the I/O space.
*/
uint8_t __result;
__asm__ __volatile__
75c: f8 9a sbi 0x1f, 0 ; 31
75e: f0 b5 in r31, 0x20 ; 32
match_lower_limit = (((sizeof(rc_lost_channel_e)/sizeof(char))/2)+1);
for(x=0; x<match_upper_limit; x++)
{
match = 0;
eeprom_buf_x = eeprom_read_byte(&rc_lost_channel_e[x]);
760: af 2f mov r26, r31
762: b0 e0 ldi r27, 0x00 ; 0
764: 2a e2 ldi r18, 0x2A ; 42
766: 30 e0 ldi r19, 0x00 ; 0
768: e0 e0 ldi r30, 0x00 ; 0
/** \ingroup avr_eeprom
Read one byte from EEPROM address \a __p.
*/
__ATTR_PURE__ static __inline__ uint8_t eeprom_read_byte (const uint8_t *__p)
{
do {} while (!eeprom_is_ready ());
76a: f9 99 sbic 0x1f, 1 ; 31
76c: fe cf rjmp .-4 ; 0x76a <load_values_from_eeprom+0x3c>
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
76e: 32 bd out 0x22, r19 ; 34
770: 21 bd out 0x21, r18 ; 33
/* Use inline assembly below as some AVRs have problems with accessing
EECR with STS instructions. For example, see errata for ATmega64.
The code below also assumes that EECR and EEDR are in the I/O space.
*/
uint8_t __result;
__asm__ __volatile__
772: f8 9a sbi 0x1f, 0 ; 31
774: 80 b5 in r24, 0x20 ; 32
for(y=0; y<match_upper_limit; y++)
{
eeprom_buf_y = eeprom_read_byte(&rc_lost_channel_e[y]);
if(eeprom_buf_y == eeprom_buf_x){ match++; }
776: 90 e0 ldi r25, 0x00 ; 0
778: 8a 17 cp r24, r26
77a: 9b 07 cpc r25, r27
77c: 09 f4 brne .+2 ; 0x780 <load_values_from_eeprom+0x52>
77e: ef 5f subi r30, 0xFF ; 255
780: 2f 5f subi r18, 0xFF ; 255
782: 3f 4f sbci r19, 0xFF ; 255
11 copies of each variable are read and if more than 50% + 1 values are the same and within limits
this value is taken to be valid.
If not all 11 values are the same then the array is written again with this 50% +1 value.
*/
void load_values_from_eeprom(void)
{
784: 85 e3 ldi r24, 0x35 ; 53
786: 90 e0 ldi r25, 0x00 ; 0
for(x=0; x<match_upper_limit; x++)
{
match = 0;
eeprom_buf_x = eeprom_read_byte(&rc_lost_channel_e[x]);
for(y=0; y<match_upper_limit; y++)
788: c2 17 cp r28, r18
78a: d3 07 cpc r29, r19
78c: 71 f7 brne .-36 ; 0x76a <load_values_from_eeprom+0x3c>
eeprom_buf_y = eeprom_read_byte(&rc_lost_channel_e[y]);
if(eeprom_buf_y == eeprom_buf_x){ match++; }
}
// If 50% +1 or more char values in the array are the same a match has been found.
// Now test them to see if they are within limits.
if(match >= match_lower_limit )
78e: e6 30 cpi r30, 0x06 ; 6
790: c0 f0 brcs .+48 ; 0x7c2 <load_values_from_eeprom+0x94>
{
if( eeprom_buf_x < RC_SERVO_INPUT_CHANNELS )
792: 18 97 sbiw r26, 0x08 ; 8
794: 08 f0 brcs .+2 ; 0x798 <load_values_from_eeprom+0x6a>
796: 7b c0 rjmp .+246 ; 0x88e <load_values_from_eeprom+0x160>
{
rc_lost_channel = eeprom_buf_x; //Load the stored value to throttle_thershold.
798: f0 93 12 01 sts 0x0112, r31
if(match < match_upper_limit)
79c: eb 30 cpi r30, 0x0B ; 11
79e: c0 f4 brcc .+48 ; 0x7d0 <load_values_from_eeprom+0xa2>
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
do {} while (!eeprom_is_ready ());
7a0: f9 99 sbic 0x1f, 1 ; 31
7a2: fe cf rjmp .-4 ; 0x7a0 <load_values_from_eeprom+0x72>
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
7a4: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (size_t)__p;
#else
EEAR = (size_t)__p;
7a6: 72 bd out 0x22, r23 ; 34
7a8: 61 bd out 0x21, r22 ; 33
#endif
EEDR = __value;
7aa: f0 bd out 0x20, r31 ; 32
__asm__ __volatile__ (
7ac: 0f b6 in r0, 0x3f ; 63
7ae: f8 94 cli
7b0: fa 9a sbi 0x1f, 2 ; 31
7b2: f9 9a sbi 0x1f, 1 ; 31
7b4: 0f be out 0x3f, r0 ; 63
7b6: 6f 5f subi r22, 0xFF ; 255
7b8: 7f 4f sbci r23, 0xFF ; 255
{
for(x=0; x<match_upper_limit; x++)
7ba: 86 17 cp r24, r22
7bc: 97 07 cpc r25, r23
7be: 81 f7 brne .-32 ; 0x7a0 <load_values_from_eeprom+0x72>
7c0: 07 c0 rjmp .+14 ; 0x7d0 <load_values_from_eeprom+0xa2>
7c2: 4f 5f subi r20, 0xFF ; 255
7c4: 5f 4f sbci r21, 0xFF ; 255
/* READ WHICH CHANNEL WILL BE USED AS A RX LOST INDICATOR */
/****************************************************************************************************/
match_upper_limit = (sizeof(rc_lost_channel_e)/sizeof(char));
match_lower_limit = (((sizeof(rc_lost_channel_e)/sizeof(char))/2)+1);
for(x=0; x<match_upper_limit; x++)
7c6: c4 17 cp r28, r20
7c8: d5 07 cpc r29, r21
7ca: 09 f0 breq .+2 ; 0x7ce <load_values_from_eeprom+0xa0>
7cc: c3 cf rjmp .-122 ; 0x754 <load_values_from_eeprom+0x26>
7ce: 5f c0 rjmp .+190 ; 0x88e <load_values_from_eeprom+0x160>
}else{ match = 0; }
break;
}
}
if( match < match_lower_limit ){ write_default_values_to_eeprom(); return; }
7d0: 04 e1 ldi r16, 0x14 ; 20
7d2: 10 e0 ldi r17, 0x00 ; 0
7d4: 68 01 movw r12, r16
11 copies of each variable are read and if more than 50% + 1 values are the same and within limits
this value is taken to be valid.
If not all 11 values are the same then the array is written again with this 50% +1 value.
*/
void load_values_from_eeprom(void)
{
7d6: 26 e1 ldi r18, 0x16 ; 22
7d8: 82 2e mov r8, r18
7da: 91 2c mov r9, r1
7dc: 80 0e add r8, r16
7de: 91 1e adc r9, r17
Read one 16-bit word (little endian) from EEPROM address \a __p.
*/
__ATTR_PURE__ static __inline__ uint16_t eeprom_read_word (const uint16_t *__p)
{
#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
return __eerd_word (__p, eeprom_read_byte);
7e0: c6 01 movw r24, r12
7e2: 63 e5 ldi r22, 0x53 ; 83
7e4: 70 e0 ldi r23, 0x00 ; 0
7e6: 0e 94 ce 05 call 0xb9c ; 0xb9c <__eerd_word>
7ea: 7c 01 movw r14, r24
7ec: c4 e1 ldi r28, 0x14 ; 20
7ee: d0 e0 ldi r29, 0x00 ; 0
7f0: bb 24 eor r11, r11
match = 0;
eeprom_buf_x = eeprom_read_word(&ppm_off_threshold_e[x]);
for(y=0; y < match_upper_limit; y++)
{
eeprom_buf_y = eeprom_read_word(&ppm_off_threshold_e[y]);
if(eeprom_buf_y == eeprom_buf_x){ match++; }
7f2: ce 01 movw r24, r28
7f4: 63 e5 ldi r22, 0x53 ; 83
7f6: 70 e0 ldi r23, 0x00 ; 0
7f8: 0e 94 ce 05 call 0xb9c ; 0xb9c <__eerd_word>
7fc: 8e 15 cp r24, r14
7fe: 9f 05 cpc r25, r15
800: 09 f4 brne .+2 ; 0x804 <load_values_from_eeprom+0xd6>
802: b3 94 inc r11
804: 22 96 adiw r28, 0x02 ; 2
11 copies of each variable are read and if more than 50% + 1 values are the same and within limits
this value is taken to be valid.
If not all 11 values are the same then the array is written again with this 50% +1 value.
*/
void load_values_from_eeprom(void)
{
806: 9a e2 ldi r25, 0x2A ; 42
808: 69 2e mov r6, r25
80a: 90 e0 ldi r25, 0x00 ; 0
80c: 79 2e mov r7, r25
for(x=0; x < match_upper_limit; x++)
{
match = 0;
eeprom_buf_x = eeprom_read_word(&ppm_off_threshold_e[x]);
for(y=0; y < match_upper_limit; y++)
80e: 8c 16 cp r8, r28
810: 9d 06 cpc r9, r29
812: 79 f7 brne .-34 ; 0x7f2 <load_values_from_eeprom+0xc4>
eeprom_buf_y = eeprom_read_word(&ppm_off_threshold_e[y]);
if(eeprom_buf_y == eeprom_buf_x){ match++; }
}
// If 50% +1 or more integer values in the array are the same a match has been found.
// Now test them to see if they are within limits.
if(match >= match_lower_limit )
814: 25 e0 ldi r18, 0x05 ; 5
816: 2b 15 cp r18, r11
818: 90 f5 brcc .+100 ; 0x87e <load_values_from_eeprom+0x150>
{
if( (eeprom_buf_x >= RC_PPM_OFF_UPPER_WINDOW_VAL) && (eeprom_buf_x <= RC_SERVO_MAX_PW_VAL) )
81a: c7 01 movw r24, r14
81c: 84 5a subi r24, 0xA4 ; 164
81e: 96 40 sbci r25, 0x06 ; 6
820: 85 5f subi r24, 0xF5 ; 245
822: 91 40 sbci r25, 0x01 ; 1
824: 98 f4 brcc .+38 ; 0x84c <load_values_from_eeprom+0x11e>
{
ppm_off_threshold = eeprom_buf_x; //Load the stored value to throttle_thershold.
826: f0 92 11 01 sts 0x0111, r15
82a: e0 92 10 01 sts 0x0110, r14
if(match < match_upper_limit)
82e: 8a e0 ldi r24, 0x0A ; 10
830: 8b 15 cp r24, r11
832: 78 f1 brcs .+94 ; 0x892 <load_values_from_eeprom+0x164>
Write a word \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_word (uint16_t *__p, uint16_t __value)
{
#if (! (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)) )
__eewr_word (__p, __value, eeprom_write_byte);
834: c8 01 movw r24, r16
836: b7 01 movw r22, r14
838: 4b e5 ldi r20, 0x5B ; 91
83a: 50 e0 ldi r21, 0x00 ; 0
83c: 0e 94 e4 05 call 0xbc8 ; 0xbc8 <__eewr_word>
840: 0e 5f subi r16, 0xFE ; 254
842: 1f 4f sbci r17, 0xFF ; 255
{
for(x=0; x < match_upper_limit; x++){ eeprom_write_word(&ppm_off_threshold_e[x], eeprom_buf_x); }
844: 60 16 cp r6, r16
846: 71 06 cpc r7, r17
848: a9 f7 brne .-22 ; 0x834 <load_values_from_eeprom+0x106>
84a: 23 c0 rjmp .+70 ; 0x892 <load_values_from_eeprom+0x164>
}
}else if( (eeprom_buf_x <= RC_PPM_OFF_LOWER_WINDOW_VAL) && (eeprom_buf_x >= RC_SERVO_MIN_PW_VAL) )
84c: c7 01 movw r24, r14
84e: 80 52 subi r24, 0x20 ; 32
850: 93 40 sbci r25, 0x03 ; 3
852: 85 5f subi r24, 0xF5 ; 245
854: 91 40 sbci r25, 0x01 ; 1
856: d8 f4 brcc .+54 ; 0x88e <load_values_from_eeprom+0x160>
{
ppm_off_threshold = eeprom_buf_x; //Load the stored value to throttle_thershold.
858: f0 92 11 01 sts 0x0111, r15
85c: e0 92 10 01 sts 0x0110, r14
if(match < match_upper_limit)
860: 8a e0 ldi r24, 0x0A ; 10
862: 8b 15 cp r24, r11
864: b0 f0 brcs .+44 ; 0x892 <load_values_from_eeprom+0x164>
866: c8 01 movw r24, r16
868: b7 01 movw r22, r14
86a: 4b e5 ldi r20, 0x5B ; 91
86c: 50 e0 ldi r21, 0x00 ; 0
86e: 0e 94 e4 05 call 0xbc8 ; 0xbc8 <__eewr_word>
872: 0e 5f subi r16, 0xFE ; 254
874: 1f 4f sbci r17, 0xFF ; 255
{
for(x=0; x < match_upper_limit; x++){ eeprom_write_word(&ppm_off_threshold_e[x], eeprom_buf_x); }
876: 60 16 cp r6, r16
878: 71 06 cpc r7, r17
87a: a9 f7 brne .-22 ; 0x866 <load_values_from_eeprom+0x138>
87c: 0a c0 rjmp .+20 ; 0x892 <load_values_from_eeprom+0x164>
87e: 82 e0 ldi r24, 0x02 ; 2
880: 90 e0 ldi r25, 0x00 ; 0
882: c8 0e add r12, r24
884: d9 1e adc r13, r25
/* NOW READ THE CHANNEL'S PULSE WIDTH SO IT CAN BE USED AS A TRIGGER */
/****************************************************************************************************/
match_upper_limit = (sizeof(ppm_off_threshold_e)/sizeof(int));
match_lower_limit = (((sizeof(ppm_off_threshold_e)/sizeof(int))/2)+1);
for(x=0; x < match_upper_limit; x++)
886: 8c 14 cp r8, r12
888: 9d 04 cpc r9, r13
88a: 09 f0 breq .+2 ; 0x88e <load_values_from_eeprom+0x160>
88c: a9 cf rjmp .-174 ; 0x7e0 <load_values_from_eeprom+0xb2>
}else{ match = 0; }
break;
}
}
if( match < match_lower_limit ){ write_default_values_to_eeprom(); return; }
88e: 0e 94 65 02 call 0x4ca ; 0x4ca <write_default_values_to_eeprom>
return;
}
892: df 91 pop r29
894: cf 91 pop r28
896: 1f 91 pop r17
898: 0f 91 pop r16
89a: ff 90 pop r15
89c: ef 90 pop r14
89e: df 90 pop r13
8a0: cf 90 pop r12
8a2: bf 90 pop r11
8a4: 9f 90 pop r9
8a6: 8f 90 pop r8
8a8: 7f 90 pop r7
8aa: 6f 90 pop r6
8ac: 08 95 ret
000008ae <main>:
/********************************************************************************************************/
/* MAIN FUNCTION */
/********************************************************************************************************/
__attribute__((noreturn)) void main(void)
{
8ae: df 93 push r29
8b0: cf 93 push r28
8b2: cd b7 in r28, 0x3d ; 61
8b4: de b7 in r29, 0x3e ; 62
8b6: 60 97 sbiw r28, 0x10 ; 16
8b8: 0f b6 in r0, 0x3f ; 63
8ba: f8 94 cli
8bc: de bf out 0x3e, r29 ; 62
8be: 0f be out 0x3f, r0 ; 63
8c0: cd bf out 0x3d, r28 ; 61
unsigned char tx_signal_detected = 0;
unsigned char servo_signals_lost = 0;
unsigned char led_frequency = 0;
unsigned char led_counter = 0;
wdt_disable();
8c2: 88 e1 ldi r24, 0x18 ; 24
8c4: 0f b6 in r0, 0x3f ; 63
8c6: f8 94 cli
8c8: 80 93 60 00 sts 0x0060, r24
8cc: 10 92 60 00 sts 0x0060, r1
8d0: 0f be out 0x3f, r0 ; 63
wdt_enable(WDTO_120MS);
8d2: 2b e0 ldi r18, 0x0B ; 11
8d4: 88 e1 ldi r24, 0x18 ; 24
8d6: 90 e0 ldi r25, 0x00 ; 0
8d8: 0f b6 in r0, 0x3f ; 63
8da: f8 94 cli
8dc: a8 95 wdr
8de: 80 93 60 00 sts 0x0060, r24
8e2: 0f be out 0x3f, r0 ; 63
8e4: 20 93 60 00 sts 0x0060, r18
wdt_reset();
8e8: a8 95 wdr
initialize_mcu();
8ea: 0e 94 68 00 call 0xd0 ; 0xd0 <initialize_mcu>
/*Load the values stored in the eeprom like the throttle channel threshold etc. */
load_values_from_eeprom();
8ee: 0e 94 97 03 call 0x72e ; 0x72e <load_values_from_eeprom>
/*77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777*/
/*88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888*/
void load_failsafe_values(void)
{
wdt_reset();
8f2: a8 95 wdr
isr_channel_pw[0] = RC_FS_CH_1_TIMER_VAL;
8f4: 2c ed ldi r18, 0xDC ; 220
8f6: 35 e0 ldi r19, 0x05 ; 5
8f8: 30 93 1f 01 sts 0x011F, r19
8fc: 20 93 1e 01 sts 0x011E, r18
#if RC_PPM_GEN_CHANNELS >= 2
isr_channel_pw[1] = RC_FS_CH_2_TIMER_VAL;
900: 30 93 21 01 sts 0x0121, r19
904: 20 93 20 01 sts 0x0120, r18
#endif
#if RC_PPM_GEN_CHANNELS >= 3
isr_channel_pw[2] = RC_FS_CH_3_TIMER_VAL;
908: 88 ee ldi r24, 0xE8 ; 232
90a: 93 e0 ldi r25, 0x03 ; 3
90c: 90 93 23 01 sts 0x0123, r25
910: 80 93 22 01 sts 0x0122, r24
#endif
#if RC_PPM_GEN_CHANNELS >= 4
isr_channel_pw[3] = RC_FS_CH_4_TIMER_VAL;
914: 30 93 25 01 sts 0x0125, r19
918: 20 93 24 01 sts 0x0124, r18
#endif
#if RC_PPM_GEN_CHANNELS >= 5
isr_channel_pw[4] = RC_FS_CH_5_TIMER_VAL;
91c: 90 93 27 01 sts 0x0127, r25
920: 80 93 26 01 sts 0x0126, r24
#endif
#if RC_PPM_GEN_CHANNELS >= 6
isr_channel_pw[5] = RC_FS_CH_6_TIMER_VAL;
924: 90 93 29 01 sts 0x0129, r25
928: 80 93 28 01 sts 0x0128, r24
#endif
#if RC_PPM_GEN_CHANNELS >= 7
isr_channel_pw[6] = RC_FS_CH_7_TIMER_VAL;
92c: 90 93 2b 01 sts 0x012B, r25
930: 80 93 2a 01 sts 0x012A, r24
#endif
#if RC_PPM_GEN_CHANNELS >= 8
isr_channel_pw[7] = RC_FS_CH_8_TIMER_VAL;
934: 90 93 2d 01 sts 0x012D, r25
938: 80 93 2c 01 sts 0x012C, r24
#endif
#if RC_PPM_GEN_CHANNELS >= 9
isr_channel_pw[8] = RC_FS_CH_8_TIMER_VAL;
#endif
isr_channel_pw[RC_PPM_GEN_CHANNELS] = RC_RESET_PW_TIMER_VAL;
93c: 8c ee ldi r24, 0xEC ; 236
93e: 9c e2 ldi r25, 0x2C ; 44
940: 90 93 2f 01 sts 0x012F, r25
944: 80 93 2e 01 sts 0x012E, r24
load_failsafe_values();
/*
The "wait_for_rx(): function waits untill the receiver has been powered up and running
so we can then detect the connected channels with certainty.
*/
wait_for_rx();
948: 0e 94 7f 01 call 0x2fe ; 0x2fe <wait_for_rx>
channels_in_use = detect_connected_channels();
94c: 0e 94 eb 00 call 0x1d6 ; 0x1d6 <detect_connected_channels>
950: 80 93 18 01 sts 0x0118, r24
check_for_setup_mode();
954: 0e 94 94 02 call 0x528 ; 0x528 <check_for_setup_mode>
led_frequency = RC_LED_FREQUENCY_VAL_1HZ; //load the defined led frequency.
/**************************** SETUP THE PIN INTERRUPT *************************************************/
// Now we must disable the pin interrupt.
RC_PIN_INT_EN_REG &= (~(1<<RC_PIN_INT_EN_BIT));
958: 80 91 68 00 lds r24, 0x0068
95c: 8b 7f andi r24, 0xFB ; 251
95e: 80 93 68 00 sts 0x0068, r24
//Now we must load the pin interrupt mask register.
RC_PIN_INT_MASK_REG = channel_mask;
962: 70 90 19 01 lds r7, 0x0119
966: 70 92 6d 00 sts 0x006D, r7
//Clear any pin interrupt flag set.
RC_PIN_INT_FLAG_REG |= (1<<RC_PIN_INT_FLAG_BIT);
96a: da 9a sbi 0x1b, 2 ; 27
// Clear the pin interrupt ISR detection variable
pin_interrupt_detected = 0;
96c: 10 92 14 01 sts 0x0114, r1
// Finally we can enable the pin interrupt again.
RC_PIN_INT_EN_REG |= (1<<RC_PIN_INT_EN_BIT);
970: 80 91 68 00 lds r24, 0x0068
974: 84 60 ori r24, 0x04 ; 4
976: 80 93 68 00 sts 0x0068, r24
// Set and start timer1
RESET_START_TIMER0();
97a: 15 bc out 0x25, r1 ; 37
97c: a8 9a sbi 0x15, 0 ; 21
97e: 16 bc out 0x26, r1 ; 38
980: 10 92 1d 01 sts 0x011D, r1
984: 82 e0 ldi r24, 0x02 ; 2
986: 85 bd out 0x25, r24 ; 37
// Take a snapshot of the servo pins in order to establish a starting point.
pin_reg_buffer1 = (RC_SERVO_PORT_PIN_REG & channel_mask);
988: 29 b1 in r18, 0x09 ; 9
98a: 27 21 and r18, r7
RESET_START_TIMER0();
98c: 15 bc out 0x25, r1 ; 37
98e: a8 9a sbi 0x15, 0 ; 21
990: 16 bc out 0x26, r1 ; 38
992: 10 92 1d 01 sts 0x011D, r1
996: 85 bd out 0x25, r24 ; 37
channel_mask_buffer &= (~y);
timer0_buffer = isr_timer0_16 - pw_of_channel[x];
if( (timer0_buffer > RC_SERVO_MIN_PW_VAL) && (timer0_buffer < RC_SERVO_MAX_PW_VAL) )
{
#if defined(RC_LOST_CHANNEL) && RC_LOST_CHANNEL > 0
if(x == rc_lost_channel)
998: 20 90 12 01 lds r2, 0x0112
{
if(ppm_off_threshold > RC_SERVO_CENTER_PW_VAL)
99c: e0 90 10 01 lds r14, 0x0110
9a0: f0 90 11 01 lds r15, 0x0111
9a4: 66 24 eor r6, r6
9a6: cc 24 eor r12, r12
9a8: bb 24 eor r11, r11
9aa: dd 24 eor r13, r13
9ac: d3 94 inc r13
9ae: 40 e1 ldi r20, 0x10 ; 16
9b0: a4 2e mov r10, r20
9b2: 00 e0 ldi r16, 0x00 ; 0
/*88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888*/
void load_failsafe_values(void)
{
wdt_reset();
isr_channel_pw[0] = RC_FS_CH_1_TIMER_VAL;
9b4: 3c ed ldi r19, 0xDC ; 220
9b6: 43 2e mov r4, r19
9b8: 35 e0 ldi r19, 0x05 ; 5
9ba: 53 2e mov r5, r19
#if RC_PPM_GEN_CHANNELS >= 2
isr_channel_pw[1] = RC_FS_CH_2_TIMER_VAL;
#endif
#if RC_PPM_GEN_CHANNELS >= 3
isr_channel_pw[2] = RC_FS_CH_3_TIMER_VAL;
9bc: 98 ee ldi r25, 0xE8 ; 232
9be: 89 2e mov r8, r25
9c0: 93 e0 ldi r25, 0x03 ; 3
9c2: 99 2e mov r9, r25
pin_reg_buffer1 = (RC_SERVO_PORT_PIN_REG & channel_mask);
RESET_START_TIMER0();
//Main endless loop.
while(1)
{
wdt_reset();
9c4: a8 95 wdr
channel_mask_buffer = channel_mask;
RESET_TIMER0();
9c6: a8 9a sbi 0x15, 0 ; 21
9c8: 16 bc out 0x26, r1 ; 38
9ca: 10 92 1d 01 sts 0x011D, r1
9ce: 17 2d mov r17, r7
9d0: 5b c0 rjmp .+182 ; 0xa88 <__stack+0x189>
while(channel_mask_buffer)
{
/* Wait until a pin change state. */
do{
if( timer0.timer0[1] >= RC_MAX_TIMEOUT_VAL )
9d2: 80 91 1d 01 lds r24, 0x011D
9d6: 86 37 cpi r24, 0x76 ; 118
9d8: 08 f0 brcs .+2 ; 0x9dc <__stack+0xdd>
9da: 5c c0 rjmp .+184 ; 0xa94 <__stack+0x195>
{
goto PPM_CONTROL;
}
}while( pin_interrupt_detected == 0 );
9dc: 80 91 14 01 lds r24, 0x0114
9e0: 88 23 and r24, r24
9e2: b9 f3 breq .-18 ; 0x9d2 <__stack+0xd3>
x=0;
y=1;
//Only pins that changed their state will be tested for a high or low level
pin_reg_buffer0 = (RC_SERVO_PORT_PIN_REG & channel_mask_buffer);
9e4: 79 b1 in r23, 0x09 ; 9
9e6: 71 23 and r23, r17
pin_interrupt_detected = 0;
9e8: 10 92 14 01 sts 0x0114, r1
channels_to_check = pin_reg_buffer1 ^ pin_reg_buffer0;
9ec: 37 2e mov r3, r23
9ee: 32 26 eor r3, r18
9f0: de 01 movw r26, r28
9f2: 11 96 adiw r26, 0x01 ; 1
9f4: 61 e0 ldi r22, 0x01 ; 1
9f6: 40 e0 ldi r20, 0x00 ; 0
9f8: 50 e0 ldi r21, 0x00 ; 0
pin_reg_buffer1 = pin_reg_buffer0;
while(x<RC_SERVO_INPUT_CHANNELS)
{
if(channels_to_check & y)
9fa: 86 2f mov r24, r22
9fc: 83 21 and r24, r3
9fe: 09 f4 brne .+2 ; 0xa02 <__stack+0x103>
a00: 3a c0 rjmp .+116 ; 0xa76 <__stack+0x177>
{
if( (pin_reg_buffer0 & y) ) /* if the pin is high then... */
a02: 86 2f mov r24, r22
a04: 87 23 and r24, r23
a06: 49 f0 breq .+18 ; 0xa1a <__stack+0x11b>
{
pw_of_channel[x] = isr_timer0_16;
a08: 80 91 16 01 lds r24, 0x0116
a0c: 90 91 17 01 lds r25, 0x0117
a10: 11 96 adiw r26, 0x01 ; 1
a12: 9c 93 st X, r25
a14: 8e 93 st -X, r24
channel_status |= y; /* signal that this channel got it's timer stamp. */
a16: 66 2a or r6, r22
a18: 2e c0 rjmp .+92 ; 0xa76 <__stack+0x177>
}else{
if( channel_status & y )
a1a: 86 2d mov r24, r6
a1c: 86 23 and r24, r22
a1e: 59 f1 breq .+86 ; 0xa76 <__stack+0x177>
{
channel_mask_buffer &= (~y);
a20: 86 2f mov r24, r22
a22: 80 95 com r24
a24: 18 23 and r17, r24
timer0_buffer = isr_timer0_16 - pw_of_channel[x];
a26: 20 91 16 01 lds r18, 0x0116
a2a: 30 91 17 01 lds r19, 0x0117
a2e: 8d 91 ld r24, X+
a30: 9c 91 ld r25, X
a32: 11 97 sbiw r26, 0x01 ; 1
a34: 28 1b sub r18, r24
a36: 39 0b sbc r19, r25
if( (timer0_buffer > RC_SERVO_MIN_PW_VAL) && (timer0_buffer < RC_SERVO_MAX_PW_VAL) )
a38: c9 01 movw r24, r18
a3a: 81 52 subi r24, 0x21 ; 33
a3c: 93 40 sbci r25, 0x03 ; 3
a3e: 87 57 subi r24, 0x77 ; 119
a40: 95 40 sbci r25, 0x05 ; 5
a42: c8 f4 brcc .+50 ; 0xa76 <__stack+0x177>
{
#if defined(RC_LOST_CHANNEL) && RC_LOST_CHANNEL > 0
if(x == rc_lost_channel)
a44: 24 16 cp r2, r20
a46: 61 f4 brne .+24 ; 0xa60 <__stack+0x161>
{
if(ppm_off_threshold > RC_SERVO_CENTER_PW_VAL)
a48: 8d ed ldi r24, 0xDD ; 221
a4a: e8 16 cp r14, r24
a4c: 85 e0 ldi r24, 0x05 ; 5
a4e: f8 06 cpc r15, r24
a50: 20 f0 brcs .+8 ; 0xa5a <__stack+0x15b>
{
if(timer0_buffer >= ppm_off_threshold)
a52: 2e 15 cp r18, r14
a54: 3f 05 cpc r19, r15
a56: 20 f0 brcs .+8 ; 0xa60 <__stack+0x161>
a58: 1b c0 rjmp .+54 ; 0xa90 <__stack+0x191>
channel_mask_buffer = 0xFF;
goto PPM_CONTROL;
}
}else{
if(timer0_buffer <= ppm_off_threshold)
a5a: e2 16 cp r14, r18
a5c: f3 06 cpc r15, r19
a5e: c0 f4 brcc .+48 ; 0xa90 <__stack+0x191>
goto PPM_CONTROL;
}
}
}
#endif
if(servo_signals_lost == 0)
a60: dd 20 and r13, r13
a62: 49 f4 brne .+18 ; 0xa76 <__stack+0x177>
{
asm("cli"); //Atomic operation needed here.
a64: f8 94 cli
isr_channel_pw[x] = timer0_buffer;
a66: fa 01 movw r30, r20
a68: ee 0f add r30, r30
a6a: ff 1f adc r31, r31
a6c: e2 5e subi r30, 0xE2 ; 226
a6e: fe 4f sbci r31, 0xFE ; 254
a70: 31 83 std Z+1, r19 ; 0x01
a72: 20 83 st Z, r18
asm("sei");
a74: 78 94 sei
a76: 4f 5f subi r20, 0xFF ; 255
a78: 5f 4f sbci r21, 0xFF ; 255
a7a: 12 96 adiw r26, 0x02 ; 2
a7c: 27 2f mov r18, r23
//Only pins that changed their state will be tested for a high or low level
pin_reg_buffer0 = (RC_SERVO_PORT_PIN_REG & channel_mask_buffer);
pin_interrupt_detected = 0;
channels_to_check = pin_reg_buffer1 ^ pin_reg_buffer0;
pin_reg_buffer1 = pin_reg_buffer0;
while(x<RC_SERVO_INPUT_CHANNELS)
a7e: 48 30 cpi r20, 0x08 ; 8
a80: 51 05 cpc r21, r1
a82: 11 f0 breq .+4 ; 0xa88 <__stack+0x189>
} // End of "if( channel_status & y )" statement.
} // End of "if( (pin_reg_buffer0 & y) )...else..." statement
} // End of "if(channels_to_check & y)" statement.
x++;
y=(y<<1);
a84: 66 0f add r22, r22
a86: b9 cf rjmp .-142 ; 0x9fa <__stack+0xfb>
while(1)
{
wdt_reset();
channel_mask_buffer = channel_mask;
RESET_TIMER0();
while(channel_mask_buffer)
a88: 11 23 and r17, r17
a8a: 09 f0 breq .+2 ; 0xa8e <__stack+0x18f>
a8c: a2 cf rjmp .-188 ; 0x9d2 <__stack+0xd3>
a8e: 02 c0 rjmp .+4 ; 0xa94 <__stack+0x195>
x++;
y=(y<<1);
}
} // End of "while(channel_mask_buffer)" loop.
PPM_CONTROL:
a90: 27 2f mov r18, r23
a92: 1f ef ldi r17, 0xFF ; 255
led_counter++;
a94: 0f 5f subi r16, 0xFF ; 255
if( led_counter >= led_frequency ){ led_counter = 0; TOGGLE_LED(); }
a96: 0a 15 cp r16, r10
a98: 28 f0 brcs .+10 ; 0xaa4 <__stack+0x1a5>
a9a: 85 b1 in r24, 0x05 ; 5
a9c: 91 e0 ldi r25, 0x01 ; 1
a9e: 89 27 eor r24, r25
aa0: 85 b9 out 0x05, r24 ; 5
aa2: 00 e0 ldi r16, 0x00 ; 0
//We need 'RC_MAX_BAD_PPM_FRAMES" consecutive readings in order to change the PPM generator's status.
if( channel_mask_buffer == 0 ) //IF ALL CHANNELS HAVE BEEN MEASURED...
aa4: 11 23 and r17, r17
aa6: 79 f5 brne .+94 ; 0xb06 <__stack+0x207>
{
tx_signal_lost = 0;
if(servo_signals_lost == 1) //IF PREVIOUSLY THE SERVO SIGNAL WAS LOST...
aa8: e1 e0 ldi r30, 0x01 ; 1
aaa: de 16 cp r13, r30
aac: 09 f0 breq .+2 ; 0xab0 <__stack+0x1b1>
aae: 61 c0 rjmp .+194 ; 0xb72 <__stack+0x273>
{
tx_signal_detected++;
ab0: b3 94 inc r11
if(tx_signal_detected > RC_MAX_BAD_PPM_FRAMES)
ab2: 34 e0 ldi r19, 0x04 ; 4
ab4: 3b 15 cp r19, r11
ab6: 08 f0 brcs .+2 ; 0xaba <__stack+0x1bb>
ab8: 5c c0 rjmp .+184 ; 0xb72 <__stack+0x273>
static inline void ppm_on(void)
{
RC_TIMER1_PRESCALER_REG &= (~(TIMER1_PRESCALER_BITS));
aba: 80 91 81 00 lds r24, 0x0081
abe: 8d 7f andi r24, 0xFD ; 253
ac0: 80 93 81 00 sts 0x0081, r24
TCNT1 = 0;
ac4: 10 92 85 00 sts 0x0085, r1
ac8: 10 92 84 00 sts 0x0084, r1
isr_channel_number = RC_PPM_GEN_CHANNELS;
acc: 88 e0 ldi r24, 0x08 ; 8
ace: 80 93 15 01 sts 0x0115, r24
RC_TIMER1_COMP1_REG = RC_RESET_PW_TIMER_VAL;
ad2: 8c ee ldi r24, 0xEC ; 236
ad4: 9c e2 ldi r25, 0x2C ; 44
ad6: 90 93 89 00 sts 0x0089, r25
ada: 80 93 88 00 sts 0x0088, r24
RC_TIMER1_COMP2_REG = RC_PPM_SYNC_PW_VAL;
ade: 8c e2 ldi r24, 0x2C ; 44
ae0: 91 e0 ldi r25, 0x01 ; 1
ae2: 90 93 8b 00 sts 0x008B, r25
ae6: 80 93 8a 00 sts 0x008A, r24
RC_TIMER1_TIFR |= ( (1<<OCIE1B)|(1<<TOIE1) );
aea: 86 b3 in r24, 0x16 ; 22
aec: 85 60 ori r24, 0x05 ; 5
aee: 86 bb out 0x16, r24 ; 22
RC_TIMER1_PRESCALER_REG |= TIMER1_PRESCALER_BITS;
af0: 80 91 81 00 lds r24, 0x0081
af4: 82 60 ori r24, 0x02 ; 2
af6: 80 93 81 00 sts 0x0081, r24
tx_signal_detected++;
if(tx_signal_detected > RC_MAX_BAD_PPM_FRAMES)
{
ppm_on();
servo_signals_lost = 0;
LED_ON();
afa: 28 9a sbi 0x05, 0 ; 5
afc: cc 24 eor r12, r12
afe: dd 24 eor r13, r13
b00: 44 e0 ldi r20, 0x04 ; 4
b02: a4 2e mov r10, r20
b04: 34 c0 rjmp .+104 ; 0xb6e <__stack+0x26f>
led_frequency = RC_LED_FREQUENCY_VAL;
}
}
}
else{ //IF NOT ALL CHANNELS HAVE BEEN MEASURED...
pin_reg_buffer1 = (RC_SERVO_PORT_PIN_REG & channel_mask);
b06: 29 b1 in r18, 0x09 ; 9
b08: 27 21 and r18, r7
tx_signal_detected = 0;
if(servo_signals_lost == 0)
b0a: dd 20 and r13, r13
b0c: a1 f5 brne .+104 ; 0xb76 <__stack+0x277>
{
tx_signal_lost++;
b0e: c3 94 inc r12
if(tx_signal_lost > RC_MAX_BAD_PPM_FRAMES)
b10: 94 e0 ldi r25, 0x04 ; 4
b12: 9c 15 cp r25, r12
b14: 80 f5 brcc .+96 ; 0xb76 <__stack+0x277>
/*77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777*/
/*88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888*/
void load_failsafe_values(void)
{
wdt_reset();
b16: a8 95 wdr
isr_channel_pw[0] = RC_FS_CH_1_TIMER_VAL;
b18: 50 92 1f 01 sts 0x011F, r5
b1c: 40 92 1e 01 sts 0x011E, r4
#if RC_PPM_GEN_CHANNELS >= 2
isr_channel_pw[1] = RC_FS_CH_2_TIMER_VAL;
b20: 50 92 21 01 sts 0x0121, r5
b24: 40 92 20 01 sts 0x0120, r4
#endif
#if RC_PPM_GEN_CHANNELS >= 3
isr_channel_pw[2] = RC_FS_CH_3_TIMER_VAL;
b28: 90 92 23 01 sts 0x0123, r9
b2c: 80 92 22 01 sts 0x0122, r8
#endif
#if RC_PPM_GEN_CHANNELS >= 4
isr_channel_pw[3] = RC_FS_CH_4_TIMER_VAL;
b30: 50 92 25 01 sts 0x0125, r5
b34: 40 92 24 01 sts 0x0124, r4
#endif
#if RC_PPM_GEN_CHANNELS >= 5
isr_channel_pw[4] = RC_FS_CH_5_TIMER_VAL;
b38: 90 92 27 01 sts 0x0127, r9
b3c: 80 92 26 01 sts 0x0126, r8
#endif
#if RC_PPM_GEN_CHANNELS >= 6
isr_channel_pw[5] = RC_FS_CH_6_TIMER_VAL;
b40: 90 92 29 01 sts 0x0129, r9
b44: 80 92 28 01 sts 0x0128, r8
#endif
#if RC_PPM_GEN_CHANNELS >= 7
isr_channel_pw[6] = RC_FS_CH_7_TIMER_VAL;
b48: 90 92 2b 01 sts 0x012B, r9
b4c: 80 92 2a 01 sts 0x012A, r8
#endif
#if RC_PPM_GEN_CHANNELS >= 8
isr_channel_pw[7] = RC_FS_CH_8_TIMER_VAL;
b50: 90 92 2d 01 sts 0x012D, r9
b54: 80 92 2c 01 sts 0x012C, r8
#endif
#if RC_PPM_GEN_CHANNELS >= 9
isr_channel_pw[8] = RC_FS_CH_8_TIMER_VAL;
#endif
isr_channel_pw[RC_PPM_GEN_CHANNELS] = RC_RESET_PW_TIMER_VAL;
b58: 8c ee ldi r24, 0xEC ; 236
b5a: 9c e2 ldi r25, 0x2C ; 44
b5c: 90 93 2f 01 sts 0x012F, r25
b60: 80 93 2e 01 sts 0x012E, r24
b64: bb 24 eor r11, r11
b66: dd 24 eor r13, r13
b68: d3 94 inc r13
b6a: 30 e1 ldi r19, 0x10 ; 16
b6c: a3 2e mov r10, r19
b6e: 00 e0 ldi r16, 0x00 ; 0
b70: 03 c0 rjmp .+6 ; 0xb78 <__stack+0x279>
b72: cc 24 eor r12, r12
b74: 01 c0 rjmp .+2 ; 0xb78 <__stack+0x279>
b76: bb 24 eor r11, r11
/*12121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212*/
void mux_control(void)
{
long PULSE_WIDTH = isr_channel_pw[RC_MUX_CHANNEL-1];
b78: 80 91 2c 01 lds r24, 0x012C
b7c: 90 91 2d 01 lds r25, 0x012D
#if RC_MUX_REVERSE == 0
if((PULSE_WIDTH>RC_MUX_MIN)&&(PULSE_WIDTH<RC_MUX_MAX))
b80: a0 e0 ldi r26, 0x00 ; 0
b82: b0 e0 ldi r27, 0x00 ; 0
b84: 01 97 sbiw r24, 0x01 ; 1
b86: a1 09 sbc r26, r1
b88: b1 09 sbc r27, r1
b8a: 81 5e subi r24, 0xE1 ; 225
b8c: 94 40 sbci r25, 0x04 ; 4
b8e: a0 40 sbci r26, 0x00 ; 0
b90: b0 40 sbci r27, 0x00 ; 0
b92: 10 f4 brcc .+4 ; 0xb98 <__stack+0x299>
{
MUX_ON();
b94: 29 9a sbi 0x05, 1 ; 5
b96: 16 cf rjmp .-468 ; 0x9c4 <__stack+0xc5>
}
else
{
MUX_OFF();
b98: 29 98 cbi 0x05, 1 ; 5
b9a: 14 cf rjmp .-472 ; 0x9c4 <__stack+0xc5>
00000b9c <__eerd_word>:
b9c: df 92 push r13
b9e: ef 92 push r14
ba0: ff 92 push r15
ba2: 0f 93 push r16
ba4: 1f 93 push r17
ba6: 7b 01 movw r14, r22
ba8: 8c 01 movw r16, r24
baa: fb 01 movw r30, r22
bac: 09 95 icall
bae: d8 2e mov r13, r24
bb0: c8 01 movw r24, r16
bb2: 01 96 adiw r24, 0x01 ; 1
bb4: f7 01 movw r30, r14
bb6: 09 95 icall
bb8: 98 2f mov r25, r24
bba: 8d 2d mov r24, r13
bbc: 1f 91 pop r17
bbe: 0f 91 pop r16
bc0: ff 90 pop r15
bc2: ef 90 pop r14
bc4: df 90 pop r13
bc6: 08 95 ret
00000bc8 <__eewr_word>:
bc8: df 92 push r13
bca: ef 92 push r14
bcc: ff 92 push r15
bce: 0f 93 push r16
bd0: 1f 93 push r17
bd2: d7 2e mov r13, r23
bd4: 7a 01 movw r14, r20
bd6: 8c 01 movw r16, r24
bd8: fa 01 movw r30, r20
bda: 09 95 icall
bdc: c8 01 movw r24, r16
bde: 01 96 adiw r24, 0x01 ; 1
be0: 6d 2d mov r22, r13
be2: f7 01 movw r30, r14
be4: 09 95 icall
be6: 1f 91 pop r17
be8: 0f 91 pop r16
bea: ff 90 pop r15
bec: ef 90 pop r14
bee: df 90 pop r13
bf0: 08 95 ret
00000bf2 <__udivmodhi4>:
bf2: aa 1b sub r26, r26
bf4: bb 1b sub r27, r27
bf6: 51 e1 ldi r21, 0x11 ; 17
bf8: 07 c0 rjmp .+14 ; 0xc08 <__udivmodhi4_ep>
00000bfa <__udivmodhi4_loop>:
bfa: aa 1f adc r26, r26
bfc: bb 1f adc r27, r27
bfe: a6 17 cp r26, r22
c00: b7 07 cpc r27, r23
c02: 10 f0 brcs .+4 ; 0xc08 <__udivmodhi4_ep>
c04: a6 1b sub r26, r22
c06: b7 0b sbc r27, r23
00000c08 <__udivmodhi4_ep>:
c08: 88 1f adc r24, r24
c0a: 99 1f adc r25, r25
c0c: 5a 95 dec r21
c0e: a9 f7 brne .-22 ; 0xbfa <__udivmodhi4_loop>
c10: 80 95 com r24
c12: 90 95 com r25
c14: bc 01 movw r22, r24
c16: cd 01 movw r24, r26
c18: 08 95 ret
00000c1a <_exit>:
c1a: f8 94 cli
00000c1c <__stop_program>:
c1c: ff cf rjmp .-2 ; 0xc1c <__stop_program>