cmake_minimum_required(VERSION 3.22)
project(bootloader C CXX ASM)

set(SRC_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/)
set(COMMON ${SRC_ROOT}/common)
set(CRYPTO ${SRC_ROOT}/cyclone_crypto)
set(UPDATE ${SRC_ROOT}/cyclone_boot)
set(TCP ${SRC_ROOT}/cyclone_tcp)
set(THIRD_PARTY ${CMAKE_SOURCE_DIR}/../../../../../third_party)
set(HAL_DRIVERS ${THIRD_PARTY}/st/drivers/stm32f4xx_hal_driver/src/)
set(BSP ${THIRD_PARTY}/st/boards/stm32f4xx_nucleo_144/)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)

# Define the build type
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")
endif()

# Enable compile command to ease indexing with e.g. clangd
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

# Core project settings
project(${CMAKE_PROJECT_NAME})
message("Build type: " ${CMAKE_BUILD_TYPE})

# Enable CMake support for ASM and C languages
enable_language(C ASM)

# Create an executable object type
add_executable(${CMAKE_PROJECT_NAME})

target_sources(${CMAKE_PROJECT_NAME} PRIVATE
        ${COMMON}/cpu_endian.c
        ${COMMON}/os_port_none.c
        ${COMMON}/date_time.c
        ${COMMON}/str.c
        ${COMMON}/path.c
        ${COMMON}/resource_manager.c
        ${UPDATE}/core/crc32.c
        ${UPDATE}/core/mailbox.c
        ${UPDATE}/drivers/mcu_core/stm32h7xx_mcu_driver.c
        ${UPDATE}/drivers/flash/external/mt25tl01g_flash_driver.c
        ${UPDATE}/modules/image/image.c
        ${UPDATE}/modules/image/image_process.c
        ${UPDATE}/modules/image/image_utils.c
        ${UPDATE}/modules/memory/memory.c
        ${UPDATE}/modules/memory/memory_ex.c
        ${UPDATE}/core/verify.c
        ${UPDATE}/modules/security/verify_auth.c
        ${UPDATE}/modules/security/verify_sign.c
        ${UPDATE}/modules/security/cipher.c
        ${UPDATE}/update/update.c
        ${UPDATE}/update/update.c
        ${UPDATE}/update/update_misc.c
        ${CRYPTO}/hardware/stm32h7xx/stm32h7xx_crypto.c
        ${CRYPTO}/hardware/stm32h7xx/stm32h7xx_crypto_trng.c
        ${CRYPTO}/hash/md5.c
        ${CRYPTO}/hash/sha1.c
        ${CRYPTO}/hash/sha224.c
        ${CRYPTO}/hash/sha256.c
        ${CRYPTO}/hash/sha384.c
        ${CRYPTO}/hash/sha512.c
        ${CRYPTO}/mac/hmac.c
        ${CRYPTO}/cipher/rc4.c
        ${CRYPTO}/cipher/idea.c
        ${CRYPTO}/cipher/des.c
        ${CRYPTO}/cipher/des3.c
        ${CRYPTO}/cipher/aes.c
        ${CRYPTO}/cipher/camellia.c
        ${CRYPTO}/cipher/seed.c
        ${CRYPTO}/cipher/aria.c
        ${CRYPTO}/cipher_modes/cbc.c
        ${CRYPTO}/aead/ccm.c
        ${CRYPTO}/aead/gcm.c
        ${CRYPTO}/cipher/chacha.c
        ${CRYPTO}/mac/poly1305.c
        ${CRYPTO}/aead/chacha20_poly1305.c
        ${CRYPTO}/pkc/dh.c
        ${CRYPTO}/pkc/rsa.c
        ${CRYPTO}/pkc/dsa.c
        ${CRYPTO}/ecc/ec.c
        ${CRYPTO}/ecc/ec_curves.c
        ${CRYPTO}/ecc/ecdh.c
        ${CRYPTO}/ecc/ecdsa.c
        ${CRYPTO}/ecc/eddsa.c
        ${CRYPTO}/ecc/curve25519.c
        ${CRYPTO}/ecc/curve448.c
        ${CRYPTO}/ecc/x25519.c
        ${CRYPTO}/ecc/x448.c
        ${CRYPTO}/ecc/ed25519.c
        ${CRYPTO}/ecc/ed448.c
        ${CRYPTO}/mpi/mpi.c
        ${CRYPTO}/mpi/mpi_misc.c
        ${CRYPTO}/encoding/base64.c
        ${CRYPTO}/encoding/asn1.c
        ${CRYPTO}/encoding/oid.c
        ${CRYPTO}/pkix/pem_import.c
        ${CRYPTO}/pkix/pem_key_import.c
        ${CRYPTO}/pkix/pem_decrypt.c
        ${CRYPTO}/pkix/pem_common.c
        ${CRYPTO}/pkix/pkcs5_decrypt.c
        ${CRYPTO}/pkix/pkcs5_common.c
        ${CRYPTO}/pkix/pkcs8_key_parse.c
        ${CRYPTO}/pkix/x509_key_parse.c
        ${CRYPTO}/pkix/x509_cert_parse.c
        ${CRYPTO}/pkix/x509_cert_validate.c
        ${CRYPTO}/pkix/x509_cert_ext_parse.c
        ${CRYPTO}/pkix/x509_common.c
        ${CRYPTO}/pkix/x509_sign_parse.c
        ${CRYPTO}/pkix/x509_sign_verify.c
        ${CRYPTO}/kdf/hkdf.c
        
        ${CRYPTO}/ecc/ec_misc.c
        ${CRYPTO}/pkc/rsa_misc.c

        ${THIRD_PARTY}/st/boards/stm32h750b_discovery/stm32h750b_discovery.c
        ${THIRD_PARTY}/st/boards/stm32h750b_discovery/stm32h750b_discovery_lcd.c
        ${THIRD_PARTY}/st/boards/stm32h750b_discovery/stm32h750b_discovery_sdram.c
        ${THIRD_PARTY}/st/boards/stm32h750b_discovery/stm32h750b_discovery_qspi.c
        ${THIRD_PARTY}/st/boards/components/ft5336/ft5336.c
        ${THIRD_PARTY}/st/boards/components/ft5336/ft5336_reg.c
        ${THIRD_PARTY}/st/boards/components/mt48lc4m32b2/mt48lc4m32b2.c

        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_dma2d.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_ltdc.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_sdram.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_ll_fmc.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_qspi.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_cortex.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_rcc.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_rcc_ex.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_flash.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_flash_ex.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_gpio.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_hsem.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_dma.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_dma_ex.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_mdma.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_pwr.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_pwr_ex.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_i2c.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_i2c_ex.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_exti.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_tim.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_tim_ex.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_uart.c
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/src/stm32h7xx_hal_uart_ex.c

        ${CMAKE_SOURCE_DIR}/cmake/startup_stm32h750xx.s
        ${CMAKE_SOURCE_DIR}/cmake/syscalls.c
        ${CMAKE_SOURCE_DIR}/cmake/sysmem.c
        ${CMAKE_SOURCE_DIR}/src/system_stm32h7xx.c
        ${CMAKE_SOURCE_DIR}/src/stm32h7xx_hal_msp.c
        ${CMAKE_SOURCE_DIR}/src/stm32h7xx_it.c
        ${CMAKE_SOURCE_DIR}/src/main.c
        ${CMAKE_SOURCE_DIR}/src/res.c
        ${CMAKE_SOURCE_DIR}/src/helper.c
        ${CMAKE_SOURCE_DIR}/src/debug.c
        ${CMAKE_SOURCE_DIR}/src/common.c
        ${CMAKE_SOURCE_DIR}/src/uart_user.c
        ${CMAKE_SOURCE_DIR}/src/ymodem.c
)

