#------------------------------------------------------------------------------
#
# \brief	CMakeLists.txt file for "libbiwak"
#
#------------------------------------------------------------------------------


cmake_minimum_required(VERSION 3.11)
project (biwak)

add_compile_options( -Werror )

include_directories(
      3th_party/
)

if ( NOT MCU_PLATFORM )
   set ( MCU_PLATFORM "linux" )
endif( NOT MCU_PLATFORM)


option ( BIWAK_USE_FREEZE_HANDLER
		"Instanziate freezing handlers for all interrupts in debug mode" False )

if ( BIWAK_USE_FREEZE_HANDLER )
	add_definitions( -DBIWAK_USE_FREEZE_HANDLER )
endif ( BIWAK_USE_FREEZE_HANDLER )

if ( "${MCU_PLATFORM}" MATCHES "linux" )
    set( CMAKE_AUTOUIC ON )
    set( CMAKE_AUTOMOC ON )
    set( CMAKE_AUTORCC ON )
    set( CMAKE_AUTOUIC_SEARCH_PATHS "ui" )

    # Check either Qt6 or Qt5
    find_package( QT NAMES Qt5 Qt6 COMPONENTS Core Widgets Gui Network REQUIRED )
    find_package( Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Gui Network )
    find_package( GitVersion REQUIRED )

endif( "${MCU_PLATFORM}" MATCHES "linux" )

set( USE_BIWAK 1 PARENT_SCOPE )

set(sources
     ${sources}
     # src/bootloader.cpp
     src/${MCU_PLATFORM}/biwak.cpp
     src/main.cpp
     src/handler.cpp
     src/lltools.cpp
     src/led.cpp
     src/output.cpp
     src/output_blink_modes.cpp
     src/gdisplay.cpp
     src/${MCU_PLATFORM}/gpio.cpp
     src/button.cpp
     src/menu.cpp
     src/ws2814.cpp

     # src/debug.cpp
     # src/bootloader.cpp
     src/${MCU_PLATFORM}/timer_calc.cpp
     src/${MCU_PLATFORM}/timer.cpp

     src/${MCU_PLATFORM}/watchdog.cpp
     # src/${MCU_PLATFORM}/usb.cpp
     src/${MCU_PLATFORM}/exti.cpp
     src/${MCU_PLATFORM}/exception.cpp
     src/${MCU_PLATFORM}/flash_intern.cpp
     src/${MCU_PLATFORM}/flash_spi.cpp
     src/${MCU_PLATFORM}/spi.cpp
     src/${MCU_PLATFORM}/gpio.cpp
     src/${MCU_PLATFORM}/gpio_modes.cpp
     src/${MCU_PLATFORM}/adc.cpp
     src/${MCU_PLATFORM}/info.cpp
     src/${MCU_PLATFORM}/eeprom_intern.cpp
     src/${MCU_PLATFORM}/dma.cpp

     # src/pwm.cpp
     # src/qjtimer.cpp
     src/${MCU_PLATFORM}/uart.cpp
     src/iostream.cpp
	  src/rfm64w.cpp
	  src/rfm69cw.cpp
     src/flash.cpp
     src/retain.cpp

     src/logoutput_uart.cpp
     src/touch_tsc2007.cpp
     src/heartbeat.cpp
	  #3th_party/bosch/bme680.c
     src/generic/shift.cpp
     src/generic/softtimer.cpp
     # src/temp_tsic.cpp
     # src/rfid.cpp
     src/${MCU_PLATFORM}/rtc.cpp
     # src/irinput.cpp
     src/input.cpp
     src/input_decoder.cpp
     src/temperature.cpp
     src/voc.cpp
     src/${MCU_PLATFORM}/pwm.cpp
     src/barrel_organ.cpp
     src/barrel_organ_beepmodes.cpp
     src/barrel_organ_fademodes.cpp
     # src/p_ansiparser.cpp
     src/log.cpp
	  src/mcp7940.cpp
     src/tmp117.cpp
     
     src/tools.cpp
     src/dataEvent.cpp
     
     src/${MCU_PLATFORM}/wkup.cpp
     
     src/time.cpp
     
     src/${MCU_PLATFORM}/gdisplay_ili9341.cpp
     src/${MCU_PLATFORM}/i2c_rtc.cpp
)


