#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make flash = Download the hex file to the device, using avrdude.
#                Please customize the avrdude settings below first!
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
#                   bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------

# MCU name: attiny13a attiny2313a attiny85 atmega8 atmega328p atmega128a
MCU = attiny13a

# Processor frequency.
#     This will define a symbol, F_CPU, in all source code files equal to the 
#     processor frequency. You can then use this symbol in your source code to 
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
#     automatically to create a 32-bit value in your source code.
F_CPU = 9600000

# Target file name (without extension).
TARGET = 1hz

# Output format. (can be srec, ihex, binary)
FORMAT = ihex

# List C source files here. (C dependencies are automatically generated.)
CSRC = 1hz.c

# List Assembler source files here.
#     Make them always end in a capital .S.  Files ending in a lowercase .s
#     will not be considered source files but generated files (assembler
#     output from the compiler), and will be deleted upon "make clean"!
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
#     it will preserve the spelling of the filenames, and gcc itself does
#     care about how the name is spelled on its command-line.
ASRC = 

# Optimization level, can be [0, 1, 2, 3, s]. 
#     0 = turn off optimization. s = optimize for size.
#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s

# Debugging format.
#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
#     AVR Studio 4.10 requires dwarf-2.
#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2


# List any extra directories to look for include files here.
#     Each directory must be seperated by a space.
#     Use forward slashes for directory separators.
#     For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =

# Compiler flag to set the C Standard level.
#     c89   = "ANSI" C
#     gnu89 = c89 plus GCC extensions
#     c99   = ISO C99 standard (not yet fully implemented)
#     gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99

# Place -I options here
CINCS =

WORKINGDIR = build

#---------------- Compiler Options ----------------
#  -g*:          generate debugging information
#  -O*:          optimization level
#  -f...:        tuning, see GCC manual and avr-libc documentation
#  -Wall...:     warning level
#  -Wa,...:      tell GCC to pass this to the assembler.
#    -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += -DF_CPU=$(F_CPU)uL $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections
CFLAGS += -Wall
# -flto
CFLAGS += -Wa,-adhlns=$(patsubst %.c,$(WORKINGDIR)/%.lst,$<)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)


#---------------- Assembler Options ----------------
#  -Wa,...:   tell GCC to pass this to the assembler.
#  -ahlms:    create listing
#  -gstabs:   have the assembler create line number information; note that
#             for use in COFF files, additional information about filenames
#             and function names needs to be present in the assembler source
#             files -- see avr-libc docs [FIXME: not yet described there]
#  -listing-cont-lines: Sets the maximum number of continuation lines of hex 
#       dump that will be displayed for a given single line of source input.
ASFLAGS = -Wa,-adhlns=$(patsubst %.S,$(WORKINGDIR)/%.lst,$<),-gstabs,--listing-cont-lines=100


#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB = 
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)


# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB = 
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)


MATH_LIB = -lm


#---------------- Linker Options ----------------
#  -Wl,...:     tell GCC to pass this to linker.
#    -Map:      create map file
#    --cref:    add cross reference to  map file
LDFLAGS = -Wl,-Map=$(WORKINGDIR)/$(TARGET).map,--gc-sections,--print-gc-sections,--cref
#,-flto
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)


## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings



#---------------- Programming Options (avrdude) ----------------

ifeq ($(MCU),attiny13a)
AVRDUDE_MCU = t13
else ifeq ($(MCU),attiny2313a)
AVRDUDE_MCU = t2313
else ifeq ($(MCU),attiny85)
AVRDUDE_MCU = t85
else ifeq ($(MCU),atmega8)
AVRDUDE_MCU = m8
else ifeq ($(MCU),atmega328p)
AVRDUDE_MCU = m328p
else
AVRDUDE_MCU = 
endif

# Programming hardware
# Type: avrdude -c ?
#       avrdude -p ?
# to get a full listing.
#
# Valid programmers: arduino usbtiny usbasp

AVRDUDE_PROGRAMMER=usbasp
#AVRDUDE_PORT=COM3
#AVRDUDE_BAUDRATE=115200

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex

ifeq ($(AVRDUDE_PROGRAMMER),arduino)
AVRDUDE_WRITE_EEPROM =
else
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
endif 

# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y

# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V

# Increase verbosity level.  Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
#AVRDUDE_VERBOSE = -v

# Disable auto erase for flash memory
#AVRDUDE_NOEEPAUTOERASE = -D

AVRDUDE_FLAGS  = -c $(AVRDUDE_PROGRAMMER) -p $(AVRDUDE_MCU)
ifeq ($(AVRDUDE_PROGRAMMER),arduino)
AVRDUDE_FLAGS += -P $(AVRDUDE_PORT) -b $(AVRDUDE_BAUDRATE)
endif
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
AVRDUDE_FLAGS += $(AVRDUDE_NOEEPAUTOERASE)


#============================================================================

# Define programs and commands.
CC = @avr-gcc
OBJCOPY = @avr-objcopy
OBJDUMP = @avr-objdump
SIZE = @avr-size
AVRDUDE = @avrdude
REMOVE = @rm -f


# Define Messages
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:


# Define all object files.
OBJ = $(patsubst %.c,$(WORKINGDIR)/%.o,$(CSRC)) $(patsubst %.s,$(WORKINGDIR)/%.o,$(ASRC))

# Define all listing files.
LST = $(patsubst %.c,$(WORKINGDIR)/%.lst,$(CSRC)) $(patsubst %.s,$(WORKINGDIR)/%.lst,$(ASRC))

# Compiler flags to generate dependency files.
GENDEPFLAGS = -MD -MP -MF $(WORKINGDIR)/$(@F).d


# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)


