提交按键库例程

This commit is contained in:
2025-12-29 19:10:44 +08:00
parent 17d380e709
commit c040394bfd
48 changed files with 10317 additions and 0 deletions

26
2gpio-lib/.vscode/compile_commands.json vendored Normal file
View File

@@ -0,0 +1,26 @@
[
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn_cb.c.o", "lib/ebtn/ebtn_cb.c"],
"file": "lib/ebtn/ebtn_cb.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn.c.o", "lib/ebtn/ebtn.c"],
"file": "lib/ebtn/ebtn.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/gpio.c.o", "user/src/gpio.c"],
"file": "user/src/gpio.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/main.c.o", "user/src/main.c"],
"file": "user/src/main.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/systick.c.o", "user/src/systick.c"],
"file": "user/src/systick.c"
}]

23
2gpio-lib/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,23 @@
{
"files.associations": {
"rcc.h": "c",
"gpio.h": "c",
"rcc_common_all.h": "c",
"main.h": "c",
"flash.h": "c",
"stdint.h": "c",
"systick.h": "c",
"scb.h": "c",
"nvic.h": "c",
"gpio_common_f24.h": "c",
"gpio_common_f234.h": "c",
"gpio_common_all.h": "c",
"pwr.h": "c",
"common.h": "c"
},
"Codegeex.Chat.fontSize": 18,
"Codegeex.RepoIndex": true,
"C_Cpp.default.compilerPath": "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc",
"C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools",
"C_Cpp.default.compileCommands": "${workspaceFolder}/compile_commands.json"
}

View File

@@ -0,0 +1,11 @@
{
options = {
mode = "release",
plat = "linux",
arch = "x86_64"
},
mtimes = {
["xmake.lua"] = 1764437527
},
recheck = false
}

View File

@@ -0,0 +1,288 @@
{
["find_program_arm-none-eabi_arch_ARM Cortex-M7_plat_MCU_checktoolcc"] = {
["arm-none-eabi-gcc"] = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc"
},
["core.tools.gcc.has_cflags"] = {
["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc_"] = {
["-shared"] = true,
["-o"] = true,
["-print-multi-directory"] = true,
["-no-canonical-prefixes"] = true,
["--param"] = true,
["-print-multiarch"] = true,
["--version"] = true,
["-dumpversion"] = true,
["-dumpspecs"] = true,
["-print-libgcc-file-name"] = true,
["-x"] = true,
["-v"] = true,
["-pass-exit-codes"] = true,
["--help"] = true,
["-E"] = true,
["-pie"] = true,
["-S"] = true,
["-print-sysroot-headers-suffix"] = true,
["-c"] = true,
["-print-search-dirs"] = true,
["-pipe"] = true,
["-print-multi-os-directory"] = true,
["-print-multi-lib"] = true,
["-Xpreprocessor"] = true,
["-time"] = true,
["-dumpmachine"] = true,
["-print-sysroot"] = true,
["--target-help"] = true,
["-Xassembler"] = true,
["-save-temps"] = true,
["-B"] = true,
["-Xlinker"] = true
}
},
find_program = {
["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-g++"] = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-g++",
["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc"] = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc",
gcc = "/usr/bin/gcc",
nim = false
},
["core.tools.gcc.has_ldflags"] = {
["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-g++_"] = {
["-rpath"] = true,
["--traditional-format"] = true,
["-e"] = true,
["--stats"] = true,
["--enable-non-contiguous-regions"] = true,
["--export-dynamic-symbol"] = true,
["-debug"] = true,
["-Tbss"] = true,
["-Qy"] = true,
["-Bno-symbolic"] = true,
["--fatal-warnings"] = true,
["--reduce-memory-overheads"] = true,
["--spare-dynamic-tags"] = true,
["--force-group-allocation"] = true,
["--dynamic-list-data"] = true,
["-Map"] = true,
["--push-state"] = true,
["--gc-keep-exported"] = true,
["--split-by-reloc"] = true,
["--fix-v4bx"] = true,
["--help"] = true,
["--error-execstack"] = true,
["--fix-v4bx-interworking"] = true,
["--pic-veneer"] = true,
["--ctf-variables"] = true,
["--rosegment"] = true,
["-T"] = true,
["--library-path"] = true,
["--no-as-needed"] = true,
["--no-warn-mismatch"] = true,
["--version-exports-section"] = true,
["-init"] = true,
["--default-imported-symver"] = true,
["--auxiliary"] = true,
["--nmagic"] = true,
["-L"] = true,
["--undefined"] = true,
["-Tldata-segment"] = true,
["-m"] = true,
["--warn-common"] = true,
["--enable-new-dtags"] = true,
["-u"] = true,
["-Bsymbolic"] = true,
["--enable-linker-version"] = true,
["--end-group"] = true,
["-no-pie"] = true,
["--trace"] = true,
["--output"] = true,
["--warn-execstack-objects"] = true,
["--no-undefined-version"] = true,
["--gc-sections"] = true,
["--check-sections"] = true,
["--accept-unknown-input-arch"] = true,
["--disable-linker-version"] = true,
["--no-error-execstack"] = true,
["--relocatable"] = true,
["--no-gc-sections"] = true,
["--task-link"] = true,
["--no-ctf-variables"] = true,
["--no-undefined"] = true,
["--no-relax"] = true,
["--demangle"] = true,
["-l"] = true,
["-dT"] = true,
["-soname"] = true,
["--no-wchar-size-warning"] = true,
["-V"] = true,
["--pop-state"] = true,
["--print-memory-usage"] = true,
["-b"] = true,
["--library"] = true,
["--section-start"] = true,
["--no-print-gc-sections"] = true,
["-Ur"] = true,
["--sort-section"] = true,
["--print-map-locals"] = true,
["--enable-non-contiguous-regions-warnings"] = true,
["--print-output-format"] = true,
["-Y"] = true,
["--discard-locals"] = true,
["--target1-rel"] = true,
["--long-plt"] = true,
["--no-rosegment"] = true,
["--no-warn-search-mismatch"] = true,
["--discard-all"] = true,
["-Ttext"] = true,
["--no-strip-discarded"] = true,
["--fix-stm32l4xx-629360"] = true,
["--cref"] = true,
["--as-needed"] = true,
["--no-export-dynamic"] = true,
["--eh-frame-hdr"] = true,
["--no-map-whole-files"] = true,
["-z"] = true,
["--strip-all"] = true,
["-f"] = true,
["--require-defined"] = true,
["-EL"] = true,
["--trace-symbol"] = true,
["--warn-rwx-segments"] = true,
["--export-dynamic"] = true,
["-P"] = true,
["-a"] = true,
["--wrap"] = true,
["-assert"] = true,
["--warn-unresolved-symbols"] = true,
["--oformat"] = true,
["--dynamic-list-cpp-new"] = true,
["-nostdlib"] = true,
["--format"] = true,
["--dependency-file"] = true,
["--no-dynamic-linker"] = true,
["--dynamic-list"] = true,
["--no-check-sections"] = true,
["-g"] = true,
["--dynamic-linker"] = true,
["-I"] = true,
["-Ttext-segment"] = true,
["--default-symver"] = true,
["--print-map"] = true,
["--warn-multiple-gp"] = true,
["--sort-common"] = true,
["--warn-textrel"] = true,
["--no-error-rwx-segments"] = true,
["--no-merge-exidx-entries"] = true,
["--force-exe-suffix"] = true,
["--no-warn-rwx-segments"] = true,
["--section-ordering-file"] = true,
["--use-blx"] = true,
["--script"] = true,
["--no-fatal-warnings"] = true,
["--disable-new-dtags"] = true,
["-O"] = true,
["-o"] = true,
["--target-help"] = true,
["-fini"] = true,
["--no-accept-unknown-input-arch"] = true,
["--no-demangle"] = true,
["-Bshareable"] = true,
["-static"] = true,
["--unique"] = true,
["-h"] = true,
["--out-implib"] = true,
["-Tdata"] = true,
["--filter"] = true,
["--map-whole-files"] = true,
["--target1-abs"] = true,
["--copy-dt-needed-entries"] = true,
["-R"] = true,
["--error-rwx-segments"] = true,
["--error-unresolved-symbols"] = true,
["-rpath-link"] = true,
["--start-group"] = true,
["--no-keep-memory"] = true,
["-F"] = true,
["-Trodata-segment"] = true,
["--verbose"] = true,
["--no-print-map-locals"] = true,
["--disable-multiple-abs-defs"] = true,
["-c"] = true,
["-flto"] = true,
["--entry"] = true,
["--no-omagic"] = true,
["--defsym"] = true,
["-dp"] = true,
["--print-map-discarded"] = true,
["--no-define-common"] = true,
["--cmse-implib"] = true,
["-y"] = true,
["--no-whole-archive"] = true,
["--architecture"] = true,
["-plugin"] = true,
["--pic-executable"] = true,
["--discard-none"] = true,
["--no-print-map-discarded"] = true,
["--no-copy-dt-needed-entries"] = true,
["--mri-script"] = true,
["--no-eh-frame-hdr"] = true,
["-Bsymbolic-functions"] = true,
["--just-symbols"] = true,
["--no-enum-size-warning"] = true,
["--retain-symbols-file"] = true,
["-G"] = true,
["--ignore-unresolved-symbol"] = true,
["--dynamic-list-cpp-typeinfo"] = true,
["--print-sysroot"] = true,
["--remap-inputs"] = true,
["--error-handling-script"] = true,
["--export-dynamic-symbol-list"] = true,
["--in-implib"] = true,
["--no-allow-shlib-undefined"] = true,
["--relax"] = true,
["-Bgroup"] = true,
["--gpsize"] = true,
["--warn-section-align"] = true,
["--strip-debug"] = true,
["--warn-once"] = true,
["--emit-relocs"] = true,
["-qmagic"] = true,
["--allow-shlib-undefined"] = true,
["--remap-inputs-file"] = true,
["--version"] = true,
["-EB"] = true,
["--vfp11-denorm-fix"] = true,
["-plugin-save-temps"] = true,
["--print-gc-sections"] = true,
["--warn-execstack"] = true,
["--version-script"] = true,
["--omagic"] = true,
["--default-script"] = true,
["--warn-alternate-em"] = true,
["--split-by-file"] = true,
["--no-warn-execstack"] = true,
["--no-warnings"] = true,
["-plugin-opt"] = true,
["--be8"] = true,
["--whole-archive"] = true,
["--allow-multiple-definition"] = true,
["--image-base"] = true,
["--orphan-handling"] = true,
["--undefined-version"] = true,
["--strip-discarded"] = true,
["-A"] = true
}
},
["find_program_arm-none-eabi_arch_ARM Cortex-M7_plat_MCU_checktoolar"] = {
["arm-none-eabi-gcc-ar"] = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc-ar"
},
["lib.detect.has_flags"] = {
["linux_x86_64_/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc__cc_cxflags__-fdiagnostics-color=always"] = true,
["linux_x86_64_/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-g++__ld___-fPIC"] = false,
["linux_x86_64_/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc__cc___-O0"] = true,
["linux_x86_64_/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc__cc___-fPIC"] = true,
["linux_x86_64_/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc__cc_cxflags__-Wno-gnu-line-marker -Werror"] = true,
["linux_x86_64_/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc__cc_cxflags__-MMD -MF"] = true
},
["find_program_arm-none-eabi_arch_ARM Cortex-M7_plat_MCU_checktoolld"] = {
["arm-none-eabi-g++"] = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-g++"
}
}

View File

@@ -0,0 +1,69 @@
{
cmdlines = {
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake -r",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake project -k compile_commands",
"xmake check",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake clean",
"xmake -r",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake -r",
"xmake clean",
"xmake -r",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/update_intellisense.lua .vscode clangd",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake check",
"xmake -r",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake -r",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake project -k makefile",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake check",
"xmake check",
"xmake check",
"xmake check",
"xmake check",
"xmake check",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/explorer.lua",
"xmake l /home/time/.vscode-server/extensions/tboox.xmake-vscode-2.4.1/assets/config.lua",
"xmake check",
"xmake clean",
"xmake -r",
"xmake lua /home/time/.local/share/xmake/modules/private/utils/statistics.lua",
"xmake lua /home/time/.local/share/xmake/actions/build/cleaner.lua"
}
}

View File

@@ -0,0 +1 @@
{ }

View File

@@ -0,0 +1 @@
{ }

View File

@@ -0,0 +1 @@
{ }

View File

@@ -0,0 +1,155 @@
{
["arm-none-eabi_arch_ARM Cortex-M7_plat_MCU"] = {
__checked = {
bindir = "/home/time/doc/mybin/arm-none-eabi/bin",
cross = "arm-none-eabi-",
sdkdir = "/home/time/doc/mybin/arm-none-eabi"
},
arch = "ARM Cortex-M7",
bindir = "/home/time/doc/mybin/arm-none-eabi/bin",
plat = "MCU",
cross = "arm-none-eabi-",
sdkdir = "/home/time/doc/mybin/arm-none-eabi"
},
yasm_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
gfortran_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
nasm_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
fpc_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
cross_arch_x86_64_plat_linux = {
__checked = false,
__global = true,
plat = "linux",
arch = "x86_64"
},
nim_arch_x86_64_plat_linux = {
__checked = false,
__global = true,
plat = "linux",
arch = "x86_64"
},
["tool_target_gpio-lib_MCU_ARM Cortex-M7_ld"] = {
toolchain_info = {
cachekey = "arm-none-eabi_arch_ARM Cortex-M7_plat_MCU",
name = "arm-none-eabi",
plat = "MCU",
arch = "ARM Cortex-M7"
},
toolname = "gxx",
program = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-g++"
},
["tool_target_gpio-lib_MCU_ARM Cortex-M7_cc"] = {
toolchain_info = {
cachekey = "arm-none-eabi_arch_ARM Cortex-M7_plat_MCU",
name = "arm-none-eabi",
plat = "MCU",
arch = "ARM Cortex-M7"
},
toolname = "gcc",
program = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc"
},
fasm_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
cuda_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
go_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
clang_arch_x86_64_plat_linux = {
__global = true,
plat = "linux",
arch = "x86_64"
},
envs_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
gcc_arch_x86_64_plat_linux = {
__checked = {
name = "gcc",
program = "/usr/bin/gcc"
},
__global = true,
plat = "linux",
arch = "x86_64"
},
["cross_arch_ARM Cortex-M7_plat_MCU"] = {
__checked = false,
plat = "MCU",
arch = "ARM Cortex-M7"
},
["envs_arch_ARM Cortex-M7_plat_MCU"] = {
__checked = true,
plat = "MCU",
arch = "ARM Cortex-M7"
},
zig_arch_x86_64_plat_linux = {
__global = true,
plat = "linux",
arch = "x86_64"
},
["tool_target_lib-ebtn_MCU_ARM Cortex-M7_ar"] = {
toolchain_info = {
cachekey = "arm-none-eabi_arch_ARM Cortex-M7_plat_MCU",
name = "arm-none-eabi",
plat = "MCU",
arch = "ARM Cortex-M7"
},
toolname = "gcc_ar",
program = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc-ar"
},
swift_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
},
["tool_target_lib-ebtn_MCU_ARM Cortex-M7_cc"] = {
toolchain_info = {
cachekey = "arm-none-eabi_arch_ARM Cortex-M7_plat_MCU",
name = "arm-none-eabi",
plat = "MCU",
arch = "ARM Cortex-M7"
},
toolname = "gcc",
program = "/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc"
},
rust_arch_x86_64_plat_linux = {
__checked = true,
__global = true,
plat = "linux",
arch = "x86_64"
}
}

View File

@@ -0,0 +1,53 @@
{
arch = "x86_64",
builddir = "build",
ccache = true,
host = "linux",
kind = "static",
mode = "release",
ndk_stdcxx = true,
plat = "linux",
target_os = "linux",
__toolchains_linux_arm32 = {
"envs",
"gcc",
"yasm",
"nasm",
"fasm",
"cuda",
"go",
"rust",
"swift",
"gfortran",
"fpc"
},
__toolchains_linux_MCU = {
"envs",
"gcc",
"yasm",
"nasm",
"fasm",
"cuda",
"go",
"rust",
"swift",
"gfortran",
"fpc"
},
__toolchains_linux_x86_64 = {
"envs",
"gcc",
"yasm",
"nasm",
"fasm",
"cuda",
"go",
"rust",
"swift",
"gfortran",
"fpc"
},
["__toolchains_MCU_ARM Cortex-M7"] = {
"envs"
}
}

View File

@@ -0,0 +1 @@
[100%]: build ok, spent 0.588s

BIN
2gpio-lib/bin/gpio-lib.bin Executable file

Binary file not shown.

BIN
2gpio-lib/bin/gpio-lib.elf Executable file

Binary file not shown.

443
2gpio-lib/bin/gpio-lib.hex Normal file
View File

