CMakeLists.txt 15.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
cmake_minimum_required(VERSION 3.11)
project(connectivity)

#[[
    This CMake file uses directory structure conventions in the SDKs 
    supported (v11 and v15) to supply information to targets and create them.
]]

set(GIT_REQUIRED_VERSION "2.19.0")

include(../cmake/nrf-download-distfile.cmake)
include(../cmake/nrf-apply-patches.cmake)
include(./cmake/util.cmake)

find_program(MAKE "make")
find_program(MERGEHEX "mergehex" HINTS "c:/Program Files (x86)/Nordic Semiconductor/nrf5x/bin")
find_program(NRFUTIL "nrfutil")
find_program(GIT "git")

if(NOT DEFINED CONNECTIVITY_VERSION)
    message(FATAL_ERROR "CONNECTIVITY_VERSION not provided, terminating compilation.")
endif()

if(NOT DEFINED ENV{GCCARMEMB_TOOLCHAIN_PATH})
    message(FATAL_ERROR "GNU Tools ARM Embedded environment variable GCCARMEMB_TOOLCHAIN_PATH not set. Stopping build.")
else()
    set(GCC_TOOLCHAIN_PATH "$ENV{GCCARMEMB_TOOLCHAIN_PATH}")
endif()

#message(STATUS "GCC_TOOLCHAIN_PATH: ${GCC_TOOLCHAIN_PATH}")
#message(STATUS "MERGEHEX: ${MERGEHEX}")
#message(STATUS "NRFUTIL: ${NRFUTIL}")

set(PCA_BLACKLIST "pca10036;")

if(NOT MERGEHEX)
    message(FATAL_ERROR "mergehex not found, not able to merge connectivity firmware with SoftDevice.")
endif()

if(NOT NRFUTIL)
    message(FATAL_ERROR "nrfutil not found, not able to create DFU packages of connectivity firmware.")
endif()

if(NOT MAKE)
    message(FATAL_ERROR "make not found, not able to compile connectivity firmware.")
endif()

if(NOT GIT)
    message(FATAL_ERROR "git not found, not able to compile connectivity firmware.")
endif()

execute_process(
    COMMAND ${GIT} "--version"
    OUTPUT_VARIABLE version_info
    RESULT_VARIABLE result
)

string(STRIP "${version_info}" version_info)

string(REGEX MATCH "([0-9]+\.[0-9]+\.[0-9]+)" found_version "${version_info}")

if (found_version VERSION_LESS "2.19.0")
    message(FATAL_ERROR "git version ${found_version} found, version ${GIT_REQUIRED_VERSION} or higher required.")
endif()

function(nrf_get_hex_paths SDK_ROOT SDK_VERSION PROJECT_PATH APP_HEX_PATH SOFTDEVICE_HEX_PATH)
    set(PROJECT_NAME)
    set(PCA_TYPE)
    set(SOFTDEVICE_TYPE_VERSION)
    set(TRANSPORT)

    nrf_extract_info_from_path(${PROJECT_PATH} PROJECT_NAME PCA_TYPE SOFTDEVICE_TYPE_VERSION TRANSPORT)
    set(SOFTDEVICE_SEARCH_PATH "${SDK_ROOT}/components/softdevice/${SOFTDEVICE_TYPE_VERSION}/hex/*.hex")
    file(GLOB FOUND_SOFTDEVICE_HEX "${SOFTDEVICE_SEARCH_PATH}")

    if(FOUND_SOFTDEVICE_HEX STREQUAL "")
        message(FATAL_ERROR "No SoftDevice found for project ${PROJECT_PATH}. Tried to locate it in ${SOFTDEVICE_SEARCH_PATH}")
    endif()

    set(ALTERNATIVE_SOFTDEVICE_HEX)
    nrf_find_alternative_softdevice(${FOUND_SOFTDEVICE_HEX} ALTERNATIVE_SOFTDEVICE_HEX)

    if(ALTERNATIVE_SOFTDEVICE_HEX)
        set(FOUND_SOFTDEVICE_HEX "${ALTERNATIVE_SOFTDEVICE_HEX}")
    endif()

    set(SOFTDEVICE_HEX_PATH "${FOUND_SOFTDEVICE_HEX}" PARENT_SCOPE)

    if(${PCA_TYPE} STREQUAL "pca10028" OR ${PCA_TYPE} STREQUAL "pca10031")
        if(SDK_VERSION EQUAL 11)
            set(APP_HEX_PATH "${PROJECT_PATH}/_build/nrf51422_xxac_s130.hex" PARENT_SCOPE)
        else()
            message(STATUS "${PCA_TYPE} is not supported in SDK ${SDK_VERSION}")
        endif()
    elseif(${PCA_TYPE} STREQUAL "pca10036")
        if(SDK_VERSION EQUAL 11)
            set(APP_HEX_PATH "${PROJECT_PATH}/_build/nrf52832_xxaa_s132.hex" PARENT_SCOPE)
        else()
            message(STATUS "${PCA_TYPE} is not supported in SDK ${SDK_VERSION}")
        endif()
    elseif(${PCA_TYPE} STREQUAL "pca10040")
        if(SDK_VERSION EQUAL 11)
            set(APP_HEX_PATH "${PROJECT_PATH}/_build/nrf52832_xxaa_s132.hex" PARENT_SCOPE)
        else()
            set(APP_HEX_PATH "${PROJECT_PATH}/_build/nrf52832_xxaa.hex" PARENT_SCOPE)
        endif()
    elseif(${PCA_TYPE} STREQUAL "pca10056" OR ${PCA_TYPE} STREQUAL "pca10059")
        set(APP_HEX_PATH "${PROJECT_PATH}/_build/nrf52840_xxaa.hex" PARENT_SCOPE)
    else()
        message(STATUS "Not able to determine app hex path.")
    endif()
