cmake_minimum_required(VERSION 3.12)
project(second_stage_tcp_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/)

message(STATUS "C flags DEBUG: ${CMAKE_C_FLAGS_DEBUG}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

add_executable(bootloader
        ${COMMON}/cpu_endian.c
        ${COMMON}/date_time.c
        ${COMMON}/path.c
        ${COMMON}/resource_manager.c
        ${COMMON}/str.c
        ${COMMON}/os_port_none.c

        ${UPDATE}/drivers/flash/internal/stm32f4xx_flash_driver.c
        ${UPDATE}/drivers/mcu_core/stm32f4xx_mcu_driver.c

        ${BSP}/stm32f4xx_nucleo_144.c

        ${TCP}/core/net.c
        ${TCP}/core/net_mem.c
        ${TCP}/core/net_misc.c
        ${TCP}/drivers/mac/stm32f4xx_eth_driver.c
        ${TCP}/drivers/phy/lan8742_driver.c
        ${TCP}/core/nic.c
        ${TCP}/core/ethernet.c
        ${TCP}/core/ethernet_misc.c
        ${TCP}/ipv4/arp.c
        ${TCP}/ipv4/arp_cache.c
        ${TCP}/ipv4/ipv4.c
        ${TCP}/ipv4/ipv4_frag.c
        ${TCP}/ipv4/ipv4_multicast.c
        ${TCP}/ipv4/ipv4_misc.c
        ${TCP}/ipv4/icmp.c
        ${TCP}/igmp/igmp_host.c
        ${TCP}/igmp/igmp_host_misc.c
        ${TCP}/igmp/igmp_common.c
        ${TCP}/igmp/igmp_debug.c
        ${TCP}/ipv6/ipv6.c
        ${TCP}/ipv6/ipv6_frag.c
        ${TCP}/ipv6/ipv6_multicast.c
        ${TCP}/ipv6/ipv6_pmtu.c
        ${TCP}/ipv6/ipv6_misc.c
        ${TCP}/ipv6/icmpv6.c
        ${TCP}/ipv6/ndp.c
        ${TCP}/ipv6/ndp_cache.c
        ${TCP}/ipv6/ndp_misc.c
        ${TCP}/ipv6/slaac.c
        ${TCP}/ipv6/slaac_misc.c
        ${TCP}/mld/mld_node.c
        ${TCP}/mld/mld_node_misc.c
        ${TCP}/mld/mld_common.c
        ${TCP}/mld/mld_debug.c
        ${TCP}/core/ip.c
        ${TCP}/core/tcp.c
        ${TCP}/core/tcp_fsm.c
        ${TCP}/core/tcp_misc.c
        ${TCP}/core/tcp_timer.c
        ${TCP}/core/udp.c
        ${TCP}/core/socket.c
        ${TCP}/core/socket_misc.c
        ${TCP}/core/bsd_socket.c
        ${TCP}/core/bsd_socket_options.c
        ${TCP}/core/bsd_socket_misc.c
        ${TCP}/core/raw_socket.c
        ${TCP}/dns/dns_cache.c
        ${TCP}/dns/dns_client.c
        ${TCP}/dns/dns_common.c
        ${TCP}/dns/dns_debug.c
        ${TCP}/mdns/mdns_client.c
        ${TCP}/mdns/mdns_responder.c
        ${TCP}/mdns/mdns_responder_misc.c
        ${TCP}/mdns/mdns_common.c
        ${TCP}/netbios/nbns_client.c
        ${TCP}/netbios/nbns_responder.c
        ${TCP}/netbios/nbns_common.c
        ${TCP}/llmnr/llmnr_client.c
        ${TCP}/llmnr/llmnr_responder.c
        ${TCP}/llmnr/llmnr_common.c
        ${TCP}/dhcp/dhcp_client.c
        ${TCP}/dhcp/dhcp_client_fsm.c
        ${TCP}/dhcp/dhcp_client_misc.c
        ${TCP}/dhcp/dhcp_common.c
        ${TCP}/dhcp/dhcp_debug.c
        ${TCP}/tftp/tftp_server.c
        ${TCP}/tftp/tftp_server_misc.c

        ${UPDATE}/core/crc32.c
        ${UPDATE}/core/mailbox.c
        ${UPDATE}/core/verify.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}/update/update.c
        ${UPDATE}/update/update_misc.c
        ${UPDATE}/update/update_fallback.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

        ${HAL_DRIVERS}/stm32f4xx_hal.c
        ${HAL_DRIVERS}/stm32f4xx_hal_adc.c
        ${HAL_DRIVERS}/stm32f4xx_hal_adc_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_can.c
        ${HAL_DRIVERS}/stm32f4xx_hal_cec.c
        ${HAL_DRIVERS}/stm32f4xx_hal_cortex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_crc.c
        ${HAL_DRIVERS}/stm32f4xx_hal_cryp.c
        ${HAL_DRIVERS}/stm32f4xx_hal_cryp_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dac.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dac_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dcmi.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dcmi_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dfsdm.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dma.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dma_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dma2d.c
        ${HAL_DRIVERS}/stm32f4xx_hal_dsi.c
        ${HAL_DRIVERS}/stm32f4xx_hal_eth.c
        ${HAL_DRIVERS}/stm32f4xx_hal_flash.c
        ${HAL_DRIVERS}/stm32f4xx_hal_flash_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_flash_ramfunc.c
        ${HAL_DRIVERS}/stm32f4xx_hal_fmpi2c.c
        ${HAL_DRIVERS}/stm32f4xx_hal_fmpi2c_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_gpio.c
        ${HAL_DRIVERS}/stm32f4xx_hal_hash.c
        ${HAL_DRIVERS}/stm32f4xx_hal_hash_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_hcd.c
        ${HAL_DRIVERS}/stm32f4xx_hal_i2c.c
        ${HAL_DRIVERS}/stm32f4xx_hal_i2c_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_i2s.c
        ${HAL_DRIVERS}/stm32f4xx_hal_i2s_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_irda.c
        ${HAL_DRIVERS}/stm32f4xx_hal_iwdg.c
        ${HAL_DRIVERS}/stm32f4xx_hal_lptim.c
        ${HAL_DRIVERS}/stm32f4xx_hal_ltdc.c
        ${HAL_DRIVERS}/stm32f4xx_hal_ltdc_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_nand.c
        ${HAL_DRIVERS}/stm32f4xx_hal_nor.c
        ${HAL_DRIVERS}/stm32f4xx_hal_pccard.c
        ${HAL_DRIVERS}/stm32f4xx_hal_pcd.c
        ${HAL_DRIVERS}/stm32f4xx_hal_pcd_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_pwr.c
        ${HAL_DRIVERS}/stm32f4xx_hal_pwr_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_qspi.c
        ${HAL_DRIVERS}/stm32f4xx_hal_rcc.c
        ${HAL_DRIVERS}/stm32f4xx_hal_rcc_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_rng.c
        ${HAL_DRIVERS}/stm32f4xx_hal_rtc.c
        ${HAL_DRIVERS}/stm32f4xx_hal_rtc_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_sai.c
        ${HAL_DRIVERS}/stm32f4xx_hal_sai_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_sd.c
        ${HAL_DRIVERS}/stm32f4xx_hal_sdram.c
        ${HAL_DRIVERS}/stm32f4xx_hal_smartcard.c
        ${HAL_DRIVERS}/stm32f4xx_hal_spdifrx.c
        ${HAL_DRIVERS}/stm32f4xx_hal_spi.c
        ${HAL_DRIVERS}/stm32f4xx_hal_sram.c
        ${HAL_DRIVERS}/stm32f4xx_hal_tim.c
        ${HAL_DRIVERS}/stm32f4xx_hal_tim_ex.c
        ${HAL_DRIVERS}/stm32f4xx_hal_uart.c
        ${HAL_DRIVERS}/stm32f4xx_hal_usart.c
        ${HAL_DRIVERS}/stm32f4xx_hal_wwdg.c
        ${HAL_DRIVERS}/stm32f4xx_ll_fmc.c
        ${HAL_DRIVERS}/stm32f4xx_ll_fsmc.c
        ${HAL_DRIVERS}/stm32f4xx_ll_sdmmc.c
        ${HAL_DRIVERS}/stm32f4xx_ll_usb.c

        ${CMAKE_SOURCE_DIR}/src/debug.c
        ${CMAKE_SOURCE_DIR}/src/tftp_server.c
        ${CMAKE_SOURCE_DIR}/src/fs_port_custom.c
        ${CMAKE_SOURCE_DIR}/src/system_stm32f4xx.c
        ${CMAKE_SOURCE_DIR}/src/res.c
        ${CMAKE_SOURCE_DIR}/src/stm32f4xx_it.c
        ${CMAKE_SOURCE_DIR}/cmake/startup_stm32f439xx.s
        ${CMAKE_SOURCE_DIR}/cmake/syscalls.c
)

target_include_directories(bootloader PUBLIC
        ${COMMON}
        ${UPDATE}
        ${UPDATE}/modules
        ${CRYPTO}/hash
        ${CRYPTO}
        ${TCP}
        ${CMAKE_SOURCE_DIR}/src
        ${THIRD_PARTY}/cmsis/include
        ${THIRD_PARTY}/st/devices/stm32f4xx
        ${THIRD_PARTY}/st/drivers/stm32f4xx_hal_driver/inc
        ${THIRD_PARTY}/st/drivers/stm32f4xx_hal_driver/
        ${BSP}
)

target_compile_definitions(bootloader PUBLIC
        STM32F4xxxI
        STM32F439xx
        USE_HAL_DRIVER
        USE_STM32F4XX_NUCLEO_144
        _WINSOCK_H
        $<$<CONFIG:Debug>:DEBUG>
)


add_custom_command(TARGET bootloader 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"
)