@@ -0,0 +1,443 @@
:020000040800F2
:100000000000022055170008511700084F1700087C
:100010004F1700084F1700084F1700080000000096
:100020000000000000000000000000005117000860
:100030005117000800000000511700088D04000847
:100040004F1700084F1700084F1700084F170008F8
:100050004F1700084F1700084F1700084F170008E8
:100060004F1700084F1700084F1700084F170008D8
:100070004F1700084F1700084F1700084F170008C8
:100080004F1700084F1700084F1700084F170008B8
:100090004F1700084F1700084F1700084F170008A8
:1000A0004F1700084F1700084F1700084F17000898
:1000B0004F1700084F1700084F1700084F17000888
:1000C0004F1700084F1700084F1700084F17000878
:1000D0004F1700084F1700084F1700084F17000868
:1000E0004F1700084F1700084F1700084F17000858
:1000F0004F1700084F1700084F1700084F17000848
:100100004F1700084F1700084F1700084F17000837
:100110004F1700084F1700084F1700084F17000827
:100120004F1700084F1700084F1700084F17000817
:100130004F1700084F1700084F1700084F17000807
:100140004F1700084F1700084F1700084F170008F7
:100150004F1700084F1700084F1700084F170008E7
:100160004F1700084F1700084F1700084F170008D7
:100170004F1700084F1700084F1700084F170008C7
:100180004F1700084F1700084F1700084F170008B7
:100190004F1700084F1700084F1700084F170008A7
:1001A0004F1700084F1700084F1700084F17000897
:1001B0004F1700084F1700084F1700084F17000887
:1001C0004F1700084F1700084F1700084F17000877
:1001D0004F1700084F1700084F1700084F17000867
:1001E0004F1700084F1700084F1700084F17000857
:1001F0004F1700084F1700084F1700084F17000847
:100200004F1700084F1700084F1700084F17000836
:100210004F1700084F1700084F1700084F17000826
:100220004F1700084F1700084F1700084F17000816
:100230004F1700084F1700084F1700084F17000806
:100240004F1700084F1700084F1700084F170008F6
:100250004F1700084F1700084F1700084F170008E6
:100260004F1700084F1700084F1700084F170008D6
:100270004F1700084F1700084F1700084F170008C6
:100280004F1700084F1700084F1700084F170008B6
:100290004F1700084F17000880B500AF41F6044023
:1002A00001F048FA082300220121104800F0F7FF6E
:1002B0000823002200210D4801F011F808210B4805
:1002C00000F0DEFF0A4B1B68094A43F48073136099
:1002D00041F6024001F02EFA4FF4005302220021B1
:1002E000044800F0DCFF00BF80BD00BF00100258D2
:1002F000004802580008025880B500AF4FF4407023
:1003000001F09BFA00F00EF84FF47A7000F09EF8BE
:10031000FFF7C2FF00F026F900F03AF9052000F0DF
:100320007BF8F9E780B58CB000AF3B462C2200216A
:10033000184601F0A9FB41F6074001F0FBF941F630
:10034000816001F0F7F9022301220121304800F019
:10035000A6FF0223022200212D4800F0C0FF002347
:10036000FB6203E000BFFB6A0133FB62FB6A132BF5
:10037000F8D90221264800F081FF00233B700223B8
:100380007B70244B7B6005233B72C0237B8102235F
:100390003B7302237B730223BB7320233B748123B3
:1003A0007B8202233B7502237B750223BB752023CE
:1003B0003B7681237B8302233B7702237B770223D7
:1003C000BB77002387F82030082387F821300423E7
:1003D00087F82230042387F82330042387F8243059
:1003E000042387F82530042387F82630012387F873
:1003F0002730022387F82830002387F829303B462E
:10040000184601F04DF800BF3037BD4680BD00BF33
:10041000001C025840787D0180B485B000AF786040
:10042000094B1B68FB6001E030BF00BF064B1A6838
:10043000FB68D31A7A689A42F6D800BF00BF143717
:10044000BD465DF8047B70474000002080B582B057
:1004500000AF7860042001F0D3F9002001F02CF9FE
:1004600002467B68B2FBF3F3013B184601F0C2F988
:1004700001F0DEF90F21FF2001F0E8F901F0CAF9DF
:1004800001F0CFF900BF0837BD4680BD80B400AF92
:10049000044B1B680133034A136000BFBD465DF87F
:1004A000047B70474000002080B582B000AF7860C8
:1004B0007B681B88002B0CD14FF40051074800F0DB
:1004C000E2FE0346B3F5005F0CBF01230023DBB25D
:1004D00000E0002318460837BD4680BD00080258DA
:1004E00080B582B000AF78600B46FB70FB78032BC1
:1004F00020D801A252F823F0350500083505000880
:1005000009050008230500087B68DB8A022B13D14C
:100510007B681B88002B0FD108210B4800F0B6FE2A
:100520000AE07B681B88002B08D10821064800F0F0
:10053000ADFE03E000BF02E000BF00E000BF00BF6F
:100540000837BD4680BD00BF0010025880B400AF20
:10055000034B1B681846BD465DF8047B704700BF1F
:100560004000002080B582B002AF064B0193064BDD
:100570000093002300220121044800F0D3FA00BFB9
:10058000BD4680BDE1040008A90400080000002069
:1005900080B500AFFFF7DAFF0346184600F032FCE3
:1005A00000BF80BD80B483B000AF78607B685B081B
:1005B00003F055337A68D31A7B607B6803F03332DB
:1005C0007B689B0803F0333313447B607B681A0914
:1005D0007B68134403F00F337B607A6813461B0279
:1005E00013441A0413441B0E18460C37BD465DF81D
:1005F000047B704780B485B000AF786039603B6899
:100600005B099B007A6813441B68FB603B6803F03E
:100610001F03FA6822FA03F303F0010318461437A4
:10062000BD465DF8047B704780B485B000AF78604C
:1006300039603B6803F01F03012202FA03F3FB60F9
:100640003B685B099A0079680A441168FA68D243EA
:100650009B00786803440A401A6000BF1437BD4607
:100660005DF8047B704780B485B000AF7860396076
:100670003B6803F01F03012202FA03F3FB603B68AF
:100680005B099A0079680A4411689B007A681344F0
:10069000FA680A431A6000BF1437BD465DF8047B50
:1006A000704780B487B000AFF860B9607A60BB680B
:1006B00003F01F03012202FA03F37B617B68002B26
:1006C0000CD0BB685B099A00F9680A4411689B006A
:1006D000FA6813447A690A431A600CE0BB685B0944
:1006E0009A00F9680A4411687A69D2439B00F86855
:1006F00003440A401A6000BF1C37BD465DF8047B06
:10070000704780B584B000AF786039600023BB606B
:100710000023FB6015E0FB689B007A6813441B68AC
:10072000002B0BD0FB689B007A6813441B681846AB
:10073000FFF738FF0246BB681344BB60FB68013318
:10074000FB603B68013B5B095A1CFB689A42E2D89C
:10075000BB6818461037BD4680BD80B487B000AF77
:10076000F860B9607A6000237B610CE07B699B00D4
:10077000BA681A447B699B00F9680B4412681A60D6
:100780007B6901337B617B68013B5B095A1C7B6998
:100790009A42EBD800BF00BF1C37BD465DF8047B12
:1007A000704780B487B000AFF860B9607A603B6092
:1007B00000237B6112E07B699B00BA6813441968CF
:1007C0007B699B007A6813441A687B699B00F86810
:1007D00003440A401A607B6901337B613B68013B3B
:1007E0005B095A1C7B699A42E5D800BF00BF1C37E1
:1007F000BD465DF8047B704780B584B000AFF860FB
:10080000B9607A607B68013B5B0901339B001A4643
:10081000B968F86801F00AF9034618461037BD4672
:1008200080BD80B483B000AF786039607A683B687F
:10083000D31A18460C37BD465DF8047B704780B567
:1008400086B000AFF8607B600B46FB721346BB724C
:100850007D4B7B61FB689B69002B00F05F81BA7A5E
:10086000FB7A9A420CD0FB687A689A60BB7A002BBC
:1008700006D0FB689B7843F00203DAB2FB689A70FB
:10088000BB7A002B00F09880FB689B7803F0010393
:10089000002B5FD1FB689B6819467868FFF7C1FFA2
:1008A0000246FB689B691B889A42C0F23881FB684C
:1008B000DB8A002B19D0FB681B6919467868FFF7A3
:1008C000B0FF0246FB689B691B899A420DDBFB68FF
:1008D000DB7803F00403002B04D07B699B690221C1
:1008E000F8689847FB680022DA82FB687A68DA6069
:1008F000FB6800229A82FB689B7843F00103DAB21E
:10090000FB689A70FB68DB7803F00103002B04D0CE
:100910007B699B690021F8689847FB687A685A6090
:10092000FDE0FB68DB68FA68926952891A44FB684B
:10093000DA60FB689B8A01339AB2FB689A82FB6893
:10094000DB7803F00803002B04D07B699B6903214B
:10095000F8689847FB689B695B89002B0BD0FB68A4
:10096000DB6819467868FFF75CFF0246FB689B6905
:100970005B899A42D5DAFB68DB8A002B00F0CF80D6
:10098000FB685B6819467868FFF74BFF0246FB6817
:100990009B69DB889A4240F3C280FB68DB7803F0F6
:1009A0000403002B04D07B699B690221F8689847F7
:1009B000FB680022DA82B2E0FB689B7803F0010357
:1009C000002B7ED0FB689B6819467868FFF729FFEB
:1009D0000246FB689B695B889A42C0F2A080FB6874
:1009E0009B7823F00103DAB2FB689A70FB68DB782E
:1009F00003F00203002B04D07B699B690121F86896
:100A00009847FB685B6819467868FFF70AFF02465B
:100A1000FB689B699B889A4218DBFB685B681946F8
:100A20007868FFF7FEFE0246FB689B69DB889A4206
:100A30000CDCFB68DB8A01339AB2FB68DA82FB6864
:100A40007A681A6120E000BF44000020FB68DB8A5E
:100A5000002B16D0FB685B6819467868FFF7E1FE4B
:100A60000246FB689B699B889A420ADAFB68DB783E
:100A700003F00403002B04D07B699B690221F86812
:100A80009847FB680022DA82FB68DB8A002B14D0CF
:100A9000FB68DA8AFB689B699B899A420DD1FB68E7
:100AA000DB7803F00403002B04D07B699B690221EF
:100AB000F8689847FB680022DA82FB687A685A6017
:100AC0002DE0FB68DB8A002B1AD0FB681B691946F6
:100AD0007868FFF7A6FE0246FB689B691B899A426D
:100AE0001DDBFB68DB7803F00403002B04D07B697B
:100AF0009B690221F8689847FB680022DA820EE0C1
:100B0000FB689B7803F00203002B08D0FB689B78FE
:100B100023F00203DAB2FB689A7000E000BF1837D6
:100B2000BD4680BD80B586B000AFF8607A601A46D9
:100B30000B467B8113463B81124B7B617B6A002B0A
:100B400002D03B6A002B01D1002317E028220021AC
:100B5000786900F099FF7B69FA681A607B697A8985
:100B60009A807B697A689A607B693A899A817B6905
:100B70007A6A9A617B693A6ADA6101231846183702
:100B8000BD4680BD4400002080B586B000AF7860CF
:100B9000224BFB6000233B6116E0FB68D969FB68D0
:100BA00018683A691346DB009B1A9B0003441846F9
:100BB00088470346BB72BB7A1A4639697868FFF7E3
:100BC00070FD3B6901333B61FB689B881A463B69BA
:100BD0009342E2DBFB681B697B61FB689B883B619E
:100BE00013E0FB68DB697A690432104698470346D4
:100BF000FB72FB7A1A4639697868FFF752FD7B6908
:100C00001B687B613B6901333B617B69002BE8D149
:100C100000BF00BF1837BD4680BD00BF44000020A4
:100C200090B585B000AFF860B9607A603B60396814
:100C3000B868FFF7DFFC0346DCB239687868FFF775
:100C4000D9FC0346DAB23B6A2146F868FFF7F7FDA4
:100C500000BF1437BD4690BD80B588B000AFF860C6
:100C6000B9607A603B6007F1140300221A605A6091
:100C700040213868FFF745FD0346002B30D007F1CF
:100C8000140040233A687968FFF78BFD07F11403DD
:100C9000402239681846FFF7AFFD0346002B0CBF12
:100CA00001230023DBB2FB7707F1140040233A68ED
:100CB000B968FFF776FD07F114034022396818463A
:100CC000FFF79AFD0346002B0CBF01230023DBB284
:100CD000BB77FA7FB97FBB6AF868FFF7B0FD00E029
:100CE00000BF2037BD4680BD90B589B002AF7860A7
:100CF0003960434BBB600023FB6013E0BB6819689D
:100D0000FA681346DB009B1A9B00C818BB6803F106
:100D100020013B680093FB687A68FFF781FFFB685E
:100D20000133FB60BB689B881A46FB689342E5DB96
:100D3000BB681B697B61BB689B88FB6010E07B69BB
:100D4000181DBB6803F120013B680093FB687A68BB
:100D5000FFF766FF7B691B687B61FB680133FB6003
:100D60007B69002BEBD10023FB601FE0BB68996817
:100D7000FA681346DB0013449B000B4403F10800A0
:100D8000BB6803F12004BB689968FA681346DB006E
:100D900013449B000B441A463B68009313467A6841
:100DA0002146FFF759FFFB680133FB60BB689B8955
:100DB0001A46FB689342D9DBBB685B693B6110E074
:100DC0003B6903F10C00BB6803F120013B691A1D6C
:100DD0003B68009313467A68FFF73EFF3B691B6848
:100DE0003B613B69002BEBD1BB6820334022796823
:100DF0001846FFF7B2FC00BF1C37BD4690BD00BFD0
:100E00004400002080B584B000AF786007F108038B
:100E100000221A605A6007F108031846FFF7B4FE73
:100E200007F1080379681846FFF75EFF00BF103727
:100E3000BD4680BD80B485B000AF0F4B7B60002302
:100E4000FB607B681B69BB607B689B881A46FB68FC
:100E50001344FB6005E0FB680133FB60BB681B6863
:100E6000BB60BB68002BF6D1FB6818461437BD4643
:100E70005DF8047B704700BF4400002080B487B059
:100E800000AF0346FB801E4BFB6000237B61002309
:100E90007B6110E0FB6819687A691346DB009B1AD6
:100EA0009B000B441B88FA889A4201D17B6921E0A0
:100EB0007B6901337B61FB689B881A467B6993429F
:100EC000E8DBFB681B693B61FB689B887B610CE08E
:100ED0003B699B88FA889A4201D17B690AE03B69A9
:100EE0001B683B617B6901337B613B69002BEFD160
:100EF0004FF0FF3318461C37BD465DF8047B704742
:100F00004400002080B487B000AF0346FB80224B32
:100F1000FB6000237B6100237B6117E0FB6819689D
:100F20007A691346DB009B1A9B000B441B88FA88E6
:100F30009A4208D1FB6819687A691346DB009B1A4C
:100F40009B000B4421E07B6901337B61FB689B883C
:100F50001A467B699342E1DBFB681B693B61FB68D6
:100F60009B887B610DE03B699B88FA889A4202D19D
:100F70003B69043309E03B691B683B617B690133D2
:100F80007B613B69002BEED1002318461C37BD4620
:100F90005DF8047B704700BF4400002080B582B03C
:100FA00000AF78607B681B881846FFF767FF034631
:100FB00018460837BD4680BD80B582B000AF786066
:100FC0007B689B881846FFF759FF03461846083789
:100FD000BD4680BD80B582B000AF786039607B6867
:100FE00039681846FFF73FFB00BF0837BD4680BD94
:100FF00080B582B000AF786039607B683968184688
:10100000FFF712FB00BF0837BD4680BD80B584B036
:1010100000AF78600B467B807B881846FFF72EFF79
:10102000F860FB68002B04DBF9687868FFF7D2FFF3
:1010300000E000BF1037BD4680BD80B584B000AF72
:1010400078600B467B807B881846FFF717FFF860B7
:10105000FB68002B04DBF9687868FFF7C9FF00E044
:1010600000BF1037BD4680BD80B483B000AF78604C
:101070007B68002B07D07B689B7803F00103002B73
:1010800001D0012300E0002318460C37BD465DF86F
:10109000047B704780B483B000AF78607B68002B1E
:1010A00007D07B689B7803F00203002B01D001235B
:1010B00000E0002318460C37BD465DF8047B7047FE
:1010C00080B584B000AF374B3B6000237B6012E0FB
:1010D0003B6819687A681346DB009B1A9B000B4437
:1010E0001846FFF7D7FF0346002B01D0012354E039
:1010F0007B6801337B603B689B881A467B68934220
:10110000E6DB3B681B69FB603B689B887B600FE00C
:10111000FB6804331846FFF7BDFF0346002B01D0E0
:1011200001233AE0FB681B68FB607B6801337B604E
:10113000FB68002BECD100237B6013E03B689968CF
:101140007A681346DB0013449B000B4408331846AF
:10115000FFF7A0FF0346002B01D001231DE07B68B1
:1011600001337B603B689B891A467B689342E5DBD1
:101170003B685B69BB600CE0BB680C331846FFF74B
:1011800089FF0346002B01D0012306E0BB681B68E2
:10119000BB60BB68002BEFD1002318461037BD465B
:1011A00080BD00BF4400002080B586B000AF7860ED
:1011B000184BFB60FB681B697B6100233B617B680C
:1011C000002B01D1002320E0FFF734FE03463F2B24
:1011D00001DD002319E07B69002B0FD1FB687A68E1
:1011E0001A61012311E07A697B689A4201D10023D8
:1011F0000BE07B693B617B691B687B617B69002B32
:10120000F1D13B697A681A60012318461837BD4648
:1012100080BD00BF4400002080B487B000AF78607C
:10122000154BFB60FB685B697B6100233B617B685E
:10123000002B01D1002319E07B69002B0FD1FB6843
:101240007A685A61012311E07A697B689A4201D178
:1012500000230BE07B693B617B691B687B617B69D9
:10126000002BF1D13B697A681A60012318461C37BC
:10127000BD465DF8047B70474400002081617047E3
:10128000090481617047006908407047436901EAB9
:10129000030221EA030141EA0241816170472DE91D
:1012A000F04105680026C4684FF0030E43FA06F7C4
:1012B000FF070DD577000EFA07FC01FA07F802FACE
:1012C00007F725EA0C0524EA0C0448EA05053C4327
:1012D0000136102EEAD10560C460BDE8F081012915
:1012E00041680CBF19439943F0B5416000248168FF
:1012F000032643FA04F5ED0707D5650006FA05F75E
:1013000002FA05F521EA070129430134102CF0D136
:101310008160F0BD2DE9F04391F800C0BCF1000FF1
:1013200000F0A580012A26D0574B9E1F022A18BF25
:101330001E46013A554D0023B1F8028045F832307F
:1013400008F1FF3355F832402343D4B245F8323028
:10135000A700B0FBFCF34E48FFB2B3FBF0FCACF1CE
:10136000030001284B4808D80423D0F82CE4BB40E4
:101370004EEA03030DE0484EDBE7ACF1050EBEF18B
:10138000030F76D80823D0F82C9403FA07FE4EEA10
:101390000903C0F82C340CFB08F3B3F5D27F09D84D
:1013A000DFF8F0C00220DCF82CE4B84040EA0E0080
:1013B000CCF82C046700087904EB4404E4B2B0B123
:1013C00055F832C000F1FF3E4CEA4E2CDFF8C4E085
:1013D00045F832C04FF4803CDEF82C840CFA04FC53
:1013E000B3FBF0F04CEA080CCEF82CC430804879FE
:1013F000B0B155F832C000F1FF3E4CEA0E4CDFF8B8
:1014000094E045F832C04FF4003CDEF82C840CFA2E
:1014100004FCB3FBF0F04CEA080CCEF82CC470804E
:10142000897999B155F8320001F1FF3C40EA0C602E
:1014300045F832004FF480221648A240D0F82C54D0
:10144000B3FBF1F32A43C0F82C24B380114AFFB256
:101450004FF08073D2F80014BB400B43C2F8003445
:101460004FF00073BB40D2F800141942FBD0BDE826
:10147000F083DFF828E073458DD94FF00C0ED0F8DB
:101480002C340EFA07FE73E7360000203044025871
:1014900040420F00004002582A0000203F548900BB
:1014A000F8B5814B0446D3F8002442F00102C3F89A
:1014B0000024D3F8102422F00702C3F81024D3F834
:1014C000102412F0380FFAD10122C3F8002494F846
:1014D000291094F8280000F02FFA94F8270000F063
:1014E00057FA94F8260000F0D3F994F82630002B30
:1014F00000F0C58000F0BCF963688BB16A4BD3F88B
:10150000002442F48032C3F80024D3F8002492036C
:10151000FBD563684FF47A72B3FBF2F3634A13842A
:10152000237C227A1B03617843EA0213227E0B4359
:1015300043EA02535C4AC2F82834002900F0A28032
:101540006568002304F108012846C2F82C34012202
:10155000FFF7E0FE022204F110012846FFF7DAFE51
:101560002846032204F11801FFF7D4FE23784F48E0
:10157000002B40F08980C38994F8245000264A4FFC
:1015800094F8201094F8212003800729C7F81864E4
:101590004FEA0516D7F818C446EA012646EA0206BD
:1015A00046EA0C06C7F8186406D90B2994BF073918
:1015B000063943FA01F18BB2072A438009D90B2A75
:1015C00095BF073A911F43FA02F20B4194BF93B2C1
:1015D0009BB2032D94F82310334E8CBFEA1E1A469B
:1015E0004FF00005838084BF43FA02F292B20329D0
:1015F000428194F82220C6F81C544FEA01258CBF82
:101600000339194645EA0215D6F81C7488BF43FA17
:1016100001F145EA070588BF89B2032AC6F81C54C0
:101620008CBF033A1A46018188BF43FA02F294F84C
:10163000251088BF92B20329C2801B4AD2F82044E9
:101640004FF00004C2F82044D2F8204444EA0114C8
:1016500084BF033943FA01F1C2F8204488BF8BB23A
:101660008381D2F8103443F00303C2F81034D2F867
:1016700010340D4AC3F3C203032B0FD1F8BD00F0A1
:10168000FFF839E70A4D5CE7012B09BF6368402387
:10169000084AB3FBF2F308BF9BB26DE7D2F81034EF
:1016A000C3F3C203E8E700BF004002581C0000205B
:1016B0000090D00340420F0008B509282CD8DFE87D
:1016C00000F00A051C0A0D0D10131619154B188889
:1016D000154B584308BD134B5888F9E7114B9888B0
:1016E000F6E7104BD888F3E70E4B1889F0E70D4B5F
:1016F0005889EDE70B4B9889EAE70C4BD3F84C344B
:1017000013F0405FC3F3017208D0022A08D1054BE1
:10171000188C4FF47A73DCE700F0A8F80448D9E796
:101720000020D7E71C00002040420F000040025874
:101730000090D0034309012200F01F0003F1B043E1
:10174000824003F5113319680A431A607047FEE7B7
:101750007047000038B51D4A1D4B1E498B4220D3EF
:101760001D4A0021934221D34FF0E0231B4C1C4D16
:10177000D3F8142D42F40072C3F8142DD3F8882D39
:1017800042F47002C3F8882DAC4212D3154C164DAA
:10179000AC4212D3154CFEF7AFFD154DAC4210D341
:1017A00038BD52F8040B43F8040BD7E743F8041B89
:1017B000D8E754F8043B9847E6E754F8043B9847C9
:1017C000E6E754F8043B9847E8E700BF3C1B0008F5
:1017D00000000020400000206C0000203C1B00089E
:1017E0003C1B00083C1B00083C1B00083C1B00087D
:1017F0003C1B000820F07F404FF0E0235861704709
:101800004FF0E02200F00400136923F004030343C7
:10181000136170474FF0E022136943F00203136134
:1018200070474FF0E022136943F0010313617047E2
:101830004FF0E02300229A61704740F0BF604FF004
:10184000E02340F40030C3F80C0D7047952804D90C
:1018500000F00F00044BC154704700F1604000F5E8
:1018600064400170704700BF14ED00E0FEE7000027
:10187000024A136843F480731360704700200052DB
:10188000024A136823F480731360704700200052EB
:10189000034A136823F00F0303431360704700BF2C
:1018A00000200052044AD2F80C3823F0070343F01A
:1018B0000203C2F80C38704700400258044AD2F8BC
:1018C0000C3823F0070343F00603C2F80C387047C6
:1018D0000040025808B50B0170B943F004030948F1
:1018E0005242D0F80C1802F0020221F03F010A43E4
:1018F0001A43C0F80C2808BD09B9FFF7B7FF43F039
:101900000C03ECE700400258044AD2F80C3823F0EC
:10191000070343F00103C2F80C3870470040025837
:10192000044AD2F80C3823F0070343F00503C2F849
:101930000C3870470040025808B5072807D8DFE880
:1019400000F0040C0F12121D1D21FFF7B7FF0F4A04
:10195000D2F804389B04FBD508BDFFF7E1FFF6E79A
:10196000FFF7A0FFF3E7A0F1040C0021DCF1000277
:1019700042EB0C020020FFF7ADFFE8E705384242DA
:101980004241F7E7FFF7C0FFE1E700BF0040025820
:10199000F8B5074608B9FFF769FF204B421E204EF5
:1019A0001B68C3F30B03B3F5906F0FD1D6F818384B
:1019B0001C4923F440438A5C43EA8233C6F8183852
:1019C000174AD2F818389B04FBD5F8BD1649B3F571
:1019D0008A6FD6F818588C5C25F440454FEA843459
:1019E00018D141F68160FFF7A5FE012F4FF0B043FB
:1019F0000AD145F44045C6F81858D3F82C2442F0D3
:101A00000102C3F82C24DBE7D3F82C2422F00102D6
:101A1000C3F82C242C43C6F81848D1E70010005C0A
:101A200000400258361B0008321B0008032A30B45D
:101A300012D941EA0004A40784460B4621D1194675
:101A4000604653F8044B5CF8045BA54219D1043A94
:101A5000032AF4D860461946541E7AB1431E013950
:101A6000021901E09A4209D013F8010F11F801CFD1
:101A70006045F7D0A0EB0C0030BC7047002030BCB4
:101A80007047541EEAE700BF830730B546D084187C
:101A9000844604E003F8011B9D0704D09C46A4453E
:101AA0006346F7D130BD013A0244A2EB0C02032A8F
:101AB00029D9CCB204EB04240F2A04EB04442FD917
:101AC000A2F1100C2CF00F0C03F11005AC44C3E98B
:101AD0000044C3E9024410336345F8D112F00C0FFF
:101AE00002F00F0E18D02EF0030C9C44AEF104054A
:101AF0001A4642F8044B6245FBD125F00304043337
:101B00000EF003022344002ACCD0C9B21A4403F8D1
:101B1000011B9342FBD130BD7246F4E70346C6E792
:101B20009646E0E71400140014002C01C800F401EC
:0C1B30000A000003020103020100000093
:101B3C000000000F0000000000000000000000008A
:101B4C000000000000000000241B000840004000C2
:101B5C004000400040004000400000000000000039
:101B6C000000000000000000000000000000000069
:040000050800175583
:00000001FF

