devices.cmake 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. function(stm32_util_create_family_targets FAMILY)
  2. set(CORES ${ARGN})
  3. list(LENGTH CORES NUM_CORES)
  4. if(${NUM_CORES} EQUAL 0)
  5. set(CORE "")
  6. set(CORE_C "")
  7. elseif(${NUM_CORES} EQUAL 1)
  8. set(CORE "_${CORES}")
  9. set(CORE_C "::${CORES}")
  10. else()
  11. message(FATAL_ERROR "Expected at most one core for family ${FAMILY}: ${CORES}")
  12. endif()
  13. if(NOT (TARGET STM32::${FAMILY}${CORE_C}))
  14. add_library(STM32::${FAMILY}${CORE_C} INTERFACE IMPORTED)
  15. # Set compiler flags for target
  16. # -Wall: all warnings activated
  17. # -ffunction-sections -fdata-sections: remove unused code
  18. target_compile_options(STM32::${FAMILY}${CORE_C} INTERFACE
  19. -mthumb -Wall -ffunction-sections -fdata-sections
  20. )
  21. # Set linker flags
  22. # -mthumb: Generate thumb code
  23. # -Wl,--gc-sections: Remove unused code
  24. target_link_options(STM32::${FAMILY}${CORE_C} INTERFACE
  25. -mthumb -Wl,--gc-sections
  26. )
  27. target_compile_definitions(STM32::${FAMILY}${CORE_C} INTERFACE
  28. STM32${FAMILY}
  29. )
  30. endif()
  31. foreach(TYPE ${STM32_${FAMILY}_TYPES})
  32. if(NOT (TARGET STM32::${TYPE}${CORE_C}))
  33. add_library(STM32::${TYPE}${CORE_C} INTERFACE IMPORTED)
  34. target_link_libraries(STM32::${TYPE}${CORE_C} INTERFACE STM32::${FAMILY}${CORE_C})
  35. target_compile_definitions(STM32::${TYPE}${CORE_C} INTERFACE
  36. STM32${TYPE}
  37. )
  38. endif()
  39. endforeach()
  40. endfunction()
  41. set(STM32_ALL_DEVICES "")
  42. set(STM32_SUPPORTED_FAMILIES_LONG_NAME "")
  43. include(stm32/c0)
  44. include(stm32/f0)
  45. include(stm32/f1)
  46. include(stm32/f2)
  47. include(stm32/f3)
  48. include(stm32/f4)
  49. include(stm32/f7)
  50. include(stm32/g0)
  51. include(stm32/g4)
  52. include(stm32/h5)
  53. include(stm32/h7)
  54. include(stm32/l0)
  55. include(stm32/l1)
  56. include(stm32/l4)
  57. include(stm32/l5)
  58. include(stm32/u0)
  59. include(stm32/u5)
  60. include(stm32/wb)
  61. include(stm32/wl)
  62. include(stm32/mp1)
  63. # Store a list of devices into a given STM_DEVICES list.
  64. # You can also specify multiple device families. Examples:
  65. # Get list of all devices for H7 family: stm32_get_devices_by_family(STM_DEVICES FAMILY H7)
  66. # Get list of all devices: stm32_get_devices_by_family(STM_DEVICES)
  67. function(stm32_get_devices_by_family STM_DEVICES)
  68. # Specify keywords for argument parsing here
  69. set(ARG_OPTIONS "")
  70. set(ARG_SINGLE "")
  71. set(ARG_MULTIPLE FAMILY)
  72. # Parse arguments. Multiple families can be specified and will be stored in ARG_<KeywordName>
  73. cmake_parse_arguments(PARSE_ARGV 1 ARG "${ARG_OPTIONS}" "${ARG_SINGLE}" "${ARG_MULTIPLE}")
  74. stm32_dev_parser_check()
  75. # Build a list of families by filtering the whole list with the specified families
  76. if(ARG_FAMILY)
  77. set(RESULTING_DEV_LIST "")
  78. foreach(FAMILY ${ARG_FAMILY})
  79. set(STM_DEVICE_LIST ${STM32_ALL_DEVICES})
  80. list(FILTER STM_DEVICE_LIST INCLUDE REGEX "^${FAMILY}")
  81. list(APPEND RESULTING_DEV_LIST ${STM_DEVICE_LIST})
  82. if(NOT STM_DEVICE_LIST)
  83. message(WARNING "No devices found for given family ${FAMILY}")
  84. endif()
  85. endforeach()
  86. else()
  87. # No family argument, so get list of all devices
  88. set(RESULTING_DEV_LIST ${STM32_ALL_DEVICES})
  89. endif()
  90. set(${STM_DEVICES} ${RESULTING_DEV_LIST} PARENT_SCOPE)
  91. endfunction()
  92. # Print the devices for a given family. You can also specify multiple device families.
  93. # Example usage:
  94. # Print devices for H7 family: stm32_print_devices_by_family(FAMILY H7)
  95. # Print all devices: stm32_print_devices_by_family()
  96. function(stm32_print_devices_by_family)
  97. # Specify keywords for argument parsing here
  98. set(ARG_OPTIONS "")
  99. set(ARG_SINGLE "")
  100. set(ARG_MULTIPLE FAMILY)
  101. # Parse arguments. Multiple families can be specified and will be stored in ARG_<KeywordName>
  102. cmake_parse_arguments(PARSE_ARGV 0 ARG "${ARG_OPTIONS}" "${ARG_SINGLE}" "${ARG_MULTIPLE}")
  103. stm32_dev_parser_check()
  104. if(ARG_FAMILY)
  105. # print devices one family per line
  106. foreach(FAMILY ${ARG_FAMILY})
  107. stm32_get_devices_by_family(STM_DEVICES FAMILY ${FAMILY})
  108. stm32_pretty_print_dev_list(${FAMILY} "${STM_DEVICES}")
  109. endforeach()
  110. else()
  111. # print all devices
  112. stm32_get_devices_by_family(STM_DEVICES)
  113. stm32_pretty_print_dev_list("all" "${STM_DEVICES}")
  114. endif()
  115. endfunction()
  116. # The arguments checked in this macro are filled by cmake_parse_argument
  117. macro(stm32_dev_parser_check)
  118. # contains unexpected arguments (unknown keywords beofre ARG_MULTIPLE)
  119. if(ARG_UNPARSED_ARGUMENTS)
  120. message(WARNING "Unknown keyword(s) ${ARG_UNPARSED_ARGUMENTS} will be ignored")
  121. endif()
  122. # is populated if ARG_SINGLE or ARG_MULTIPLE is used without values
  123. if(ARG_KEYWORDS_MISSING_VALUES)
  124. message(FATAL_ERROR "Keyword ${ARG_KEYWORDS_MISSING_VALUES} expects values")
  125. endif()
  126. endmacro()
  127. # Pretty printer to limit amount of list entries printed per line
  128. macro(stm32_pretty_print_dev_list FAMILIES STM_DEVICES)
  129. if(${FAMILIES} STREQUAL "all")
  130. message(STATUS "Devices for all families")
  131. else()
  132. message(STATUS "Devices for ${FAMILIES} family")
  133. endif()
  134. set(TMP_LIST "")
  135. foreach(STM_DEVICE ${STM_DEVICES})
  136. list(APPEND TMP_LIST ${STM_DEVICE})
  137. list(LENGTH TMP_LIST CURR_LEN)
  138. if(CURR_LEN EQUAL 10)
  139. message(STATUS "${TMP_LIST}")
  140. set(TMP_LIST "")
  141. endif()
  142. endforeach()
  143. if(TMP_LIST)
  144. message(STATUS "${TMP_LIST}")
  145. endif()
  146. endmacro()
  147. include(FetchContent)
  148. FetchContent_Declare(
  149. STM32-CMSIS
  150. GIT_REPOSITORY https://github.com/STMicroelectronics/cmsis_core/
  151. GIT_TAG v5.6.0
  152. GIT_PROGRESS TRUE
  153. )
  154. foreach(FAMILY ${STM32_FETCH_FAMILIES})
  155. string(TOLOWER ${FAMILY} FAMILY_L)
  156. FetchContent_Declare(
  157. STM32Cube${FAMILY}
  158. GIT_REPOSITORY https://github.com/STMicroelectronics/STM32Cube${FAMILY}/
  159. GIT_TAG ${CUBE_${FAMILY}_VERSION}
  160. GIT_PROGRESS TRUE
  161. )
  162. if(CMSIS_${FAMILY}_VERSION STREQUAL cube)
  163. set(STM32_USE_CMSIS_FROM_CUBE_${FAMILY} ON)
  164. else()
  165. FetchContent_Declare(
  166. STM32-CMSIS-${FAMILY}
  167. GIT_REPOSITORY https://github.com/STMicroelectronics/cmsis_device_${FAMILY_L}/
  168. GIT_TAG ${CMSIS_${FAMILY}_VERSION}
  169. GIT_PROGRESS TRUE
  170. )
  171. endif()
  172. if(HAL_${FAMILY}_VERSION STREQUAL cube)
  173. set(STM32_USE_HAL_FROM_CUBE_${FAMILY} ON)
  174. else()
  175. FetchContent_Declare(
  176. STM32-HAL-${FAMILY}
  177. GIT_REPOSITORY https://github.com/STMicroelectronics/stm32${FAMILY_L}xx_hal_driver/
  178. GIT_TAG ${HAL_${FAMILY}_VERSION}
  179. GIT_PROGRESS TRUE
  180. )
  181. endif()
  182. endforeach()
  183. function(stm32_fetch_cube)
  184. foreach(FAMILY ${ARGV})
  185. set(CUBE_NAME STM32Cube${FAMILY})
  186. string(TOLOWER ${CUBE_NAME} CUBE_NAME_L)
  187. if(STM32_CUBE_${FAMILY}_PATH)
  188. message(VERBOSE "STM32_CUBE_${FAMILY}_PATH specified, skipping fetch for ${CUBE_NAME}")
  189. continue()
  190. endif()
  191. FetchContent_MakeAvailable(${CUBE_NAME})
  192. set(STM32_CUBE_${FAMILY}_PATH ${${CUBE_NAME_L}_SOURCE_DIR} PARENT_SCOPE)
  193. endforeach()
  194. endfunction()
  195. function(stm32_fetch_cmsis)
  196. if(NOT STM32_CMSIS_PATH)
  197. FetchContent_MakeAvailable(STM32-CMSIS)
  198. set(STM32_CMSIS_PATH ${stm32-cmsis_SOURCE_DIR} PARENT_SCOPE)
  199. else()
  200. message(INFO "STM32_CMSIS_PATH specified, skipping fetch for STM32-CMSIS")
  201. endif()
  202. foreach(FAMILY ${ARGV})
  203. if(STM32_USE_CMSIS_FROM_CUBE_${FAMILY})
  204. stm32_fetch_cube(${FAMILY})
  205. message(STATUS "Cube fetched for ${FAMILY} at ${STM32_CUBE_${FAMILY}_PATH}")
  206. set(STM32_CMSIS_${FAMILY}_PATH ${STM32_CUBE_${FAMILY}_PATH}/Drivers/CMSIS/Device/ST/STM32${FAMILY}xx PARENT_SCOPE)
  207. else()
  208. set(CMSIS_NAME STM32-CMSIS-${FAMILY})
  209. string(TOLOWER ${CMSIS_NAME} CMSIS_NAME_L)
  210. if(STM32_CMSIS_${FAMILY}_PATH)
  211. message(INFO "STM32_CMSIS_${FAMILY}_PATH specified, skipping fetch for ${CMSIS_NAME}")
  212. continue()
  213. endif()
  214. FetchContent_MakeAvailable(${CMSIS_NAME})
  215. set(STM32_CMSIS_${FAMILY}_PATH ${${CMSIS_NAME_L}_SOURCE_DIR} PARENT_SCOPE)
  216. endif()
  217. endforeach()
  218. endfunction()
  219. function(stm32_fetch_hal)
  220. foreach(FAMILY ${ARGV})
  221. if(STM32_USE_HAL_FROM_CUBE_${FAMILY})
  222. stm32_fetch_cube(${FAMILY})
  223. message(STATUS "Cube fetched for ${FAMILY} at ${STM32_CUBE_${FAMILY}_PATH}")
  224. set(STM32_HAL_${FAMILY}_PATH ${STM32_CUBE_${FAMILY}_PATH}/Drivers/STM32${FAMILY}xx_HAL_Driver PARENT_SCOPE)
  225. else()
  226. set(HAL_NAME STM32-HAL-${FAMILY})
  227. string(TOLOWER ${HAL_NAME} HAL_NAME_L)
  228. if(STM32_HAL_${FAMILY}_PATH)
  229. message(INFO "STM32_HAL_${FAMILY}_PATH specified, skipping fetch for ${HAL_NAME}")
  230. continue()
  231. endif()
  232. FetchContent_MakeAvailable(${HAL_NAME})
  233. set(STM32_HAL_${FAMILY}_PATH ${${HAL_NAME_L}_SOURCE_DIR} PARENT_SCOPE)
  234. endif()
  235. endforeach()
  236. endfunction()