# Default target.
all: gccversion build size

# Display compiler version information.
# $(shell mkdir $(WORKINGDIR)>NUL)
gccversion: 
	$(CC) -dumpversion
	@$(shell mkdir build)


size: $(WORKINGDIR)/${TARGET}.elf
#	$(SIZE) -C --mcu=${MCU} $<
	$(SIZE) $<


build: elf lss hex eep

elf: $(WORKINGDIR)/$(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(WORKINGDIR)/$(TARGET).lss 

.SECONDARY : $(WORKINGDIR)/$(TARGET).elf
.PRECIOUS : $(OBJ)

# Create preprocessed source for use in sending a bug report.
%.i: %.c
	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@


# Create assembler file from C source files.
%.s : %.c
	$(CC) -S $(ALL_CFLAGS) $< -o $@


# Assemble: create object files from assembler source files.
$(WORKINGDIR)/%.o: %.S
	@echo $(MSG_ASSEMBLING) $<
	$(CC) -c $(ALL_ASFLAGS) $< -o $@

# Compile: create object files from C source files.
$(WORKINGDIR)/%.o: %.c
	@echo $(MSG_COMPILING) $<
	$(CC) -c $(ALL_CFLAGS) $< -o $@


# Link: create ELF output file from object files.

$(WORKINGDIR)/$(TARGET).elf: $(OBJ)
	@echo $(MSG_LINKING) $@
	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)


# Create extended listing file from ELF output file.
%.lss: %.elf
	@echo $(MSG_EXTENDED_LISTING) $@
	$(OBJDUMP) -h -S $< > $@


# Create final output files (.hex, .eep) from ELF output file.

$(TARGET).hex: $(WORKINGDIR)/$(TARGET).elf
	@echo $(MSG_FLASH) $@
	$(OBJCOPY) -O $(FORMAT) $(HEX_FLASH_FLAGS) $< $@


$(TARGET).eep: $(WORKINGDIR)/$(TARGET).elf
	@echo $(MSG_EEPROM) $@
	$(OBJCOPY) $(HEX_EEPROM_FLAGS) -O $(FORMAT) $< $@


# Program the device.  
flash: $(TARGET).hex $(TARGET).eep
	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)

# Read EEPROM
readeeprom:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U eeprom:r:eeprom_dump.bin:r

# Read calibration data
readcal:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U calibration:r:cal_dump.bin:r

#tiny13a
# Int. RC Osc. 9.6 MHz, Start-up time 14 CK + 64 msec, SPIEN enabled, Preserve EEPROM memory through the Chip Erase cycle
fuses13a96:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:0x3A:m
# -U hfuse:w:0xFF:m -U lock:w:0xFF:m

# Int. RC Osc. 4.8 MHz, Start-up time 14 CK + 64 msec, SPIEN enabled, Preserve EEPROM memory through the Chip Erase cycle
fuses13a48:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:0x39:m
# -U hfuse:w:0xFF:m -U lock:w:0xFF:m

# Int. RC Osc. 1.2 MHz, Start-up time 14 CK + 64 msec, SPIEN enabled, Preserve EEPROM memory through the Chip Erase cycle
fuses13a12:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:0x2A:m
# -U hfuse:w:0xFF:m -U lock:w:0xFF:m

# Int. RC Osc. 0.6 MHz, Start-up time 14 CK + 64 msec, SPIEN enabled, Preserve EEPROM memory through the Chip Erase cycle
fuses13a06:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:0x29:m
# -U hfuse:w:0xFF:m -U lock:w:0xFF:m

# Int. RC Osc. 128 kHz, Start-up time 14 CK + 64 msec, SPIEN enabled, Preserve EEPROM memory through the Chip Erase cycle
fuses13a128:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:0x3B:m
# -U hfuse:w:0xFF:m -U lock:w:0xFF:m

# Ext. Clock, Start-up time 14 CK + 64 msec, SPIEN enabled, Preserve EEPROM memory through the Chip Erase cycle
fuses13ext:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:0x38:m
# -U hfuse:w:0xFF:m -U lock:w:0xFF:m

# Ext. Clock Divide by 8, Start-up time 14 CK + 64 msec, SPIEN enabled, Preserve EEPROM memory through the Chip Erase cycle
fuses13ext8:
	$(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:0x28:m
# -U hfuse:w:0xFF:m -U lock:w:0xFF:m

# Target: clean project.
clean:
	@echo $(MSG_CLEANING) $(TARGET).hex
	$(REMOVE) $(TARGET).hex
	@echo $(MSG_CLEANING) $(TARGET).eep
	$(REMOVE) $(TARGET).eep
	@echo $(MSG_CLEANING) $(WORKINGDIR)/$(TARGET).elf
	$(REMOVE) $(WORKINGDIR)/$(TARGET).elf
	@echo $(MSG_CLEANING) $(WORKINGDIR)/$(TARGET).map
	$(REMOVE) $(WORKINGDIR)/$(TARGET).map
	@echo $(MSG_CLEANING) $(WORKINGDIR)/$(TARGET).lss
	$(REMOVE) $(WORKINGDIR)/$(TARGET).lss
	@echo $(MSG_CLEANING) $(OBJ)
	$(REMOVE) $(OBJ)
	@echo $(MSG_CLEANING) $(LST)
	$(REMOVE) $(LST)
	@echo $(MSG_CLEANING) $(OBJ:.o=.s)
	$(REMOVE) $(OBJ:.o=.s)
	@echo $(MSG_CLEANING) $(OBJ:.o=.o.d)
	$(REMOVE) $(OBJ:.o=.o.d)


# Listing of phony targets.
.PHONY : all gccversion build size clean flash fuses