4343
2gpio-lib/bin/gpio-lib.list Executable file

File diff suppressed because it is too large Load Diff

1396
2gpio-lib/bin/gpio-lib.map Normal file

File diff suppressed because it is too large Load Diff

2
2gpio-lib/bin/gpio-lib.size Executable file
View File

@@ -0,0 +1,2 @@
text data bss dec hex filename
6972 64 524332 531368 81ba8 /home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib/bin/gpio-lib.elf

442
2gpio-lib/bin/gpio-lib.srec Executable file
View File

@@ -0,0 +1,442 @@
S02B00002F686F6D652F74696D652F646F632F636F646566696C652F656D62652F426C6F672F73746D33322FBD
S315080000000000022055170008511700084F1700086E
S315080000104F1700084F1700084F1700080000000088
S315080000200000000000000000000000005117000852
S315080000305117000800000000511700088D04000839
S315080000404F1700084F1700084F1700084F170008EA
S315080000504F1700084F1700084F1700084F170008DA
S315080000604F1700084F1700084F1700084F170008CA
S315080000704F1700084F1700084F1700084F170008BA
S315080000804F1700084F1700084F1700084F170008AA
S315080000904F1700084F1700084F1700084F1700089A
S315080000A04F1700084F1700084F1700084F1700088A
S315080000B04F1700084F1700084F1700084F1700087A
S315080000C04F1700084F1700084F1700084F1700086A
S315080000D04F1700084F1700084F1700084F1700085A
S315080000E04F1700084F1700084F1700084F1700084A
S315080000F04F1700084F1700084F1700084F1700083A
S315080001004F1700084F1700084F1700084F17000829
S315080001104F1700084F1700084F1700084F17000819
S315080001204F1700084F1700084F1700084F17000809
S315080001304F1700084F1700084F1700084F170008F9
S315080001404F1700084F1700084F1700084F170008E9
S315080001504F1700084F1700084F1700084F170008D9
S315080001604F1700084F1700084F1700084F170008C9
S315080001704F1700084F1700084F1700084F170008B9
S315080001804F1700084F1700084F1700084F170008A9
S315080001904F1700084F1700084F1700084F17000899
S315080001A04F1700084F1700084F1700084F17000889
S315080001B04F1700084F1700084F1700084F17000879
S315080001C04F1700084F1700084F1700084F17000869
S315080001D04F1700084F1700084F1700084F17000859
S315080001E04F1700084F1700084F1700084F17000849
S315080001F04F1700084F1700084F1700084F17000839
S315080002004F1700084F1700084F1700084F17000828
S315080002104F1700084F1700084F1700084F17000818
S315080002204F1700084F1700084F1700084F17000808
S315080002304F1700084F1700084F1700084F170008F8
S315080002404F1700084F1700084F1700084F170008E8
S315080002504F1700084F1700084F1700084F170008D8
S315080002604F1700084F1700084F1700084F170008C8
S315080002704F1700084F1700084F1700084F170008B8
S315080002804F1700084F1700084F1700084F170008A8
S315080002904F1700084F17000880B500AF41F6044015
S315080002A001F048FA082300220121104800F0F7FF60
S315080002B00823002200210D4801F011F808210B48F7
S315080002C000F0DEFF0A4B1B68094A43F4807313608B
S315080002D041F6024001F02EFA4FF4005302220021A3
S315080002E0044800F0DCFF00BF80BD00BF00100258C4
S315080002F0004802580008025880B500AF4FF4407015
S3150800030001F09BFA00F00EF84FF47A7000F09EF8B0
S31508000310FFF7C2FF00F026F900F03AF9052000F0D1
S315080003207BF8F9E780B58CB000AF3B462C2200215C
S31508000330184601F0A9FB41F6074001F0FBF941F622
S31508000340816001F0F7F9022301220121304800F00B
S31508000350A6FF0223022200212D4800F0C0FF002339
S31508000360FB6203E000BFFB6A0133FB62FB6A132BE7
S31508000370F8D90221264800F081FF00233B700223AA
S315080003807B70244B7B6005233B72C0237B81022351
S315080003903B7302237B730223BB7320233B748123A5
S315080003A07B8202233B7502237B750223BB752023C0
S315080003B03B7681237B8302233B7702237B770223C9
S315080003C0BB77002387F82030082387F821300423D9
S315080003D087F82230042387F82330042387F824304B
S315080003E0042387F82530042387F82630012387F865
S315080003F02730022387F82830002387F829303B4620
S31508000400184601F04DF800BF3037BD4680BD00BF25
S31508000410001C025840787D0180B485B000AF786032
S31508000420094B1B68FB6001E030BF00BF064B1A682A
S31508000430FB68D31A7A689A42F6D800BF00BF143709
S31508000440BD465DF8047B70474000002080B582B049
S3150800045000AF7860042001F0D3F9002001F02CF9F0
S3150800046002467B68B2FBF3F3013B184601F0C2F97A
S3150800047001F0DEF90F21FF2001F0E8F901F0CAF9D1
S3150800048001F0CFF900BF0837BD4680BD80B400AF84
S31508000490044B1B680133034A136000BFBD465DF871
S315080004A0047B70474000002080B582B000AF7860BA
S315080004B07B681B88002B0CD14FF40051074800F0CD
S315080004C0E2FE0346B3F5005F0CBF01230023DBB24F
S315080004D000E0002318460837BD4680BD00080258CC
S315080004E080B582B000AF78600B46FB70FB78032BB3
S315080004F020D801A252F823F0350500083505000872
S3150800050009050008230500087B68DB8A022B13D13E
S315080005107B681B88002B0FD108210B4800F0B6FE1C
S315080005200AE07B681B88002B08D10821064800F0E2
S31508000530ADFE03E000BF02E000BF00E000BF00BF61
S315080005400837BD4680BD00BF0010025880B400AF12
S31508000550034B1B681846BD465DF8047B704700BF11
S315080005604000002080B582B002AF064B0193064BCF
S315080005700093002300220121044800F0D3FA00BFAB
S31508000580BD4680BDE1040008A9040008000000205B
S3150800059080B500AFFFF7DAFF0346184600F032FCD5
S315080005A000BF80BD80B483B000AF78607B685B080D
S315080005B003F055337A68D31A7B607B6803F03332CD
S315080005C07B689B0803F0333313447B607B681A0906
S315080005D07B68134403F00F337B607A6813461B026B
S315080005E013441A0413441B0E18460C37BD465DF80F
S315080005F0047B704780B485B000AF786039603B688B
S315080006005B099B007A6813441B68FB603B6803F030
S315080006101F03FA6822FA03F303F001031846143796
S31508000620BD465DF8047B704780B485B000AF78603E
S3150800063039603B6803F01F03012202FA03F3FB60EB
S315080006403B685B099A0079680A441168FA68D243DC
S315080006509B00786803440A401A6000BF1437BD46F9
S315080006605DF8047B704780B485B000AF7860396068
S315080006703B6803F01F03012202FA03F3FB603B68A1
S315080006805B099A0079680A4411689B007A681344E2
S31508000690FA680A431A6000BF1437BD465DF8047B42
S315080006A0704780B487B000AFF860B9607A60BB68FD
S315080006B003F01F03012202FA03F37B617B68002B18
S315080006C00CD0BB685B099A00F9680A4411689B005C
S315080006D0FA6813447A690A431A600CE0BB685B0936
S315080006E09A00F9680A4411687A69D2439B00F86847
S315080006F003440A401A6000BF1C37BD465DF8047BF8
S31508000700704780B584B000AF786039600023BB605D
S315080007100023FB6015E0FB689B007A6813441B689E
S31508000720002B0BD0FB689B007A6813441B6818469D
S31508000730FFF738FF0246BB681344BB60FB6801330A
S31508000740FB603B68013B5B095A1CFB689A42E2D88E
S31508000750BB6818461037BD4680BD80B487B000AF69
S31508000760F860B9607A6000237B610CE07B699B00C6
S31508000770BA681A447B699B00F9680B4412681A60C8
S315080007807B6901337B617B68013B5B095A1C7B698A
S315080007909A42EBD800BF00BF1C37BD465DF8047B04
S315080007A0704780B487B000AFF860B9607A603B6084
S315080007B000237B6112E07B699B00BA6813441968C1
S315080007C07B699B007A6813441A687B699B00F86802
S315080007D003440A401A607B6901337B613B68013B2D
S315080007E05B095A1C7B699A42E5D800BF00BF1C37D3
S315080007F0BD465DF8047B704780B584B000AFF860ED
S31508000800B9607A607B68013B5B0901339B001A4635
S31508000810B968F86801F00AF9034618461037BD4664
S3150800082080BD80B483B000AF786039607A683B6871
S31508000830D31A18460C37BD465DF8047B704780B559
S3150800084086B000AFF8607B600B46FB721346BB723E
S315080008507D4B7B61FB689B69002B00F05F81BA7A50
S31508000860FB7A9A420CD0FB687A689A60BB7A002BAE
S3150800087006D0FB689B7843F00203DAB2FB689A70ED
S31508000880BB7A002B00F09880FB689B7803F0010385
S31508000890002B5FD1FB689B6819467868FFF7C1FF94
S315080008A00246FB689B691B889A42C0F23881FB683E
S315080008B0DB8A002B19D0FB681B6919467868FFF795
S315080008C0B0FF0246FB689B691B899A420DDBFB68F1
S315080008D0DB7803F00403002B04D07B699B690221B3
S315080008E0F8689847FB680022DA82FB687A68DA605B
S315080008F0FB6800229A82FB689B7843F00103DAB210
S31508000900FB689A70FB68DB7803F00103002B04D0C0
S315080009107B699B690021F8689847FB687A685A6082
S31508000920FDE0FB68DB68FA68926952891A44FB683D
S31508000930DA60FB689B8A01339AB2FB689A82FB6885
S31508000940DB7803F00803002B04D07B699B6903213D
S31508000950F8689847FB689B695B89002B0BD0FB6896
S31508000960DB6819467868FFF75CFF0246FB689B69F7
S315080009705B899A42D5DAFB68DB8A002B00F0CF80C8
S31508000980FB685B6819467868FFF74BFF0246FB6809
S315080009909B69DB889A4240F3C280FB68DB7803F0E8
S315080009A00403002B04D07B699B690221F8689847E9
S315080009B0FB680022DA82B2E0FB689B7803F0010349
S315080009C0002B7ED0FB689B6819467868FFF729FFDD
S315080009D00246FB689B695B889A42C0F2A080FB6866
S315080009E09B7823F00103DAB2FB689A70FB68DB7820
S315080009F003F00203002B04D07B699B690121F86888
S31508000A009847FB685B6819467868FFF70AFF02464D
S31508000A10FB689B699B889A4218DBFB685B681946EA
S31508000A207868FFF7FEFE0246FB689B69DB889A42F8
S31508000A300CDCFB68DB8A01339AB2FB68DA82FB6856
S31508000A407A681A6120E000BF44000020FB68DB8A50
S31508000A50002B16D0FB685B6819467868FFF7E1FE3D
S31508000A600246FB689B699B889A420ADAFB68DB7830
S31508000A7003F00403002B04D07B699B690221F86804
S31508000A809847FB680022DA82FB68DB8A002B14D0C1
S31508000A90FB68DA8AFB689B699B899A420DD1FB68D9
S31508000AA0DB7803F00403002B04D07B699B690221E1
S31508000AB0F8689847FB680022DA82FB687A685A6009
S31508000AC02DE0FB68DB8A002B1AD0FB681B691946E8
S31508000AD07868FFF7A6FE0246FB689B691B899A425F
S31508000AE01DDBFB68DB7803F00403002B04D07B696D
S31508000AF09B690221F8689847FB680022DA820EE0B3
S31508000B00FB689B7803F00203002B08D0FB689B78F0
S31508000B1023F00203DAB2FB689A7000E000BF1837C8
S31508000B20BD4680BD80B586B000AFF8607A601A46CB
S31508000B300B467B8113463B81124B7B617B6A002BFC
S31508000B4002D03B6A002B01D1002317E0282200219E
S31508000B50786900F099FF7B69FA681A607B697A8977
S31508000B609A807B697A689A607B693A899A817B69F7
S31508000B707A6A9A617B693A6ADA61012318461837F4
S31508000B80BD4680BD4400002080B586B000AF7860C1
S31508000B90224BFB6000233B6116E0FB68D969FB68C2
S31508000BA018683A691346DB009B1A9B0003441846EB
S31508000BB088470346BB72BB7A1A4639697868FFF7D5
S31508000BC070FD3B6901333B61FB689B881A463B69AC
S31508000BD09342E2DBFB681B697B61FB689B883B6190
S31508000BE013E0FB68DB697A690432104698470346C6
S31508000BF0FB72FB7A1A4639697868FFF752FD7B69FA
S31508000C001B687B613B6901333B617B69002BE8D13B
S31508000C1000BF00BF1837BD4680BD00BF4400002096
S31508000C2090B585B000AFF860B9607A603B60396806
S31508000C30B868FFF7DFFC0346DCB239687868FFF767
S31508000C40D9FC0346DAB23B6A2146F868FFF7F7FD96
S31508000C5000BF1437BD4690BD80B588B000AFF860B8
S31508000C60B9607A603B6007F1140300221A605A6083
S31508000C7040213868FFF745FD0346002B30D007F1C1
S31508000C80140040233A687968FFF78BFD07F11403CF
S31508000C90402239681846FFF7AFFD0346002B0CBF04
S31508000CA001230023DBB2FB7707F1140040233A68DF
S31508000CB0B968FFF776FD07F114034022396818462C
S31508000CC0FFF79AFD0346002B0CBF01230023DBB276
S31508000CD0BB77FA7FB97FBB6AF868FFF7B0FD00E01B
S31508000CE000BF2037BD4680BD90B589B002AF786099
S31508000CF03960434BBB600023FB6013E0BB6819688F
S31508000D00FA681346DB009B1A9B00C818BB6803F1F8
S31508000D1020013B680093FB687A68FFF781FFFB6850
S31508000D200133FB60BB689B881A46FB689342E5DB88
S31508000D30BB681B697B61BB689B88FB6010E07B69AD
S31508000D40181DBB6803F120013B680093FB687A68AD
S31508000D50FFF766FF7B691B687B61FB680133FB60F5
S31508000D607B69002BEBD10023FB601FE0BB68996809
S31508000D70FA681346DB0013449B000B4403F1080092
S31508000D80BB6803F12004BB689968FA681346DB0060
S31508000D9013449B000B441A463B68009313467A6833
S31508000DA02146FFF759FFFB680133FB60BB689B8947
S31508000DB01A46FB689342D9DBBB685B693B6110E066
S31508000DC03B6903F10C00BB6803F120013B691A1D5E
S31508000DD03B68009313467A68FFF73EFF3B691B683A
S31508000DE03B613B69002BEBD1BB6820334022796815
S31508000DF01846FFF7B2FC00BF1C37BD4690BD00BFC2
S31508000E004400002080B584B000AF786007F108037D
S31508000E1000221A605A6007F108031846FFF7B4FE65
S31508000E2007F1080379681846FFF75EFF00BF103719
S31508000E30BD4680BD80B485B000AF0F4B7B600023F4
S31508000E40FB607B681B69BB607B689B881A46FB68EE
S31508000E501344FB6005E0FB680133FB60BB681B6855
S31508000E60BB60BB68002BF6D1FB6818461437BD4635
S31508000E705DF8047B704700BF4400002080B487B04B
S31508000E8000AF0346FB801E4BFB6000237B610023FB
S31508000E907B6110E0FB6819687A691346DB009B1AC8
S31508000EA09B000B441B88FA889A4201D17B6921E092
S31508000EB07B6901337B61FB689B881A467B69934291
S31508000EC0E8DBFB681B693B61FB689B887B610CE080
S31508000ED03B699B88FA889A4201D17B690AE03B699B
S31508000EE01B683B617B6901337B613B69002BEFD152
S31508000EF04FF0FF3318461C37BD465DF8047B704734
S31508000F004400002080B487B000AF0346FB80224B24
S31508000F10FB6000237B6100237B6117E0FB6819688F
S31508000F207A691346DB009B1A9B000B441B88FA88D8
S31508000F309A4208D1FB6819687A691346DB009B1A3E
S31508000F409B000B4421E07B6901337B61FB689B882E
S31508000F501A467B699342E1DBFB681B693B61FB68C8
S31508000F609B887B610DE03B699B88FA889A4202D18F
S31508000F703B69043309E03B691B683B617B690133C4
S31508000F807B613B69002BEED1002318461C37BD4612
S31508000F905DF8047B704700BF4400002080B582B02E
S31508000FA000AF78607B681B881846FFF767FF034623
S31508000FB018460837BD4680BD80B582B000AF786058
S31508000FC07B689B881846FFF759FF0346184608377B
S31508000FD0BD4680BD80B582B000AF786039607B6859
S31508000FE039681846FFF73FFB00BF0837BD4680BD86
S31508000FF080B582B000AF786039607B68396818467A
S31508001000FFF712FB00BF0837BD4680BD80B584B028
S3150800101000AF78600B467B807B881846FFF72EFF6B
S31508001020F860FB68002B04DBF9687868FFF7D2FFE5
S3150800103000E000BF1037BD4680BD80B584B000AF64
S3150800104078600B467B807B881846FFF717FFF860A9
S31508001050FB68002B04DBF9687868FFF7C9FF00E036
S3150800106000BF1037BD4680BD80B483B000AF78603E
S315080010707B68002B07D07B689B7803F00103002B65
S3150800108001D0012300E0002318460C37BD465DF861
S31508001090047B704780B483B000AF78607B68002B10
S315080010A007D07B689B7803F00203002B01D001234D
S315080010B000E0002318460C37BD465DF8047B7047F0
S315080010C080B584B000AF374B3B6000237B6012E0ED
S315080010D03B6819687A681346DB009B1A9B000B4429
S315080010E01846FFF7D7FF0346002B01D0012354E02B
S315080010F07B6801337B603B689B881A467B68934212
S31508001100E6DB3B681B69FB603B689B887B600FE0FE
S31508001110FB6804331846FFF7BDFF0346002B01D0D2
S3150800112001233AE0FB681B68FB607B6801337B6040
S31508001130FB68002BECD100237B6013E03B689968C1
S315080011407A681346DB0013449B000B4408331846A1
S31508001150FFF7A0FF0346002B01D001231DE07B68A3
S3150800116001337B603B689B891A467B689342E5DBC3
S315080011703B685B69BB600CE0BB680C331846FFF73D
S3150800118089FF0346002B01D0012306E0BB681B68D4
S31508001190BB60BB68002BEFD1002318461037BD464D
S315080011A080BD00BF4400002080B586B000AF7860DF
S315080011B0184BFB60FB681B697B6100233B617B68FE
S315080011C0002B01D1002320E0FFF734FE03463F2B16
S315080011D001DD002319E07B69002B0FD1FB687A68D3
S315080011E01A61012311E07A697B689A4201D10023CA
S315080011F00BE07B693B617B691B687B617B69002B24
S31508001200F1D13B697A681A60012318461837BD463A
S3150800121080BD00BF4400002080B487B000AF78606E
S31508001220154BFB60FB685B697B6100233B617B6850
S31508001230002B01D1002319E07B69002B0FD1FB6835
S315080012407A685A61012311E07A697B689A4201D16A
S3150800125000230BE07B693B617B691B687B617B69CB
S31508001260002BF1D13B697A681A60012318461C37AE
S31508001270BD465DF8047B70474400002081617047D5
S31508001280090481617047006908407047436901EAAB
S31508001290030221EA030141EA0241816170472DE90F
S315080012A0F04105680026C4684FF0030E43FA06F7B6
S315080012B0FF070DD577000EFA07FC01FA07F802FAC0
S315080012C007F725EA0C0524EA0C0448EA05053C4319
S315080012D00136102EEAD10560C460BDE8F081012907
S315080012E041680CBF19439943F0B5416000248168F1
S315080012F0032643FA04F5ED0707D5650006FA05F750
S3150800130002FA05F521EA070129430134102CF0D128
S315080013108160F0BD2DE9F04391F800C0BCF1000FE3
S3150800132000F0A580012A26D0574B9E1F022A18BF17
S315080013301E46013A554D0023B1F8028045F8323071
S3150800134008F1FF3355F832402343D4B245F832301A
S31508001350A700B0FBFCF34E48FFB2B3FBF0FCACF1C0
S31508001360030001284B4808D80423D0F82CE4BB40D6
S315080013704EEA03030DE0484EDBE7ACF1050EBEF17D
S31508001380030F76D80823D0F82C9403FA07FE4EEA02
S315080013900903C0F82C340CFB08F3B3F5D27F09D83F
S315080013A0DFF8F0C00220DCF82CE4B84040EA0E0072
S315080013B0CCF82C046700087904EB4404E4B2B0B115
S315080013C055F832C000F1FF3E4CEA4E2CDFF8C4E077
S315080013D045F832C04FF4803CDEF82C840CFA04FC45
S315080013E0B3FBF0F04CEA080CCEF82CC430804879F0
S315080013F0B0B155F832C000F1FF3E4CEA0E4CDFF8AA
S3150800140094E045F832C04FF4003CDEF82C840CFA20
S3150800141004FCB3FBF0F04CEA080CCEF82CC4708040
S31508001420897999B155F8320001F1FF3C40EA0C6020
S3150800143045F832004FF480221648A240D0F82C54C2
S31508001440B3FBF1F32A43C0F82C24B380114AFFB248
S315080014504FF08073D2F80014BB400B43C2F8003437
S315080014604FF00073BB40D2F800141942FBD0BDE818
S31508001470F083DFF828E073458DD94FF00C0ED0F8CD
S315080014802C340EFA07FE73E7360000203044025863
S3150800149040420F00004002582A0000203F548900AD
S315080014A0F8B5814B0446D3F8002442F00102C3F88C
S315080014B00024D3F8102422F00702C3F81024D3F826
S315080014C0102412F0380FFAD10122C3F8002494F838
S315080014D0291094F8280000F02FFA94F8270000F055
S315080014E057FA94F8260000F0D3F994F82630002B22
S315080014F000F0C58000F0BCF963688BB16A4BD3F87D
S31508001500002442F48032C3F80024D3F8002492035E
S31508001510FBD563684FF47A72B3FBF2F3634A13841C
S31508001520237C227A1B03617843EA0213227E0B434B
S3150800153043EA02535C4AC2F82834002900F0A28024
S315080015406568002304F108012846C2F82C340122F4
S31508001550FFF7E0FE022204F110012846FFF7DAFE43
S315080015602846032204F11801FFF7D4FE23784F48D2
S31508001570002B40F08980C38994F8245000264A4FEE
S3150800158094F8201094F8212003800729C7F81864D6
S315080015904FEA0516D7F818C446EA012646EA0206AF
S315080015A046EA0C06C7F8186406D90B2994BF07390A
S315080015B0063943FA01F18BB2072A438009D90B2A67
S315080015C095BF073A911F43FA02F20B4194BF93B2B3
S315080015D09BB2032D94F82310334E8CBFEA1E1A468D
S315080015E04FF00005838084BF43FA02F292B20329C2
S315080015F0428194F82220C6F81C544FEA01258CBF74
S315080016000339194645EA0215D6F81C7488BF43FA09
S3150800161001F145EA070588BF89B2032AC6F81C54B2
S315080016208CBF033A1A46018188BF43FA02F294F83E
S31508001630251088BF92B20329C2801B4AD2F82044DB
S315080016404FF00004C2F82044D2F8204444EA0114BA
S3150800165084BF033943FA01F1C2F8204488BF8BB22C
S315080016608381D2F8103443F00303C2F81034D2F859
S3150800167010340D4AC3F3C203032B0FD1F8BD00F093
S31508001680FFF839E70A4D5CE7012B09BF6368402379
S31508001690084AB3FBF2F308BF9BB26DE7D2F81034E1
S315080016A0C3F3C203E8E700BF004002581C0000204D
S315080016B00090D00340420F0008B509282CD8DFE86F
S315080016C000F00A051C0A0D0D10131619154B18887B
S315080016D0154B584308BD134B5888F9E7114B9888A2
S315080016E0F6E7104BD888F3E70E4B1889F0E70D4B51
S315080016F05889EDE70B4B9889EAE70C4BD3F84C343D
S3150800170013F0405FC3F3017208D0022A08D1054BD3
S31508001710188C4FF47A73DCE700F0A8F80448D9E788
S315080017200020D7E71C00002040420F000040025866
S315080017300090D0034309012200F01F0003F1B043D3
S31508001740824003F5113319680A431A607047FEE7A9
S315080017507047000038B51D4A1D4B1E498B4220D3E1
S315080017601D4A0021934221D34FF0E0231B4C1C4D08
S31508001770D3F8142D42F40072C3F8142DD3F8882D2B
S3150800178042F47002C3F8882DAC4212D3154C164D9C
S31508001790AC4212D3154CFEF7AFFD154DAC4210D333
S315080017A038BD52F8040B43F8040BD7E743F8041B7B
S315080017B0D8E754F8043B9847E6E754F8043B9847BB
S315080017C0E6E754F8043B9847E8E700BF3C1B0008E7
S315080017D000000020400000206C0000203C1B000890
S315080017E03C1B00083C1B00083C1B00083C1B00086F
S315080017F03C1B000820F07F404FF0E02358617047FB
S315080018004FF0E02200F00400136923F004030343B9
S31508001810136170474FF0E022136943F00203136126
S3150800182070474FF0E022136943F0010313617047D4
S315080018304FF0E02300229A61704740F0BF604FF0F6
S31508001840E02340F40030C3F80C0D7047952804D9FE
S3150800185000F00F00044BC154704700F1604000F5DA
S3150800186064400170704700BF14ED00E0FEE7000019
S31508001870024A136843F480731360704700200052CD
S31508001880024A136823F480731360704700200052DD
S31508001890034A136823F00F0303431360704700BF1E
S315080018A000200052044AD2F80C3823F0070343F00C
S315080018B00203C2F80C38704700400258044AD2F8AE
S315080018C00C3823F0070343F00603C2F80C387047B8
S315080018D00040025808B50B0170B943F004030948E3
S315080018E05242D0F80C1802F0020221F03F010A43D6
S315080018F01A43C0F80C2808BD09B9FFF7B7FF43F02B
S315080019000C03ECE700400258044AD2F80C3823F0DE
S31508001910070343F00103C2F80C3870470040025829
S31508001920044AD2F80C3823F0070343F00503C2F83B
S315080019300C3870470040025808B5072807D8DFE872
S3150800194000F0040C0F12121D1D21FFF7B7FF0F4AF6
S31508001950D2F804389B04FBD508BDFFF7E1FFF6E78C
S31508001960FFF7A0FFF3E7A0F1040C0021DCF1000269
S3150800197042EB0C020020FFF7ADFFE8E705384242CC
S315080019804241F7E7FFF7C0FFE1E700BF0040025812
S31508001990F8B5074608B9FFF769FF204B421E204EE7
S315080019A01B68C3F30B03B3F5906F0FD1D6F818383D
S315080019B01C4923F440438A5C43EA8233C6F8183844
S315080019C0174AD2F818389B04FBD5F8BD1649B3F563
S315080019D08A6FD6F818588C5C25F440454FEA84344B
S315080019E018D141F68160FFF7A5FE012F4FF0B043ED
S315080019F00AD145F44045C6F81858D3F82C2442F0C5
S31508001A000102C3F82C24DBE7D3F82C2422F00102C8
S31508001A10C3F82C242C43C6F81848D1E70010005CFC
S31508001A2000400258361B0008321B0008032A30B44F
S31508001A3012D941EA0004A40784460B4621D1194667
S31508001A40604653F8044B5CF8045BA54219D1043A86
S31508001A50032AF4D860461946541E7AB1431E013942
S31508001A60021901E09A4209D013F8010F11F801CFC3
S31508001A706045F7D0A0EB0C0030BC7047002030BCA6
S31508001A807047541EEAE700BF830730B546D084186E
S31508001A90844604E003F8011B9D0704D09C46A44530
S31508001AA06346F7D130BD013A0244A2EB0C02032A81
S31508001AB029D9CCB204EB04240F2A04EB04442FD909
S31508001AC0A2F1100C2CF00F0C03F11005AC44C3E97D
S31508001AD00044C3E9024410336345F8D112F00C0FF1
S31508001AE002F00F0E18D02EF0030C9C44AEF104053C
S31508001AF01A4642F8044B6245FBD125F00304043329
S31508001B000EF003022344002ACCD0C9B21A4403F8C3
S31508001B10011B9342FBD130BD7246F4E70346C6E784
S31508001B209646E0E71400140014002C01C800F401DE
S31108001B300A000003020103020100000085
S31508001B3C0000000F0000000000000000000000007C
S31508001B4C0000000000000000241B000840004000B4
S31508001B5C400040004000400040000000000000002B
S31508001B6C000000000000000000000000000000005B
S7050800175586