endfunction()

function(nrf_create_connectivity_compile_targets)
    set(oneValueArgs PROJECT_DIRECTORY SDK_ROOT SDK_VERSION VERSION)
    cmake_parse_arguments(nrf_create_connectivity_compile_targets "" "${oneValueArgs}" "${multipleValuesArgs}" ${ARGN})

    if(NOT DEFINED nrf_create_connectivity_compile_targets_PROJECT_DIRECTORY)
        message(FATAL_ERROR "nrf_create_connectivity_compile_targets requires a PROJECT_DIRECTORY argument.")
    endif()

    if(NOT DEFINED nrf_create_connectivity_compile_targets_VERSION)
        message(FATAL_ERROR "nrf_create_connectivity_compile_targets requires a VERSION argument.")
    endif()

    if(NOT DEFINED nrf_create_connectivity_compile_targets_SDK_ROOT)
        message(FATAL_ERROR "nrf_create_connectivity_compile_targets requires a SDK_ROOT argument.")
    endif()

    if(NOT DEFINED nrf_create_connectivity_compile_targets_SDK_VERSION)
        message(FATAL_ERROR "nrf_create_connectivity_compile_targets requires a SDK_VERSION argument.")
    endif()

    set(SDK_ROOT "${nrf_create_connectivity_compile_targets_SDK_ROOT}")
    message(STATUS "SDK_ROOT:" ${SDK_ROOT})
    set(SDK_VERSION ${nrf_create_connectivity_compile_targets_SDK_VERSION})
    set(VERSION ${nrf_create_connectivity_compile_targets_VERSION})

    set(PROJECT_FULL_PATH "${SDK_ROOT}/${nrf_create_connectivity_compile_targets_PROJECT_DIRECTORY}")
    #message(STATUS "Searching for projects within project ${PROJECT_FULL_PATH}")
    file(GLOB FOUND_PCA_PATHS "${PROJECT_FULL_PATH}/pca100[1-9][0-9]")

    foreach(PCA_PATH ${FOUND_PCA_PATHS})
        file(GLOB FOUND_PROJECTS "${PCA_PATH}/*_hci")
        #message(STATUS "Found projects: ${FOUND_PROJECTS}")

        foreach(PROJECT ${FOUND_PROJECTS})
            set(PROJECT_NAME)
            set(PCA_TYPE)
            set(SOFTDEVICE_TYPE_VERSION)
            set(TRANSPORT)
            nrf_extract_info_from_path(${PROJECT} PROJECT_NAME PCA_TYPE SOFTDEVICE_TYPE_VERSION TRANSPORT)
            set(TRANSPORTS)

            if(PROJECT_NAME AND NOT (PCA_TYPE IN_LIST PCA_BLACKLIST))
                message(STATUS "PROJECT_NAME:${PROJECT_NAME} PCA_TYPE:${PCA_TYPE} SD_TV: ${SOFTDEVICE_TYPE_VERSION} TRANSPORT:${TRANSPORT}")

                if(TRANSPORT STREQUAL "usb")
                    list(APPEND TRANSPORTS "usb")
                endif()

                if(TRANSPORT STREQUAL "uart")
                    list(APPEND TRANSPORTS "115k2")
                    list(APPEND TRANSPORTS "1m")
                endif()

                foreach(TRANSPORT ${TRANSPORTS})
                    set(ARMGCC_PROJECT_DIRECTORY "${PROJECT}/armgcc")

                    set(SOFTDEVICE_HEX_PATH)
                    set(APP_HEX_PATH)
                    nrf_get_hex_paths("${SDK_ROOT}" "${SDK_VERSION}" "${ARMGCC_PROJECT_DIRECTORY}" APP_HEX_PATH SOFTDEVICE_HEX_PATH)
                    #message(STATUS "APP_HEX_PATH: ${APP_HEX_PATH} SOFTDEVICE_HEX_PATH: ${SOFTDEVICE_HEX_PATH}")

                    set(SD_VERSION)
                    set(SOC_FAMILY)
                    set(SD_API_VERSION)
                    set(SD_ID)
                    nrf_extract_softdevice_info("${SOFTDEVICE_HEX_PATH}" SD_VERSION SOC_FAMILY SD_API_VERSION SD_ID)

