Code:
#include <avr/io.h>
#include <avr/boot.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include "uart.h"


#define PAGE_SIZE 64 + 3 // Bytes +1 PageNo +2 CRC16


unsigned int mask = 0xA001;




//-- Protoypes -----------
void boot_program_page(uint32_t page, uint8_t *buf);
unsigned int calcCRC16r(unsigned int crc, unsigned char c, unsigned int mask);




int main(void) {
    unsigned char temp;
    char buffer[PAGE_SIZE];
    uint16_t page_cnt = 0;
    //uint8_t cnt = 0;
    
    void (*start)(void) = 0x0000;        /* Funktionspointer auf 0x0000 */
    
    // Init
    DDRD |= (1<<PD2) | (1<<PD0); //StatusLED RED Ausgang/ IR-Empfänger Eingang
    DDRB |= (1<<PB0) | (1<<PB3); //StatusLED GREEN Ausgang / IR-LED Ausgang


    //IR-Schnittstelle
    // fast PWM, set OC2A on compare match, clear OC2A at bottom, clk/1
    TCCR2 = _BV(WGM20) | _BV(WGM21) | _BV(COM20) | _BV(COM21) | _BV(CS20);
    // interrupt on timer overflow
    TIMSK |= _BV(TOIE2);
    
    OCR2  = 0x91;
    
    PORTD |= (1<<PD2); //StatusLED RED
    PORTB |= (1<<PB0); //StatusLED GREEN
    PORTB |= (1<<PB3); //IRTX = 1
    PORTD |= (1<<PD1); //IRTX = 0
    
    // Interrupt vektoren verbiegen
    char sregtemp = SREG;
    cli();
    temp = GICR;
    GICR = temp | (1<<IVCE);
    GICR = temp | (1<<IVSEL);
    SREG = sregtemp;
    
    // UART
    UartInit();
    
    sei();    //Interrupt Ein
    
    _delay_ms(10);
    
    //while(cnt < 16) {
    memset(buffer, 0, sizeof(buffer));
    //SerRead(buffer, 18, 65000);
    SerRead(buffer, 18, 0);
    
    if(strstr(buffer, "Flash")) {
        memset(buffer, 0, sizeof(buffer));
        unsigned int crc = 0, i = 0, h_crc = 0;
        
        //cnt = 20;
        
        _delay_ms(1);
        SerWrite("ASURO\0\0\0\0\0\0\0\0\0");
        _delay_ms(1);
        
        while(1) {
            // receive
            memset(buffer, 0, sizeof(buffer));
            
            SerRead(buffer, PAGE_SIZE, 0);
            
            crc = 0;
            for(i = 0; i < (PAGE_SIZE - 2); i++) {
                crc = calcCRC16r(crc, buffer[i], mask);
            }
            
            memcpy(&h_crc, &buffer[i], 2);
            
            // Last page
            if(buffer[0] == 0xFF) {
                _delay_ms(16);
                SerWrite("OK");
                break;
            }
            
            if(buffer[0] == 1) {
                _delay_ms(16);
                SerWrite("ER");
            }
            
            if(crc == h_crc) {
                // transmission OK
                // flash page
                _delay_ms(16);
                //boot_program_page(page_cnt, (uint8_t*)&buffer[1]);
                //if(last_page != buffer[0])
                page_cnt += 64;
                
                SerWrite("OK");
            } else {
                _delay_ms(16);
                SerWrite("CK");
            }
        }
    }
    //}
    
    PORTD &= ~(1<<PD2);
    
    // Interrupt Vektoren wieder gerade biegen
    cli();
    sregtemp = GICR;
    GICR = sregtemp | (1<<IVCE);
    GICR = sregtemp & ~(1<<IVSEL);
    
    // Rücksprung zur Adresse 0x0000
    start();
    
    return 0;
}