258
2gpio-lib/bin/gpio-lib.sym Executable file
View File

@@ -0,0 +1,258 @@
08000000 T vector_table
08000298 T user_gpio_setup
080002f8 T main
08000324 t system_clock_setup
08000418 T user_delay_ms
0800044c T systick_init
0800048c T sys_tick_handler
080004a8 t prv_btn_get_state
080004e0 t prv_btn_event
0800054c t ebtn_user_get_tick
08000564 T ebtn_user_init
08000590 T ebtn_user_process
080005a4 t _windows_popcount
080005f4 t bit_array_get
08000628 t bit_array_clear
08000666 t bit_array_set
080006a2 t bit_array_assign
08000702 t bit_array_num_bits_set
0800075a t bit_array_copy_all
080007a2 t bit_array_and
080007f8 t bit_array_cmp
08000822 t ebtn_timer_sub
0800083e t prv_process_btn
08000b24 T ebtn_init
08000b88 t ebtn_get_current_state
08000c20 t ebtn_process_btn
08000c58 t ebtn_process_btn_combo
08000ce8 T ebtn_process_with_curr_state
08000e04 T ebtn_process
08000e34 T ebtn_get_total_btn_cnt
08000e7c T ebtn_get_btn_index_by_key_id
08000f04 T ebtn_get_btn_by_key_id
08000f9c T ebtn_get_btn_index_by_btn
08000fb8 T ebtn_get_btn_index_by_btn_dyn
08000fd4 T ebtn_combo_btn_add_btn_by_idx
08000ff0 T ebtn_combo_btn_remove_btn_by_idx
0800100c T ebtn_combo_btn_add_btn
0800103a T ebtn_combo_btn_remove_btn
08001068 T ebtn_is_btn_active
08001094 T ebtn_is_btn_in_process
080010c0 T ebtn_is_in_process
080011a8 T ebtn_register
08001218 T ebtn_combo_register
0800127c T gpio_set
08001280 T gpio_clear
08001286 T gpio_get
0800128c T gpio_toggle
0800129e T gpio_mode_setup
080012de T gpio_set_output_options
08001314 t rcc_configure_pll
080014a0 T rcc_clock_setup_pll
080016b8 T rcc_get_bus_clk_freq
08001734 T rcc_periph_clock_enable
0800174e W adc1_2_isr
0800174e W adc3_isr
0800174e W bdma_ch0_isr
0800174e W bdma_ch1_isr
0800174e W bdma_ch2_isr
0800174e W bdma_ch3_isr
0800174e W bdma_ch4_isr
0800174e W bdma_ch5_isr
0800174e W bdma_ch6_isr
0800174e W bdma_ch7_isr
0800174e T blocking_handler
0800174e W bus_fault_handler
0800174e W cec_isr
0800174e W cm7_sev_isr
0800174e W comp_isr
0800174e W crs_isr
0800174e W cryp_isr
0800174e W dcmi_isr
0800174e W dfsdm1_it0_isr
0800174e W dfsdm1_it1_isr
0800174e W dfsdm1_it2_isr
0800174e W dfsdm1_it3_isr
0800174e W dma1_str0_isr
0800174e W dma1_str1_isr
0800174e W dma1_str2_isr
0800174e W dma1_str3_isr
0800174e W dma1_str4_isr
0800174e W dma1_str5_isr
0800174e W dma1_str6_isr
0800174e W dma1_str7_isr
0800174e W dma2d_isr
0800174e W dma2_str0_isr
0800174e W dma2_str1_isr
0800174e W dma2_str2_isr
0800174e W dma2_str3_isr
0800174e W dma2_str4_isr
0800174e W dma2_str5_isr
0800174e W dma2_str6_isr
0800174e W dma2_str7_isr
0800174e W dmamux1_ov_isr
0800174e W dmamux2_ovr_isr
0800174e W eth_isr
0800174e W eth_wkup_isr
0800174e W exti0_isr
0800174e W exti15_10_isr
0800174e W exti1_isr
0800174e W exti2_isr
0800174e W exti3_isr
0800174e W exti4_isr
0800174e W exti9_5_isr
0800174e W fdcan1_it0_isr
0800174e W fdcan1_it1_isr
0800174e W fdcan2_it0_isr
0800174e W fdcan2_it1_isr
0800174e W fdcan_cal_isr
0800174e W flash_isr
0800174e W fpu_isr
0800174e W fsmc_isr
0800174e W hard_fault_handler
0800174e W hash_rng_isr
0800174e W hrtim1_flt_isr
0800174e W hrtim1_mst_isr
0800174e W hrtim1_tima_isr
0800174e W hrtim1_timb_isr
0800174e W hrtim1_timc_isr
0800174e W hrtim1_timd_isr
0800174e W hrtim1_time_isr
0800174e W hsem0_isr
0800174e W i2c1_er_isr
0800174e W i2c1_ev_isr
0800174e W i2c2_er_isr
0800174e W i2c2_ev_isr
0800174e W i2c3_er_isr
0800174e W i2c3_ev_isr
0800174e W i2c4_er_isr
0800174e W i2c4_ev_isr
0800174e W jpeg_isr
0800174e W lp_tim1_isr
0800174e W lptim2_isr
0800174e W lptim3_isr
0800174e W lptim4_isr
0800174e W lptim5_isr
0800174e W lpuart_isr
0800174e W ltdc_er_isr
0800174e W ltdc_isr
0800174e W mdios_isr
0800174e W mdios_wkup_isr
0800174e W mdma_isr
0800174e W mem_manage_handler
0800174e W otg_fs_ep1_in_isr
0800174e W otg_fs_ep1_out_isr
0800174e W otg_fs_isr
0800174e W otg_fs_wkup_isr
0800174e W otg_hs_ep1_in_isr
0800174e W otg_hs_ep1_out_isr
0800174e W otg_hs_isr
0800174e W otg_hs_wkup_isr
0800174e W pvd_isr
0800174e W quadspi_isr
0800174e W ramecc1_isr
0800174e W rcc_isr
0800174e W reserved1_isr
0800174e W reserved2_isr
0800174e W reserved3_isr
0800174e W reserved4_isr
0800174e W reserved5_isr
0800174e W reserved6_isr
0800174e W reserved7_isr
0800174e W reserved8_isr
0800174e W rtc_alarm_isr
0800174e W rtc_wkup_isr
0800174e W sai1_isr
0800174e W sai2_isr
0800174e W sai3_isr
0800174e W sai4_isr
0800174e W sdmmc1_isr
0800174e W sdmmc2_isr
0800174e W spdifrx_isr
0800174e W spi1_isr
0800174e W spi2_isr
0800174e W spi3_isr
0800174e W spi4_isr
0800174e W spi5_isr
0800174e W spi6_isr
0800174e W swpmi1_isr
0800174e W tamp_stamp_isr
0800174e W tim15_isr
0800174e W tim16_isr
0800174e W tim17_isr
0800174e W tim1_brk_tim9_isr
0800174e W tim1_cc_isr
0800174e W tim1_trg_com_tim11_isr
0800174e W tim1_up_tim10_isr
0800174e W tim2_isr
0800174e W tim3_isr
0800174e W tim4_isr
0800174e W tim5_isr
0800174e W tim6_dac_isr
0800174e W tim7_isr
0800174e W tim8_brk_tim12_isr
0800174e W tim8_cc_isr
0800174e W tim8_trg_com_tim14_isr
0800174e W tim8_up_tim13_isr
0800174e W uart4_isr
0800174e W uart5_isr
0800174e W uart7_isr
0800174e W uart8_isr
0800174e W usage_fault_handler
0800174e W usart1_isr
0800174e W usart2_isr
0800174e W usart3_isr
0800174e W usart6_isr
0800174e W wkup_isr
0800174e W wwdg1_rst_isr
0800174e W wwdg_isr
08001750 W debug_monitor_handler
08001750 W nmi_handler
08001750 T null_handler
08001750 W pend_sv_handler
08001750 W sv_call_handler
08001754 W reset_handler
080017f4 T systick_set_reload
08001800 T systick_set_clocksource
08001814 T systick_interrupt_enable
08001822 T systick_counter_enable
08001830 T systick_clear
0800183a T scb_set_priority_grouping
0800184c T nvic_set_priority
0800186c W cm3_assert_failed
08001870 T flash_prefetch_enable
08001880 T flash_prefetch_disable
08001890 T flash_set_ws
080018a4 T pwr_set_mode_ldo
080018bc T pwr_set_mode_scu_ldo
080018d4 T pwr_set_mode_smps_ldo
08001908 T pwr_set_mode_bypass
08001920 T pwr_set_mode_scu_bypass
08001938 T pwr_set_mode
08001990 T pwr_set_vos_scale
08001a2c T memcmp
08001a88 T memset
08001b24 t default_param
08001b32 t d3cr_vos_values.0
08001b36 t srdcr_vos_values.1
08001b3c A _data_loadaddr
08001b3c D _etext
08001b3c D __exidx_end
08001b3c D __exidx_start
08001b3c D __fini_array_end
08001b3c D __fini_array_start
08001b3c D __init_array_end
08001b3c D __init_array_start
08001b3c D __preinit_array_end
08001b3c D __preinit_array_start
20000000 d btns
20000000 D _data
2000001c d rcc_clock_tree
20000040 D _edata
20000040 B systick
20000044 b ebtn_default
2000006c B _ebss
20020000 B _stack
24000000 B _sheap
24080000 B _eheap
24080000 B end

15
2gpio-lib/cmsis-dap.cfg Normal file
View File

@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# ARM CMSIS-DAP compliant adapter
#
# http://www.keil.com/support/man/docs/dapdebug/
#
adapter driver cmsis-dap
transport select swd
reset_config none
# Optionally specify the serial number of CMSIS-DAP usb device.
# adapter serial 02200201E6661E601B98E3B9

View File

@@ -0,0 +1,26 @@
[
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/gpio-lib/linux/arm32/release/user/src/gpio.c.o", "user/src/gpio.c"],
"file": "user/src/gpio.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/gpio-lib/linux/arm32/release/user/src/main.c.o", "user/src/main.c"],
"file": "user/src/main.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/gpio-lib/linux/arm32/release/user/src/systick.c.o", "user/src/systick.c"],
"file": "user/src/systick.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/lib-ebtn/linux/arm32/release/lib/ebtn/ebtn_cb.c.o", "lib/ebtn/ebtn_cb.c"],
"file": "lib/ebtn/ebtn_cb.c"
},
{
"directory": "/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib",
"arguments": ["/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc", "-c", "-g", "-O0", "-I../../libopencm3/include", "-Iuser/inc", "-Ilib/ebtn", "-DSTM32H7", "-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", "-o", "build/.objs/lib-ebtn/linux/arm32/release/lib/ebtn/ebtn.c.o", "lib/ebtn/ebtn.c"],
"file": "lib/ebtn/ebtn.c"
}]

View File

@@ -0,0 +1,117 @@
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x200000 /* Flash 2MB */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 /* 128 KB */
ram2 (rwx) : ORIGIN = 0x24000000, LENGTH = 0x80000 /* 512 KB */
}
/* Enforce emmition of the vector table. */
EXTERN (vector_table)
/* Define the entry point of the output file. */
ENTRY(reset_handler)
/* Define sections. */
SECTIONS
{
.text : {
*(.vectors) /* Vector table */
*(.text*) /* Program code */
. = ALIGN(4);
*(.rodata*) /* Read-only data */
. = ALIGN(4);
} >rom
/* C++ Static constructors/destructors, also used for __attribute__
* ((constructor)) and the likes */
.preinit_array : {
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
} >rom
.init_array : {
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} >rom
.fini_array : {
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} >rom
/*
* Another section used by C++ stuff, appears when using newlib with
* 64bit (long long) printf support
*/
.ARM.extab : {
*(.ARM.extab*)
} >rom
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >rom
. = ALIGN(4);
_etext = .;
/* ram, but not cleared on reset, eg boot/app comms */
.noinit (NOLOAD) : {
*(.noinit*)
} >ram
. = ALIGN(4);
.data : {
_data = .;
*(.data*) /* Read-write initialized data */
*(.ramtext*) /* "text" functions to run in ram */
. = ALIGN(4);
_edata = .;
} >ram AT >rom
_data_loadaddr = LOADADDR(.data);
.bss : {
*(.bss*) /* Read-write zero initialized data */
*(COMMON)
. = ALIGN(4);
_ebss = .;
} >ram
/*
* The .eh_frame section appears to be used for C++ exception handling.
* You may need to fix this if you're using C++.
*/
/DISCARD/ : { *(.eh_frame) }
/* Heap 分配到第二块 RAM */
.heap : {
_sheap = .;
. = ORIGIN(ram2) + LENGTH(ram2);
_eheap = .;
} >ram2
/* 第二块 RAM,用于大数组或 heap */
/*
.ext_ram (NOLOAD) : {
_sext_ram = .;
*(.ext_ram*)
*(.bss_ext_ram*)
. = ALIGN(4);
_eext_ram = .;
} > ram2
*/
. = ALIGN(4);
end = .;
}
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
PROVIDE(_sheap = ORIGIN(ram2));
PROVIDE(_eheap = ORIGIN(ram2) + LENGTH(ram2));

View File

