Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed


main.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000009  0080011b  00000d82  00000e16  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  1 .text         00000d82  00000000  00000000  00000094  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .bss          000000b1  00800124  00800124  00000e1f  2**0
                  ALLOC
  3 .noinit       00000000  008001d5  008001d5  00000e1f  2**0
                  CONTENTS
  4 .eeprom       00000000  00810000  00810000  00000e1f  2**0
                  CONTENTS
  5 .stab         00002b20  00000000  00000000  00000e20  2**2
                  CONTENTS, READONLY, DEBUGGING
  6 .stabstr      00001f11  00000000  00000000  00003940  2**0
                  CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
   0:   0c 94 34 00     jmp 0x68 <__ctors_end>
   4:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
   8:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
   c:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  10:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  14:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  18:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  1c:   0c 94 7e 00     jmp 0xfc <__vector_7>
  20:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  24:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  28:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  2c:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  30:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  34:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  38:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  3c:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  40:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  44:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  48:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  4c:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  50:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  54:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  58:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  5c:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  60:   0c 94 4f 00     jmp 0x9e <__bad_interrupt>
  64:   0c 94 4f 00     jmp 0x9e <__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:   d4 e0           ldi r29, 0x04   ; 4
  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:   ab e1           ldi r26, 0x1B   ; 27
  78:   b1 e0           ldi r27, 0x01   ; 1
  7a:   e2 e8           ldi r30, 0x82   ; 130
  7c:   fd e0           ldi r31, 0x0D   ; 13
  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 32           cpi r26, 0x24   ; 36
  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 e2           ldi r26, 0x24   ; 36
  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:   a5 3d           cpi r26, 0xD5   ; 213
  96:   b1 07           cpc r27, r17
  98:   e1 f7           brne    .-8         ; 0x92 <.do_clear_bss_loop>
  9a:   0c 94 51 00     jmp 0xa2 <main>

0000009e <__bad_interrupt>:
  9e:   0c 94 00 00     jmp 0x0 <__heap_end>

000000a2 <main>:

#include "../modules/sns_ds18x20/sns_ds18x20.h"