if( "${MCU_REV}" STREQUAL "l4" )
  set(sources
     ${sources}
     src/${MCU_PLATFORM}/qspi.cpp
     src/${MCU_PLATFORM}/sd.cpp
  )
endif()



   if( NOT "${MCU_REV}" STREQUAL "l0" )
      set(sources
         ${sources}
         src/${MCU_PLATFORM}/usb.cpp
         src/${MCU_PLATFORM}/usb_device.cpp
         src/${MCU_PLATFORM}/usb_descriptor.cpp
         src/${MCU_PLATFORM}/usb_class.cpp
      )
   if ( NOT ( ( MCU_REV_LONG STREQUAL "f042x6") OR ( MCU_REV STREQUAL "g4") ) )
         set(sources
            ${sources}
            src/${MCU_PLATFORM}/dac.cpp
            src/${MCU_PLATFORM}/dac_line_dma.cpp
            src/${MCU_PLATFORM}/tsc.cpp
         )
      endif()

   endif()


if( "${MCU_REV}" STREQUAL "f0" )
   set(headers
         ${headers}
         include/biwak/crc.hpp
   )

   set(sources
      ${sources}
      src/${MCU_PLATFORM}/crc.cpp
      )
endif()


if( "${MCU_PLATFORM}" MATCHES "stm32" )
   set(sources
         ${sources}
         src/${MCU_PLATFORM}/rcc.cpp
         src/${MCU_PLATFORM}/adc.cpp
         src/${MCU_PLATFORM}/systick.cpp
         src/${MCU_PLATFORM}/nvic.cpp
         src/${MCU_PLATFORM}/synthesizer.cpp
         src/${MCU_PLATFORM}/gdisplay_nh.cpp
         src/${MCU_PLATFORM}/gdisplay_dem.cpp
         #src/${MCU_PLATFORM}/bu21026muv.cpp
         # src/${MCU_PLATFORM}/bme680.cpp
         src/${MCU_PLATFORM}/stlm75ds2f.cpp
         src/${MCU_PLATFORM}/si705x.cpp
         src/${MCU_PLATFORM}/spi_slave.cpp
         src/${MCU_PLATFORM}/flash_spi.cpp
         src/${MCU_PLATFORM}/max31855.cpp
         src/${MCU_PLATFORM}/crc.cpp
         src/${MCU_PLATFORM}/option_bytes.cpp

         src/logoutput_itm.cpp
         # src/syscalls.cpp
         src/${MCU_PLATFORM}/eadisplay.cpp
         src/${MCU_PLATFORM}/i2c.cpp
         src/${MCU_PLATFORM}/i2c_slave.cpp
         src/${MCU_PLATFORM}/flash_i2c.cpp
         src/${MCU_PLATFORM}/temp_i2c.cpp
   )
endif( )


if( "${MCU_PLATFORM}" MATCHES "linux" )

   set(sources
         ${sources}
         src/${MCU_PLATFORM}/qspi.cpp
         src/${MCU_PLATFORM}/boardgui.cpp
         src/${MCU_PLATFORM}/systick.cpp
         # src/${MCU_PLATFORM}/qtgateway.cpp
         src/${MCU_PLATFORM}/temp_linux.cpp
         src/${MCU_PLATFORM}/arbiter.cpp
         src/${MCU_PLATFORM}/gdisplay_qt.cpp
         src/${MCU_PLATFORM}/flash_file.cpp
         src/${MCU_PLATFORM}/i2c.cpp
         src/${MCU_PLATFORM}/i2c_slave.cpp
         src/${MCU_PLATFORM}/flash_i2c.cpp
         src/${MCU_PLATFORM}/crc.cpp
         src/${MCU_PLATFORM}/option_bytes.cpp
         src/${MCU_PLATFORM}/si705x.cpp
         src/${MCU_PLATFORM}/spi_slave.cpp
         src/${MCU_PLATFORM}/sd.cpp
         src/${MCU_PLATFORM}/linker_script.cpp
         ui/boardgui.ui
   )
