cmake_minimum_required(VERSION 3.19)

set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/gcc-arm-none-eabi.cmake)

project(shmingo-HAL)
set(PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR})

enable_language(C ASM CXX)

set(MCU_FAMILY "STM32H7xx")
set(MCU_MODEL "STM32H753xx")

set(CPU_PARAMETERS
        -mcpu=cortex-m7
        -mfpu=fpv5-d16
        -mfloat-abi=hard
)

set(STARTUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/H753ZIT6/startup_stm32h753xx.S)
set(MCU_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/H753ZIT6/stm32h753zitx_flash.ld)

set(EXECUTABLE ${CMAKE_PROJECT_NAME})
enable_language(C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)

set(MX_INCLUDE_DIRECTORIES
        ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include
        ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include
)

set(PROJECT_INCLUDE_DIRECTORIES
        ${CMAKE_CURRENT_SOURCE_DIR}

        #[[

SHAL/Include/Peripheral/I2C
SHAL/Include/Peripheral/I2C/Reg
SHAL/Include/Peripheral/ADC
SHAL/Include/Peripheral/ADC/Reg
SHAL/Include/Peripheral/EXT
SHAL/Include/Peripheral/EXT/Reg
]]#
        SHAL/Include/Core/
        SHAL/Include/Peripheral/GPIO
        SHAL/Include/Peripheral/GPIO/Reg
        SHAL/Include/Peripheral/Timer
        SHAL/Include/Peripheral/Timer/Reg
        SHAL/Include/Peripheral/UART
        SHAL/Include/Peripheral/UART/Reg
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
)

file(GLOB_RECURSE PROJECT_SOURCES
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/Universal/*.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/Universal/*.c
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/*.c
#${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/*.cpp

        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/main.cpp

        #Temporary manual method of including source files to avoid including broken code
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/GPIO/*.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/Timer/*.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/UART/*.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Core/*.cpp
)

add_executable(${EXECUTABLE}
    ${PROJECT_SOURCES}
    ${STARTUP_SCRIPT}
)

target_compile_definitions(${EXECUTABLE} PRIVATE
        USE_PWR_LDO_SUPPLY
        ${MCU_MODEL}
        ${MCU_FAMILY}
)

target_include_directories(${EXECUTABLE} PRIVATE
    ${MX_INCLUDE_DIRECTORIES}
    ${PROJECT_INCLUDE_DIRECTORIES}
)

target_compile_options(${EXECUTABLE} PRIVATE
${CPU_PARAMETERS}
-Wall
-Wextra
-Wpedantic
-Wno-unused-parameter
-Wno-unused-function
$<$<COMPILE_LANGUAGE:CXX>:
-Wno-volatile
-Wsuggest-override>

$<$<CONFIG:Debug>:-Og -g3 -ggdb>
$<$<CONFIG:Release>:-Og -g0>
)

target_link_options(${EXECUTABLE} PRIVATE
-T${MCU_LINKER_SCRIPT}
${CPU_PARAMETERS}
-Wl,-Map=${CMAKE_PROJECT_NAME}.map
--specs=nosys.specs
-Wl,--start-group
-lc
-lm
-lstdc++
-lsupc++
-Wl,--end-group
-Wl,--print-memory-usage
)

add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${EXECUTABLE}>
)

add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${EXECUTABLE}>
${EXECUTABLE}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}>
${EXECUTABLE}.bin
)