diff --git a/Makefile b/Makefile index cb6161a..1ae511f 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,27 @@ PRG = twiboot OBJ = main.o -MCU_TARGET = atmega8 +MCU_TARGET = atmega88 OPTIMIZE = -Os -DEFS = +ifeq ($(MCU_TARGET), atmega8) +BOOTLOADER_START=0x1C00 +AVRDUDE_MCU=m8 +endif +ifeq ($(MCU_TARGET), atmega88) +BOOTLOADER_START=0x1C00 +AVRDUDE_MCU=m88 +endif +ifeq ($(MCU_TARGET), atmega168) +BOOTLOADER_START=0x3C00 +AVRDUDE_MCU=m168 +endif + +DEFS = -DAPP_END=$(BOOTLOADER_START) LIBS = # Override is only needed by avr-lib build system. override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) -override LDFLAGS = -Wl,-Map,$(PRG).map,--section-start=.text=0x1C00 +override LDFLAGS = -Wl,-Map,$(PRG).map,--section-start=.text=$(BOOTLOADER_START) CC = avr-gcc OBJCOPY = avr-objcopy @@ -21,6 +34,9 @@ all: $(PRG).elf lst text $(PRG).elf: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) +%.o: %.c $(MAKEFILE_LIST) + $(CC) $(CFLAGS) -c $< -o $@ + clean: rm -rf *.o *.lst *.map $(PRG).elf *.hex *.bin @@ -41,4 +57,9 @@ bin: $(PRG).bin $(OBJCOPY) -j .text -j .data -O binary $< $@ install: text - uisp -dprog=avr910 -dserial=/dev/ttyS0 -dspeed=115200 -dpart=M8 --erase --upload if=$(PRG).hex + avrdude -c dragon_isp -P usb -p $(AVRDUDE_MCU) -U flash:w:$(PRG).hex + +fuses: + avrdude -c dragon_isp -P usb -p $(AVRDUDE_MCU) -U lfuse:w:0xc2:m + avrdude -c dragon_isp -P usb -p $(AVRDUDE_MCU) -U hfuse:w:0xdd:m + avrdude -c dragon_isp -P usb -p $(AVRDUDE_MCU) -U efuse:w:0xfa:m diff --git a/main.c b/main.c index 9f80fd8..c258c3e 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 09/2007 by Olaf Rempel * + * Copyright (C) 08/2010 by Olaf Rempel * * razzor@kopf-tisch.de * * * * This program is free software; you can redistribute it and/or modify * @@ -24,65 +24,133 @@ #define F_CPU 8000000 #include +/* + * atmega8: + * Fuse E: 0xfa (512 words bootloader) + * Fuse H: 0xdd (2.7V BOD) + * Fuse L: 0xc2 (8Mhz internal RC-Osz.) + * + * atmega88: + * Fuse E: 0xfa (512 words bootloader) + * Fuse H: 0xdd (2.7V BOD) + * Fuse L: 0xc2 (8Mhz internal RC-Osz.) + * + * atmega168: + * Fuse E: 0xfa (512 words bootloader) + * Fuse H: 0xdd (2.7V BOD) + * Fuse L: 0xc2 (8Mhz internal RC-Osz.) + */ + +#if defined (__AVR_ATmega8__) +#define VERSION_STRING "TWIBOOT m8v2.0" +#define SIGNATURE_BYTES 0x1E, 0x93, 0x07 + +#elif defined (__AVR_ATmega88__) +#define VERSION_STRING "TWIBOOT m88v2.0" +#define SIGNATURE_BYTES 0x1E, 0x93, 0x0A + +#elif defined (__AVR_ATmega168__) +#define VERSION_STRING "TWIBOOT m168v2.0" +#define SIGNATURE_BYTES 0x1E, 0x94, 0x06 + +#else +#error MCU not supported +#endif + +/* 25ms @8MHz */ +#define TIMER_RELOAD (0xFF - 195) + +/* 40 * 25ms */ +#define TIMEOUT 40 + #define LED_RT (1<> 8) & 0xFF, + APP_END & 0xFF, + + (E2END >> 8 & 0xFF), + E2END & 0xFF +}; /* wait 40 * 25ms = 1s */ -static uint8_t boot_timeout = 40; +static uint8_t boot_timeout = TIMEOUT; volatile static uint8_t cmd = CMD_WAIT; /* flash buffer */ static uint8_t buf[SPM_PAGESIZE]; static uint16_t addr; -void write_flash_page(void) +static void write_flash_page(void) { uint16_t pagestart = addr; uint8_t size = SPM_PAGESIZE; @@ -108,21 +176,36 @@ void write_flash_page(void) boot_rww_enable(); } -void write_eeprom_byte(uint8_t val) +static uint8_t read_eeprom_byte(void) +{ + EEARL = addr; + EEARH = (addr >> 8); + EECR |= (1<> 8); EEDR = val; addr++; - +#if defined (__AVR_ATmega8__) EECR |= (1< receive data and ACK */ @@ -134,64 +217,95 @@ ISR(TWI_vect) /* prev. SLA+W, data received, ACK returned -> receive data and ACK */ case 0x80: - if (bcnt == 0) { - cmd = TWDR; - switch (cmd) { - case CMD_GET_INFO: - case CMD_GET_SIGNATURE: - case CMD_WRITE_FLASH: - case CMD_READ_FLASH: - case CMD_WRITE_EEPROM: - case CMD_READ_EEPROM: + data = TWDR; + switch (bcnt) { + case 0: + switch (data) { + case CMD_SWITCH_APPLICATION: + case CMD_WRITE_MEMORY: + bcnt++; + /* no break */ + + case CMD_WAIT: /* abort countdown */ boot_timeout = 0; + break; - case CMD_BOOT_APPLICATION: + default: + /* boot app now */ + data = CMD_BOOT_APPLICATION; + ack = (0<> 8)) - bcnt++; - else - bcnt = 0; - - } else if (bcnt == 4) { - if (TWDR == (COOKIE & 0xFF)) - bcnt++; - else - bcnt = 0; - - } else if (bcnt >= 5 && cmd == CMD_WRITE_FLASH) { - buf[bcnt -5] = TWDR; - if (bcnt < sizeof(buf) +4) { - bcnt++; - - } else { - write_flash_page(); - bcnt = 0; - } - - } else if (bcnt >= 5 && cmd == CMD_WRITE_EEPROM) { - write_eeprom_byte(TWDR); - bcnt++; + break; } - TWCR |= (1< send data */ @@ -202,33 +316,30 @@ ISR(TWI_vect) /* prev. SLA+R, data sent, ACK returned -> send data */ case 0xB8: switch (cmd) { - case CMD_GET_INFO: - TWDR = info[bcnt++]; + case CMD_READ_VERSION: + data = info[bcnt++]; bcnt %= sizeof(info); break; - case CMD_GET_SIGNATURE: - TWDR = signature[bcnt++]; - bcnt %= sizeof(signature); + case CMD_READ_CHIPINFO: + data = chipinfo[bcnt++]; + bcnt %= sizeof(chipinfo); break; case CMD_READ_FLASH: - TWDR = pgm_read_byte_near(addr++); + data = pgm_read_byte_near(addr++); break; case CMD_READ_EEPROM: - EEARL = addr; - EEARH = (addr >> 8); - EECR |= (1<