181
182
                    set(CONNECTIVITY_NAME "connectivity_${VERSION}_${TRANSPORT}")
                    set(TARGET_NAME "${CONNECTIVITY_NAME}_with_${SD_VERSION}_${SD_API_VERSION}")
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

                    # Check if target name already exists
                    list(FIND CONNECTIVITY_BUILD_TARGETS "compile_${TARGET_NAME}" FOUND_TARGET)

                    if(FOUND_TARGET GREATER -1)
                        message(STATUS "Target ${TARGET_NAME} already exists.")
                    else()
                        set(COMMAND_NAME "${TARGET_NAME}_cmd")

                        set(SER_CONFIG_PATH)
                        set(MAIN_PATH)
                        nrf_configure_sdk_affected_files(${SDK_VERSION} ${SDK_ROOT} SER_CONFIG_PATH MAIN_PATH)

                        set(SER_CONFIG_IN_PATH "${SER_CONFIG_PATH}.in")
                        if(NOT EXISTS ${SER_CONFIG_IN_PATH})
                            message(FATAL_ERROR "ser_config.h.in not found. The SDK needs to be prepared. Please delete the build folder and try again  (${SDK_ROOT}).")
                        endif()

                        set(MAIN_IN_PATH "${MAIN_PATH}.in")
                        if(NOT EXISTS ${MAIN_IN_PATH})
                            message(FATAL_ERROR "main.c.in not found. The SDK needs to be prepared. Please delete the build folder and try again (${SDK_ROOT}).")
                        endif()

                        # Setup ser_config.h
                        add_custom_command(
                            OUTPUT "${COMMAND_NAME}"
                            COMMAND ${CMAKE_COMMAND} -DSDK_VERSION=${SDK_VERSION} -DSER_CONFIG_IN_PATH=${SER_CONFIG_IN_PATH} -DBAUD_RATE=${TRANSPORT} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/build_cmd_ser_config.cmake
                            WORKING_DIRECTORY ${ARMGCC_PROJECT_DIRECTORY}
                        )

                        # Setup main.c
                        add_custom_command(
                            OUTPUT "${COMMAND_NAME}"
                            APPEND COMMAND ${CMAKE_COMMAND} -DMAIN_IN_PATH=${MAIN_IN_PATH} -DCONNECTIVITY_VERSION=${VERSION} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/build_cmd_main.cmake
                        )

                        message(STATUS "Running make:${MAKE} in ARMGCC_PROJECT_DIRECTORY:${ARMGCC_PROJECT_DIRECTORY}")

                        # Compile project
                        add_custom_command(
                            OUTPUT "${COMMAND_NAME}"
                            APPEND COMMAND ${MAKE}
                        )

                        set(HEX_MERGED "${TARGET_NAME}.hex")

                        # Merge SoftDevice and application
                        add_custom_command(
                            OUTPUT "${COMMAND_NAME}"
                            APPEND COMMAND ${MERGEHEX} -m "${APP_HEX_PATH}" "${SOFTDEVICE_HEX_PATH}" -o "${HEX_MERGED}"
                        )

                        set(MAJOR)
                        set(MINOR)
                        set(PATCH)
                        nrf_extract_version_number("${SD_API_VERSION}" MAJOR MINOR PATCH)
                        set(OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/sd_api_v${MAJOR}")

                        message(STATUS "Storing files in ${OUTPUT_DIRECTORY}")

                        if(NOT EXISTS ${OUTPUT_DIRECTORY})
                            message(STATUS "Adding step to create directory ${OUTPUT_DIRECTORY} during build process")
                            add_custom_command(
                                OUTPUT "${COMMAND_NAME}"
                                APPEND COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIRECTORY}
                            )
                        endif()

                        # Copy merged file to binary directory
                        add_custom_command(
                            OUTPUT "${COMMAND_NAME}"
                            APPEND COMMAND ${CMAKE_COMMAND} -E copy "${HEX_MERGED}" "${OUTPUT_DIRECTORY}"
                        )

                        # Create a DFU package if it is a nRF52 device with USB support
                        if(SOC_FAMILY EQUAL 52 AND TRANSPORT STREQUAL "usb")
                            if(PCA_TYPE STREQUAL "pca10056" OR PCA_TYPE STREQUAL "pca10059")
                                set(DFU_PKG "${TARGET_NAME}_dfu_pkg.zip")

                                add_custom_command(
                                    OUTPUT "${COMMAND_NAME}"
                                    APPEND COMMAND ${NRFUTIL} pkg generate "--application" "${APP_HEX_PATH}" "--hw-version" 52 "--sd-req" 0 "--sd-id" ${SD_ID} "--debug-mode" "--softdevice" "${SOFTDEVICE_HEX_PATH}" "${DFU_PKG}"
                                )

                                add_custom_command(
                                    OUTPUT "${COMMAND_NAME}"
                                    APPEND COMMAND ${CMAKE_COMMAND} -E copy "${DFU_PKG}" "${OUTPUT_DIRECTORY}"
                                )