@@ -0,0 +1,597 @@
#ifndef _BIT_ARRAY_H_
#define _BIT_ARRAY_H_
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// #define BIT_ARRAY_CONFIG_64
// here can change to uint64_t, if you system is 64bit.
#ifdef BIT_ARRAY_CONFIG_64
typedef uint64_t bit_array_t;
#define BIT_ARRAY_BIT(n) (1ULL << (n))
#else
typedef uint32_t bit_array_t;
#define BIT_ARRAY_BIT(n) (1UL << (n))
#endif
typedef bit_array_t bit_array_val_t;
#define BIT_ARRAY_BITS (sizeof(bit_array_val_t) * 8)
#define BIT_ARRAY_BIT_WORD(bit) ((bit) / BIT_ARRAY_BITS)
#define BIT_ARRAY_BIT_INDEX(bit) ((bit_array_val_t)(bit) & (BIT_ARRAY_BITS - 1U))
#define BIT_ARRAY_MASK(bit) BIT_ARRAY_BIT(BIT_ARRAY_BIT_INDEX(bit))
#define BIT_ARRAY_ELEM(addr, bit) ((addr)[BIT_ARRAY_BIT_WORD(bit)])
// word of all 1s
#define BIT_ARRAY_WORD_MAX (~(bit_array_val_t)0)
#define BIT_ARRAY_SUB_MASK(nbits) ((nbits) ? BIT_ARRAY_WORD_MAX >> (BIT_ARRAY_BITS - (nbits)) : (bit_array_val_t)0)
// A possibly faster way to combine two words with a mask
// #define bitmask_merge(a,b,abits) ((a & abits) | (b & ~abits))
#define bitmask_merge(a, b, abits) (b ^ ((a ^ b) & abits))
/**
* @brief This macro computes the number of bit array variables necessary to
* represent a bitmap with @a num_bits.
*
* @param num_bits Number of bits.
*/
#define BIT_ARRAY_BITMAP_SIZE(num_bits) (1 + ((num_bits)-1) / BIT_ARRAY_BITS)
/**
* @brief Define an array of bit array variables.
*
* This macro defines an array of bit array variables containing at least
* @a num_bits bits.
*
* @note
* If used from file scope, the bits of the array are initialized to zero;
* if used from within a function, the bits are left uninitialized.
*
* @cond INTERNAL_HIDDEN
* @note
* This macro should be replicated in the PREDEFINED field of the documentation
* Doxyfile.
* @endcond
*
* @param name Name of array of bit array variables.
* @param num_bits Number of bits needed.
*/
#define BIT_ARRAY_DEFINE(name, num_bits) bit_array_t name[BIT_ARRAY_BITMAP_SIZE(num_bits)]
#if 1
// See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
static inline bit_array_val_t _windows_popcount(bit_array_val_t w)
{
w = w - ((w >> 1) & (bit_array_val_t) ~(bit_array_val_t)0 / 3);
w = (w & (bit_array_val_t) ~(bit_array_val_t)0 / 15 * 3) + ((w >> 2) & (bit_array_val_t) ~(bit_array_val_t)0 / 15 * 3);
w = (w + (w >> 4)) & (bit_array_val_t) ~(bit_array_val_t)0 / 255 * 15;
return (bit_array_val_t)(w * ((bit_array_val_t) ~(bit_array_val_t)0 / 255)) >> (sizeof(bit_array_val_t) - 1) * 8;
}
#define POPCOUNT(x) _windows_popcount(x)
#else
#define POPCOUNT(x) (unsigned)__builtin_popcountll(x)
#endif
#define bits_in_top_word(nbits) ((nbits) ? BIT_ARRAY_BIT_INDEX((nbits)-1) + 1 : 0)
static inline void _bit_array_mask_top_word(bit_array_t *target, int num_bits)
{
// Mask top word
int num_of_words = BIT_ARRAY_BITMAP_SIZE(num_bits);
int bits_active = bits_in_top_word(num_bits);
target[num_of_words - 1] &= BIT_ARRAY_SUB_MASK(bits_active);
}
/**
* @brief Bit Array test a bit.
*
* This routine tests whether bit number @a bit of @a target is set or not.
*
* @param target Address of bit array variable or array.
* @param bit Bit number (starting from 0).
*
* @return true if the bit was set, false if it wasn't.
*/
static inline int bit_array_get(const bit_array_t *target, int bit)
{
bit_array_val_t val = BIT_ARRAY_ELEM(target, bit);
return (1 & (val >> (bit & (BIT_ARRAY_BITS - 1)))) != 0;
}
/**
* @brief Bit Array clear a bit.
*
* Bit Array clear bit number @a bit of @a target.
*
* @param target Address of bit array variable or array.
* @param bit Bit number (starting from 0).
*/
static inline void bit_array_clear(bit_array_t *target, int bit)
{
bit_array_val_t mask = BIT_ARRAY_MASK(bit);
BIT_ARRAY_ELEM(target, bit) &= ~mask;
}
/**
* @brief Bit Array set a bit.
*
* Bit Array set bit number @a bit of @a target.
*
* @param target Address of bit array variable or array.
* @param bit Bit number (starting from 0).
*/
static inline void bit_array_set(bit_array_t *target, int bit)
{
bit_array_val_t mask = BIT_ARRAY_MASK(bit);
BIT_ARRAY_ELEM(target, bit) |= mask;
}
/**
* @brief Bit Array toggle a bit.
*
* Bit Array toggle bit number @a bit of @a target.
*
* @param target Address of bit array variable or array.
* @param bit Bit number (starting from 0).
*/
static inline void bit_array_toggle(bit_array_t *target, int bit)
{
bit_array_val_t mask = BIT_ARRAY_MASK(bit);
BIT_ARRAY_ELEM(target, bit) ^= mask;
}
/**
* @brief Bit Array set a bit to a given value.
*
* Bit Array set bit number @a bit of @a target to value @a val.
*
* @param target Address of bit array variable or array.
* @param bit Bit number (starting from 0).
* @param val true for 1, false for 0.
*/
static inline void bit_array_assign(bit_array_t *target, int bit, int val)
{
bit_array_val_t mask = BIT_ARRAY_MASK(bit);
if (val)
{
BIT_ARRAY_ELEM(target, bit) |= mask;
}
else
{
BIT_ARRAY_ELEM(target, bit) &= ~mask;
}
}
static inline void bit_array_clear_all(bit_array_t *target, int num_bits)
{
memset((void *)target, 0, BIT_ARRAY_BITMAP_SIZE(num_bits) * sizeof(bit_array_val_t));
}
static inline void bit_array_set_all(bit_array_t *target, int num_bits)
{
memset((void *)target, 0xff, BIT_ARRAY_BITMAP_SIZE(num_bits) * sizeof(bit_array_val_t));
_bit_array_mask_top_word(target, num_bits);
}
static inline void bit_array_toggle_all(bit_array_t *target, int num_bits)
{
for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++)
{
target[i] ^= BIT_ARRAY_WORD_MAX;
}
_bit_array_mask_top_word(target, num_bits);
}
//
// Strings and printing
//
// Construct a BIT_ARRAY from a substring with given on and off characters.
// From string method
static inline void bit_array_from_str(bit_array_t *bitarr, const char *str)
{
int i, index;
int space = 0;
int len = strlen(str);
for (i = 0; i < len; i++)
{
index = i - space;
if (strchr("1", str[i]) != NULL)
{
bit_array_set(bitarr, index);
}
else if (strchr("0", str[i]) != NULL)
{
bit_array_clear(bitarr, index);
}
else
{
// error.
space++;
}
}
}
// Takes a char array to write to. `str` must be bitarr->num_of_bits+1 in length
// Terminates string with '\0'
static inline char *bit_array_to_str(const bit_array_t *bitarr, int num_bits, char *str)
{
int i;
for (i = 0; i < num_bits; i++)
{
str[i] = bit_array_get(bitarr, i) ? '1' : '0';
}
str[num_bits] = '\0';
return str;
}
// Takes a char array to write to. `str` must be bitarr->num_of_bits+1 in length
// Terminates string with '\0'
static inline char *bit_array_to_str_8(const bit_array_t *bitarr, int num_bits, char *str)
{
int i;
int space = 0;
for (i = 0; i < num_bits; i++)
{
str[i + space] = bit_array_get(bitarr, i) ? '1' : '0';
if ((i + 1) % 8 == 0)
{
space++;
str[i + space] = ' ';
}
}
str[num_bits + space] = '\0';
return str;
}
//
// Get and set words (internal use only -- no bounds checking)
//
static inline bit_array_val_t _bit_array_get_word(const bit_array_t *target, int num_bits, int start)
{
int word_index = BIT_ARRAY_BIT_WORD(start);
int word_offset = BIT_ARRAY_BIT_INDEX(start);
bit_array_val_t result = target[word_index] >> word_offset;
int bits_taken = BIT_ARRAY_BITS - word_offset;
// word_offset is now the number of bits we need from the next word
// Check the next word has at least some bits
if (word_offset > 0 && start + bits_taken < num_bits)
{
result |= target[word_index + 1] << (BIT_ARRAY_BITS - word_offset);
}
return result;
}
// Set 64 bits from a particular start position
// Doesn't extend bit array
static inline void _bit_array_set_word(bit_array_t *target, int num_bits, int start, bit_array_val_t word)
{
int word_index = BIT_ARRAY_BIT_WORD(start);
int word_offset = BIT_ARRAY_BIT_INDEX(start);
if (word_offset == 0)
{
target[word_index] = word;
}
else
{
target[word_index] = (word << word_offset) | (target[word_index] & BIT_ARRAY_SUB_MASK(word_offset));
if (word_index + 1 < BIT_ARRAY_BITMAP_SIZE(num_bits))
{
target[word_index + 1] = (word >> (BIT_ARRAY_BITS - word_offset)) | (target[word_index + 1] & (BIT_ARRAY_WORD_MAX << word_offset));
}
}
// Mask top word
_bit_array_mask_top_word(target, num_bits);
}
//
// Fill a region (internal use only)
//
// FillAction is fill with 0 or 1 or toggle
typedef enum
{
ZERO_REGION,
FILL_REGION,
SWAP_REGION
} FillAction;
static inline void _bit_array_set_region(bit_array_t *target, int start, int length, FillAction action)
{
if (length == 0)
return;
int first_word = BIT_ARRAY_BIT_WORD(start);
int last_word = BIT_ARRAY_BIT_WORD(start + length - 1);
int foffset = BIT_ARRAY_BIT_INDEX(start);
int loffset = BIT_ARRAY_BIT_INDEX(start + length - 1);
if (first_word == last_word)
{
bit_array_val_t mask = BIT_ARRAY_SUB_MASK(length) << foffset;
switch (action)
{
case ZERO_REGION:
target[first_word] &= ~mask;
break;
case FILL_REGION:
target[first_word] |= mask;
break;
case SWAP_REGION:
target[first_word] ^= mask;
break;
}
}
else
{
// Set first word
switch (action)
{
case ZERO_REGION:
target[first_word] &= BIT_ARRAY_SUB_MASK(foffset);
break;
case FILL_REGION:
target[first_word] |= ~BIT_ARRAY_SUB_MASK(foffset);
break;
case SWAP_REGION:
target[first_word] ^= ~BIT_ARRAY_SUB_MASK(foffset);
break;
}
int i;
// Set whole words
switch (action)
{
case ZERO_REGION:
for (i = first_word + 1; i < last_word; i++)
target[i] = (bit_array_val_t)0;
break;
case FILL_REGION:
for (i = first_word + 1; i < last_word; i++)
target[i] = BIT_ARRAY_WORD_MAX;
break;
case SWAP_REGION:
for (i = first_word + 1; i < last_word; i++)
target[i] ^= BIT_ARRAY_WORD_MAX;
break;
}
// Set last word
switch (action)
{
case ZERO_REGION:
target[last_word] &= ~BIT_ARRAY_SUB_MASK(loffset + 1);
break;
case FILL_REGION:
target[last_word] |= BIT_ARRAY_SUB_MASK(loffset + 1);
break;
case SWAP_REGION:
target[last_word] ^= BIT_ARRAY_SUB_MASK(loffset + 1);
break;
}
}
}
// Get the number of bits set (hamming weight)
static inline int bit_array_num_bits_set(bit_array_t *target, int num_bits)
{
int i;
int num_of_bits_set = 0;
for (i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++)
{
if (target[i] > 0)
{
num_of_bits_set += POPCOUNT(target[i]);
}
}
return num_of_bits_set;
}
// Get the number of bits not set (1 - hamming weight)
static inline int bit_array_num_bits_cleared(bit_array_t *target, int num_bits)
{
return num_bits - bit_array_num_bits_set(target, num_bits);
}
// Copy bits from one array to another
// Note: use MACRO bit_array_copy
// Destination and source can be the same bit_array and
// src/dst regions can overlap
static inline void bit_array_copy(bit_array_t *dst, int dstindx, const bit_array_t *src, int srcindx, int length, int src_num_bits, int dst_num_bits)
{
// Num of full words to copy
int num_of_full_words = length / BIT_ARRAY_BITS;
int i;
int bits_in_last_word = bits_in_top_word(length);
if (dst == src && srcindx > dstindx)
{
// Work left to right
for (i = 0; i < num_of_full_words; i++)
{
bit_array_val_t word = _bit_array_get_word(src, src_num_bits, srcindx + i * BIT_ARRAY_BITS);
_bit_array_set_word(dst, dst_num_bits, dstindx + i * BIT_ARRAY_BITS, word);
}
if (bits_in_last_word > 0)
{
bit_array_val_t src_word = _bit_array_get_word(src, src_num_bits, srcindx + i * BIT_ARRAY_BITS);
bit_array_val_t dst_word = _bit_array_get_word(dst, dst_num_bits, dstindx + i * BIT_ARRAY_BITS);
bit_array_val_t mask = BIT_ARRAY_SUB_MASK(bits_in_last_word);
bit_array_val_t word = bitmask_merge(src_word, dst_word, mask);
_bit_array_set_word(dst, dst_num_bits, dstindx + num_of_full_words * BIT_ARRAY_BITS, word);
}
}
else
{
// Work right to left
for (i = 0; i < num_of_full_words; i++)
{
bit_array_val_t word = _bit_array_get_word(src, src_num_bits, srcindx + length - (i + 1) * BIT_ARRAY_BITS);
_bit_array_set_word(dst, dst_num_bits, dstindx + length - (i + 1) * BIT_ARRAY_BITS, word);
}
if (bits_in_last_word > 0)
{
bit_array_val_t src_word = _bit_array_get_word(src, src_num_bits, srcindx);
bit_array_val_t dst_word = _bit_array_get_word(dst, dst_num_bits, dstindx);
bit_array_val_t mask = BIT_ARRAY_SUB_MASK(bits_in_last_word);
bit_array_val_t word = bitmask_merge(src_word, dst_word, mask);
_bit_array_set_word(dst, dst_num_bits, dstindx, word);
}
}
_bit_array_mask_top_word(dst, dst_num_bits);
}
// copy all of src to dst. dst is resized to match src.
static inline void bit_array_copy_all(bit_array_t *dst, const bit_array_t *src, int num_bits)
{
for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++)
{
dst[i] = src[i];
}
}
//
// Logic operators
//
// Destination can be the same as one or both of the sources
static inline void bit_array_and(bit_array_t *dest, const bit_array_t *src1, const bit_array_t *src2, int num_bits)
{
for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++)
{
dest[i] = src1[i] & src2[i];
}
}
static inline void bit_array_or(bit_array_t *dest, const bit_array_t *src1, const bit_array_t *src2, int num_bits)
{
for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++)
{
dest[i] = src1[i] | src2[i];
}
}
static inline void bit_array_xor(bit_array_t *dest, const bit_array_t *src1, const bit_array_t *src2, int num_bits)
{
for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++)
{
dest[i] = src1[i] ^ src2[i];
}
}
static inline void bit_array_not(bit_array_t *dest, const bit_array_t *src, int num_bits)
{
for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++)
{
dest[i] = ~src[i];
}
}
//
// Shift array left/right. If fill is zero, filled with 0, otherwise 1
//
// Shift towards LSB / lower index
static inline void bit_array_shift_right(bit_array_t *target, int num_bits, int shift_dist, int fill)
{
if (shift_dist >= num_bits)
{
fill ? bit_array_set_all(target, num_bits) : bit_array_clear_all(target, num_bits);
return;
}
else if (shift_dist == 0)
{
return;
}
FillAction action = fill ? FILL_REGION : ZERO_REGION;
int cpy_length = num_bits - shift_dist;
bit_array_copy(target, 0, target, shift_dist, cpy_length, num_bits, num_bits);
_bit_array_set_region(target, cpy_length, shift_dist, action);
}
// Shift towards MSB / higher index
static inline void bit_array_shift_left(bit_array_t *target, int num_bits, int shift_dist, int fill)
{
if (shift_dist >= num_bits)
{
fill ? bit_array_set_all(target, num_bits) : bit_array_clear_all(target, num_bits);
return;
}
else if (shift_dist == 0)
{
return;
}
FillAction action = fill ? FILL_REGION : ZERO_REGION;
int cpy_length = num_bits - shift_dist;
bit_array_copy(target, shift_dist, target, 0, cpy_length, num_bits, num_bits);
_bit_array_set_region(target, 0, shift_dist, action);
}
//
// Comparisons
//
// Compare two bit arrays by value stored, with index 0 being the Least
// Significant Bit (LSB). Arrays must have the same length.
// returns:
// >0 iff bitarr1 > bitarr2
// 0 iff bitarr1 == bitarr2
// <0 iff bitarr1 < bitarr2
static inline int bit_array_cmp(const bit_array_t *bitarr1, const bit_array_t *bitarr2, int num_bits)
{
return memcmp(bitarr1, bitarr2, BIT_ARRAY_BITMAP_SIZE(num_bits) * sizeof(bit_array_val_t));
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _BIT_ARRAY_H_ */

574
2gpio-lib/lib/ebtn/ebtn.c Normal file
View File

@@ -0,0 +1,574 @@
#include <string.h>
#include "ebtn.h"
#define EBTN_FLAG_ONPRESS_SENT ((uint8_t)0x01) /*!< Flag indicates that on-press event has been sent */
#define EBTN_FLAG_IN_PROCESS ((uint8_t)0x02) /*!< Flag indicates that button in process */
/* Default button group instance */
static ebtn_t ebtn_default;
/**
* \brief Process the button information and state
*
* \param[in] btn: Button instance to process
* \param[in] old_state: old state
* \param[in] new_state: new state
* \param[in] mstime: Current milliseconds system time
*/
static void prv_process_btn(ebtn_btn_t *btn, uint8_t old_state, uint8_t new_state, ebtn_time_t mstime)
{
ebtn_t *ebtobj = &ebtn_default;
/* Check params set or not. */
if (btn->param == NULL)
{
return;
}
/* Button state has just changed */
if (new_state != old_state)
{
btn->time_state_change = mstime;
if (new_state)
{
btn->flags |= EBTN_FLAG_IN_PROCESS;
}
}
/* Button is still pressed */
if (new_state)
{
/*
* Handle debounce and send on-press event
*
* This is when we detect valid press
*/
if (!(btn->flags & EBTN_FLAG_ONPRESS_SENT))
{
/*
* Run if statement when:
*
* - Runtime mode is enabled -> user sets its own config for debounce
* - Config debounce time for press is more than `0`
*/
if (ebtn_timer_sub(mstime, btn->time_state_change) >= btn->param->time_debounce)
{
/*
* Check mutlti click limit reach or not.
*/
if ((btn->click_cnt > 0) && (ebtn_timer_sub(mstime, btn->click_last_time) >= btn->param->time_click_multi_max))
{
if (btn->event_mask & EBTN_EVT_MASK_ONCLICK)
{
ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK);
}
btn->click_cnt = 0;
}
/* Set keep alive time */
btn->keepalive_last_time = mstime;
btn->keepalive_cnt = 0;
/* Start with new on-press */
btn->flags |= EBTN_FLAG_ONPRESS_SENT;
if (btn->event_mask & EBTN_EVT_MASK_ONPRESS)
{
ebtobj->evt_fn(btn, EBTN_EVT_ONPRESS);
}
btn->time_change = mstime; /* Button state has now changed */
}
}
/*
* Handle keep alive, but only if on-press event has been sent
*
* Keep alive is sent when valid press is being detected
*/
else
{
while ((btn->param->time_keepalive_period > 0) && (ebtn_timer_sub(mstime, btn->keepalive_last_time) >= btn->param->time_keepalive_period))
{
btn->keepalive_last_time += btn->param->time_keepalive_period;
++btn->keepalive_cnt;
if (btn->event_mask & EBTN_EVT_MASK_KEEPALIVE)
{
ebtobj->evt_fn(btn, EBTN_EVT_KEEPALIVE);
}
}
// Scene1: multi click end with a long press, need send onclick event.
if ((btn->click_cnt > 0) && (ebtn_timer_sub(mstime, btn->time_change) > btn->param->time_click_pressed_max))
{
if (btn->event_mask & EBTN_EVT_MASK_ONCLICK)
{
ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK);
}
btn->click_cnt = 0;
}
}
}
/* Button is still released */
else
{
/*
* We only need to react if on-press event has even been started.
*
* Do nothing if that was not the case
*/
if (btn->flags & EBTN_FLAG_ONPRESS_SENT)
{
/*
* Run if statement when:
*
* - Runtime mode is enabled -> user sets its own config for debounce
* - Config debounce time for release is more than `0`
*/
if (ebtn_timer_sub(mstime, btn->time_state_change) >= btn->param->time_debounce_release)
{
/* Handle on-release event */
btn->flags &= ~EBTN_FLAG_ONPRESS_SENT;
if (btn->event_mask & EBTN_EVT_MASK_ONRELEASE)
{
ebtobj->evt_fn(btn, EBTN_EVT_ONRELEASE);
}
/* Check time validity for click event */
if (ebtn_timer_sub(mstime, btn->time_change) >= btn->param->time_click_pressed_min &&
ebtn_timer_sub(mstime, btn->time_change) <= btn->param->time_click_pressed_max)
{
++btn->click_cnt;
btn->click_last_time = mstime;
}
else
{
// Scene2: If last press was too short, and previous sequence of clicks was
// positive, send event to user.
if ((btn->click_cnt > 0) && (ebtn_timer_sub(mstime, btn->time_change) < btn->param->time_click_pressed_min))
{
if (btn->event_mask & EBTN_EVT_MASK_ONCLICK)
{
ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK);
}
}
/*
* There was an on-release event, but timing
* for click event detection is outside allowed window.
*
* Reset clicks counter -> not valid sequence for click event.
*/
btn->click_cnt = 0;
}
// Scene3: this part will send on-click event immediately after release event, if
// maximum number of consecutive clicks has been reached.
if ((btn->click_cnt > 0) && (btn->click_cnt == btn->param->max_consecutive))
{
if (btn->event_mask & EBTN_EVT_MASK_ONCLICK)
{
ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK);
}
btn->click_cnt = 0;
}
btn->time_change = mstime; /* Button state has now changed */
}
}
else
{
/*
* Based on te configuration, this part of the code
* will send on-click event after certain timeout.
*
* This feature is useful if users prefers multi-click feature
* that is reported only after last click event happened,
* including number of clicks made by user
*/
if (btn->click_cnt > 0)
{
if (ebtn_timer_sub(mstime, btn->click_last_time) >= btn->param->time_click_multi_max)
{
if (btn->event_mask & EBTN_EVT_MASK_ONCLICK)
{
ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK);
}
btn->click_cnt = 0;
}
}
else
{
// check button in process
if (btn->flags & EBTN_FLAG_IN_PROCESS)
{
btn->flags &= ~EBTN_FLAG_IN_PROCESS;
}
}
}
}
}
int ebtn_init(ebtn_btn_t *btns, uint16_t btns_cnt, ebtn_btn_combo_t *btns_combo, uint16_t btns_combo_cnt, ebtn_get_state_fn get_state_fn, ebtn_evt_fn evt_fn)
{
ebtn_t *ebtobj = &ebtn_default;
if (evt_fn == NULL || get_state_fn == NULL /* Parameter is a must only in callback-only mode */
)
{
return 0;
}
memset(ebtobj, 0x00, sizeof(*ebtobj));
ebtobj->btns = btns;
ebtobj->btns_cnt = btns_cnt;
ebtobj->btns_combo = btns_combo;
ebtobj->btns_combo_cnt = btns_combo_cnt;
ebtobj->evt_fn = evt_fn;
ebtobj->get_state_fn = get_state_fn;
return 1;
}
/**
* \brief Get all button state with get_state_fn.
*
* \param[out] state_array: store the button state
*/
static void ebtn_get_current_state(bit_array_t *state_array)
{
ebtn_t *ebtobj = &ebtn_default;
ebtn_btn_dyn_t *target;
int i;
/* Process all buttons */
for (i = 0; i < ebtobj->btns_cnt; ++i)
{
/* Get button state */
uint8_t new_state = ebtobj->get_state_fn(&ebtobj->btns[i]);
// save state
bit_array_assign(state_array, i, new_state);
}
for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++)
{
/* Get button state */
uint8_t new_state = ebtobj->get_state_fn(&target->btn);
// save state
bit_array_assign(state_array, i, new_state);
}
}
/**
* \brief Process the button state
*
* \param[in] btn: Button instance to process
* \param[in] old_state: all button old state
* \param[in] curr_state: all button current state
* \param[in] idx: Button internal key_idx
* \param[in] mstime: Current milliseconds system time
*/
static void ebtn_process_btn(ebtn_btn_t *btn, bit_array_t *old_state, bit_array_t *curr_state, int idx, ebtn_time_t mstime)
{
prv_process_btn(btn, bit_array_get(old_state, idx), bit_array_get(curr_state, idx), mstime);
}
/**
* \brief Process the combo-button state
*
* \param[in] btn: Button instance to process
* \param[in] old_state: all button old state
* \param[in] curr_state: all button current state
* \param[in] comb_key: Combo key
* \param[in] mstime: Current milliseconds system time
*/
static void ebtn_process_btn_combo(ebtn_btn_t *btn, bit_array_t *old_state, bit_array_t *curr_state, bit_array_t *comb_key, ebtn_time_t mstime)
{
BIT_ARRAY_DEFINE(tmp_data, EBTN_MAX_KEYNUM) = {0};
if (bit_array_num_bits_set(comb_key, EBTN_MAX_KEYNUM) == 0)
{
return;
}
bit_array_and(tmp_data, curr_state, comb_key, EBTN_MAX_KEYNUM);
uint8_t curr = bit_array_cmp(tmp_data, comb_key, EBTN_MAX_KEYNUM) == 0;
bit_array_and(tmp_data, old_state, comb_key, EBTN_MAX_KEYNUM);
uint8_t old = bit_array_cmp(tmp_data, comb_key, EBTN_MAX_KEYNUM) == 0;
prv_process_btn(btn, old, curr, mstime);
}
void ebtn_process_with_curr_state(bit_array_t *curr_state, ebtn_time_t mstime)
{
ebtn_t *ebtobj = &ebtn_default;
ebtn_btn_dyn_t *target;
ebtn_btn_combo_dyn_t *target_combo;
int i;
/* Process all buttons */
for (i = 0; i < ebtobj->btns_cnt; ++i)
{
ebtn_process_btn(&ebtobj->btns[i], ebtobj->old_state, curr_state, i, mstime);
}
for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++)
{
ebtn_process_btn(&target->btn, ebtobj->old_state, curr_state, i, mstime);
}
/* Process all comb buttons */
for (i = 0; i < ebtobj->btns_combo_cnt; ++i)
{
ebtn_process_btn_combo(&ebtobj->btns_combo[i].btn, ebtobj->old_state, curr_state, ebtobj->btns_combo[i].comb_key, mstime);
}
for (target_combo = ebtobj->btn_combo_dyn_head; target_combo; target_combo = target_combo->next)
{
ebtn_process_btn_combo(&target_combo->btn.btn, ebtobj->old_state, curr_state, target_combo->btn.comb_key, mstime);
}
bit_array_copy_all(ebtobj->old_state, curr_state, EBTN_MAX_KEYNUM);
}
void ebtn_process(ebtn_time_t mstime)
{
BIT_ARRAY_DEFINE(curr_state, EBTN_MAX_KEYNUM) = {0};
// Get Current State
ebtn_get_current_state(curr_state);
ebtn_process_with_curr_state(curr_state, mstime);
}
int ebtn_get_total_btn_cnt(void)
{
ebtn_t *ebtobj = &ebtn_default;
int total_cnt = 0;
ebtn_btn_dyn_t *curr = ebtobj->btn_dyn_head;
total_cnt += ebtobj->btns_cnt;
while (curr)
{
total_cnt++;
curr = curr->next;
}
return total_cnt;
}
int ebtn_get_btn_index_by_key_id(uint16_t key_id)
{
ebtn_t *ebtobj = &ebtn_default;
int i = 0;
ebtn_btn_dyn_t *target;
for (i = 0; i < ebtobj->btns_cnt; ++i)
{
if (ebtobj->btns[i].key_id == key_id)
{
return i;
}
}
for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++)
{
if (target->btn.key_id == key_id)
{
return i;
}
}
return -1;
}
ebtn_btn_t *ebtn_get_btn_by_key_id(uint16_t key_id)
{
ebtn_t *ebtobj = &ebtn_default;
int i = 0;
ebtn_btn_dyn_t *target;
for (i = 0; i < ebtobj->btns_cnt; ++i)
{
if (ebtobj->btns[i].key_id == key_id)
{
return &ebtobj->btns[i];
}
}
for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++)
{
if (target->btn.key_id == key_id)
{
return &target->btn;
}
}
return NULL;
}
int ebtn_get_btn_index_by_btn(ebtn_btn_t *btn)
{
return ebtn_get_btn_index_by_key_id(btn->key_id);
}
int ebtn_get_btn_index_by_btn_dyn(ebtn_btn_dyn_t *btn)
{
return ebtn_get_btn_index_by_key_id(btn->btn.key_id);
}
void ebtn_combo_btn_add_btn_by_idx(ebtn_btn_combo_t *btn, int idx)
{
bit_array_set(btn->comb_key, idx);
}
void ebtn_combo_btn_remove_btn_by_idx(ebtn_btn_combo_t *btn, int idx)
{
bit_array_clear(btn->comb_key, idx);
}
void ebtn_combo_btn_add_btn(ebtn_btn_combo_t *btn, uint16_t key_id)
{
int idx = ebtn_get_btn_index_by_key_id(key_id);
if (idx < 0)
{
return;
}
ebtn_combo_btn_add_btn_by_idx(btn, idx);
}
void ebtn_combo_btn_remove_btn(ebtn_btn_combo_t *btn, uint16_t key_id)
{
int idx = ebtn_get_btn_index_by_key_id(key_id);
if (idx < 0)
{
return;
}
ebtn_combo_btn_remove_btn_by_idx(btn, idx);
}
int ebtn_is_btn_active(const ebtn_btn_t *btn)
{
return btn != NULL && (btn->flags & EBTN_FLAG_ONPRESS_SENT);
}
int ebtn_is_btn_in_process(const ebtn_btn_t *btn)
{
return btn != NULL && (btn->flags & EBTN_FLAG_IN_PROCESS);
}
int ebtn_is_in_process(void)
{
ebtn_t *ebtobj = &ebtn_default;
ebtn_btn_dyn_t *target;
ebtn_btn_combo_dyn_t *target_combo;
int i;
/* Process all buttons */
for (i = 0; i < ebtobj->btns_cnt; ++i)
{
if (ebtn_is_btn_in_process(&ebtobj->btns[i]))
{
return 1;
}
}
for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++)
{
if (ebtn_is_btn_in_process(&target->btn))
{
return 1;
}
}
/* Process all comb buttons */
for (i = 0; i < ebtobj->btns_combo_cnt; ++i)
{
if (ebtn_is_btn_in_process(&ebtobj->btns_combo[i].btn))
{
return 1;
}
}
for (target_combo = ebtobj->btn_combo_dyn_head; target_combo; target_combo = target_combo->next)
{
if (ebtn_is_btn_in_process(&target_combo->btn.btn))
{
return 1;
}
}
return 0;
}
int ebtn_register(ebtn_btn_dyn_t *button)
{
ebtn_t *ebtobj = &ebtn_default;
ebtn_btn_dyn_t *curr = ebtobj->btn_dyn_head;
ebtn_btn_dyn_t *last = NULL;
if (!button)
{
return 0;
}
if (ebtn_get_total_btn_cnt() >= EBTN_MAX_KEYNUM)
{
return 0; /* reach max cnt. */
}
if (curr == NULL)
{
ebtobj->btn_dyn_head = button;
return 1;
}
while (curr)
{
if (curr == button)
{
return 0; /* already exist. */
}
last = curr;
curr = curr->next;
}
last->next = button;
return 1;
}
int ebtn_combo_register(ebtn_btn_combo_dyn_t *button)
{
ebtn_t *ebtobj = &ebtn_default;
ebtn_btn_combo_dyn_t *curr = ebtobj->btn_combo_dyn_head;
ebtn_btn_combo_dyn_t *last = NULL;
if (!button)
{
return 0;
}
if (curr == NULL)
{
ebtobj->btn_combo_dyn_head = button;
return 1;
}
while (curr)
{
if (curr == button)
{
return 0; /* already exist. */
}
last = curr;
curr = curr->next;
}
last->next = button;
return 1;
}

