x9e with horus bt module (#5214)
[opentx.git] / radio / src / CMakeLists.txt
bloba14eaf65b9ec41c67957186b231ee94fcc3b13b4
1 include(CMakeForceCompiler)
2 include(Bitmaps)
4 set(PCB_TYPES X7 X7S X9D X9D+ X9E X10 X12S 9X 9XR 9X128 9XR128 9X2561 GRUVIN9X MEGA2560 SKY9X 9XRPRO AR9X)
5 set(GUI_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU NL)
6 set(TTS_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU)
8 set(PCB "X9D+" CACHE STRING "Radio type, one of: ${PCB_TYPES}")
9 set_property(CACHE PCB PROPERTY STRINGS ${PCB_TYPES})
10 set(TRANSLATIONS "EN" CACHE STRING "Radio language, one of: ${GUI_LANGUAGES}")
11 set_property(CACHE TRANSLATIONS PROPERTY STRINGS ${GUI_LANGUAGES})
12 set(SPLASH "DEFAULT" CACHE STRING "Splash (DEFAULT/OFF/FRSKY)")
13 set_property(CACHE SPLASH PROPERTY STRINGS DEFAULT OFF FRSKY)
14 set(PPM_UNIT "PERCENT_PREC1" CACHE STRING "PPM display unit (US/PERCENT_PREC1/PERCENT_PREC0)")
15 set_property(CACHE PPM_UNIT PROPERTY STRINGS US PERCENT_PREC1 PERCENT_PREC0)
16 set(DEFAULT_MODE "" CACHE STRING "Default sticks mode")
17 set(FONT "STD" CACHE STRING "Choose font : STD or SQT5")
18 set_property(CACHE FONT PROPERTY STRINGS SQT5)
20 option(HELI "Heli menu" ON)
21 option(FLIGHT_MODES "Flight Modes" ON)
22 option(CURVES "Curves" ON)
23 option(GVARS "Global variables" OFF)
24 option(GUI "GUI enabled" ON)
25 option(PPM_CENTER_ADJUSTABLE "PPM center adjustable" ON)
26 option(PPM_LIMITS_SYMETRICAL "PPM limits symetrical" OFF)
27 option(OVERRIDE_CHANNEL_FUNCTION "OverrideChannel function available" ON)
28 option(DANGEROUS_MODULE_FUNCTIONS "Dangerous module functions (RangeCheck / Bind / Module OFF, etc.) available" OFF)
29 option(FAI "Competition mode (no telemetry)" OFF)
30 option(AUTOSOURCE "Automatic source detection in menus" ON)
31 option(AUTOSWITCH "Automatic switch detection in menus" ON)
32 option(SEMIHOSTING "Enable debugger semihosting" OFF)
33 option(JITTER_MEASURE "Enable ADC jitter measurement" OFF)
34 option(WATCHDOG_DISABLED "Disable hardware Watchdog" OFF)
35 if(SDL_FOUND)
36   option(SIMU_AUDIO "Enable simulator audio." ON)
37 endif()
38 option(SIMU_DISKIO "Enable disk IO simulation in simulator. Simulator will use FatFs module and simulated IO layer that  uses \"./sdcard.image\" file as image of SD card. This file must contain whole SD card from first to last sector" OFF)
39 option(SIMU_LUA_COMPILER "Pre-compile and save Lua scripts in simulator." ON)
40 option(FAS_PROTOTYPE "Support of old FAS prototypes (different resistors)" OFF)
41 option(TEMPLATES "Model templates menu" OFF)
42 option(TRACE_SIMPGMSPACE "Turn on traces in simpgmspace.cpp" ON)
43 option(TRACE_LUA_INTERNALS "Turn on traces for Lua internals" OFF)
44 option(BINDING_OPTIONS "Allow advanced frsky bindings" OFF)
45 option(FRSKY_STICKS "Reverse sticks for FrSky sticks" OFF)
46 option(NANO "Use nano newlib and binalloc")
47 option(NIGHTLY_BUILD_WARNING "Warn this is a nightly build" OFF)
48 option(USEHORUSBT "X9E BT module replaced by Horus BT module" OFF)
50 # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags.
51 set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).")
52 set(FIRMWARE_C_FLAGS_DEBUG "-g" CACHE STRING "Additional flags for firmware target (Debug config) c compiler (note: CMAKE_C_FLAGS_DEBUG is ignored for firmware/bootloader).")
53 set(FIRMWARE_CXX_FLAGS "" CACHE STRING "Additional flags for firmware target c++ compiler (note: all CMAKE_CXX_FLAGS[_*] are ignored for firmware/bootloader).")
54 set(FIRMWARE_CXX_FLAGS_DEBUG "-g" CACHE STRING "Additional flags for firmware target (Debug config) c++ compiler (note: CMAKE_CXX_FLAGS_DEBUG is ignored for firmware/bootloader).")
56 # Python check
57 find_package("PythonInterp")
58 if(PYTHONINTERP_FOUND)
59   message(STATUS "Python found, version: ${PYTHON_VERSION_STRING}")
60 else()
61   message(WARNING "Python not found! Most firmware and simu flavors not buildable.")
62   set(LUA NO)
63 endif()
65 set(THIRDPARTY_DIR thirdparty)
66 set(LUA_DIR ${THIRDPARTY_DIR}/Lua/src)
67 set(COOS_DIR ${THIRDPARTY_DIR}/CoOS)
68 set(FATFS_DIR ${THIRDPARTY_DIR}/FatFs)
69 set(RADIO_BIN_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
71 configure_file(stamp.h.in stamp.h @ONLY)
73 add_subdirectory(translations)
74 add_subdirectory(bitmaps)
75 add_subdirectory(fonts)
77 set(EEPROM_VARIANT  0)
78 set(GVARS_VARIANT   1)
79 set(FRSKY_VARIANT   2)
80 set(3POS_VARIANT    4)
81 set(MAVLINK_VARIANT 8)
82 set(M2561_VARIANT   16384)
83 set(M128_VARIANT    32768)
85 set(FIRMWARE_DEPENDENCIES firmware_translations)
87 set(FATFS_SRC
88   ${FATFS_DIR}/ff.c
89   ${FATFS_DIR}/fattime.c
90   ${FATFS_DIR}/option/ccsbcs.c
93 if(PCB STREQUAL X12S OR PCB STREQUAL X10)
94   include(targets/horus/CMakeLists.txt)
95 elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X7S)
96   include(targets/taranis/CMakeLists.txt)
97 elseif(PCB STREQUAL SKY9X OR PCB STREQUAL 9XRPRO OR PCB STREQUAL AR9X)
98   include(targets/sky9x/CMakeLists.txt)
99 elseif(PCB STREQUAL 9X OR PCB STREQUAL 9XR OR PCB STREQUAL 9X128 OR PCB STREQUAL 9XR128)
100   include(targets/9x/CMakeLists.txt)
101 elseif(PCB STREQUAL 9X2561)
102   set(ARCH AVR)
103   set(MCU atmega2561)
104   string(TOLOWER ${PCB} FLAVOUR)
105   set(EEPROM EEPROM_RLC)
106   set(SDCARD NO)
107   add_definitions(-DEEPROM_VARIANT=${M2561_VARIANT})
108   set(GUI_DIR 128x64)
109   set(TARGET_DIR 9x)
110   set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps)
111   add_definitions(-DPCBSTD -DPCB${PCB} -DCPUM2561)
112   set(TARGET_SRC ${TARGET_SRC} board.cpp)
113   set(GUI_SRC
114     ${GUI_SRC}
115     model_inputs_mixes.cpp
116     radio_diagkeys.cpp
117     radio_diaganas.cpp)
118   if(SP22)
119     add_definitions(-DSP22)
120   endif()
121   if(PWM_BACKLIGHT)
122     add_definitions(-DPWM_BACKLIGHT)
123   endif()
124   set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} lcd_driver.cpp)
125 elseif(PCB STREQUAL GRUVIN9X)
126   include(targets/gruvin9x/CMakeLists.txt)
127 elseif(PCB STREQUAL MEGA2560)
128   include(targets/mega2560/CMakeLists.txt)
129 else()
130   message(FATAL_ERROR "Unknown PCB '${PCB}'")
131 endif()
133 if(NOT PCB STREQUAL 9XR AND NOT PCB STREQUAL 9XRPRO)
134   option(DBLKEYS "Double Keys" ON)
135   if(DBLKEYS)
136     add_definitions(-DDBLKEYS)
137   endif()
138 endif()
140 if(CPU_TYPE STREQUAL STM32F4)
141   include(targets/common/arm/stm32/f4/CMakeLists.txt)
142 endif()
144 if(CPU_TYPE STREQUAL STM32F2)
145   include(targets/common/arm/stm32/f2/CMakeLists.txt)
146 endif()
148 if(CPU_FAMILY STREQUAL STM32)
149   include(targets/common/arm/stm32/CMakeLists.txt)
150 endif()
152 if(ARCH STREQUAL ARM)
153   include(targets/common/arm/CMakeLists.txt)
154 else()
155   include(targets/common/avr/CMakeLists.txt)
156 endif()
158 include_directories(targets/${TARGET_DIR} ${THIRDPARTY_DIR})
160 foreach(LANGUAGE ${GUI_LANGUAGES})
161   if(TRANSLATIONS STREQUAL ${LANGUAGE})
162     add_definitions(-DTRANSLATIONS_${LANGUAGE} -DTRANSLATIONS="${LANGUAGE}")
163   endif()
164 endforeach()
166 set(SRC ${SRC} debug.cpp)
168 if(${EEPROM} STREQUAL SDCARD)
169   set(SRC ${SRC} storage/storage_common.cpp storage/sdcard_raw.cpp)
170 elseif(${EEPROM} STREQUAL EEPROM_RLC)
171   set(SRC ${SRC} storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_rlc.cpp)
172   add_definitions(-DEEPROM -DEEPROM_RLC)
173 else()
174   set(SRC ${SRC} storage/storage_common.cpp storage/eeprom_common.cpp storage/eeprom_raw.cpp)
175   add_definitions(-DEEPROM -DEEPROM_RAW)
176 endif()
178 if(ARCH STREQUAL ARM AND NOT PCB STREQUAL X12S AND NOT PCB STREQUAL X10 AND NOT PCB STREQUAL FLAMENCO)
179   set(SRC ${SRC} storage/eeprom_conversions.cpp)
180 endif()
182 add_definitions(-DFLAVOUR="${FLAVOUR}")
184 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
185 include_directories(${CMAKE_CURRENT_BINARY_DIR})
186 include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${GUI_DIR})
188 add_subdirectory(lua)
189 include(gui/CMakeLists.txt)
191 if(RAMBACKUP)
192   add_definitions(-DRAMBACKUP)
193   set(SRC ${SRC} storage/rambackup.cpp storage/rlc.cpp)
194 endif()
196 if(TEMPLATES)
197   add_definitions(-DTEMPLATES)
198   set(SRC ${SRC} templates.cpp)
199   set(GUI_SRC ${GUI_SRC} model_templates.cpp)
200 endif()
202 if(NOT LUA STREQUAL NO)
203   add_definitions(-DLUA)
204   if(LUA_COMPILER)
205     add_definitions(-DLUA_COMPILER)
206   endif()
207   if(NOT "${LUA_SCRIPT_LOAD_MODE}" STREQUAL "")
208     add_definitions(-DLUA_SCRIPT_LOAD_MODE="${LUA_SCRIPT_LOAD_MODE}")
209   endif()
210   include_directories(${LUA_DIR})
211   set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} ${LUA_EXPORT})
212   if(LUA STREQUAL YES)
213     add_definitions(-DLUA_MODEL_SCRIPTS)
214     set(GUI_SRC ${GUI_SRC} model_custom_scripts.cpp)
215   endif()
216   set(SRC ${SRC} lua/interface.cpp lua/api_general.cpp lua/api_lcd.cpp lua/api_model.cpp)
217   if(PCB STREQUAL X12S OR PCB STREQUAL X10)
218     set(SRC ${SRC} lua/widgets.cpp)
219   endif()
220   set(LUA_SRC lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c
221     lstate.c lstring.c ltable.c lrotable.c ltm.c lundump.c lvm.c lzio.c linit.c
222     lbaselib.c lmathlib.c lbitlib.c loadlib.c lauxlib.c ltablib.c lcorolib.c liolib.c lstrlib.c
223     )
224   foreach(FILE ${LUA_SRC})
225     set(SRC ${SRC} ${LUA_DIR}/${FILE})
226   endforeach()
227   if(MSVC)
228     # silence lots of warnings regarding "insecure" use of functions (sprintf, strcpy, etc) from Lua code
229     set(WARNING_FLAGS "${WARNING_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
230   endif()
231 endif()
233 if(HELI)
234   add_definitions(-DHELI)
235 endif()
237 if(FLIGHT_MODES)
238   add_definitions(-DFLIGHT_MODES)
239   set(GUI_SRC ${GUI_SRC} model_flightmodes.cpp)
240 endif()
242 if(CURVES)
243   add_definitions(-DCURVES)
244   set(SRC ${SRC} curves.cpp)
245 endif()
247 if(GVARS)
248   add_definitions(-DGVARS)
249   set(SRC ${SRC} gvars.cpp)
250   math(EXPR EEPROM_VARIANT ${EEPROM_VARIANT}+${GVARS_VARIANT})
251 endif()
253 if(FAI STREQUAL YES)
254   add_definitions(-DFAI)
255 elseif(FAI STREQUAL CHOICE)
256   add_definitions(-DFAI_CHOICE)
257 endif()
259 if(FAS_PROTOTYPE)
260   add_definitions(-DFAS_PROTOTYPE)
261 endif()
263 if(AUTOSOURCE)
264   add_definitions(-DAUTOSOURCE)
265 endif()
267 if(AUTOSWITCH)
268   add_definitions(-DAUTOSWITCH)
269 endif()
271 if(JITTER_MEASURE)
272   add_definitions(-DJITTER_MEASURE)
273 endif()
275 if(WATCHDOG_DISABLED)
276   add_definitions(-DWATCHDOG_DISABLED)
277 endif()
279 if(SIMU_AUDIO)
280   add_definitions(-DSIMU_AUDIO)
281 endif()
283 if(SDCARD)
284   add_definitions(-DSDCARD)
285   include_directories(${FATFS_DIR} ${FATFS_DIR}/option)
286   set(SRC ${SRC} sdcard.cpp rtc.cpp logs.cpp)
287   set(FIRMWARE_SRC ${FIRMWARE_SRC} ${FATFS_SRC})
288 endif()
290 if(SHUTDOWN_CONFIRMATION)
291   add_definitions(-DSHUTDOWN_CONFIRMATION)
292 endif()
294 if(PPM_UNIT STREQUAL US)
295   add_definitions(-DPPM_UNIT_US)
296 elseif(PPM_UNIT STREQUAL PERCENT_PREC1)
297   add_definitions(-DPPM_UNIT_PERCENT_PREC1)
298 else()
299   add_definitions(-DPPM_UNIT_PERCENT_PREC0)
300 endif()
302 if(PPM_CENTER_ADJUSTABLE)
303   add_definitions(-DPPM_CENTER_ADJUSTABLE)
304 endif()
306 if(PPM_LIMITS_SYMETRICAL)
307   add_definitions(-DPPM_LIMITS_SYMETRICAL)
308 endif()
310 if(OVERRIDE_CHANNEL_FUNCTION)
311   add_definitions(-DOVERRIDE_CHANNEL_FUNCTION)
312 endif()
314 if(DANGEROUS_MODULE_FUNCTIONS)
315   add_definitions(-DDANGEROUS_MODULE_FUNCTIONS)
316 endif()
318 if(SPLASH STREQUAL FRSKY)
319   add_definitions(-DSPLASH -DSPLASH_FRSKY)
320 elseif(NOT SPLASH STREQUAL OFF)
321   add_definitions(-DSPLASH)
322 endif()
324 if(NOT DEFAULT_MODE STREQUAL "")
325   add_definitions(-DDEFAULT_MODE=${DEFAULT_MODE})
326 endif()
328 if(TRACE_SIMPGMSPACE)
329   add_definitions(-DTRACE_SIMPGMSPACE)
330 endif()
332 if(TRACE_LUA_INTERNALS)
333   add_definitions(-DTRACE_LUA_INTERNALS_ENABLED)
334 endif()
336 if(BINDING_OPTIONS)
337   add_definitions(-DBINDING_OPTIONS)
338 endif()
340 if(FRSKY_STICKS)
341   add_definitions(-DFRSKY_STICKS)
342 endif()
344 if(NOT FONT STREQUAL "")
345   add_definitions(-DFONT=${DEFAULT_MODE})
346 endif()
348 if(EEPROM_VARIANT_NEEDED)
349   add_definitions(-DEEPROM_VARIANT=${EEPROM_VARIANT})
350 endif()
352 if(NIGHTLY_BUILD_WARNING)
353   add_definitions(-DNIGHTLY_BUILD_WARNING)
354 endif(NIGHTLY_BUILD_WARNING)
356 if(USEHORUSBT)
357   add_definitions(-DUSEHORUSBT)
358 endif(USEHORUSBT)
360 set(SRC
361   ${SRC}
362   opentx.cpp
363   functions.cpp
364   strhelpers.cpp
365   switches.cpp
366   mixer.cpp
367   stamp.cpp
368   timers.cpp
369   trainer_input.cpp
370   )
372 if(GUI)
373   add_definitions(-DGUI)
374   set(SRC
375     ${SRC}
376     keys.cpp
377     maths.cpp
378     translations.cpp
379     gui/gui_common.cpp
380     )
381   foreach(FILE ${GUI_SRC})
382     set(SRC ${SRC} gui/${GUI_DIR}/${FILE})
383   endforeach()
384   if(ARCH STREQUAL ARM)
385     set(SRC
386       ${SRC}
387       gui/gui_common_arm.cpp
388       )
389   endif()
390 endif()
392 foreach(FILE ${TARGET_SRC})
393   set(SRC targets/${TARGET_DIR}/${FILE} ${SRC})
394 endforeach()
396 foreach(FILE ${FIRMWARE_TARGET_SRC})
397   set(FIRMWARE_SRC ${FIRMWARE_SRC} targets/${TARGET_DIR}/${FILE})
398 endforeach()
400 foreach(FILE ${PULSES_SRC})
401   set(SRC ${SRC} pulses/${FILE})
402 endforeach()
404 add_definitions(-DCORRECT_NEGATIVE_SHIFTS)
406 if(NOT MSVC)
407   set(WARNING_FLAGS "${WARNING_FLAGS} -Wall -Wno-strict-aliasing -Wformat -Wreturn-type -Wunused -Wuninitialized -Wunknown-pragmas -Wno-switch -Wtype-limits")
408   if(WARNINGS_AS_ERRORS)
409     set(WARNING_FLAGS "${WARNING_FLAGS} -Werror")
410   endif(WARNINGS_AS_ERRORS)
411 else()
412   add_definitions(-DHAVE_STRUCT_TIMESPEC)  # this is for pthread.h
413   if(WARNINGS_AS_ERRORS)
414     set(WARNING_FLAGS "${WARNING_FLAGS} /WX")
415   endif(WARNINGS_AS_ERRORS)
416 endif()
418 add_subdirectory(targets/simu)
419 if(NOT MSVC)
420   add_subdirectory(tests)
421 endif()
423 set(SRC ${SRC} ${FIRMWARE_SRC})
426 ##### firmware target #####
428 option(FIRMWARE_TARGET "Configure Firmware target (can be turned of for compiling Companion only)" ON)
429 if(NOT FIRMWARE_TARGET)
430   message(STATUS "firmware target disabled")
431   return()
432 endif()
434 set(CMAKE_EXECUTABLE_SUFFIX ".elf")
435 # trick to remove the -rdynamic and --out-implib issues
436 set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
437 set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
438 # similar for -mmacosx-version-min="
439 set(CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG "")
440 set(CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG "")
441 # reset some CMake default flags which assume optimization levels/etc
442 set(CMAKE_C_FLAGS "${FIRMWARE_C_FLAGS}")
443 set(CMAKE_C_FLAGS_DEBUG "${FIRMWARE_C_FLAGS_DEBUG}")
444 set(CMAKE_C_FLAGS_RELEASE "")
445 set(CMAKE_C_FLAGS_MINSIZEREL "")
446 set(CMAKE_C_FLAGS_RELWITHDEBINFO "")
447 set(CMAKE_CXX_FLAGS "${FIRMWARE_CXX_FLAGS}")
448 set(CMAKE_CXX_FLAGS_DEBUG "${FIRMWARE_CXX_FLAGS_DEBUG}")
449 set(CMAKE_CXX_FLAGS_RELEASE "")
450 set(CMAKE_CXX_FLAGS_MINSIZEREL "")
451 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
452 # customize linker command
453 set(CMAKE_EXE_LINKER_FLAGS "")
454 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET>")
455 set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET>")
457 use_cxx11()  # ensure gnu++11 in CXX_FLAGS with CMake < 3.1
459 find_program(BASH bash HINTS "c:/cygwin/bin/" "c:/msys/bin/" DOC "bash shell for firmware size report (eg. c:/cygwin/bin/bash.exe on Windows).")
461 if(NOT MSVC)
462   set(OPT s)
464   if(ARCH STREQUAL ARM)
466     enable_language(ASM)
467     set(CMAKE_C_COMPILER arm-none-eabi-gcc)
468     set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
469     set(CMAKE_ASM_COMPILER arm-none-eabi-as)
471     set(CMAKE_SYSTEM_NAME Generic)
472     set(CMAKE_SYSTEM_VERSION 1)
473     set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -o <OBJECT> <SOURCE>")
475     set(COMMON_FLAGS "-mcpu=${MCU} -mthumb -fomit-frame-pointer -fverbose-asm -Wa,-ahlms=firmware.lst -O${OPT} -gdwarf-2 -DHSE_VALUE=${HSE_VALUE} -fno-exceptions -fdata-sections -ffunction-sections ${WARNING_FLAGS}")
476     set(COMMON_FLAGS "${COMMON_FLAGS} ${FPU_FLAGS}")
478     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS} -Wimplicit")
479     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}")
481     # these are in addition to CMAKE_CXX_FLAGS
482     set(CMAKE_EXE_LINKER_FLAGS "-lm -T${RADIO_SRC_DIRECTORY}/${LINKER_SCRIPT} -Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections")
483     if(SEMIHOSTING)
484       add_definitions(-DSEMIHOSTING)
485       set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=rdimon.specs")
486     endif()
487     # Use newlib nano, which saves a few kilobytes.
488     if(NOT NANO STREQUAL NO)
489       set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=nano.specs")
490       if(NOT LUA STREQUAL NO)
491         # Lua needs %g and %f
492         set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u _printf_float -u _scanf_float")
493       endif()
494       # Nano's malloc does work well with lua, use our own
495       add_definitions(-DUSE_BIN_ALLOCATOR)
496       set(SRC ${SRC} bin_allocator.cpp)
497     endif()
500     if(PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL X7S)
501       add_subdirectory(targets/${TARGET_DIR}/bootloader)
502       include_directories(${CMAKE_CURRENT_BINARY_DIR}/targets/${TARGET_DIR}/bootloader)
503       set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} bootloader)
504     elseif(OPENRC_BOOTLOADER)
505       # We fetch Mike's bootloader as it is not included inside OpenTX
506       message(STATUS "Downloading Mike's bootloader: https://github.com/MikeBland/OpenRcBootloader/releases/download/V1.9/${OPENRC_BOOTLOADER}")
507       file(DOWNLOAD https://github.com/MikeBland/OpenRcBootloader/releases/download/V1.9/${OPENRC_BOOTLOADER} ${CMAKE_CURRENT_BINARY_DIR}/bootloader.lbm STATUS status)
508       list(GET status 0 error_code)
509       if(error_code)
510         list(GET status 1 error_message)
511         message(FATAL_ERROR "Download failed: ${error_message}")
512       endif()
513     endif()
515     add_executable(firmware ${SRC} ${FIRMWARE_HEADERS})
516     link_libraries(firmware -lstdc++)
517     add_dependencies(firmware ${FIRMWARE_DEPENDENCIES})
519     add_custom_command(
520       TARGET firmware POST_BUILD
521       COMMAND arm-none-eabi-objcopy -O binary firmware.elf firmware.bin
522       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
523     )
525     find_program(GAWK gawk HINTS "c:/cygwin/bin/" "c:/msys/bin/" DOC "gawk for firmware size report.")  # OS X might only have "awk"
526     if (BASH AND GAWK)
527       add_custom_target(firmware-size
528         COMMAND ${BASH} -kc '${RADIO_DIRECTORY}/util/elf-size-report.sh --mcu=${CPU_TYPE_FULL} ${SIZE_TARGET_MEM_DEFINE} firmware.elf'
529         DEPENDS firmware
530         WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
531         )
532     else()
533       add_custom_target(firmware-size
534         COMMAND arm-none-eabi-size -A firmware.elf
535         DEPENDS firmware
536         WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
537         )
538     endif()
540   else()  # AVR
542     set(CMAKE_C_COMPILER avr-gcc)
543     set(CMAKE_CXX_COMPILER avr-gcc)
545     set(COMMON_FLAGS "-mmcu=${MCU} -DF_CPU=16000000UL -O${OPT} -gdwarf-2 -fno-exceptions -flto -fwhole-program -fno-inline-small-functions -mstrict-X ${WARNING_FLAGS}")
546     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}")
547     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}")
548     set(CMAKE_EXE_LINKER_FLAGS "-Wno-uninitialized")  # bogus "uninitialized" warnings from ld
550     include_directories(storage gui/${GUI_DIR})
552     set(ALLSRC ${PROJECT_BINARY_DIR}/allsrc.cpp)
553     if (BASH AND NOT WIN32)
554       add_custom_command(
555         OUTPUT ${ALLSRC}
556         COMMAND ${BASH} -kc 'rm -f ${ALLSRC}\; for f in ${SRC}\; do echo "\\# 1 \\\"$$f\\\"" >> ${ALLSRC}\; cat "$$f" >> ${ALLSRC}\; done'
557         WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}
558         DEPENDS ${SRC}
559         )
560     elseif(WIN32)
561       string(REPLACE "/" "\\" SRC_WIN "${SRC}")
562       string(REPLACE "/" "\\" ALLSRC_WIN "${ALLSRC}")
563       set(ALLSRC_BAT
564           "setlocal EnableDelayedExpansion"
565           "del \"${ALLSRC_WIN}\""
566           "for %%f in (${SRC_WIN}) do ("
567             "set p=\"%%f\""
568             "set p=!p:^\\=/! \necho \# 1 !p! >> \"${ALLSRC_WIN}\""
569             "type %%f >> \"${ALLSRC_WIN}\""
570           ")\n"
571         )
572       string(REPLACE ";" "\n" ALLSRC_BAT "${ALLSRC_BAT}")
573       file(WRITE "${ALLSRC}.bat" "${ALLSRC_BAT}")
574       add_custom_command(
575         OUTPUT ${ALLSRC}
576         COMMAND "${ALLSRC}.bat"
577         WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}
578         DEPENDS ${SRC}
579         )
580     else()
581       set(ALLSRC ${SRC})
582     endif()
583     add_executable(firmware ${ALLSRC})
585     add_dependencies(firmware ${FIRMWARE_DEPENDENCIES})
587     add_custom_command(
588       TARGET firmware POST_BUILD
589       COMMAND avr-objcopy -O ihex -R .eeprom firmware.elf firmware.hex
590       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
591       )
593     add_custom_target(firmware.lss
594       COMMAND avr-objdump -h -S firmware.elf > firmware.lss
595       DEPENDS firmware
596       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
597       )
599     add_custom_target(firmware-size
600       COMMAND avr-size --format=avr --mcu=${MCU} firmware.elf
601       DEPENDS firmware
602       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
603       )
605   endif()  # ARM or AVR
607   if(CPU_FAMILY STREQUAL STM32)
608     add_custom_target(flash
609       COMMAND dfu-util --alt 0 --dfuse-address 0x08000000:leave -d 0483:df11 -D firmware.bin
610       DEPENDS firmware
611       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
612     )
614     add_custom_target(jtag-flash
615       COMMAND st-flash --reset write firmware.bin 0x8000000
616       DEPENDS firmware
617       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
618       )
619   else()
620     add_custom_target(flash
621       COMMAND avrdude -c usbasp -p ${AVRDUDE_MCU} -U flash:w:firmware.hex:i
622       DEPENDS firmware
623       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
624       )
625   endif()
627   PrintTargetReport("firmware")
629 endif(NOT MSVC)