###############################################################################
# Makefile for STM32F103C8T6 Self-Balancing Car
# Requires: arm-none-eabi-gcc, stlink, openocd
# Target: Blue Pill (STM32F103C8T6, 64KB Flash, 20KB RAM)
###############################################################################

# Project
TARGET = self_balancing_car

# Toolchain
PREFIX  = arm-none-eabi-
CC      = $(PREFIX)gcc
OBJCOPY = $(PREFIX)objcopy
SIZE    = $(PREFIX)size
GDB     = $(PREFIX)gdb

# Source files
C_SOURCES = \
Core/Src/main.c \
Core/Src/mpu6050.c \
Core/Src/motor.c \
Core/Src/encoder.c \
Core/Src/pid.c \
Core/Src/balancer.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c

# Assembly startup
ASM_SOURCES = \
Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s

# Includes
INCLUDES = \
-ICore/Inc \
-IDrivers/STM32F1xx_HAL_Driver/Inc \
-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \
-IDrivers/CMSIS/Include

# Compiler flags
MCU_FLAGS = -mcpu=cortex-m3 -mthumb
OPT_FLAGS = -Os -ffunction-sections -fdata-sections
CFLAGS   = $(MCU_FLAGS) $(OPT_FLAGS) $(INCLUDES) -DSTM32F103xB
CFLAGS  += -Wall -Wextra -Wno-unused-parameter
CFLAGS  += -g

# Linker flags
LSCRIPT  = Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/linker/stm32f103xb_flash.ld
LDFLAGS  = $(MCU_FLAGS) -T$(LSCRIPT) -Wl,--gc-sections -u _printf_float -lm

# Objects
OBJECTS = $(C_SOURCES:.c=.o) $(ASM_SOURCES:.s=.o)

# Default target
all: $(TARGET).elf $(TARGET).bin size

# Link
$(TARGET).elf: $(OBJECTS)
	$(CC) $^ $(LDFLAGS) -o $@

# Binary
$(TARGET).bin: $(TARGET).elf
	$(OBJCOPY) -O binary $< $@

# Compile C
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# Compile assembly
%.o: %.s
	$(CC) $(MCU_FLAGS) -c $< -o $@

# Show size
size: $(TARGET).elf
	$(SIZE) $(TARGET).elf

# Flash via ST-Link
flash: $(TARGET).bin
	st-flash write $(TARGET).bin 0x08000000

# Debug via OpenOCD + GDB
debug: $(TARGET).elf
	openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg &
	sleep 1
	$(GDB) $(TARGET).elf -ex "target remote localhost:3333" -ex "mon reset halt"

# Clean
clean:
	rm -f $(OBJECTS) $(TARGET).elf $(TARGET).bin

# Dependencies
-include $(OBJECTS:.o=.d)

.PHONY: all clean flash debug size