479
2gpio-lib/lib/ebtn/ebtn.h Normal file
View File

@@ -0,0 +1,479 @@
#ifndef _EBTN_H
#define _EBTN_H
#include <stdint.h>
#include <string.h>
#include "bit_array.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// #define EBTN_CONFIG_TIMER_16
// here can change to uint16_t, if you want reduce RAM size.
#ifdef EBTN_CONFIG_TIMER_16
typedef uint16_t ebtn_time_t;
typedef int16_t ebtn_time_sign_t;
#else
typedef uint32_t ebtn_time_t;
typedef int32_t ebtn_time_sign_t;
#endif
/* Forward declarations */
struct ebtn_btn;
struct ebtn;
#define EBTN_MAX_KEYNUM (64)
/**
* \brief List of button events
*
*/
typedef enum
{
EBTN_EVT_ONPRESS = 0x00, /*!< On press event - sent when valid press is detected */
EBTN_EVT_ONRELEASE, /*!< On release event - sent when valid release event is detected (from
active to inactive) */
EBTN_EVT_ONCLICK, /*!< On Click event - sent when valid sequence of on-press and on-release
events occurs */
EBTN_EVT_KEEPALIVE, /*!< Keep alive event - sent periodically when button is active */
} ebtn_evt_t;
#define EBTN_EVT_MASK_ONPRESS (1 << EBTN_EVT_ONPRESS)
#define EBTN_EVT_MASK_ONRELEASE (1 << EBTN_EVT_ONRELEASE)
#define EBTN_EVT_MASK_ONCLICK (1 << EBTN_EVT_ONCLICK)
#define EBTN_EVT_MASK_KEEPALIVE (1 << EBTN_EVT_KEEPALIVE)
#define EBTN_EVT_MASK_ALL (EBTN_EVT_MASK_ONPRESS | EBTN_EVT_MASK_ONRELEASE | EBTN_EVT_MASK_ONCLICK | EBTN_EVT_MASK_KEEPALIVE)
/**
* @brief Returns the difference between two absolute times: time1-time2.
* @param[in] time1: Absolute time expressed in internal time units.
* @param[in] time2: Absolute time expressed in internal time units.
* @return resulting signed relative time expressed in internal time units.
*/
static inline ebtn_time_sign_t ebtn_timer_sub(ebtn_time_t time1, ebtn_time_t time2)
{
return time1 - time2;
}
// test time overflow error
// #define ebtn_timer_sub(time1, time2) (time1 - time2)
/**
* \brief Button event function callback prototype
* \param[in] btn: Button instance from array for which event occured
* \param[in] evt: Event type
*/
typedef void (*ebtn_evt_fn)(struct ebtn_btn *btn, ebtn_evt_t evt);
/**
* \brief Get button/input state callback function
*
* \param[in] btn: Button instance from array to read state
* \return `1` when button is considered `active`, `0` otherwise
*/
typedef uint8_t (*ebtn_get_state_fn)(struct ebtn_btn *btn);
/**
* \brief Button Params structure
*/
typedef struct ebtn_btn_param
{
/**
* \brief Minimum debounce time for press event in units of milliseconds
*
* This is the time when the input shall have stable active level to detect valid *onpress*
* event.
*
* When value is set to `> 0`, input must be in active state for at least
* minimum milliseconds time, before valid *onpress* event is detected.
*
* \note If value is set to `0`, debounce is not used and *press* event will be
* triggered immediately when input states goes to *inactive* state.
*
* To be safe not using this feature, external logic must ensure stable
* transition at input level.
*
*/
uint16_t time_debounce; /*!< Debounce time in milliseconds */
/**
* \brief Minimum debounce time for release event in units of milliseconds
*
* This is the time when the input shall have minimum stable released level to detect valid
* *onrelease* event.
*
* This setting can be useful if application wants to protect against
* unwanted glitches on the line when input is considered "active".
*
* When value is set to `> 0`, input must be in inactive low for at least
* minimum milliseconds time, before valid *onrelease* event is detected
*
* \note If value is set to `0`, debounce is not used and *release* event will be
* triggered immediately when input states goes to *inactive* state
*
*/
uint16_t time_debounce_release; /*!< Debounce time in milliseconds for release event */
/**
* \brief Minimum active input time for valid click event, in milliseconds
*
* Input shall be in active state (after debounce) at least this amount of time to even consider
* the potential valid click event. Set the value to `0` to disable this feature
*
*/
uint16_t time_click_pressed_min; /*!< Minimum pressed time for valid click event */
/**
* \brief Maximum active input time for valid click event, in milliseconds
*
* Input shall be pressed at most this amount of time to still trigger valid click.
* Set to `-1` to allow any time triggering click event.
*
* When input is active for more than the configured time, click even is not detected and is
* ignored.
*
*/
uint16_t time_click_pressed_max; /*!< Maximum pressed time for valid click event*/
/**
* \brief Maximum allowed time between last on-release and next valid on-press,
* to still allow multi-click events, in milliseconds
*
* This value is also used as a timeout length to send the *onclick* event to application from
* previously detected valid click events.
*
* If application relies on multi consecutive clicks, this is the max time to allow user
* to trigger potential new click, or structure will get reset (before sent to user if any
* clicks have been detected so far)
*
*/
uint16_t time_click_multi_max; /*!< Maximum time between 2 clicks to be considered consecutive
click */
/**
* \brief Keep-alive event period, in milliseconds
*
* When input is active, keep alive events will be sent through this period of time.
* First keep alive will be sent after input being considered
* active.
*
*/
uint16_t time_keepalive_period; /*!< Time in ms for periodic keep alive event */
/**
* \brief Maximum number of allowed consecutive click events,
* before structure gets reset to default value.
*
* \note When consecutive value is reached, application will get notification of
* clicks. This can be executed immediately after last click has been detected, or after
* standard timeout (unless next on-press has already been detected, then it is send to
* application just before valid next press event).
*
*/
uint16_t max_consecutive; /*!< Max number of consecutive clicks */
} ebtn_btn_param_t;
#define EBTN_PARAMS_INIT(_time_debounce, _time_debounce_release, _time_click_pressed_min, _time_click_pressed_max, _time_click_multi_max, \
_time_keepalive_period, _max_consecutive) \
{ \
.time_debounce = _time_debounce, .time_debounce_release = _time_debounce_release, .time_click_pressed_min = _time_click_pressed_min, \
.time_click_pressed_max = _time_click_pressed_max, .time_click_multi_max = _time_click_multi_max, .time_keepalive_period = _time_keepalive_period, \
.max_consecutive = _max_consecutive \
}
#define EBTN_BUTTON_INIT_RAW(_key_id, _param, _mask) \
{ \
.key_id = _key_id, .param = _param, .event_mask = _mask, \
}
#define EBTN_BUTTON_INIT(_key_id, _param) EBTN_BUTTON_INIT_RAW(_key_id, _param, EBTN_EVT_MASK_ALL)
#define EBTN_BUTTON_DYN_INIT(_key_id, _param) \
{ \
.next = NULL, .btn = EBTN_BUTTON_INIT(_key_id, _param), \
}
#define EBTN_BUTTON_COMBO_INIT_RAW(_key_id, _param, _mask) \
{ \
.comb_key = {0}, .btn = EBTN_BUTTON_INIT_RAW(_key_id, _param, _mask), \
}
#define EBTN_BUTTON_COMBO_INIT(_key_id, _param) \
{ \
.comb_key = {0}, .btn = EBTN_BUTTON_INIT(_key_id, _param), \
}
#define EBTN_BUTTON_COMBO_DYN_INIT(_key_id, _param) \
{ \
.next = NULL, .btn = EBTN_BUTTON_COMBO_INIT(_key_id, _param), \
}
#define EBTN_ARRAY_SIZE(_arr) sizeof(_arr) / sizeof((_arr)[0])
/**
* \brief Button structure
*/
typedef struct ebtn_btn
{
uint16_t key_id; /*!< User defined custom argument for callback function purpose */
uint8_t flags; /*!< Private button flags management */
uint8_t event_mask; /*!< Private button event mask management */
ebtn_time_t time_change; /*!< Time in ms when button state got changed last time after valid
debounce */
ebtn_time_t time_state_change; /*!< Time in ms when button state got changed last time */
ebtn_time_t keepalive_last_time; /*!< Time in ms of last send keep alive event */
ebtn_time_t click_last_time; /*!< Time in ms of last successfully detected (not sent!) click event
*/
uint16_t keepalive_cnt; /*!< Number of keep alive events sent after successful on-press
detection. Value is reset after on-release */
uint16_t click_cnt; /*!< Number of consecutive clicks detected, respecting maximum timeout
between clicks */
const ebtn_btn_param_t *param;
} ebtn_btn_t;
/**
* \brief ComboButton structure
*/
typedef struct ebtn_btn_combo
{
BIT_ARRAY_DEFINE(comb_key, EBTN_MAX_KEYNUM); /*!< select key index - `1` means active, `0` means inactive */
ebtn_btn_t btn;
} ebtn_btn_combo_t;
/**
* \brief Dynamic Button structure
*/
typedef struct ebtn_btn_dyn
{
struct ebtn_btn_dyn *next; /*!< point to next button */
ebtn_btn_t btn;
} ebtn_btn_dyn_t;
/**
* \brief Dynamic ComboButton structure
*/
typedef struct ebtn_btn_combo_dyn
{
struct ebtn_btn_combo_dyn *next; /*!< point to next combo-button */
ebtn_btn_combo_t btn;
} ebtn_btn_combo_dyn_t;
/**
* \brief easy_button group structure
*/
typedef struct ebtn
{
ebtn_btn_t *btns; /*!< Pointer to buttons array */
uint16_t btns_cnt; /*!< Number of buttons in array */
ebtn_btn_combo_t *btns_combo; /*!< Pointer to comb-buttons array */
uint16_t btns_combo_cnt; /*!< Number of comb-buttons in array */
ebtn_btn_dyn_t *btn_dyn_head; /*!< Pointer to btn-dynamic list */
ebtn_btn_combo_dyn_t *btn_combo_dyn_head; /*!< Pointer to btn-combo-dynamic list */
ebtn_evt_fn evt_fn; /*!< Pointer to event function */
ebtn_get_state_fn get_state_fn; /*!< Pointer to get state function */
BIT_ARRAY_DEFINE(old_state, EBTN_MAX_KEYNUM); /*!< Old button state - `1` means active, `0` means inactive */
} ebtn_t;
/**
* \brief Button processing function, that reads the inputs and makes actions accordingly.
*
*
* \param[in] mstime: Current system time in milliseconds
*/
void ebtn_process(ebtn_time_t mstime);
/**
* \brief Button processing function, with all button input state.
*
* \param[in] curr_state: Current all button input state
* \param[in] mstime: Current system time in milliseconds
*/
void ebtn_process_with_curr_state(bit_array_t *curr_state, ebtn_time_t mstime);
/**
* \brief Check if button is active.
* Active is considered when initial debounce period has been a pass.
* This is the period between on-press and on-release events.
*
* \param[in] btn: Button handle to check
* \return `1` if active, `0` otherwise
*/
int ebtn_is_btn_active(const ebtn_btn_t *btn);
/**
* \brief Check if button is in process.
* Used for low-power processing, indicating that the buttons are temporarily idle, and embedded systems can consider entering deep sleep.
*
* \param[in] btn: Button handle to check
* \return `1` if in process, `0` otherwise
*/
int ebtn_is_btn_in_process(const ebtn_btn_t *btn);
/**
* \brief Check if some button is in process.
* Used for low-power processing, indicating that the buttons are temporarily idle, and embedded systems can consider entering deep sleep.
*
* \return `1` if in process, `0` otherwise
*/
int ebtn_is_in_process(void);
/**
* \brief Initialize button manager
* \param[in] btns: Array of buttons to process
* \param[in] btns_cnt: Number of buttons to process
* \param[in] btns_combo: Array of combo-buttons to process
* \param[in] btns_combo_cnt: Number of combo-buttons to process
* \param[in] get_state_fn: Pointer to function providing button state on demand.
* \param[in] evt_fn: Button event function callback
*
* \return `1` on success, `0` otherwise
*/
int ebtn_init(ebtn_btn_t *btns, uint16_t btns_cnt, ebtn_btn_combo_t *btns_combo, uint16_t btns_combo_cnt, ebtn_get_state_fn get_state_fn, ebtn_evt_fn evt_fn);
/**
* @brief Register a dynamic button
*
* @param button: Dynamic button structure instance
* \return `1` on success, `0` otherwise
*/
int ebtn_register(ebtn_btn_dyn_t *button);
/**
* \brief Register a dynamic combo-button
* \param[in] button: Dynamic combo-button structure instance
*
* \return `1` on success, `0` otherwise
*/
int ebtn_combo_register(ebtn_btn_combo_dyn_t *button);
/**
* \brief Get the current total button cnt
*
* \return size of button.
*/
int ebtn_get_total_btn_cnt(void);
/**
* \brief Get the internal key_idx of the key_id
* \param[in] key_id: key_id
*
* \return '-1' on error, other is key_idx
*/
int ebtn_get_btn_index_by_key_id(uint16_t key_id);
/**
* \brief Get the internal btn instance of the key_id, here is the button instance, and what is dynamically registered is also to obtain its button
* instance
*
* \param[in] key_id: key_id
*
* \return 'NULL' on error, other is button instance
*/
ebtn_btn_t *ebtn_get_btn_by_key_id(uint16_t key_id);
/**
* \brief Get the internal key_idx of the button
* \param[in] btn: Button
*
* \return '-1' on error, other is key_idx
*/
int ebtn_get_btn_index_by_btn(ebtn_btn_t *btn);
/**
* \brief Get the internal key_idx of the dynamic button
* \param[in] btn: Button
*
* \return '-1' on error, other is key_idx
*/
int ebtn_get_btn_index_by_btn_dyn(ebtn_btn_dyn_t *btn);
/**
* \brief Bind combo-button key with key_idx
* \param[in] btn: Combo Button
* \param[in] idx: key_idx
*
*/
void ebtn_combo_btn_add_btn_by_idx(ebtn_btn_combo_t *btn, int idx);
/**
* \brief Remove combo-button key with key_idx
* \param[in] btn: Combo Button
* \param[in] idx: key_idx
*
*/
void ebtn_combo_btn_remove_btn_by_idx(ebtn_btn_combo_t *btn, int idx);
/**
* \brief Bind combo-button key with key_id, make sure key_id(button) is already register.
* \param[in] btn: Combo Button
* \param[in] key_id: key_id
*
*/
void ebtn_combo_btn_add_btn(ebtn_btn_combo_t *btn, uint16_t key_id);
/**
* \brief Remove combo-button key with key_id, make sure key_id(button) is already
* register. \param[in] btn: Combo Button \param[in] key_id: key_id
*
*/
void ebtn_combo_btn_remove_btn(ebtn_btn_combo_t *btn, uint16_t key_id);
/**
* \brief Get keep alive period for specific button
* \param[in] btn: Button instance to get keep alive period for
* \return Keep alive period in `ms`
*/
#define ebtn_keepalive_get_period(btn) ((btn)->time_keepalive_period)
/**
* \brief Get actual number of keep alive counts since the last on-press event.
* It is set to `0` if btn isn't pressed
* \param[in] btn: Button instance to get keep alive period for
* \return Number of keep alive events since on-press event
*/
#define ebtn_keepalive_get_count(btn) ((btn)->keepalive_cnt)
/**
* \brief Get number of keep alive counts for specific required time in milliseconds.
* It will calculate number of keepalive ticks specific button shall make,
* before requested time is reached.
*
* Result of the function can be used with \ref ebtn_keepalive_get_count which returns
* actual number of keep alive counts since last on-press event of the button.
*
* \note Value is always integer aligned, with granularity of one keepalive time period
* \note Implemented as macro, as it may be optimized by compiler when static keep alive
* is used
*
* \param[in] btn: Button to use for check
* \param[in] ms_time: Time in ms to calculate number of keep alive counts
* \return Number of keep alive counts
*/
#define ebtn_keepalive_get_count_for_time(btn, ms_time) ((ms_time) / ebtn_keepalive_get_period(btn))
/**
* \brief Get number of consecutive click events on a button
* \param[in] btn: Button instance to get number of clicks
* \return Number of consecutive clicks on a button
*/
#define ebtn_click_get_count(btn) ((btn)->click_cnt)
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _EBTN_H */