endif( )

#--- Further generic optional sources -----------------------------------

set(sources
      ${sources}
      src/generic/font.cpp
      # src/generic/font_9x9.cpp
      src/generic/font_11x12.cpp
      src/generic/font_6x6.cpp
      # c/generic/font_5x5.cpp
      # src/generic/font_5x5_bl.cpp
      src/generic/font_8x8_b.cpp
      src/generic/font_16x16.cpp
      src/generic/font_32x32.cpp
      src/generic/font_24x24.cpp
)


set ( syscalls_sources
      src/syscalls.cpp
      src/stdio.cpp
)

set(headers
      ${headers}
      include/biwak/adc.hpp
      include/biwak/biwak.h
      include/biwak/bringup.h
      include/biwak/button.hpp
      include/biwak/crc.hpp
      include/biwak/dac.hpp
      include/biwak/dac_line_dma.hpp
      include/biwak/device_config.h
      include/biwak/dma.hpp
      include/biwak/eadisplay.hpp
      include/biwak/eeprom_intern.h
      include/biwak/exti.h
      include/biwak/exception.h
      include/biwak/flash.h
      include/biwak/flash_i2c.hpp
      include/biwak/flash_spi.hpp
      include/biwak/font.h
      include/biwak/gpio.hpp
      include/biwak/gpio_modes.hpp
      include/biwak/gdisplay.h
      include/biwak/graphic_types.h
      include/biwak/handler.h
      include/biwak/heartbeat.hpp
      include/biwak/i2c.hpp
      include/biwak/i2c_rtc.h
      include/biwak/input.hpp
      include/biwak/input_decoder.h
      include/biwak/iostream.h
      include/biwak/ir_input.h
      include/biwak/lcd.hpp
      include/biwak/lcd_com.hpp
      include/biwak/lcd_seg.hpp
      include/biwak/led.hpp
      include/biwak/log.h
      include/biwak/mcp7940.hpp
      include/biwak/menu.h
      include/biwak/nvic.h
      include/biwak/output.hpp
      include/biwak/pwm.hpp
      include/biwak/qjtimer.h
      include/biwak/rcc.h
      include/biwak/retain.h
      include/biwak/rfid.h
      include/biwak/rtc.hpp
      include/biwak/shift.h
      include/biwak/softtimer.h
      include/biwak/spi.hpp
      include/biwak/spi_slave.h
      include/biwak/synthesizer.h
      include/biwak/systick.h
      include/biwak/temp_i2c.h
      include/biwak/temp_tsic.h
      include/biwak/timer.hpp
      include/biwak/tmp117.hpp
      include/biwak/tsc.h
      include/biwak/uart.hpp
      include/biwak/voc.h
      include/biwak/watchdog.h
      include/biwak/rfm64w.hpp
      include/biwak/rfm69cw.hpp
      
      include/biwak/tools.hpp
)

# Even x86 uses the can class for unit tests
if( NOT ( ( "${MCU_REV}" STREQUAL "l1" )
       OR ( "${MCU_REV}" STREQUAL "l0" )
       OR ( "${MCU_REV}" STREQUAL "g0" )
       OR ( "${MCU_REV}" STREQUAL "g4" ) ) )
   set(headers
         ${headers}
         include/biwak/can.hpp
   )
   set(sources
         ${sources}
         src/${MCU_PLATFORM}/can.cpp
   )
endif()

# message( FATAL_ERROR "MCU ${MCU_REV_LONG}")

if( "${MCU_REV_LONG}" MATCHES "l152x." )
   set(headers
      ${headers}
      include/biwak/lcd.hpp
   )
   set(sources
      ${sources}
      src/${MCU_PLATFORM}/lcd_seg.cpp
      src/${MCU_PLATFORM}/lcd_com.cpp
      src/${MCU_PLATFORM}/lcd.cpp
   )
endif()

