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;
}
Lesezeichen