target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
        ${CMAKE_SOURCE_DIR}/src/
        ${THIRD_PARTY}/cmsis/include
        ${THIRD_PARTY}/st/devices/stm32h7xx
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/inc
        ${THIRD_PARTY}/st/drivers/stm32h7xx_hal_driver/inc/legacy
        ${THIRD_PARTY}/st/boards/stm32h750b_discovery
        ${THIRD_PARTY}/st/boards/utilities/
        #${THIRD_PARTY}/st/boards/Utilities/lcd
        ${THIRD_PARTY}/st/boards/utilities/Fonts
        ${THIRD_PARTY}/st/boards/components
        ${THIRD_PARTY}/st/boards/components/Common
        ${THIRD_PARTY}/st/boards/components/ft5336
        ${THIRD_PARTY}/st/boards/components/mt48lc4m32b2
        ${THIRD_PARTY}/st/boards/components/rk043fn48h
        ${COMMON}
        ${CRYPTO}
        ${UPDATE}
        ${UPDATE}/bootloader/
        ${UPDATE}/modules
)

target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
    STM32H750xx
    STM32H750xB
    MT25TL01G_MEMORY_MAPPED
    USE_HAL_DRIVER
    USE_STM32H750B_DISCO
    USE_PWR_LDO_SUPPLY
    __USE_C99_MATH

    $<$<CONFIG:Debug>:DEBUG>
)

add_custom_command(TARGET ${CMAKE_PROJECT_NAME} PRE_BUILD
        COMMAND ${CMAKE_SOURCE_DIR}/compile_resources.sh
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
        COMMENT "Compiling resources to res.c..."
)

# Add the map file to the list of files to be removed with 'clean' target
set_target_properties(bootloader PROPERTIES ADDITIONAL_CLEAN_FILES ${CMAKE_PROJECT_NAME}.map)

# Convert .elf to .bin
add_custom_command(TARGET bootloader POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -O binary
        ${CMAKE_CURRENT_BINARY_DIR}/bootloader.elf
        ${CMAKE_CURRENT_BINARY_DIR}/bootloader.bin
        COMMENT "Generating binary file from ELF"
)

# Copy the generated .bin file to ../
add_custom_command(TARGET bootloader POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
        ${CMAKE_CURRENT_BINARY_DIR}/bootloader.bin
        ${CMAKE_CURRENT_SOURCE_DIR}/../
        COMMENT "Copying bootloader.bin to parent directory"
)
