#----------------------------------------------------------------------------
# Makefile для демонстрационного проекта (матрица 16x32, ATmega128)
#
# Основан на старом шаблоне (WinAVR + avr-coff-objcopy для VMLAB).
# Отличия:
#  - Явный список SRC (без "пылесоса" *.c).
#  - Нет цели depend, Makefile не переписывает себя.
#  - Авто-зависимости через -MMD -MP -MF .dep/... и -include.
#  - Сохранён coff с параметрами для VMLAB.
#  - Два листинга: demo.lss (байты, avr-objdump) и
#    demo_vmlab.lss (слова, через convert_lss_addrs.py).
#
# Использование:
#   make            - собрать всё (elf hex eep coff sym lss)
#   make lss        - только листинги (байты + слова)
#   make coff       - COFF для VMLAB
#   make flash      - прошить demo.hex
#   make clean      - удалить временные файлы
#   make erase      - стереть прошивку
#----------------------------------------------------------------------------

# ==================== НАСТРОЙКИ ПРОЕКТА ====================

MCU = atmega128
F_CPU = 11059200
FORMAT = ihex
OPT = s
DEBUG = stabs
CSTANDARD = -std=gnu99

# Имя проекта (для демо - demo).
TARGET = demo

# Явный список исходных файлов (без "пылесоса").
SRC = demo_rect.c \
      matrix.c
ASRC =

# ==================== ПРОГРАММАТОР ====================

AVRDUDE_PROGRAMMER = usbasp
AVRDUDE_PORT = usb

# ==================== КОМПИЛЯТОР И УТИЛИТЫ ====================

CC = avr-gcc
OBJCOPY = avr-objcopy
COFFCOPY = avr-coff-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
PYTHON = python3

# Скрипт перевода адресов байт -> слова для VMLAB.
CONVERT_LSS = convert_lss_addrs.py

# ==================== ФЛАГИ КОМПИЛЯЦИИ ====================

CDEFS = -DF_CPU=$(F_CPU)UL
CINCS =

CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes -pedantic
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CTUNING) $(CEXTRA)

ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs

# Генерация зависимостей: -MMD -MP -MF .dep/<obj>.d
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d

ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)

LDMAP = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS = $(LDMAP)

# ==================== ФАЙЛЫ ====================

OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
LST = $(SRC:.c=.lst) $(ASRC:.S=.lst)

# ==================== COFF ДЛЯ VMLAB (ВАЖНО!) ====================

COFFCONVERT = $(COFFCOPY) -v --debugging \
	--change-section-address .data-0x800000 \
	--change-section-address .bss-0x800000 \
	--change-section-address .noinit-0x800000 \
	--change-section-address .eeprom-0x810000

# ==================== ЦЕЛИ ====================

all: build

build: elf hex eep coff sym lss

elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss $(TARGET)_vmlab.lss
sym: $(TARGET).sym

# COFF для VMLAB (сохранены все хитрые параметры).
coff: $(TARGET).elf
	$(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof

flash: $(TARGET).hex
	$(AVRDUDE) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) -P $(AVRDUDE_PORT) \
		-U flash:w:$(TARGET).hex:i

erase:
	$(AVRDUDE) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) -P $(AVRDUDE_PORT) -e

clean:
	$(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \
	$(TARGET).map $(TARGET).sym $(TARGET).lss $(TARGET)_vmlab.lss \
	$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d)
	$(REMOVE) -r .dep

# ==================== ПРАВИЛА ====================

.SUFFIXES: .elf .hex .eep .lss .sym

.elf.hex:
	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@

.elf.eep:
	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@

# Листинг в байтах (avr-objdump).
.elf.lss:
	$(OBJDUMP) -h -S $< > $@

# Листинг в словах (для VMLAB), через convert_lss_addrs.py.
$(TARGET)_vmlab.lss: $(TARGET).lss
	$(PYTHON) $(CONVERT_LSS) $< -o $@

.elf.sym:
	$(NM) -n $< > $@

# Линковка (перед компиляцией создаём .dep).
$(TARGET).elf: $(OBJ)
	@mkdir -p .dep
	$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
	$(SIZE) $@

# Компиляция (с генерацией .dep).
.c.o:
	@mkdir -p .dep
	$(CC) -c $(ALL_CFLAGS) $< -o $@

.c.s:
	$(CC) -S $(ALL_CFLAGS) $< -o $@

.S.o:
	@mkdir -p .dep
	$(CC) -c $(ALL_ASFLAGS) $< -o $@

# Подключаем сгенерированные зависимости.
-include $(wildcard .dep/*.d)

.PHONY: all build elf hex eep lss sym coff flash erase clean
