91 lines
3.4 KiB
CMake
91 lines
3.4 KiB
CMake
cmake_minimum_required(VERSION 3.10)
|
|
|
|
# Set the toolchain file BEFORE the project() call
|
|
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/.cmake/avr-gcc.cmake)
|
|
|
|
project(AVRDxBlink C)
|
|
|
|
# Configurable variables
|
|
set(MCU "avr128db28" CACHE STRING "Target Microcontroller")
|
|
set(F_CPU "20000000" CACHE STRING "Clock frequency in Hz")
|
|
set(DEVICE_PACK_DIR "/opt/toolchains/microchip/device-packs/AVRDx" CACHE STRING "Path to Device Packs")
|
|
set(PROGRAMMER "pickit4_updi" CACHE STRING "Programmer for avrdude") # often pickit4_updi is the right name for UPDI
|
|
|
|
# Include Device Pack
|
|
# -B instructs gcc to look for device-specific binaries/specs in this folder
|
|
# -I adds the device-specific headers
|
|
set(AVR_PACK_FLAGS "-B${DEVICE_PACK_DIR}/gcc/dev/${MCU} -I${DEVICE_PACK_DIR}/include")
|
|
|
|
# Clangd (and therefore eglot/lsp) often does not know about the AVR Device Pack.
|
|
# We define the corresponding macro manually so <avr/io.h> works.
|
|
string(TOUPPER "${MCU}" MCU_UPPER)
|
|
set(AVR_MACRO "-D__AVR_${MCU_UPPER}__ -D__AVR_DEVICE_NAME__=${MCU}")
|
|
|
|
# If the MCU is a modern AVR (Dx/Ex) or XMEGA, avr-gcc defines __AVR_XMEGA__ internally.
|
|
# Clangd needs this so <avr/fuse.h> uses NVM_FUSES_t instead of the old __fuse_t.
|
|
if(MCU MATCHES "^avr[0-9]+" OR MCU MATCHES "^atxmega")
|
|
set(AVR_MACRO "${AVR_MACRO} -D__AVR_XMEGA__")
|
|
endif()
|
|
|
|
# Set Build Type (Default: Release)
|
|
if(NOT CMAKE_BUILD_TYPE)
|
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type: Debug or Release" FORCE)
|
|
endif()
|
|
|
|
# General Compiler Flags (for all build types)
|
|
# -ffunction-sections and -fdata-sections allow the linker to remove unused code
|
|
set(COMMON_FLAGS "-mmcu=${MCU} ${AVR_MACRO} -DF_CPU=${F_CPU}UL -Wall -Wstrict-prototypes -std=gnu99 ${AVR_PACK_FLAGS} -ffunction-sections -fdata-sections")
|
|
set(CMAKE_C_FLAGS "${COMMON_FLAGS}")
|
|
|
|
# Specific flags for Debug and Release
|
|
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG")
|
|
set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG")
|
|
|
|
# Linker Flags: -Wl,--gc-sections removes everything that is not needed
|
|
set(CMAKE_EXE_LINKER_FLAGS "-mmcu=${MCU} ${AVR_PACK_FLAGS} -Wl,--gc-sections")
|
|
|
|
# Generate compile_commands.json for Emacs/clangd (code completion)
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
|
# Source and Header files
|
|
file(GLOB_RECURSE SRC_FILES src/*.c)
|
|
list(FILTER SRC_FILES EXCLUDE REGEX "/[.]#") # Ignore Emacs lock files like .#main.c
|
|
include_directories(inc)
|
|
|
|
# Generate Executable (.elf)
|
|
add_executable(${PROJECT_NAME}.elf ${SRC_FILES})
|
|
|
|
# Display size after build (Hex file is obsolete thanks to ELF support)
|
|
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
|
|
COMMAND avr-size --format=avr --mcu=${MCU} ${PROJECT_NAME}.elf
|
|
)
|
|
|
|
# --- Avrdude Programming Targets ---
|
|
|
|
# F6: Program Flash only
|
|
add_custom_target(flash
|
|
COMMAND avrdude -c ${PROGRAMMER} -p ${MCU} -U flash:w:${PROJECT_NAME}.elf:e
|
|
DEPENDS ${PROJECT_NAME}.elf
|
|
COMMENT "Flashing program code (Flash)..."
|
|
)
|
|
|
|
# C-F6: Program Flash and EEPROM
|
|
add_custom_target(flash_eeprom
|
|
COMMAND avrdude -c ${PROGRAMMER} -p ${MCU} -U flash:w:${PROJECT_NAME}.elf:e -U eeprom:w:${PROJECT_NAME}.elf:e
|
|
DEPENDS ${PROJECT_NAME}.elf
|
|
COMMENT "Flashing program code and EEPROM..."
|
|
)
|
|
|
|
# F7: Read Fuses
|
|
add_custom_target(read_fuses
|
|
COMMAND avrdude -c ${PROGRAMMER} -p ${MCU} -U fuses:r:-:h
|
|
COMMENT "Reading fuses..."
|
|
)
|
|
|
|
# C-F7: Program Fuses only
|
|
add_custom_target(flash_fuses
|
|
COMMAND avrdude -c ${PROGRAMMER} -p ${MCU} -U fuses:w:${PROJECT_NAME}.elf:e
|
|
DEPENDS ${PROJECT_NAME}.elf
|
|
COMMENT "Programming fuses from ELF file..."
|
|
)
|