if( "${MCU_REV}" STREQUAL "g4" )
   set(headers
         ${headers}
         include/biwak/can.hpp
   )
   set(sources
         ${sources}
         # src/${MCarenaU_PLATFORM}/fdcan.cpp
         src/${MCU_PLATFORM}/can.cpp
   )
endif()


if ( NOT MCU_REV OR "${MCU_REV}" MATCHES "x86" )

   SET(biwak_FORMS
         ui/boardgui.ui
   )

   SET(biwak_MOCHEADERS
         include/biwak/linux/boardgui.h
         src/linux/arbiter.h
   )

   INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

endif( NOT MCU_REV OR "${MCU_REV}" MATCHES "x86" )


set(sources
      ${sources}
      src/generic/timer.cpp
)


set(handler_sources
      src/handler_freezer.cpp
)

set(handler_headers
      include/biwak/handler_freezer.h
)


add_library(
   ${PROJECT_NAME}
   STATIC
      ${sources}
      ${biwak_HEADERS_MOC}
      ${biwak_MOCHEADERS}
      ${biwak_FORMS_HEADERS}
      ${biwak_RESOURCES_RCC}
      ${headers}
      ${handler_sources}
      ${handler_headers}
)

if ( COMMON_CONFIG_HEADER )
   set ( BIWAK_CONFIG_HEADER "${COMMON_CONFIG_HEADER}" )
elseif( EXISTS "${CMAKE_SYSROOT}/usr/include/biwak/config.h" )
   set ( BIWAK_CONFIG_HEADER "${CMAKE_SYSROOT}/usr/include/biwak/config.h" )
endif()

target_compile_definitions(
   ${PROJECT_NAME}
   PUBLIC
      -DUSE_BIWAK
      -DBIWAK_PLATFORM=${MCU_PLATFORM}
)


# If you dont want a config header, stop biwak to complain about this.
if( BIWAK_CONFIGURED )
   target_compile_definitions(
      ${PROJECT_NAME}
      PUBLIC
         "-DBIWAK_CONFIGURED"
   )
endif()

if( BIWAK_CONFIG_HEADER )
   target_compile_options(
      ${PROJECT_NAME}
      PRIVATE
         "SHELL:-include ${BIWAK_CONFIG_HEADER}"
      PUBLIC
         "SHELL:-include ${BIWAK_CONFIG_HEADER}"
   )

   set_source_files_properties(
         ${sources}
         ${headers}
         ${handler_sources}
         ${handler_headers}
      PROPERTIES
      OBJECT_DEPENDS
         ${BIWAK_CONFIG_HEADER}
   )

   set( BIWAK_CONFIGURED Yes )
endif()

if( NOT BIWAK_CONFIGURED )
   message( ERROR "BIWAK_CONFIGURED not set." )
   message( FATAL_ERROR "No config header for biwak defined" )
endif()


add_library(
   freezer_handlers
   STATIC
      ${handler_sources}
      ${handler_headers}
)

target_include_directories(
   freezer_handlers
   PRIVATE
      "include/"
   INTERFACE
      "include/"
)

target_link_libraries(
        freezer_handlers
        lepto
)

if( "${MCU_PLATFORM}" MATCHES "stm32" )

   set ( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -nostdlib")

   add_library(
      syscalls
      STATIC
         ${syscalls_sources}
   )

   target_link_libraries(
      syscalls
      biwak
      lepto
      stm-${MCU_REV}
   )

endif()

if( "${MCU_PLATFORM}" MATCHES "stm32" )
   target_link_libraries(
      biwak
      lepto
      stm-${MCU_REV}
   )
else()
   target_link_libraries(
      biwak
      PRIVATE
      PUBLIC
      # The graphic display inherits from CGDisplayQt which contains a QPixmap
      Qt${QT_VERSION_MAJOR}::Core
      Qt${QT_VERSION_MAJOR}::Widgets
      Qt${QT_VERSION_MAJOR}::Gui
      lepto
   )
endif()

target_include_directories(
   ${PROJECT_NAME}
   PRIVATE
      "include/"
   INTERFACE
      "include/"
)

if( "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" )
    add_subdirectory(tests)
endif()


#------------------------------------------------------------------------------
