diff --git a/avrprog_boot.pnproj b/avrprog_boot.pnproj index 03620e0..1777f3c 100644 --- a/avrprog_boot.pnproj +++ b/avrprog_boot.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/chipdef.h b/chipdef.h index a6197fd..afbf5f9 100644 --- a/chipdef.h +++ b/chipdef.h @@ -25,12 +25,24 @@ typedef uint8_t pagebuf_t; #elif defined(__AVR_ATmega16__) #include "mega16.h" +#elif defined(__AVR_ATmega162__) +#include "mega162.h" + #elif defined(__AVR_ATmega8__) #include "mega8.h" #elif defined(__AVR_ATmega32__) #include "mega32.h" +#elif defined(__AVR_ATmega324P__) +#include "mega324p.h" + +#elif defined(__AVR_ATmega644__) +#include "mega644.h" + +#elif defined(__AVR_ATmega644P__) +#include "mega644p.h" + #elif defined(__AVR_ATmega128__) #include "mega128.h" diff --git a/main b/main new file mode 100644 index 0000000..c4b93b7 Binary files /dev/null and b/main differ diff --git a/main.c b/main.c index e1a726c..02fc23e 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,8 @@ /***************************************************************************** * * AVRPROG compatible boot-loader -* Version : 0.80beta3 (May 2006) -* Compiler : avr-gcc 3.4.6 / avr-libc 1.4.4 +* Version : 0.83 (Apr. 2008) +* Compiler : avr-gcc 4.1.2 / avr-libc 1.4.6 * size : depends on features and startup ( minmal features < 512 words) * by : Martin Thomas, Kaiserslautern, Germany * eversmith@heizung-thomas.de @@ -11,33 +11,27 @@ * - Bjoern Riemer * - Olaf Rempel * -* License : Copyright (c) 2006 Martin Thomas +* License : Copyright (c) 2006-2008 M. Thomas, U. Bonnes, O. Rempel * Free to use. You have to mention the copyright * owners in source-code and documentation of derived -* work. No warranty! +* work. No warranty! (Yes, you can insert the BSD +* license here) * -* Tested with ATmega8, ATmega16, ATmega32, ATmega128, AT90CAN128 +* Tested with ATmega8, ATmega16, ATmega162, ATmega32, ATmega324P, +* ATmega644, ATmega644P, ATmega128, AT90CAN128 * * - Initial versions have been based on the Butterfly bootloader-code * by Atmel Corporation (Authors: BBrandal, PKastnes, ARodland, LHM) * **************************************************************************** * -* See the makefile for information how to adapt the linker-settings to -* the selected Boot Size (BOOTSIZE=xxxx), the AVR clock-frequency and the -* MCU-type in +* See the makefile and readme.txt for information on how to adapt +* the linker-settings to the selected Boot Size (BOOTSIZE=xxxx) and +* the MCU-type. Other configurations futher down in this file. * * With BOOT_SIMPLE, minimal features and discarded int-vectors -* this bootloader has -* 0x2CA - atmega8 -* 0x308 - atmega16 -* 0x322 - atmega169 -* 0x308 - atmega32 -* 0x34C - atmega128 -* 0x352 - at90can128 -* bytes size and should fit into a 512 word (0x400 byte) bootloader-section. -* The above values depend on the compiler-version and may differ from -* your results. +* this bootloader has should fit into a a 512 word (1024, 0x400 bytes) +* bootloader-section. * ****************************************************************************/ /* @@ -46,6 +40,7 @@ - __bad_interrupt still linked even with modified linker-scripts which needs a default-handler, "wasted": 3 words for AVR5 (>8kB), 2 words for AVR4 + - Check watchdog-disable-function in avr-libc. */ // tabsize: 4 @@ -63,7 +58,7 @@ /* use "Double Speed Operation" */ //#define UART_DOUBLESPEED -/* use second UART on mega128 / can128 */ +/* use second UART on mega128 / can128 / mega162 / mega324p / mega644p */ //#define UART_USE_SECOND /* Device-Type: @@ -71,16 +66,27 @@ which is the "correct" value for a bootloader. avrdude may only detect the part-code for ISP */ #define DEVTYPE DEVTYPE_BOOT -//#define DEVTYPE DEVTYPE_ISP +// #define DEVTYPE DEVTYPE_ISP /* * Pin "STARTPIN" on port "STARTPORT" in this port has to grounded * (active low) to start the bootloader */ -#define BLPORT PORTB -#define BLDDR DDRB -#define BLPIN PINB -#define BLPNUM PINB0 +#define BLPORT PORTC +#define BLDDR DDRC +#define BLPIN PINC +#define BLPNUM PINC7 + +/* + * Define if Watchdog-Timer should be disable at startup + */ +#define DISABLE_WDT_AT_STARTUP + +/* + * Watchdog-reset is issued at exit + * define the timeout-value here (see avr-libc manual) + */ +#define EXIT_WDT_TIME WDTO_250MS /* * Select startup-mode @@ -108,8 +114,8 @@ /* character to start the bootloader in mode START_WAIT */ #define START_WAIT_UARTCHAR 'S' -/* wait 1s in START_WAIT mode (10ms steps) */ -#define WAIT_VALUE 100 +/* wait-time for START_WAIT mode ( t = WAIT_TIME * 10ms ) */ +#define WAIT_VALUE 100 /* here: 100*10ms = 1000ms = 1sec */ /* * enable/disable readout of fuse and lock-bits @@ -118,7 +124,7 @@ */ //#define ENABLEREADFUSELOCK - /* enable/disable write of lock-bits +/* enable/disable write of lock-bits * WARNING: lock-bits can not be reseted by bootloader (as far as I know) * Only protection no unprotection, "chip erase" from bootloader only * clears the flash but does no real "chip erase" (this is not possible @@ -127,6 +133,13 @@ */ //#define WRITELOCKBITS +/* + * define the following if the bootloader should not output + * itself at flash read (will fake an empty boot-section) + */ +#define READ_PROTECT_BOOTLOADER + + #define VERSION_HIGH '0' #define VERSION_LOW '8' @@ -141,8 +154,9 @@ #include #include #include -// #include -#include +#include +#include +#include #include "chipdef.h" @@ -184,8 +198,9 @@ static inline void recvBuffer(pagebuf_t size) pagebuf_t cnt; uint8_t *tmp = gBuffer; - for (cnt = 0; cnt < sizeof(gBuffer); cnt++) + for (cnt = 0; cnt < sizeof(gBuffer); cnt++) { *tmp++ = (cnt < size) ? recvchar() : 0xFF; + } } static inline uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size) @@ -206,7 +221,7 @@ static inline uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size) boot_page_write(pagestart); boot_spm_busy_wait(); - boot_rww_enable(); // Re-enable the RWW section + boot_rww_enable(); // Re-enable the RWW section return baddr>>1; } @@ -216,18 +231,13 @@ static inline uint16_t writeEEpromPage(uint16_t address, pagebuf_t size) uint8_t *tmp = gBuffer; do { - EEARL = address; // Setup EEPROM address - EEARH = (address >> 8); - EEDR = *tmp++; + eeprom_write_byte( (uint8_t*)address, *tmp++ ); address++; // Select next byte - - EECR |= (1<> 8)); // send MSB baddr += 2; // Select next word in memory size -= 2; // Subtract two bytes from number of bytes to read - } while (size); // Repeat until all block has been read + } while (size); // Repeat until block has been read return baddr>>1; } @@ -254,15 +279,10 @@ static inline uint16_t readFlashPage(uint16_t waddr, pagebuf_t size) static inline uint16_t readEEpromPage(uint16_t address, pagebuf_t size) { do { - EEARL = address; // Setup EEPROM address - EEARH = (address >> 8); - EECR |= (1< UART_STATUS = (1< +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_COMPILING_CPP = Compiling C++: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + + + + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT = $(OBJCOPY) --debugging +COFFCONVERT += --change-section-address .data-0x800000 +COFFCONVERT += --change-section-address .bss-0x800000 +COFFCONVERT += --change-section-address .noinit-0x800000 +COFFCONVERT += --change-section-address .eeprom-0x810000 + + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create object files from C++ source files. +$(OBJDIR)/%.o : %.cpp + @echo + @echo $(MSG_COMPILING_CPP) $< + $(CC) -c $(ALL_CPPFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C++ source files. +%.s : %.cpp + $(CC) -S $(ALL_CPPFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +$(OBJDIR)/%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + +# Create preprocessed source for use in sending a bug report. +%.i : %.c + $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ + + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) $(SRC:.c=.i) + $(REMOVEDIR) .dep + + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program debug gdb-config diff --git a/testapp/testapp.c b/testapp/testapp.c new file mode 100644 index 0000000..4174cf2 --- /dev/null +++ b/testapp/testapp.c @@ -0,0 +1,62 @@ +// Martin Thomas 4/2008 + +#include +#include +#include +#include + +#define LED_PORT PORTB +#define LED_DDR DDRB +#define LED_BIT PB2 + +#define BT_PORT PORTC +#define BT_DDR DDRC +#define BT_PIN PINC +#define BT_BIT PC7 + +static inline void my_wdt_off(void) +{ + cli(); + wdt_reset(); + /* Clear WDRF in MCUSR */ + MCUSR &= ~(1<