271
272
273
274
275
276

                                # Copy connectivity hex file to binary make_directory
                                add_custom_command(
                                    OUTPUT "${COMMAND_NAME}"
                                    APPEND COMMAND ${CMAKE_COMMAND} -E copy "${APP_HEX_PATH}" "${OUTPUT_DIRECTORY}/${CONNECTIVITY_NAME}.hex"
                                )
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
                            endif()
                        endif()

                        # Make the last target added to list of targets a dependency to this target
                        # We need to make sure that the targets are compiled in sequence
                        # since the source code changes in every target (configuration of .in files)
                        list(LENGTH CONNECTIVITY_BUILD_TARGETS CONNECTIVITY_BUILD_TARGETS_LENGTH)
                        if(CONNECTIVITY_BUILD_TARGETS_LENGTH GREATER_EQUAL 1)
                            list(GET CONNECTIVITY_BUILD_TARGETS -1 PREVIOUS_TARGET)
                        endif()

                        add_custom_target("compile_${TARGET_NAME}" DEPENDS ${COMMAND_NAME} ${PREVIOUS_TARGET})
                        list(APPEND CONNECTIVITY_BUILD_TARGETS "compile_${TARGET_NAME}")
                    endif()
                endforeach()
            endif()
        endforeach()
    endforeach()

    set(CONNECTIVITY_BUILD_TARGETS ${CONNECTIVITY_BUILD_TARGETS} PARENT_SCOPE)
endfunction(nrf_create_connectivity_compile_targets)

set(SDK_PATH )
set(CONNECTIVITY_BUILD_TARGETS "")

nrf_prepare_sdk(
    SDK_VERSION 11
    URLS "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v11.x.x/nRF5_SDK_11.0.0_89a8197.zip"
    FILENAME "nRF5_SDK_11.0.0_89a8197.zip"
    SHA512 4fe84c4080e2eab664672366a5abfcd605777297835b7b864e0f51f376cd946a28178dfda7e6cefdd04b791058038711d78901ec5d260477a68eb5527c3b2c06
    PATCH_FILES "${CMAKE_CURRENT_LIST_DIR}/nRF5_SDK_11.0.0_connectivity.patch"
)

nrf_create_connectivity_compile_targets(
    SDK_VERSION 11
    SDK_ROOT "${SDK_PATH}"
    PROJECT_DIRECTORY "examples/ble_central_and_peripheral/ble_connectivity"
    VERSION "${CONNECTIVITY_VERSION}"
)

nrf_prepare_sdk(
    SDK_VERSION 15
    URLS "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.2.0_9412b96.zip"
    FILENAME "nRF5_SDK_15.2.0_9412b96.zip"
    SHA512 6ed3cbcbb798775557affc9a323f2665629e17359aaf8ae2e2f70c99645862185ae5d0f8fa46b17ade2af7e6dd7a62e6292b01f4e883107265c3c39c3eb22b46
    PATCH_FILES "${CMAKE_CURRENT_LIST_DIR}/nRF5_SDK_15.2.0_connectivity.patch"
)

nrf_create_connectivity_compile_targets(
    SDK_VERSION 15
    SDK_ROOT "${SDK_PATH}"
    PROJECT_DIRECTORY "examples/connectivity/ble_connectivity"
    VERSION "${CONNECTIVITY_VERSION}"
)

# Add a connectivity compilation target that depends on the last target added to CONNECTIVITY_BUILD_TARGETS
# This target makes it easier for the developer to know which target to invoke to compile
# all versions of connectivity firmware
list(LENGTH CONNECTIVITY_BUILD_TARGETS CONNECTIVITY_BUILD_TARGETS_LENGTH)
if(CONNECTIVITY_BUILD_TARGETS_LENGTH GREATER_EQUAL 1)
    list(GET CONNECTIVITY_BUILD_TARGETS -1 PREVIOUS_TARGET)
    add_custom_target("compile_connectivity" DEPENDS ${PREVIOUS_TARGET})
endif()