diff --git a/.clangd b/.clangd new file mode 100644 index 0000000000..18790456cc --- /dev/null +++ b/.clangd @@ -0,0 +1,3 @@ +CompileFlags: + Remove: -mcall-prologues + Add: -nostdinc \ No newline at end of file diff --git a/.gitignore b/.gitignore index e36b9ae130..908d5089ee 100644 --- a/.gitignore +++ b/.gitignore @@ -52,9 +52,12 @@ quantum/version.h .history/ build/ cmake-build-debug -CMakeLists.txt +# CMakeLists.txt *.pdf +# cmake toolchain downloads +/toolchains + # Let these ones be user specific, since we have so many different configurations *.code-workspace .stfolder diff --git a/.vscode/cmake-kits.json b/.vscode/cmake-kits.json new file mode 100644 index 0000000000..ca0bc0126c --- /dev/null +++ b/.vscode/cmake-kits.json @@ -0,0 +1,9 @@ +[ + { + "name": "AVR GCC", + "compilers": { + "CC": "C:\\QMK_MSYS\\mingw64\\bin\\avr-gcc.exe", + "CXX": "C:\\QMK_MSYS\\mingw64\\bin\\avr-g++.exe" + } + } +] \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 76117e52e0..1b5fbafd4d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,8 +5,8 @@ // Configure glob patterns for excluding files and folders. "files.exclude": { "**/.build": true, - "**/*.hex": true, - "**/*.bin": true, + // "**/*.hex": true, + // "**/*.bin": true, "**/*.uf2": true }, "files.associations": { diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000..f1b4467496 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,114 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Load Keyboard", + "dependsOrder": "sequence", + "dependsOn":[ + "Only Load Keyboard", + "Configure CMake" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Only Load Keyboard", + "type": "shell", + "command": "cmake -D QMK_KEYBOARD_FOLDER=\"${input:all_keyboards}\" -D QMK_KEYMAP_FOLDER=\"${input:keyboard_keymap}\" -P ${workspaceFolder}/cmake/ConfigureKeyboard.cmake", + "problemMatcher": [] + }, + { + "label": "Configure CMake", + "type": "cmake", + "command": "configure" + }, + { + "label": "Build", + "problemMatcher": [ + { + "base": "$gcc", + "fileLocation": ["relative", "${workspaceFolder}/build"] + }, + ], + "options": { + "environment": { + "CLICOLOR_FORCE": "1" + } + }, + "type": "cmake", + "command": "build", + "targets":[ + "${input:keyboard_target}" + ], + "group": { + "kind": "build", + "isDefault": true + }, + }, + // { + // "label": "Rebuild", + // "problemMatcher": [ + // { + // "base": "$gcc", + // "fileLocation": ["relative", "${workspaceFolder}/build"] + // }, + // ], + // "options": { + // "environment": { + // "CLICOLOR_FORCE": "1" + // } + // }, + // "type": "cmake", + // "command": "cleanRebuild", + // "targets":[ + // "${input:keyboard_target}" + // ], + // "group": { + // "kind": "build", + // "isDefault": true + // }, + // } + ], + "inputs": [ + { + "id": "keyboard_target", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": "type build\\targets", + "description": "Target:", + "fieldSeparator": "|" + }, + }, + { + "id": "all_keyboards", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": "type build\\all_keyboards", + "description": "Keyboard:", + "default": "" + }, + }, + { + "id": "keymap", + "description": "Keymap:", + "type": "pickString", + "options":[ + "default" + ] + }, + { + "id": "keyboard_keymap", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": "cmake -D QMK_KEYBOARD_FOLDER=\"${input:all_keyboards}\" -P ${workspaceFolder}/cmake/GetKeymaps.cmake && type build\\keyboard_keymaps", + "description": "Keymap:", + "default": "" + }, + }, + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..29829c16b1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,97 @@ +cmake_minimum_required(VERSION 3.20) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +include(UpdateSubmodule) +include(ResolveKeyboard) +include(ValidateJson) +include(ProcessKeyboard) + +set(QMK_KEYBOARDS_FOLDER "${CMAKE_SOURCE_DIR}/keyboards") + +function(_get_all_cmake_targets out_var current_dir) + get_property(targets DIRECTORY ${current_dir} PROPERTY BUILDSYSTEM_TARGETS) + get_property(subdirs DIRECTORY ${current_dir} PROPERTY SUBDIRECTORIES) + + foreach(subdir ${subdirs}) + _get_all_cmake_targets(subdir_targets ${subdir}) + list(APPEND targets ${subdir_targets}) + endforeach() + + set(${out_var} ${targets} PARENT_SCOPE) +endfunction() + +if(NOT DEFINED QMK_KEYBOARD) + # configure step - populate targets + project(qmk_firmware) + + add_subdirectory(keyboards) + +else() + # build step + if(NOT DEFINED QMK_KEYMAP_FOLDER) + set(QMK_KEYMAP_FOLDER "default") + endif() + + resolve_keyboard(${QMK_KEYBOARD_FOLDER} QMK_KEYBOARD_FOLDER_ABS) + cmake_path(IS_PREFIX QMK_KEYBOARDS_FOLDER "${QMK_KEYBOARD_FOLDER_ABS}" IS_KEYBOARDS_FOLDER) + resolve_config_h(${QMK_KEYBOARD_FOLDER_ABS} QMK_KEYBOARD_CONFIG_H) + process_keyboard() + resolve_keyboard_h(${QMK_KEYBOARD_FOLDER_ABS} QMK_KEYBOARD_H) + resolve_keymap_c(${QMK_KEYBOARD_FOLDER_ABS} ${QMK_KEYMAP_FOLDER} QMK_KEYMAP_C) + + message(STATUS "config.h: ${QMK_KEYBOARD_CONFIG_H}") + message(STATUS "keyboard.h: ${QMK_KEYBOARD_H}") + message(STATUS "keymap.c: ${QMK_KEYMAP_C}") + + + project(${QMK_KEYBOARD} + LANGUAGES C CXX ASM + HOMEPAGE_URL ${URL} + VERSION ${DEVICE_VER}) + + # add_compile_options( + # -include ${QMK_KEYBOARD_CONFIG_H} + # ) + add_compile_definitions( + QMK_KEYBOARD_H="${QMK_KEYBOARD_H}" + KEYBOARD_${QMK_KEYBOARD} + KEYMAP_C="${QMK_KEYMAP_C}" + MATRIX_ROWS=8 + MATRIX_COLS=6 + ) + + if(DEFINED DIODE_DIRECTION) + add_compile_definitions(DIODE_DIRECTION=${DIODE_DIRECTION}) + endif() + + include_directories(${CMAKE_SOURCE_DIR}) + + # if(EXISTS ${QMK_KEYBOARD_FOLDER_ABS}/CMakeLists.txt) + # add_subdirectory(${QMK_KEYBOARD_FOLDER_ABS}) + # else() + file(GLOB KEYBOARD_SRC "${QMK_KEYBOARD_FOLDER_ABS}/*.c") + list(REMOVE_ITEM KEYBOARD_SRC "${QMK_KEYMAP_C}") + add_qmk_executable(${TARGET_NAME} ${KEYBOARD_SRC}) + + # endif() + # add_library(qmk) + + target_precompile_headers(qmk PUBLIC + ${QMK_KEYBOARD_CONFIG_H} + ) + + resolve_keyboard_includes(${QMK_KEYBOARD_FOLDER_ABS}) + + add_subdirectory(quantum) + add_subdirectory(platforms) + add_subdirectory(tmk_core/protocol) + + include(features/oled) + include(features/backlight) + include(features/eeprom) + include(features/matrix) + include(features/fnv) +endif() diff --git a/chibios_mcu.json b/chibios_mcu.json new file mode 100644 index 0000000000..9624804932 --- /dev/null +++ b/chibios_mcu.json @@ -0,0 +1,41 @@ +{ + "MKL26Z64" : { + "MCU" : "cortex-m0plus", + "ARMV": 6, + "MCU_FAMILY": "KINETIS", + "MCU_SERIES": "KL2x", + "MCU_LDSCRIPT": "MKL26Z64", + "MCU_STARTUP": "kl2x", + "BOARD": "PJRC_TEENSY_LC" + }, + "MK20DX128" : { + "MCU" : "cortex-m4", + "ARMV": 7, + "MCU_FAMILY": "KINETIS", + "MCU_SERIES": "K20x", + "MCU_LDSCRIPT": "MK20DX128", + "MCU_STARTUP": "k20x5", + "BOARD": "PJRC_TEENSY_3" + }, + "MK20DX256" : { + "MCU" : "cortex-m4", + "ARMV": 7, + "MCU_FAMILY": "KINETIS", + "MCU_SERIES": "K20x", + "MCU_LDSCRIPT": "MK20DX256", + "MCU_STARTUP": "k20x7", + "BOARD": "PJRC_TEENSY_3_1" + }, + "STM32F303" : { + "MCU" : "cortex-m4", + "ARMV": 7, + "MCU_FAMILY": "STM32", + "MCU_SERIES": "STM32F3xx", + "MCU_LDSCRIPT": "STM32F303xC", + "MCU_STARTUP": "stm32f3xx", + "BOARD": "GENERIC_STM32_F303XC", + "USE_FPU": true, + "UF2_FAMILY": "STM32F3", + "STM32_BOOTLOADER_ADDRESS": "0x1FFFD800" + } +} \ No newline at end of file diff --git a/cmake/AddKeyboard.cmake b/cmake/AddKeyboard.cmake new file mode 100644 index 0000000000..6605afef29 --- /dev/null +++ b/cmake/AddKeyboard.cmake @@ -0,0 +1,83 @@ +include(ResolveKeyboard) +include(ValidateJson) +include(ResolveToolchain) + +macro(add_keyboard KEYBOARD_FOLDER KEYMAP_FOLDER) + # not entirely sure why this is necessary + # set(TEMP_PATH ${KEYBOARD_FOLDER}) + # cmake_path(IS_RELATIVE TEMP_PATH IS_KEYBOARD_FOLDER_RELATIVE) + # if(${IS_KEYBOARD_FOLDER_RELATIVE}) + # set(KEYBOARD_FOLDER_ABS ${CMAKE_SOURCE_DIR}/keyboards/${KEYBOARD_FOLDER}) + # if(NOT EXISTS ${KEYBOARD_FOLDER_ABS}) + # # message(FATAL_ERROR "Keyboard does not exist in QMK - try using an absolute path to the keyboard folder") + # resolve_keyboard(${KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS) + # endif() + # else() + # set(KEYBOARD_FOLDER_ABS ${KEYBOARD_FOLDER}) + # if(NOT EXISTS ${KEYBOARD_FOLDER_ABS}) + # message(FATAL_ERROR "Absolute path to keyboard does not exist") + # endif() + # endif() + + resolve_keyboard(${KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS) + + set(TEMP_PATH ${KEYBOARD_FOLDER}) + cmake_path(IS_RELATIVE TEMP_PATH IS_KEYBOARD_FOLDER_RELATIVE) + + set(TEMP_PATH ${KEYMAP_FOLDER}) + cmake_path(IS_RELATIVE TEMP_PATH IS_KEYMAP_FOLDER_RELATIVE) + if(${IS_KEYMAP_FOLDER_RELATIVE}) + set(KEYMAP_NAME ${KEYMAP_FOLDER}) + else() + if(WIN32) + set(KEYMAP_NAME $ENV{USERNAME}) + else() + set(KEYMAP_NAME $ENV{USE}) + endif() + endif() + + # find the right toolchain + + # not sure we need to validate here + validate_json(${KEYBOARD_FOLDER_ABS}/info.json keyboard JSON_STRING) + + string(JSON PROCESSOR GET ${JSON_STRING} processor) + resolve_toolchain(${PROCESSOR} TOOLCHAIN) + + string(JSON KEYBOARD_NAME GET ${JSON_STRING} keyboard_name) + if(${IS_KEYBOARD_FOLDER_RELATIVE}) + string(MAKE_C_IDENTIFIER ${KEYBOARD_FOLDER} KEYBOARD_SLUG) + else() + string(MAKE_C_IDENTIFIER ${KEYBOARD_NAME} KEYBOARD_SLUG) + endif() + string(JSON MANUFACTURER GET ${JSON_STRING} manufacturer) + set(TARGET_NAME "${KEYBOARD_SLUG}_${KEYMAP_NAME}") + ExternalProject_Add(${TARGET_NAME} + SOURCE_DIR ${CMAKE_SOURCE_DIR} + # PREFIX ${CMAKE_SOURCE_DIR}/build/keyboards/${KEYBOARD_FOLDER} + TMP_DIR ${CMAKE_SOURCE_DIR}/build/tmp + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/build/download + BINARY_DIR ${CMAKE_SOURCE_DIR}/build/keyboards/${TARGET_NAME} + STAMP_DIR ${CMAKE_SOURCE_DIR}/build/stamp + LOG_DIR ${CMAKE_SOURCE_DIR}/build/log + INSTALL_DIR ${CMAKE_SOURCE_DIR}/build/install + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/build/${TARGET_NAME}${QMK_EXTENSION} ${CMAKE_SOURCE_DIR}/${TARGET_NAME}${QMK_EXTENSION} + # this seems to work well for all systems so far - not sure if it'd be useful to customize + CMAKE_GENERATOR "Unix Makefiles" + CMAKE_ARGS + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/toolchains/${TOOLCHAIN}.cmake + -DQMK_KEYBOARD=${KEYBOARD_SLUG} + -DQMK_KEYBOARD_FOLDER=${KEYBOARD_FOLDER} + -DQMK_KEYMAP_FOLDER=${KEYMAP_FOLDER} + -DTARGET_NAME=${TARGET_NAME} + ) + ExternalProject_Add_Step(${TARGET_NAME} copy_compile_commands + DEPENDEES configure + DEPENDERS build + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/build/keyboards/${TARGET_NAME}/compile_commands.json ${CMAKE_SOURCE_DIR}/compile_commands.json + # BYPRODUCTS ${CMAKE_SOURCE_DIR}/compile_commands.json + ALWAYS TRUE + ) + +# file(APPEND "${CMAKE_SOURCE_DIR}/build/targets" "${TARGET_NAME}|${KEYBOARD_NAME} with ${KEYMAP_FOLDER}|${KEYBOARD_FOLDER}|Made by: ${MANUFACTURER}\n") +endmacro(add_keyboard) diff --git a/cmake/ConfigureKeyboard.cmake b/cmake/ConfigureKeyboard.cmake new file mode 100644 index 0000000000..aba7f3d1aa --- /dev/null +++ b/cmake/ConfigureKeyboard.cmake @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.20) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +include(ResolveKeyboard) +include(ValidateJSON) + +resolve_keyboard(${QMK_KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS) +validate_json(${KEYBOARD_FOLDER_ABS}/info.json keyboard JSON_STRING) + +if(NOT DEFINED QMK_KEYMAP_FOLDER) + set(QMK_KEYMAP_FOLDER default) +endif() + +set(TEMP_PATH ${QMK_KEYBOARD_FOLDER}) +cmake_path(IS_RELATIVE TEMP_PATH IS_KEYBOARD_FOLDER_RELATIVE) + +set(TEMP_PATH ${QMK_KEYMAP_FOLDER}) +cmake_path(IS_RELATIVE TEMP_PATH IS_KEYMAP_FOLDER_RELATIVE) + +if(${IS_KEYMAP_FOLDER_RELATIVE}) + set(KEYMAP_NAME ${QMK_KEYMAP_FOLDER}) +else() + if(WIN32) + set(KEYMAP_NAME $ENV{USERNAME}) + else() + set(KEYMAP_NAME $ENV{USE}) + endif() +endif() + +string(JSON KEYBOARD_NAME GET ${JSON_STRING} keyboard_name) + +if(${IS_KEYBOARD_FOLDER_RELATIVE}) + string(MAKE_C_IDENTIFIER ${QMK_KEYBOARD_FOLDER} KEYBOARD_SLUG) +else() + string(MAKE_C_IDENTIFIER ${KEYBOARD_NAME} KEYBOARD_SLUG) +endif() + +string(JSON MANUFACTURER GET ${JSON_STRING} manufacturer) + +set(TARGET_NAME "${KEYBOARD_SLUG}_${KEYMAP_NAME}") +file(APPEND "${CMAKE_SOURCE_DIR}/build/targets" "${TARGET_NAME}|${KEYBOARD_NAME} with ${QMK_KEYMAP_FOLDER}|${QMK_KEYBOARD_FOLDER}:${QMK_KEYMAP_FOLDER}|Made by: ${MANUFACTURER}\n") + +message(STATUS "Added keyboard '${QMK_KEYBOARD_FOLDER}' with keymap '${QMK_KEYMAP_FOLDER}'") diff --git a/cmake/FindARMToolchain.cmake b/cmake/FindARMToolchain.cmake new file mode 100644 index 0000000000..0078451c43 --- /dev/null +++ b/cmake/FindARMToolchain.cmake @@ -0,0 +1,14 @@ +macro(find_arm_toolchain) + find_toolchain(arm-none-eabi TOOLCHAIN_ROOT) + + if(NOT TOOLCHAIN_ROOT) + include(GetARMToolchain) + find_toolchain(arm-none-eabi TOOLCHAIN_ROOT) + endif() + + if(NOT TOOLCHAIN_ROOT) + message(FATAL_ERROR "ARM Toolchain could not be found") + endif() + + message(STATUS "ARM toolchain found: ${TOOLCHAIN_ROOT}") +endmacro() \ No newline at end of file diff --git a/cmake/FindAVRToolchain.cmake b/cmake/FindAVRToolchain.cmake new file mode 100644 index 0000000000..bb207e1555 --- /dev/null +++ b/cmake/FindAVRToolchain.cmake @@ -0,0 +1,20 @@ +macro(find_avr_toolchain) + find_toolchain(avr TOOLCHAIN_ROOT) + + if(NOT TOOLCHAIN_ROOT) + include(GetAVRToolchain) + find_toolchain(avr TOOLCHAIN_ROOT) + endif() + + find_program(DFU_PROGRAMMER NAMES dfu-programmer PATHS ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/) + if(${DFU_PROGRAMMER} STREQUAL "DFU_PROGRAMMER-NOTFOUND") + include(GetDfuProgrammer) + find_program(DFU_PROGRAMMER NAMES dfu-programmer PATHS ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/) + endif() + + if(NOT TOOLCHAIN_ROOT) + message(FATAL_ERROR "AVR Toolchain could not be found") + endif() + + message(STATUS "AVR toolchain found: ${TOOLCHAIN_ROOT}") +endmacro() \ No newline at end of file diff --git a/cmake/Findchibios.cmake b/cmake/Findchibios.cmake new file mode 100644 index 0000000000..3fb5744b1c --- /dev/null +++ b/cmake/Findchibios.cmake @@ -0,0 +1,282 @@ +include(ParseMakefile) + +# STM32F303 + +set(MCU "cortex-m4") +set(ARMV 7) +set(MCU_FAMILY "STM32") +set(MCU_SERIES "STM32F3xx") +string(TOUPPER ${MCU_SERIES} MCU_SERIES_UPPER) +set(MCU_LDSCRIPT "STM32F303xC") +set(MCU_STARTUP "stm32f3xx") +set(BOARD "GENERIC_STM32_F303XC") +set(USE_FPU TRUE) +set(UF2_FAMILY "STM32F3") +set(STM32_BOOTLOADER_ADDRESS 0x1FFFD800) +set(EEPROM_DRIVER "wear_leveling" FORCE) +set(WEAR_LEVELING_DRIVER "embedded_flash" FORCE) + +target_compile_definitions(qmk PUBLIC + QMK_MCU_FAMILY_${MCU_FAMILY} + QMK_MCU_SERIES_${MCU_SERIES_UPPER} +) + +target_compile_options(qmk PUBLIC + -march=armv7-m +) + +target_compile_definitions(qmk PUBLIC + MCU_${MCU_FAMILY} + __ARM_ARCH_7M__ +) + +# platforms/chibios/platform.mk + +if(NOT DEFINED USE_PROCESS_STACKSIZE) + set(USE_PROCESS_STACKSIZE 0x800) +endif() + +if(NOT DEFINED USE_EXCEPTIONS_STACKSIZE) + set(USE_EXCEPTIONS_STACKSIZE 0x400) +endif() + +target_link_options(qmk PUBLIC + -Wl,--defsym=__process_stack_size__=${USE_PROCESS_STACKSIZE},--defsym=__main_stack_size__=${USE_EXCEPTIONS_STACKSIZE} +) + +if(NOT DEFINED MCU_PORT_NAME) + set(MCU_PORT_NAME ${MCU_FAMILY}) +endif() +set(MCU_ARCH ${MCU}) +if(NOT DEFINED CHIBIOS_PORT) + set(CHIBIOS_PORT "ARMv${ARMV}-M") +endif() +if(NOT DEFINED PLATFORM_NAME) + set(PLATFORM_NAME platform) +endif() + +set(CHIBIOS ${CMAKE_SOURCE_DIR}/lib/chibios) +set(CHIBIOS_CONTRIB ${CMAKE_SOURCE_DIR}/lib/chibios-contrib) + +# port*.mk +include(chibios/ports/${CHIBIOS_PORT}) + +# platform.mk +include(chibios/ports/${MCU_SERIES}) + +# startup_*.mk - might need to convert these +find_file(STARTUP_MK startup_${MCU_STARTUP}.mk + ${CHIBIOS}/os/common/ports/ARMCMx/compilers/GCC/mk + ${CHIBIOS}/os/common/startup/ARMCMx/compilers/GCC/mk + ${CHIBIOS_CONTRIB}/os/common/startup/ARMCMx/compilers/GCC/mk +) +get_filename_component(STARTUP_DIR ${STARTUP_MK} DIRECTORY) +ParseMakefile(${STARTUP_MK}) +target_sources(qmk PUBLIC ${STARTUPSRC}) +target_sources(qmk PUBLIC ${STARTUPASM}) +target_include_directories(qmk PUBLIC ${STARTUPINC}) + +# board paths - we should just standardize these +find_path(BOARD_PATH +NAMES + boards/${BOARD}/board.mk + board/board.mk +PATHS + ${QMK_KEYBOARD_FOLDER}/boards/${BOARD} + ${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD} + ${CHIBIOS}/os/hal/ + ${CHIBIOS_CONTRIB}/os/hal/ +) +# if(EXISTS ${BOARD_PATH}/rules.mk) +# ParseMakefile(${BOARD_PATH}/rules.mk) +# endif() + +if(EXISTS ${BOARD_PATH}/configs/config.h) +target_precompile_headers(qmk PUBLIC + ${BOARD_PATH}/configs/config.h +) +endif() + +if(EXISTS ${BOARD_PATH}/configs/post_config.h) + target_precompile_headers(qmk PUBLIC + ${BOARD_PATH}/configs/post_config.h + ) +endif() + +find_file(BOARD_MK board.mk + ${BOARD_PATH}/boards/${BOARD} + ${BOARD_PATH}/board +) +ParseMakefile(${BOARD_MK}) + +target_sources(qmk PUBLIC ${BOARDSRC}) +target_include_directories(qmk PUBLIC ${BOARDINC}) + +# allow board.c to be overriden +file(RELATIVE_PATH INIT_HOOK_RELATIVE ${CMAKE_BINARY_DIR} + "${CMAKE_SOURCE_DIR}/tmk_core/protocol/chibios/init_hooks.h") +set_source_files_properties(${BOARDSRC} TARGET_DIRECTORY qmk PROPERTIES + # COMPILE_OPTIONS "-include ../../../tmk_core/protocol/chibios/init_hooks.h" + COMPILE_OPTIONS "-include ${INIT_HOOK_RELATIVE}" +) + +# bootloader +if(DEFINED STM32_BOOTLOADER_ADDRESS) + target_compile_definitions(qmk PUBLIC STM32_BOOTLOADER_ADDRESS=${STM32_BOOTLOADER_ADDRESS}) +endif() +if(DEFINED WB32_BOOTLOADER_ADDRESS) + target_compile_definitions(qmk PUBLIC WB32_BOOTLOADER_ADDRESS=${WB32_BOOTLOADER_ADDRESS}) +endif() + +find_file(BOOTLOADER_DEFS_H bootloader_defs.h + ${QMK_KEYBOARD_FOLDER} + ${QMK_KEYBOARD_FOLDER}/boards/${BOARD} + ${BOARD_PATH}/configs +) +if(EXISTS ${BOOTLOADER_DEFS_H}) + target_compile_options(qmk PUBLIC -include ${BOOTLOADER_DEFS_H}) +endif() + +# chconf directories +find_path(CHCONFDIR chconf.h + ${QMK_KEYBOARD_FOLDER} + ${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD}/configs + ${CMAKE_SOURCE_DIR}/platforms/chibios/boards/common/configs +) +target_include_directories(qmk PUBLIC ${CHCONFDIR}) + +# halconf directories +find_path(HALCONFDIR halconf.h + ${QMK_KEYBOARD_FOLDER} + ${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD}/configs + ${CMAKE_SOURCE_DIR}/platforms/chibios/boards/common/configs +) +target_include_directories(qmk PUBLIC ${HALCONFDIR}) + +# linker script +find_file(LDSCRIPT ${MCU_LDSCRIPT}.ld + ${QMK_KEYBOARD_FOLDER}/ld + ${CMAKE_SOURCE_DIR}/platforms/chibios/boards/${BOARD}/ld + ${CMAKE_SOURCE_DIR}/platforms/chibios/boards/common/ld + ${STARTUPLD} + ${STARTUPLD_CONTRIB} +) +get_filename_component(LDSCRIPT_PATH ${LDSCRIPT} DIRECTORY) +target_link_options(qmk PUBLIC + -T ${LDSCRIPT} + -L ${LDSCRIPT_PATH} +) + +# os/hal/hal.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/src/hal.c + ${CHIBIOS}/os/hal/src/hal_st.c + ${CHIBIOS}/os/hal/src/hal_buffers.c + ${CHIBIOS}/os/hal/src/hal_queues.c + ${CHIBIOS}/os/hal/src/hal_flash.c + ${CHIBIOS}/os/hal/src/hal_mmcsd.c + ${CHIBIOS}/os/hal/src/hal_adc.c + ${CHIBIOS}/os/hal/src/hal_can.c + ${CHIBIOS}/os/hal/src/hal_crypto.c + ${CHIBIOS}/os/hal/src/hal_dac.c + ${CHIBIOS}/os/hal/src/hal_efl.c + ${CHIBIOS}/os/hal/src/hal_gpt.c + ${CHIBIOS}/os/hal/src/hal_i2c.c + ${CHIBIOS}/os/hal/src/hal_i2s.c + ${CHIBIOS}/os/hal/src/hal_icu.c + ${CHIBIOS}/os/hal/src/hal_mac.c + ${CHIBIOS}/os/hal/src/hal_mmc_spi.c + ${CHIBIOS}/os/hal/src/hal_pal.c + ${CHIBIOS}/os/hal/src/hal_pwm.c + ${CHIBIOS}/os/hal/src/hal_rtc.c + ${CHIBIOS}/os/hal/src/hal_sdc.c + ${CHIBIOS}/os/hal/src/hal_serial.c + ${CHIBIOS}/os/hal/src/hal_serial_usb.c + ${CHIBIOS}/os/hal/src/hal_sio.c + ${CHIBIOS}/os/hal/src/hal_spi.c + ${CHIBIOS}/os/hal/src/hal_trng.c + ${CHIBIOS}/os/hal/src/hal_uart.c + ${CHIBIOS}/os/hal/src/hal_usb.c + ${CHIBIOS}/os/hal/src/hal_wdg.c + ${CHIBIOS}/os/hal/src/hal_wspi.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/hal/include +) + +# os/hal/osal/rt-nil/osal.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/osal/rt-nil/osal.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/hal/osal/rt-nil +) + +# os/rt/rt.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/rt/src/chsys.c + ${CHIBIOS}/os/rt/src/chrfcu.c + ${CHIBIOS}/os/rt/src/chdebug.c + ${CHIBIOS}/os/rt/src/chtrace.c + ${CHIBIOS}/os/rt/src/chvt.c + ${CHIBIOS}/os/rt/src/chschd.c + ${CHIBIOS}/os/rt/src/chinstances.c + ${CHIBIOS}/os/rt/src/chthreads.c + ${CHIBIOS}/os/rt/src/chsys.c + ${CHIBIOS}/os/rt/src/chrfcu.c + ${CHIBIOS}/os/rt/src/chdebug.c + ${CHIBIOS}/os/rt/src/chtrace.c + ${CHIBIOS}/os/rt/src/chvt.c + ${CHIBIOS}/os/rt/src/chschd.c + ${CHIBIOS}/os/rt/src/chinstances.c + ${CHIBIOS}/os/rt/src/chthreads.c + ${CHIBIOS}/os/rt/src/chtm.c + ${CHIBIOS}/os/rt/src/chstats.c + ${CHIBIOS}/os/rt/src/chregistry.c + ${CHIBIOS}/os/rt/src/chsem.c + ${CHIBIOS}/os/rt/src/chmtx.c + ${CHIBIOS}/os/rt/src/chcond.c + ${CHIBIOS}/os/rt/src/chevents.c + ${CHIBIOS}/os/rt/src/chmsg.c + ${CHIBIOS}/os/rt/src/chdynamic.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/rt/include +) + +# os/oslib/oslib.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/oslib/src/chmboxes.c + ${CHIBIOS}/os/oslib/src/chmemcore.c + ${CHIBIOS}/os/oslib/src/chmemheaps.c + ${CHIBIOS}/os/oslib/src/chmempools.c + ${CHIBIOS}/os/oslib/src/chpipes.c + ${CHIBIOS}/os/oslib/src/chobjcaches.c + ${CHIBIOS}/os/oslib/src/chdelegates.c + ${CHIBIOS}/os/oslib/src/chfactory.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/oslib/include +) + +# os/hal/lib/streams/streams.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/lib/streams/chprintf.c + ${CHIBIOS}/os/hal/lib/streams/chscanf.c + ${CHIBIOS}/os/hal/lib/streams/memstreams.c + ${CHIBIOS}/os/hal/lib/streams/nullstreams.c + ${CHIBIOS}/os/hal/lib/streams/bufstreams.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/hal/lib/streams +) + +# resume platform.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/various/syscalls.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/license + ${CHIBIOS}/os/oslib/include + ${CHIBIOS}/os/various +) \ No newline at end of file diff --git a/cmake/Findlufa.cmake b/cmake/Findlufa.cmake new file mode 100644 index 0000000000..83912123b3 --- /dev/null +++ b/cmake/Findlufa.cmake @@ -0,0 +1,27 @@ +include(UpdateSubmodule) +update_submodule(lib/lufa) +set(LUFA_PATH ${CMAKE_SOURCE_DIR}/lib/lufa) +set(LUFA_ROOT_PATH ${LUFA_PATH}/LUFA) +target_sources(qmk PUBLIC + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/USBController_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/USBInterrupt_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/ConfigDescriptors.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/Events.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/USBTask.c + ${LUFA_ROOT_PATH}/Drivers/USB/Class/Common/HIDParser.c + + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Host_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Pipe_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/PipeStream_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/HostStandardReq.c + + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Device_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/Endpoint_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/${ARCH}/EndpointStream_${ARCH}.c + ${LUFA_ROOT_PATH}/Drivers/USB/Core/DeviceStandardReq.c + ${LUFA_PATH}/LUFA/Drivers/USB/USB.h +) +target_include_directories(qmk PUBLIC ${LUFA_PATH}) +# target_link_libraries(lufa ${QMK_TARGET}) +# target_link_libraries(lufa tmk_core_protocol) +# target_link_libraries(lufa tmk_core_protocol_lufa) \ No newline at end of file diff --git a/cmake/GetARMToolchain.cmake b/cmake/GetARMToolchain.cmake new file mode 100644 index 0000000000..20dd3b33bf --- /dev/null +++ b/cmake/GetARMToolchain.cmake @@ -0,0 +1,24 @@ +message("Downloading gcc-arm-none-eabi") +if(WIN32) +file(DOWNLOAD + https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-win32.zip?rev=8f4a92e2ec2040f89912f372a55d8cf3&hash=8A9EAF77EF1957B779C59EADDBF2DAC118170BBF + ${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-win32.zip + EXPECTED_HASH MD5=2bc8f0c4c4659f8259c8176223eeafc1 + SHOW_PROGRESS +) +file(ARCHIVE_EXTRACT + INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-win32.zip + DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/ +) +elseif(UNIX) +file(DOWNLOAD + https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2?rev=78196d3461ba4c9089a67b5f33edf82a&hash=D484B37FF37D6FC3597EBE2877FB666A41D5253B + ${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-x86_64-linux.tar.bz2 + EXPECTED_HASH MD5=3fe3d8bb693bd0a6e4615b6569443d0d + SHOW_PROGRESS +) +file(ARCHIVE_EXTRACT + INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/gcc-arm-none-eabi-x86_64-linux.tar.bz2 + DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/ +) +endif() \ No newline at end of file diff --git a/cmake/GetAVRToolchain.cmake b/cmake/GetAVRToolchain.cmake new file mode 100644 index 0000000000..8fefc704bc --- /dev/null +++ b/cmake/GetAVRToolchain.cmake @@ -0,0 +1,24 @@ +message("Downloading avr-gcc") +if(WIN32) +file(DOWNLOAD + https://github.com/ZakKemble/avr-gcc-build/releases/download/v12.1.0-1/avr-gcc-12.1.0-x64-windows.zip + ${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-windows.zip + EXPECTED_HASH SHA256=e921a964fdeaedbe963352d0f26c6520a0a3eb8effc6ff232f3824b06c4ea0e2 + SHOW_PROGRESS +) +file(ARCHIVE_EXTRACT + INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-windows.zip + DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/ +) +elseif(UNIX) +file(DOWNLOAD + https://github.com/ZakKemble/avr-gcc-build/releases/download/v12.1.0-1/avr-gcc-12.1.0-x64-linux.tar.bz2 + ${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-linux.tar.bz2 + EXPECTED_HASH SHA256=feb034f4b85237032da8bac1f03765af5ebc4a8939b69bed57ff31bc482ca1a6 + SHOW_PROGRESS +) +file(ARCHIVE_EXTRACT + INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/avr-gcc-x64-linux.tar.bz2 + DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/ +) +endif() \ No newline at end of file diff --git a/cmake/GetDfuProgrammer.cmake b/cmake/GetDfuProgrammer.cmake new file mode 100644 index 0000000000..3f1b289e18 --- /dev/null +++ b/cmake/GetDfuProgrammer.cmake @@ -0,0 +1,22 @@ +message("Downloading dfu-programmer") +if(WIN32) +file(DOWNLOAD + https://github.com/dfu-programmer/dfu-programmer/releases/download/v1.0.0/dfu-programmer-x64-1.0.0.7z + ${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-x64-1.0.0.7z + SHOW_PROGRESS +) +file(ARCHIVE_EXTRACT + INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-x64-1.0.0.7z + DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/ +) +elseif(UNIX) +file(DOWNLOAD + https://github.com/dfu-programmer/dfu-programmer/releases/download/v1.0.0/dfu-programmer-linux-1.0.0.7z + ${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-linux-1.0.0.7z + SHOW_PROGRESS +) +file(ARCHIVE_EXTRACT + INPUT ${CMAKE_SOURCE_DIR}/toolchains/downloads/dfu-programmer-linux-1.0.0.7z + DESTINATION ${CMAKE_SOURCE_DIR}/toolchains/dfu-programmer/ +) +endif() \ No newline at end of file diff --git a/cmake/GetKeymaps.cmake b/cmake/GetKeymaps.cmake new file mode 100644 index 0000000000..31602b58f3 --- /dev/null +++ b/cmake/GetKeymaps.cmake @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.20) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +include(ResolveKeyboard) +include(ValidateJson) + +set(QMK_KEYBOARDS_FOLDER "${CMAKE_SOURCE_DIR}/keyboards") +set(CMAKE_MESSAGE_INDENT "") + +resolve_keyboard(${QMK_KEYBOARD_FOLDER} KEYBOARD_FOLDER_ABS) +validate_json(${KEYBOARD_FOLDER_ABS}/info.json keyboard JSON_STR) +cmake_path(IS_PREFIX QMK_KEYBOARDS_FOLDER "${KEYBOARD_FOLDER_ABS}" IS_KEYBOARDS_FOLDER) + +file(WRITE "${CMAKE_SOURCE_DIR}/build/keyboard_keymaps" "") +if(${IS_KEYBOARDS_FOLDER}) + file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS}) + while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "") + file(GLOB KEYMAPS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps/*/keymap.c") + foreach(KEYMAP ${KEYMAPS}) + file(RELATIVE_PATH KEYMAP_C "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps" "${KEYMAP}") + get_filename_component(KEYMAP_FOLDER ${KEYMAP_C} DIRECTORY) + # message(STATUS "${KEYMAP_FOLDER}") + file(APPEND "${CMAKE_SOURCE_DIR}/build/keyboard_keymaps" "${KEYMAP_FOLDER}\n") + endforeach() + get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY) + endwhile() +else() + if(EXISTS "${KEYBOARD_FOLDER_ABS}/keymap.c") + set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymap.c" PARENT_SCOPE) + elseif(EXISTS "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c") + set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE) + endif() +endif() + +string(JSON COMMUNITY_LAYOUTS ERROR_VARIABLE NO_COMMUNITY_LAYOUTS GET ${JSON_STR} community_layouts) + +if(${NO_COMMUNITY_LAYOUTS} STREQUAL "NOTFOUND") + string(JSON NUM_LAYOUTS LENGTH ${COMMUNITY_LAYOUTS}) + math(EXPR MAX "${NUM_LAYOUTS} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON LAYOUT GET ${COMMUNITY_LAYOUTS} ${IDX}) + file(GLOB KEYMAPS "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/*/keymap.c") + foreach(KEYMAP ${KEYMAPS}) + file(RELATIVE_PATH KEYMAP_C "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}" "${KEYMAP}") + get_filename_component(KEYMAP_FOLDER ${KEYMAP_C} DIRECTORY) + # message(STATUS "${KEYMAP_FOLDER}") + file(APPEND "${CMAKE_SOURCE_DIR}/build/keyboard_keymaps" "${KEYMAP_FOLDER}\n") + endforeach() + endforeach() +endif() \ No newline at end of file diff --git a/cmake/ParseHeader.cmake b/cmake/ParseHeader.cmake new file mode 100644 index 0000000000..98c0718f20 --- /dev/null +++ b/cmake/ParseHeader.cmake @@ -0,0 +1,64 @@ +# Simple CMake utility to read variables from MK files +# - Gets contents from given file (name or path) +# - Parses the assignment statements +# - Makes the same assignments in the PARENT_SCOPE + +if(POLICY CMP0007) + cmake_policy(SET CMP0007 NEW) +endif() + +function(ParseHeader HeaderFile Prefix) + _ParseHeader(${HeaderFile} ${Prefix}) +endfunction() + +macro(_ParseHeader HeaderFile Prefix) + message(CHECK_START "Parsing Header") + list(APPEND CMAKE_MESSAGE_INDENT " ") + message(STATUS "Reading \"${HeaderFile}\"") + + file(READ "${HeaderFile}" FileContents) + string(REGEX REPLACE "/\\*.*\\*/" "" FileContents ${FileContents}) + # replace the \ newlines with spaces + string(REGEX REPLACE "\\\\\r?\n *" " " FileContents ${FileContents}) + # turn each line into an item in a list + string(REGEX REPLACE "\r?\n" ";" FileLines ${FileContents}) + list(REMOVE_ITEM FileLines "") + + foreach(line ${FileLines}) + # remove comments from the ends of each line + string(REGEX REPLACE "//.*" "" line ${line}) + + # remove now-empty lines + if("${line}" STREQUAL "") + continue() + endif() + + # try to process includes, if the file exists + if(line MATCHES "^#include \"(.+)\"") + set(INCLUDED_HEADER ${CMAKE_MATCH_1}) + if(EXISTS ${INCLUDED_HEADER}) + _ParseHeader("${INCLUDED_HEADER}" ${Prefix}) + else() + message(STATUS "Could not read ${INCLUDED_HEADER}") + endif() + continue() + endif() + + # array + if(line MATCHES "#define ([A-Za-z0-9_]+) {(.*)}") + set(VARIABLE_NAME ${CMAKE_MATCH_1}) + set(VARIABLE_VALUE ${CMAKE_MATCH_2}) + set(${Prefix}${VARIABLE_NAME} ${VARIABLE_VALUE}) + endif() + + # regular variable + if(line MATCHES "#define ([A-Za-z0-9_]+) (.*)") + set(VARIABLE_NAME ${CMAKE_MATCH_1}) + set(VARIABLE_VALUE ${CMAKE_MATCH_2}) + set(${Prefix}${VARIABLE_NAME} ${VARIABLE_VALUE}) + endif() + endforeach() + + list(POP_BACK CMAKE_MESSAGE_INDENT) + message(CHECK_PASS "Complete") +endmacro() \ No newline at end of file diff --git a/cmake/ParseMakefile.cmake b/cmake/ParseMakefile.cmake new file mode 100644 index 0000000000..6c59633f61 --- /dev/null +++ b/cmake/ParseMakefile.cmake @@ -0,0 +1,98 @@ +# Simple CMake utility to read variables from MK files +# - Gets contents from given file (name or path) +# - Parses the assignment statements +# - Makes the same assignments in the PARENT_SCOPE + +if(POLICY CMP0007) + cmake_policy(SET CMP0007 NEW) +endif() + +function(ParseMakefile MKFile) + _ParseMakefile(${MKFile} ${ARGN}) +endfunction() + +macro(_ParseMakefile MKFile) + message(CHECK_START "Parsing Makefile") + list(APPEND CMAKE_MESSAGE_INDENT " ") + message(STATUS "Reading \"${MKFile}\"") + + file(READ "${MKFile}" FileContents) + # replace the \ newlines with spaces + string(REGEX REPLACE "\\\\\r?\n *" " " FileContents ${FileContents}) + # turn each line into an item in a list + string(REGEX REPLACE "\r?\n" ";" FileLines ${FileContents}) + list(REMOVE_ITEM FileLines "") + + foreach(line ${FileLines}) + # remove comments from the ends of each line + string(REGEX REPLACE "#.*" "" line ${line}) + + # remove now-empty lines + if("${line}" STREQUAL "") + continue() + endif() + + # try to process includes, if the file exists + if(line MATCHES "^-?include (.+)$") + set(MAKE_CHILD ${CMAKE_MATCH_1}) + if(EXISTS ${MAKE_CHILD}) + _ParseMakefile("${MAKE_CHILD}" ${ARGN}) + else() + message(STATUS "Could not read ${MAKE_CHILD}") + endif() + continue() + endif() + + # turn the assignment into a list with the first item being the variable name + string(REPLACE "=" ";" line_split ${line}) + list(LENGTH line_split count) + + if(count LESS 2) + message(STATUS "Skipping ${line}") + continue() + endif() + + list(GET line_split -1 value) + string(STRIP ${value} value) + # separate_arguments(value) + # string(REPLACE " " ";" value ${value}) + list(REMOVE_AT line_split -1) + + foreach(var_name ${line_split}) + string(STRIP ${var_name} var_name) + # replace $(?) with the variable ? from cmake + if(value MATCHES "\\$\\(([^\\(\\)]+)\\)") + set(MAKE_VARIABLE "${CMAKE_MATCH_1}") + string(REPLACE "$(${MAKE_VARIABLE})" "${${MAKE_VARIABLE}}" value ${value}) + endif() + + # look for +, assuming it used to be += + if(${var_name} MATCHES "([^ \\+]+) *\\+") + message(STATUS "Appending \"${CMAKE_MATCH_1}\" with \"${value}\"") + # read parent variable in local & append + set(LOCAL_${CMAKE_MATCH_1} ${CMAKE_MATCH_1}) + # APPEND accepts spaces between values + list(APPEND LOCAL_${CMAKE_MATCH_1} ${value}) + set(${CMAKE_MATCH_1} ${LOCAL_${CMAKE_MATCH_1}}) + set(${CMAKE_MATCH_1} ${LOCAL_${CMAKE_MATCH_1}} PARENT_SCOPE) + else() + # set needs ; between elements to be considered a list + string(REGEX REPLACE " +" ";" value ${value}) + # try to find variable in cache and FORCE wtih INTERNAL if it exists + if(DEFINED CACHE${${var_name}}) + message(STATUS "Caching \"${var_name}\" to \"${value}\"") + # set locally so replacement still work + set(${var_name} ${value}) + set(${var_name} ${value} CACHE INTERNAL "") + else() + message(STATUS "Setting \"${var_name}\" to \"${value}\"") + set(${var_name} ${value}) + set(${var_name} ${value} PARENT_SCOPE) + endif() + endif() + endforeach() + endforeach() + + list(POP_BACK CMAKE_MESSAGE_INDENT) + message(CHECK_PASS "Complete") +endmacro() \ No newline at end of file diff --git a/cmake/ProcessKeyboard.cmake b/cmake/ProcessKeyboard.cmake new file mode 100644 index 0000000000..7e453ccf04 --- /dev/null +++ b/cmake/ProcessKeyboard.cmake @@ -0,0 +1,78 @@ +include(ParseMakefile) +include(Utils) + +macro(process_keyboard) + message(CHECK_START "Processing keyboard") + list(APPEND CMAKE_MESSAGE_INDENT " ") + + validate_json(${QMK_KEYBOARD_FOLDER_ABS}/info.json keyboard QMK_KEYBOARD_INFO_JSON_STRING) + + # process rules from info.json + file(READ ${CMAKE_SOURCE_DIR}/data/mappings/info_rules.hjson JSON_STRING) + string(JSON MAPPING_LENGTH LENGTH ${JSON_STRING}) + math(EXPR MAX "${MAPPING_LENGTH} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON RULE_KEY MEMBER ${JSON_STRING} ${IDX}) + # string(JSON INFO_KEY GET ${JSON_STRING} ${RULE_KEY} info_key) + json_get_with_default(INFO_KEY ${JSON_STRING} _ ${RULE_KEY} info_key) + string(REPLACE "." " " INFO_KEYS ${INFO_KEY}) + string(JSON RULE_VALUE ERROR_VARIABLE RULE_KEY_NOT_FOUND GET ${QMK_KEYBOARD_INFO_JSON_STRING} ${INFO_KEYS}) + if(${RULE_KEY_NOT_FOUND} STREQUAL "NOTFOUND") + json_get_with_default(VALUE_TYPE ${JSON_STRING} raw ${RULE_KEY} value_type) + if(${VALUE_TYPE} STREQUAL "list") + string(JSON NUM_VALUES LENGTH ${RULE_VALUE}) + math(EXPR MAX "${NUM_VALUES} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON VALUE GET ${RULE_VALUE} ${IDX}) + list(APPEND ${RULE_KEY} ${VALUE}) + endforeach() + message(STATUS "Found rule '${INFO_KEY}': '${${RULE_KEY}}' assigned to '${RULE_KEY}'") + else() + set(${RULE_KEY} ${RULE_VALUE}) + message(STATUS "Found rule '${INFO_KEY}': '${RULE_VALUE}' assigned to '${RULE_KEY}'") + endif() + endif() + endforeach() + + # process definitions from info.json + file(READ ${CMAKE_SOURCE_DIR}/data/mappings/info_config.hjson JSON_STRING) + string(JSON MAPPING_LENGTH LENGTH ${JSON_STRING}) + math(EXPR MAX "${MAPPING_LENGTH} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON CONFIG_KEY MEMBER ${JSON_STRING} ${IDX}) + json_get_with_default(INFO_KEY ${JSON_STRING} _ ${CONFIG_KEY} info_key) + string(REPLACE "." ";" INFO_KEYS ${INFO_KEY}) + # string(JSON CONFIG_VALUE ERROR_VARIABLE CONFIG_KEY_NOT_FOUND GET ${QMK_KEYBOARD_INFO_JSON_STRING} ${INFO_KEYS}) + json_get_with_default(CONFIG_VALUE ${QMK_KEYBOARD_INFO_JSON_STRING} NOTFOUND ${INFO_KEYS}) + if(NOT CONFIG_VALUE STREQUAL "NOTFOUND") + set(${CONFIG_KEY} ${CONFIG_VALUE}) + json_get_with_default(VALUE_TYPE ${JSON_STRING} raw ${CONFIG_KEY} value_type) + if(${VALUE_TYPE} STREQUAL "str") + add_compile_definitions(${CONFIG_KEY}="${CONFIG_VALUE}") + message(STATUS "Found definition '${INFO_KEY}': '\"${CONFIG_VALUE}\"' assigned to '${CONFIG_KEY}'") + elseif(${VALUE_TYPE} STREQUAL "bcd_version") + string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH ${CONFIG_VALUE}) + set(VERSION_MAJOR ${CMAKE_MATCH_1}) + set(VERSION_MINOR ${CMAKE_MATCH_2}) + set(VERSION_PATCH ${CMAKE_MATCH_3}) + math(EXPR BCD_VERSION "${VERSION_MAJOR} * 10000 + ${VERSION_MINOR} * 100 + ${VERSION_PATCH}" OUTPUT_FORMAT HEXADECIMAL) + add_compile_definitions(${CONFIG_KEY}=${BCD_VERSION}) + message(STATUS "Found definition '${INFO_KEY}': '${BCD_VERSION}' assigned to '${CONFIG_KEY}'") + else() + add_compile_definitions(${CONFIG_KEY}=${CONFIG_VALUE}) + message(STATUS "Found definition '${INFO_KEY}': '${CONFIG_VALUE}' assigned to '${CONFIG_KEY}'") + endif() + endif() + endforeach() + + string(JSON KEYBOARD_NAME GET ${QMK_KEYBOARD_INFO_JSON_STRING} keyboard_name) + string(JSON MANUFACTURER GET ${QMK_KEYBOARD_INFO_JSON_STRING} manufacturer) + string(JSON URL GET ${QMK_KEYBOARD_INFO_JSON_STRING} url) + string(JSON QMK_MCU GET ${QMK_KEYBOARD_INFO_JSON_STRING} processor) + + list(POP_BACK CMAKE_MESSAGE_INDENT) + message(CHECK_PASS "info.json validated and loaded") + + + ParseMakefile(${QMK_KEYBOARD_FOLDER_ABS}/rules.mk) +endmacro() \ No newline at end of file diff --git a/cmake/ResolveKeyboard.cmake b/cmake/ResolveKeyboard.cmake new file mode 100644 index 0000000000..796dbac3b0 --- /dev/null +++ b/cmake/ResolveKeyboard.cmake @@ -0,0 +1,146 @@ +include(Utils) + +function(resolve_keyboard KEYBOARD KEYBOAD_FOLDER_ABS_STR) + message(VERBOSE "Resolving ${KEYBOARD}") + if(EXISTS "${CMAKE_SOURCE_DIR}/keyboards/${KEYBOARD}") + message(VERBOSE "Found in repo: ${KEYBOARD}") + set(${KEYBOAD_FOLDER_ABS_STR} "${CMAKE_SOURCE_DIR}/keyboards/${KEYBOARD}" PARENT_SCOPE) + return() + endif() + if(EXISTS "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}") + message(VERBOSE "Already checked out: ${KEYBOARD}") + set(${KEYBOAD_FOLDER_ABS_STR} "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}" PARENT_SCOPE) + return() + endif() + file(READ ${CMAKE_SOURCE_DIR}/data/keyboards.json KEYBOARDS_JSON) + string(JSON KEYBOARD_SLUG ERROR_VARIABLE JSON_ERROR GET ${KEYBOARDS_JSON} ${KEYBOARD}) + if(${JSON_ERROR} STREQUAL "NOTFOUND") + message(VERBOSE "Found ${KEYBOARD_SLUG}") + if(${KEYBOARD_SLUG} MATCHES "^@([0-9a-zA-Z_]+/[0-9a-zA-Z_]+)") + # keyboard slug is mapped to a github repo + set(GIT_SLUG ${CMAKE_MATCH_1}) + # string(MAKE_C_IDENTIFIER ${KEYBOARD} KEYBOARD_NAME) + message(VERBOSE "Cloning ${GIT_SLUG}") + find_package(Git QUIET) + if(GIT_FOUND) + file(MAKE_DIRECTORY "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}") + execute_process(COMMAND ${GIT_EXECUTABLE} clone "https://github.com/${GIT_SLUG}.git" . + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}" + RESULT_VARIABLE GIT_SUBMOD_RESULT) + if(NOT GIT_SUBMOD_RESULT EQUAL "0") + message(FATAL_ERROR "git clone failed with ${GIT_SUBMOD_RESULT}") + endif() + else() + message("Git not found - skipping submodule update") + endif() + set(${KEYBOAD_FOLDER_ABS_STR} "${CMAKE_SOURCE_DIR}/build/keyboard_repository/${KEYBOARD}" PARENT_SCOPE) + else() + message(FATAL_ERROR "Didn't match") + endif() + else() + message(FATAL_ERROR "Couldn't find") + # set(${RESULT_STR} "NOTFOUND" PARENT_SCOPE) + endif() +endfunction() + +function(resolve_config_h KEYBOARD_FOLDER_ABS CONFIG_H_STR) + set(${CONFIG_H_STR} PARENT_SCOPE) + if(${IS_KEYBOARDS_FOLDER}) + file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS}) + # get the deepest config.h + while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "") + if(EXISTS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h") + parent_list(PREPEND ${CONFIG_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h") + # set(${CONFIG_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/config.h" PARENT_SCOPE) + # return() + endif() + get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY) + endwhile() + # message(FATAL_ERROR "Could not find config.h in ${KEYBOARD_FOLDER_ABS}") + else() + if(EXISTS "${KEYBOARD_FOLDER_ABS}/config.h") + set(${CONFIG_H_STR} "${KEYBOARD_FOLDER_ABS}/config.h" PARENT_SCOPE) + else() + message(FATAL_ERROR "Could not find config.h in ${KEYBOARD_FOLDER_ABS}") + endif() + endif() +endfunction() + +function(resolve_keyboard_h KEYBOARD_FOLDER_ABS KEYBOARD_H_STR) + if(${IS_KEYBOARDS_FOLDER}) + file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS}) + # get the deepest header + while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "") + get_filename_component(LAST_PART ${RELATIVE_KEYBOARD_FOLDER} NAME) + if(EXISTS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/${LAST_PART}.h") + set(${KEYBOARD_H_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/${LAST_PART}.h" PARENT_SCOPE) + return() + endif() + get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY) + endwhile() + message(FATAL_ERROR "Could not find *.h in ${KEYBOARD_FOLDER_ABS}") + else() + if(EXISTS "${KEYBOARD_FOLDER_ABS}/keyboard.h") + set(${KEYBOARD_H_STR} "${KEYBOARD_FOLDER_ABS}/keyboard.h" PARENT_SCOPE) + else() + message(FATAL_ERROR "Could not find keyboard.h in ${KEYBOARD_FOLDER_ABS}") + endif() + endif() +endfunction() + +function(resolve_keymap_c KEYBOARD_FOLDER_ABS KEYMAP_FOLDER KEYMAP_C_STR) + if(IS_ABSOLUTE ${KEYMAP_FOLDER}) + if(EXISTS "${KEYMAP_FOLDER}/keymap.c") + set(${KEYMAP_C_STR} "${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE) + return() + endif() + else() + if(${IS_KEYBOARDS_FOLDER}) + file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS}) + # get the deepest keymap.c + while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "") + if(EXISTS "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps/${KEYMAP_FOLDER}/keymap.c") + set(${KEYMAP_C_STR} "${QMK_KEYBOARDS_FOLDER}/${RELATIVE_KEYBOARD_FOLDER}/keymaps/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE) + return() + endif() + get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY) + endwhile() + else() + if(EXISTS "${KEYBOARD_FOLDER_ABS}/keymap.c") + set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymap.c" PARENT_SCOPE) + return() + elseif(EXISTS "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c") + set(${KEYMAP_C_STR} "${KEYBOARD_FOLDER_ABS}/keymaps/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE) + return() + endif() + endif() + endif() + + # string(JSON COMMUNITY_LAYOUTS ERROR_VARIABLE NO_COMMUNITY_LAYOUTS GET ${QMK_KEYBOARD_INFO_JSON_STRING} community_layouts) + + # if(${NO_COMMUNITY_LAYOUTS} STREQUAL "NOTFOUND") + # string(JSON NUM_LAYOUTS LENGTH ${COMMUNITY_LAYOUTS}) + # math(EXPR MAX "${NUM_LAYOUTS} - 1") + foreach(LAYOUT ${LAYOUTS}) + # foreach(IDX RANGE ${MAX}) + # string(JSON LAYOUT GET ${COMMUNITY_LAYOUTS} ${IDX}) + if(EXISTS "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/${KEYMAP_FOLDER}/keymap.c") + set(${KEYMAP_C_STR} "${CMAKE_SOURCE_DIR}/layouts/community/${LAYOUT}/${KEYMAP_FOLDER}/keymap.c" PARENT_SCOPE) + return() + endif() + endforeach() + # endif() + message(FATAL_ERROR "Could not resolve keymap '${KEYMAP_FOLDER}'") +endfunction() + +function(resolve_keyboard_includes KEYBOARD_FOLDER_ABS) + if(${IS_KEYBOARDS_FOLDER}) + file(RELATIVE_PATH RELATIVE_KEYBOARD_FOLDER ${QMK_KEYBOARDS_FOLDER} ${KEYBOARD_FOLDER_ABS}) + while(NOT ${RELATIVE_KEYBOARD_FOLDER} STREQUAL "") + target_include_directories(qmk PUBLIC "${CMAKE_SOURCE_DIR}/keyboards/${RELATIVE_KEYBOARD_FOLDER}") + get_filename_component(RELATIVE_KEYBOARD_FOLDER ${RELATIVE_KEYBOARD_FOLDER} DIRECTORY) + endwhile() + else() + target_include_directories(qmk PUBLIC "${KEYBOARD_FOLDER_ABS}") + endif() +endfunction() \ No newline at end of file diff --git a/cmake/ResolveToolchain.cmake b/cmake/ResolveToolchain.cmake new file mode 100644 index 0000000000..ff25d586ab --- /dev/null +++ b/cmake/ResolveToolchain.cmake @@ -0,0 +1,60 @@ +function(resolve_toolchain PROCESSOR TOOLCHAIN_STR) + unset(${TOOLCHAIN_STR} PARENT_SCOPE) + if( + ${PROCESSOR} MATCHES "^at.*" + ) + set(${TOOLCHAIN_STR} "avr" PARENT_SCOPE) + set(QMK_EXTENSION ".hex" PARENT_SCOPE) + include(FindAVRToolchain) + find_avr_toolchain() + elseif( + ${PROCESSOR} MATCHES "^STM.*" OR + ${PROCESSOR} MATCHES "^WB32.*" OR + ${PROCESSOR} MATCHES "^MK.*" OR + ${PROCESSOR} MATCHES "RP2040" OR + ${PROCESSOR} MATCHES "^GD32.*" + ) + set(${TOOLCHAIN_STR} "arm-none-eabi" PARENT_SCOPE) + set(QMK_EXTENSION ".bin" PARENT_SCOPE) + include(FindARMToolchain) + find_arm_toolchain() + elseif( + ${PROCESSOR} MATCHES "risc-v" + ) + set(${TOOLCHAIN_STR} "riscv32-unknown-elf" PARENT_SCOPE) + set(QMK_EXTENSION ".bin" PARENT_SCOPE) + else() + message(FATAL_ERROR "Could not find toolchain for ${PROCESSOR}") + endif() +endfunction() + +function(find_toolchain TOOLCHAIN TOOLCHAIN_ROOT_STR) + unset(${TOOLCHAIN_STR} PARENT_SCOPE) + if(UNIX) + set(OS_SUFFIX "") + find_path(TOOLCHAIN_ROOT + NAMES + ${TOOLCHAIN}-gcc${OS_SUFFIX} + PATHS + "${CMAKE_SOURCE_DIR}/toolchains/avr-gcc/avr-gcc-12.1.0-x64-linux/bin/" + "${CMAKE_SOURCE_DIR}/toolchains/gcc-arm-none-eabi-10.3-2021.10/bin/" + /usr/bin/ + /usr/local/bin + /bin/ + $ENV{AVR_ROOT} + ) + elseif(WIN32) + set(OS_SUFFIX ".exe") + find_path(TOOLCHAIN_ROOT + NAMES + ${TOOLCHAIN}-gcc${OS_SUFFIX} + PATHS + "${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-windows/bin" + "${CMAKE_SOURCE_DIR}/toolchains/gcc-arm-none-eabi-10.3-2021.10/bin/" + $ENV{AVR_ROOT} + ) + else() + message(FATAL_ERROR "Unsure how to handle this OS") + endif(UNIX) + set(${TOOLCHAIN_ROOT_STR} ${TOOLCHAIN_ROOT} PARENT_SCOPE) +endfunction(find_toolchain) \ No newline at end of file diff --git a/cmake/UpdateSubmodule.cmake b/cmake/UpdateSubmodule.cmake new file mode 100644 index 0000000000..dede02c885 --- /dev/null +++ b/cmake/UpdateSubmodule.cmake @@ -0,0 +1,22 @@ +# can be passed a relative path (to CMAKE_SOURCE_DIR) to update/checkout that submodule +macro(update_submodule SUBMODULE) + find_package(Git QUIET) + if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git") + option(GIT_SUBMODULE "Check submodules during build" ON) + if(GIT_SUBMODULE) + message(STATUS "Updating submoudle ${SUBMODULE}") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update ${SUBMODULE} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE GIT_SUBMOD_RESULT) + if(NOT GIT_SUBMOD_RESULT EQUAL "0") + message(FATAL_ERROR "git submodule update ${SUBMODULE} failed with ${GIT_SUBMOD_RESULT}, please checkout submodules") + endif() + endif() + else() + message("Git not found - skipping submodule update") + endif() + + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/${SUBMODULE}/.git") + message(FATAL_ERROR "The submodule was not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") + endif() +endmacro() \ No newline at end of file diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake new file mode 100644 index 0000000000..3b4b91d8d4 --- /dev/null +++ b/cmake/Utils.cmake @@ -0,0 +1,25 @@ +macro(json_get_with_default KEY_STR JSON_STR DEFAULT) + # message(STATUS "Getting ${ARGN} for ${KEY_STR}") + string(JSON ${KEY_STR} ERROR_VARIABLE JSON_ERROR GET ${JSON_STR} ${ARGN}) + if(NOT ${JSON_ERROR} STREQUAL "NOTFOUND") + set(${KEY_STR} ${DEFAULT}) + endif() +endmacro() + +macro(json_get KEY_STR JSON_STR) + # message(STATUS "Getting ${ARGN} for ${KEY_STR}") + string(JSON ${KEY_STR} ERROR_VARIABLE JSON_ERROR GET ${JSON_STR} ${ARGN}) + if(NOT ${JSON_ERROR} STREQUAL "NOTFOUND") + unset(${KEY_STR}) + endif() +endmacro() + +macro(parent_list ACTION LIST_STR) + set(ARGS ${ARGN}) + string(REPLACE ";" " " ARGS ${ARGS}) + set(LOCAL_LIST ${${LIST_STR}}) + list(${ACTION} LOCAL_LIST ${ARGS}) + # set in current scope too + set(${LIST_STR} ${LOCAL_LIST}) + set(${LIST_STR} ${LOCAL_LIST} PARENT_SCOPE) +endmacro() \ No newline at end of file diff --git a/cmake/ValidateJson.cmake b/cmake/ValidateJson.cmake new file mode 100644 index 0000000000..478dd0487b --- /dev/null +++ b/cmake/ValidateJson.cmake @@ -0,0 +1,199 @@ +function(validate_json JSON_FILE SCHEMA_NAME JSON_STRING_STR) + unset(${JSON_STRING_STR} PARENT_SCOPE) + message(VERBOSE "Validating ${JSON_FILE} with '${SCHEMA_NAME}' schema") + file(READ ${JSON_FILE} JSON_STRING) + file(READ ${CMAKE_SOURCE_DIR}/data/schemas/${SCHEMA_NAME}.jsonschema SCHEMA_STRING) + string(JSON SCHEMA_ID GET ${SCHEMA_STRING} $id) + + set(DEFINITIONS "{}") + file(READ ${CMAKE_SOURCE_DIR}/data/schemas/definitions.jsonschema DEFINITIONS_STRING) + string(JSON DEFINITION_ID GET ${DEFINITIONS_STRING} $id) + string(JSON DEFINITIONS SET ${DEFINITIONS} "${DEFINITION_ID}#" ${DEFINITIONS_STRING}) + + string(JSON SCHEMA_DEFINITIONS ERROR_VARIABLE JSON_ERROR GET ${SCHEMA_STRING} definitions) + if(${JSON_ERROR} STREQUAL "NOTFOUND") + string(JSON DEFINITIONS SET ${DEFINITIONS} "#" "{}") + string(JSON DEFINITIONS SET ${DEFINITIONS} "#" definitions ${SCHEMA_DEFINITIONS}) + # string(JSON DEFINITIONS_LENGTH LENGTH ${SCHEMA_DEFINITIONS}) + # math(EXPR MAX "${DEFINITIONS_LENGTH} - 1") + # foreach(IDX RANGE ${MAX}) + # string(JSON DEFINITION_NAME MEMBER ${SCHEMA_DEFINITIONS} ${IDX}) + # string(JSON DEFINITION GET ${SCHEMA_DEFINITIONS} ${DEFINITION_NAME}) + # message(VERBOSE "Loading local definition '${DEFINITION_NAME}'") + # string(JSON DEFINITIONS_STRING SET ${DEFINITIONS_STRING} ${DEFINITION_NAME} ${DEFINITION}) + # endforeach() + endif() + + validate_object(${JSON_STRING} ${SCHEMA_STRING} OBJECT_ERROR) + if(DEFINED OBJECT_ERROR) + message(FATAL_ERROR ${OBJECT_ERROR}) + else() + set(${JSON_STRING_STR} ${JSON_STRING} PARENT_SCOPE) + endif() +endfunction() + +function(validate_object JSON_STRING SCHEMA_STRING OBJECT_ERROR_STR) + unset(${OBJECT_ERROR_STR} PARENT_SCOPE) + set(OBJECT_ERROR) + string(JSON PROPERTY_NAME_SCHEMA ERROR_VARIABLE PROPERTY_NAMES_ERROR GET ${SCHEMA_STRING} propertyNames) + string(JSON REQUIRED_PROPERTIES ERROR_VARIABLE REQUIRED_PROPERTIES_ERROR GET ${SCHEMA_STRING} required) + set(REQUIRED_LIST) + if(${REQUIRED_PROPERTIES_ERROR} STREQUAL "NOTFOUND") + string(JSON REQUIRED_LENGTH LENGTH ${REQUIRED_PROPERTIES}) + math(EXPR MAX "${REQUIRED_LENGTH} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON REQUIRED GET ${REQUIRED_PROPERTIES} ${IDX}) + list(APPEND REQUIRED_LIST ${REQUIRED}) + endforeach() + endif() + string(JSON NUM_PROPERTIES LENGTH ${JSON_STRING}) + math(EXPR MAX "${NUM_PROPERTIES} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON PROPERTY_NAME MEMBER ${JSON_STRING} ${IDX}) + list(REMOVE_ITEM REQUIRED_LIST ${PROPERTY_NAME}) + message(VERBOSE "Validating property '${PROPERTY_NAME}'") + if(${PROPERTY_NAMES_ERROR} STREQUAL "NOTFOUND") + validate_property(${PROPERTY_NAME} ${PROPERTY_NAME_SCHEMA} PROPERTY_NAME_ERROR) + if(DEFINED PROPERTY_NAME_ERROR) + list(APPEND OBJECT_ERROR "${PROPERTY_NAME_ERROR}") + endif() + endif() + string(JSON PROPERTY GET ${JSON_STRING} ${PROPERTY_NAME}) + string(JSON SCHEMA_PROPERTIES ERROR_VARIABLE PROPERTIES_ERROR GET ${SCHEMA_STRING} properties ${PROPERTY_NAME}) + if(${PROPERTIES_ERROR} STREQUAL "NOTFOUND") + string(JSON PROPERTY_SCHEMA GET ${SCHEMA_STRING} properties ${PROPERTY_NAME}) + else() + string(JSON PROPERTY_SCHEMA ERROR_VARIABLE ADDITIONAL_PROPERTIES_ERROR GET ${SCHEMA_STRING} additionalProperties) + if(NOT ${ADDITIONAL_PROPERTIES_ERROR} STREQUAL "NOTFOUND" OR "${PROPERTY_SCHEMA}" STREQUAL "OFF") + list(APPEND OBJECT_ERROR "Additional properties like '${PROPERTY_NAME}' not permitted in '${JSON_STRING}'") + endif() + endif() + validate_property(${PROPERTY} ${PROPERTY_SCHEMA} PROPERTY_ERROR) + if(DEFINED PROPERTY_ERROR) + list(APPEND OBJECT_ERROR "${PROPERTY_ERROR}") + endif() + endforeach() + list(LENGTH REQUIRED_LIST REQUIRED_REMAINING_LENGTH) + if(${REQUIRED_REMAINING_LENGTH} GREATER 0) + list(APPEND OBJECT_ERROR "Required properties not found: ${REQUIRED_LIST}") + endif() + set(${OBJECT_ERROR_STR} ${OBJECT_ERROR} PARENT_SCOPE) +endfunction() + +function(validate_property PROPERTY PROPERTY_SCHEMA PROPERTY_ERROR_STR) + unset(${PROPERTY_ERROR_STR} PARENT_SCOPE) + set(PROPERTY_ERROR) + string(JSON PROPERTY_REF ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} $ref) + if(${JSON_ERROR} STREQUAL "NOTFOUND") + string(REPLACE "/" ";" REF_COMPONENTS "${PROPERTY_REF}") + string(JSON PROPERTY_SCHEMA GET ${DEFINITIONS} ${REF_COMPONENTS}) + endif() + string(JSON PROPERTY_TYPE ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} type) + if(${JSON_ERROR} STREQUAL "NOTFOUND") + message(VERBOSE "Validating property type '${PROPERTY_TYPE}'") + if(${PROPERTY_TYPE} STREQUAL "object") + validate_object(${PROPERTY} ${PROPERTY_SCHEMA} OBJECT_ERROR) + if(DEFINED OBJECT_ERROR) + list(APPEND PROPERTY_ERROR ${OBJECT_ERROR}) + endif() + elseif(${PROPERTY_TYPE} STREQUAL "array") + string(JSON ARRAY_LENGTH LENGTH ${PROPERTY}) + string(JSON MAX_ITEMS ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} maxItems) + if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${ARRAY_LENGTH} GREATER ${MAX_ITEMS}) + list(APPEND PROPERTY_ERROR "Number of items in '${PROPERTY}' exceeds maximum ${MAX_ITEMS}") + endif() + string(JSON MIN_ITEMS ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} minItems) + if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${ARRAY_LENGTH} LESS ${MIN_ITEMS}) + list(APPEND PROPERTY_ERROR "Number of items in '${PROPERTY}' is less than ${MIN_ITEMS}") + endif() + string(JSON ITEM_SCHEMA ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} items) + if(${JSON_ERROR} STREQUAL "NOTFOUND") + math(EXPR MAX "${ARRAY_LENGTH} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON ITEM GET ${PROPERTY} ${IDX}) + validate_property(${ITEM} ${ITEM_SCHEMA} ITEM_ERROR) + if(DEFINED ITEM_ERROR) + list(APPEND PROPERTY_ERROR ${ITEM_ERROR}) + endif() + endforeach() + endif() + elseif(${PROPERTY_TYPE} STREQUAL "null") + if(NOT "${PROPERTY}" STREQUAL "null") + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not null'") + endif() + elseif(${PROPERTY_TYPE} STREQUAL "boolean") + if(NOT "${PROPERTY}" STREQUAL "OFF" AND NOT "${PROPERTY}" STREQUAL "ON") + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not a boolean'") + endif() + elseif(${PROPERTY_TYPE} STREQUAL "number") + if(NOT "${PROPERTY}" MATCHES "-?[0-9]+\\.?[0-9]*") + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not a number'") + endif() + elseif(${PROPERTY_TYPE} STREQUAL "integer") + if(NOT "${PROPERTY}" MATCHES "-?[0-9]+") + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not an integer'") + endif() + string(JSON MIN ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} minimum) + if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${PROPERTY} LESS ${MIN}) + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is less than the minimum of ${MIN}") + endif() + string(JSON MAX ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} maximum) + if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${PROPERTY} GREATER ${MAX}) + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is greater than the maximum of ${MAX}") + endif() + elseif(${PROPERTY_TYPE} STREQUAL "string") + # cmake regex doesn't support {}, so other options might be needed here + string(JSON PATTERN ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} pattern) + if(${JSON_ERROR} STREQUAL "NOTFOUND" AND NOT "${PROPERTY}" MATCHES "${PATTERN}") + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' does not match '${PATTERN}'") + endif() + string(LENGTH ${PROPERTY} STRING_LENGTH) + string(JSON MIN_LENGTH ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} minLength) + if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${STRING_LENGTH} LESS ${MIN_LENGTH}) + list(APPEND PROPERTY_ERROR "Length of property '${PROPERTY}' is less than the minimum of ${MIN_LENGTH}") + endif() + string(JSON MAX_LENGTH ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} maxLength) + if(${JSON_ERROR} STREQUAL "NOTFOUND" AND ${STRING_LENGTH} GREATER ${MAX_LENGTH}) + list(APPEND PROPERTY_ERROR "Length of property '${PROPERTY}' is greater than the maximum of ${MAX_LENGTH}") + endif() + string(JSON ENUM_LIST ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} enum) + if(${JSON_ERROR} STREQUAL "NOTFOUND") + set(FOUND_IN_ENUM_LIST FALSE) + string(JSON ENUM_LENGTH LENGTH ${ENUM_LIST}) + math(EXPR MAX "${ENUM_LENGTH} - 1") + foreach(IDX RANGE ${MAX}) + string(JSON ENUM GET ${PROPERTY_SCHEMA} enum ${IDX}) + if(${ENUM} STREQUAL ${PROPERTY}) + set(FOUND_IN_ENUM_LIST TRUE) + endif() + endforeach() + if(NOT ${FOUND_IN_ENUM_LIST}) + list(APPEND PROPERTY_ERROR "Property '${PROPERTY}' is not defined in the schema's enum: ${ENUM_LIST}") + endif() + endif() + else() + message(VERBOSE "Unknown type '${PROPERTY_TYPE}'") + endif() + else() + string(JSON PROPERTY_ONEOF ERROR_VARIABLE JSON_ERROR GET ${PROPERTY_SCHEMA} oneOf) + if(${JSON_ERROR} STREQUAL "NOTFOUND") + set(TYPE_SUCCESS FALSE) + string(JSON NUM_ONEOF LENGTH ${PROPERTY_ONEOF}) + math(EXPR MAX "${NUM_ONEOF} - 1") + set(ONEOF_ERRORS) + foreach(IDX RANGE ${MAX}) + string(JSON PROPERTY_SCHEMA GET ${PROPERTY_ONEOF} ${IDX}) + validate_property(${PROPERTY} ${PROPERTY_SCHEMA} ONEOF_ERROR) + if(NOT DEFINED ONEOF_ERROR) + set(TYPE_SUCCESS TRUE) + else() + list(APPEND ONEOF_ERRORS "${ONEOF_ERROR}\n") + endif() + endforeach() + if(NOT TYPE_SUCCESS) + list(APPEND PROPERTY_ERROR "Could not validate oneOf type '${PROPERTY}' :\n${ONEOF_ERRORS}") + endif() + endif() + endif() + set(${PROPERTY_ERROR_STR} ${PROPERTY_ERROR} PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/cmake/chibios/LLD/ADCv3.cmake b/cmake/chibios/LLD/ADCv3.cmake new file mode 100644 index 0000000000..8eabe28b4c --- /dev/null +++ b/cmake/chibios/LLD/ADCv3.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/ADCv3/hal_adc_lld.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/ADCv3) \ No newline at end of file diff --git a/cmake/chibios/LLD/CANv1.cmake b/cmake/chibios/LLD/CANv1.cmake new file mode 100644 index 0000000000..cc4c38730a --- /dev/null +++ b/cmake/chibios/LLD/CANv1.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/CANv1/hal_can_lld.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/CANv1) \ No newline at end of file diff --git a/cmake/chibios/LLD/DACv1.cmake b/cmake/chibios/LLD/DACv1.cmake new file mode 100644 index 0000000000..9e38b43095 --- /dev/null +++ b/cmake/chibios/LLD/DACv1.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DACv1/hal_dac_lld.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DACv1) \ No newline at end of file diff --git a/cmake/chibios/LLD/DMAv1.cmake b/cmake/chibios/LLD/DMAv1.cmake new file mode 100644 index 0000000000..cca7b3ef5f --- /dev/null +++ b/cmake/chibios/LLD/DMAv1.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DMAv1/stm32_dma.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/DMAv1) \ No newline at end of file diff --git a/cmake/chibios/LLD/EXTIv1.cmake b/cmake/chibios/LLD/EXTIv1.cmake new file mode 100644 index 0000000000..f623222046 --- /dev/null +++ b/cmake/chibios/LLD/EXTIv1.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/EXTIv1/stm32_exti.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/EXTIv1) \ No newline at end of file diff --git a/cmake/chibios/LLD/GPIOv2.cmake b/cmake/chibios/LLD/GPIOv2.cmake new file mode 100644 index 0000000000..9e01767fdd --- /dev/null +++ b/cmake/chibios/LLD/GPIOv2.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/GPIOv2/hal_pal_lld.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/GPIOv2) \ No newline at end of file diff --git a/cmake/chibios/LLD/I2Cv2.cmake b/cmake/chibios/LLD/I2Cv2.cmake new file mode 100644 index 0000000000..19c8916981 --- /dev/null +++ b/cmake/chibios/LLD/I2Cv2.cmake @@ -0,0 +1,7 @@ +if(${USE_HAL_I2C_FALLBACK}) + target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2C/hal_i2c_lld.c) + target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2C) +else() + target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2Cv2/hal_i2c_lld.c) + target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/I2Cv2) +endif() \ No newline at end of file diff --git a/cmake/chibios/LLD/RTCv2.cmake b/cmake/chibios/LLD/RTCv2.cmake new file mode 100644 index 0000000000..e07111389a --- /dev/null +++ b/cmake/chibios/LLD/RTCv2.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/RTCv2/hal_rtc_lld.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/RTCv2) \ No newline at end of file diff --git a/cmake/chibios/LLD/SPIv2.cmake b/cmake/chibios/LLD/SPIv2.cmake new file mode 100644 index 0000000000..ff34e2e4bb --- /dev/null +++ b/cmake/chibios/LLD/SPIv2.cmake @@ -0,0 +1,5 @@ +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SPIv2/hal_i2s_lld.c + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SPIv2/hal_spi_v2_lld.c +) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SPIv2) \ No newline at end of file diff --git a/cmake/chibios/LLD/SYSTICKv1.cmake b/cmake/chibios/LLD/SYSTICKv1.cmake new file mode 100644 index 0000000000..dcdb4bb8c4 --- /dev/null +++ b/cmake/chibios/LLD/SYSTICKv1.cmake @@ -0,0 +1,2 @@ +target_sources(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SYSTICKv1/hal_st_lld.c) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/SYSTICKv1) \ No newline at end of file diff --git a/cmake/chibios/LLD/TIMv1.cmake b/cmake/chibios/LLD/TIMv1.cmake new file mode 100644 index 0000000000..7714c08620 --- /dev/null +++ b/cmake/chibios/LLD/TIMv1.cmake @@ -0,0 +1,6 @@ +target_sources(qmk PUBLIC +${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1/hal_gpt_lld.c +${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1/hal_icu_lld.c +${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1/hal_pwm_lld.c +) +target_include_directories(qmk PUBLIC ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/TIMv1) \ No newline at end of file diff --git a/cmake/chibios/LLD/USARTv2.cmake b/cmake/chibios/LLD/USARTv2.cmake new file mode 100644 index 0000000000..aa01d68c6c --- /dev/null +++ b/cmake/chibios/LLD/USARTv2.cmake @@ -0,0 +1,9 @@ +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2/hal_serial_lld.c + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2/hal_sio_lld.c + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2/hal_uart_lld.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USART + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USARTv2 +) \ No newline at end of file diff --git a/cmake/chibios/LLD/USBv1.cmake b/cmake/chibios/LLD/USBv1.cmake new file mode 100644 index 0000000000..e92690993c --- /dev/null +++ b/cmake/chibios/LLD/USBv1.cmake @@ -0,0 +1,6 @@ +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USBv1/hal_usb_lld.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/USBv1 +) \ No newline at end of file diff --git a/cmake/chibios/LLD/xWDGv1.cmake b/cmake/chibios/LLD/xWDGv1.cmake new file mode 100644 index 0000000000..6c5e40f9c0 --- /dev/null +++ b/cmake/chibios/LLD/xWDGv1.cmake @@ -0,0 +1,6 @@ +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/xWDGv1/hal_wdg_lld.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/${MCU_PORT_NAME}/LLD/xWDGv1 +) \ No newline at end of file diff --git a/cmake/chibios/ports/ARMv7-M.cmake b/cmake/chibios/ports/ARMv7-M.cmake new file mode 100644 index 0000000000..73662b453e --- /dev/null +++ b/cmake/chibios/ports/ARMv7-M.cmake @@ -0,0 +1,10 @@ +# os/common/ports/ARMv7/compilers/GCC/mk/port.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/common/ports/ARMv7-M/chcore.c + ${CHIBIOS}/os/common/ports/ARMv7-M/compilers/GCC/chcoreasm.S +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/common/portability/GCC + ${CHIBIOS}/os/common/ports/ARM-common + ${CHIBIOS}/os/common/ports/ARMv7-M +) \ No newline at end of file diff --git a/cmake/chibios/ports/STM32F3xx.cmake b/cmake/chibios/ports/STM32F3xx.cmake new file mode 100644 index 0000000000..5c410e3b58 --- /dev/null +++ b/cmake/chibios/ports/STM32F3xx.cmake @@ -0,0 +1,25 @@ +# os/hal/ports/STM32/STM32F3xx/platform.mk +target_sources(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c + ${CHIBIOS}/os/hal/ports/STM32/STM32F3xx/stm32_isr.c + ${CHIBIOS}/os/hal/ports/STM32/STM32F3xx/hal_lld.c + ${CHIBIOS}/os/hal/ports/STM32/STM32F3xx/hal_efl_lld.c +) +target_include_directories(qmk PUBLIC + ${CHIBIOS}/os/hal/ports/common/ARMCMx + ${CHIBIOS}/os/hal/ports/STM32/STM32F3xx +) +include(chibios/LLD/ADCv3) +include(chibios/LLD/CANv1) +include(chibios/LLD/DACv1) +include(chibios/LLD/DMAv1) +include(chibios/LLD/EXTIv1) +include(chibios/LLD/GPIOv2) +include(chibios/LLD/I2Cv2) +include(chibios/LLD/RTCv2) +include(chibios/LLD/SPIv2) +include(chibios/LLD/SYSTICKv1) +include(chibios/LLD/TIMv1) +include(chibios/LLD/USARTv2) +include(chibios/LLD/USBv1) +include(chibios/LLD/xWDGv1) \ No newline at end of file diff --git a/cmake/features/backlight.cmake b/cmake/features/backlight.cmake new file mode 100644 index 0000000000..e48e2cffcf --- /dev/null +++ b/cmake/features/backlight.cmake @@ -0,0 +1,32 @@ +option(BACKLIGHT_ENABLE "" TRUE) +set(BACKLIGHT_DRIVER "pwm" CACHE STRING "Backlight driver") +set_property(CACHE BACKLIGHT_DRIVER PROPERTY STRINGS pwm timer software custom) + +string(JSON BACKLIGHT_PIN ERROR_VARIABLE NO_BACKLIGHT_PIN GET ${QMK_KEYBOARD_INFO_JSON_STRING} backlight pin) +if(${BACKLIGHT_ENABLE} AND NOT ${BACKLIGHT_PIN} STREQUAL "backlight-NOTFOUND") + target_sources(qmk PUBLIC + quantum/backlight/backlight.c + quantum/process_keycode/process_backlight.c + ) + target_compile_definitions(qmk PUBLIC + BACKLIGHT_ENABLE + BACKLIGHT_PIN=${BACKLIGHT_PIN} + ) + if(${BACKLIGHT_DRIVER} STREQUAL "custom") + target_compile_definitions(qmk PUBLIC BACKLIGHT_CUSTOM_DRIVER) + else() + target_sources(qmk PUBLIC quantum/backlight/backlight_driver_common.c) + if(${BACKLIGHT_DRIVER} STREQUAL "pwm") + target_sources(qmk PUBLIC quantum/backlight/backlight_${QMK_PLATFORM}.c) + else() + target_sources(qmk PUBLIC quantum/backlight/backlight_${BACKLIGHT_DRIVER}.c) + endif() + endif() + target_include_directories(qmk PUBLIC quantum/backlight) + target_include_directories(qmk PUBLIC drivers/oled) + # target_link_libraries(backlight qmk) + # target_include_directories(backlight PUBLIC quantum/backlight) + # target_include_directories(quantum PUBLIC quantum/backlight) + # target_link_libraries(backlight ${QMK_TARGET}) + # target_link_libraries(backlight quantum) +endif() diff --git a/cmake/features/eeprom.cmake b/cmake/features/eeprom.cmake new file mode 100644 index 0000000000..5d3121c046 --- /dev/null +++ b/cmake/features/eeprom.cmake @@ -0,0 +1,70 @@ +set(EEPROM_DRIVER "vendor" CACHE STRING "EEPROM driver") +set_property(CACHE EEPROM_DRIVER PROPERTY STRINGS vendor custom transient i2c spi wear_leveling legacy_stm32_flash) +set(WEAR_LEVELING_DRIVER "none" CACHE STRING "EEPROM wear-leveling driver") +set_property(CACHE WEAR_LEVELING_DRIVER PROPERTY STRINGS custom embedded_flash spi_flash rp2040_flash legacy) + +target_compile_definitions(qmk PUBLIC + EEPROM_ENABLE +) +target_include_directories(qmk PUBLIC + platforms/${QMK_PLATFORM}/drivers/eeprom + drivers/eeprom + platforms/common +) + +if(${EEPROM_DRIVER} STREQUAL "wear_leveling") + target_compile_definitions(qmk PUBLIC + EEPROM_DRIVER + EEPROM_WEAR_LEVELING + ) + target_sources(qmk PUBLIC + drivers/eeprom/eeprom_driver.c + drivers/eeprom/eeprom_wear_leveling.c + ) +elseif(${EEPROM_DRIVER} STREQUAL "vendor") + target_compile_definitions(qmk PUBLIC + EEPROM_VENDOR + ) + if(${QMK_PLATFORM} STREQUAL "chibios") + if(${QMK_MCU} MATCHES "STM32F[1-9].*" OR ${QMK_MCU} MATCHES "WB32.*" OR ${QMK_MCU} MATCHES "GD32.*") + target_compile_definitions(qmk PUBLIC + EEPROM_DRIVER + EEPROM_WEAR_LEVELING + ) + target_sources(qmk PUBLIC + drivers/eeprom/eeprom_driver.c + drivers/eeprom/eeprom_wear_leveling.c + ) + set(WEAR_LEVELING_DRIVER "embedded_flash") + endif() + endif() +endif() + +if(NOT ${WEAR_LEVELING_DRIVER} STREQUAL "none") + set(FNV_ENABLE TRUE) + target_compile_definitions(qmk PUBLIC + WEAR_LEVELING_ENABLE + ) + target_include_directories(qmk PUBLIC + platforms/${QMK_PLATFORM}/drivers/wear_leveling + drivers/wear_leveling + quantum/wear_leveling + ) + target_sources(qmk PUBLIC quantum/wear_leveling/wear_leveling.c) + + if(${WEAR_LEVELING_DRIVER} STREQUAL "embedded_flash") + target_compile_definitions(qmk PUBLIC + HAL_USE_EFL + WEAR_LEVELING_EMBEDDED_FLASH + ) + target_sources(qmk PUBLIC + platforms/${QMK_PLATFORM}/drivers/wear_leveling/wear_leveling_efl.c + ) + # target_compile_options(qmk PUBLIC + # -include ${CMAKE_SOURCE_DIR}/platforms/${QMK_PLATFORM}/drivers/wear_leveling/wear_leveling_efl_config.h + # ) + target_precompile_headers(qmk PUBLIC + ${CMAKE_SOURCE_DIR}/platforms/${QMK_PLATFORM}/drivers/wear_leveling/wear_leveling_efl_config.h + ) + endif() +endif() diff --git a/cmake/features/fnv.cmake b/cmake/features/fnv.cmake new file mode 100644 index 0000000000..1a05dc5654 --- /dev/null +++ b/cmake/features/fnv.cmake @@ -0,0 +1,9 @@ +if(${FNV_ENABLE}) + target_compile_definitions(qmk PUBLIC FNV_ENABLE) + target_include_directories(qmk PUBLIC lib/fnv) + target_sources(qmk PUBLIC + lib/fnv/qmk_fnv_type_validation.c + lib/fnv/hash_32a.c + lib/fnv/hash_64a.c + ) +endif() \ No newline at end of file diff --git a/cmake/features/matrix.cmake b/cmake/features/matrix.cmake new file mode 100644 index 0000000000..a215df66fd --- /dev/null +++ b/cmake/features/matrix.cmake @@ -0,0 +1,9 @@ +message(STATUS "Custom Matrix: ${CUSTOM_MATRIX}") +set(CUSTOM_MATRIX "no" CACHE STRING "Custom matrix-scanning") +set_property(CACHE CUSTOM_MATRIX PROPERTY STRINGS yes lite no) +if(NOT ${CUSTOM_MATRIX} STREQUAL yes) + target_sources(qmk PUBLIC quantum/matrix_common.c) + if(NOT ${CUSTOM_MATRIX} STREQUAL lite) + target_sources(qmk PUBLIC quantum/matrix.c) + endif() +endif() \ No newline at end of file diff --git a/cmake/features/oled.cmake b/cmake/features/oled.cmake new file mode 100644 index 0000000000..bc0928b563 --- /dev/null +++ b/cmake/features/oled.cmake @@ -0,0 +1,10 @@ +option(OLED_ENABLE "" OFF) +if(${OLED_ENABLE}) + target_sources(qmk PUBLIC + drivers/oled/ssd1306_sh1106.c + platforms/${QMK_PLATFORM}/drivers/i2c_master.c) + target_compile_definitions(qmk PUBLIC OLED_ENABLE) + target_include_directories(qmk PUBLIC drivers) + target_include_directories(qmk PUBLIC drivers/oled) + target_include_directories(qmk PUBLIC platforms/${QMK_PLATFORM}/drivers) +endif() diff --git a/cmake/toolchains/arm-none-eabi.cmake b/cmake/toolchains/arm-none-eabi.cmake new file mode 100644 index 0000000000..8db6062549 --- /dev/null +++ b/cmake/toolchains/arm-none-eabi.cmake @@ -0,0 +1,144 @@ +set(CMAKE_EXPORT_COMPILE_COMMANDS on) + +include(ResolveToolchain) + +set(QMK_TOOLCHAIN "arm-none-eabi") +set(QMK_PLATFORM "chibios") +set(QMK_PROTOCOL "chibios") +set(QMK_EXTENSION ".bin") + +if(UNIX) + set(OS_SUFFIX "") +elseif(WIN32) + set(OS_SUFFIX ".exe") +endif() + +find_toolchain(arm-none-eabi TOOLCHAIN_ROOT) + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_CROSS_COMPILING 1) + +set(CMAKE_C_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-gcc${OS_SUFFIX}" CACHE PATH "gcc" FORCE) +set(CMAKE_CXX_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-g++${OS_SUFFIX}" CACHE PATH "g++" FORCE) +set(CMAKE_AR "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ar${OS_SUFFIX}" CACHE PATH "ar" FORCE) +set(CMAKE_AS "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-as${OS_SUFFIX}" CACHE PATH "as" FORCE) +set(CMAKE_LINKER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ld${OS_SUFFIX}" CACHE PATH "linker" FORCE) +set(CMAKE_NM "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-nm${OS_SUFFIX}" CACHE PATH "nm" FORCE) +set(CMAKE_OBJCOPY "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objcopy${OS_SUFFIX}" CACHE PATH "objcopy" FORCE) +set(CMAKE_OBJDUMP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objdump${OS_SUFFIX}" CACHE PATH "objdump" FORCE) +set(CMAKE_STRIP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-strip${OS_SUFFIX}" CACHE PATH "strip" FORCE) +set(CMAKE_RANLIB "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ranlib${OS_SUFFIX}" CACHE PATH "ranlib" FORCE) +set(CMAKE_SIZE "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-size${OS_SUFFIX}" CACHE PATH "size" FORCE) + +find_program(CMAKE_MAKE_PROGRAM NAME make + PATHS + "${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-windows/bin/" + "${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-linux/bin/" + /usr/bin/ + /usr/local/bin + /bin/ +) + +add_compile_options( + $<$:-std=gnu11> + $<$:-std=gnu++14> + $<$:-fno-rtti> + # -flto + -Os + -Wall + -Wstrict-prototypes + # -fcommon + # -g + + -fomit-frame-pointer + -ffunction-sections + -fdata-sections + -fno-common + -fshort-wchar + -fno-builtin-printf + # -funsigned-char + # -funsigned-bitfields + # -ffunction-sections + # -fdata-sections + # -fpack-struct + # -fshort-enums + # -fno-builtin-printf + # $<$:-fno-inline-small-functions> + # $<$:-fno-strict-aliasing> + # $<$:-fno-exceptions> +) + +add_link_options( + -Wl,--gc-sections + -nostartfiles + -Wl,--no-wchar-size-warning + --specs=nano.specs + -lm +) + +macro(add_qmk_executable target_name) + + set(elf_file ${target_name}.elf) + set(map_file ${target_name}.map) + set(bin_file ${target_name}.bin) + set(lst_file ${target_name}.lst) + + add_link_options( + -Wl,-Map=${map_file},--cref + ) + + # create elf file + add_executable(qmk ${ARGN}) + # add_executable(${elf_file} ${ARGN}) + # target_link_libraries(${elf_file} qmk) + + set_target_properties(qmk + PROPERTIES + OUTPUT_NAME ${elf_file} + ) + + # generate the lst file + add_custom_command( + OUTPUT ${lst_file} + COMMAND ${CMAKE_OBJDUMP} -h -S ${elf_file} > ${lst_file} + DEPENDS qmk + ) + + # add_custom_command( + # OUTPUT "print-size-${elf_file}" + + # COMMAND + # ${CMAKE_SIZE} ${elf_file} + + # DEPENDS ${elf_file} + # ) + + # add_custom_command( + # OUTPUT "print-size-${bin_file}" + + # COMMAND + # ${CMAKE_SIZE} ${bin_file} sizeafter + + # DEPENDS ${bin_file} + # ) + + add_custom_command( + TARGET qmk + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary ${elf_file} ${CMAKE_SOURCE_DIR}/build/${bin_file} + # COMMAND ${CMAKE_COMMAND} -E copy ${elf_file} ${CMAKE_SOURCE_DIR}/build/${elf_file} + # COMMAND ${CMAKE_COMMAND} -E copy ${lst_file} ${CMAKE_SOURCE_DIR}/build/${lst_file} + # COMMAND ${CMAKE_COMMAND} -E copy ${map_file} ${CMAKE_SOURCE_DIR}/build/${map_file} + ) + + # build the intel hex file for the device + add_custom_target(${target_name} ALL + DEPENDS ${elf_file} ${lst_file} + ) + + set_target_properties(${target_name} + PROPERTIES + OUTPUT_NAME ${bin_file} + ) +endmacro(add_qmk_executable) diff --git a/cmake/toolchains/avr.cmake b/cmake/toolchains/avr.cmake new file mode 100644 index 0000000000..7797ba8784 --- /dev/null +++ b/cmake/toolchains/avr.cmake @@ -0,0 +1,182 @@ +# +# AVR GCC Toolchain file +# +# @author Natesh Narain +# @since Feb 06 2016 + +set(CMAKE_EXPORT_COMPILE_COMMANDS on) + +include(ResolveToolchain) + +set(QMK_TOOLCHAIN "avr") +set(QMK_PLATFORM "avr") +set(QMK_PROTOCOL "lufa") +set(QMK_EXTENSION ".hex") + +if(UNIX) + set(OS_SUFFIX "") +elseif(WIN32) + set(OS_SUFFIX ".exe") +endif() + +find_toolchain(avr TOOLCHAIN_ROOT) + +# setup the AVR compiler variables + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR avr) +set(CMAKE_CROSS_COMPILING 1) + +set(CMAKE_C_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-gcc${OS_SUFFIX}" CACHE PATH "gcc" FORCE) +set(CMAKE_CXX_COMPILER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-g++${OS_SUFFIX}" CACHE PATH "g++" FORCE) +set(CMAKE_AR "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ar${OS_SUFFIX}" CACHE PATH "ar" FORCE) +set(CMAKE_AS "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-as${OS_SUFFIX}" CACHE PATH "as" FORCE) +set(CMAKE_LINKER "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ld${OS_SUFFIX}" CACHE PATH "linker" FORCE) +set(CMAKE_NM "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-nm${OS_SUFFIX}" CACHE PATH "nm" FORCE) +set(CMAKE_OBJCOPY "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objcopy${OS_SUFFIX}" CACHE PATH "objcopy" FORCE) +set(CMAKE_OBJDUMP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-objdump${OS_SUFFIX}" CACHE PATH "objdump" FORCE) +set(CMAKE_STRIP "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-strip${OS_SUFFIX}" CACHE PATH "strip" FORCE) +set(CMAKE_RANLIB "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-ranlib${OS_SUFFIX}" CACHE PATH "ranlib" FORCE) +set(AVR_SIZE "${TOOLCHAIN_ROOT}/${QMK_TOOLCHAIN}-size${OS_SUFFIX}" CACHE PATH "size" FORCE) + +# set(CMAKE_EXE_LINKER_FLAGS "-L /usr/lib/gcc/avr/4.8.2") + +# avr uploader config +find_program(AVR_UPLOAD + NAME + avrdude + PATHS + /usr/bin/ + $ENV{AVR_ROOT} +) + +find_program(CMAKE_MAKE_PROGRAM NAME make + PATHS + "${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-windows/bin/" + "${CMAKE_SOURCE_DIR}/toolchains/avr-gcc-12.1.0-x64-linux/bin/" + /usr/bin/ + /usr/local/bin + /bin/ +) + +# setup the avr exectable macro + +# set(AVR_LINKER_LIBS "-lc -lm -lgcc -Wl,-lprintf_flt -Wl,-u,vfprintf") + +add_compile_options( + $<$:-std=gnu11> + $<$:-std=gnu++14> + -flto + # -mrelax + -Os + -Wall + -Wstrict-prototypes + -fcommon + # -g + $<$:--param=min-pagesize=0> + -funsigned-char + -funsigned-bitfields + -ffunction-sections + -fdata-sections + -fpack-struct + -fshort-enums + -mcall-prologues + -fno-builtin-printf + $<$:-fno-inline-small-functions> + $<$:-fno-strict-aliasing> + $<$:-fno-exceptions> +) + +add_compile_definitions( + F_CPU=16000000 + F_USB=16000000UL + __AVR_ATmega32U4__ + LTO_ENABLE +) + +add_link_options( + -Wl,--gc-sections +) + +macro(add_qmk_executable target_name) + + set(elf_file ${target_name}.elf) + set(map_file ${target_name}.map) + set(hex_file ${target_name}.hex) + set(lst_file ${target_name}.lst) + + add_compile_options( + -mmcu=${QMK_MCU} + ) + + add_link_options( + -mmcu=${QMK_MCU} + -Wl,-Map=${map_file} + ) + + # create elf file + # add_executable(${elf_file} ${ARGN}) + # target_link_libraries(${elf_file} qmk) + + add_executable(qmk ${ARGN}) + set_target_properties(qmk + PROPERTIES + OUTPUT_NAME ${elf_file} + ) + + + # set_target_properties(${elf_file} + # PROPERTIES + # COMPILE_FLAGS "-mmcu=${QMK_MCU} ${COMPILE_OPTIONS}" + # LINK_FLAGS "-mmcu=${QMK_MCU} ${LINK_OPTIONS}" + # ) + + # add_custom_target(compileOptions + # COMMAND cmake -P ${CMAKE_SOURCE_DIR}/cmake/WriteCompileOptions.cmake + # COMMENT "Writing compile_flags.txt" + # ) + + # generate the lst file + add_custom_command( + OUTPUT ${lst_file} + COMMAND ${CMAKE_OBJDUMP} -h -S ${elf_file} > ${lst_file} + DEPENDS ${elf_file} + ) + + # create hex file + add_custom_command( + OUTPUT ${hex_file} + # COMMAND ${CMAKE_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file} + COMMAND ${CMAKE_OBJCOPY} -O ihex -R .eeprom -R .fuse -R .lock -R .signature ${elf_file} ${hex_file} + DEPENDS ${elf_file} + ) + + add_custom_command( + OUTPUT "print-size-${elf_file}" + COMMAND ${AVR_SIZE} ${elf_file} + DEPENDS ${elf_file} + ) + + add_custom_command( + OUTPUT "print-size-${hex_file}" + COMMAND ${AVR_SIZE} ${hex_file} + DEPENDS ${hex_file} + ) + + add_custom_target(copy_hex + COMMAND ${CMAKE_COMMAND} -E copy ${hex_file} ${CMAKE_SOURCE_DIR}/build/${hex_file} + DEPENDS ${hex_file} + ) + + # build the intel hex file for the device + add_custom_target(${target_name} ALL + DEPENDS ${hex_file} ${lst_file} "print-size-${elf_file}" "print-size-${hex_file}" copy_hex + ) + + set_target_properties(${target_name} + PROPERTIES + OUTPUT_NAME ${hex_file} + ) + + +endmacro(add_qmk_executable) diff --git a/cmake/toolchains/riscv32-unknown-elf.cmake b/cmake/toolchains/riscv32-unknown-elf.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cmake/toolchains/riscv64-unknown-elf.cmake b/cmake/toolchains/riscv64-unknown-elf.cmake new file mode 100644 index 0000000000..d270270f24 --- /dev/null +++ b/cmake/toolchains/riscv64-unknown-elf.cmake @@ -0,0 +1,16 @@ +if(${USE_PICOLIBC}) + add_compile_options( + --specs=picolibc.specs + ) + add_compile_definitions(USE_PICOLIBC) + add_link_options( + -Wl,--defsym=__heap_start=__heap_base__,--defsym=__heap_end=__heap_end__ + ) +endif() + +add_compile_options( + -march=${MCU_ARCH} + -mabi=${MCU_ABI} + -mcmodel=${MCU_CMODEL} + -mstrict-align +) \ No newline at end of file diff --git a/data/keyboards.json b/data/keyboards.json new file mode 100644 index 0000000000..9e72c053c8 --- /dev/null +++ b/data/keyboards.json @@ -0,0 +1,4 @@ +{ + "olkb/planck/rev3": "@jackhumbert/test_keyboard", + "olkb/planck/rev6": "planck/rev6" +} \ No newline at end of file diff --git a/data/mappings/info_config.hjson b/data/mappings/info_config.hjson index 46108e6fe6..f82b706ef6 100644 --- a/data/mappings/info_config.hjson +++ b/data/mappings/info_config.hjson @@ -129,7 +129,7 @@ "TAPPING_FORCE_HOLD": {"info_key": "tapping.force_hold", "value_type": "bool", "deprecated": true}, "TAPPING_FORCE_HOLD_PER_KEY": {"info_key": "tapping.force_hold_per_key", "value_type": "bool", "deprecated": true}, "IGNORE_MOD_TAP_INTERRUPT": {"info_key": "_deprecated.ignore_mod_tap_interrupt", "value_type": "bool", "deprecated": true}, - "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true} + "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true}, // USB params, need to mark as failure when specified in config.h, rather than deprecated "PRODUCT_ID": {"info_key": "usb.pid", "value_type": "hex", "deprecated": true, "replace_with": "`usb.pid` in info.json"}, diff --git a/data/schemas/definitions.jsonschema b/data/schemas/definitions.jsonschema index 94a94157c0..c4e2a8af6b 100644 --- a/data/schemas/definitions.jsonschema +++ b/data/schemas/definitions.jsonschema @@ -14,15 +14,15 @@ }, "hex_number_2d": { "type": "string", - "pattern": "^0x[0-9A-F]{2}$" + "pattern": "^0x[0-9A-F][0-9A-F]$" }, "hex_number_4d": { "type": "string", - "pattern": "^0x[0-9A-F]{4}$" + "pattern": "^0x[0-9A-F][0-9A-F][0-9A-F][0-9A-F]$" }, "bcd_version": { "type": "string", - "pattern": "^[0-9]{1,2}\\.[0-9]\\.[0-9]$" + "pattern": "^[0-9][0-9]?\\.[0-9]\\.[0-9]$" }, "text_identifier": { "type": "string", @@ -83,15 +83,15 @@ }, { "type": "string", - "pattern": "^[A-K]\\d{1,2}$" + "pattern": "^[A-K]\\d\\d?$" }, { "type": "string", - "pattern": "^LINE_PIN\\d{1,2}$" + "pattern": "^LINE_PIN\\d\\d?$" }, { "type": "string", - "pattern": "^GP\\d{1,2}$" + "pattern": "^GP\\d\\d?$" }, { "type": "integer" diff --git a/keyboards/CMakeLists.txt b/keyboards/CMakeLists.txt new file mode 100644 index 0000000000..161b8089a4 --- /dev/null +++ b/keyboards/CMakeLists.txt @@ -0,0 +1,43 @@ +include(ExternalProject) +include(AddKeyboard) + +if(NOT EXISTS "${CMAKE_SOURCE_DIR}/build/targets") + file(WRITE "${CMAKE_SOURCE_DIR}/build/targets" "") +endif() + +# if(DEFINED QMK_KEYBOARD_FOLDER) +# if(NOT DEFINED QMK_KEYMAP_FOLDER) +# set(QMK_KEYMAP_FOLDER "default") +# endif() +# add_keyboard(${QMK_KEYBOARD_FOLDER} ${QMK_KEYMAP_FOLDER}) +# endif() + +# file(GLOB_RECURSE KEYBOARDS **/CMakeLists.txt) + +# foreach(KEYBOARD_CMAKE ${KEYBOARDS}) +# get_filename_component(KEYBOARD_FOLDER_ABS "${KEYBOARD_CMAKE}" DIRECTORY) +# file(RELATIVE_PATH KEYBOARD_FOLDER "${CMAKE_SOURCE_DIR}/keyboards" "${KEYBOARD_FOLDER_ABS}") +# add_keyboard(${KEYBOARD_FOLDER} "default") +# endforeach() + +file(STRINGS "${CMAKE_SOURCE_DIR}/build/targets" TARGETS) + +while(TARGETS) + list(POP_FRONT TARGETS LINE) + if (LINE MATCHES "(.+)\\|(.+)\\|(.+):(.+)\\|(.+)") + set(KEYBOARD_FOLDER ${CMAKE_MATCH_3}) + set(KEYMAP_FOLDER ${CMAKE_MATCH_4}) + add_keyboard(${KEYBOARD_FOLDER} ${KEYMAP_FOLDER}) + endif() +endwhile() + +# list all keyboards in build/all_keyboards + +file(GLOB_RECURSE POSSIBLE_KEYBOARDS **/info.json) + +file(WRITE "${CMAKE_SOURCE_DIR}/build/all_keyboards" "") +foreach(KEYBOARD_INFO ${POSSIBLE_KEYBOARDS}) + get_filename_component(KEYBOARD_FOLDER_ABS "${KEYBOARD_INFO}" DIRECTORY) + file(RELATIVE_PATH KEYBOARD_FOLDER "${CMAKE_SOURCE_DIR}/keyboards" "${KEYBOARD_FOLDER_ABS}") + file(APPEND "${CMAKE_SOURCE_DIR}/build/all_keyboards" "${KEYBOARD_FOLDER}\n") +endforeach() diff --git a/keyboards/mntre/CMakeLists.txt b/keyboards/mntre/CMakeLists.txt new file mode 100644 index 0000000000..190aac9a75 --- /dev/null +++ b/keyboards/mntre/CMakeLists.txt @@ -0,0 +1 @@ +add_qmk_executable(mntre mntre.c) \ No newline at end of file diff --git a/keyboards/mntre/keymaps/default/keymap.c b/keyboards/mntre/keymaps/default/keymap.c index 227ab15c62..2db7a7d975 100644 --- a/keyboards/mntre/keymaps/default/keymap.c +++ b/keyboards/mntre/keymaps/default/keymap.c @@ -23,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_FN] = LAYOUT( _______, BL_DOWN, BL_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ diff --git a/keyboards/planck/rev6/CMakeLists.txt b/keyboards/planck/rev6/CMakeLists.txt new file mode 100644 index 0000000000..ebaf8f44ef --- /dev/null +++ b/keyboards/planck/rev6/CMakeLists.txt @@ -0,0 +1 @@ +add_qmk_executable(planck.rev6 rev6.c planck.c) \ No newline at end of file diff --git a/keyboards/planck/rev6/info.json b/keyboards/planck/rev6/info.json index 9cc60ab5f0..af6ae49780 100644 --- a/keyboards/planck/rev6/info.json +++ b/keyboards/planck/rev6/info.json @@ -16,6 +16,7 @@ "processor": "STM32F303", "bootloader": "stm32-dfu", "board": "QMK_PROTON_C", + "diode_direction": "COL2ROW", "community_layouts": ["ortho_4x12", "planck_mit"], "layouts": { "LAYOUT_ortho_4x12": { diff --git a/keyboards/planck/rev6_drop/info.json b/keyboards/planck/rev6_drop/info.json index 828f0c20b8..3a73712173 100644 --- a/keyboards/planck/rev6_drop/info.json +++ b/keyboards/planck/rev6_drop/info.json @@ -15,6 +15,7 @@ }, "processor": "STM32F303", "bootloader": "stm32-dfu", + "diode_direction": "COL2ROW", "community_layouts": ["ortho_4x12", "planck_mit"], "layouts": { "LAYOUT_ortho_4x12": { diff --git a/platforms/CMakeLists.txt b/platforms/CMakeLists.txt new file mode 100644 index 0000000000..d39d9d45ef --- /dev/null +++ b/platforms/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(qmk PUBLIC suspend.c synchronization_util.c timer.c) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +# target_link_libraries(platforms ${QMK_TARGET}) +# target_link_libraries(platforms quantum) + +add_subdirectory(${QMK_PLATFORM}) \ No newline at end of file diff --git a/platforms/avr/CMakeLists.txt b/platforms/avr/CMakeLists.txt new file mode 100644 index 0000000000..5556923a06 --- /dev/null +++ b/platforms/avr/CMakeLists.txt @@ -0,0 +1,19 @@ +# add_compile_options( +# -mmcu=${QMK_MCU} +# ) +# add_link_options( +# -mmcu=${QMK_MCU} +# ) +target_sources(qmk PUBLIC + hardware_id.c + platform.c + suspend.c + timer.c + printf.c + bootloaders/bootloadhid.c + xprintf.S +) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +# target_link_libraries(platforms_avr ${QMK_TARGET}) +# target_link_libraries(platforms_avr quantum) \ No newline at end of file diff --git a/platforms/chibios/CMakeLists.txt b/platforms/chibios/CMakeLists.txt new file mode 100644 index 0000000000..5b68191462 --- /dev/null +++ b/platforms/chibios/CMakeLists.txt @@ -0,0 +1,55 @@ +find_package(Chibios REQUIRED) + +target_link_options(qmk PUBLIC + -mcpu=${MCU} + -mthumb + -mno-thumb-interwork + -mno-unaligned-access +) + +target_compile_definitions(qmk PUBLIC + MCU_${MCU_FAMILY} + THUMB_PRESENT + THUMB_NO_INTERWORKING + PLATFORM_SUPPORTS_SYNCHRONIZATION + PORT_IGNORE_GCC_VERSION_CHECK=1 +) + +if(NOT ${USE_FPU}) + target_compile_options(qmk PUBLIC + -mfloat-abi=hard + -mfpu=fpv4-sp-d16 + -fsingle-precision-constant + ) + target_compile_definitions(qmk PUBLIC + CORTEX_USE_FPU=TRUE + ) +else() + target_compile_definitions(qmk PUBLIC + CORTEX_USE_FPU=FALSE + ) +endif() + +# bootloader +if(${BOOTLOADER} STREQUAL "stm32-dfu") + target_compile_definitions(qmk PUBLIC BOOTLOADER_STM32_DFU) + set(BOOTLOADER_TYPE stm32_dfu) +endif() + +target_sources(qmk PUBLIC + syscall-fallbacks.c + wait.c + synchronization_util.c + hardware_id.c + platform.c + suspend.c + timer.c + bootloaders/${BOOTLOADER_TYPE}.c +) + +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/boards/common/configs) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}/configs) + +# mabye this should be in a different place +add_subdirectory(${CMAKE_SOURCE_DIR}/quantum/logging logging) \ No newline at end of file diff --git a/quantum/CMakeLists.txt b/quantum/CMakeLists.txt new file mode 100644 index 0000000000..70f84f4db2 --- /dev/null +++ b/quantum/CMakeLists.txt @@ -0,0 +1,33 @@ +target_sources(qmk PUBLIC + main.c + keymap_introspection.c + quantum.c + bitwise.c + led.c + action.c + action_layer.c + action_tapping.c + action_util.c + eeconfig.c + keyboard.c + keymap_common.c + keycode_config.c + sync_timer.c + logging/debug.c + logging/sendchar.c + debounce/sym_defer_g.c + bootmagic/magic.c +) + +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/keymap_extras) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/process_keycode) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/sequencer) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/logging) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bootmagic) + +# target_link_libraries(quantum ${QMK_TARGET}) +# target_link_libraries(quantum platforms) +# target_link_libraries(quantum platforms_${QMK_PLATFORM}) +# target_link_libraries(quantum tmk_core_protocol) +# target_link_libraries(quantum tmk_core_protocol_${QMK_PROTOCOL}) diff --git a/quantum/logging/CMakeLists.txt b/quantum/logging/CMakeLists.txt new file mode 100644 index 0000000000..09d185aa89 --- /dev/null +++ b/quantum/logging/CMakeLists.txt @@ -0,0 +1,19 @@ +set(PRINTF_PATH ${CMAKE_SOURCE_DIR}/lib/printf/src) + +target_sources(qmk PUBLIC + print.c + ${PRINTF_PATH}/printf/printf.c +) +target_include_directories(qmk PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${PRINTF_PATH}/printf + ${PRINTF_PATH} +) +target_compile_definitions(qmk PUBLIC + PRINTF_SUPPORT_DECIMAL_SPECIFIERS=0 + PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS=0 + PRINTF_SUPPORT_LONG_LONG=0 + PRINTF_SUPPORT_WRITEBACK_SPECIFIER=0 + SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS=0 + PRINTF_ALIAS_STANDARD_FUNCTION_NAMES=1 +) \ No newline at end of file diff --git a/tmk_core/protocol/CMakeLists.txt b/tmk_core/protocol/CMakeLists.txt new file mode 100644 index 0000000000..86c2afd0dc --- /dev/null +++ b/tmk_core/protocol/CMakeLists.txt @@ -0,0 +1,18 @@ +target_sources(qmk PUBLIC + host.c + report.c + usb_device_state.c + usb_util.c +) +# target_compile_definitions( + # MOUSE_ENABLED + # EXTRAKEY_ENABLE + # NKRO_ENABLE +# ) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +# target_link_libraries(tmk_core_protocol ${QMK_TARGET}) +# target_link_libraries(tmk_core_protocol quantum) +# target_link_libraries(tmk_core_protocol tmk_core_protocol_${QMK_PROTOCOL}) +# target_link_libraries(tmk_core_protocol platforms_${QMK_PLATFORM}) + +add_subdirectory(${QMK_PROTOCOL}) \ No newline at end of file diff --git a/tmk_core/protocol/chibios/CMakeLists.txt b/tmk_core/protocol/chibios/CMakeLists.txt new file mode 100644 index 0000000000..353bd2d638 --- /dev/null +++ b/tmk_core/protocol/chibios/CMakeLists.txt @@ -0,0 +1,19 @@ +target_compile_definitions(qmk PUBLIC + PROTOCOL_CHIBIOS + FIXED_CONTROL_ENDPOINT_SIZE=64 + FIXED_NUM_CONFIGURATIONS=1 +) + +target_sources(qmk PUBLIC + usb_main.c + chibios.c + ../usb_descriptor.c + usb_driver.c + usb_util.c +) + +find_package(Chibios REQUIRED) +# include(FindChibios) + +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/lufa_utils) \ No newline at end of file diff --git a/tmk_core/protocol/lufa/CMakeLists.txt b/tmk_core/protocol/lufa/CMakeLists.txt new file mode 100644 index 0000000000..84012a7bc6 --- /dev/null +++ b/tmk_core/protocol/lufa/CMakeLists.txt @@ -0,0 +1,33 @@ +set(ARCH AVR8) +set(USE_STATIC_OPTIONS "(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)") + +target_compile_definitions(qmk PUBLIC + PROTOCOL_LUFA + ARCH=ARCH_${ARCH} + BOARD=BOARD_NONE + + USB_DEVICE_ONLY + USE_FLASH_DESCRIPTORS + USE_STATIC_OPTIONS=${USE_STATIC_OPTIONS} + FIXED_CONTROL_ENDPOINT_SIZE=8 + FIXED_NUM_CONFIGURATIONS=1 +) + +target_sources(qmk PUBLIC + lufa.c + ../usb_descriptor.c + usb_util.c +) + +find_package(Lufa REQUIRED) +# target_compile_definitions(lufa PUBLIC ${COMPILE_DEFINITIONS}) + +target_include_directories(qmk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +# target_link_libraries(qmk lufa) + +# target_link_libraries(tmk_core_protocol_lufa ${QMK_TARGET}) +# target_link_libraries(tmk_core_protocol_lufa quantum) +# target_link_libraries(tmk_core_protocol_lufa tmk_core_protocol) +# target_link_libraries(tmk_core_protocol_lufa lufa) +# target_link_libraries(tmk_core_protocol_lufa platforms) +# target_link_libraries(tmk_core_protocol_lufa platforms_${QMK_PLATFORM}) \ No newline at end of file