int main(void)
{
  a2:   c2 ef           ldi r28, 0xF2   ; 242
  a4:   d4 e0           ldi r29, 0x04   ; 4
  a6:   de bf           out 0x3e, r29   ; 62
  a8:   cd bf           out 0x3d, r28   ; 61
    StdCan_Msg_t rxMsg; // Message storage

    // Enable interrupts as early as possible
    sei();
  aa:   78 94           sei
    
    Timer_Init();
  ac:   0e 94 da 00     call    0x1b4 <Timer_Init>

    StdCan_Init();
  b0:   0e 94 5b 05     call    0xab6 <StdCan_Init>
    
    Timer_SetTimeout(APP_HEARTBEAT_TIMER, STDCAN_HEARTBEAT_PERIOD, TimerTypeFreeRunning, StdCan_SendHeartbeat);
  b4:   2f ed           ldi r18, 0xDF   ; 223
  b6:   34 e0           ldi r19, 0x04   ; 4
  b8:   41 e0           ldi r20, 0x01   ; 1
  ba:   60 e1           ldi r22, 0x10   ; 16
  bc:   77 e2           ldi r23, 0x27   ; 39
  be:   80 e0           ldi r24, 0x00   ; 0
  c0:   0e 94 f6 00     call    0x1ec <Timer_SetTimeout>
    
    sns_ds18x20_Init();
  c4:   0e 94 c8 05     call    0xb90 <sns_ds18x20_Init>

    while (1) {
    
        sns_ds18x20_Process();
  c8:   0e 94 58 06     call    0xcb0 <sns_ds18x20_Process>
    
        if (StdCan_Get(&rxMsg) == StdCan_Ret_OK) {
  cc:   8e 01           movw    r16, r28
  ce:   0f 5f           subi    r16, 0xFF   ; 255
  d0:   1f 4f           sbci    r17, 0xFF   ; 255
  d2:   c8 01           movw    r24, r16
  d4:   0e 94 83 04     call    0x906 <StdCan_Get>
  d8:   88 23           and r24, r24
  da:   b1 f7           brne    .-20        ; 0xc8 <main+0x26>
            if ((uint8_t)StdCan_Ret_class(rxMsg) == CAN_MODULE_NMT) {
  dc:   8c 81           ldd r24, Y+4    ; 0x04
  de:   86 95           lsr r24
  e0:   8f 70           andi    r24, 0x0F   ; 15
  e2:   8b 30           cpi r24, 0x0B   ; 11
  e4:   39 f4           brne    .+14        ; 0xf4 <main+0x52>
                
                if (rxMsg.Header.ModuleType == CAN_MODULE_NMT_LIST) {
  e6:   8b 81           ldd r24, Y+3    ; 0x03
  e8:   8d 32           cpi r24, 0x2D   ; 45
  ea:   71 f7           brne    .-36        ; 0xc8 <main+0x26>
                    sns_ds18x20_List(1);
  ec:   81 e0           ldi r24, 0x01   ; 1
  ee:   0e 94 9e 05     call    0xb3c <sns_ds18x20_List>
  f2:   ea cf           rjmp    .-44        ; 0xc8 <main+0x26>
                }
            }
            else {
            
                sns_ds18x20_HandleMessage(&rxMsg);
  f4:   c8 01           movw    r24, r16
  f6:   0e 94 9d 05     call    0xb3a <sns_ds18x20_HandleMessage>
  fa:   e6 cf           rjmp    .-52        ; 0xc8 <main+0x26>

000000fc <__vector_7>:
/*-----------------------------------------------------------------------------
 * Interrupt Service Routines
 *---------------------------------------------------------------------------*/
ISR(TIMER_VECTOR)
{
  fc:   1f 92           push    r1
  fe:   0f 92           push    r0
 100:   0f b6           in  r0, 0x3f    ; 63
 102:   0f 92           push    r0
 104:   11 24           eor r1, r1
 106:   0f 93           push    r16
 108:   1f 93           push    r17
 10a:   2f 93           push    r18
 10c:   3f 93           push    r19
 10e:   4f 93           push    r20
 110:   5f 93           push    r21
 112:   6f 93           push    r22
 114:   7f 93           push    r23
 116:   8f 93           push    r24
 118:   9f 93           push    r25
 11a:   af 93           push    r26
 11c:   bf 93           push    r27
 11e:   cf 93           push    r28
 120:   df 93           push    r29
 122:   ef 93           push    r30
 124:   ff 93           push    r31
    uint8_t t;
#if defined(TIMER_RELOAD)
    /* The hw timer does not support auto-reload so set the count manually. */
    TIMER_RELOAD(TIMER_COUNTS_PER_TICK);
#endif

    /* Increase the global tick count. */
    ticks++;
 126:   80 91 62 01     lds r24, 0x0162
 12a:   90 91 63 01     lds r25, 0x0163
 12e:   a0 91 64 01     lds r26, 0x0164
 132:   b0 91 65 01     lds r27, 0x0165
 136:   01 96           adiw    r24, 0x01   ; 1
 138:   a1 1d           adc r26, r1
 13a:   b1 1d           adc r27, r1
 13c:   80 93 62 01     sts 0x0162, r24
 140:   90 93 63 01     sts 0x0163, r25
 144:   a0 93 64 01     sts 0x0164, r26
 148:   b0 93 65 01     sts 0x0165, r27
 14c:   00 e0           ldi r16, 0x00   ; 0
 14e:   10 e0           ldi r17, 0x00   ; 0
 150:   cd e4           ldi r28, 0x4D   ; 77
 152:   d1 e0           ldi r29, 0x01   ; 1
    
    /* Decrease the timeout of all active timers and check if any have
     * expired. */
    for (t = 0; t < TIMER_NUM_TIMERS; t++)
    {
        if ((timers[t].timeout > 0) && (--timers[t].timeout == 0))
 154:   88 81           ld  r24, Y
 156:   99 81           ldd r25, Y+1    ; 0x01
 158:   00 97           sbiw    r24, 0x00   ; 0
 15a:   89 f0           breq    .+34        ; 0x17e <__vector_7+0x82>
 15c:   01 97           sbiw    r24, 0x01   ; 1
 15e:   99 83           std Y+1, r25    ; 0x01
 160:   88 83           st  Y, r24
 162:   89 2b           or  r24, r25
 164:   61 f4           brne    .+24        ; 0x17e <__vector_7+0x82>
        {
            timers[t].expired = 1;
 166:   81 e0           ldi r24, 0x01   ; 1
 168:   8c 83           std Y+4, r24    ; 0x04
            timers[t].timeout = timers[t].reload;
 16a:   8a 81           ldd r24, Y+2    ; 0x02
 16c:   9b 81           ldd r25, Y+3    ; 0x03
 16e:   99 83           std Y+1, r25    ; 0x01
 170:   88 83           st  Y, r24
            /* Call the callback, if any. */
            if (timers[t].callback) timers[t].callback(t);
 172:   ed 81           ldd r30, Y+5    ; 0x05
 174:   fe 81           ldd r31, Y+6    ; 0x06
 176:   30 97           sbiw    r30, 0x00   ; 0
 178:   11 f0           breq    .+4         ; 0x17e <__vector_7+0x82>
 17a:   80 2f           mov r24, r16
 17c:   09 95           icall
 17e:   0f 5f           subi    r16, 0xFF   ; 255
 180:   1f 4f           sbci    r17, 0xFF   ; 255
 182:   27 96           adiw    r28, 0x07   ; 7
 184:   03 30           cpi r16, 0x03   ; 3
 186:   11 05           cpc r17, r1
 188:   29 f7           brne    .-54        ; 0x154 <__vector_7+0x58>
 18a:   ff 91           pop r31
 18c:   ef 91           pop r30
 18e:   df 91           pop r29
 190:   cf 91           pop r28
 192:   bf 91           pop r27
 194:   af 91           pop r26
 196:   9f 91           pop r25
 198:   8f 91           pop r24
 19a:   7f 91           pop r23
 19c:   6f 91           pop r22
 19e:   5f 91           pop r21
 1a0:   4f 91           pop r20
 1a2:   3f 91           pop r19
 1a4:   2f 91           pop r18
 1a6:   1f 91           pop r17
 1a8:   0f 91           pop r16
 1aa:   0f 90           pop r0
 1ac:   0f be           out 0x3f, r0    ; 63
 1ae:   0f 90           pop r0
 1b0:   1f 90           pop r1
 1b2:   18 95           reti

000001b4 <Timer_Init>:
        }
    }
}


/*-----------------------------------------------------------------------------
 * Public Functions
 *---------------------------------------------------------------------------*/

void Timer_Init()
{
    /* Do basic setup of the timer hw, including interrupts. */
    TIMER_INIT();
 1b4:   82 e0           ldi r24, 0x02   ; 2
 1b6:   80 93 b0 00     sts 0x00B0, r24
 1ba:   87 bb           out 0x17, r24   ; 23
 1bc:   e0 e7           ldi r30, 0x70   ; 112
 1be:   f0 e0           ldi r31, 0x00   ; 0
 1c0:   80 81           ld  r24, Z
 1c2:   82 60           ori r24, 0x02   ; 2
 1c4:   80 83           st  Z, r24
#if defined(TIMER_RELOAD)
    /* The hw timer does not support auto-reload so set the count manually. */
    TIMER_RELOAD(TIMER_COUNTS_PER_TICK);
#endif
#if defined(TIMER_COMPARE_REG)
    /* The hw timer has a compare match module so use it for auto-reload. */
    TIMER_COMPARE_REG = TIMER_COUNTS_PER_TICK;
 1c6:   8c e7           ldi r24, 0x7C   ; 124
 1c8:   80 93 b3 00     sts 0x00B3, r24
#endif
    /* Finalize hw setup and start the timer by setting its prescaler. */
    TIMER_SET_PRESCALER();
 1cc:   84 e0           ldi r24, 0x04   ; 4
 1ce:   80 93 b1 00     sts 0x00B1, r24
 1d2:   08 95           ret

000001d4 <Timer_GetTicks>:
}

/*---------------------------------------------------------------------------*/

uint32_t Timer_GetTicks()
{
    uint32_t res;
    uint8_t sreg = SREG;
 1d4:   2f b7           in  r18, 0x3f   ; 63
    cli();
 1d6:   f8 94           cli
    res = ticks;
 1d8:   60 91 62 01     lds r22, 0x0162
 1dc:   70 91 63 01     lds r23, 0x0163
 1e0:   80 91 64 01     lds r24, 0x0164
 1e4:   90 91 65 01     lds r25, 0x0165
    SREG = sreg;
 1e8:   2f bf           out 0x3f, r18   ; 63
 1ea:   08 95           ret

000001ec <Timer_SetTimeout>:
    return res;
}

/*---------------------------------------------------------------------------*/

void Timer_SetTimeout(uint8_t timer, uint16_t timeout, uint8_t type, timerCallback_t callback)
{
    if (timer<TIMER_NUM_TIMERS)
 1ec:   83 30           cpi r24, 0x03   ; 3
 1ee:   20 f5           brcc    .+72        ; 0x238 <Timer_SetTimeout+0x4c>
    {
        uint8_t sreg = SREG;
 1f0:   5f b7           in  r21, 0x3f   ; 63
        cli();
 1f2:   f8 94           cli
        timers[timer].expired = 0;
 1f4:   99 27           eor r25, r25
 1f6:   fc 01           movw    r30, r24
 1f8:   a3 e0           ldi r26, 0x03   ; 3
 1fa:   ee 0f           add r30, r30
 1fc:   ff 1f           adc r31, r31
 1fe:   aa 95           dec r26
 200:   e1 f7           brne    .-8         ; 0x1fa <Timer_SetTimeout+0xe>
 202:   e8 1b           sub r30, r24
 204:   f9 0b           sbc r31, r25
 206:   e3 5b           subi    r30, 0xB3   ; 179
 208:   fe 4f           sbci    r31, 0xFE   ; 254
 20a:   14 82           std Z+4, r1 ; 0x04
        timers[timer].timeout = timeout;
 20c:   71 83           std Z+1, r23    ; 0x01
 20e:   60 83           st  Z, r22
        if (type == TimerTypeFreeRunning)
 210:   41 30           cpi r20, 0x01   ; 1
 212:   19 f4           brne    .+6         ; 0x21a <Timer_SetTimeout+0x2e>
            timers[timer].reload = timeout;
 214:   73 83           std Z+3, r23    ; 0x03
 216:   62 83           std Z+2, r22    ; 0x02
 218:   02 c0           rjmp    .+4         ; 0x21e <Timer_SetTimeout+0x32>
        else
            timers[timer].reload = 0;
 21a:   13 82           std Z+3, r1 ; 0x03
 21c:   12 82           std Z+2, r1 ; 0x02
        timers[timer].callback = callback;
 21e:   fc 01           movw    r30, r24
 220:   43 e0           ldi r20, 0x03   ; 3
 222:   ee 0f           add r30, r30
 224:   ff 1f           adc r31, r31
 226:   4a 95           dec r20
 228:   e1 f7           brne    .-8         ; 0x222 <Timer_SetTimeout+0x36>
 22a:   e8 1b           sub r30, r24
 22c:   f9 0b           sbc r31, r25
 22e:   e3 5b           subi    r30, 0xB3   ; 179
 230:   fe 4f           sbci    r31, 0xFE   ; 254
 232:   36 83           std Z+6, r19    ; 0x06
 234:   25 83           std Z+5, r18    ; 0x05
        SREG = sreg;
 236:   5f bf           out 0x3f, r21   ; 63
 238:   08 95           ret

0000023a <Timer_Expired>:
    }
}

/*---------------------------------------------------------------------------*/

uint8_t Timer_Expired(uint8_t timer)
{
    if ((timer<TIMER_NUM_TIMERS) && (timers[timer].expired))
 23a:   83 30           cpi r24, 0x03   ; 3
 23c:   90 f4           brcc    .+36        ; 0x262 <Timer_Expired+0x28>
 23e:   99 27           eor r25, r25
 240:   fc 01           movw    r30, r24
 242:   b3 e0           ldi r27, 0x03   ; 3
 244:   ee 0f           add r30, r30
 246:   ff 1f           adc r31, r31
 248:   ba 95           dec r27
 24a:   e1 f7           brne    .-8         ; 0x244 <Timer_Expired+0xa>
 24c:   e8 1b           sub r30, r24
 24e:   f9 0b           sbc r31, r25
 250:   e3 5b           subi    r30, 0xB3   ; 179
 252:   fe 4f           sbci    r31, 0xFE   ; 254
 254:   84 81           ldd r24, Z+4    ; 0x04
 256:   88 23           and r24, r24
 258:   21 f0           breq    .+8         ; 0x262 <Timer_Expired+0x28>
    {
        timers[timer].expired = 0;
 25a:   14 82           std Z+4, r1 ; 0x04
 25c:   81 e0           ldi r24, 0x01   ; 1
 25e:   90 e0           ldi r25, 0x00   ; 0
 260:   08 95           ret
        return 1;
 262:   80 e0           ldi r24, 0x00   ; 0
 264:   90 e0           ldi r25, 0x00   ; 0
    }
    return 0;
}
 266:   08 95           ret

00000268 <Mcu_Init>:
#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
    // set the clock speed to 8MHz
    // set the clock prescaler. First write CLKPCE to enable setting of clock the
    // next four instructions.
    CLKPR=(1<<CLKPCE);
 268:   e1 e6           ldi r30, 0x61   ; 97
 26a:   f0 e0           ldi r31, 0x00   ; 0
 26c:   80 e8           ldi r24, 0x80   ; 128
 26e:   80 83           st  Z, r24
    #ifndef AVR_CLOCK_PRESC
        CLKPR=0; // 8 MHZ
 270:   10 82           st  Z, r1
 272:   08 95           ret

00000274 <Mcu_EnableIRQ>:
    #endif
    
    #if AVR_CLOCK_PRESC == 1
        CLKPR=0; // 8 MHZ
    #elif AVR_CLOCK_PRESC == 2
        CLKPR=1; // 4 MHZ
    #elif AVR_CLOCK_PRESC == 4
        CLKPR=2; // 2 MHZ
    #elif AVR_CLOCK_PRESC == 8
        CLKPR=3; // 1 MHZ
    #elif AVR_CLOCK_PRESC == 16
        CLKPR=4; // 500 kHZ
    #elif AVR_CLOCK_PRESC == 32
        CLKPR=5; // 250 kHZ
    #elif AVR_CLOCK_PRESC == 64
        CLKPR=6; // 125 kHZ
    #elif AVR_CLOCK_PRESC == 128
        CLKPR=7; // 62.5 kHZ
    #elif AVR_CLOCK_PRESC == 256
        CLKPR=8; // 31.25 kHZ
    #endif
#endif
}

/**
 * Enable interrupts.
 */
void Mcu_EnableIRQ() {
    #if MCU == atmega8
        sei();
 274:   78 94           sei
 276:   08 95           ret

00000278 <Mcu_DisableIRQ>:
    #endif
}

/**
 * Disable interrupts.
 */
void Mcu_DisableIRQ() {
    #if MCU == atmega8
        cli();
 278:   f8 94           cli
 27a:   08 95           ret

0000027c <DS18X20_meas_to_cel>:
   TODO invalid-values detection (but should be covered by CRC)
*/
uint8_t DS18X20_meas_to_cel( uint8_t fc, uint8_t *sp, 
    uint8_t* subzero, uint8_t* cel, uint8_t* cel_frac_bits)
{
 27c:   ff 92           push    r15
 27e:   0f 93           push    r16
 280:   1f 93           push    r17
 282:   cf 93           push    r28
 284:   df 93           push    r29
 286:   f8 2e           mov r15, r24
 288:   fb 01           movw    r30, r22
 28a:   da 01           movw    r26, r20
 28c:   e9 01           movw    r28, r18
 28e:   a8 01           movw    r20, r16
    uint16_t meas;
    uint8_t  i;
    
    meas = sp[0];  // LSB
 290:   80 81           ld  r24, Z
 292:   28 2f           mov r18, r24
 294:   33 27           eor r19, r19
    meas |= ((uint16_t)sp[1])<<8; // MSB
 296:   81 81           ldd r24, Z+1    ; 0x01
 298:   99 27           eor r25, r25
 29a:   98 2f           mov r25, r24
 29c:   88 27           eor r24, r24
 29e:   28 2b           or  r18, r24
 2a0:   39 2b           or  r19, r25
    //meas = 0xff5e; meas = 0xfe6f;
    
    //  only work on 12bit-base
    if( fc == DS18S20_ID ) { // 9 -> 12 bit if 18S20
 2a2:   80 e1           ldi r24, 0x10   ; 16
 2a4:   f8 16           cp  r15, r24
 2a6:   59 f4           brne    .+22        ; 0x2be <DS18X20_meas_to_cel+0x42>
        /* Extended measurements for DS18S20 contributed by Carsten Foss */
        meas &= (uint16_t) 0xfffe;  // Discard LSB , needed for later extended precicion calc
 2a8:   2e 7f           andi    r18, 0xFE   ; 254
        meas <<= 3;                 // Convert to 12-bit , now degrees are in 1/16 degrees units
        meas += (16 - sp[6]) - 4;   // Add the compensation , and remember to subtract 0.25 degree (4/16)
 2aa:   63 e0           ldi r22, 0x03   ; 3
 2ac:   22 0f           add r18, r18
 2ae:   33 1f           adc r19, r19
 2b0:   6a 95           dec r22
 2b2:   e1 f7           brne    .-8         ; 0x2ac <DS18X20_meas_to_cel+0x30>
 2b4:   86 81           ldd r24, Z+6    ; 0x06
 2b6:   28 1b           sub r18, r24
 2b8:   31 09           sbc r19, r1
 2ba:   24 5f           subi    r18, 0xF4   ; 244
 2bc:   3f 4f           sbci    r19, 0xFF   ; 255
    }
    
    // check for negative 
    if ( meas & 0x8000 )  {
 2be:   37 ff           sbrs    r19, 7
 2c0:   06 c0           rjmp    .+12        ; 0x2ce <DS18X20_meas_to_cel+0x52>
        *subzero=1;      // mark negative
 2c2:   81 e0           ldi r24, 0x01   ; 1
 2c4:   8c 93           st  X, r24
        meas ^= 0xffff;  // convert to positive => (twos complement)++
        meas++;
 2c6:   30 95           com r19
 2c8:   21 95           neg r18
 2ca:   3f 4f           sbci    r19, 0xFF   ; 255
 2cc:   01 c0           rjmp    .+2         ; 0x2d0 <DS18X20_meas_to_cel+0x54>
    }
    else *subzero=0;
 2ce:   1c 92           st  X, r1
    
    // clear undefined bits for B != 12bit
    if ( fc == DS18B20_ID ) { // check resolution 18B20
 2d0:   88 e2           ldi r24, 0x28   ; 40
 2d2:   f8 16           cp  r15, r24
 2d4:   91 f4           brne    .+36        ; 0x2fa <DS18X20_meas_to_cel+0x7e>
        i = sp[DS18B20_CONF_REG];
        if ( (i & DS18B20_12_BIT) == DS18B20_12_BIT ) ;
 2d6:   84 81           ldd r24, Z+4    ; 0x04
 2d8:   68 2f           mov r22, r24
 2da:   77 27           eor r23, r23
 2dc:   cb 01           movw    r24, r22
 2de:   80 76           andi    r24, 0x60   ; 96
 2e0:   90 70           andi    r25, 0x00   ; 0
 2e2:   80 36           cpi r24, 0x60   ; 96
 2e4:   91 05           cpc r25, r1
 2e6:   49 f0           breq    .+18        ; 0x2fa <DS18X20_meas_to_cel+0x7e>
        else if ( (i & DS18B20_11_BIT) == DS18B20_11_BIT ) 
 2e8:   66 ff           sbrs    r22, 6
 2ea:   02 c0           rjmp    .+4         ; 0x2f0 <DS18X20_meas_to_cel+0x74>
            meas &= ~(DS18B20_11_BIT_UNDF);
 2ec:   2e 7f           andi    r18, 0xFE   ; 254
 2ee:   05 c0           rjmp    .+10        ; 0x2fa <DS18X20_meas_to_cel+0x7e>
        else if ( (i & DS18B20_10_BIT) == DS18B20_10_BIT ) 
 2f0:   65 ff           sbrs    r22, 5
 2f2:   02 c0           rjmp    .+4         ; 0x2f8 <DS18X20_meas_to_cel+0x7c>
            meas &= ~(DS18B20_10_BIT_UNDF);
 2f4:   2c 7f           andi    r18, 0xFC   ; 252
 2f6:   01 c0           rjmp    .+2         ; 0x2fa <DS18X20_meas_to_cel+0x7e>
        else { // if ( (i & DS18B20_9_BIT) == DS18B20_9_BIT ) { 
            meas &= ~(DS18B20_9_BIT_UNDF);
 2f8:   28 7f           andi    r18, 0xF8   ; 248
        }
    }           
    
    *cel  = (uint8_t)(meas >> 4); 
 2fa:   c9 01           movw    r24, r18
 2fc:   34 e0           ldi r19, 0x04   ; 4
 2fe:   96 95           lsr r25
 300:   87 95           ror r24
 302:   3a 95           dec r19
 304:   e1 f7           brne    .-8         ; 0x2fe <DS18X20_meas_to_cel+0x82>
 306:   88 83           st  Y, r24
    *cel_frac_bits = (uint8_t)(meas & 0x000F);
 308:   82 2f           mov r24, r18
 30a:   8f 70           andi    r24, 0x0F   ; 15
 30c:   fa 01           movw    r30, r20
 30e:   80 83           st  Z, r24
    
    return DS18X20_OK;
}
 310:   80 e0           ldi r24, 0x00   ; 0
 312:   90 e0           ldi r25, 0x00   ; 0
 314:   df 91           pop r29
 316:   cf 91           pop r28
 318:   1f 91           pop r17
 31a:   0f 91           pop r16
 31c:   ff 90           pop r15
 31e:   08 95           ret

00000320 <DS18X20_temp_to_decicel>:

/* converts to decicelsius
   input is ouput from meas_to_cel
   returns absolute value of temperatur in decicelsius
    i.e.: sz=0, c=28, frac=15 returns 289 (=28.9�C)
0    0    0    
1   625 625 1
2   1250    250 
3   1875    875 3
4   2500    500 4
5   3125    125 
6   3750    750 6
7   4375    375 
8   5000    0    
9   5625    625 9
10  6250    250 
11  6875    875 11
12  7500    500 12
13  8125    125 
14  8750    750 14
15  9375    375 */
uint16_t DS18X20_temp_to_decicel(uint8_t subzero, uint8_t cel, 
    uint8_t cel_frac_bits)
{
 320:   0f 93           push    r16
 322:   1f 93           push    r17
 324:   cf 93           push    r28
 326:   df 93           push    r29
 328:   cd b7           in  r28, 0x3d   ; 61
 32a:   de b7           in  r29, 0x3e   ; 62
 32c:   28 97           sbiw    r28, 0x08   ; 8
 32e:   0f b6           in  r0, 0x3f    ; 63
 330:   f8 94           cli
 332:   de bf           out 0x3e, r29   ; 62
 334:   0f be           out 0x3f, r0    ; 63
 336:   cd bf           out 0x3d, r28   ; 61
 338:   08 2f           mov r16, r24
 33a:   16 2f           mov r17, r22
    uint16_t h;
    uint8_t  i;
    uint8_t need_rounding[] = { 1, 3, 4, 6, 9, 11, 12, 14 };
 33c:   de 01           movw    r26, r28
 33e:   11 96           adiw    r26, 0x01   ; 1
 340:   eb e1           ldi r30, 0x1B   ; 27
 342:   f1 e0           ldi r31, 0x01   ; 1
 344:   88 e0           ldi r24, 0x08   ; 8
 346:   01 90           ld  r0, Z+
 348:   0d 92           st  X+, r0
 34a:   81 50           subi    r24, 0x01   ; 1
 34c:   e1 f7           brne    .-8         ; 0x346 <DS18X20_temp_to_decicel+0x26>
    
    h = cel_frac_bits*DS18X20_FRACCONV/1000;
 34e:   24 2f           mov r18, r20
 350:   33 27           eor r19, r19
 352:   81 e7           ldi r24, 0x71   ; 113
 354:   92 e0           ldi r25, 0x02   ; 2
 356:   bc 01           movw    r22, r24
 358:   26 9f           mul r18, r22
 35a:   c0 01           movw    r24, r0
 35c:   27 9f           mul r18, r23
 35e:   90 0d           add r25, r0
 360:   36 9f           mul r19, r22
 362:   90 0d           add r25, r0
 364:   11 24           eor r1, r1
 366:   68 ee           ldi r22, 0xE8   ; 232
 368:   73 e0           ldi r23, 0x03   ; 3
 36a:   0e 94 9a 06     call    0xd34 <__divmodhi4>
    h += cel*10;
 36e:   8a e0           ldi r24, 0x0A   ; 10
 370:   18 9f           mul r17, r24
 372:   c0 01           movw    r24, r0
 374:   11 24           eor r1, r1
 376:   68 0f           add r22, r24
 378:   79 1f           adc r23, r25
    if (!subzero) {
 37a:   00 23           and r16, r16
 37c:   79 f4           brne    .+30        ; 0x39c <DS18X20_temp_to_decicel+0x7c>
 37e:   fe 01           movw    r30, r28
 380:   31 96           adiw    r30, 0x01   ; 1
 382:   9e 01           movw    r18, r28
 384:   27 5f           subi    r18, 0xF7   ; 247
 386:   3f 4f           sbci    r19, 0xFF   ; 255
        for (i=0; i<sizeof(need_rounding); i++) {
            if ( cel_frac_bits == need_rounding[i] ) {
 388:   80 81           ld  r24, Z
 38a:   48 17           cp  r20, r24
 38c:   19 f4           brne    .+6         ; 0x394 <DS18X20_temp_to_decicel+0x74>
                h++;
 38e:   6f 5f           subi    r22, 0xFF   ; 255
 390:   7f 4f           sbci    r23, 0xFF   ; 255
 392:   04 c0           rjmp    .+8         ; 0x39c <DS18X20_temp_to_decicel+0x7c>
                break;
 394:   31 96           adiw    r30, 0x01   ; 1
 396:   e2 17           cp  r30, r18
 398:   f3 07           cpc r31, r19
 39a:   b1 f7           brne    .-20        ; 0x388 <DS18X20_temp_to_decicel+0x68>
            }
        }
    }
    return h;
}
 39c:   cb 01           movw    r24, r22
 39e:   28 96           adiw    r28, 0x08   ; 8
 3a0:   0f b6           in  r0, 0x3f    ; 63
 3a2:   f8 94           cli
 3a4:   de bf           out 0x3e, r29   ; 62
 3a6:   0f be           out 0x3f, r0    ; 63
 3a8:   cd bf           out 0x3d, r28   ; 61
 3aa:   df 91           pop r29
 3ac:   cf 91           pop r28
 3ae:   1f 91           pop r17
 3b0:   0f 91           pop r16
 3b2:   08 95           ret

000003b4 <DS18X20_temp_cmp>:

/* compare temperature values (full celsius only)
   returns -1 if param-pair1 < param-pair2 
            0 if == 
            1 if >    */
int8_t DS18X20_temp_cmp(uint8_t subzero1, uint16_t cel1, 
    uint8_t subzero2, uint16_t cel2)
{
    int16_t t1 = (subzero1) ? (cel1*(-1)) : (cel1);
 3b4:   88 23           and r24, r24
 3b6:   19 f0           breq    .+6         ; 0x3be <DS18X20_temp_cmp+0xa>
 3b8:   70 95           com r23
 3ba:   61 95           neg r22
 3bc:   7f 4f           sbci    r23, 0xFF   ; 255
    int16_t t2 = (subzero2) ? (cel2*(-1)) : (cel2);
 3be:   44 23           and r20, r20
 3c0:   19 f0           breq    .+6         ; 0x3c8 <DS18X20_temp_cmp+0x14>
 3c2:   30 95           com r19
 3c4:   21 95           neg r18
 3c6:   3f 4f           sbci    r19, 0xFF   ; 255
    
    if (t1<t2) return -1;
 3c8:   62 17           cp  r22, r18
 3ca:   73 07           cpc r23, r19
 3cc:   1c f4           brge    .+6         ; 0x3d4 <DS18X20_temp_cmp+0x20>
 3ce:   8f ef           ldi r24, 0xFF   ; 255
 3d0:   9f ef           ldi r25, 0xFF   ; 255
 3d2:   08 95           ret
 3d4:   80 e0           ldi r24, 0x00   ; 0
 3d6:   90 e0           ldi r25, 0x00   ; 0
 3d8:   26 17           cp  r18, r22
 3da:   37 07           cpc r19, r23
 3dc:   14 f4           brge    .+4         ; 0x3e2 <DS18X20_temp_cmp+0x2e>
 3de:   81 e0           ldi r24, 0x01   ; 1
 3e0:   90 e0           ldi r25, 0x00   ; 0
    if (t1>t2) return 1;
    return 0;
}
 3e2:   08 95           ret

000003e4 <DS18X20_read_meas_single>:

/* find DS18X20 Sensors on 1-Wire-Bus
   input/ouput: diff is the result of the last rom-search
   output: id is the rom-code of the sensor found */
void DS18X20_find_sensor(uint8_t *diff, uint8_t id[])
{
    for (;;) {
        *diff = ow_rom_search( *diff, &id[0] );
        if ( *diff==OW_PRESENCE_ERR || *diff==OW_DATA_ERR ||
          *diff == OW_LAST_DEVICE ) return;
        if ( id[0] == DS18B20_ID || id[0] == DS18S20_ID ) return;
    }
}

/* get power status of DS18x20 
   input  : id = rom_code 
   returns: DS18X20_POWER_EXTERN or DS18X20_POWER_PARASITE */
uint8_t DS18X20_get_power_status(uint8_t id[])
{
    uint8_t pstat;
    ow_reset();
    ow_command(DS18X20_READ_POWER_SUPPLY, id);
    pstat=ow_bit_io(1); // pstat 0=is parasite/ !=0 ext. powered
    ow_reset();
    return (pstat) ? DS18X20_POWER_EXTERN:DS18X20_POWER_PARASITE;
}

/* start measurement (CONVERT_T) for all sensors if input id==NULL 
   or for single sensor. then id is the rom-code */
uint8_t DS18X20_start_meas( uint8_t with_power_extern, uint8_t id[])
{
    ow_reset(); //**
    if( ow_input_pin_state() ) { // only send if bus is "idle" = high
        ow_command( DS18X20_CONVERT_T, id );
        if (with_power_extern != DS18X20_POWER_EXTERN)
            ow_parasite_enable();
        return DS18X20_OK;
    } 
    else { 
        #ifdef DS18X20_VERBOSE
        uart_puts_P( "DS18X20_start_meas: Short Circuit !\r" );
        #endif
        return DS18X20_START_FAIL;
    }
}

/* reads temperature (scratchpad) of sensor with rom-code id
   output: subzero==1 if temp.<0, cel: full celsius, mcel: frac 
   in millicelsius*0.1
   i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C */
uint8_t DS18X20_read_meas(uint8_t id[], uint8_t *subzero, 
    uint8_t *cel, uint8_t *cel_frac_bits)
{
    uint8_t i;
    uint8_t sp[DS18X20_SP_SIZE];
    
    ow_reset(); //**
    ow_command(DS18X20_READ, id);
    for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) sp[i]=ow_byte_rd();
    if ( crc8( &sp[0], DS18X20_SP_SIZE ) ) 
        return DS18X20_ERROR_CRC;
    DS18X20_meas_to_cel(id[0], sp, subzero, cel, cel_frac_bits);
    return DS18X20_OK;
}

/* reads temperature (scratchpad) of a single sensor (uses skip-rom)
   output: subzero==1 if temp.<0, cel: full celsius, mcel: frac 
   in millicelsius*0.1
   i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C */
uint8_t DS18X20_read_meas_single(uint8_t familycode, uint8_t *subzero, 
    uint8_t *cel, uint8_t *cel_frac_bits)
{
 3e4:   7f 92           push    r7
 3e6:   8f 92           push    r8
 3e8:   9f 92           push    r9
 3ea:   af 92           push    r10
 3ec:   bf 92           push    r11
 3ee:   cf 92           push    r12
 3f0:   df 92           push    r13
 3f2:   ef 92           push    r14
 3f4:   ff 92           push    r15
 3f6:   0f 93           push    r16
 3f8:   1f 93           push    r17
 3fa:   cf 93           push    r28
 3fc:   df 93           push    r29
 3fe:   cd b7           in  r28, 0x3d   ; 61
 400:   de b7           in  r29, 0x3e   ; 62
 402:   29 97           sbiw    r28, 0x09   ; 9
 404:   0f b6           in  r0, 0x3f    ; 63
 406:   f8 94           cli
 408:   de bf           out 0x3e, r29   ; 62
 40a:   0f be           out 0x3f, r0    ; 63
 40c:   cd bf           out 0x3d, r28   ; 61
 40e:   78 2e           mov r7, r24
 410:   4b 01           movw    r8, r22
 412:   5a 01           movw    r10, r20
 414:   69 01           movw    r12, r18
    uint8_t i;
    uint8_t sp[DS18X20_SP_SIZE];
    
    ow_command(DS18X20_READ, NULL);
 416:   60 e0           ldi r22, 0x00   ; 0
 418:   70 e0           ldi r23, 0x00   ; 0
 41a:   8e eb           ldi r24, 0xBE   ; 190
 41c:   0e 94 a9 03     call    0x752 <ow_command>
 420:   8e 01           movw    r16, r28
 422:   0f 5f           subi    r16, 0xFF   ; 255
 424:   1f 4f           sbci    r17, 0xFF   ; 255
    for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) sp[i]=ow_byte_rd();
 426:   0e 94 80 03     call    0x700 <ow_byte_rd>
 42a:   f8 01           movw    r30, r16
 42c:   81 93           st  Z+, r24
 42e:   8f 01           movw    r16, r30
 430:   ce 01           movw    r24, r28
 432:   0a 96           adiw    r24, 0x0a   ; 10
 434:   e8 17           cp  r30, r24
 436:   f9 07           cpc r31, r25
 438:   b1 f7           brne    .-20        ; 0x426 <DS18X20_read_meas_single+0x42>
    if ( crc8( &sp[0], DS18X20_SP_SIZE ) ) 
 43a:   69 e0           ldi r22, 0x09   ; 9
 43c:   70 e0           ldi r23, 0x00   ; 0
 43e:   7e 01           movw    r14, r28
 440:   08 94           sec
 442:   e1 1c           adc r14, r1
 444:   f1 1c           adc r15, r1
 446:   c7 01           movw    r24, r14
 448:   0e 94 24 04     call    0x848 <crc8>
 44c:   88 23           and r24, r24
 44e:   19 f0           breq    .+6         ; 0x456 <DS18X20_read_meas_single+0x72>
 450:   83 e0           ldi r24, 0x03   ; 3
 452:   90 e0           ldi r25, 0x00   ; 0
 454:   09 c0           rjmp    .+18        ; 0x468 <DS18X20_read_meas_single+0x84>
        return DS18X20_ERROR_CRC;
    DS18X20_meas_to_cel(familycode, sp, subzero, cel, cel_frac_bits);
 456:   86 01           movw    r16, r12
 458:   95 01           movw    r18, r10
 45a:   a4 01           movw    r20, r8
 45c:   b7 01           movw    r22, r14
 45e:   87 2d           mov r24, r7
 460:   0e 94 3e 01     call    0x27c <DS18X20_meas_to_cel>
 464:   80 e0           ldi r24, 0x00   ; 0
 466:   90 e0           ldi r25, 0x00   ; 0
 468:   29 96           adiw    r28, 0x09   ; 9
 46a:   0f b6           in  r0, 0x3f    ; 63
 46c:   f8 94           cli
 46e:   de bf           out 0x3e, r29   ; 62
 470:   0f be           out 0x3f, r0    ; 63
 472:   cd bf           out 0x3d, r28   ; 61
 474:   df 91           pop r29
 476:   cf 91           pop r28
 478:   1f 91           pop r17
 47a:   0f 91           pop r16
 47c:   ff 90           pop r15
 47e:   ef 90           pop r14
 480:   df 90           pop r13
 482:   cf 90           pop r12
 484:   bf 90           pop r11
 486:   af 90           pop r10
 488:   9f 90           pop r9
 48a:   8f 90           pop r8
 48c:   7f 90           pop r7
 48e:   08 95           ret

00000490 <DS18X20_read_meas>:
 490:   6f 92           push    r6
 492:   7f 92           push    r7
 494:   8f 92           push    r8
 496:   9f 92           push    r9
 498:   af 92           push    r10
 49a:   bf 92           push    r11
 49c:   cf 92           push    r12
 49e:   df 92           push    r13
 4a0:   ef 92           push    r14
 4a2:   ff 92           push    r15
 4a4:   0f 93           push    r16
 4a6:   1f 93           push    r17
 4a8:   cf 93           push    r28
 4aa:   df 93           push    r29
 4ac:   cd b7           in  r28, 0x3d   ; 61
 4ae:   de b7           in  r29, 0x3e   ; 62
 4b0:   29 97           sbiw    r28, 0x09   ; 9
 4b2:   0f b6           in  r0, 0x3f    ; 63
 4b4:   f8 94           cli
 4b6:   de bf           out 0x3e, r29   ; 62
 4b8:   0f be           out 0x3f, r0    ; 63
 4ba:   cd bf           out 0x3d, r28   ; 61
 4bc:   6c 01           movw    r12, r24
 4be:   3b 01           movw    r6, r22
 4c0:   4a 01           movw    r8, r20
 4c2:   59 01           movw    r10, r18
 4c4:   0e 94 85 03     call    0x70a <ow_reset>
 4c8:   b6 01           movw    r22, r12
 4ca:   8e eb           ldi r24, 0xBE   ; 190
 4cc:   0e 94 a9 03     call    0x752 <ow_command>
 4d0:   8e 01           movw    r16, r28
 4d2:   0f 5f           subi    r16, 0xFF   ; 255
 4d4:   1f 4f           sbci    r17, 0xFF   ; 255
 4d6:   0e 94 80 03     call    0x700 <ow_byte_rd>
 4da:   f8 01           movw    r30, r16
 4dc:   81 93           st  Z+, r24
 4de:   8f 01           movw    r16, r30
 4e0:   ce 01           movw    r24, r28
 4e2:   0a 96           adiw    r24, 0x0a   ; 10
 4e4:   e8 17           cp  r30, r24
 4e6:   f9 07           cpc r31, r25
 4e8:   b1 f7           brne    .-20        ; 0x4d6 <DS18X20_read_meas+0x46>
 4ea:   69 e0           ldi r22, 0x09   ; 9
 4ec:   70 e0           ldi r23, 0x00   ; 0
 4ee:   7e 01           movw    r14, r28
 4f0:   08 94           sec
 4f2:   e1 1c           adc r14, r1
 4f4:   f1 1c           adc r15, r1
 4f6:   c7 01           movw    r24, r14
 4f8:   0e 94 24 04     call    0x848 <crc8>
 4fc:   88 23           and r24, r24
 4fe:   19 f0           breq    .+6         ; 0x506 <__stack+0x7>
 500:   83 e0           ldi r24, 0x03   ; 3
 502:   90 e0           ldi r25, 0x00   ; 0
 504:   0a c0           rjmp    .+20        ; 0x51a <__stack+0x1b>
 506:   85 01           movw    r16, r10
 508:   94 01           movw    r18, r8
 50a:   a3 01           movw    r20, r6
 50c:   b7 01           movw    r22, r14
 50e:   f6 01           movw    r30, r12
 510:   80 81           ld  r24, Z
 512:   0e 94 3e 01     call    0x27c <DS18X20_meas_to_cel>
 516:   80 e0           ldi r24, 0x00   ; 0
 518:   90 e0           ldi r25, 0x00   ; 0
 51a:   29 96           adiw    r28, 0x09   ; 9
 51c:   0f b6           in  r0, 0x3f    ; 63
 51e:   f8 94           cli
 520:   de bf           out 0x3e, r29   ; 62
 522:   0f be           out 0x3f, r0    ; 63
 524:   cd bf           out 0x3d, r28   ; 61
 526:   df 91           pop r29
 528:   cf 91           pop r28
 52a:   1f 91           pop r17
 52c:   0f 91           pop r16
 52e:   ff 90           pop r15
 530:   ef 90           pop r14
 532:   df 90           pop r13
 534:   cf 90           pop r12
 536:   bf 90           pop r11
 538:   af 90           pop r10
 53a:   9f 90           pop r9
 53c:   8f 90           pop r8
 53e:   7f 90           pop r7
 540:   6f 90           pop r6
 542:   08 95           ret

00000544 <DS18X20_start_meas>:
 544:   1f 93           push    r17
 546:   cf 93           push    r28
 548:   df 93           push    r29
 54a:   18 2f           mov r17, r24
 54c:   eb 01           movw    r28, r22
 54e:   0e 94 85 03     call    0x70a <ow_reset>
 552:   0e 94 41 03     call    0x682 <ow_input_pin_state>
 556:   88 23           and r24, r24
 558:   19 f4           brne    .+6         ; 0x560 <DS18X20_start_meas+0x1c>
 55a:   82 e0           ldi r24, 0x02   ; 2
 55c:   90 e0           ldi r25, 0x00   ; 0
 55e:   0a c0           rjmp    .+20        ; 0x574 <DS18X20_start_meas+0x30>
 560:   be 01           movw    r22, r28
 562:   84 e4           ldi r24, 0x44   ; 68
 564:   0e 94 a9 03     call    0x752 <ow_command>
 568:   11 30           cpi r17, 0x01   ; 1
 56a:   11 f0           breq    .+4         ; 0x570 <DS18X20_start_meas+0x2c>
 56c:   0e 94 46 03     call    0x68c <ow_parasite_enable>
 570:   80 e0           ldi r24, 0x00   ; 0
 572:   90 e0           ldi r25, 0x00   ; 0
 574:   df 91           pop r29
 576:   cf 91           pop r28
 578:   1f 91           pop r17
 57a:   08 95           ret

0000057c <DS18X20_get_power_status>:
 57c:   0f 93           push    r16
 57e:   1f 93           push    r17
 580:   8c 01           movw    r16, r24
 582:   0e 94 85 03     call    0x70a <ow_reset>
 586:   b8 01           movw    r22, r16
 588:   84 eb           ldi r24, 0xB4   ; 180
 58a:   0e 94 a9 03     call    0x752 <ow_command>
 58e:   81 e0           ldi r24, 0x01   ; 1
 590:   0e 94 4c 03     call    0x698 <ow_bit_io>
 594:   18 2f           mov r17, r24
 596:   0e 94 85 03     call    0x70a <ow_reset>
 59a:   80 e0           ldi r24, 0x00   ; 0
 59c:   90 e0           ldi r25, 0x00   ; 0
 59e:   11 23           and r17, r17
 5a0:   11 f0           breq    .+4         ; 0x5a6 <DS18X20_get_power_status+0x2a>
 5a2:   81 e0           ldi r24, 0x01   ; 1
 5a4:   90 e0           ldi r25, 0x00   ; 0
 5a6:   1f 91           pop r17
 5a8:   0f 91           pop r16
 5aa:   08 95           ret

000005ac <DS18X20_find_sensor>:
 5ac:   0f 93           push    r16
 5ae:   1f 93           push    r17
 5b0:   cf 93           push    r28
 5b2:   df 93           push    r29
 5b4:   8c 01           movw    r16, r24
 5b6:   eb 01           movw    r28, r22
 5b8:   be 01           movw    r22, r28
 5ba:   f8 01           movw    r30, r16
 5bc:   80 81           ld  r24, Z
 5be:   0e 94 c8 03     call    0x790 <ow_rom_search>
 5c2:   f8 01           movw    r30, r16
 5c4:   80 83           st  Z, r24
 5c6:   81 50           subi    r24, 0x01   ; 1
 5c8:   8d 3f           cpi r24, 0xFD   ; 253
 5ca:   28 f4           brcc    .+10        ; 0x5d6 <DS18X20_find_sensor+0x2a>
 5cc:   88 81           ld  r24, Y
 5ce:   88 32           cpi r24, 0x28   ; 40
 5d0:   11 f0           breq    .+4         ; 0x5d6 <DS18X20_find_sensor+0x2a>
 5d2:   80 31           cpi r24, 0x10   ; 16
 5d4:   89 f7           brne    .-30        ; 0x5b8 <DS18X20_find_sensor+0xc>
 5d6:   df 91           pop r29
 5d8:   cf 91           pop r28
 5da:   1f 91           pop r17
 5dc:   0f 91           pop r16
 5de:   08 95           ret

000005e0 <search_sensors>:
 5e0:   af 92           push    r10
 5e2:   bf 92           push    r11
 5e4:   cf 92           push    r12
 5e6:   df 92           push    r13
 5e8:   ff 92           push    r15
 5ea:   0f 93           push    r16
 5ec:   1f 93           push    r17
 5ee:   cf 93           push    r28
 5f0:   df 93           push    r29
 5f2:   cd b7           in  r28, 0x3d   ; 61
 5f4:   de b7           in  r29, 0x3e   ; 62
 5f6:   29 97           sbiw    r28, 0x09   ; 9
 5f8:   0f b6           in  r0, 0x3f    ; 63
 5fa:   f8 94           cli
 5fc:   de bf           out 0x3e, r29   ; 62
 5fe:   0f be           out 0x3f, r0    ; 63
 600:   cd bf           out 0x3d, r28   ; 61
 602:   8f ef           ldi r24, 0xFF   ; 255
 604:   89 83           std Y+1, r24    ; 0x01
 606:   00 e0           ldi r16, 0x00   ; 0
 608:   10 e0           ldi r17, 0x00   ; 0
 60a:   cc 24           eor r12, r12
 60c:   dd 24           eor r13, r13
 60e:   f0 2e           mov r15, r16
 610:   e2 e0           ldi r30, 0x02   ; 2
 612:   ae 2e           mov r10, r30
 614:   b1 2c           mov r11, r1
 616:   ac 0e           add r10, r28
 618:   bd 1e           adc r11, r29
 61a:   b5 01           movw    r22, r10
 61c:   ce 01           movw    r24, r28
 61e:   01 96           adiw    r24, 0x01   ; 1
 620:   0e 94 d6 02     call    0x5ac <DS18X20_find_sensor>
 624:   99 81           ldd r25, Y+1    ; 0x01
 626:   9f 3f           cpi r25, 0xFF   ; 255
 628:   d1 f0           breq    .+52        ; 0x65e <search_sensors+0x7e>
 62a:   9e 3f           cpi r25, 0xFE   ; 254
 62c:   c1 f0           breq    .+48        ; 0x65e <search_sensors+0x7e>
 62e:   d6 01           movw    r26, r12
 630:   a3 5d           subi    r26, 0xD3   ; 211
 632:   be 4f           sbci    r27, 0xFE   ; 254
 634:   f5 01           movw    r30, r10
 636:   9e 01           movw    r18, r28
 638:   26 5f           subi    r18, 0xF6   ; 246
 63a:   3f 4f           sbci    r19, 0xFF   ; 255
 63c:   81 91           ld  r24, Z+
 63e:   8d 93           st  X+, r24
 640:   e2 17           cp  r30, r18
 642:   f3 07           cpc r31, r19
 644:   d9 f7           brne    .-10        ; 0x63c <search_sensors+0x5c>
 646:   f3 94           inc r15
 648:   99 23           and r25, r25
 64a:   49 f0           breq    .+18        ; 0x65e <search_sensors+0x7e>
 64c:   0f 5f           subi    r16, 0xFF   ; 255
 64e:   1f 4f           sbci    r17, 0xFF   ; 255
 650:   88 e0           ldi r24, 0x08   ; 8
 652:   90 e0           ldi r25, 0x00   ; 0
 654:   c8 0e           add r12, r24
 656:   d9 1e           adc r13, r25
 658:   04 30           cpi r16, 0x04   ; 4
 65a:   11 05           cpc r17, r1
 65c:   c1 f6           brne    .-80        ; 0x60e <search_sensors+0x2e>
 65e:   8f 2d           mov r24, r15
 660:   99 27           eor r25, r25
 662:   29 96           adiw    r28, 0x09   ; 9
 664:   0f b6           in  r0, 0x3f    ; 63
 666:   f8 94           cli
 668:   de bf           out 0x3e, r29   ; 62
 66a:   0f be           out 0x3f, r0    ; 63
 66c:   cd bf           out 0x3d, r28   ; 61
 66e:   df 91           pop r29
 670:   cf 91           pop r28
 672:   1f 91           pop r17
 674:   0f 91           pop r16
 676:   ff 90           pop r15
 678:   df 90           pop r13
 67a:   cf 90           pop r12
 67c:   bf 90           pop r11
 67e:   af 90           pop r10
 680:   08 95           ret

00000682 <ow_input_pin_state>:
#endif

uint8_t ow_input_pin_state()
{
    return OW_GET_IN();
 682:   89 b1           in  r24, 0x09   ; 9
 684:   99 27           eor r25, r25
}
 686:   80 74           andi    r24, 0x40   ; 64
 688:   90 70           andi    r25, 0x00   ; 0
 68a:   08 95           ret

0000068c <ow_parasite_enable>:

void ow_parasite_enable(void)
{
    OW_OUT_HIGH();
 68c:   5e 9a           sbi 0x0b, 6 ; 11
    OW_DIR_OUT();
 68e:   56 9a           sbi 0x0a, 6 ; 10
 690:   08 95           ret

00000692 <ow_parasite_disable>:
}

void ow_parasite_disable(void)
{
    OW_OUT_LOW();
 692:   5e 98           cbi 0x0b, 6 ; 11
    OW_DIR_IN();
 694:   56 98           cbi 0x0a, 6 ; 10
 696:   08 95           ret

00000698 <ow_bit_io>:
}

uint8_t ow_reset(void)
{
    uint8_t err;
    uint8_t sreg;
    
    OW_OUT_LOW(); // disable internal pull-up (maybe on from parasite)
    OW_DIR_OUT(); // pull OW-Pin low for 480us
    
    delay_us(480);
    
    sreg=SREG;
    cli();
    
    // set Pin as input - wait for clients to pull low
    OW_DIR_IN(); // input
    
    delay_us(66);
    err = OW_GET_IN();      // no presence detect
    // nobody pulled to low, still high
    
    SREG=sreg; // sei()
    
    // after a delay the clients should release the line
    // and input-pin gets back to high due to pull-up-resistor
    delay_us(480-66);
    if( OW_GET_IN() == 0 )      // short circuit
        err = 1;
    
    return err;
}

/* Timing issue when using runtime-bus-selection (!OW_ONE_BUS):
   The master should sample at the end of the 15-slot after initiating
   the read-time-slot. The variable bus-settings need more
   cycles than the constant ones so the delays had to be shortened 
   to achive a 15uS overall delay 
   Setting/clearing a bit in I/O Register needs 1 cyle in OW_ONE_BUS
   but around 14 cyles in configureable bus (us-Delay is 4 cyles per uS) */
uint8_t ow_bit_io( uint8_t b )
{
 698:   28 2f           mov r18, r24
    uint8_t sreg;
    
    sreg=SREG;
 69a:   3f b7           in  r19, 0x3f   ; 63
    cli();
 69c:   f8 94           cli
    
    OW_DIR_OUT(); // drive bus low
 69e:   56 9a           sbi 0x0a, 6 ; 10
   4 cpu cycles per loop + 1 cycles(?) overhead 
   when a constant is passed. */
static inline void delayloop16(uint16_t count)
{
    asm volatile (  "cp  %A0,__zero_reg__ \n\t"  \
 6a0:   81 e0           ldi r24, 0x01   ; 1
 6a2:   90 e0           ldi r25, 0x00   ; 0
 6a4:   81 15           cp  r24, r1
 6a6:   91 05           cpc r25, r1
 6a8:   11 f0           breq    .+4         ; 0x6ae <L_Exit_39>

000006aa <L_LOOP_39>:
 6aa:   01 97           sbiw    r24, 0x01   ; 1
 6ac:   f1 f7           brne    .-4         ; 0x6aa <L_LOOP_39>

000006ae <L_Exit_39>:
    
    delay_us(1); // Recovery-Time wuffwuff was 1
    if ( b ) OW_DIR_IN(); // if bit is 1 set bus high (by ext. pull-up)
 6ae:   21 11           cpse    r18, r1
 6b0:   56 98           cbi 0x0a, 6 ; 10
   4 cpu cycles per loop + 1 cycles(?) overhead 
   when a constant is passed. */
static inline void delayloop16(uint16_t count)
{
    asm volatile (  "cp  %A0,__zero_reg__ \n\t"  \
 6b2:   8b e1           ldi r24, 0x1B   ; 27
 6b4:   90 e0           ldi r25, 0x00   ; 0
 6b6:   81 15           cp  r24, r1
 6b8:   91 05           cpc r25, r1
 6ba:   11 f0           breq    .+4         ; 0x6c0 <L_Exit_52>

000006bc <L_LOOP_52>:
 6bc:   01 97           sbiw    r24, 0x01   ; 1
 6be:   f1 f7           brne    .-4         ; 0x6bc <L_LOOP_52>

000006c0 <L_Exit_52>:
        
    // wuffwuff delay was 15uS-1 see comment above
    delay_us(15-1-OW_CONF_DELAYOFFSET);
        
    if( OW_GET_IN() == 0 ) b = 0;  // sample at end of read-timeslot
 6c0:   4e 9b           sbis    0x09, 6 ; 9
 6c2:   20 e0           ldi r18, 0x00   ; 0
   4 cpu cycles per loop + 1 cycles(?) overhead 
   when a constant is passed. */
static inline void delayloop16(uint16_t count)
{
    asm volatile (  "cp  %A0,__zero_reg__ \n\t"  \
 6c4:   89 e5           ldi r24, 0x59   ; 89
 6c6:   90 e0           ldi r25, 0x00   ; 0
 6c8:   81 15           cp  r24, r1
 6ca:   91 05           cpc r25, r1
 6cc:   11 f0           breq    .+4         ; 0x6d2 <L_Exit_65>

000006ce <L_LOOP_65>:
 6ce:   01 97           sbiw    r24, 0x01   ; 1
 6d0:   f1 f7           brne    .-4         ; 0x6ce <L_LOOP_65>

000006d2 <L_Exit_65>:
    
    delay_us(60-15);
    OW_DIR_IN();
 6d2:   56 98           cbi 0x0a, 6 ; 10
    
    SREG=sreg; // sei();
 6d4:   3f bf           out 0x3f, r19   ; 63
    
    return b;
}
 6d6:   82 2f           mov r24, r18
 6d8:   99 27           eor r25, r25
 6da:   08 95           ret

000006dc <ow_byte_wr>:


uint8_t ow_byte_wr( uint8_t b )
{
 6dc:   0f 93           push    r16
 6de:   1f 93           push    r17
 6e0:   18 2f           mov r17, r24
 6e2:   08 e0           ldi r16, 0x08   ; 8
    uint8_t i = 8, j;
    
    do {
        j = ow_bit_io( b & 1 );
 6e4:   81 2f           mov r24, r17
 6e6:   81 70           andi    r24, 0x01   ; 1
 6e8:   0e 94 4c 03     call    0x698 <ow_bit_io>
        b >>= 1;
 6ec:   16 95           lsr r17
        if( j ) b |= 0x80;
 6ee:   81 11           cpse    r24, r1
 6f0:   10 68           ori r17, 0x80   ; 128
    } while( --i );
 6f2:   01 50           subi    r16, 0x01   ; 1
 6f4:   b9 f7           brne    .-18        ; 0x6e4 <ow_byte_wr+0x8>
    
    return b;
}
 6f6:   81 2f           mov r24, r17
 6f8:   99 27           eor r25, r25
 6fa:   1f 91           pop r17
 6fc:   0f 91           pop r16
 6fe:   08 95           ret

00000700 <ow_byte_rd>:


uint8_t ow_byte_rd( void )
{
  // read by sending 0xff (a dontcare?)
  return ow_byte_wr( 0xFF ); 
 700:   8f ef           ldi r24, 0xFF   ; 255
 702:   0e 94 6e 03     call    0x6dc <ow_byte_wr>
}
 706:   99 27           eor r25, r25
 708:   08 95           ret

0000070a <ow_reset>:
 70a:   5e 98           cbi 0x0b, 6 ; 11
 70c:   56 9a           sbi 0x0a, 6 ; 10
   4 cpu cycles per loop + 1 cycles(?) overhead 
   when a constant is passed. */
static inline void delayloop16(uint16_t count)
{
    asm volatile (  "cp  %A0,__zero_reg__ \n\t"  \
 70e:   8f eb           ldi r24, 0xBF   ; 191
 710:   93 e0           ldi r25, 0x03   ; 3
 712:   81 15           cp  r24, r1
 714:   91 05           cpc r25, r1
 716:   11 f0           breq    .+4         ; 0x71c <L_Exit_124>

00000718 <L_LOOP_124>:
 718:   01 97           sbiw    r24, 0x01   ; 1
 71a:   f1 f7           brne    .-4         ; 0x718 <L_LOOP_124>

0000071c <L_Exit_124>:
 71c:   2f b7           in  r18, 0x3f   ; 63
 71e:   f8 94           cli
 720:   56 98           cbi 0x0a, 6 ; 10
   4 cpu cycles per loop + 1 cycles(?) overhead 
   when a constant is passed. */
static inline void delayloop16(uint16_t count)
{
    asm volatile (  "cp  %A0,__zero_reg__ \n\t"  \
 722:   83 e8           ldi r24, 0x83   ; 131
 724:   90 e0           ldi r25, 0x00   ; 0
 726:   81 15           cp  r24, r1
 728:   91 05           cpc r25, r1
 72a:   11 f0           breq    .+4         ; 0x730 <L_Exit_137>

0000072c <L_LOOP_137>:
 72c:   01 97           sbiw    r24, 0x01   ; 1
 72e:   f1 f7           brne    .-4         ; 0x72c <L_LOOP_137>

00000730 <L_Exit_137>:
 730:   39 b1           in  r19, 0x09   ; 9
 732:   2f bf           out 0x3f, r18   ; 63
   4 cpu cycles per loop + 1 cycles(?) overhead 
   when a constant is passed. */
static inline void delayloop16(uint16_t count)
{
    asm volatile (  "cp  %A0,__zero_reg__ \n\t"  \
 734:   8b e3           ldi r24, 0x3B   ; 59
 736:   93 e0           ldi r25, 0x03   ; 3
 738:   81 15           cp  r24, r1
 73a:   91 05           cpc r25, r1
 73c:   11 f0           breq    .+4         ; 0x742 <L_Exit_148>

0000073e <L_LOOP_148>:
 73e:   01 97           sbiw    r24, 0x01   ; 1
 740:   f1 f7           brne    .-4         ; 0x73e <L_LOOP_148>

00000742 <L_Exit_148>:
 742:   4e 99           sbic    0x09, 6 ; 9
 744:   02 c0           rjmp    .+4         ; 0x74a <L_Exit_148+0x8>
 746:   81 e0           ldi r24, 0x01   ; 1
 748:   02 c0           rjmp    .+4         ; 0x74e <L_Exit_148+0xc>
 74a:   83 2f           mov r24, r19
 74c:   80 74           andi    r24, 0x40   ; 64
 74e:   99 27           eor r25, r25
 750:   08 95           ret

00000752 <ow_command>:


uint8_t ow_rom_search( uint8_t diff, uint8_t *id )
{
    uint8_t i, j, next_diff;
    uint8_t b;
    
    if( ow_reset() ) return OW_PRESENCE_ERR;    // error, no device found
    
    ow_byte_wr( OW_SEARCH_ROM );            // ROM search command
    next_diff = OW_LAST_DEVICE;         // unchanged on last device
    
    i = OW_ROMCODE_SIZE * 8;                    // 8 bytes
    
    do {
        j = 8;                  // 8 bits
        do {
            b = ow_bit_io( 1 );         // read bit
            if( ow_bit_io( 1 ) ) {          // read complement bit
                if( b )                 // 11
                return OW_DATA_ERR;         // data error
            }
            else {
                if( !b ) {              // 00 = 2 devices
                    if( diff > i || ((*id & 1) && diff != i) ) {
                    b = 1;              // now 1
                    next_diff = i;          // next pass 0
                    }
                }
            }
            ow_bit_io( b );                 // write bit
            *id >>= 1;
            if( b ) *id |= 0x80;            // store bit
            
            i--;
            
        } while( --j );
        
        id++;                   // next byte
    
    } while( i );
    
    return next_diff;               // to continue search
}


void ow_command( uint8_t command, uint8_t *id )
{
 752:   0f 93           push    r16
 754:   1f 93           push    r17
 756:   cf 93           push    r28
 758:   df 93           push    r29
 75a:   08 2f           mov r16, r24
 75c:   eb 01           movw    r28, r22
    uint8_t i;

    ow_reset();
 75e:   0e 94 85 03     call    0x70a <ow_reset>

    if( id ) {
 762:   20 97           sbiw    r28, 0x00   ; 0
 764:   51 f0           breq    .+20        ; 0x77a <ow_command+0x28>
        ow_byte_wr( OW_MATCH_ROM );         // to a single device
 766:   85 e5           ldi r24, 0x55   ; 85
 768:   0e 94 6e 03     call    0x6dc <ow_byte_wr>
 76c:   18 e0           ldi r17, 0x08   ; 8
        i = OW_ROMCODE_SIZE;
        do {
            ow_byte_wr( *id );
 76e:   89 91           ld  r24, Y+
 770:   0e 94 6e 03     call    0x6dc <ow_byte_wr>
            id++;
        } while( --i );
 774:   11 50           subi    r17, 0x01   ; 1
 776:   21 f0           breq    .+8         ; 0x780 <ow_command+0x2e>
 778:   fa cf           rjmp    .-12        ; 0x76e <ow_command+0x1c>
    } 
    else {
        ow_byte_wr( OW_SKIP_ROM );          // to all devices
 77a:   8c ec           ldi r24, 0xCC   ; 204
 77c:   0e 94 6e 03     call    0x6dc <ow_byte_wr>
    }
    
    ow_byte_wr( command );
 780:   80 2f           mov r24, r16
 782:   0e 94 6e 03     call    0x6dc <ow_byte_wr>
 786:   df 91           pop r29
 788:   cf 91           pop r28
 78a:   1f 91           pop r17
 78c:   0f 91           pop r16
 78e:   08 95           ret

00000790 <ow_rom_search>:
 790:   df 92           push    r13
 792:   ef 92           push    r14
 794:   ff 92           push    r15
 796:   0f 93           push    r16
 798:   1f 93           push    r17
 79a:   cf 93           push    r28
 79c:   df 93           push    r29
 79e:   e8 2e           mov r14, r24
 7a0:   eb 01           movw    r28, r22
 7a2:   0e 94 85 03     call    0x70a <ow_reset>
 7a6:   88 23           and r24, r24
 7a8:   19 f0           breq    .+6         ; 0x7b0 <ow_rom_search+0x20>
 7aa:   8f ef           ldi r24, 0xFF   ; 255
 7ac:   90 e0           ldi r25, 0x00   ; 0
 7ae:   37 c0           rjmp    .+110       ; 0x81e <ow_rom_search+0x8e>
 7b0:   80 ef           ldi r24, 0xF0   ; 240
 7b2:   0e 94 6e 03     call    0x6dc <ow_byte_wr>
 7b6:   00 e4           ldi r16, 0x40   ; 64
 7b8:   dd 24           eor r13, r13
 7ba:   88 e0           ldi r24, 0x08   ; 8
 7bc:   f8 2e           mov r15, r24
 7be:   81 e0           ldi r24, 0x01   ; 1
 7c0:   0e 94 4c 03     call    0x698 <ow_bit_io>
 7c4:   18 2f           mov r17, r24
 7c6:   81 e0           ldi r24, 0x01   ; 1
 7c8:   0e 94 4c 03     call    0x698 <ow_bit_io>
 7cc:   88 23           and r24, r24
 7ce:   29 f0           breq    .+10        ; 0x7da <ow_rom_search+0x4a>
 7d0:   11 23           and r17, r17
 7d2:   61 f0           breq    .+24        ; 0x7ec <ow_rom_search+0x5c>
 7d4:   8e ef           ldi r24, 0xFE   ; 254
 7d6:   90 e0           ldi r25, 0x00   ; 0
 7d8:   22 c0           rjmp    .+68        ; 0x81e <ow_rom_search+0x8e>
 7da:   11 23           and r17, r17
 7dc:   c9 f4           brne    .+50        ; 0x810 <ow_rom_search+0x80>
 7de:   0e 15           cp  r16, r14
 7e0:   a8 f0           brcs    .+42        ; 0x80c <ow_rom_search+0x7c>
 7e2:   88 81           ld  r24, Y
 7e4:   80 ff           sbrs    r24, 0
 7e6:   02 c0           rjmp    .+4         ; 0x7ec <ow_rom_search+0x5c>
 7e8:   e0 16           cp  r14, r16
 7ea:   81 f4           brne    .+32        ; 0x80c <ow_rom_search+0x7c>
 7ec:   80 e0           ldi r24, 0x00   ; 0
 7ee:   0e 94 4c 03     call    0x698 <ow_bit_io>
 7f2:   88 81           ld  r24, Y
 7f4:   86 95           lsr r24
 7f6:   88 83           st  Y, r24
 7f8:   01 50           subi    r16, 0x01   ; 1
 7fa:   fa 94           dec r15
 7fc:   01 f7           brne    .-64        ; 0x7be <ow_rom_search+0x2e>
 7fe:   00 23           and r16, r16
 800:   11 f0           breq    .+4         ; 0x806 <ow_rom_search+0x76>
 802:   21 96           adiw    r28, 0x01   ; 1
 804:   da cf           rjmp    .-76        ; 0x7ba <ow_rom_search+0x2a>
 806:   8d 2d           mov r24, r13
 808:   99 27           eor r25, r25
 80a:   09 c0           rjmp    .+18        ; 0x81e <ow_rom_search+0x8e>
 80c:   d0 2e           mov r13, r16
 80e:   11 e0           ldi r17, 0x01   ; 1
 810:   81 2f           mov r24, r17
 812:   0e 94 4c 03     call    0x698 <ow_bit_io>
 816:   88 81           ld  r24, Y
 818:   86 95           lsr r24
 81a:   80 68           ori r24, 0x80   ; 128
 81c:   ec cf           rjmp    .-40        ; 0x7f6 <ow_rom_search+0x66>
 81e:   df 91           pop r29
 820:   cf 91           pop r28
 822:   1f 91           pop r17
 824:   0f 91           pop r16
 826:   ff 90           pop r15
 828:   ef 90           pop r14
 82a:   df 90           pop r13
 82c:   08 95           ret

0000082e <delayloop32>:

#include "delay.h"

void delayloop32(uint32_t loops) 
{
 82e:   dc 01           movw    r26, r24
 830:   cb 01           movw    r24, r22
  __asm__ volatile ( "cp  %A0,__zero_reg__ \n\t"  \
 832:   81 15           cp  r24, r1
 834:   91 05           cpc r25, r1
 836:   a1 05           cpc r26, r1
 838:   b1 05           cpc r27, r1
 83a:   29 f0           breq    .+10        ; 0x846 <L_Exit_5>

0000083c <L_LOOP_5>:
 83c:   81 50           subi    r24, 0x01   ; 1
 83e:   90 40           sbci    r25, 0x00   ; 0
 840:   a0 40           sbci    r26, 0x00   ; 0
 842:   b0 40           sbci    r27, 0x00   ; 0
 844:   d9 f7           brne    .-10        ; 0x83c <L_LOOP_5>

00000846 <L_Exit_5>:
 846:   08 95           ret

00000848 <crc8>:
#define CRC8INIT    0x00
#define CRC8POLY    0x18              //0X18 = X^8+X^5+X^4+X^0

uint8_t crc8 ( uint8_t *data_in, uint16_t number_of_bytes_to_read )
{
 848:   20 e0           ldi r18, 0x00   ; 0
 84a:   40 e0           ldi r20, 0x00   ; 0
 84c:   50 e0           ldi r21, 0x00   ; 0
 84e:   fc 01           movw    r30, r24
 850:   13 c0           rjmp    .+38        ; 0x878 <crc8+0x30>
    uint8_t  crc;
    uint16_t loop_count;
    uint8_t  bit_counter;
    uint8_t  data;
    uint8_t  feedback_bit;
    
    crc = CRC8INIT;

    for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++)
    {
        data = data_in[loop_count];
 852:   90 81           ld  r25, Z
 854:   38 e0           ldi r19, 0x08   ; 8
 856:   a8 e1           ldi r26, 0x18   ; 24
        
        bit_counter = 8;
        do {
            feedback_bit = (crc ^ data) & 0x01;
    
            if ( feedback_bit == 0x01 ) {
 858:   82 2f           mov r24, r18
 85a:   89 27           eor r24, r25
 85c:   80 ff           sbrs    r24, 0
 85e:   04 c0           rjmp    .+8         ; 0x868 <crc8+0x20>
                crc = crc ^ CRC8POLY;
            }
            crc = (crc >> 1) & 0x7F;
 860:   2a 27           eor r18, r26
 862:   26 95           lsr r18
            if ( feedback_bit == 0x01 ) {
                crc = crc | 0x80;
 864:   20 68           ori r18, 0x80   ; 128
 866:   01 c0           rjmp    .+2         ; 0x86a <crc8+0x22>
 868:   26 95           lsr r18
            }
        
            data = data >> 1;
            bit_counter--;
 86a:   31 50           subi    r19, 0x01   ; 1
        
        } while (bit_counter > 0);
 86c:   11 f0           breq    .+4         ; 0x872 <crc8+0x2a>
 86e:   96 95           lsr r25
 870:   f3 cf           rjmp    .-26        ; 0x858 <crc8+0x10>
 872:   4f 5f           subi    r20, 0xFF   ; 255
 874:   5f 4f           sbci    r21, 0xFF   ; 255
 876:   31 96           adiw    r30, 0x01   ; 1
 878:   46 17           cp  r20, r22
 87a:   57 07           cpc r21, r23
 87c:   51 f7           brne    .-44        ; 0x852 <crc8+0xa>
    }
    
    return crc;
}
 87e:   82 2f           mov r24, r18
 880:   99 27           eor r25, r25
 882:   08 95           ret

00000884 <Can_Process>:
 * Callback for when a message is received from the lower
 * layer (BIOS or CAN driver).
 */
void Can_Process(Can_Message_t* msg)
{
 884:   cf 93           push    r28
 886:   df 93           push    r29
 888:   ec 01           movw    r28, r24
    unsigned char n;
    /* Check if there is room on the queue. */
    if (RxQ_Len < STDCAN_RX_QUEUE_SIZE) {
 88a:   60 91 67 01     lds r22, 0x0167
 88e:   68 30           cpi r22, 0x08   ; 8
 890:   b8 f5           brcc    .+110       ; 0x900 <Can_Process+0x7c>
        
#if (STDCAN_FILTER)
        /* Try to match each filter in turn. */
        for (n = 0; n < STDCAN_NUM_FILTERS; n++) {
            if (RxFilters[n].Active && !((msg->Id ^ RxFilters[n].Id) & RxFilters[n].Mask)) {
                RxQ[RxQ_Wr_idx].Match = n;
                break;
            }
        }
        
        if (n == STDCAN_NUM_FILTERS) return; // No match found, discard message.
#endif
        /* Copy the message from lower layer into the queue. */
        RxQ[RxQ_Wr_idx].Id     = msg->Id;
 892:   70 91 d0 01     lds r23, 0x01D0
 896:   27 2f           mov r18, r23
 898:   33 27           eor r19, r19
 89a:   8d e0           ldi r24, 0x0D   ; 13
 89c:   90 e0           ldi r25, 0x00   ; 0
 89e:   28 9f           mul r18, r24
 8a0:   f0 01           movw    r30, r0
 8a2:   29 9f           mul r18, r25
 8a4:   f0 0d           add r31, r0
 8a6:   38 9f           mul r19, r24
 8a8:   f0 0d           add r31, r0
 8aa:   11 24           eor r1, r1
 8ac:   e8 59           subi    r30, 0x98   ; 152
 8ae:   fe 4f           sbci    r31, 0xFE   ; 254
 8b0:   88 81           ld  r24, Y
 8b2:   99 81           ldd r25, Y+1    ; 0x01
 8b4:   aa 81           ldd r26, Y+2    ; 0x02
 8b6:   bb 81           ldd r27, Y+3    ; 0x03
 8b8:   80 83           st  Z, r24
 8ba:   91 83           std Z+1, r25    ; 0x01
 8bc:   a2 83           std Z+2, r26    ; 0x02
 8be:   b3 83           std Z+3, r27    ; 0x03
        RxQ[RxQ_Wr_idx].Length = msg->DataLength;
 8c0:   8c 81           ldd r24, Y+4    ; 0x04
 8c2:   84 83           std Z+4, r24    ; 0x04
 8c4:   20 e0           ldi r18, 0x00   ; 0
 8c6:   30 e0           ldi r19, 0x00   ; 0
 8c8:   af 01           movw    r20, r30
 8ca:   98 2f           mov r25, r24
 8cc:   09 c0           rjmp    .+18        ; 0x8e0 <Can_Process+0x5c>
        //TODO: This should be guarded against invalid DataLength.
        for (n = 0; n < RxQ[RxQ_Wr_idx].Length; n++) {
            RxQ[RxQ_Wr_idx].Data[n] = msg->Data.bytes[n];
 8ce:   ff 27           eor r31, r31
 8d0:   da 01           movw    r26, r20
 8d2:   ae 0f           add r26, r30
 8d4:   bf 1f           adc r27, r31
 8d6:   ec 0f           add r30, r28
 8d8:   fd 1f           adc r31, r29
 8da:   87 81           ldd r24, Z+7    ; 0x07
 8dc:   fd 01           movw    r30, r26
 8de:   85 83           std Z+5, r24    ; 0x05
 8e0:   e2 2f           mov r30, r18
 8e2:   2f 5f           subi    r18, 0xFF   ; 255
 8e4:   3f 4f           sbci    r19, 0xFF   ; 255
 8e6:   e9 17           cp  r30, r25
 8e8:   90 f3           brcs    .-28        ; 0x8ce <Can_Process+0x4a>
        }
        /* Increment write index and queue length. */
        if (++RxQ_Wr_idx >= STDCAN_RX_QUEUE_SIZE) RxQ_Wr_idx = 0;
 8ea:   87 2f           mov r24, r23
 8ec:   8f 5f           subi    r24, 0xFF   ; 255
 8ee:   80 93 d0 01     sts 0x01D0, r24
 8f2:   88 30           cpi r24, 0x08   ; 8
 8f4:   10 f0           brcs    .+4         ; 0x8fa <Can_Process+0x76>
 8f6:   10 92 d0 01     sts 0x01D0, r1
        RxQ_Len++;
 8fa:   6f 5f           subi    r22, 0xFF   ; 255
 8fc:   60 93 67 01     sts 0x0167, r22
 900:   df 91           pop r29
 902:   cf 91           pop r28
 904:   08 95           ret

00000906 <StdCan_Get>:
    } else {
        /* Overflow, just drop the new message. In the future, some
         * form of priority scheme could be used to drop another
         * message in the queue.
         */
    }
}

StdCan_Ret_t StdCan_Init()
{
    StdCan_Ret_t retval;
    
    /* Reset all queue variables. */
    RxQ_Rd_idx = 0;
    RxQ_Wr_idx = 0;
    RxQ_Len    = 0;
#if (STDCAN_TX_QUEUE_SIZE > 1)
    TxQ_Rd_idx = 0;
    TxQ_Wr_idx = 0;
    TxQ_Len    = 0;
#endif
    
#if defined(_AVRLIB_BIOS_)
    /* Initialize BIOS' interface for CAN. */
    BIOS_CanCallback = Can_Process;
    retval = StdCan_Ret_OK;
#else
    /* Initialize CAN driver. */
    if (Can_Init() == CAN_OK)
        retval = StdCan_Ret_OK;
    else
        retval = StdCan_Ret_Fail;
#endif
    
    //TODO: Do something with the Node Descriptor. 
    //(why have constats passed as parameters? they are defined at compiletime /arune)
#if defined(_AVRLIB_BIOS_)
    /* TODO: When a Tx queue is implemented, the startup message should
     * be sent via StdCan_Put instead of directly to lower layer.
     */
    Can_Message_t Startup;
    
    /* Set up Startup message format. */
    Startup.ExtendedFlag = 1;
    Startup.RemoteFlag = 0;
    Startup.DataLength = 4;
    Startup.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE);
    Startup.Data.bytes[0] = NODE_HW_ID&0xff;
    Startup.Data.bytes[1] = (NODE_HW_ID>>8)&0xff;
    Startup.Data.bytes[2] = (NODE_HW_ID>>16)&0xff;
    Startup.Data.bytes[3] = (NODE_HW_ID>>24)&0xff;
    
    /* Try to send it. */
    Can_Send(&Startup);
#endif
    
    return retval;
}

StdCan_Ret_t StdCan_Get(StdCan_Msg_t* msg)
{
 906:   cf 93           push    r28
 908:   df 93           push    r29
 90a:   ec 01           movw    r28, r24
    unsigned char n;
    
    /* Check if there's a message waiting. */
    if (RxQ_Len) {
 90c:   80 91 67 01     lds r24, 0x0167
 910:   88 23           and r24, r24
 912:   19 f4           brne    .+6         ; 0x91a <StdCan_Get+0x14>
 914:   82 e0           ldi r24, 0x02   ; 2
 916:   90 e0           ldi r25, 0x00   ; 0
 918:   4b c0           rjmp    .+150       ; 0x9b0 <StdCan_Get+0xaa>
        
        /* Copy message to user buffer. */
        msg->Id     = RxQ[RxQ_Rd_idx].Id;
 91a:   80 91 66 01     lds r24, 0x0166
 91e:   99 27           eor r25, r25
 920:   2d e0           ldi r18, 0x0D   ; 13
 922:   30 e0           ldi r19, 0x00   ; 0
 924:   82 9f           mul r24, r18
 926:   f0 01           movw    r30, r0
 928:   83 9f           mul r24, r19
 92a:   f0 0d           add r31, r0
 92c:   92 9f           mul r25, r18
 92e:   f0 0d           add r31, r0
 930:   11 24           eor r1, r1
 932:   e8 59           subi    r30, 0x98   ; 152
 934:   fe 4f           sbci    r31, 0xFE   ; 254
 936:   80 81           ld  r24, Z
 938:   91 81           ldd r25, Z+1    ; 0x01
 93a:   a2 81           ldd r26, Z+2    ; 0x02
 93c:   b3 81           ldd r27, Z+3    ; 0x03
 93e:   88 83           st  Y, r24
 940:   99 83           std Y+1, r25    ; 0x01
 942:   aa 83           std Y+2, r26    ; 0x02
 944:   bb 83           std Y+3, r27    ; 0x03
        msg->Length = RxQ[RxQ_Rd_idx].Length;
 946:   84 81           ldd r24, Z+4    ; 0x04
 948:   8c 83           std Y+4, r24    ; 0x04
 94a:   20 e0           ldi r18, 0x00   ; 0
 94c:   30 e0           ldi r19, 0x00   ; 0
 94e:   6d e0           ldi r22, 0x0D   ; 13
 950:   70 e0           ldi r23, 0x00   ; 0
 952:   0b c0           rjmp    .+22        ; 0x96a <StdCan_Get+0x64>
        //TODO: Consider a mempcy() of the entire message.
        for (n = 0; n < RxQ[RxQ_Rd_idx].Length; n++) {
            msg->Data[n] = RxQ[RxQ_Rd_idx].Data[n];
 954:   85 2f           mov r24, r21
 956:   99 27           eor r25, r25
 958:   ac 01           movw    r20, r24
 95a:   4c 0f           add r20, r28
 95c:   5d 1f           adc r21, r29
 95e:   a8 0f           add r26, r24
 960:   b9 1f           adc r27, r25
 962:   fd 01           movw    r30, r26
 964:   85 81           ldd r24, Z+5    ; 0x05
 966:   fa 01           movw    r30, r20
 968:   85 83           std Z+5, r24    ; 0x05
 96a:   52 2f           mov r21, r18
 96c:   40 91 66 01     lds r20, 0x0166
 970:   84 2f           mov r24, r20
 972:   99 27           eor r25, r25
 974:   2f 5f           subi    r18, 0xFF   ; 255
 976:   3f 4f           sbci    r19, 0xFF   ; 255
 978:   86 9f           mul r24, r22
 97a:   d0 01           movw    r26, r0
 97c:   87 9f           mul r24, r23
 97e:   b0 0d           add r27, r0
 980:   96 9f           mul r25, r22
 982:   b0 0d           add r27, r0
 984:   11 24           eor r1, r1
 986:   a8 59           subi    r26, 0x98   ; 152
 988:   be 4f           sbci    r27, 0xFE   ; 254
 98a:   fd 01           movw    r30, r26
 98c:   84 81           ldd r24, Z+4    ; 0x04
 98e:   58 17           cp  r21, r24
 990:   08 f3           brcs    .-62        ; 0x954 <StdCan_Get+0x4e>
        }
        
        /* Increment read index and decrease queue length. */
        if (++RxQ_Rd_idx >= STDCAN_RX_QUEUE_SIZE) RxQ_Rd_idx = 0;
 992:   84 2f           mov r24, r20
 994:   8f 5f           subi    r24, 0xFF   ; 255
 996:   80 93 66 01     sts 0x0166, r24
 99a:   88 30           cpi r24, 0x08   ; 8
 99c:   10 f0           brcs    .+4         ; 0x9a2 <StdCan_Get+0x9c>
 99e:   10 92 66 01     sts 0x0166, r1
        RxQ_Len--;
 9a2:   80 91 67 01     lds r24, 0x0167
 9a6:   81 50           subi    r24, 0x01   ; 1
 9a8:   80 93 67 01     sts 0x0167, r24
 9ac:   80 e0           ldi r24, 0x00   ; 0
 9ae:   90 e0           ldi r25, 0x00   ; 0
 9b0:   df 91           pop r29
 9b2:   cf 91           pop r28
 9b4:   08 95           ret

000009b6 <StdCan_Get_Pending>:
        
        return StdCan_Ret_OK;
    } else {
        /* Queue is empty. */
        return StdCan_Ret_Empty;
    }
}

unsigned char StdCan_Get_Pending(void)
{
 9b6:   80 91 67 01     lds r24, 0x0167
    return RxQ_Len;
}
 9ba:   99 27           eor r25, r25
 9bc:   08 95           ret

000009be <StdCan_SendHeartbeat>:

StdCan_Ret_t StdCan_Put(StdCan_Msg_t* msg)
{
    Can_Message_t Can_Msg;
    unsigned char n;
    
    /* Validate message. */
    if ((unsigned)msg->Length > 8) return StdCan_Ret_DataErr;
    
    /* Copy message directly to lower layer until a proper
     * queue has been implemented.
     * TODO: Implement a proper queue. This requires TX interrupt
     * support in the driver and BIOS.
     */
    Can_Msg.ExtendedFlag = 1;
    Can_Msg.RemoteFlag = 0;
    Can_Msg.Id = msg->Id;
    Can_Msg.DataLength = msg->Length;
    for (n = 0; n < msg->Length; n++) {
        Can_Msg.Data.bytes[n] = msg->Data[n];
    }

    if (Can_Send(&Can_Msg) == CAN_OK) {
        Can_Process(&Can_Msg);
        return StdCan_Ret_OK;
    }
    else
        return StdCan_Ret_Full;
}

void StdCan_SendHeartbeat(uint8_t n)
{
 9be:   cf 93           push    r28
 9c0:   df 93           push    r29
 9c2:   cd b7           in  r28, 0x3d   ; 61
 9c4:   de b7           in  r29, 0x3e   ; 62
 9c6:   2f 97           sbiw    r28, 0x0f   ; 15
 9c8:   0f b6           in  r0, 0x3f    ; 63
 9ca:   f8 94           cli
 9cc:   de bf           out 0x3e, r29   ; 62
 9ce:   0f be           out 0x3f, r0    ; 63
 9d0:   cd bf           out 0x3d, r28   ; 61
    /* TODO: When a Tx queue is implemented, the heartbeat should
     * be sent via StdCan_Put instead of directly to lower layer.
     */
    Can_Message_t Heartbeat;
    
    /* Set up Heartbeat message format. */
    Heartbeat.ExtendedFlag = 1;
 9d2:   81 e0           ldi r24, 0x01   ; 1
 9d4:   8e 83           std Y+6, r24    ; 0x06
    Heartbeat.RemoteFlag = 0;
 9d6:   1f 82           std Y+7, r1 ; 0x07
    Heartbeat.DataLength = 4;
 9d8:   84 e0           ldi r24, 0x04   ; 4
 9da:   8d 83           std Y+5, r24    ; 0x05
    Heartbeat.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_HEARTBEAT << CAN_SHIFT_NMT_TYPE);
 9dc:   80 e0           ldi r24, 0x00   ; 0
 9de:   90 e0           ldi r25, 0x00   ; 0
 9e0:   ac e2           ldi r26, 0x2C   ; 44
 9e2:   b0 e0           ldi r27, 0x00   ; 0
 9e4:   89 83           std Y+1, r24    ; 0x01
 9e6:   9a 83           std Y+2, r25    ; 0x02
 9e8:   ab 83           std Y+3, r26    ; 0x03
 9ea:   bc 83           std Y+4, r27    ; 0x04
    Heartbeat.Data.bytes[0] = NODE_HW_ID&0xff;
 9ec:   8f e1           ldi r24, 0x1F   ; 31
 9ee:   88 87           std Y+8, r24    ; 0x08
    Heartbeat.Data.bytes[1] = (NODE_HW_ID>>8)&0xff;
 9f0:   8b e0           ldi r24, 0x0B   ; 11
 9f2:   89 87           std Y+9, r24    ; 0x09
    Heartbeat.Data.bytes[2] = (NODE_HW_ID>>16)&0xff;
 9f4:   80 e9           ldi r24, 0x90   ; 144
 9f6:   8a 87           std Y+10, r24   ; 0x0a
    Heartbeat.Data.bytes[3] = (NODE_HW_ID>>24)&0xff;
 9f8:   87 eb           ldi r24, 0xB7   ; 183
 9fa:   8b 87           std Y+11, r24   ; 0x0b
    
    /* Try to send it. */
    Can_Send(&Heartbeat);
 9fc:   ce 01           movw    r24, r28
 9fe:   01 96           adiw    r24, 0x01   ; 1
 a00:   0e 94 e1 18     call    0x31c2 <BIOS_CanSend>
 a04:   2f 96           adiw    r28, 0x0f   ; 15
 a06:   0f b6           in  r0, 0x3f    ; 63
 a08:   f8 94           cli
 a0a:   de bf           out 0x3e, r29   ; 62
 a0c:   0f be           out 0x3f, r0    ; 63
 a0e:   cd bf           out 0x3d, r28   ; 61
 a10:   df 91           pop r29
 a12:   cf 91           pop r28
 a14:   08 95           ret

00000a16 <StdCan_Put>:
 a16:   0f 93           push    r16
 a18:   1f 93           push    r17
 a1a:   cf 93           push    r28
 a1c:   df 93           push    r29
 a1e:   cd b7           in  r28, 0x3d   ; 61
 a20:   de b7           in  r29, 0x3e   ; 62
 a22:   2f 97           sbiw    r28, 0x0f   ; 15
 a24:   0f b6           in  r0, 0x3f    ; 63
 a26:   f8 94           cli
 a28:   de bf           out 0x3e, r29   ; 62
 a2a:   0f be           out 0x3f, r0    ; 63
 a2c:   cd bf           out 0x3d, r28   ; 61
 a2e:   9c 01           movw    r18, r24
 a30:   fc 01           movw    r30, r24
 a32:   44 81           ldd r20, Z+4    ; 0x04
 a34:   49 30           cpi r20, 0x09   ; 9
 a36:   18 f0           brcs    .+6         ; 0xa3e <StdCan_Put+0x28>
 a38:   84 e0           ldi r24, 0x04   ; 4
 a3a:   90 e0           ldi r25, 0x00   ; 0
 a3c:   31 c0           rjmp    .+98        ; 0xaa0 <StdCan_Put+0x8a>
 a3e:   81 e0           ldi r24, 0x01   ; 1
 a40:   8e 83           std Y+6, r24    ; 0x06
 a42:   1f 82           std Y+7, r1 ; 0x07
 a44:   f9 01           movw    r30, r18
 a46:   80 81           ld  r24, Z
 a48:   91 81           ldd r25, Z+1    ; 0x01
 a4a:   a2 81           ldd r26, Z+2    ; 0x02
 a4c:   b3 81           ldd r27, Z+3    ; 0x03
 a4e:   89 83           std Y+1, r24    ; 0x01
 a50:   9a 83           std Y+2, r25    ; 0x02
 a52:   ab 83           std Y+3, r26    ; 0x03
 a54:   bc 83           std Y+4, r27    ; 0x04
 a56:   4d 83           std Y+5, r20    ; 0x05
 a58:   40 e0           ldi r20, 0x00   ; 0
 a5a:   50 e0           ldi r21, 0x00   ; 0
 a5c:   8e 01           movw    r16, r28
 a5e:   0f 5f           subi    r16, 0xFF   ; 255
 a60:   1f 4f           sbci    r17, 0xFF   ; 255
 a62:   0a c0           rjmp    .+20        ; 0xa78 <StdCan_Put+0x62>
 a64:   e9 2f           mov r30, r25
 a66:   ff 27           eor r31, r31
 a68:   df 01           movw    r26, r30
 a6a:   a0 0f           add r26, r16
 a6c:   b1 1f           adc r27, r17
 a6e:   e2 0f           add r30, r18
 a70:   f3 1f           adc r31, r19
 a72:   85 81           ldd r24, Z+5    ; 0x05
 a74:   fd 01           movw    r30, r26
 a76:   87 83           std Z+7, r24    ; 0x07
 a78:   94 2f           mov r25, r20
 a7a:   4f 5f           subi    r20, 0xFF   ; 255
 a7c:   5f 4f           sbci    r21, 0xFF   ; 255
 a7e:   f9 01           movw    r30, r18
 a80:   84 81           ldd r24, Z+4    ; 0x04
 a82:   98 17           cp  r25, r24
 a84:   78 f3           brcs    .-34        ; 0xa64 <StdCan_Put+0x4e>
 a86:   c8 01           movw    r24, r16
 a88:   0e 94 e1 18     call    0x31c2 <BIOS_CanSend>
 a8c:   81 30           cpi r24, 0x01   ; 1
 a8e:   19 f0           breq    .+6         ; 0xa96 <StdCan_Put+0x80>
 a90:   81 e0           ldi r24, 0x01   ; 1
 a92:   90 e0           ldi r25, 0x00   ; 0
 a94:   05 c0           rjmp    .+10        ; 0xaa0 <StdCan_Put+0x8a>
 a96:   c8 01           movw    r24, r16
 a98:   0e 94 42 04     call    0x884 <Can_Process>
 a9c:   80 e0           ldi r24, 0x00   ; 0
 a9e:   90 e0           ldi r25, 0x00   ; 0
 aa0:   2f 96           adiw    r28, 0x0f   ; 15
 aa2:   0f b6           in  r0, 0x3f    ; 63
 aa4:   f8 94           cli
 aa6:   de bf           out 0x3e, r29   ; 62
 aa8:   0f be           out 0x3f, r0    ; 63
 aaa:   cd bf           out 0x3d, r28   ; 61
 aac:   df 91           pop r29
 aae:   cf 91           pop r28
 ab0:   1f 91           pop r17
 ab2:   0f 91           pop r16
 ab4:   08 95           ret

00000ab6 <StdCan_Init>:
 ab6:   cf 93           push    r28
 ab8:   df 93           push    r29
 aba:   cd b7           in  r28, 0x3d   ; 61
 abc:   de b7           in  r29, 0x3e   ; 62
 abe:   2f 97           sbiw    r28, 0x0f   ; 15
 ac0:   0f b6           in  r0, 0x3f    ; 63
 ac2:   f8 94           cli
 ac4:   de bf           out 0x3e, r29   ; 62
 ac6:   0f be           out 0x3f, r0    ; 63
 ac8:   cd bf           out 0x3d, r28   ; 61
 aca:   10 92 66 01     sts 0x0166, r1
 ace:   10 92 d0 01     sts 0x01D0, r1
 ad2:   10 92 67 01     sts 0x0167, r1
 ad6:   82 e4           ldi r24, 0x42   ; 66
 ad8:   94 e0           ldi r25, 0x04   ; 4
 ada:   90 93 16 01     sts 0x0116, r25
 ade:   80 93 15 01     sts 0x0115, r24
 ae2:   81 e0           ldi r24, 0x01   ; 1
 ae4:   8e 83           std Y+6, r24    ; 0x06
 ae6:   1f 82           std Y+7, r1 ; 0x07
 ae8:   84 e0           ldi r24, 0x04   ; 4
 aea:   8d 83           std Y+5, r24    ; 0x05
 aec:   80 e0           ldi r24, 0x00   ; 0
 aee:   90 e0           ldi r25, 0x00   ; 0
 af0:   a8 e2           ldi r26, 0x28   ; 40
 af2:   b0 e0           ldi r27, 0x00   ; 0
 af4:   89 83           std Y+1, r24    ; 0x01
 af6:   9a 83           std Y+2, r25    ; 0x02
 af8:   ab 83           std Y+3, r26    ; 0x03
 afa:   bc 83           std Y+4, r27    ; 0x04
 afc:   8f e1           ldi r24, 0x1F   ; 31
 afe:   88 87           std Y+8, r24    ; 0x08
 b00:   8b e0           ldi r24, 0x0B   ; 11
 b02:   89 87           std Y+9, r24    ; 0x09
 b04:   80 e9           ldi r24, 0x90   ; 144
 b06:   8a 87           std Y+10, r24   ; 0x0a
 b08:   87 eb           ldi r24, 0xB7   ; 183
 b0a:   8b 87           std Y+11, r24   ; 0x0b
 b0c:   ce 01           movw    r24, r28
 b0e:   01 96           adiw    r24, 0x01   ; 1
 b10:   0e 94 e1 18     call    0x31c2 <BIOS_CanSend>
 b14:   80 e0           ldi r24, 0x00   ; 0
 b16:   90 e0           ldi r25, 0x00   ; 0
 b18:   2f 96           adiw    r28, 0x0f   ; 15
 b1a:   0f b6           in  r0, 0x3f    ; 63
 b1c:   f8 94           cli
 b1e:   de bf           out 0x3e, r29   ; 62
 b20:   0f be           out 0x3f, r0    ; 63
 b22:   cd bf           out 0x3d, r28   ; 61
 b24:   df 91           pop r29
 b26:   cf 91           pop r28
 b28:   08 95           ret

00000b2a <ReadTemperature_callback>:
uint8_t FlagReadTemperature, FlagConvertTemperature, FlagSearchSensors;

void ReadTemperature_callback(uint8_t timer)
{
    FlagReadTemperature = 1;
 b2a:   81 e0           ldi r24, 0x01   ; 1
 b2c:   80 93 d1 01     sts 0x01D1, r24
 b30:   08 95           ret

00000b32 <ConvertTemperature_callback>:
}

void ReadTemperature(void)
{
    static uint8_t SearchSensorsTimeout = sns_ds18x20_SEARCH_TIMEOUT;
    static uint8_t CurrentSensor = 0;
    uint8_t subzero, cel, cel_frac_bits = 0;
    StdCan_Msg_t txMsg;

    StdCan_Set_class(txMsg, CAN_MODULE_SNS);
    StdCan_Set_direction(txMsg, OWNER);
    txMsg.Header.ModuleType = MODULE_TYPE_sns_ds18x20;
    txMsg.Header.ModuleId = sns_ds18x20_ID;
    txMsg.Header.Command = SNS_CMD_TEMPERATURE_CELSIUS;
    txMsg.Length = 3;

    txMsg.Data[0] = SensorIds[CurrentSensor];

    if (DS18X20_read_meas(&gSensorIDs[CurrentSensor][0], &subzero, &cel, &cel_frac_bits) == DS18X20_OK)
    {
        if (subzero)
        {
            txMsg.Data[1] = -cel-1;
            txMsg.Data[2] = ~(cel_frac_bits<<4);
        }
        else
        {
            txMsg.Data[1] = cel;
            txMsg.Data[2] = (cel_frac_bits<<4);
        }
    }
    /* send txMsg */

    StdCan_Put(&txMsg);

    CurrentSensor++;
    if (CurrentSensor < NumberOfSensors)
        Timer_SetTimeout(sns_ds18x20_TIMER, sns_ds18x20_SEND_DELAY, TimerTypeOneShot, &ReadTemperature_callback);
    else
    {
        SearchSensorsTimeout--;
        if (SearchSensorsTimeout == 0)
        {
            SearchSensorsTimeout = sns_ds18x20_SEARCH_TIMEOUT;
            FlagSearchSensors = 1;
        }
        
        CurrentSensor = 0;

        Timer_SetTimeout(sns_ds18x20_TIMER, sns_ds18x20_SEND_PERIOD , TimerTypeOneShot, &ConvertTemperature_callback);
    }
}

void ConvertTemperature_callback(uint8_t timer)
{
    FlagConvertTemperature = 1;
 b32:   81 e0           ldi r24, 0x01   ; 1
 b34:   80 93 d4 01     sts 0x01D4, r24
 b38:   08 95           ret

00000b3a <sns_ds18x20_HandleMessage>:
}

void ConvertTemperature(void)
{
    if (DS18X20_start_meas(DS18X20_POWER_PARASITE, NULL) == DS18X20_OK)
    {
        Timer_SetTimeout(sns_ds18x20_TIMER, DS18B20_TCONV_12BIT, TimerTypeOneShot, &ReadTemperature_callback);
    }
}


void sns_ds18x20_Init(void)
{
    /* Make sure there is no more then 4 sensors. */
    NumberOfSensors = search_sensors();
    
    Timer_SetTimeout(sns_ds18x20_TIMER, sns_ds18x20_SEND_PERIOD , TimerTypeFreeRunning, &ConvertTemperature_callback);
    
}

void sns_ds18x20_Process(void)
{
    if (FlagConvertTemperature)
    {
        ConvertTemperature();
        FlagConvertTemperature = 0;
    }

    if (FlagSearchSensors)
    {
        NumberOfSensors = search_sensors();
        uint8_t i, j;

        for(i = 0; i < NumberOfSensors; i++)
        {
            SensorIds[i] = 0;
            for (j = 0; j < 7; j++)
            {
                SensorIds[i] ^= gSensorIDs[i][j];   
            }
        }
        FlagSearchSensors = 0;
    }

    if (FlagReadTemperature)
    {
        ReadTemperature();
        FlagReadTemperature = 0;
    }
}


void sns_ds18x20_HandleMessage(StdCan_Msg_t *rxMsg)
{
 b3a:   08 95           ret

00000b3c <sns_ds18x20_List>:
}

void sns_ds18x20_List(uint8_t ModuleSequenceNumber)
{
 b3c:   cf 93           push    r28
 b3e:   df 93           push    r29
 b40:   cd b7           in  r28, 0x3d   ; 61
 b42:   de b7           in  r29, 0x3e   ; 62
 b44:   2d 97           sbiw    r28, 0x0d   ; 13
 b46:   0f b6           in  r0, 0x3f    ; 63
 b48:   f8 94           cli
 b4a:   de bf           out 0x3e, r29   ; 62
 b4c:   0f be           out 0x3f, r0    ; 63
 b4e:   cd bf           out 0x3d, r28   ; 61
    StdCan_Msg_t txMsg;
    
    StdCan_Set_class(txMsg, CAN_MODULE_SNS);
    StdCan_Set_direction(txMsg, OWNER);
 b50:   9b e1           ldi r25, 0x1B   ; 27
 b52:   9c 83           std Y+4, r25    ; 0x04
    txMsg.Header.ModuleType = MODULE_TYPE_sns_ds18x20;
 b54:   93 e0           ldi r25, 0x03   ; 3
 b56:   9b 83           std Y+3, r25    ; 0x03
    txMsg.Header.ModuleId = sns_ds18x20_ID;
 b58:   21 e0           ldi r18, 0x01   ; 1
 b5a:   2a 83           std Y+2, r18    ; 0x02
    txMsg.Header.Command = CMD_LIST;
 b5c:   19 82           std Y+1, r1 ; 0x01
    txMsg.Length = 6;
 b5e:   96 e0           ldi r25, 0x06   ; 6
 b60:   9d 83           std Y+5, r25    ; 0x05

    txMsg.Data[3] = NODE_HW_ID&0xff;
 b62:   9f e1           ldi r25, 0x1F   ; 31
 b64:   99 87           std Y+9, r25    ; 0x09
    txMsg.Data[2] = (NODE_HW_ID>>8)&0xff;
 b66:   9b e0           ldi r25, 0x0B   ; 11
 b68:   98 87           std Y+8, r25    ; 0x08
    txMsg.Data[1] = (NODE_HW_ID>>16)&0xff;
 b6a:   90 e9           ldi r25, 0x90   ; 144
 b6c:   9f 83           std Y+7, r25    ; 0x07
    txMsg.Data[0] = (NODE_HW_ID>>24)&0xff;
 b6e:   97 eb           ldi r25, 0xB7   ; 183
 b70:   9e 83           std Y+6, r25    ; 0x06
    
    txMsg.Data[4] = NUMBEROFMODULES;
 b72:   2a 87           std Y+10, r18   ; 0x0a
    txMsg.Data[5] = ModuleSequenceNumber;
 b74:   8b 87           std Y+11, r24   ; 0x0b
    
    StdCan_Put(&txMsg);
 b76:   ce 01           movw    r24, r28
 b78:   01 96           adiw    r24, 0x01   ; 1
 b7a:   0e 94 0b 05     call    0xa16 <StdCan_Put>
 b7e:   2d 96           adiw    r28, 0x0d   ; 13
 b80:   0f b6           in  r0, 0x3f    ; 63
 b82:   f8 94           cli
 b84:   de bf           out 0x3e, r29   ; 62
 b86:   0f be           out 0x3f, r0    ; 63
 b88:   cd bf           out 0x3d, r28   ; 61
 b8a:   df 91           pop r29
 b8c:   cf 91           pop r28
 b8e:   08 95           ret

00000b90 <sns_ds18x20_Init>:
 b90:   0e 94 f0 02     call    0x5e0 <search_sensors>
 b94:   80 93 d2 01     sts 0x01D2, r24
 b98:   29 e9           ldi r18, 0x99   ; 153
 b9a:   35 e0           ldi r19, 0x05   ; 5
 b9c:   41 e0           ldi r20, 0x01   ; 1
 b9e:   60 e2           ldi r22, 0x20   ; 32
 ba0:   7e e4           ldi r23, 0x4E   ; 78
 ba2:   81 e0           ldi r24, 0x01   ; 1
 ba4:   0e 94 f6 00     call    0x1ec <Timer_SetTimeout>
 ba8:   08 95           ret

00000baa <ConvertTemperature>:
 baa:   60 e0           ldi r22, 0x00   ; 0
 bac:   70 e0           ldi r23, 0x00   ; 0
 bae:   80 e0           ldi r24, 0x00   ; 0
 bb0:   0e 94 a2 02     call    0x544 <DS18X20_start_meas>
 bb4:   88 23           and r24, r24
 bb6:   41 f4           brne    .+16        ; 0xbc8 <ConvertTemperature+0x1e>
 bb8:   25 e9           ldi r18, 0x95   ; 149
 bba:   35 e0           ldi r19, 0x05   ; 5
 bbc:   40 e0           ldi r20, 0x00   ; 0
 bbe:   6e ee           ldi r22, 0xEE   ; 238
 bc0:   72 e0           ldi r23, 0x02   ; 2
 bc2:   81 e0           ldi r24, 0x01   ; 1
 bc4:   0e 94 f6 00     call    0x1ec <Timer_SetTimeout>
 bc8:   08 95           ret

00000bca <ReadTemperature>:
 bca:   cf 93           push    r28
 bcc:   df 93           push    r29
 bce:   cd b7           in  r28, 0x3d   ; 61
 bd0:   de b7           in  r29, 0x3e   ; 62
 bd2:   60 97           sbiw    r28, 0x10   ; 16
 bd4:   0f b6           in  r0, 0x3f    ; 63
 bd6:   f8 94           cli
 bd8:   de bf           out 0x3e, r29   ; 62
 bda:   0f be           out 0x3f, r0    ; 63
 bdc:   cd bf           out 0x3d, r28   ; 61
 bde:   1b 82           std Y+3, r1 ; 0x03
 be0:   8b e1           ldi r24, 0x1B   ; 27
 be2:   8f 83           std Y+7, r24    ; 0x07
 be4:   93 e0           ldi r25, 0x03   ; 3
 be6:   9e 83           std Y+6, r25    ; 0x06
 be8:   81 e0           ldi r24, 0x01   ; 1
 bea:   8d 83           std Y+5, r24    ; 0x05
 bec:   84 e0           ldi r24, 0x04   ; 4
 bee:   8c 83           std Y+4, r24    ; 0x04
 bf0:   98 87           std Y+8, r25    ; 0x08
 bf2:   80 91 2c 01     lds r24, 0x012C
 bf6:   99 27           eor r25, r25
 bf8:   88 0f           add r24, r24
 bfa:   99 1f           adc r25, r25
 bfc:   fc 01           movw    r30, r24
 bfe:   ec 5d           subi    r30, 0xDC   ; 220
 c00:   fe 4f           sbci    r31, 0xFE   ; 254
 c02:   20 81           ld  r18, Z
 c04:   29 87           std Y+9, r18    ; 0x09
 c06:   88 0f           add r24, r24
 c08:   99 1f           adc r25, r25
 c0a:   88 0f           add r24, r24
 c0c:   99 1f           adc r25, r25
 c0e:   9e 01           movw    r18, r28
 c10:   2d 5f           subi    r18, 0xFD   ; 253
 c12:   3f 4f           sbci    r19, 0xFF   ; 255
 c14:   ae 01           movw    r20, r28
 c16:   4e 5f           subi    r20, 0xFE   ; 254
 c18:   5f 4f           sbci    r21, 0xFF   ; 255
 c1a:   be 01           movw    r22, r28
 c1c:   6f 5f           subi    r22, 0xFF   ; 255
 c1e:   7f 4f           sbci    r23, 0xFF   ; 255
 c20:   83 5d           subi    r24, 0xD3   ; 211
 c22:   9e 4f           sbci    r25, 0xFE   ; 254
 c24:   0e 94 48 02     call    0x490 <DS18X20_read_meas>
 c28:   88 23           and r24, r24
 c2a:   79 f4           brne    .+30        ; 0xc4a <ReadTemperature+0x80>
 c2c:   89 81           ldd r24, Y+1    ; 0x01
 c2e:   2a 81           ldd r18, Y+2    ; 0x02
 c30:   9b 81           ldd r25, Y+3    ; 0x03
 c32:   88 23           and r24, r24
 c34:   31 f0           breq    .+12        ; 0xc42 <ReadTemperature+0x78>
 c36:   20 95           com r18
 c38:   2a 87           std Y+10, r18   ; 0x0a
 c3a:   92 95           swap    r25
 c3c:   90 7f           andi    r25, 0xF0   ; 240
 c3e:   90 95           com r25
 c40:   03 c0           rjmp    .+6         ; 0xc48 <ReadTemperature+0x7e>
 c42:   2a 87           std Y+10, r18   ; 0x0a
 c44:   92 95           swap    r25
 c46:   90 7f           andi    r25, 0xF0   ; 240
 c48:   9b 87           std Y+11, r25   ; 0x0b
 c4a:   ce 01           movw    r24, r28
 c4c:   04 96           adiw    r24, 0x04   ; 4
 c4e:   0e 94 0b 05     call    0xa16 <StdCan_Put>
 c52:   80 91 2c 01     lds r24, 0x012C
 c56:   8f 5f           subi    r24, 0xFF   ; 255
 c58:   80 93 2c 01     sts 0x012C, r24
 c5c:   90 91 d2 01     lds r25, 0x01D2
 c60:   89 17           cp  r24, r25
 c62:   30 f4           brcc    .+12        ; 0xc70 <ReadTemperature+0xa6>
 c64:   25 e9           ldi r18, 0x95   ; 149
 c66:   35 e0           ldi r19, 0x05   ; 5
 c68:   40 e0           ldi r20, 0x00   ; 0
 c6a:   64 ef           ldi r22, 0xF4   ; 244
 c6c:   71 e0           ldi r23, 0x01   ; 1
 c6e:   14 c0           rjmp    .+40        ; 0xc98 <ReadTemperature+0xce>
 c70:   80 91 23 01     lds r24, 0x0123
 c74:   81 50           subi    r24, 0x01   ; 1
 c76:   80 93 23 01     sts 0x0123, r24
 c7a:   88 23           and r24, r24
 c7c:   31 f4           brne    .+12        ; 0xc8a <ReadTemperature+0xc0>
 c7e:   85 e0           ldi r24, 0x05   ; 5
 c80:   80 93 23 01     sts 0x0123, r24
 c84:   81 e0           ldi r24, 0x01   ; 1
 c86:   80 93 d3 01     sts 0x01D3, r24
 c8a:   10 92 2c 01     sts 0x012C, r1
 c8e:   29 e9           ldi r18, 0x99   ; 153
 c90:   35 e0           ldi r19, 0x05   ; 5
 c92:   40 e0           ldi r20, 0x00   ; 0
 c94:   60 e2           ldi r22, 0x20   ; 32
 c96:   7e e4           ldi r23, 0x4E   ; 78
 c98:   81 e0           ldi r24, 0x01   ; 1
 c9a:   0e 94 f6 00     call    0x1ec <Timer_SetTimeout>
 c9e:   60 96           adiw    r28, 0x10   ; 16
 ca0:   0f b6           in  r0, 0x3f    ; 63
 ca2:   f8 94           cli
 ca4:   de bf           out 0x3e, r29   ; 62
 ca6:   0f be           out 0x3f, r0    ; 63
 ca8:   cd bf           out 0x3d, r28   ; 61
 caa:   df 91           pop r29
 cac:   cf 91           pop r28
 cae:   08 95           ret

00000cb0 <sns_ds18x20_Process>:
 cb0:   80 91 d4 01     lds r24, 0x01D4
 cb4:   88 23           and r24, r24
 cb6:   21 f0           breq    .+8         ; 0xcc0 <sns_ds18x20_Process+0x10>
 cb8:   0e 94 d5 05     call    0xbaa <ConvertTemperature>
 cbc:   10 92 d4 01     sts 0x01D4, r1
 cc0:   80 91 d3 01     lds r24, 0x01D3
 cc4:   88 23           and r24, r24
 cc6:   69 f1           breq    .+90        ; 0xd22 <sns_ds18x20_Process+0x72>
 cc8:   0e 94 f0 02     call    0x5e0 <search_sensors>
 ccc:   68 2f           mov r22, r24
 cce:   80 93 d2 01     sts 0x01D2, r24
 cd2:   50 e0           ldi r21, 0x00   ; 0
 cd4:   22 c0           rjmp    .+68        ; 0xd1a <sns_ds18x20_Process+0x6a>
 cd6:   a5 2f           mov r26, r21
 cd8:   bb 27           eor r27, r27
 cda:   fd 01           movw    r30, r26
 cdc:   ee 0f           add r30, r30
 cde:   ff 1f           adc r31, r31
 ce0:   ec 5d           subi    r30, 0xDC   ; 220
 ce2:   fe 4f           sbci    r31, 0xFE   ; 254
 ce4:   11 82           std Z+1, r1 ; 0x01
 ce6:   10 82           st  Z, r1
 ce8:   fd 01           movw    r30, r26
 cea:   73 e0           ldi r23, 0x03   ; 3
 cec:   ee 0f           add r30, r30
 cee:   ff 1f           adc r31, r31
 cf0:   7a 95           dec r23
 cf2:   e1 f7           brne    .-8         ; 0xcec <sns_ds18x20_Process+0x3c>
 cf4:   e3 5d           subi    r30, 0xD3   ; 211
 cf6:   fe 4f           sbci    r31, 0xFE   ; 254
 cf8:   40 e0           ldi r20, 0x00   ; 0
 cfa:   20 e0           ldi r18, 0x00   ; 0
 cfc:   30 e0           ldi r19, 0x00   ; 0
 cfe:   81 91           ld  r24, Z+
 d00:   99 27           eor r25, r25
 d02:   28 27           eor r18, r24
 d04:   39 27           eor r19, r25
 d06:   4f 5f           subi    r20, 0xFF   ; 255
 d08:   47 30           cpi r20, 0x07   ; 7
 d0a:   c9 f7           brne    .-14        ; 0xcfe <sns_ds18x20_Process+0x4e>
 d0c:   aa 0f           add r26, r26
 d0e:   bb 1f           adc r27, r27
 d10:   ac 5d           subi    r26, 0xDC   ; 220
 d12:   be 4f           sbci    r27, 0xFE   ; 254
 d14:   2d 93           st  X+, r18
 d16:   3c 93           st  X, r19
 d18:   5f 5f           subi    r21, 0xFF   ; 255
 d1a:   56 17           cp  r21, r22
 d1c:   e1 f6           brne    .-72        ; 0xcd6 <sns_ds18x20_Process+0x26>
 d1e:   10 92 d3 01     sts 0x01D3, r1
 d22:   80 91 d1 01     lds r24, 0x01D1
 d26:   88 23           and r24, r24
 d28:   21 f0           breq    .+8         ; 0xd32 <sns_ds18x20_Process+0x82>
 d2a:   0e 94 e5 05     call    0xbca <ReadTemperature>
 d2e:   10 92 d1 01     sts 0x01D1, r1
 d32:   08 95           ret

00000d34 <__divmodhi4>:
 d34:   97 fb           bst r25, 7
 d36:   09 2e           mov r0, r25
 d38:   07 26           eor r0, r23
 d3a:   0a d0           rcall   .+20        ; 0xd50 <__divmodhi4_neg1>
 d3c:   77 fd           sbrc    r23, 7
 d3e:   04 d0           rcall   .+8         ; 0xd48 <__divmodhi4_neg2>
 d40:   0c d0           rcall   .+24        ; 0xd5a <__udivmodhi4>
 d42:   06 d0           rcall   .+12        ; 0xd50 <__divmodhi4_neg1>
 d44:   00 20           and r0, r0
 d46:   1a f4           brpl    .+6         ; 0xd4e <__divmodhi4_exit>

00000d48 <__divmodhi4_neg2>:
 d48:   70 95           com r23
 d4a:   61 95           neg r22
 d4c:   7f 4f           sbci    r23, 0xFF   ; 255

00000d4e <__divmodhi4_exit>:
 d4e:   08 95           ret

00000d50 <__divmodhi4_neg1>:
 d50:   f6 f7           brtc    .-4         ; 0xd4e <__divmodhi4_exit>
 d52:   90 95           com r25
 d54:   81 95           neg r24
 d56:   9f 4f           sbci    r25, 0xFF   ; 255
 d58:   08 95           ret

00000d5a <__udivmodhi4>:
 d5a:   aa 1b           sub r26, r26
 d5c:   bb 1b           sub r27, r27
 d5e:   51 e1           ldi r21, 0x11   ; 17
 d60:   07 c0           rjmp    .+14        ; 0xd70 <__udivmodhi4_ep>

00000d62 <__udivmodhi4_loop>:
 d62:   aa 1f           adc r26, r26
 d64:   bb 1f           adc r27, r27
 d66:   a6 17           cp  r26, r22
 d68:   b7 07           cpc r27, r23
 d6a:   10 f0           brcs    .+4         ; 0xd70 <__udivmodhi4_ep>
 d6c:   a6 1b           sub r26, r22
 d6e:   b7 0b           sbc r27, r23

00000d70 <__udivmodhi4_ep>:
 d70:   88 1f           adc r24, r24
 d72:   99 1f           adc r25, r25
 d74:   5a 95           dec r21
 d76:   a9 f7           brne    .-22        ; 0xd62 <__udivmodhi4_loop>
 d78:   80 95           com r24
 d7a:   90 95           com r25
 d7c:   bc 01           movw    r22, r24
 d7e:   cd 01           movw    r24, r26
 d80:   08 95           ret