From 51022040f12af482901edbd8010d1b2e4fd1508a Mon Sep 17 00:00:00 2001 From: Dave Date: Wed, 7 Sep 2022 15:38:28 -0500 Subject: [PATCH] Update to automate firmware builds - build on checkin to asdf-release or asdf-built-test - deploy to https://dfnr2.github.io/unified-retro-keyboard --- .github/workflows/asdf-firmware.yml | 25 +++++ firmware/asdf/CMakeLists.txt | 24 +++-- firmware/asdf/cmake/generic-gcc-avr.cmake | 126 +++++++++++++--------- firmware/asdf/eeprom-spec.org | 25 +++++ firmware/asdf/make-targets.sh | 3 +- firmware/asdf/src/CMakeLists.txt | 20 ++-- firmware/asdf/test/CmakeLists.txt | 30 +++--- 7 files changed, 171 insertions(+), 82 deletions(-) create mode 100644 .github/workflows/asdf-firmware.yml create mode 100644 firmware/asdf/eeprom-spec.org diff --git a/.github/workflows/asdf-firmware.yml b/.github/workflows/asdf-firmware.yml new file mode 100644 index 0000000..df87178 --- /dev/null +++ b/.github/workflows/asdf-firmware.yml @@ -0,0 +1,25 @@ +name: asdf-firmware +on: + push: + branches: + asdf-release + asdf-build-test + +uses: lukka/get-cmake@latest + +jobs: + build_firmware: + runs-on: ubuntu-latest + steps: + - run: apt-get install gcc-avr binutils-avr avr-libc + - run: snap install cmake + - run: pip install -U sphinx sphinx-rtd-theme sphinx-autodoc-typehints + - run: pip install -U sphinxcontrib-napoleon + - run: pip install -U toml build + - run: pip install pipenv + + # Create the build directories, make all targets, and copy + # hex files to sphinx source directory for download links + - run: bash ./make-targets.sh -a -p -i -s + - run: mkdir public + - run: sphinx-build -b html docs/source public diff --git a/firmware/asdf/CMakeLists.txt b/firmware/asdf/CMakeLists.txt index e7ec9ab..7fb7164 100644 --- a/firmware/asdf/CMakeLists.txt +++ b/firmware/asdf/CMakeLists.txt @@ -11,7 +11,7 @@ if(ARCH MATCHES atmega328p) set(AVR_MCU ${ARCH}) set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generic-gcc-avr.cmake) - set (ASDF_OUT_TARGET ${ASDF_TARGET}.elf) + set (PROJECT_OUT_TARGET ${PROJECT_TARGET}.elf) elseif(ARCH MATCHES atmega2560) message(STATUS "setting up for atmega2560") @@ -20,7 +20,7 @@ elseif(ARCH MATCHES atmega2560) set(AVR_MCU ${ARCH}) set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generic-gcc-avr.cmake) - set (ASDF_OUT_TARGET ${ASDF_TARGET}.elf) + set (PROJECT_OUT_TARGET ${PROJECT_TARGET}.elf) endif() @@ -31,16 +31,23 @@ project("asdf" set_property(GLOBAL PROPERTY C_STANDARD 99) -set(ASDF_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) +set(PROJECT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) +message("SRC Dir is ${PROJECT_SRC_DIR}") -set (ASDF_TARGET_NAME asdf-v${PROJECT_VERSION}-${ARCH}) -set (ASDF_EXECUTABLE_TARGET_NAME ${ASDF_TARGET_NAME}) +#set(PYTHON_SCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/scripts) +#message("Python scripts Dir is ${PYTHON_SCRIPTS_DIR}") + +set(DOC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs) +message("Documentation and web page directory is ${DOC_DIR}") + +set (PROJECT_TARGET_NAME asdf-v${PROJECT_VERSION}-${ARCH}) +set (PROJECT_EXECUTABLE_TARGET_NAME ${PROJECT_TARGET_NAME}) if(ARCH MATCHES test) add_subdirectory(test) else() if((ARCH MATCHES atmega328p) OR (ARCH MATCHES atmega2560)) - set (ASDF_EXECUTABLE_TARGET_NAME ${ASDF_TARGET_NAME}.elf) + set (PROJECT_EXECUTABLE_TARGET_NAME ${PROJECT_TARGET_NAME}.elf) function(custom_add_library EXECUTABLE_NAME) add_avr_library(${EXECUTABLE_NAME} ${ARGN}) @@ -53,3 +60,8 @@ else() add_subdirectory(src) endif() + +# generate reStructuredText index file for project version: Note: this may be +# rebuilt for each target, but as long as all have the same project version, the +# build is idempotent, so no issues. +configure_file(${DOC_DIR}/source/_templates/index.rst.in ${DOC_DIR}/source/index.rst) diff --git a/firmware/asdf/cmake/generic-gcc-avr.cmake b/firmware/asdf/cmake/generic-gcc-avr.cmake index c27c638..064c14b 100644 --- a/firmware/asdf/cmake/generic-gcc-avr.cmake +++ b/firmware/asdf/cmake/generic-gcc-avr.cmake @@ -50,6 +50,66 @@ set(CMAKE_SYSTEM_PROCESSOR avr) set(CMAKE_C_COMPILER ${AVR_CC}) set(CMAKE_CXX_COMPILER ${AVR_CXX}) +########################################################################## +# c_toolchain_flags +# - Adds a list of compiler-specific flags to the CFLAGS variable in the +# parent scope. +########################################################################## +function(c_toolchain_flags) + # fix array base indexing beginning in AVR-GCC 12: + + list(APPEND TOOLCHAIN_FLAGS + -std=c99 + # -Wa,-adhln + -Wall + -funsigned-char + -funsigned-bitfields + -ffunction-sections + -fdata-sections + -fpack-struct + -fshort-enums + -O2 + -Wall + -Wextra + -Wpointer-arith + -Wcast-align + -Wwrite-strings + -Wswitch-default + -Wunreachable-code + -Winit-self + -Wmissing-field-initializers + -Wno-unknown-pragmas + -Wstrict-prototypes + -Wundef + -Wold-style-definition + ) + + if(CMAKE_C_COMPILER_VERSION GREATER_EQUAL "11.3") + message(STATUS "Appending page size fix for GCC >= 11.3") + list(APPEND TOOLCHAIN_FLAGS --param=min-pagesize=0) + endif() + + set(CFLAGS ${TOOLCHAIN_FLAGS} PARENT_SCOPE) +endfunction(c_toolchain_flags) + + +########################################################################## +# Macros for setting optimization flag: +# - optimization_off: turn off optimization for RTOS +# - optimization_full: set optimization to desired level for app. +########################################################################## + +macro(optimization_off) + set(CMAKE_CFLAGS_RELEASE "-O0" "-NDEBUG") + set(CMAKE_CFLAGS "-O0" "-NDEBUG") +endmacro(optimization_off) + + +macro(optimization_full) + set(CMAKE_CFLAGS_RELEASE "-O3" "-NDEBUG") + set(CMAKE_CFLAGS "-O3" "-NDEBUG") +endmacro(optimization_full) + ########################################################################## # Identification ########################################################################## @@ -100,11 +160,7 @@ endif(NOT AVR_MCU) #default avr-size args if(NOT AVR_SIZE_ARGS) - if(APPLE) - set(AVR_SIZE_ARGS -B) - else(APPLE) - set(AVR_SIZE_ARGS -C;--mcu=${AVR_MCU}) - endif(APPLE) + set(AVR_SIZE_ARGS -B) endif(NOT AVR_SIZE_ARGS) # prepare base flags for upload tool @@ -151,44 +207,6 @@ else(WITH_MCU) set(MCU_TYPE_FOR_FILENAME "") endif(WITH_MCU) -function(c_toolchain_flags) - # fix array base indexing beginning in AVR-GCC 12: - - list(APPEND TOOLCHAIN_FLAGS - -std=c99 - # -Wa,-adhln - -Wall - -funsigned-char - -funsigned-bitfields - -ffunction-sections - -fdata-sections - -fpack-struct - -fshort-enums - -O2 - -Wall - -Wextra - -Wpointer-arith - -Wcast-align - -Wwrite-strings - -Wswitch-default - -Wunreachable-code - -Winit-self - -Wmissing-field-initializers - -Wno-unknown-pragmas - -Wstrict-prototypes - -Wundef - -Wold-style-definition - ) - - if(CMAKE_C_COMPILER_VERSION GREATER_EQUAL "11.3") - message(STATUS "Appending page size fix for GCC >= 11.3") - list(APPEND TOOLCHAIN_FLAGS --param=min-pagesize=0) - endif() - - set(CFLAGS ${TOOLCHAIN_FLAGS} PARENT_SCOPE) -endfunction(c_toolchain_flags) - - ########################################################################## # add_avr_executable @@ -208,12 +226,22 @@ function(add_avr_executable EXECUTABLE_NAME) endif(NOT ARGN) # set file names - set(elf_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.elf) - set(hex_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.hex) - set(lst_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.lst) - set(map_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.map) - set(eeprom_image ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}-eeprom.hex) - message(STATUS "elf name: ${elf_file}") + set(basename ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}) + set(elf_file ${basename}.elf) + set(hex_file ${basename}.hex) + set(lst_file ${basename}.lst) + set(map_file ${basename}.map) + set(eeprom_image ${basename}-eeprom.hex) + message(STATUS "elf name: ${elf_file}") + message(STATUS "project target name: ${PROJECT_TARGET_NAME}") + + set(sphinx_file ${CMAKE_CURRENT_BINARY_DIR}/toc_${PROJECT_TARGET_NAME}.rst) + configure_file(${DOC_DIR}/source/_templates/hexfile_link.in ${sphinx_file}) + + message(STATUS "sphinx file: ${sphinx_file}") + + install(FILES ${sphinx_file} DESTINATION docs/source) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${basename}.hex DESTINATION dist) # elf file add_executable(${elf_file} EXCLUDE_FROM_ALL ${ARGN}) diff --git a/firmware/asdf/eeprom-spec.org b/firmware/asdf/eeprom-spec.org new file mode 100644 index 0000000..8d03e81 --- /dev/null +++ b/firmware/asdf/eeprom-spec.org @@ -0,0 +1,25 @@ +* EEPROM management +** Uses +*** Store current keyboard ID +*** Store status of various options +**** key repeat rates and delays +**** communications delays +**** serial baud rates +**** keyboard macros +**** keyboard specific options +***** all caps / upper+lower +***** handling of special keys +** Allocate on demand +** System block does not change as keyboards are changed +*** Items include: +**** current keyboard +*** All system block allocation must occur before any keyboard allocation may occur. +*** Once system EEPROM is allocated, system EEPROM is "locked" +*** If system EEPROM is locked, then EEPROM cannot be reallocated, although the parameters may be re-written. +*** provision to unlock EEPROM, for example, when firmware is updated, or during development + +** Keyboard block is reset whenever the keyboard changes +*** Any parameters specific to a keyboard, such as macros, keymap-specific settings, etc. are stored here. +*** This section is erased when keymap changes, but not when a keymap is loaded from EEPROM at powerup. + +* diff --git a/firmware/asdf/make-targets.sh b/firmware/asdf/make-targets.sh index 4dd7835..13b713c 100755 --- a/firmware/asdf/make-targets.sh +++ b/firmware/asdf/make-targets.sh @@ -199,11 +199,10 @@ main() { fi echo Valid Targets: "${VALID_TARGETS[*]}" - echo ${CMAKE_TARGETS[*]} + for (( i=0; $i<$NUM_CMAKE_TARGETS; i++ )) do TARGET=${CMAKE_TARGETS[$i]} - echo $TARGET if [[ "$CLEAN_BEFORE_BUILD" == "yes" ]] then clean_arch ${VALID_TARGETS[$TARGET]} diff --git a/firmware/asdf/src/CMakeLists.txt b/firmware/asdf/src/CMakeLists.txt index f639fb3..99cda5b 100644 --- a/firmware/asdf/src/CMakeLists.txt +++ b/firmware/asdf/src/CMakeLists.txt @@ -44,12 +44,12 @@ message("**********************") message("Keymap table: ${keymap_report}") message("**********************\n\n") -set (ASDF_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}) +set (PROJECT_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}) -configure_file(${ASDF_SRC_DIR}/Arch/asdf_arch_${ARCH}.h ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.h COPYONLY) -configure_file(${ASDF_SRC_DIR}/Arch/asdf_arch_${ARCH}.c ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.c COPYONLY) -configure_file(${ASDF_SRC_DIR}/asdf_keymap_setup.c.in ${CMAKE_CURRENT_BINARY_DIR}/asdf_keymap_setup.c) -configure_file(${ASDF_SRC_DIR}/asdf_keymap_setup.h.in ${CMAKE_CURRENT_BINARY_DIR}/asdf_keymap_setup.h) +configure_file(${PROJECT_SRC_DIR}/Arch/asdf_arch_${ARCH}.h ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.h COPYONLY) +configure_file(${PROJECT_SRC_DIR}/Arch/asdf_arch_${ARCH}.c ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.c COPYONLY) +configure_file(${PROJECT_SRC_DIR}/asdf_keymap_setup.c.in ${CMAKE_CURRENT_BINARY_DIR}/asdf_keymap_setup.c) +configure_file(${PROJECT_SRC_DIR}/asdf_keymap_setup.h.in ${CMAKE_CURRENT_BINARY_DIR}/asdf_keymap_setup.h) c_toolchain_flags() @@ -82,16 +82,16 @@ list (APPEND SOURCES # add the executable if (COMMAND custom_add_executable) - custom_add_executable(${ASDF_TARGET_NAME} + custom_add_executable(${PROJECT_TARGET_NAME} ${SOURCES} ) else() - add_executable(${ASDF_TARGET_NAME} + add_executable(${PROJECT_TARGET_NAME} ${SOURCES} ) endif() -target_include_directories(${ASDF_EXECUTABLE_TARGET_NAME} +target_include_directories(${PROJECT_EXECUTABLE_TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} @@ -99,11 +99,11 @@ target_include_directories(${ASDF_EXECUTABLE_TARGET_NAME} ) -target_compile_options(${ASDF_EXECUTABLE_TARGET_NAME} +target_compile_options(${PROJECT_EXECUTABLE_TARGET_NAME} PRIVATE ${CFLAGS} ) -#target_link_libraries(${ASDF_EXECUTABLE_TARGET_NAME} +#target_link_libraries(${PROJECT_EXECUTABLE_TARGET_NAME} # keymaps # ) diff --git a/firmware/asdf/test/CmakeLists.txt b/firmware/asdf/test/CmakeLists.txt index 5518198..b6867e4 100644 --- a/firmware/asdf/test/CmakeLists.txt +++ b/firmware/asdf/test/CmakeLists.txt @@ -1,4 +1,4 @@ -configure_file(${ASDF_SRC_DIR}/Arch/asdf_arch_test.h ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.h COPYONLY) +configure_file(${PROJECT_SRC_DIR}/Arch/asdf_arch_test.h ${CMAKE_CURRENT_BINARY_DIR}/asdf_arch.h COPYONLY) list(APPEND C_FLAGS "-std=c99" @@ -21,8 +21,8 @@ list(APPEND C_FLAGS list(APPEND TEST_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} - ${ASDF_SRC_DIR} - ${ASDF_SRC_DIR}/Arch + ${PROJECT_SRC_DIR} + ${PROJECT_SRC_DIR}/Arch ) add_library(unity @@ -39,21 +39,21 @@ target_include_directories(unity add_library(asdf_core STATIC asdf_keymap_table.c - ${ASDF_SRC_DIR}/asdf.c - ${ASDF_SRC_DIR}/asdf_buffer.c - ${ASDF_SRC_DIR}/asdf_hook.c - ${ASDF_SRC_DIR}/asdf_keymaps.c - ${ASDF_SRC_DIR}/asdf_modifiers.c - ${ASDF_SRC_DIR}/asdf_physical.c - ${ASDF_SRC_DIR}/asdf_repeat.c - ${ASDF_SRC_DIR}/asdf_virtual.c - ${ASDF_SRC_DIR}/Arch/asdf_arch_test.c + ${PROJECT_SRC_DIR}/asdf.c + ${PROJECT_SRC_DIR}/asdf_buffer.c + ${PROJECT_SRC_DIR}/asdf_hook.c + ${PROJECT_SRC_DIR}/asdf_keymaps.c + ${PROJECT_SRC_DIR}/asdf_modifiers.c + ${PROJECT_SRC_DIR}/asdf_physical.c + ${PROJECT_SRC_DIR}/asdf_repeat.c + ${PROJECT_SRC_DIR}/asdf_virtual.c + ${PROJECT_SRC_DIR}/Arch/asdf_arch_test.c ) target_include_directories(asdf_core PRIVATE - ${ASDF_SRC_DIR} - ${ASDF_SRC_DIR}/Arch + ${PROJECT_SRC_DIR} + ${PROJECT_SRC_DIR}/Arch ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) @@ -68,7 +68,7 @@ add_library(test_helpers target_include_directories(test_helpers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${ASDF_SRC_DIR} + ${PROJECT_SRC_DIR} ${CMAKE_CURRENT_BINARY_DIR} )