View File

@@ -0,0 +1,90 @@
#include "ebtn_cb.h"
/* ---------------- 按钮参数配置 ---------------- */
static const ebtn_btn_param_t default_param = EBTN_PARAMS_INIT
(
20, // 按下去抖时间(ms)
20, // 释放去抖时间(ms)
20, // 点击最短时间(ms)
300, // 点击最长时间(ms)
200, // 连击间隔最大值(ms)
500, // 长按KEEPALIVE间隔(ms)
10 // 最大连续点击次数
);
/* ---------------- 按钮ID定义 ---------------- */
typedef enum
{
USER_BUTTON1 = 0,
USER_BUTTON_MAX,
} user_button_t;
/* ---------------- 按钮对象 ---------------- */
static ebtn_btn_t btns[] =
{
EBTN_BUTTON_INIT(USER_BUTTON1, &default_param),
};
/* ---------------- 获取按键状态 ---------------- */
static uint8_t prv_btn_get_state(struct ebtn_btn* btn)
{
switch(btn->key_id)
{
case USER_BUTTON1:
return gpio_get(GPIOC, GPIO13) == GPIO13;
default:
return 0;
}
}
/* ---------------- 事件回调函数 ---------------- */
static void prv_btn_event(struct ebtn_btn* btn, ebtn_evt_t evt)
{
switch(evt)
{
case EBTN_EVT_ONPRESS:
break;
case EBTN_EVT_ONRELEASE:
break;
case EBTN_EVT_ONCLICK:
if((ebtn_click_get_count(btn) == 2) && (btn->key_id == USER_BUTTON1))
{
gpio_toggle(GPIOE, GPIO3);
}
//printf("[BTN %d] Clicked, count=%d\r\n", btn->key_id, ebtn_click_get_count(btn));
break;
case EBTN_EVT_KEEPALIVE:
if(btn->key_id == USER_BUTTON1)
{
gpio_toggle(GPIOE, GPIO3);
}
//printf("[BTN %d] Keepalive, cnt=%d\r\n", btn->key_id, ebtn_keepalive_get_count(btn));
break;
default:
break;
}
}
/* ---------------- 系统时间 ---------------- */
static uint32_t ebtn_user_get_tick(void)
{
return systick;
}
/* ---------------- 初始化函数 ---------------- */
void ebtn_user_init(void)
{
ebtn_init(btns,
EBTN_ARRAY_SIZE(btns),
NULL, 0, // 无组合键
prv_btn_get_state,
prv_btn_event);
}
/* ---------------- 周期处理函数 ---------------- */
void ebtn_user_process(void)
{
ebtn_process(ebtn_user_get_tick());
}

View File

@@ -0,0 +1,21 @@
#ifndef __EBTN_CB_H_
#define __EBTN_CB_H_
#include "ebtn.h"
#include "gpio.h"
#include "systick.h"
#ifdef __cplusplus
extern "C" {
#endif
void ebtn_user_init(void);
void ebtn_user_process(void);
#ifdef __cplusplus
}
#endif
#endif

97
2gpio-lib/makefile Normal file
View File

@@ -0,0 +1,97 @@
# this is the build file for project stm32h7
# it is autogenerated by the xmake build system.
# do not edit by hand.
ifneq ($(VERBOSE),1)
VV=@
endif
CU=/usr/bin/clang
RC=/home/time/.cargo/bin/rustc
MM=/usr/bin/gcc
AS=/usr/bin/gcc
GC=/usr/local/go/bin/go
CXX=/usr/bin/g++
CC=/usr/bin/gcc
MXX=/usr/bin/g++
SH=/usr/bin/g++
RCSH=/home/time/.cargo/bin/rustc
GCAR=/usr/local/go/bin/go
AR=/usr/bin/ar
RCAR=/home/time/.cargo/bin/rustc
GCLD=/usr/local/go/bin/go
LD=/usr/bin/g++
RCLD=/home/time/.cargo/bin/rustc
lib-ebtn_AR=/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc-ar
lib-ebtn_CC=/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc
gpio-lib_LD=/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-g++
gpio-lib_CC=/home/time/doc/mybin/arm-none-eabi/bin/arm-none-eabi-gcc
lib-ebtn_CCFLAGS=-g -O0 -I../../libopencm3/include -Iuser/inc -Ilib/ebtn -DSTM32H7 -mthumb -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard
lib-ebtn_ARFLAGS=-cr
gpio-lib_CCFLAGS=-g -O0 -I../../libopencm3/include -Iuser/inc -Ilib/ebtn -DSTM32H7 -mthumb -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard
gpio-lib_LDFLAGS=-L../../libopencm3/lib "-L\"build/MCU/ARM Cortex-M7/release\"" -llib-ebtn -lopencm3_stm32h7 -lc -lgcc -lnosys -mthumb -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -T./cortex-m-generic.ld --static -nostartfiles -Wl,--gc-sections -Wl,-Map=/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib/bin/gpio-lib.map,-cref
default: lib-ebtn lib gpio-lib
all: lib-ebtn lib gpio-lib
.PHONY: default all lib-ebtn lib gpio-lib
lib-ebtn: "build/MCU/ARM Cortex-M7/release/liblib-ebtn.a"
"build/MCU/ARM Cortex-M7/release/liblib-ebtn.a": "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn_cb.c.o" "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn.c.o"
@echo linking.release liblib-ebtn.a"
@mkdir -p "build/MCU/ARM Cortex-M7/release
$(VV)$(lib-ebtn_AR) $(lib-ebtn_ARFLAGS) "\"build/MCU/ARM Cortex-M7/release/liblib-ebtn.a\"" "\"build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn_cb.c.o\"" "\"build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn.c.o\""
"build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn_cb.c.o": lib/ebtn/ebtn_cb.c
@echo compiling.release lib/ebtn/ebtn_cb.c
@mkdir -p "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn
$(VV)$(lib-ebtn_CC) -c $(lib-ebtn_CCFLAGS) -o "\"build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn_cb.c.o\"" lib/ebtn/ebtn_cb.c
"build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn.c.o": lib/ebtn/ebtn.c
@echo compiling.release lib/ebtn/ebtn.c
@mkdir -p "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn
$(VV)$(lib-ebtn_CC) -c $(lib-ebtn_CCFLAGS) -o "\"build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn.c.o\"" lib/ebtn/ebtn.c
lib: lib-ebtn
gpio-lib: bin/gpio-lib.elf
bin/gpio-lib.elf: lib "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/gpio.c.o" "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/main.c.o" "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/systick.c.o"
@echo linking.release gpio-lib.elf
@mkdir -p bin
$(VV)$(gpio-lib_LD) -o bin/gpio-lib.elf "\"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/gpio.c.o\"" "\"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/main.c.o\"" "\"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/systick.c.o\"" $(gpio-lib_LDFLAGS)
"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/gpio.c.o": user/src/gpio.c
@echo compiling.release user/src/gpio.c
@mkdir -p "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src
$(VV)$(gpio-lib_CC) -c $(gpio-lib_CCFLAGS) -o "\"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/gpio.c.o\"" user/src/gpio.c
"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/main.c.o": user/src/main.c
@echo compiling.release user/src/main.c
@mkdir -p "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src
$(VV)$(gpio-lib_CC) -c $(gpio-lib_CCFLAGS) -o "\"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/main.c.o\"" user/src/main.c
"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/systick.c.o": user/src/systick.c
@echo compiling.release user/src/systick.c
@mkdir -p "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src
$(VV)$(gpio-lib_CC) -c $(gpio-lib_CCFLAGS) -o "\"build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/systick.c.o\"" user/src/systick.c
clean: clean_lib-ebtn clean_lib clean_gpio-lib
clean_lib-ebtn:
@rm -rf "build/MCU/ARM Cortex-M7/release/liblib-ebtn.a"
@rm -rf "build/MCU/ARM Cortex-M7/release/lib-ebtn.sym"
@rm -rf "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn_cb.c.o"
@rm -rf "build/.objs/lib-ebtn/MCU/ARM Cortex-M7/release/lib/ebtn/ebtn.c.o"
clean_lib: clean_lib-ebtn
clean_gpio-lib: clean_lib
@rm -rf bin/gpio-lib.elf
@rm -rf bin/gpio-lib.sym
@rm -rf "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/gpio.c.o"
@rm -rf "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/main.c.o"
@rm -rf "build/.objs/gpio-lib/MCU/ARM Cortex-M7/release/user/src/systick.c.o"

308
2gpio-lib/stm32h7x.cfg Normal file
View File

@@ -0,0 +1,308 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# script for stm32h7x family
#
# stm32h7 devices support both JTAG and SWD transports.
#
source [find target/swj-dp.tcl]
source [find mem_helper.tcl]
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32h7x
}
if { [info exists DUAL_BANK] } {
set $_CHIPNAME.DUAL_BANK $DUAL_BANK
unset DUAL_BANK
} else {
set $_CHIPNAME.DUAL_BANK 0
}
if { [info exists DUAL_CORE] } {
set $_CHIPNAME.DUAL_CORE $DUAL_CORE
unset DUAL_CORE
} else {
set $_CHIPNAME.DUAL_CORE 0
}
# Issue a warning when hla is used, and fallback to single core configuration
if { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {
echo "Warning : hla does not support multicore debugging"
set $_CHIPNAME.DUAL_CORE 0
}
if { [info exists USE_CTI] } {
set $_CHIPNAME.USE_CTI $USE_CTI
unset USE_CTI
} else {
set $_CHIPNAME.USE_CTI 0
}
# Issue a warning when DUAL_CORE=0 and USE_CTI=1, and fallback to USE_CTI=0
if { ![set $_CHIPNAME.DUAL_CORE] && [set $_CHIPNAME.USE_CTI] } {
echo "Warning : could not use CTI with a single core device, CTI is disabled"
set $_CHIPNAME.USE_CTI 0
}
set _ENDIAN little
# Work-area is a space in RAM used for flash programming
# By default use 64kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x10000
}
#jtag scan chain
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
if { [using_jtag] } {
set _CPUTAPID 0x6ba00477
} {
set _CPUTAPID 0x6ba02477
}
}
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
if {[using_jtag]} {
jtag newtap $_CHIPNAME bs -irlen 5
}
if {![using_hla]} {
# STM32H7 provides an APB-AP at access port 2, which allows the access to
# the debug and trace features on the system APB System Debug Bus (APB-D).
target create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2
swo create $_CHIPNAME.swo -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00E3000
tpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00F5000
}
target create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0
$_CHIPNAME.cpu0 configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
flash bank $_CHIPNAME.bank1.cpu0 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0
if {[set $_CHIPNAME.DUAL_BANK]} {
flash bank $_CHIPNAME.bank2.cpu0 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu0
}
if {[set $_CHIPNAME.DUAL_CORE]} {
target create $_CHIPNAME.cpu1 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 3
$_CHIPNAME.cpu1 configure -work-area-phys 0x38000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
flash bank $_CHIPNAME.bank1.cpu1 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu1
if {[set $_CHIPNAME.DUAL_BANK]} {
flash bank $_CHIPNAME.bank2.cpu1 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu1
}
}
# Make sure that cpu0 is selected
targets $_CHIPNAME.cpu0
if { [info exists QUADSPI] && $QUADSPI } {
set a [llength [flash list]]
set _QSPINAME $_CHIPNAME.qspi
flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000
} else {
if { [info exists OCTOSPI1] && $OCTOSPI1 } {
set a [llength [flash list]]
set _OCTOSPINAME1 $_CHIPNAME.octospi1
flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000
}
if { [info exists OCTOSPI2] && $OCTOSPI2 } {
set b [llength [flash list]]
set _OCTOSPINAME2 $_CHIPNAME.octospi2
flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_CHIPNAME.cpu0 0x5200A000
}
}
# Clock after reset is HSI at 64 MHz, no need of PLL
adapter speed 1800
adapter srst delay 100
if {[using_jtag]} {
jtag_ntrst_delay 100
}
# use hardware reset
#
# The STM32H7 does not support connect_assert_srst mode because the AXI is
# unavailable while SRST is asserted, and that is used to access the DBGMCU
# component at 0x5C001000 in the examine-end event handler.
#
# It is possible to access the DBGMCU component at 0xE00E1000 via AP2 instead
# of the default AP0, and that works with SRST asserted; however, nonzero AP
# usage does not work with HLA, so is not done by default. That change could be
# made in a local configuration file if connect_assert_srst mode is needed for
# a specific application and a non-HLA adapter is in use.
reset_config srst_nogate
if {![using_hla]} {
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq
if {[set $_CHIPNAME.DUAL_CORE]} {
$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq
}
# Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal
# HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3
# makes the data access cacheable. This allows reading and writing data in the
# CPU cache from the debugger, which is far more useful than going straight to
# RAM when operating on typical variables, and is generally no worse when
# operating on special memory locations.
$_CHIPNAME.dap apcsw 0x08000000 0x08000000
}
$_CHIPNAME.cpu0 configure -event examine-end {
# Enable D3 and D1 DBG clocks
# DBGMCU_CR |= D3DBGCKEN | D1DBGCKEN
stm32h7x_dbgmcu_mmw 0x004 0x00600000 0
# Enable debug during low power modes (uses more power)
# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D1 Domain
stm32h7x_dbgmcu_mmw 0x004 0x00000007 0
# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D2 Domain
stm32h7x_dbgmcu_mmw 0x004 0x00000038 0
# Stop watchdog counters during halt
# DBGMCU_APB3FZ1 |= WWDG1
stm32h7x_dbgmcu_mmw 0x034 0x00000040 0
# DBGMCU_APB1LFZ1 |= WWDG2
stm32h7x_dbgmcu_mmw 0x03C 0x00000800 0
# DBGMCU_APB4FZ1 |= WDGLSD1 | WDGLSD2
stm32h7x_dbgmcu_mmw 0x054 0x000C0000 0
# Enable clock for tracing
# DBGMCU_CR |= TRACECLKEN
stm32h7x_dbgmcu_mmw 0x004 0x00100000 0
# RM0399 (id 0x450) M7+M4 with SWO Funnel
# RM0433 (id 0x450) M7 with SWO Funnel
# RM0455 (id 0x480) M7 without SWO Funnel
# RM0468 (id 0x483) M7 without SWO Funnel
# Enable CM7 and CM4 slave ports in SWO trace Funnel
# Works ok also on devices single core and without SWO funnel
# Hack, use stm32h7x_dbgmcu_mmw with big offset to control SWTF
# SWTF_CTRL |= ENS0 | ENS1
stm32h7x_dbgmcu_mmw 0x3000 0x00000003 0
}
$_CHIPNAME.cpu0 configure -event reset-init {
# Clock after reset is HSI at 64 MHz, no need of PLL
adapter speed 4000
}
# get _CHIPNAME from current target
proc stm32h7x_get_chipname {} {
set t [target current]
set sep [string last "." $t]
if {$sep == -1} {
return $t
}
return [string range $t 0 [expr {$sep - 1}]]
}
if {[set $_CHIPNAME.DUAL_CORE]} {
$_CHIPNAME.cpu1 configure -event examine-end {
set _CHIPNAME [stm32h7x_get_chipname]
global $_CHIPNAME.USE_CTI
# Stop watchdog counters during halt
# DBGMCU_APB3FZ2 |= WWDG1
stm32h7x_dbgmcu_mmw 0x038 0x00000040 0
# DBGMCU_APB1LFZ2 |= WWDG2
stm32h7x_dbgmcu_mmw 0x040 0x00000800 0
# DBGMCU_APB4FZ2 |= WDGLSD1 | WDGLSD2
stm32h7x_dbgmcu_mmw 0x058 0x000C0000 0
if {[set $_CHIPNAME.USE_CTI]} {
stm32h7x_cti_start
}
}
}
# like mrw, but with target selection
proc stm32h7x_mrw {used_target reg} {
return [$used_target read_memory $reg 32 1]
}
# like mmw, but with target selection
proc stm32h7x_mmw {used_target reg setbits clearbits} {
set old [stm32h7x_mrw $used_target $reg]
set new [expr {($old & ~$clearbits) | $setbits}]
$used_target mww $reg $new
}
# mmw for dbgmcu component registers, it accepts the register offset from dbgmcu base
# this procedure will use the mem_ap on AP2 whenever possible
proc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} {
# use $_CHIPNAME.ap2 if possible, and use the proper dbgmcu base address
if {![using_hla]} {
set _CHIPNAME [stm32h7x_get_chipname]
set used_target $_CHIPNAME.ap2
set reg_addr [expr {0xE00E1000 + $reg_offset}]
} {
set used_target [target current]
set reg_addr [expr {0x5C001000 + $reg_offset}]
}
stm32h7x_mmw $used_target $reg_addr $setbits $clearbits
}
if {[set $_CHIPNAME.USE_CTI]} {
# create CTI instances for both cores
cti create $_CHIPNAME.cti0 -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0043000
cti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 3 -baseaddr 0xE0043000
$_CHIPNAME.cpu0 configure -event halted { stm32h7x_cti_prepare_restart_all }
$_CHIPNAME.cpu1 configure -event halted { stm32h7x_cti_prepare_restart_all }
$_CHIPNAME.cpu0 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }
$_CHIPNAME.cpu1 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }
proc stm32h7x_cti_start {} {
set _CHIPNAME [stm32h7x_get_chipname]
# Configure Cores' CTIs to halt each other
# TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0
$_CHIPNAME.cti0 write INEN0 0x1
$_CHIPNAME.cti0 write OUTEN0 0x1
$_CHIPNAME.cti1 write INEN0 0x1
$_CHIPNAME.cti1 write OUTEN0 0x1
# enable CTIs
$_CHIPNAME.cti0 enable on
$_CHIPNAME.cti1 enable on
}
proc stm32h7x_cti_stop {} {
set _CHIPNAME [stm32h7x_get_chipname]
$_CHIPNAME.cti0 enable off
$_CHIPNAME.cti1 enable off
}
proc stm32h7x_cti_prepare_restart_all {} {
stm32h7x_cti_prepare_restart cti0
stm32h7x_cti_prepare_restart cti1
}
proc stm32h7x_cti_prepare_restart {cti} {
set _CHIPNAME [stm32h7x_get_chipname]
# Acknowlodge EDBGRQ at TRIGOUT0
$_CHIPNAME.$cti write INACK 0x01
$_CHIPNAME.$cti write INACK 0x00
}
}

