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
9e: 0c 94 0d 06 jmp 0xc1a ; 0xc1a <_exit> 000000a2 <__bad_interrupt>: a2: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 000000a6 : /** \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 #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 : /** \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 #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 : 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< // 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 /** \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 #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 /** \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 #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 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 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<: /*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 { 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 x=0; while(timer0.timer0[1] <= RC_MAX_TIMEOUT_VAL ) { if(RC_SERVO_PORT_PIN_REG & (1< 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 226: 5f 5f subi r21, 0xFF ; 255 228: 04 c0 rjmp .+8 ; 0x232 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 { if(RC_SERVO_PORT_PIN_REG & (1<= RC_PULSE_TIMEOUT_VAL ){ servo_connected++; break; } } if(servo_connected >= 3){ channel_mask |= (1< 236: f6 2b or r31, r22 238: af 5f subi r26, 0xFF ; 255 23a: 03 c0 rjmp .+6 ; 0x242 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 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 24c: be 01 movw r22, r28 24e: 02 2e mov r0, r18 250: 02 c0 rjmp .+4 ; 0x256 252: 66 0f add r22, r22 254: 77 1f adc r23, r23 256: 0a 94 dec r0 258: e2 f7 brpl .-8 ; 0x252 25a: 50 e0 ldi r21, 0x00 ; 0 25c: 40 e0 ldi r20, 0x00 ; 0 25e: cd cf rjmp .-102 ; 0x1fa 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 : { 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< 27e: 22 0f add r18, r18 280: 33 1f adc r19, r19 282: 8a 95 dec r24 284: e2 f7 brpl .-8 ; 0x27e 286: 20 93 6d 00 sts 0x006D, r18 //Clear any pin interrupt flag set. RC_PIN_INT_FLAG_REG |= (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 2b6: 20 e0 ldi r18, 0x00 ; 0 2b8: 30 e0 ldi r19, 0x00 ; 0 2ba: 1f c0 rjmp .+62 ; 0x2fa { 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 pin_interrupt_detected = 0; 2c4: 10 92 14 01 sts 0x0114, r1 if( RC_SERVO_PORT_PIN_REG & (1< { 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 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 { 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 : } #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 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 328: 22 0f add r18, r18 32a: 33 1f adc r19, r19 32c: 0a 94 dec r0 32e: e2 f7 brpl .-8 ; 0x328 330: 40 e0 ldi r20, 0x00 ; 0 332: 0f c0 rjmp .+30 ; 0x352 servo_connected = 0; x=0; while(timer0.timer0[1] <= RC_MAX_TIMEOUT_VAL ) { if(RC_SERVO_PORT_PIN_REG & (1< 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 { 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 35a: 12 c0 rjmp .+36 ; 0x380 35c: 00 e0 ldi r16, 0x00 ; 0 35e: dc cf rjmp .-72 ; 0x318 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 364: fb cf rjmp .-10 ; 0x35c 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 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 378: 1f 5f subi r17, 0xFF ; 255 if(x >= 3) { break; } 37a: 13 30 cpi r17, 0x03 ; 3 37c: a8 f3 brcs .-22 ; 0x368 37e: 02 c0 rjmp .+4 ; 0x384 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 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 : /*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 : /*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 { 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< 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 : /*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 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 #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 { 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 : /*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< 546: 90 e0 ldi r25, 0x00 ; 0 548: 01 c0 rjmp .+2 ; 0x54c 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 554: e7 c0 rjmp .+462 ; 0x724 } }while(x < 100); 556: 94 36 cpi r25, 0x64 ; 100 558: a0 f3 brcs .-24 ; 0x542 55a: d9 c0 rjmp .+434 ; 0x70e /****************************************************************************************************/ 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 { 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 #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 590: 2e c0 rjmp .+92 ; 0x5ee 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 596: 74 c0 rjmp .+232 ; 0x680 { for(x=0; x < RC_SERVO_INPUT_CHANNELS; x++) { if(channel_mask & (1< 5ac: 95 95 asr r25 5ae: 87 95 ror r24 5b0: 0a 94 dec r0 5b2: e2 f7 brpl .-8 ; 0x5ac 5b4: 80 ff sbrs r24, 0 5b6: 15 c0 rjmp .+42 ; 0x5e2 { 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 #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 5e0: 06 c0 rjmp .+12 ; 0x5ee 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 5ec: 49 c0 rjmp .+146 ; 0x680 /****************************************************************************************************/ /* 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 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 { 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 { 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 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 650: 65 c0 rjmp .+202 ; 0x71c { 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 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 67e: 4e c0 rjmp .+156 ; 0x71c while(timer0.timer0[1] < RC_MAX_TIMEOUT_VAL ); } } }else{ write_default_values_to_eeprom(); 680: 0e 94 65 02 call 0x4ca ; 0x4ca { 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 if(success == 2) { RC_SETUP_PORT_OUT_REG &= (~(1< { RC_SETUP_PORT_OUT_REG &= (~(1< 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 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 6ca: df cf rjmp .-66 ; 0x68a }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 }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 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 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 70c: df cf rjmp .-66 ; 0x6cc 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 718: 21 cf rjmp .-446 ; 0x55c 71a: 3b cf rjmp .-394 ; 0x592 /****************************************************************************************************/ /* LASTLY WE MUST INDICATE TO THE USER IF THE SETUP PROCEDURE WAS SUCCESSFUL */ /****************************************************************************************************/ if(success == 2) { RC_SETUP_PORT_OUT_REG &= (~(1< } } // 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 : 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 #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 #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 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 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 { if( eeprom_buf_x < RC_SERVO_INPUT_CHANNELS ) 792: 18 97 sbiw r26, 0x08 ; 8 794: 08 f0 brcs .+2 ; 0x798 796: 7b c0 rjmp .+246 ; 0x88e { 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 /** \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 #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 7c0: 07 c0 rjmp .+14 ; 0x7d0 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 7cc: c3 cf rjmp .-122 ; 0x754 7ce: 5f c0 rjmp .+190 ; 0x88e }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 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 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 { 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 { 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 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 84a: 23 c0 rjmp .+70 ; 0x892 } }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 { 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 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 87c: 0a c0 rjmp .+20 ; 0x892 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 88c: a9 cf rjmp .-174 ; 0x7e0 }else{ match = 0; } break; } } if( match < match_lower_limit ){ write_default_values_to_eeprom(); return; } 88e: 0e 94 65 02 call 0x4ca ; 0x4ca 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 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 /*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 /*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 channels_in_use = detect_connected_channels(); 94c: 0e 94 eb 00 call 0x1d6 ; 0x1d6 950: 80 93 18 01 sts 0x0118, r24 check_for_setup_mode(); 954: 0e 94 94 02 call 0x528 ; 0x528 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_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 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 } // 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< 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 { 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>