multicpu support
This commit is contained in:
parent
e013aea33c
commit
f73b52bc3c
26
Makefile
26
Makefile
@ -3,12 +3,25 @@ OBJ = main.o
|
|||||||
MCU_TARGET = atmega88
|
MCU_TARGET = atmega88
|
||||||
OPTIMIZE = -Os
|
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 =
|
LIBS =
|
||||||
|
|
||||||
# Override is only needed by avr-lib build system.
|
# Override is only needed by avr-lib build system.
|
||||||
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
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
|
CC = avr-gcc
|
||||||
OBJCOPY = avr-objcopy
|
OBJCOPY = avr-objcopy
|
||||||
@ -21,6 +34,9 @@ all: $(PRG).elf lst text
|
|||||||
$(PRG).elf: $(OBJ)
|
$(PRG).elf: $(OBJ)
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
%.o: %.c $(MAKEFILE_LIST)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o *.lst *.map $(PRG).elf *.hex *.bin
|
rm -rf *.o *.lst *.map $(PRG).elf *.hex *.bin
|
||||||
|
|
||||||
@ -41,7 +57,9 @@ bin: $(PRG).bin
|
|||||||
$(OBJCOPY) -j .text -j .data -O binary $< $@
|
$(OBJCOPY) -j .text -j .data -O binary $< $@
|
||||||
|
|
||||||
install: text
|
install: text
|
||||||
avrdude -c dragon_isp -P usb -p m88 -U flash:w:$(PRG).hex
|
avrdude -c dragon_isp -P usb -p $(AVRDUDE_MCU) -U flash:w:$(PRG).hex
|
||||||
|
|
||||||
fuses:
|
fuses:
|
||||||
avrdude -c dragon_isp -P usb -p m88 -U lfuse:w:0xc2:m -U hfuse:w:0xdd:m -U efuse:w:0xfa:m
|
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
|
||||||
|
101
main.c
101
main.c
@ -1,5 +1,5 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 07/2010 by Olaf Rempel *
|
* Copyright (C) 08/2010 by Olaf Rempel *
|
||||||
* razzor@kopf-tisch.de *
|
* razzor@kopf-tisch.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
@ -25,12 +25,38 @@
|
|||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* atmega8:
|
||||||
|
* Fuse E: 0xfa (512 words bootloader)
|
||||||
|
* Fuse H: 0xdd (2.7V BOD)
|
||||||
|
* Fuse L: 0xc2 (8Mhz internal RC-Osz.)
|
||||||
|
*
|
||||||
* atmega88:
|
* atmega88:
|
||||||
* Fuse E: 0xfa (512 words bootloader)
|
* Fuse E: 0xfa (512 words bootloader)
|
||||||
* Fuse H: 0xdd (2.7V BOD)
|
* Fuse H: 0xdd (2.7V BOD)
|
||||||
* Fuse L: 0xc2 (8Mhz internal RC-Osz.)
|
* 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 */
|
/* 25ms @8MHz */
|
||||||
#define TIMER_RELOAD (0xFF - 195)
|
#define TIMER_RELOAD (0xFF - 195)
|
||||||
|
|
||||||
@ -42,17 +68,12 @@
|
|||||||
|
|
||||||
#define TWI_ADDRESS 0x21
|
#define TWI_ADDRESS 0x21
|
||||||
|
|
||||||
#define APP_END 0x1C00
|
|
||||||
|
|
||||||
#define VERSION_STRING "TWIBOOT m88-v20"
|
|
||||||
#define SIGNATURE_BYTES { 0x1E, 0x93, 0x0A, 0x00 }
|
|
||||||
|
|
||||||
/* SLA+R */
|
/* SLA+R */
|
||||||
#define CMD_WAIT 0x00
|
#define CMD_WAIT 0x00
|
||||||
#define CMD_READ_VERSION 0x01
|
#define CMD_READ_VERSION 0x01
|
||||||
#define CMD_READ_MEMORY 0x02
|
#define CMD_READ_MEMORY 0x02
|
||||||
/* internal mappings */
|
/* internal mappings */
|
||||||
#define CMD_READ_SIGNATURE (0x10 | CMD_READ_MEMORY)
|
#define CMD_READ_CHIPINFO (0x10 | CMD_READ_MEMORY)
|
||||||
#define CMD_READ_FLASH (0x20 | CMD_READ_MEMORY)
|
#define CMD_READ_FLASH (0x20 | CMD_READ_MEMORY)
|
||||||
#define CMD_READ_EEPROM (0x30 | CMD_READ_MEMORY)
|
#define CMD_READ_EEPROM (0x30 | CMD_READ_MEMORY)
|
||||||
#define CMD_READ_PARAMETERS (0x40 | CMD_READ_MEMORY) /* only in APP */
|
#define CMD_READ_PARAMETERS (0x40 | CMD_READ_MEMORY) /* only in APP */
|
||||||
@ -63,7 +84,7 @@
|
|||||||
/* internal mappings */
|
/* internal mappings */
|
||||||
#define CMD_BOOT_BOOTLOADER (0x10 | CMD_SWITCH_APPLICATION) /* only in APP */
|
#define CMD_BOOT_BOOTLOADER (0x10 | CMD_SWITCH_APPLICATION) /* only in APP */
|
||||||
#define CMD_BOOT_APPLICATION (0x20 | CMD_SWITCH_APPLICATION)
|
#define CMD_BOOT_APPLICATION (0x20 | CMD_SWITCH_APPLICATION)
|
||||||
#define CMD_WRITE_SIGNATURE (0x10 | CMD_WRITE_MEMORY)
|
#define CMD_WRITE_CHIPINFO (0x10 | CMD_WRITE_MEMORY) /* invalid */
|
||||||
#define CMD_WRITE_FLASH (0x20 | CMD_WRITE_MEMORY)
|
#define CMD_WRITE_FLASH (0x20 | CMD_WRITE_MEMORY)
|
||||||
#define CMD_WRITE_EEPROM (0x30 | CMD_WRITE_MEMORY)
|
#define CMD_WRITE_EEPROM (0x30 | CMD_WRITE_MEMORY)
|
||||||
#define CMD_WRITE_PARAMETERS (0x40 | CMD_WRITE_MEMORY) /* only in APP */
|
#define CMD_WRITE_PARAMETERS (0x40 | CMD_WRITE_MEMORY) /* only in APP */
|
||||||
@ -73,7 +94,7 @@
|
|||||||
#define BOOTTYPE_APPLICATION 0x80
|
#define BOOTTYPE_APPLICATION 0x80
|
||||||
|
|
||||||
/* CMD_{READ|WRITE}_* parameter */
|
/* CMD_{READ|WRITE}_* parameter */
|
||||||
#define MEMTYPE_SIGNATURE 0x00
|
#define MEMTYPE_CHIPINFO 0x00
|
||||||
#define MEMTYPE_FLASH 0x01
|
#define MEMTYPE_FLASH 0x01
|
||||||
#define MEMTYPE_EEPROM 0x02
|
#define MEMTYPE_EEPROM 0x02
|
||||||
#define MEMTYPE_PARAMETERS 0x03 /* only in APP */
|
#define MEMTYPE_PARAMETERS 0x03 /* only in APP */
|
||||||
@ -92,7 +113,7 @@
|
|||||||
* - start application
|
* - start application
|
||||||
* SLA+W, 0x01, 0x80, STO
|
* SLA+W, 0x01, 0x80, STO
|
||||||
*
|
*
|
||||||
* - read signature bytes
|
* - read chip info: 3byte signature, 1byte page size, 2byte flash size, 2byte eeprom size
|
||||||
* SLA+W, 0x02, 0x00, SLA+R, {4 bytes}, STO
|
* SLA+W, 0x02, 0x00, SLA+R, {4 bytes}, STO
|
||||||
*
|
*
|
||||||
* - read one (or more) flash bytes
|
* - read one (or more) flash bytes
|
||||||
@ -109,7 +130,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const static uint8_t info[16] = VERSION_STRING;
|
const static uint8_t info[16] = VERSION_STRING;
|
||||||
const static uint8_t signature[4] = SIGNATURE_BYTES;
|
const static uint8_t chipinfo[8] = {
|
||||||
|
SIGNATURE_BYTES,
|
||||||
|
|
||||||
|
SPM_PAGESIZE,
|
||||||
|
|
||||||
|
(APP_END >> 8) & 0xFF,
|
||||||
|
APP_END & 0xFF,
|
||||||
|
|
||||||
|
(E2END >> 8 & 0xFF),
|
||||||
|
E2END & 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
/* wait 40 * 25ms = 1s */
|
/* wait 40 * 25ms = 1s */
|
||||||
static uint8_t boot_timeout = TIMEOUT;
|
static uint8_t boot_timeout = TIMEOUT;
|
||||||
@ -160,9 +191,13 @@ static void write_eeprom_byte(uint8_t val)
|
|||||||
EEARH = (addr >> 8);
|
EEARH = (addr >> 8);
|
||||||
EEDR = val;
|
EEDR = val;
|
||||||
addr++;
|
addr++;
|
||||||
|
#if defined (__AVR_ATmega8__)
|
||||||
|
EECR |= (1<<EEMWE);
|
||||||
|
EECR |= (1<<EEWE);
|
||||||
|
#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__)
|
||||||
EECR |= (1<<EEMPE);
|
EECR |= (1<<EEMPE);
|
||||||
EECR |= (1<<EEPE);
|
EECR |= (1<<EEPE);
|
||||||
|
#endif
|
||||||
eeprom_busy_wait();
|
eeprom_busy_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +251,8 @@ ISR(TWI_vect)
|
|||||||
|
|
||||||
case CMD_WRITE_MEMORY:
|
case CMD_WRITE_MEMORY:
|
||||||
bcnt++;
|
bcnt++;
|
||||||
if (data == MEMTYPE_SIGNATURE) {
|
if (data == MEMTYPE_CHIPINFO) {
|
||||||
cmd = CMD_WRITE_SIGNATURE;
|
cmd = CMD_WRITE_CHIPINFO;
|
||||||
|
|
||||||
} else if (data == MEMTYPE_FLASH) {
|
} else if (data == MEMTYPE_FLASH) {
|
||||||
cmd = CMD_WRITE_FLASH;
|
cmd = CMD_WRITE_FLASH;
|
||||||
@ -229,6 +264,10 @@ ISR(TWI_vect)
|
|||||||
ack = (0<<TWEA);
|
ack = (0<<TWEA);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ack = (0<<TWEA);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -255,6 +294,10 @@ ISR(TWI_vect)
|
|||||||
write_eeprom_byte(data);
|
write_eeprom_byte(data);
|
||||||
bcnt++;
|
bcnt++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ack = (0<<TWEA);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -278,9 +321,9 @@ ISR(TWI_vect)
|
|||||||
bcnt %= sizeof(info);
|
bcnt %= sizeof(info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_SIGNATURE:
|
case CMD_READ_CHIPINFO:
|
||||||
data = signature[bcnt++];
|
data = chipinfo[bcnt++];
|
||||||
bcnt %= sizeof(signature);
|
bcnt %= sizeof(chipinfo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_FLASH:
|
case CMD_READ_FLASH:
|
||||||
@ -332,13 +375,14 @@ ISR(TIMER0_OVF_vect)
|
|||||||
cmd = CMD_BOOT_APPLICATION;
|
cmd = CMD_BOOT_APPLICATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*jump_to_app)(void) = 0x0000;
|
static void (*jump_to_app)(void) __attribute__ ((noreturn)) = 0x0000;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For newer devices (mega88) the watchdog timer remains active even after a
|
* For newer devices (mega88) the watchdog timer remains active even after a
|
||||||
* system reset. So disable it as soon as possible.
|
* system reset. So disable it as soon as possible.
|
||||||
* automagically called on startup
|
* automagically called on startup
|
||||||
*/
|
*/
|
||||||
|
#if defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__)
|
||||||
void disable_wdt_timer(void) __attribute__((naked, section(".init3")));
|
void disable_wdt_timer(void) __attribute__((naked, section(".init3")));
|
||||||
void disable_wdt_timer(void)
|
void disable_wdt_timer(void)
|
||||||
{
|
{
|
||||||
@ -346,7 +390,9 @@ void disable_wdt_timer(void)
|
|||||||
WDTCSR = (1<<WDCE) | (1<<WDE);
|
WDTCSR = (1<<WDCE) | (1<<WDE);
|
||||||
WDTCSR = (0<<WDE);
|
WDTCSR = (0<<WDE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(void) __attribute__ ((noreturn));
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
DDRB = LED_GN | LED_RT;
|
DDRB = LED_GN | LED_RT;
|
||||||
@ -356,11 +402,14 @@ int main(void)
|
|||||||
MCUCR = (1<<IVCE);
|
MCUCR = (1<<IVCE);
|
||||||
MCUCR = (1<<IVSEL);
|
MCUCR = (1<<IVSEL);
|
||||||
|
|
||||||
/* timer0: running with F_CPU/1024 */
|
/* timer0: running with F_CPU/1024, OVF interrupt */
|
||||||
|
#if defined (__AVR_ATmega8__)
|
||||||
|
TCCR0 = (1<<CS02) | (1<<CS00);
|
||||||
|
TIMSK = (1<<TOIE0);
|
||||||
|
#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__)
|
||||||
TCCR0B = (1<<CS02) | (1<<CS00);
|
TCCR0B = (1<<CS02) | (1<<CS00);
|
||||||
|
|
||||||
/* enable timer0 OVF interrupt */
|
|
||||||
TIMSK0 = (1<<TOIE0);
|
TIMSK0 = (1<<TOIE0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TWI init: set address, auto ACKs with interrupts */
|
/* TWI init: set address, auto ACKs with interrupts */
|
||||||
TWAR = (TWI_ADDRESS<<1);
|
TWAR = (TWI_ADDRESS<<1);
|
||||||
@ -374,8 +423,13 @@ int main(void)
|
|||||||
TWCR = 0x00;
|
TWCR = 0x00;
|
||||||
|
|
||||||
/* disable timer0 */
|
/* disable timer0 */
|
||||||
|
#if defined (__AVR_ATmega8__)
|
||||||
|
TCCR0 = 0x00;
|
||||||
|
TIMSK = 0x00;
|
||||||
|
#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__)
|
||||||
TIMSK0 = 0x00;
|
TIMSK0 = 0x00;
|
||||||
TCCR0B = 0x00;
|
TCCR0B = 0x00;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* move interrupt vectors back to application */
|
/* move interrupt vectors back to application */
|
||||||
MCUCR = (1<<IVCE);
|
MCUCR = (1<<IVCE);
|
||||||
@ -383,10 +437,5 @@ int main(void)
|
|||||||
|
|
||||||
PORTB = 0x00;
|
PORTB = 0x00;
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
_delay_ms(10);
|
|
||||||
|
|
||||||
jump_to_app();
|
jump_to_app();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user