View File

@@ -0,0 +1,8 @@
#ifndef _GPIO_H
#define _GPIO_H
#include "main.h"
void user_gpio_setup(void);
#endif

17
2gpio-lib/user/inc/main.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef _MAIN_H
#define _MAIN_H
#include <stdint.h>
// 包含libopencm3内核的相关头文件
#include <libopencm3/cm3/systick.h> // 系统滴答定时器相关定义
#include <libopencm3/cm3/scb.h> // 系统控制块相关定义
// 包含STM32 H系列微控制器的相关头文件
#include <libopencm3/stm32/rcc.h> // 复位和时钟控制相关定义
#include <libopencm3/stm32/pwr.h> // 电源控制相关定义
#include <libopencm3/stm32/gpio.h> // 通用输入输出相关定义
#include <libopencm3/stm32/flash.h> // 闪存控制相关定义
#include <libopencm3/stm32/h7/nvic.h> // 中断向量控制器相关定义
#endif

View File

@@ -0,0 +1,11 @@
#ifndef _SYSTICK_H
#define _SYSTICK_H
#include "main.h"
extern volatile uint32_t systick;
void user_delay_ms(uint32_t ms);
void systick_init(uint32_t ticks);
#endif

47
2gpio-lib/user/src/gpio.c Normal file
View File

@@ -0,0 +1,47 @@
#include "gpio.h"
/**
* @brief 初始化用户GPIO引脚配置
*
* @details 该函数用于初始化和配置用户所需的GPIO引脚,主要包括以下配置:
* 1. 使能GPIOE时钟,配置PE3引脚为推挽输出模式,速度为2MHz,初始状态为低电平
* 2. 使能备份区域寄存器访问通过设置PWR_CR1_DBP位
* 3. 使能GPIOC时钟,配置PC13引脚为输入模式,并启用下拉电阻
* 这些配置通常用于设置LED控制引脚和按钮输入引脚等常见外设接口。
*
* @note 该函数应在系统初始化阶段调用,确保GPIO引脚在使用前已正确配置。
* PE3引脚配置为输出模式,可用于驱动LED或其他输出设备。
* PC13引脚配置为输入模式并启用下拉电阻,适合连接按钮或开关等输入设备。
* PWR_CR1_DBP位的设置允许访问备份寄存器,这在某些应用中可能是必要的。
*
* @warning 在调用此函数前,应确保系统时钟已经正确配置。
* 修改GPIO配置可能会影响连接到这些引脚的外设功能。
* 在多任务系统中,如果多个任务访问同一GPIO,可能需要添加同步机制。
*
* @see rcc_periph_clock_enable(), gpio_mode_setup(), gpio_set_output_options(), gpio_clear()
*/
void user_gpio_setup(void)
{
// 使能GPIOE端口的时钟,必须先使能时钟才能配置和使用该端口的引脚
rcc_periph_clock_enable(RCC_GPIOE);
// 配置GPIOE端口的引脚3为输出模式,不使用上拉或下拉电阻
gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3);
// 设置GPIOE端口引脚3的输出选项推挽输出类型,速度为2MHz
gpio_set_output_options(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO3);
// 将GPIOE端口引脚3设置为低电平,也就是灯灭
gpio_clear(GPIOE, GPIO3);
// 使能备份域访问,通过设置电源控制寄存器1的DBP位
// 这是访问RTC、备份寄存器等备份域外设的必要步骤
// PC13-PC15是备份域的GPIO引脚,需要使能备份域访问才能配置这些引脚
PWR_CR1 |= PWR_CR1_DBP;
// 使能GPIOC端口的时钟,必须先使能时钟才能配置和使用该端口的引脚
rcc_periph_clock_enable(RCC_GPIOC);
// 配置GPIOC端口的引脚13为输入模式,并启用下拉电阻
gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO13);
}

162
2gpio-lib/user/src/main.c Normal file
View File

@@ -0,0 +1,162 @@
#include "main.h"
#include "gpio.h"
#include "systick.h"
#include "ebtn_cb.h"
static void system_clock_setup(void);
/**
* @brief 主函数,程序入口点
*
* @details 该函数是程序的入口点,负责系统的初始化和主循环。主要执行以下步骤:
* 1. 设置中断优先级分组为16个优先级,无子优先级
* 2. 初始化系统时钟配置
* 3. 初始化SysTick定时器,设置为每毫秒产生一次中断
* 4. 初始化用户GPIO引脚配置
* 5. 进入主循环,检测按钮状态并控制LED
* 主循环中检测PC13引脚按钮的状态,当检测到按钮按下时,
* 进行消抖处理,然后切换PE3引脚LED的状态,并等待按钮释放。
*
* @note 该函数不会返回,除非发生严重错误。
* 主循环中的按钮检测包含了简单的消抖处理,通过延时和再次检测实现。
* 程序使用了轮询方式检测按钮状态,适用于简单的嵌入式应用。
*
* @warning 在修改此函数时,应确保系统初始化顺序正确,特别是时钟配置。
* 按钮消抖延时时间(20ms)可能需要根据实际硬件特性进行调整。
* 如果使用RTOS,此函数结构需要重新设计以适应任务调度。
*
* @see scb_set_priority_grouping(), system_clock_setup(), systick_init(),
* user_gpio_setup(), user_delay_ms(), gpio_get(), gpio_toggle()
*/
int main(void)
{
// 设置中断优先级分组为16个主优先级,无子优先级
// 这意味着每个中断都有独立的优先级,没有子优先级用于同一优先级中断的排序
scb_set_priority_grouping(SCB_AIRCR_PRIGROUP_GROUP16_NOSUB);
// 初始化系统时钟配置
system_clock_setup();
// 初始化SysTick定时器,参数1000U表示每秒产生1000次中断,即每1ms一次
systick_init(1000U);
// 初始化用户GPIO引脚配置
// 根据gpio的代码,这包括配置PE3为输出LED和PC13为输入按钮
user_gpio_setup();
// 初始化按键库
ebtn_user_init();
// 主循环,程序将在此无限循环
while (1)
{
// 处理按键事件,该函数可以放到其他可以周期运行的地方
ebtn_user_process();
user_delay_ms(5);
}
// 理论上不会执行到这里,因为上面是无限循环
// 这行代码主要是为了满足C语言标准中main函数应有返回值的要求
return 0;
}
/**
* @brief 系统时钟配置函数
*
* @details 该函数用于初始化和配置系统的时钟树,包括PLL锁相环、系统时钟分频、Flash等待状态
* 和电源管理设置。函数执行以下主要步骤:
* 1. 初始化GPIOH和SYSCFG时钟,配置GPIOH1引脚为输出模式
* 2. 设置PLL配置结构体的各个参数,包括时钟源选择、PLL分频系数等
* 3. 配置系统时钟分频参数,确定各个总线的时钟频率
* 4. 设置Flash等待状态,确保Flash访问速度与系统时钟频率匹配
* 5. 配置电压缩放比例和电源模式
* 6. 应用PLL配置,完成系统时钟设置
* 这些配置参数与STM32CubeMX工具生成的配置可以一一对应,便于调试和验证。
*
* @note 该函数应在系统启动初期调用,确保系统时钟正确配置后再进行其他初始化。
* 函数中配置的GPIOH1引脚可能用于指示时钟配置状态或调试目的。
* PLL配置基于25MHz的外部高速晶振(HSE),通过PLL1产生系统时钟。
* PLL2和PLL3可用于为特定外设提供时钟。
* 系统时钟配置完成后,CPU将运行在较高频率(约480MHz),具体取决于PLL1配置。
*
* @warning 修改此函数中的时钟配置参数时,应确保不超过芯片的最大工作频率限制。
* 不正确的时钟配置可能导致系统不稳定或无法正常工作。
* 修改时钟配置可能会影响依赖于精确时序的外设(如UART、SPI等)。
* 在多任务系统中,修改系统时钟可能需要重新调整定时器和调度器的配置。
*
* @see rcc_periph_clock_enable(), gpio_mode_setup(), gpio_set_output_options(),
* gpio_set(), rcc_clock_setup_pll()
*/
static void system_clock_setup(void)
{
// 初始化PLL配置结构体,所有成员清零
struct rcc_pll_config pll_config = {0};
// 使能GPIOH端口时钟,用于配置GPIOH1引脚
// OSC_IN是GPIOH0,OSC_OUT是GPIOH1
rcc_periph_clock_enable(RCC_GPIOH);
// 使能SYSCFG时钟,用于系统配置
rcc_periph_clock_enable(RCC_SYSCFG);
// 配置GPIOH1引脚为输出模式,启用上拉电阻
gpio_mode_setup(GPIOH, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO1);
// 设置GPIOH1引脚为推挽输出,速度为50MHz
gpio_set_output_options(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO1);
// 短暂延时,确保GPIO配置稳定
for (unsigned i = 0; i < 20; i++)
{
__asm__("nop"); // 空操作指令,用于延时
}
// 将GPIOH1引脚设置为高电平
gpio_set(GPIOH, GPIO1);
// 设置系统时钟源为PLL
pll_config.sysclock_source = RCC_PLL;
// 设置PLL时钟源为外部高速晶振(HSE)
pll_config.pll_source = RCC_PLLCKSELR_PLLSRC_HSE;
// 设置HSE频率为25MHz
pll_config.hse_frequency = 25000000U;
// 配置PLL1参数,这一部分可以和CubeMX进行一一对应
// 系统时钟频率 = HSE / M * N / P = 25MHz / 5 * 192 / 2 = 480MHz
pll_config.pll1.divm = 5;
pll_config.pll1.divn = 192;
pll_config.pll1.divp = 2;
pll_config.pll1.divq = 2;
pll_config.pll1.divr = 2;
// 配置PLL2参数
pll_config.pll2.divm = 32;
pll_config.pll2.divn = 129;
pll_config.pll2.divp = 2;
pll_config.pll2.divq = 2;
pll_config.pll2.divr = 2;
// 配置PLL3参数
pll_config.pll3.divm = 32;
pll_config.pll3.divn = 129;
pll_config.pll3.divp = 2;
pll_config.pll3.divq = 2;
pll_config.pll3.divr = 2;
// 配置系统时钟分频参数,还是可以和CubeMX进行一一对应
pll_config.core_pre = RCC_D1CFGR_D1CPRE_BYP; // CPU核心时钟不分频
pll_config.hpre = RCC_D1CFGR_D1HPRE_DIV2; // AHB总线时钟2分频
pll_config.ppre1 = RCC_D2CFGR_D2PPRE_DIV2; // APB1总线时钟2分频
pll_config.ppre2 = RCC_D2CFGR_D2PPRE_DIV2; // APB2总线时钟2分频
pll_config.ppre3 = RCC_D1CFGR_D1PPRE_DIV2; // APB3总线时钟2分频
pll_config.ppre4 = RCC_D3CFGR_D3PPRE_DIV2; // APB4总线时钟2分频
// 设置Flash等待状态为4个周期,确保在480MHz系统时钟下能正确访问Flash
pll_config.flash_waitstates = FLASH_ACR_LATENCY_4WS;
// 配置电压缩放和电源模式
pll_config.voltage_scale = PWR_VOS_SCALE_0; // 电压缩放级别0,最高性能模式
pll_config.power_mode = PWR_SYS_LDO; // 使用LDO(低压差线性稳压器)电源模式
pll_config.smps_level = 0; // SMPS(开关模式电源)级别
// 应用PLL配置,完成系统时钟设置
rcc_clock_setup_pll(&pll_config);
}

View File

@@ -0,0 +1,145 @@
#include "systick.h"
/**
* @brief 系统毫秒计数器
*
* @details 这是一个全局变量,用于记录系统运行的毫秒数。
* 该变量在SysTick定时器中断服务程序(sys_tick_handler)中递增,
* 通常用于实现系统计时和延时功能如user_delay_ms函数
* 变量被声明为volatile,确保编译器不会优化掉对它的访问,
* 因为它可以在中断上下文中被修改,而主程序可能需要读取它的值。
*
* @note 该变量的初始值为0,表示系统启动后经过的毫秒数。
* 变量的递增频率取决于SysTick定时器的配置,通常为每毫秒递增一次。
* 在32位系统上,该变量约每49.7天会溢出一次从2^32-1回到0
*
* @warning 在多任务或多线程环境中访问此变量时,可能需要添加适当的同步机制,
* 如禁用中断或使用原子操作,以避免竞态条件。
* 不应直接修改此变量的值,除非有特殊需求并了解其影响。
*
* @see sys_tick_handler(), user_delay_ms(), systick_init()
*/
volatile uint32_t systick = 0;
/**
* @brief 执行WFI(Wait For Interrupt)指令,使处理器进入低功耗状态
*
* @details 该函数使用内联汇编执行ARM Cortex-M处理器的WFI指令。
* WFI指令会使处理器进入低功耗状态,直到下一个中断发生时才会唤醒处理器。
* 该函数被声明为静态内联(always_inline),确保总是被内联展开以减少函数调用开销。
* 使用volatile关键字防止编译器优化掉看似"无用"的指令。
*
* @note 该函数不会改变处理器状态,只是暂停执行直到中断发生。
* 在中断发生时,处理器会恢复执行WFI指令之后的代码。
* 该函数通常用于在等待事件或延时期间降低系统功耗。
*
* @warning 使用该函数时,确保系统中存在能够唤醒处理器的中断源,
* 否则处理器可能会一直保持低功耗状态。
*/
static inline __attribute__((always_inline)) void __WFI(void)
{
__asm volatile("wfi");
}
/**
* @brief 实现毫秒级延时的函数
*
* @details 该函数使用SysTick定时器实现精确的毫秒级延时。函数记录当前的SysTick值作为起始时间,
* 然后进入循环等待,直到经过的时间达到指定的毫秒数。在等待期间,CPU会通过WFI指令
* 进入低功耗状态,以降低系统功耗。该函数适用于裸机系统中的简单延时需求。
*
* @param ms 要延时的毫秒数,取值范围为1到(2^32-1)毫秒。
*
* @note 该函数是阻塞式的,在延时期间CPU无法执行其他任务。
* 函数依赖于全局变量systick的正确更新,通常systick在SysTick中断服务程序中递增。
* SysTick定时器应配置为每毫秒产生一次中断。
* 函数内部使用了WFI指令降低功耗,但实际延时的精度取决于中断的频率和响应时间。
*
* @warning 如果系统中没有中断或中断被禁用,使用此函数可能导致系统死锁。
* 在实时性要求高的系统中,应谨慎使用阻塞式延时函数。
* 最大延时时间受限于32位无符号整数的最大值(约49.7天)。
*
* @see systick, __WFI()
*/
void user_delay_ms(uint32_t ms)
{
// 记录开始延时的时刻systick的当前值
uint32_t start = systick;
// 循环等待,直到经过的时间达到指定的毫秒数
while (systick - start < ms)
{
// 进入低功耗模式,等待中断唤醒,有助于在延时时降低CPU功耗
__WFI();
}
}
/**
* @brief 初始化SysTick定时器
*
* @details 该函数用于初始化和配置ARM Cortex-M的SysTick定时器,使其能够以指定的频率产生中断。
* 函数执行以下配置步骤:
* 1. 设置SysTick时钟源为AHB总线时钟
* 2. 根据指定的中断频率计算并设置重载值
* 3. 清除当前计数值
* 4. 设置中断优先级
* 5. 使能中断和计数器
* 配置完成后,SysTick定时器将开始工作,并在每次计数到0时产生中断。
*
* @param ticks 指定SysTick定时器的中断频率,单位为Hz每秒中断次数
* 例如,传入1000表示定时器每1秒产生1000次中断,即每1毫秒产生一次中断。
*
* @note 该函数依赖于rcc_get_bus_clk_freq()函数获取CPU时钟频率。
* SysTick中断优先级被设置为15最低优先级,在需要更高实时性的应用中可能需要调整。
* 函数使用了库函数封装的方式操作SysTick寄存器,而不是直接寄存器访问。
* 重载值的计算方式为:(CPU时钟频率 / ticks) - 1,确保ticks值不能导致计算结果超过24位最大值(16,777,215)。
*
* @warning 如果ticks参数过大,可能导致重载值小于1,此时定时器可能无法正常工作。
* 在调用此函数前,应确保CPU时钟已经正确配置。
* 此函数会覆盖任何之前的SysTick配置,包括中断处理函数的注册。
*
* @see sys_tick_handler(), systick, user_delay_ms()
*/
void systick_init(uint32_t ticks)
{
// 设置SysTick时钟源为AHB总线时钟
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
// 计算重载值总线频率除以定时器周期数减1
systick_set_reload((rcc_get_bus_clk_freq(RCC_CPUCLK) / ticks) - 1UL);
// 清除SysTick当前值寄存器被注释掉的代码
//STK_CVR = 0UL;
// 使用函数方式清除SysTick计数器
systick_clear();
// 设置SysTick中断优先级为15最低优先级
nvic_set_priority(NVIC_SYSTICK_IRQ, 15);
// 使用函数方式配置SysTick控制寄存器被注释掉的代码
// STK_CSR = STK_CSR_CLKSOURCE | STK_CSR_TICKINT | STK_CSR_ENABLE;
// 分别使能SysTick中断和计数器
systick_interrupt_enable();
systick_counter_enable();
}
/**
* @brief SysTick定时器中断服务函数
*
* @details 该函数是SysTick定时器的中断服务程序(ISR),每当SysTick定时器计数到0时触发。
* 函数的主要功能是递增全局变量systick,该变量通常用于系统计时和延时功能。
*
* @note 该函数应保持简短高效,因为它是中断服务程序,执行时间过长可能影响系统实时性。
* systick变量通常定义为全局变量,用于记录系统运行的毫秒数假设SysTick配置为1ms中断一次
* 在多任务系统中,此函数可能需要添加任务切换相关的代码。
*
* @warning 此函数不应被用户代码直接调用,它是由硬件自动调用的中断服务程序。
* 在函数内部应避免调用可能导致长时间阻塞的函数或复杂的计算。
* 如果systick变量在多线程/多任务环境中被访问,可能需要添加适当的同步机制。
*
* @see systick, systick_init(), user_delay_ms()
*/
void sys_tick_handler(void)
{
systick++;
}

90
2gpio-lib/xmake.lua Normal file
View File

@@ -0,0 +1,90 @@
-- 工程名
set_project("stm32h7")
-- 定义工具链
toolchain("arm-none-eabi")
set_kind("standalone")
set_sdkdir("/home/time/doc/mybin/arm-none-eabi")
toolchain_end()
-- 使用自定义的 arm-none-eabi 工具链
set_toolchains("arm-none-eabi")
-- 设置平台与架构
set_plat("MCU")
set_arch("ARM Cortex-M7")
-- 编译优化与调试
set_optimize("none")
set_symbols("debug")
-- 全局架构 & FPU
add_cxflags("-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", {force = true})
add_asflags("-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", {force = true})
add_ldflags("-mthumb", "-mcpu=cortex-m7", "-mfpu=fpv5-d16", "-mfloat-abi=hard", {force = true})
-- 全局头文件路径 (libopencm3)
add_includedirs("../../libopencm3/include")
-- 全局链接 libopencm3
add_linkdirs("../../libopencm3/lib")
add_links("opencm3_stm32h7")
-- 全局额外链接选项
add_ldflags("-T./cortex-m-generic.ld", "--static", "-nostartfiles", "-Wl,--gc-sections", {force = true})
add_syslinks("c", "gcc", "nosys")
-- 全局宏定义
add_defines("STM32H7")
-- 全局用户头文件路径
add_includedirs("user/inc")
-- 目标程序
target("gpio-lib")
set_kind("binary")
add_files("user/src/*.c")
set_targetdir("$(projectdir)/bin")
add_deps("lib")
on_load(function (target)
target:set("filename", target:name() .. ".elf")
-- 生成 map 文件并带 cref显示 cross reference
target:add("ldflags",
"-Wl,-Map=" .. path.join(target:targetdir(), target:name() .. ".map") .. ",-cref",
{force = true}
)
end)
-- 生成额外文件
after_build(function (target)
local elf = target:targetfile()
local bindir = target:targetdir()
local name = target:name()
-- 常见格式
os.execv("arm-none-eabi-objcopy", {"-Obinary", elf, path.join(bindir, name .. ".bin")})
os.execv("arm-none-eabi-objcopy", {"-Oihex", elf, path.join(bindir, name .. ".hex")})
os.execv("arm-none-eabi-objcopy", {"-Osrec", elf, path.join(bindir, name .. ".srec")})
os.execv("arm-none-eabi-objdump", {"-S", elf}, {stdout = path.join(bindir, name .. ".list")})
-- 🔥 符号表 (对应 MDK Image Symbol Table)
os.execv("arm-none-eabi-nm", {"-n", elf}, {stdout = path.join(bindir, name .. ".sym")})
-- 🔥 段大小统计 (对应 MDK Image component sizes)
os.execv("arm-none-eabi-size", {"-B", elf}, {stdout = path.join(bindir, name .. ".size")})
end)
on_clean(function (target)
os.rm("build")
os.rm("bin")
end)
target("lib")
set_kind("phony")
add_deps("lib-ebtn")
target("lib-ebtn")
set_kind("static")
add_includedirs("lib/ebtn", {public = true})
add_files("lib/ebtn/*.c")